📄 ega.asm
字号:
or al,bl ; Or intensity into palette
or al,2 ; Green (2) or cyan (3)
mov [AttrRegs][001h],al ; Stash color 1
inc ax ; Red (4) or magenta (5)
inc ax ; "
mov [AttrRegs][002h],al ; Stash color 2
inc ax ; Brown/yellow (6) or white (7)
inc ax ; "
mov [AttrRegs][003h],al ; Stash color 3
scpX:
pop bx
ret
SetCgaPalette endp
subttl WriteDot
page
;
; WriteDot - shadow int 10h WriteDot functionality (subfunction 0Ch)
;
; ENTRY
; al = current video mode
; ah = static copy of ega info byte
;
; EXIT
; none
; DESTROYS
; ax, flags
;
assume cs:CODE, ds:CODE, es:nothing, ss:nothing
WriteDot proc near
mov al,0FFh
mov [GraphicsRegs][003h],ah ; Put 000h in data rotate reg
mov [GraphicsRegs][008h],al ; Put 0FFh in bit mask reg
mov [SeqRegs][002h],al ; Put 0FFh in map mask reg
ret
WriteDot endp
subttl ReadDot
page
;
; ReadDot - shadow int 10h ReadDot functionality (subfunction 0Dh)
;
; ENTRY
; al = current video mode
; ah = static copy of ega info byte
;
; EXIT
; none
; DESTROYS
; ax, flags
;
assume cs:CODE, ds:CODE, es:nothing, ss:nothing
ReadDot proc near
push bx
mov bl,003h ; Assume >64K or modes 0Dh/0Eh
cmp al,00Fh ; If mode < 0Fh,
jb @F ; assumption is correct
test ah,01100000b ; If EGA memory > 64K,
jnz @F ; assumption is correct
dec bx ; Else use crippled default
@@:
mov [GraphicsRegs][004h],bl ; Put in read map reg
pop bx
ret
ReadDot endp
subttl SetEGAPalette
page
;
; SetEGAPalette - shadow int 10h SetEGAPalette functionality (subfunction 10h)
;
; ENTRY
; (Source - Direct quote from IBM Enhanced Graphics Adapter manual)
; SubFunctions:
; (AL) = 0 Set individual palette register
; BL = Palette register to be set
; BH = Value to set
;
; AL = 1 Set overscan register
; BH = Value to set
;
; AL = 2 Set all palette register and overscan
; ES:BX points to a 17 byte table
; Bytes 0 - 15 are the palette values, respectively
; Byte 16 is the overscan value
;
; AL = 3 Toggle intensity/blinking bit
; BL - 0 Enable intensity
; BL - 1 Enable blinking
;
; EXIT
; none
; DESTROYS
; ax, si, ds, flags
;
assume cs:CODE, ds:CODE, es:nothing, ss:nothing
SetEgaPalette proc near
push bp
mov bp,sp
xor ax,ax
mov ds,ax
assume ds:INTVEC
mov al,0D4h ; Assume color
test [Info],00000010b ; If EGA has color monitor,
jz @F ; go check Addr6845
mov al,0B4h ; Else try mono
@@:
cmp byte ptr [Addr6845],al ; If no agreement with Addr6845,
jne sepX0 ; get out
push bx
mov al,byte ptr [bp].userAX ; AL = original subfunction
xor ah,ah ; Allows dec ax instruction
or al,al ; If al != 0 (set one reg),
jnz @F ; try next subfunction
cmp bl,NumAttrRegs - 1 ; If user gave us bogus index,
ja sepX1 ; get out or we'll lunch
mov al,bh ; Copy data
xor bh,bh ; Zero bh for the index
mov [AttrRegs][bx],al ; Stash it
jmp short sepX1
@@:
dec ax ; If al != 1 (set overscan reg),
jnz @F ; try next subfunction
mov [AttrRegs][011h],bh ; Stash overscan reg
jmp short sepX1
@@:
push es
dec ax ; If al != 2 (set all regs),
jnz @F ; try next subfunction
push cx
push di
mov ax,es
mov ds,ax ; DS = ES
assume ds:nothing
mov ax,cs
mov es,ax ; ES = CS
assume es:CODE
mov si,dx ; DS:SI -> src table
mov di,offset AttrRegs ; ES:DI -> AttrReg array
mov cx,8 ; Do first 16 bytes
rep movsw
inc di ; Bump past mode control
movsb ; Stash overscan
pop di
pop cx
jmp short sepX
@@:
assume ds:INTVEC, es:nothing
dec ax ; If al != 3 (toggle blink),
jnz sepX ; get out
;
; Legal values of bl (0 or 1) should be used to act NOT on the current
; setting of the mode reg, but on the default value pointed to by the parm
; ptr in the save ptr table. Illegal values for bl cause this reg to be
; restored to the default value given by the parm ptr. See IBM EGA BIOS
; pg. 148
;
mov ah,[CrtMode] ; AH = video mode
call MakeBase
assume es:nothing
mov al,es:[si][51] ; Get default attr mode value
or bl,bl ; If bl != 0 (reset bit)
jnz @F ; try next subfunction
and al,11110111b ; Reset blink bit
jmp short sepStoreBit
@@:
dec bl ; If bl still not 0,
jnz sepStoreBit ; give'em a default
or al,00001000b ; Set blink bit
sepStoreBit:
mov [AttrRegs][010h],al
sepX:
assume ds:nothing, es:nothing
pop es
assume es:nothing
sepX1:
pop bx
sepX0:
assume ds:INTVEC, es:nothing
pop bp
ret
SetEgaPalette endp
subttl DownloadFont
page
;
; DownloadFont - shadow int 10h DownloadFont functionality (subfunction 11h)
;
; ENTRY
; (Source - Direct quote from IBM Enhanced Graphics Adapter manual)
; SubFunctions:
; Note: This call will initiate a mode set, completely
; resetting the video environment but maintaining
; the regen buffer.
;
; AL = 00 User alpha load
; ES:BP - Pointer to user table
; CX - Count to store
; DX - Character offset into table
; BL - Block to load
; BH - Number of bytes per character
; AL = 01 ROM monochrome set
; BL - Block to load
; AL = 02 ROM 8x8 double dot
; BL - Block to load
; AL = 03 Set block specifier
; BL - Char gen block specifier
; D3-D2 Attr bit 3 one, char gen 0-3
; D1-D0 Attr bit 3 zero, char gen 0-3
; Note: When using AL = 03 a function call
; AX = 1000H
; BX = 0712H
; is recommended to set the color planes
; resulting in 512 characters and eight
; consistant colors
;
; Note : The following interface (AL=1X) is similar in function
; to (AL=0X) except that :
; - Page zero must be active
; - Points (bytes/char) will be recalculated
; - Rows will be calculated from the following:
; INT((200 or 350) / points) - 1
; - CRT_LEN will be calculated from :
; (rows + 1) * CRT_COLS * 2
; - The CRTC will be reprogrammed as follows :
; R09H = points - 1 Max scan line
; R09H done only in mode 7
; R0AH = points 2 Cursor start
; R0BH = 0 Cursor end
; R12H = Vert disp end
; ((rows + 1) * points) - 1
; R14H = points Underline loc
;
; The above register calculations must be close to the
; original table values or undetermined results will
; occur.
;
; Note : The following interface is designed to be
; called only immediately after a mode set has
; been issued. Failure to adhere to this practice
; may cause undetermined results.
;
; AL = 10 User alpha load
; ES:BP - Pointer to user table
; CX - Count to store
; DX - Character offset into table
; BL - Block to load
; BH - Number of bytes per character
; AL = 11 ROM monochrome set
; BL - Block to load
; AL = 12 ROM 8x8 double dot
; BL - Block to load
;
; Note : The following interface is designed to be
; called only immediately after a mode set has
; been issued. Failure to adhere to this practice
; may cause undetermined results.
;
; AL = 20 User graphics chars INT 01FH (8x8)
; ES:BP - Pointer to user table
; AL = 21 User graphics chars
; ES:BP - Pointer to user table
; CX - Points (bytes per character)
; BL - Row specifier
;
; BL = 0 User
; DL - Rows
; BL = 1 14 (0EH)
; BL = 2 25 (19H)
; BL = 3 43 (28H)
;
; AL = 22 ROM 8 x 14 set
; BL - Row specifier
; AL = 23 ROM 8 x 8 double dot
; BL - Row specifier
;
; AL = 30 Information
; CX - Points
; DL - Rows
; BH - 0 Return current INT 1FH Ptr
; ES:BP - Ptr to table
; BH - 1 Return current INT 44H Ptr
; ES:BP - Ptr to table
; BH - 2 Return ROM 8 x 14 Ptr
; ES:BP - Ptr to table
; BH - 3 Return ROM double dot Ptr
; ES:BP - Ptr to table
; BH - 4 Return ROM double dot Ptr (TOP)
; ES:BP - Ptr to table
; BH - 5 Return ROM alpha alternate 9 x 14
; ES:BP - Ptr to table
;
; EXIT
; None
;
; DESTROYS
; AX, SI
;
assume cs:CODE, ds:CODE, es:nothing, ss:nothing
DownloadFont proc near
push bp ; Save environment
mov bp,sp
mov al,byte ptr [bp].userAX ; Recover original subfunction
cmp al,20h ; If not one of the alpha loads,
jae dfX0 ; get out
cmp al,3 ; If only changing banks,
je dfSetBlock ; go do it
and al,00001111b ; Else extract sub-subfunction
cmp al,3 ; If not 0, 1, or 2,
jae dfX0 ; get out
mov si,bx ; Get row specifier
and si,000000000000011b ; Extract font bank
mov byte ptr [FontBank][si],al ; Stash font id in table
xor ax,ax
mov ds,ax ; DS = 0
assume ds:INTVEC
mov ah,[CrtMode] ; Get current video mode
push bx ; Save environment
mov bl,ah ; Save a copy for later
mov al,byte ptr [Addr6845] ; Get low byte CRTC io address
call ChangeRegs ; Re-initialize all regs
assume ds:CODE
mov al,byte ptr [bp].userAX ; Get original subfunction
sub al,010h ; Check 1x series
js dfX ; If not 1x series, we're done
jz dfSetUnderLine ; If al was 10h, bh set by user
mov bh,14 ; Assume 8x14 font
cmp [fVga],FALSE ; Do we have a VGA Card?
je @F ; No - skip
mov bh,16 ; Assume 8x16 font
@@:
dec al ; If al was 11h,
jz dfSetUnderLine ; go check underline
mov bh,008h ; Assume 8x8 font
dec al ; If al was not 12h,
jnz dfX ; then invalid code
dfSetUnderLine:
cmp bl,007h ; If not mono alpha,
jne @F ; don't set underline
mov [CRTCRegs][014h],bh ; Set underline position
@@:
dec bh ; Make 0-based
mov [CRTCRegs][009h],bh ; Set last char line
mov ax,350 ; Assume 350 total scan lines
cmp bl,003h ; If not color alpha,
ja @F ; skip special alpha tests
call BrstDet ; If 350 lines,
jnc @F ; our assumption was good
mov ax,200 ; Else show 200 lines
@@:
inc bh ; Make char lines 1-based
div bh
mul bh
dec ax ; Make total lines 0-based
mov [CRTCRegs][012h],al ; Stash new vertical total
dfX:
pop bx ; Restore environment
dfX0:
pop bp ; Restore environment
ret
dfSetBlock:
mov [SeqRegs][003h],bl ; Stash new font bank selection
pop bp ; Restore environment
ret
DownloadFont endp
endif ; CallTableNeeded
subttl Read Register
page
;
; ReadReg - Read a single EGA register from shadow maps
;
; ENTRY
; urAH = 0F0h
; bx = register index if register id is indexed chip
; ignored if register id is single reg
; dx = register id
; EXIT
; bl = current register data
; DESTROYS
; ax, si, flags
;
assume cs:CODE, ds:CODE, es:nothing, ss:nothing
ReadReg proc near
cmp dl,18h ; Is it Attr reg?
jne @F ; No - skip
cmp bl,10h ; Is it palette reg?
jae @F ; No - skip
mov [fPalette],dl ; fPalette = TRUE
@@:
call UpdateCRTCMap ; Get latest readable regs
mov si,dx ; Reg id indexes PortTable
mov si,[PortTable][si].prCurrTable
cmp dl,NumPtrData * SIZE PortRec ; If not a chip,
jae @F ; no need for bx
mov bl,CODE:[si][bx] ; Read indexed chip data
ret
@@:
mov bl,CODE:[si] ; Read a single reg
ret
ReadReg endp
subttl Write Register
page
;
; WriteReg - write to a single EGA register and update shadow maps
;
; ENTRY
; urAH = 0F1h
; bl = register index if register id is indexed chip
; data to be written if register id is single reg
; bh = data to be written if register id is indexed chip
; = ignored if register id is single reg
; dx = register id
; EXIT
; none
; DESTROYS
; ax, bh, dx, si, flags
;
assume cs:CODE, ds:CODE, es:nothing, ss:nothing
WriteReg proc near
mov ax,bx
mov si,dx ; Reg id indexes PortTable
cli ; Disable interrupts
or [PortTable][si].prModFlag,3
cmp dl,NumPtrData * SIZE PortRec ; If not a chip,
mov dx,[PortTable][si].prPortAddr
mov si,[PortTable][si].prCurrTable
jae WRegNotPtr ; Just write it directly
xor bh,bh ; Zero bh for indexing
mov CODE:[si][bx],ah ; Update shadow map
cmp dl,AttCtrlAddrReg AND 0FFh ; If not attribute chip,
jne @F ; Skip special processing
OutWordAttr ax,NoInts ; Write index/data to AttrAddr
sti ; Restore interrupt state
ret
@@:
OutWord NoInts,DestroyAX,DestroyDX
sti ; Restore interrupt state
ret
WRegNotPtr:
mov CODE:[si],al ; Update shadow map
or [SingleRegMod],3 ; Show a single reg is dirty
out dx,al ; And finally send out data
sti ; Restore interrupt state
ret
WriteReg endp
subttl Read Register Range
page
;
; ReadRange - read a range of EGA registers from shadow maps
;
; ENTRY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -