📄 egaint10.inc
字号:
;
; cmp al,cl ;check if page # hasn't changed
; je SDispPageEnd ;branch if new page == old page
; mov cx,ax ;cx <- display page #
; xor si,si ;si will end up with regen buffer
; ; address for selected page
; jcxz SetDispPage2 ;branch if page 0 selected
;SetDispPage1: add si,bx ;add page offset to page start
; loop SetDispPage1 ;sum pages until done
;SetDispPage2: mov bx,si ;bh <- msb of CRTC start address
; cmp dh,7 ;modes <= 7 use word addresses
; ja SetDispPage3 ;branch if display mode > 7
; sar bx,1 ;use starting word address
;SetDispPage3: mov 12[CRTCRegs],bh ;save Start Address High Reg value
; mov 13[CRTCRegs],bl ;save Start Address Low Reg value
; mov bx,di ;bh <- curs row / bl <- curs col
; mov cl,dl ;cl <- characters/line
; mov dx,si ;dx <- page starting byte offset
; sar dx,1 ;dx <- page starting cursor posn
; mov al,bh ;al <- cursor position row
; mul cl ;ax <- cursor row address/2
; xor bh,bh ;bh <- cursor column #
; add ax,bx ;ax <- page cursor position
; add ax,dx ;ax <- cursor position
; mov 14[CRTCRegs],ah ;save Cursor Loc High Reg value
; mov 15[CRTCRegs],al ;save Cursor Loc Low Reg value
; mov byte ptr PortTable[0].PRModFlag,1 ;set CRTC dirty flag
;
;SDispPageEnd: pop di
; pop dx
; pop cx
; pop bx
; pop ax
; ret
;SetDisplayPage endp
SetCgaPalette proc near
push ax ;save registers that may get
push bx ; destroyed
push cx
push dx
push ds ;save ds
mov cx,40h ;set ds pointing to the BIOS
mov ds,cx ; data segment
mov cl,ds:[BiosCrtPalette] ;cl <- BIOS CRT palette byte
mov ch,ds:[BiosCrtMode] ;ch <- BIOS CRT mode
pop ds ;restore ds
or bh,bh ;background or palette colors ?
jnz SCgaPalette ;branch if set CGA palette colors
and cl,11100000b ;cl gets an updated
and bl,00011111b ; version of the BIOS palette byte
or cl,bl ; now, with new background color
mov bh,bl ;convert the color number
shl bl,1 ; in bl into an intensity
and bl,10h ; in bit 4 and color in
and bh,7 ; bits 2-0 and leave the
or bh,bl ; results in bh
cmp ch,3 ;check for character modes
jbe SCgaCharPal ;branch if in a character mode
mov dx,18h ;dx <- attribute controller port #
push bx ;save color in bh
xor bl,bl ;set attr cntrlr palette color 0
call SimWriteReg ; (background) to value in bh
pop bx ;restore color to bh
SCgaCharPal: mov dx,18h ;dx <- attribute controller port #
mov bl,11h ;set attribute controller
call SimWriteReg ; overscan color to value in bh
; jmp short SCgaPaletteEnd
mov bl,cl ;ega function w/bh=0 sets both
and bl,00100000b ; border and background color,
;[1] rol bl,3 ; so we drop into background logic
rol bl,1 ;[1]
rol bl,1 ;[1]
rol bl,1 ;[1]
SCgaPalette: cmp ch,3 ;check for character modes
jbe SCgaPaletteEnd ;branch if character mode (no
; palettes for character modes)
and cl,10h ;cl <- intensity bit from palette
; which is actually derived from
; the background color by the BIOS
and bl,1 ;only allow palettes 0 and 1
or bl,cl ;or intensity into palette
or bl,2 ;color 1 is green (2) or cyan (3)
mov bh,bl ;bh <- color and intensity
mov bl,1 ;set attribute controller palette
; register 1 to value in bh
mov dx,18h ;dx <- attribute controller port #
push bx ;save bx
call SimWriteReg ;write it!
pop bx ;restore bx
inc bh ;color 2 is red (4) or magenta (5)
inc bh
inc bl ;set attribute controller palette
; register 2 to value in bh
mov dx,18h ;dx <- attribute controller port #
push bx ;save bx
call SimWriteReg ;write it!!
pop bx ;restore bx
inc bh ;color 3 is brown (6) or white (7)
inc bh
inc bl ;set attribute controller palette
; register 3 to value in bh
mov dx,18h ;dx <- attribute controller port #
call SimWriteReg ;write it!!!
SCgaPaletteEnd: pop dx
pop cx
pop bx
pop ax
ret
SetCgaPalette endp
SetEgaPalette proc near
push ax ;save registers that may get
push bx ; destroyed
push cx
push dx
mov dx,18h ;dx <- attribute controller port #
mov al,byte ptr [SaveAX] ;al <- subfunction
or al,al ;0 = set individual palette reg
jnz NotS1EgaPalReg ;branch if not set 1 register
S1EgaPalReg: call SimWriteReg ;write 1 Attribute Controller Reg
jmp short SEgaPaletteEnd
NotS1EgaPalReg: dec al ;1 = set overscan register
jnz NotSetOverscan ;branch if not overscan register
mov bl,11h ;bl <- overscan register number
jmp short S1EgaPalReg ;write it!!!
NotSetOverscan: dec al ;2 = set palette & overscan regs
jnz ToggleBlink ;branch if not set all
pop bx ;bx <- table offset (was in dx)
push bx ;put dx value back onto stack
mov cx,16 ;16 registers to write first
call SimWriteRange ;write them!!!
pop bx
push bx ;get pointer to data again
mov bh,es:[bx+16] ;get the overscan byte now
mov bl,11h ;ptr to overscan reg
call SimWriteReg ;write separated overscan now!
jmp short SEgaPaletteEnd
ToggleBlink: dec al ;3 = toggle blink bit
jnz SEgaPaletteEnd ;branch if not toggle blink bit
; In order to parallel EGA Bios logic (strange though it sometimes is),
; this code must fetch the default attr mode reg value from the tables in
; EGA ROM and modify THAT, rather than the CURRENT setting of the mode reg.
; If the bh parm is not legal, then that default value is stored instead,
; which may well be different from the current setting of the mode reg. 4/12/87
push ds
push es
cbw ;we know al already 0
mov ds,ax ;MakeBase requires ds = 0
mov ah,ds:[449h] ;also requires video bios mode #
call MakeBase
mov bh,es:[si+51] ;get default attr mode value
pop es
pop ds
or bl,bl ;what's our purpose in life?
jz resetbit ;0 means shut off bit
dec bl
or bl,bl
jnz storebit ;still not 0? give'em a default
or bh,00001000b
jmp short storebit
resetbit: and bh,11110111b
; mov bx,16 ;read attr controller mode reg
; call ReadReg ;bl <- attr controller mode reg
; pop cx ;cx <- toggle bit
; shl cl,1 ;move toggle bit from
; shl cl,1 ; bit 0 to bit 3
; shl cl,1
; or cl,bl ;cl <- new value for mode reg
; mov bh,cl ;bh <- new value for mode reg
storebit: mov bl,16 ;write attr controller mode reg
mov dx,18h ;dx <- attribute controller port #
jmp short S1EgaPalReg ;write attr controller mode reg
SEgaPaletteEnd: pop dx
pop cx
pop bx
pop ax
ret
SetEgaPalette endp
Int10Routine proc far
cmp ah,0f0h ;Fast EGA R.I. call?
jb NotMine ;no
MyCall: push ds ;CallInt10 depends on this!
push si
push ax
mov al,ah
and ax,000fh
shl ax,1
mov si,ax
mov ax,cs
mov ds,ax
call [si].MyCallTable
pop ax
pop si
pop ds
iret
NotMine: cmp ah,0Bh ;SetCgaPalette call?
je Mine2 ;we hook that one
test ah,0Fh ;test for AH=00 or 10
jz Mine1 ;we hook both of those calls
jmp cs:[Int10Vector] ;we don't hook any other AH=0X
Mine1: cmp ah,MaxBIOSCall ;but we don't hook AH=20,30,etc
ja DoInt10
Mine2: push ds
mov cs:[SaveSI],si
mov si,cs
mov ds,si
mov [SaveAX],ax
mov al,ah
xor ah,ah
shl ax,1
mov si,ax
call BIOSCallTable[si]
mov ax,[SaveAX]
mov si,[SaveSI]
pop ds
DoInt10: jmp cs:[Int10Vector]
Int10Routine endp
SimWriteReg proc near
mov ax,bx
mov si,dx
cmp dx,NumPtrData * size PortRec
mov dx,PortTable[si].PRPortAddr
mov byte ptr PortTable[si].PRModFlag,1
mov si,PortTable[si].PRCurrTable
jge SWRegNoPtr
xor bh,bh
mov [si+bx],ah
ret
SWRegNoPtr: mov [si],al
mov [SingleRegMod],1
ret
SimWriteReg endp
SimWriteRange proc near
cld
push di
push es
mov si,bx
mov di,dx
mov byte ptr PortTable[di].PRModFlag,1
mov di,PortTable[di].PRCurrTable
mov ax,es
mov bx,ds
mov es,bx
mov ds,ax
xor ax,ax
xchg al,ch
add di,ax
shr cx,1
rep movsw
rcl cx,1
rep movsb
mov ds,bx
pop es
pop di
ret
SimWriteRange endp
ReadReg proc near
mov si,dx
mov si,PortTable[si].PRCurrTable
cmp dx,NumPtrData * size PortRec
jge RRegNoPtr
mov bl,[si+bx]
ret
RRegNoPtr: mov bl,[si]
ret
ReadReg endp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -