File: dos\fr8514a.asm
1
2
3 IFDEF ??version
4 MASM51
5 QUIRKS
6 ENDIF
7
8 .MODEL medium,c
9
10 .8086
11
12
13
14 HOPEN equ 8
15 HSMX equ 9
16 HINT equ 16
17 HLDPAL equ 19
18 HBBW equ 21
19 HBBR equ 23
20 HBBCHN equ 24
21 HBBC equ 25
22 HQMODE equ 29
23 HRECT equ 32
24 HCLOSE equ 34
25 HINIT equ 48
26 HSYNC equ 49
27 HSPAL equ 57
28 HRPAL equ 58
29
30
31 HLINE equ 0
32 HSCOL equ 7
33
34
35 .DATA
36
37 extrn sxdots:word, sydots:word ; number of dots across and down
38 extrn dacbox:byte, daccount:word
39
40 afiptr dd 0
41
42 xadj dw 0
43 yadj dw 0
44
45 extrn paldata:byte ; 1024-byte array (in GENERAL.ASM)
46
47 extrn stbuff:byte ; 415-byte array (in GENERAL.ASM)
48
49 linedata db 0
50
51 hopendata db 3, 0, 0, 0, 0
52 hclosedata dw 2, 0
53 hinitdata dw 2, 0
54 bbw dw 10, 8, 0, 1, 0, 0
55 bbr dw 12, 8, 0, 1, 0, 0, 0
56 smx dw 2, 0
57 chn dw 6
58 dd linedata
59 dw 1
60 pal dw 10, 0, 0, 256
61 dd paldata
62 hidata dw 4, 0, 8000h
63 amode dw 18, 9 dup(?)
64
65
66 hlinedata dw 8, 0, 0, 0, 0
67 hscoldata dw 4, 0, 0
68
69
70 .CODE
71
72
73 callafi proc near
74
75 push ds ; Pass the parameter pointer
76 push si
77
78 shl ax,1 ; form offset from entry no. required
79 shl ax,1
80 mov si,ax
81
82 les bx, afiptr ; entry block address to es:bx
83 call dword ptr es:[bx][si] ; call entry point
84
85 ret ; return to caller
86
87 callafi endp
88
89
90 getafi proc near
91
92 mov ax,357fh ; read interrupt vector 7f
93 int 21h
94 mov ax,es
95 or ax,bx ; is 7f vector null
96 stc
97 jz getafiret
98
99 mov ax,0105h ; get Interface address
100 int 7fh ; by software interrupt 7f
101
102 jc getafiret ; Interface not OK if carry set
103
104 mov word ptr afiptr,dx ; save afi pointer offset
105 mov word ptr afiptr+2,cx ; save afi pointer segment
106
107 clc ; clear carry flag
108
109 getafiret:
110 ret ; return to caller
111
112 getafi endp
113
114
115 do85open proc near
116
117 push ax
118 mov ax, HOPEN
119 call callafi
120
121 mov ax, offset stbuff ;get the state segment
122 add ax, 15
123 mov cl, 4
124 shr ax, cl
125
126 mov bx, ds
127 add ax, bx
128
129 mov si, offset hinitdata
130 mov [si] + 2, ax
131
132 pop ax
133 call callafi
134
135 clc
136 ret
137
138 do85open endp
139
140
141 open8514 proc far
142
143 call load8514dacbox ; load dacbox for 8514/A setup JCO 4/6/92
144
145 call getafi ;get adapter interface
146 jc afinotfound
147
148 mov bl, 0 ;if > 640 x 480 then 1024 x 768
149
150 mov ax, sxdots
151
152 cmp ax, 1024 ;if > 1024, don't use afi, JCO 4/4/92
ja afinotfound
cmp ax, 800 ; must be 1024
ja setupopen
cmp ax, 640 ; could be 800
ja afinotfound
mov ax, sydots
cmp ax, 480
ja setupopen
inc bl
setupopen:
mov si, offset hopendata ;open the adapter
mov byte ptr [si + 2], 40h ;zero the image but leave pallette
mov [si + 3], bl
mov ax, HINIT ;initialize state
call do85open
jc afinotfound
mov si, offset amode ;make sure on the size
mov ax, HQMODE ;get the adapter mode
call callafi
mov ax, amode + 10 ;get the screen width
cmp ax, sxdots
jae xdotsok ;check for fit
mov sxdots, ax
xdotsok:
sub ax, sxdots ;save centering factor
shr ax, 1
mov xadj, ax
mov ax, amode + 12 ;get the screen height
cmp ax, sydots
jae ydotsok
mov sydots, ax
ydotsok:
sub ax, sydots
shr ax, 1
mov yadj, ax
clc
ret
afinotfound: ; No 8514/A interface found
stc ; flag bad mode
ret ; and bail out
open8514 endp
reopen8514 proc far
mov si, offset hopendata ;open the adapter
mov byte ptr [si + 2], 0C0h ;zero the image but leave pallette
mov ax, HSYNC ;initialize state
call do85open
ret
reopen8514 endp
close8514 proc far
mov si, offset hclosedata ;turn off 8514a
mov ax, HCLOSE
call callafi
ret
close8514 endp
fr85wdotnew proc near uses si
mov byte ptr [hscoldata + 2], al
add cx, xadj
add dx, yadj
mov hlinedata + 2, cx
mov hlinedata + 4, dx
inc cx ; increment x direction
mov hlinedata + 6, cx
mov hlinedata + 8, dx
; set the color
mov si, offset hscoldata
mov ax, HSCOL
call callafi
; plot the point
mov si, offset hlinedata
mov ax, HLINE
call callafi
ret
fr85wdotnew endp
fr85wdot proc far uses si
mov linedata, al
mov bbw + 4, 1 ;define the rectangle
; mov bbw + 6, 1
add cx, xadj
add dx, yadj
mov bbw + 8, cx
mov bbw + 10, dx
mov si, offset bbw
mov ax, HBBW
call callafi
mov si, offset chn
mov word ptr [si + 2], offset linedata
mov word ptr [si + 6], 1 ;send the data
mov ax, HBBCHN
call callafi
fr85wdotx:
ret
fr85wdot endp
fr85wbox proc far uses si
sub ax, cx
inc ax ; BDT patch 11/4/90
; add ax, xadj
add cx, xadj
add dx, yadj
mov chn + 2, si ;point to data
mov chn + 6, ax
mov bbw + 4, ax ;define the rectangle
; mov bbw + 6, 1 ;set in declaration
mov bbw + 8, cx
mov bbw + 10, dx
mov si, offset bbw
mov ax, HBBW
call callafi
mov si, offset chn
mov ax, HBBCHN
call callafi
ret
fr85wbox endp
fr85rdot proc far uses si
mov bbr + 4, 1 ;define the rectangle
; mov bbr + 6, 1 ;set in declaration
add cx, xadj
add dx, yadj
mov bbr + 10, cx
mov bbr + 12, dx
mov si, offset bbr
mov ax, HBBR
call callafi
mov si, offset chn
mov word ptr [si + 2], offset linedata
mov word ptr [si + 6], 1 ;send the data
mov ax, HBBCHN
call callafi
mov al, linedata
fr85rdotx:
ret
fr85rdot endp
fr85rbox proc far uses si
sub ax, cx
inc ax ; BDT patch 11/4/90
; add ax, xadj
add cx, xadj
add dx, yadj
mov chn + 2, di ;point to data
mov chn + 6, ax
mov bbr + 4, ax ;define the rectangle
; mov bbr + 6, 1 ;set in declaration
mov bbr + 10, cx
mov bbr + 12, dx
mov si, offset bbr
mov ax, HBBR
call callafi
mov si, offset chn
mov ax, HBBCHN
call callafi
ret
fr85rbox endp
w8514pal proc far
mov si, offset dacbox
mov cx, daccount ;limit daccount to 128 to avoid fliker
cmp cx, 128
jbe countok
mov cx, 128
mov daccount, cx
countok: ;now build 8514 pallette
mov ax, 256 ;from the data in dacbox
mov pal + 4, 0
mov di, offset paldata
cld
cpallp:
push ax ;do daccount at a time
mov dx, di
cmp ax, cx
jae dopass
mov cx, ax
dopass:
mov pal + 6, cx ;entries this time
push cx
cpallp2:
push ds ;pallette format is r, b, g
pop es ;0 - 255 each
lodsb ;red
shl al, 1
shl al, 1
stosb
lodsb ;green
shl al, 1
shl al, 1
xchg ah, al
lodsb ;blue
shl al, 1
shl al, 1
stosw
mov al, 0 ;filler
stosb
loop cpallp2
push si
push di
push dx
mov si, hidata ;wait for flyback
mov ax, HINT
call callafi
pop dx
mov pal + 8, dx
mov si, offset pal ;load this piece
mov ax, HLDPAL
call callafi
pop di
pop si
pop cx
add pal + 4, cx ;increment the pallette index
pop ax
sub ax, cx
jnz cpallp
ret
w8514pal endp
;********************************************************************
;* 8514/A Hardware Interface Routines
;* Written by Aaron M. Williams for Fractint
;* This code may be used freely by anyone for anything and freely distributed.
;* All routines here are written for a V20 (80186) or better CPU.
;* All code has been at least partially optimized for a 486 (i.e. pipelining)
;* The macros were written by Roger Brown for Adex Corporation and have been
;* placed into the public domain by Adex corporation.
;*
;* Special support has been added for the Brooktree RAMDAC, which uses 8
;* bits for rgb values instead of 6 bits. This RAMDAC is used only in the
;* 1280x1024 mode (unless programmed otherwise)
;*
;* Completed on 3/8/92
;* Revised by JCO on 4/12/92
; changed width to wdth and other minor fixes so it would assemble
; using MASM 6.0
; took out duplicate variables, xadj, yadj, linedata
; took out .model C
; added VIDEO_TEXT to .code and made procedures near
; added TRANSY macro for 640x480x16 (512K), but not used
; w8514hwpal
; Changed normal 8514/A routine to slow it down
; reopen8514hw
; Renamed enableHIRES as reopen8514hw
; Commented out old reopen8514hw
; open8514hw
; Changed where board is reset so a hung board won't prevent detect of 8514/A
153 ; Added load8514dacbox routine to initialize colors
154 ; Added detection and setup of 512K 8514/A, use debug=8514 to test on 1 Meg
155 ; Changed foreground mix to FSS_FRGDCOL. It's faster to use FRGD_COLOR for
; dots and set/reset the mix for boxes.
; Took out call to w8514hwpal, hangs machine if another video mode is not used
; first, load8514dacbox takes care of loading initial colors
; fr85hwwdot, fr85hwrdot
; Replaced with routines that use short stroke vectors, uses fewer port calls
; fr85hwwbox, fr85hwrbox
; Replaced with routines that use vectors
; close8514hw
; Made non-Adex 8514/A not use the enableVGA routine
; load8514dacbox
; Added this routine to load dacbox
;* Added support for ATI ULTRA 800x600x256 and 1280x1024x16 modes JCO, 11/7/92
.286 ; we use 286 code here for speed
; for in graphics, speed is everything
.DATA
; Defines
BIT_0_ON EQU 0000000000000001b
BIT_1_ON EQU 0000000000000010b
BIT_2_ON EQU 0000000000000100b
BIT_3_ON EQU 0000000000001000b
BIT_4_ON EQU 0000000000010000b
BIT_5_ON EQU 0000000000100000b
BIT_6_ON EQU 0000000001000000b
BIT_7_ON EQU 0000000010000000b
BIT_8_ON EQU 0000000100000000b
BIT_9_ON EQU 0000001000000000b
BIT_10_ON EQU 0000010000000000b
BIT_11_ON EQU 0000100000000000b
BIT_12_ON EQU 0001000000000000b
BIT_13_ON EQU 0010000000000000b
BIT_14_ON EQU 0100000000000000b
BIT_15_ON EQU 1000000000000000b
BIT_0_OFF EQU 1111111111111110b
BIT_1_OFF EQU 1111111111111101b
BIT_2_OFF EQU 1111111111111011b
BIT_3_OFF EQU 1111111111110111b
BIT_4_OFF EQU 1111111111101111b
BIT_5_OFF EQU 1111111111011111b
BIT_6_OFF EQU 1111111110111111b
BIT_7_OFF EQU 1111111101111111b
BIT_8_OFF EQU 1111111011111111b
BIT_9_OFF EQU 1111110111111111b
BIT_10_OFF EQU 1111101111111111b
BIT_11_OFF EQU 1111011111111111b
BIT_12_OFF EQU 1110111111111111b
BIT_13_OFF EQU 1101111111111111b
BIT_14_OFF EQU 1011111111111111b
BIT_15_OFF EQU 0111111111111111b
;==========================================
; Equates for use with Wait_Till_FIFO Macro
;==========================================
ONEEMPTY = BIT_7_ON
TWOEMPTY = BIT_6_ON
THREEEMPTY = BIT_5_ON
FOUREMPTY = BIT_4_ON
FIVEEMPTY = BIT_3_ON
SIXEMPTY = BIT_2_ON
SEVENEMPTY = BIT_1_ON
EIGHTEMPTY = BIT_0_ON
VSYNC_BIT_MASK = BIT_0_ON
DEFAULT_MASK = 00FFh ; Default to all 8 bits.
LOCK_FLAG = BIT_15_ON ; Flag to lock CRTC timing regs
GE_BUSY_MASK = BIT_9_ON ; Mask for GE_BUSY
GE_BUSY_SHFT = 9
MAX_RES_MASK = BIT_3_ON
MAX_RES_SHFT = 3
PATTERN_POS_MASK = (BIT_13_ON+BIT_12_ON+BIT_11_ON+BIT_10_ON+BIT_9_ON+BIT_8_ON)
PATTERN_POS_SHFT = 8
SELECT_DPAGE_2 = BIT_1_ON
SELECT_DPAGE_1 = BIT_1_OFF
SELECT_VPAGE_2 = BIT_2_ON
SELECT_VPAGE_1 = BIT_2_OFF
LOWER_12_BITS = 0FFFh ; Mask off upper 4 bits
;*****************************************************************************
;
; MACRO DEFINITIONS
;
;*****************************************************************************
;PURPOSE : Wait until there is [number] locations available in the FIFO.
Wait_Till_FIFO MACRO number
LOCAL waitfifoloop
mov dx, GP_STAT
waitfifoloop:
in ax, dx
test ax, number
jnz waitfifoloop
ENDM
; Wait if Hardware is Busy
Wait_If_HW_Busy MACRO
LOCAL waithwloop
mov dx, GP_STAT
waithwloop:
in ax, dx
test ax, FSR_HWBUSY
jnz waithwloop
ENDM
; PURPOSE: Wait Till CPU data is Available (Used for Image Read/Write)
Wait_Till_Data_Avail MACRO
LOCAL waitdataloop
mov dx, GP_STAT
waitdataloop:
in ax, dx
test ax, 0100h
jz waitdataloop
ENDM
; PURPOSE: Output a word to the specified i/o port
Out_Port MACRO port, value
IFIDNI , ;; [ax] already loaded
ELSE
mov ax, value
ENDIF
IFIDNI , ;; [dx] already loaded
ELSE
mov dx, port
ENDIF
out dx, ax
ENDM
; PURPOSE: Input a word from the specified i/o port
In_Port MACRO port
IFIDNI , ;; [dx] already loaded
ELSE
mov dx, port
ENDIF
in ax, dx
ENDM
; PURPOSE: Output a byte to the specified i/o port
Out_Port_Byte MACRO port, value
IFIDNI , ;; [al] already loaded
ELSE
mov al, value
ENDIF
IFIDNI , ;; [dx] already loaded
ELSE
mov dx, port
ENDIF
out dx, al
ENDM
; PURPOSE: Input a byte from the specified i/o port
In_Port_Byte MACRO port
mov dx, port ;; output contents of ax
in al, dx ;; al = value from [port]
ENDM
; PURPOSE: Wait for Vsync to go low, then high,
Wait_For_Vsync MACRO
LOCAL wait_low, wait_high
mov dx, SUBSYS_STAT
mov ax, RVBLNKFLAG
out dx, ax ; Clear Vsync status bit
wait_low:
; in ax, dx
; test ax, VSYNC_BIT_MASK
; jnz wait_low ; causes problems with ATI ********
wait_high:
in ax, dx
test ax, VSYNC_BIT_MASK
jz wait_high ; Loop until beginning of Vysnc (blank)
ENDM
; PURPOSE: Enter Western Digital Enhanced Mode.
Enter_WD_Enhanced_Mode MACRO
mov dx, WD_ESCAPE_REG
in al, dx
ENDM
; PURPOSE: Write pixel data in [ax] to PIX_TRANS port [dx]
; ENTRY : [dx] = PIX_TRANS, data in [ax]
Write_A_Pixel MACRO
Out_Port dx, ax
ENDM
; PURPOSE: Resets MULTIFUNC_CNTL register to FCOL & MIX
Reset_MULTIFUNC_CNTL MACRO
Out_Port MULTIFUNC_CNTL, 0A000h
ENDM
;
; TRANSY
;
; Translate y value for the case of 4 bpp and 640x480
; The y value is assumed to be in ax.
; The result is left in ax.
; result = (y & 1) | ((y >> 1) << 2)
; by Jonathan Osuch, 2/15/92
; Not needed by Graphics Ultra, others might need it
;
TRANSY macro
push bx
mov bx, ax
and bx, 1
shr ax, 1
shl ax, 1
shl ax, 1
or ax, bx
pop bx
endm
;
;========================================
; Return Value Definitions
;========================================
TRUE = 1
FALSE = 0
;*****************************************************************************
;
; VESA STANDARD 8514/A REGISTER MNEMONICS
;
;*****************************************************************************
;=============================
; 8514/A READBACK REGISTER SET
;=============================
SETUP_ID1 equ 00100h ; Setup Mode Identification
SETUP_ID2 equ 00101h ; Setup Mode Identification
DISP_STAT equ 002E8h ; Display Status
WD_ESCAPE_REG equ 028E9h ; WD Escape Functions
SUBSYS_STAT equ 042E8h ; Subsystem Status
WD_ENHANCED_MODE_REG equ 096E8h ; Enter WD Enhanced Mode
GP_STAT equ 09AE8h ; Graphics Processor Status
FSR_HWBUSY equ 00200h ; Bit Set if Hardware Busy
;==========================
; 8514/A WRITE REGISTER SET
;==========================
SETUP_OPT equ 00102h ; Setup Mode Option Select
H_TOTAL equ 002E8h ; Horizontal Total
DAC_MASK equ 002EAh ; DAC Mask
DAC_R_INDEX equ 002EBh ; DAC Read Index
DAC_W_INDEX equ 002ECh ; DAC Write Index
DAC_DATA equ 002EDh ; DAC Data
H_DISP equ 006E8h ; Horizontal Displayed
H_SYNC_STRT equ 00AE8h ; Horizontal Sync Start
H_SYNC_WID equ 00EE8h ; Horizontal Sync Width
V_TOTAL equ 012E8h ; Vertical Total
V_DISP equ 016E8h ; Vertical Displayed
V_SYNC_STRT equ 01AE8h ; Vertical Sync Start
V_SYNC_WID equ 01EE8h ; Vertical Sync Width
DISP_CNTL equ 022E8h ; Display Control
SUBSYS_CNTL equ 042E8h ; Subsystem Control
ICR_GERESET equ 09000h ; reset mask
ICR_NORMAL equ 08000h ; normal mask
ROM_PAGE_SEL equ 046E8h ; ROM Page Select
ADVFUNC_CNTL equ 04AE8h ; Advanced Function Control
MODE_VGA equ 00010b ;
MODE_768 equ 00111b ;
MODE_480 equ 00011b ;
CUR_Y equ 082E8h ; Current Y Position
CUR_X equ 086E8h ; Current X Position
DESTY_AXSTP equ 08AE8h ; Destination Y Position /
; Axial Step Constant
DESTX_DIASTP equ 08EE8h ; Destination X Position /
; Axial Step Constant
ERR_TERM equ 092E8h ; Error Term
MAJ_AXIS_PCNT equ 096E8h ; Major Axis Pixel Count
CMD equ 09AE8h ; Command
SHORT_STROKE equ 09EE8h ; Short Stroke Vector Trnsf
BKGD_COLOR equ 0A2E8h ; Background Color
FRGD_COLOR equ 0A6E8h ; Foreground Color
WRT_MASK equ 0AAE8h ; Write Mask
RD_MASK equ 0AEE8h ; Read Mask
COLOR_CMP equ 0B2E8h ; Color Compare
BKGD_MIX equ 0B6E8h ; Background Mix
FRGD_MIX equ 0BAE8h ; Foreground Mix
MULTIFUNC_CNTL equ 0BEE8h ; Multi-Function Control
PIX_TRANS equ 0E2E8h ; Pixel Data Transfer
MIN_AXIS_PCNT equ 0000h ; Minor Axis Pixel Count
T_SCISSORS equ 1000h ; Top Scissors
L_SCISSORS equ 2000h ; Left Scissors
B_SCISSORS equ 3000h ; Bottom Scissors
R_SCISSORS equ 4000h ; Right Scissors
MEM_CNTL equ 5000h ; Memory Control
PATTERN_L equ 8000h ; Fixed Pattern - Low
PATTERN_H equ 9000h ; Fixed Pattern - High
PIX_CNTL equ 0A000h ; Pixel Control
; Display Status bit field
HORTOG equ 0004h ;
VBLANK equ 0002h ;
SENSE equ 0001h
; Horizontal Sync Width Bit Field
HSYNCPOL_NEG equ 0020h ; negative polarity
HSYNCPOL_POS equ 0000h ; positive polarity
; Vertical Sync Width Bit Field
VSYNCPOL_NEG equ 0020h ; negative polarity
VSYNCPOL_POS equ 0000h ; positive polarity
; Display control bit field
DISPEN_NC equ 0000h ; no change
DISPEN_DISAB equ 0040h ; disable display, syncs, and refresh
DISPEN_ENAB equ 0020h ; enable display, syncs, and refresh
INTERLACE equ 0010h ; interlace enable bit
DBLSCAN equ 0008h ; double scan bit
MEMCFG_2 equ 0000h ; 2 CAS configuration
MEMCFG_4 equ 0002h ;
MEMCFG_6 equ 0004h ;
MEMCFG_8 equ 0006h ;
ODDBANKENAB equ 0001h ; Use alternate odd/even banks for
; each line
; Subsystem status register bits
_8PLANE equ 0080h ; 8 planes of memory installed
MONITORID_MASK equ 0070h ; Monitor ID mask
MONITORID_8503 equ 0050h ;
MONITORID_8507 equ 0010h ;
MONITORID_8512 equ 0060h ;
MONITORID_8513 equ 0060h ;
MONITORID_8514 equ 0020h ;
MONITORID_NONE equ 0070h ;
GPIDLE equ 0008h ; Processor idle bit, command queue empty
INVALIDIO equ 0004h ; Set when command written to full queue
; or the Pixel Data Transfer register was
; read when no data was available. This
; bit must be cleared prior to any other
; operation with RINVALIDIO bit
PICKFLAG equ 0002h ; This bit is set when a write inside the
; clipping rectangle is about to be made.
; You can clear it with RPICKFLAG
VBLNKFLAG equ 0001h ; This bit is set at the start of the
; vertical blanking period. It can only
; be cleared by setting RVBLNKFLG
; Subsystem Control Register bit field
GPCTRL_NC equ 0000h ; no change
GPCTRL_ENAB equ 4000h ; enable 8514
GPCTRL_RESET equ 8000h ; reset 8514/A and disable
; also flushes command queue
CHPTEST_NC equ 0000h ; no change
CHPTEST_NORMAL equ 1000h ; Enables synchronization between
; chips
CHPTEST_ENAB equ 2000h ; Disables synchronization. Use
; only as a diagnostic procedure
IGPIDLE equ 0800h ; Enable GPIDLE interrupt.
; Usually this is IRQ9 (SW IRQ2)
IINVALIDIO equ 0400h ; Enable invalid I/O interrupt
; Interrupt when subsystem status
; register INVALIDIO bit set
IPICKFLAG equ 0200h ; Interrupts the system when
; PICKFLAG in the subsystem
; status register goes high
IVBLNKFLAG equ 0100h ; Interrupts the system when
; VBLNKFLAG in Subsystem Status
; goes high
RGPIDLE equ 0008h ; Resets GPIDLE bit in subsystem
; status register
RINVALIDIO equ 0004h ; Resets INVALIDIO bit in
; Subsystem Status Register
RPICKFLAG equ 0002h ; Resets PICKFLAG in Subsystem
; Status Register
RVBLNKFLAG equ 0001h ; Resets VBLNKFLAG in Subsystem
; Status Register
; Current X, Y and Destination X, Y mask
COORD_MASK equ 07FFh ; coordinate mask (2047)
; Advanced Function Control Register bit field
CLKSEL equ 0004h ; 1 = 44.9 MHz clock, 0 = 25.175 MHz
DISSABPASSTHRU equ 0001h ; 0 = VGA pass through, 1 = 8514/A
; Graphics Processor Status Register
GPBUSY equ 0200h ; 1 when processor is busy in command
; and in data transfer
DATARDY equ 0100h ; 0 = no data ready to be read
; 1 = data ready for reading.
; used for Pixel Data Transfer reads
; Command Register
CMD_NOP equ 0000h ; do nothing
CMD_LINE equ 2000h ; Draw a line according to LINETYPE bit
; when LINETYPE = 1, bits 567 specify
; direction of vector with length
; stored in Major Axis Pixel Count
CMD_RECT equ 4000h ; Fast-Fill Rectangle accordign to
; PLANEMODE. Can read as well as write
; according to PCDATA and WRTDATA
CMD_RECTV1 equ 6000h ; Draws a rectangle vertically in
; columns starting at the upper left
; and working down
CMD_RECTV2 equ 8000h ; Like CMD_RECT1, except accesses 4
; pixels at a time horizontally rather
; than 1
CMD_LINEAF equ 0A000h ; Draw line for area fill. Only draws
; one pixel for each scan line crossed.
CMD_BITBLT equ 0C000h ; Copy rectangle on display and to/from
; PC memory through Pixel Data Transfer
; register.
CMD_OP_MSK equ 0E000h ; command mask
BYTSEQ equ 01000h ; Selects byte ordering for pixel data
; transfer and short-stroke vector
; transfer registers only. 0 = high
; byte first, low byte second, 1 =
; low byte first, high byte second.
_16BIT equ 00200h ; Affects Pixel Data Transfer and Short
; Stroke Vector Transfer registers.
; 0 = 8-bit access, 1 = 16-bit access
PCDATA equ 00100h ; 0 = drawing operations use 8514/A
; based data
; 1 = drawing operations wait for
; data to be written or read from
; the Pixel Data Transfer register
; before proceeding to the next
; pixel. Direction of transfer
; is based on WRTDATA
INC_Y equ 00080h ; Determines y direction of lines
; during line drawing when LINETYPE is
; cleared.
; 0 = UP, 1 = DOWN
YMAJAXIS equ 00040h ; Determines major axis when LINETYPE
; is 0.
; 0 = X is major axis, 1 = Y is major
; axis.
INC_X equ 00020h ; Determines direction of X when drawing
; lines when LINETYPE = 0
; 0 = right to left (negative X dir)
; 1 = left to right (positive X dir)
DRAW equ 00010h ; 0 = move only, no pixels drawn
; 1 = draw
LINETYPE equ 00008h ; Selects line drawing algorithm
; 0 = normal Bresenham line drawing
; 1 = vector drawing CMD_NOP = short
; stroke, CMD_LINE = long line
LASTPIX equ 00004h ; 0 = last pixel for lines and vectors
; drawn
; 1 = last pixel not drawn
PLANAR equ 00002h ; Access is Pixel at a time or Planar
; 0 = Pixel, 1 = Planar
WRTDATA equ 00001h ; 0 = read operation, 1 = write
; used for Pixel Data Transfer
; Short Stroke vector transfer register
; can also be used for command register when LINETYPE=1 and CMD_LINE
VECDIR_000 equ 0000h
VECDIR_045 equ 0020h
VECDIR_090 equ 0040h
VECDIR_135 equ 0060h
VECDIR_180 equ 0080h
VECDIR_225 equ 00A0h
VECDIR_270 equ 00C0h
VECDIR_315 equ 00E0h
SSVDRAW equ 0010h ; 0 = move position, 1 = draw vector
; and move
; Background MIX register
BSS_BKGDCOL equ 0000h ; use background color
BSS_FRGDCOL equ 0020h ; use foreground color
BSS_PCDATA equ 0040h ; PC data (via Pixel Data Transfer reg)
BSS_BITBLT equ 0060h ; All-Plane Copy
; Foreground MIX register
FSS_BKGDCOL equ 0000h ; use background color
FSS_FRGDCOL equ 0020h ; use foreground color
FSS_PCDATA equ 0040h ; PC data (via Pixel Data Transfer reg)
FSS_BITBLT equ 0060h ; All-Plane Copy
; Mixing applications
MIX_MASK equ 001Fh ; mask for mixing values
MIX_NOT_DST equ 0000h ; NOT Dst
MIX_0 equ 0001h ; All bits cleared
MIX_1 equ 0002h ; All bits set
MIX_DST equ 0003h ; Dst
MIX_LEAVE_ALONE equ 0003h ; Do nothing
MIX_NOT_SRC equ 0004h ; NOT Src
MIX_SRC_XOR_DST equ 0005h ; Src XOR Dst
MIX_XOR equ 0005h ;
MIX_NOT__SRC_XOR_DST equ 0006h ; NOT (Src XOR Dst)
MIX_XNOR equ 0006h ;
MIX_SRC equ 0007h ; Src
MIX_REPLACE equ 0007h ;
MIX_PAINT equ 0007h ;
MIX_NOT_SRC_OR_NOT_DST equ 0008h ; Not Src OR NOT Dst
MIX_NAND equ 0008h ;
MIX_NOT_SRC_OR_DST equ 0009h ; NOT Src OR Dst
MIX_SRC_OR_NOT_DST equ 000Ah ; Src OR NOT Dst
MIX_SRC_OR_DST equ 000Bh ; Src OR Dst
MIX_OR equ 000Bh ;
MIX_SRC_AND_DST equ 000Ch ; Src AND Dst
MIX_AND equ 000Ch
MIX_SRC_AND_NOT_DST equ 000Dh ; Src AND NOT Dst
MIX_NOT_SRC_AND_DST equ 000Eh ; NOT Src AND Dst
MIX_NOT_SRC_AND_NOT_DST equ 000Fh ; NOT Src AND NOT Dst
MIX_NOR equ 000Fh ; Src NOR Dst
MIX_MIN equ 0010h ; MINIMUM (Src, Dst)
MIX_DST_MINUS_SRC equ 0011h ; Dst - Src (with underflow)
MIX_SRC_MINUS_DST equ 0012h ; Src - Dst (with underflow)
MIX_PLUS equ 0013h ; Src + Dst (with overflow)
MIX_MAX equ 0014h ; MAXIMUM (Src, Dst)
MIX_HALF__DST_MINUS_SRC equ 0015h ; (Dst - Src) / 2 (with underflow)
MIX_HALF__SRC_MINUS_DST equ 0016h ; (Src - Dst) / 2 (with underflow)
MIX_AVERAGE equ 0017h ; (Src + Dst) / 2 (with overflow)
MIX_DST_MINUS_SRC_SAT equ 0018h ; (Dst - Src) (with saturate)
MIX_SRC_MINUS_DST_SAT equ 001Ah ; (Src - Dst) (with saturate)
MIX_PLUS_SAT equ 001Bh ; (Src + Dst) (with saturate)
MIX_HALF__DST_MINUS_SRC_SAT equ 001Ch ; (Dst - Src) / 2 (with sat)
MIX_HALF__SRC_MINUS_DST_SAT equ 001Eh ; (Src - Dst) / 2 (with sat)
MIX_AVERAGE_SAT equ 001Fh ; (Src + Dst) / 2 (with saturate)
; Memory control register
BUFSWP equ 0010h ; pseudo 8-plane on 4-plane board
VRTCFG_2 equ 0000h ; vertical memory configuration
VRTCFG_4 equ 0004h
VRTCFG_6 equ 0008h
VRTCFG_8 equ 000Ch
HORCFG_4 equ 0000h ; Horizontal memory configuration
HORCFG_5 equ 0001h
HORCFG_8 equ 0002h
HORCFG_10 equ 0003h
; Pixel Control Register
MIXSEL_FRGDMIX equ 0000h ; use foreground mix for all drawing
; operations
MIXSEL_PATT equ 0040h ; use fixed pattern to decide which
; mix setting to use on a pixel
MIXSEL_EXPPC equ 0080h ; PC Data Expansion. Use data from
; Pixel Transfer Register
MIXSEL_EXPBLT equ 00C0h ; Bits in source plane determine
; foreground or background MIX
; 0 = bkgd, 1 = frgd
COLCMPOP_F equ 0000h ; FALSE
COLCMPOP_T equ 0008h ; TRUE
COLCMPOP_GE equ 0010h ; Dst >= CC
COLCMPOP_LT equ 0018h ; Dst < CC
COLCMPOP_NE equ 0020h ; Dst != CC
COLCMPOP_EQ equ 0028h ; Dst == CC
COLCMPOP_LE equ 0030h ; Dst <= CC
COLCMPOP_GT equ 0038h ; Dst > CC
PLANEMODE equ 0004h ; Enables plane mode for area fill and
; single plane expansion
; The following code was written largely by Aaron Williams
; and largely mucked up by Jonathan Osuch
.DATA
TEMP_SIZE = 12
NUM_ENTRIES = 256
__temp_palette DB TEMP_SIZE DUP (?)
Gra_mode_ctl_sh dw ?
WD_enhance_mode_sh dw 0
extrn sxdots:word, sydots:word ; number of dots across and down
extrn dacbox:byte
extrn daccount:word ; count of entries in DAC table
extrn cpu:word ; CPU type 88, 186, etc.
extrn debugflag:word ; for debugging purposes
wdth dw 0 ; JCO 4/11/92
height dw 0
bppstatus dw 0 ; temporary status for bpp ; JCO 4/11/92
bpp4x640 db 0 ; flag for 4 bpp and 640x480 ; JCO 4/11/92
adexboard db 0 ; set to 1 when ADEX board
currentmode dw 0 ; points to current mode table
ati_enhance_mode dw 0 ; 1 for 800x600, 11h for 1280x1024
loadset dd 0C0000064h ; entries to bios jump table
setmode dd 0C0000068h ; modified later if rom is moved
ati_temp dw 0
; 8514/A initialization tables written by Aaron Williams
mode640 dw 2381h ; Western Digital Enhanced Mode Register
dw 0003h ; advanced function control
dw 5006h ; Multifunction control
dw 0063h ; Horizontal total
dw 004Fh ; Horizontal displayed
dw 0052h ; Horizontal sync start
dw 002Ch ; Horizontal sync width
dw 0418h ; Vertical total
dw 03BBh ; Vertical displayed
dw 03D2h ; Vertical sync start
dw 0022h ; Vertical sync width
dw 0023h ; Display control
mode1024 dw 2501h ; Western Digital Enhanced Mode Register
; I will later add options for 70hz mode,
; interlaced mode, etc. This is used only
; for Adex or compatible boards
; for 70 hz, change to 2581h
dw 0007h ; advanced function control
dw 5006h ; Multifunction control
dw 00A2h ; Horizontal total
dw 007Fh ; Horizontal displayed
dw 0083h ; Horizontal sync start
dw 0016h ; Horizontal sync width
dw 0660h ; Vertical total
dw 05FBh ; Vertical displayed
dw 0600h ; Vertical sync start
dw 0008h ; Vertical sync width
disp1024 dw 0023h ; Display control
; The 1280 mode is supported only on Adex boards. If anyone has any info on
; other boards capable of this mode, I'd like to add support.
156 mode1280 dw 2589h ; WD enhanced mode register
157 dw 0007h ; advanced function control
158 dw 5006h ; Multifunction control
159 dw 0069h ; Horizontal total
160 dw 004Fh ; Horizontal displayed
161 dw 0053h ; Horizontal sync start
162 dw 0009h ; Horizontal sync width
163 dw 0874h ; Vertical total
164 dw 07FFh ; Vertical displayed
165 dw 0806h ; Vertical sync start
166 dw 0003h ; Vertical sync width
167 dw 0023h ; Display control
168
169 ; 4bpp mode added by JCO 4/5/92, 1024x4 same as 1024x8
170 mode640x4 dw 0000h ; Western Digital Enhanced Mode Register ????
171 dw 0003h ; advanced function control
172 dw 5002h ; Multifunction control ; This may need to be 5000h
173 dw 0063h ; Horizontal total
174 dw 004Fh ; Horizontal displayed
175 dw 0052h ; Horizontal sync start
176 dw 002Ch ; Horizontal sync width
177 dw 0830h ; Vertical total
178 dw 0779h ; Vertical displayed
179 dw 07A8h ; Vertical sync start
180 dw 0022h ; Vertical sync width
181 dw 0021h ; Display control ; This may need to be 0020h
182
183
184 .CODE
185
186 ; This routine updates the 8514/A palette
187 ; For modes with resolutions > 1024x768, a different DAC must be used.
188 ; The ADEX board uses a high-speed Brooktree DAC which uses 24 bits per
189 ; color instead of the usual 18 bits.
190 ; The data is written out in 3 parts during vertical retrace to prevent snow.
191 ; Normal 8514/A routine modified to slow down the spin, JCO 4/3/92
192 w8514hwpal proc far
193
194 mov si, offset dacbox
195 cld
196
197 ; dac_w_index
198 mov dx, DAC_W_INDEX
199 mov al, 0 ;start at beginning of 8514a palette
200 out dx, al;
201
202 cmp wdth, 1024
203 jbe writedac
204 cmp adexboard, 1
205 je wbrooktree
206
207
208 writedac: ; rewritten to slow down the spin, JCO 4/11/92
209 mov cx, daccount
210 mov bx, 0 ;use bx to hold index into the dac
211
212 mov ax, 256
213 cpallp:
214 push ax
215 cmp ax, cx
216 jae dopass
217 mov cx, ax
218 dopass:
219 push cx
220
221 ; wait for first vertical blank
222 mov dx, DISP_STAT
223 chkvblnk1: ;loop til vertical blank
224 in ax, dx ;read status register
225 test ax, VBLANK
226 jz chkvblnk1 ;set to 1 during vertical blank
227
228 ; wait for screen to display
229 chkvblnk2: ;loop while screen displayed
230 in ax, dx ;read status register
231 test ax, VBLANK
232 jnz chkvblnk2 ;set to 0 during screen display
233
234 ; wait for next vertical blank, make sure we didn't miss it
chkvblnk3: ;loop til vertical blank
in ax, dx ;read status register
test ax, VBLANK
jz chkvblnk3 ;set to 1 during vertical blank
; move the palette in dacbox
mov dx, DAC_DATA
cpall2:
outsb ;put red into 8514/a palette
outsb ;put green into 8514/a palette
outsb ;put blue into 8514/a palette
loop cpall2
pop cx
add bx, cx
mov dx, DAC_W_INDEX ;load next piece of palette
mov ax, bx
out dx, al
pop ax
sub ax, cx
jnz cpallp
sti
ret
wbrooktree: ; we go here for updating the Brooktree
mov cx, 256 ; output first 1/3 of data
cli
Wait_For_Vsync ; wait for vertical retrace
mov dx, 02EDh
pall1: ; the brooktree uses 8 bits instead of 6
lodsb
shl al, 2
out dx, al
loop pall1
sti
mov cx, 256 ; output second 1/3 of data
cli
Wait_For_Vsync ; wait for vertical retrace
mov dx, 02EDh
pall2:
lodsb
shl al, 2
out dx, al
loop pall2
sti
mov cx, 256 ; output third 1/3 of data
cli
Wait_For_Vsync ; wait for vertical retrace
mov dx, 02EDh
pall3:
lodsb
shl al, 2
out dx, al
loop pall3
sti
ret
w8514hwpal endp
; reopen8514hw turns off VGA pass through and enables the 8514/A display
reopen8514hw PROC far
cmp adexboard, 0
je enableati
mov dx, WD_ESCAPE_REG
in al, dx
mov si, currentmode
mov dx, WD_ENHANCED_MODE_REG
outsw
jmp enablegeneric
enableati:
cmp ati_enhance_mode, 0
je enablegeneric
mov ax, ati_enhance_mode ; load mode into shadow set 1 (lores)
call dword ptr [loadset]
mov ax, 1 ; set lores mode
call dword ptr [setmode]
ret
enablegeneric:
mov ax, [Gra_mode_ctl_sh] ; Read shadow register.
or ax, BIT_0_ON ; Set for HIRES mode
mov [Gra_mode_ctl_sh], ax ; Update shadow register.
Out_Port ADVFUNC_CNTL, ax
ret
reopen8514hw ENDP
; open8514hw initializes the 8514/A for drawing graphics. It test for the
; existence of an 8514/A first.
; CY set on error
open8514hw proc far
; Test for the existence of an 8514/A card by writing to and reading
; from the Error term register.
xor al, al
mov adexboard, al
call load8514dacbox ; load dacbox for 8514/A setup JCO 4/6/92
; Assume 8514/A present and reset it. Otherwise a locked up board
; would not appear as an 8514/A. JCO 4/3/92
; reset 8514/A subsystem
mov dx, SUBSYS_CNTL
mov ax, GPCTRL_RESET+CHPTEST_NORMAL ; Reset + Normal
out dx, ax
mov ax, GPCTRL_ENAB+CHPTEST_NORMAL ; Enable + Normal
out dx, ax
mov dx, ERR_TERM
mov ax, 5A5Ah ; output our test value
out dx, ax
jmp $+2 ; add slight delay
jmp $+2
in ax, dx
cmp ax, 5A5Ah
je Found_8514 ; jump if ok
stc ; set error if not found
ret
Found_8514:
; we need at least a 186 or better for rep outsw and stuff for speed.
; We won't support the 8086/8088, since it's *very* unlikely that
; anyone with an 8088 based machine would invest in an 8514/A
;
cmp [cpu], 88
jne GoodCPU
stc
ret
GoodCPU: ; JCO 5/8/92
mov bx, sxdots ; uncommented this section and made check
cmp bx, 640 ; for interlaced monitor vs non-interlaced
jbe monitor_ok ; any old monitor should work non-interlaced
mov dx, SUBSYS_STAT
in ax,dx
and ax, MONITORID_MASK
cmp ax, MONITORID_8514 ; do we need to interlace?
jz setinterlaced ; yes, jump
cmp ax, MONITORID_8507 ; do we need to interlace?
jz setinterlaced ; yes, jump
jmp monitor_ok ; use default non-interlaced mode
setinterlaced:
or disp1024, INTERLACE ; set interlace bit, JCO 5/8/92
monitor_ok:
mov bpp4x640, 0 ;clear flag for y value translation
mov dx, SUBSYS_STAT
in ax, dx
;************** debug 4bpp
cmp debugflag, 8514
jne notest
test ax, _8PLANE ;if not set, 4bpp anyway, don't change
235 jnz notest
236 xor ax, _8PLANE ;clear the 8bpp bit to test 4bpp
237 notest:
238 ;**************
239
240 mov bppstatus, ax ;save the status for a while
241 test ax, _8PLANE ;is it 8 bits per pixel?
242 jnz plane8 ;yes, 1024K video memory
243
244 ; no, only 512K video memory, 4 bits per pixel
245
246 mov ax, sxdots ; AX contains H resolution
247
248 ; test if 640x480x4bpp
249 mov bpp4x640, 1 ;set flag for y value translation
250 mov si, offset mode640x4 ; SI = offset of register data
251 mov bx, 640 ; BX = X resolution
252 mov cx, 480 ; CX = Y resolution
253 mov wdth, bx ; store display width
254 mov height, cx ; store display height
255 cmp ax, 640 ; jump if this resolution is correct
256 jbe setupopen
257
258 ; test if 1024x768x4bpp
259 mov bpp4x640, 0 ;clear flag for y value translation
260 mov si, offset mode1024
261 mov bx, 1024
262 mov cx, 768
263 mov wdth, bx
264 mov height, cx
265 cmp ax, 1024
266 jbe setupopen
267 stc ; oops, to high a resolution
268 ret
269
270 plane8:
271 mov ax, sxdots ; AX contains H resolution
272
273 ; test if 640x480
274 mov si, offset mode640 ; SI = offset of register data
275 mov bx, 640 ; BX = X resolution
276 mov cx, 480 ; CX = Y resolution
277 mov wdth, bx ; store display width
278 mov height, cx ; store display height
279 cmp ax, 640 ; jump if this resolution is correct
280 jbe setupopen
281
282 ; test if 800x600 (special ati ultra mode)
283 ; si does not need to be set, everything is in eeprom
284 mov bx, 800
285 mov cx, 600
286 mov wdth, bx
287 mov height, cx
288 cmp ax, 800
289 jbe setupopen
290
291 ; test if 1024x768
292 mov si, offset mode1024
293 mov bx, 1024
294 mov cx, 768
295 mov wdth, bx
296 mov height, cx
297 cmp ax, 1024
298 jbe setupopen
299
300 ; must be 1280x1024
301 mov si, offset mode1280
302 mov bx, 1280
303 mov cx, 1024
304 mov wdth, bx
305 mov height, cx
306
307 setupopen:
308 ; test for Western Digital Chipset
309 mov currentmode, si
310 mov dx, WD_ESCAPE_REG
311 in al, dx
312
313 mov ax, 6AAAh
314 mov dx, MAJ_AXIS_PCNT
315 out dx, ax
316
317 mov dx, WD_ESCAPE_REG ; enable enhanced mode for ADEX board
318 in al, dx
319
320 mov dx, MAJ_AXIS_PCNT ; if port 96E8 is between 3F00h and 2A00h we
321 in ax, dx ; have a WD board, else IBM/Other
322 cmp ax, 2A00h
323 jb ati_ultra
324 cmp ax, 3F00h
325 ja ati_ultra
326
327 ; We must have a Western Digital chip set.
328 ; May not be Adex.
329 ; Future test to implement will be to write a pixel to X,Y location
330 ; with X > 1024 and read it back to check for enough memory for 1280
331 ; mode.
332 mov al, 1
333 mov adexboard, al ; set adex board
334 mov dx, WD_ESCAPE_REG ; program WD
335 in al, dx
336
337 mov dx, WD_ENHANCED_MODE_REG
338 outsw ; output the Western Digital
339 ; enhanced mode register
340
341 mov [WD_enhance_mode_sh], ax ; keep a copy of it
342 jmp openOK
343
344 ibm_8514_step:
345 jmp ibm_8514
346
347 ati_ultra:
348 mov ati_enhance_mode, 0 ; make sure enhanced mode is clear
349 ; check for ATI
350 mov dx, 52EEh ; ROM_ADDR_1 register
351 in ax, dx
352 mov ati_temp, ax ; temporary save
353 mov ax, 5555h
354 out dx, ax
355 Wait_If_HW_Busy ; make sure HW is not busy
356 mov dx, 52EEh ; ROM_ADDR_1 register
357 in ax, dx
358 cmp ax, 5555h
359 jne ibm_8514_step ; nope must be real 8514a
360
361 mov ax, 2A2Ah
362 out dx, ax
363 Wait_If_HW_Busy ; make sure HW is not busy
364 mov dx, 52EEh ; ROM_ADDR_1 register
365 in ax, dx
366 cmp ax, 2A2Ah
367 jne ibm_8514_step ; nope must be real 8514a
368
369 mov ax, ati_temp
370 out dx, ax ; restore ROM_ADDR_1 register
371
372 and ati_temp, 007Fh ; calculate the ROM base address
373 mov ax, 80h ; (ROM_ADDR_1 & 0x7F)*0x80 + 0xC000
374 mul ati_temp
375 add ax, 0C000h
376 mov word ptr loadset+2, ax
377 mov word ptr setmode+2, ax
378
379 mov es, ax
380 mov ax, es:4Ch ; get ati bios revision
381 cmp al, 1h
382 jl ibm_8514 ; revision level too low, can't do it
cmp ah, 3h
jl ibm_8514 ; revision level too low, can't do it
383
384 ; everything appears okay
385
386 ; get resolution, could be 800x600 or 1280x1024
387 mov ax, sxdots ; AX contains H resolution
388 cmp ax, 640
389 jbe ibm_8514 ; too low for 800x600
390 cmp ax, 800
391 jbe set_800x600 ; must be 800x600
392 cmp ax, 1024
393 jbe ibm_8514 ; too low for 1280x1024
394 cmp ax, 1280
395 jbe set_1280x1024 ; must be 1280x1024
396 jmp ibm_8514 ; too high
397
398 set_800x600:
399 mov ax, 1 ; load 800x600 into shadow set 1 (lores)
400 call dword ptr [loadset]
401 jc ibm_8514 ; didn't work, forget it
mov ax, 1 ; set lores mode
call dword ptr [setmode]
jc ibm_8514 ; didn't work, forget it
402
403 mov ati_enhance_mode, 1 ; save mode
404 jmp setplane8
405
406 set_1280x1024:
407 mov ax, 11h ; load 1280x1024 into shadow set 1 (lores)
408 call dword ptr [loadset]
409 jc ibm_8514 ; didn't work, forget it
mov ax, 1 ; set lores mode
call dword ptr [setmode]
jc ibm_8514 ; didn't work, forget it
410
411 mov ati_enhance_mode, 11h ; save mode
412 jmp setplane4 ; 4 bits/pixel
413
414 ibm_8514:
415 lodsw ; ignore WD enhanced mode register
416 cmp wdth, 1024 ; make sure the resolution isn't too high
jbe openOK
stc ; a *real* 8514/A cannot run higher than
ret ; 1024x768, so quit
openOK:
Wait_If_HW_Busy ; make sure HW is not busy
mov dx, ADVFUNC_CNTL
lodsw ; get Multifunction Control
mov Gra_mode_ctl_sh, ax ; keep a copy of it
out dx, ax
mov dx, MULTIFUNC_CNTL ; program multifunction control
outsw
mov dx, H_TOTAL ; program HTOTAL
outsw
mov dx, H_DISP ; program HDISPLAYED
outsw
mov dx, H_SYNC_STRT ; set start of HSYNC
outsw
mov dx, H_SYNC_WID ; set width of HSYNC signal
outsw
mov dx, V_TOTAL ; set vertical total
outsw
mov dx, V_DISP ; set vertical resolution
outsw
mov dx, V_SYNC_STRT ; set start of V Sync
outsw
mov dx, V_SYNC_WID ; set width of V Sync signal
outsw
mov dx, DISP_CNTL ; set the display control
outsw
mov ax, bppstatus ;get status again, push/pop doesn't work!
417 test ax, _8PLANE
418 jnz setplane8
419
420 ; enable 4 bits per pixel
421 setplane4:
422 mov ax, 0Fh
423 mov dx, DAC_MASK
424 out dx, al
425 mov ax, 0FF0Fh
426 mov dx, WRT_MASK
427 out dx, ax
428 jmp doneset
429
430 setplane8:
431 ; enable 8 bits per pixel
432 mov ax, 0FFh
433 mov dx, DAC_MASK
434 out dx, al
435 mov ax, 0FFFFh
436 mov dx, WRT_MASK
437 out dx, ax
438
439 doneset:
440 ; Complete environment set up 3/20/92 JCO
441 Out_Port BKGD_MIX, or MIX_REPLACE> ;set mixes
442 ; FRGD_MIX set below
443 ; WRT_MASK set above
444 Out_Port MULTIFUNC_CNTL, or 0h> ; clear lower bits
445 ; 3/20/92 JCO
446
447 ; set clipping
448 Wait_Till_FIFO FOUREMPTY ; wait for room in queue
449 mov dx, MULTIFUNC_CNTL
450 mov ax, T_SCISSORS
451 out dx, ax ; set top clip to 0
452 mov ax, cx
453 dec ax
454 or ax, B_SCISSORS
455 out dx, ax ; set bottom clip to maxy
456
457 mov ax, L_SCISSORS
458 out dx, ax ; set left clip to 0
459
460 mov ax, bx
461 dec ax
462 or ax, R_SCISSORS ; set right clip to maxx
463 out dx, ax
464
465 ; clear screen
466 Wait_Till_FIFO SIXEMPTY ; wait for room in FIFO
467 mov dx, FRGD_MIX
468 mov ax, 0021h ; zero memory ?? why 21h and not 01h? JCO
469 out dx, ax
470
471 xor ax, ax
472 mov dx, CUR_X ; set start of rectangle to 0,0
473 out dx, ax
474
475 mov dx, CUR_Y
476 out dx, ax
477
478 mov ax, wdth
479 mov dx, MAJ_AXIS_PCNT
480 dec ax
481 out dx, ax ; set width of rectangle to draw
482
483 mov ax, height
484 mov dx, MULTIFUNC_CNTL
485 dec ax
486 out dx, ax ; set height of rectangle to draw
487
488 ; Reset_MULTIFUNC_CNTL ; done above
489 mov dx, CMD
490 mov ax, 42F3h ; issue rect draw command
491 out dx, ax ; draw the rectangle
492
493 ; Wait_Till_FIFO ONEEMPTY ; set write mask ** done above
494 ; mov dx, WRT_MASK ; to include all
495 ; mov ax, 00FFh ; bits
496 ; out dx, ax
497
498 Wait_Till_FIFO THREEEMPTY ; set foreground to default
499 mov dx, FRGD_MIX
500 ; mov ax, FSS_PCDATA + MIX_SRC
501 mov ax, FSS_FRGDCOL + MIX_SRC ;slightly faster to not use pcdata
502 ;to draw the dots, JCO 4/12/92
503 out dx, ax
504
505 xor ax, ax
506 mov dx, CUR_X ; set X,Y back to 0,0
507 out dx, ax
508 mov dx, CUR_Y
509 out dx, ax
510
511 ; enable palette
512 Wait_If_HW_Busy ; wait until HW is done
513
514 cmp adexboard, 1 ; if adex board, we must assume a brooktree
515 jne notadexdac ; dac at all resolutions > 1024x768
516 cmp wdth, 1024 ;
517 ja brooktree ; jmp if using special Brooktree RAMDAC
518
519 notadexdac:
520 ; mov dx, 2EAh ; set palette mask ** done above
521 ; mov al, 0FFh
522 ; out dx, al
523 jmp paletteinitdone
524
525 brooktree: ; brooktree DAC requires special
526 mov dx, 2ECh ; configuration. This DAC is required
527 mov al, 04h ; for 1280x1024 resolution, and it is not
528 out dx, al ; totally compatible with the standard RAMDAC
529 mov dx, 2EAh
530 mov al, 0FFh ; This code enables the DAC for proper operation
531 out dx, al
532 mov dx, 2ECh
533 mov al, 05h
534 out dx, al
535 mov dx, 2EAh
536 mov al, 0h
537 out dx, al
538 mov dx, 2ECh
539 mov al, 06h
540 out dx, al
541 mov dx, 2EAh
542 mov al, 040h
543 out dx, al
544
545 paletteinitdone:
546 ; push bx ; This works if another video mode is used first. JCO 4/9/92
547 ; push cx ; Using load8514dacbox, above, sets the 8514/A palette.
548 ; call w8514hwpal ; set 8514 palette
549 ; pop cx
550 ; pop bx
551
552 mov ax, bx
553 sub ax, sxdots ;save centering factor
554 shr ax, 1
555 mov xadj, ax
556
557 mov ax, cx
558 sub ax, sydots
559 shr ax, 1
560 mov yadj, ax
561 clc ; no errors
562 ret
563 open8514hw endp
564
565
566 ;reopen8514hw proc near
567 ; Return to 8514/A after VGA
568 ; call enableHIRES
569 ; ret
570 ;reopen8514hw endp
571
572
573 fr85hwwdot proc far
574 ; draws a pixel at cx,dx of color al
575 mov bx, dx ; temporary save of dx (y position)
576
577 push ax ; need to save ax register (color)
578 Wait_Till_FIFO FIVEEMPTY
579
580 pop ax
581 mov dx, FRGD_COLOR
582 out dx, ax
583
584 add cx, xadj
585 mov ax, cx
586 mov dx, CUR_X
587 out dx, ax ; set x position
588
589 mov ax, bx ; put y position into ax
590 add ax, yadj
591
592 ;******* not needed by Graphics Ultra, may be needed by others.
593 ;******* would only be needed in 640x480x16 mode, 512K video memory
594 ; cmp bpp4x640, 1
595 ; jne wdotnorm
596 ; TRANSY ;flag set, translate y value
597 ;wdotnorm:
598
599 mov dx, CUR_Y
600 out dx, ax ; set y position
601
602 ; next, set up command register
603 Out_Port CMD, or LINETYPE or WRTDATA>
604 Out_Port SHORT_STROKE, or SSVDRAW or 0> ; plot 1 pixel
605
606 ret
607
608 fr85hwwdot endp
609
610
611 fr85hwwbox proc far uses si
612 ; copies a line of data from ds:si to the display from cx,dx to ax,dx
613
614 sub ax, cx ; delta is now in ax, 8514/a uses deltas
615 mov bx, ax ; temporary save
616
617 push dx ; need to save dx register (y value)
618 Wait_Till_FIFO SIXEMPTY
619 pop ax
620
621 add ax, yadj
622
623 ;******* not needed by Graphics Ultra, may be needed by others.
624 ;******* would only be needed in 640x480x16 mode, 512K video memory
625 ; cmp bpp4x640, 1
626 ; jne wboxnorm
627 ; TRANSY ;flag set, translate y value
628 ;wboxnorm:
629
630 mov dx, CUR_Y
631 out dx, ax ; y position
632
633 add cx, xadj
634 mov ax, cx
635 mov dx, CUR_X
636 out dx, ax ; x position
637
638 mov ax, bx
639 mov dx, MAJ_AXIS_PCNT
640 out dx, ax ; line length delta
641
642 Out_Port FRGD_MIX, or MIX_SRC> ;set mix
643
644 mov cx, bx ; number of pixels delta
645 inc cx ; number of bytes to move
646 shr cx, 1 ; number of words to move
647 jnc evn ; carry set if odd number of bytes
648 inc cx ; write last byte
649 evn:
650
651 Out_Port CMD, or LINETYPE or _16BIT or BYTSEQ or PCDATA \
652 or DRAW or WRTDATA or VECDIR_000>
653 cld
654 mov dx, PIX_TRANS
655
656 rep outsw
657
658 Out_Port FRGD_MIX, or MIX_SRC> ;reset mix
659
660 ret
661
662 fr85hwwbox endp
663
664
665 fr85hwrdot proc far
666 ; Reads a single pixel (x,y = cx,dx). Color returned in ax
667
668 push dx ; need to save dx register (y value)
669 Wait_Till_FIFO FOUREMPTY
670 pop ax ; put y position into ax
671 add ax, yadj
672
673 ;******* not needed by Graphics Ultra, may be needed by others.
674 ;******* would only be needed in 640x480x16 mode, 512K video memory
675 ; cmp bpp4x640, 1
676 ; jne rdotnorm
677 ; TRANSY ;flag set, translate y value
678 ;rdotnorm:
679
680 mov dx, CUR_Y
681 out dx, ax ; set y position
682
683 mov ax, cx ; put x position into ax
684 add ax, xadj
685 mov dx, CUR_X
686 out dx, ax ; set x position
687
688 ; next, set up command register
689 Out_Port CMD, or LINETYPE or PCDATA>
690 Out_Port SHORT_STROKE, or SSVDRAW or 0> ; move to pixel
691
692 Wait_Till_Data_Avail ; make sure data is available to read
693 In_Port PIX_TRANS
694
695 ret
696
697 fr85hwrdot endp
698
699 fr85hwrbox proc far uses es
700 ; copies a line of data from cx,dx to ax,dx to es:di
701 mov bx, ds ;set up string write
702 mov es, bx
703
704 sub ax, cx ; delta is now in ax, 8514/a uses deltas
705 mov bx, ax ; temporary save
706
707 push dx ; need to save dx register
708 Wait_Till_FIFO FOUREMPTY
709 pop ax ; put y value in ax
710
711 add ax, yadj
712
713 ;******* not needed by Graphics Ultra, may be needed by others.
714 ;******* would only be needed in 640x480x16 mode, 512K video memory
715 ; cmp bpp4x640, 1
716 ; jne rboxnorm
717 ; TRANSY ;flag set, translate y value
718 ;rboxnorm:
719
720 mov dx, CUR_Y
721 out dx, ax ; y position
722
723 add cx, xadj
724 mov ax, cx
725 mov dx, CUR_X
726 out dx, ax ; x position
727
728 mov ax, bx
729 mov dx, MAJ_AXIS_PCNT
730 out dx, ax ; line length delta
731
732 mov cx, bx ; number of pixels delta
733 inc cx ; number of bytes to move
734 shr cx, 1 ; number of words to move
735 jnc revn ; carry set if odd number of bytes
736 inc cx ; read last byte
737 revn:
738
739 Out_Port CMD, or LINETYPE or _16BIT or BYTSEQ or PCDATA \
740 or DRAW or VECDIR_000>
741 cld ; di is already set when routine is entered
742 Wait_Till_Data_Avail ; wait until data is available
743 mov dx, PIX_TRANS
744
745 rep insw
746
747 ret
748
749 fr85hwrbox endp
750
751
752 ; enableVGA causes the VGA pass-through to be enabled.
753 ; This was mostly written by Roger Brown, and optimized and updated by
754 ; Aaron Williams
755 enableVGA PROC USES ds es si di
756 ; disable DAC mask
757 mov al, 0
758 Out_Port_Byte DAC_MASK, al
759
760 Wait_For_Vsync
761
762 ; use VGA lock up palette for Hi Res mode 8514/a display
763
764 xor bx, bx ; Initial palette entry
765
766 read_palette_loop:
767 mov di, OFFSET __temp_palette ; Buffer address
768
769 mov al, bl ; [1] VGA 3C8h register is byte
770 ; register, use byte output only
771 mov dx, 3c8h ; VGA_DAC_W reg.
772 out dx, al
773
774 mov dx, 3c7h ; set VGA DAC read index
775 out dx, al ; any write change mode
776
777 mov cx, TEMP_SIZE ; Number of bytes to read each pass
778 mov dx, 3c9h ; VGA_DAC_DATA_REG
779 mov ax, ds ; Segment of _temp_palette[]
780 mov es, ax
781 cld
782 rep insb ; Read in the palette
783
784
785 ; BX->start_index, CX->count, DS:DI->DWORD
786
787 Out_Port_Byte DAC_W_INDEX, bl
788 cli
789 cld
790 mov si, OFFSET __temp_palette ; Buffer address
791 mov dx, DAC_DATA
792 mov cx, (TEMP_SIZE ) ; Number of entries to write each pass
793 rep outsb ; update the DAC data
794 sti
795
796 mov cx, (TEMP_SIZE / 3)
797 add bx, cx
798 cmp bx, NUM_ENTRIES
799 jl read_palette_loop
800
801 ; reading vga DAC mask and writing to 8514 DAC mask 02EA
802
803 mov dx, 3c6h
804 in al, dx
805 Out_Port_Byte DAC_MASK, al
806
807 ; enable vga pass-through mode
808
809 mov ax, Gra_mode_ctl_sh ; Read shadow register.
810 ; [2] No FIFO checking needed for
811 ; 4AE8h register.
812 and ax, BIT_0_OFF ; Set for VGA pass-through mode.
813 mov Gra_mode_ctl_sh, ax
814 Out_Port ADVFUNC_CNTL, ax;
815
816 ret
817 enableVGA ENDP
818
819
820 close8514hw proc far
821
822 ; Re-enables VGA pass-through.
823
824 cmp adexboard, 0
825 je close_notAdex ; Don't call enableVGA if not Adex, JCO 4/4/92
call enableVGA ; This seems to transfer the dac from
; the VGA to the 8514/A and then enable
; VGA mode!!!
mov si, offset mode1024
mov dx, WD_ESCAPE_REG ; program WD
in al, dx
mov dx, WD_ENHANCED_MODE_REG
outsw
close_notAdex:
cmp ati_enhance_mode, 0
je close_notati
mov ax, 0 ; load defaults into shadow sets
call dword ptr [loadset]
mov ax, 0 ; set VGA passthrough
call dword ptr [setmode]
close_notati:
mov dx, ADVFUNC_CNTL
mov ax, 6
out dx, ax ; enable VGA
ret
close8514hw endp
; This routine sets 320x200x256 VGA mode and then loads dacbox, JCO 4/11/92
load8514dacbox proc near uses es
mov ax,13h ; switch to 320x200x256 mode
int 10h
push ds ; ...
pop es ; ...
mov ax,1017h ; get the old DAC values
mov bx,0 ; (assuming, of course, they exist)
mov cx,256 ; ...
mov dx,offset dacbox ; ...
int 10h ; do it.
ret
load8514dacbox endp
END