📄 svga.asm
字号:
procstart __clear16
push bp ; Set up stack frame
mov bp,sp
push si ; Save registers
push di
; Setup graphics controller
mov dx,3CEh ; DX := Graphics Controller I/O port
mov ah,0 ; AH := Background color
xor al,al ; AL := 0 (Set/Reset register number)
out dx,ax ; load set/reset register
mov ax,0F01h ; AH := 1111b (mask for Enable set/reset)
; AL := 1 (enable Set/reset reg number)
out dx,ax ; load enable set/reset reg
mov ax,[_maxy]
inc ax
mul [_bytesperline] ; DX:AX := number of bytes to fill
mov bx,ax ; BX := bytes in last bank to fill
mov dh,dl ; DH := number of full banks to fill
mov ax,VGABufferSeg
mov es,ax
mov di,[OriginOffset] ; ES:DI -> video buffer
mov ax,[BankOffset] ; AX := starting bank number
cld ; Moves go up in memory
or dh,dh ; More than one bank to fill?
jz @@SingleBank ; No, only fill a single bank
; Fill all of the full 64k banks first
@@OuterLoop:
call setBank
mov cx,4000h ; Need to set 4000h double words per bank
rep stosd
inc al
dec dh
jnz @@OuterLoop
; Now fill the last partial bank
@@SingleBank:
call setBank
mov cx,bx
shr cx,2 ; CX := number of double words to set
rep stosd
; Restore graphics controller
mov dx,3CEh ; DX := Graphics Controller I/O port
xor ax,ax ; AH := 0, AL := 0
out dx,ax ; Restore default Set/Reset register
inc ax ; AH := 0, AL := 1
out dx,ax ; Restore enable Set/Reset register
pop di
pop si
pop bp
ret
procend __clear16
;----------------------------------------------------------------------------
; void clear256(void)
;----------------------------------------------------------------------------
; Routine to clear the screen. Assumes pages begin on bank boundaries
; for simplicity of coding.
;----------------------------------------------------------------------------
procstart __clear256
push di
mov ax,[_maxy]
inc ax
mul [_bytesperline] ; DX:AX := number of bytes to fill
mov bx,ax ; BX := bytes in last bank to fill
mov dh,dl ; DH := number of full banks to fill
mov ax,VGABufferSeg
mov es,ax
mov di,[OriginOffset] ; ES:DI -> video buffer
mov dl,[BYTE BankOffset]; DL := starting bank number
cld ; Moves go up in memory
or dh,dh ; More than one bank to fill?
jz @@SingleBank ; No, only fill a single bank
; Fill all of the full 64k banks first
@@OuterLoop:
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,4000h ; Need to set 4000h double words per bank
rep stosd
inc dl
dec dh
jnz @@OuterLoop
; Now fill the last partial bank
@@SingleBank:
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,bx
shr cx,2 ; CX := number of double words to set
rep stosd
pop di
ret
procend __clear256
;----------------------------------------------------------------------------
; void clear32k(void)
;----------------------------------------------------------------------------
; Routine to clear the screen. Assumes pages begin on bank boundaries
; for simplicity of coding.
;----------------------------------------------------------------------------
procstart __clear32k
push di
mov ax,[_maxy]
inc ax
mul [_bytesperline] ; DX:AX := number of bytes to fill
mov bx,ax ; BX := bytes in last bank to fill
mov dh,dl ; DH := number of full banks to fill
mov ax,VGABufferSeg
mov es,ax
mov di,[OriginOffset] ; ES:DI -> video buffer
mov dl,[BYTE BankOffset]; DL := starting bank number
cld ; Moves go up in memory
; Fill all of the full 64k banks first
@@OuterLoop:
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,4000h ; Need to set 4000h double words per bank
rep stosd
inc dl
dec dh
jnz @@OuterLoop
; Now fill the last partial bank
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,bx
shr cx,2 ; CX := number of double words to set
rep stosd
pop di
ret
procend __clear32k
;----------------------------------------------------------------------------
; void clear64k(void)
;----------------------------------------------------------------------------
; Routine to clear the screen. Assumes pages begin on bank boundaries
; for simplicity of coding.
;----------------------------------------------------------------------------
procstart __clear64k
push di
mov ax,[_maxy]
inc ax
mul [_bytesperline] ; DX:AX := number of bytes to fill
mov bx,ax ; BX := bytes in last bank to fill
mov dh,dl ; DH := number of full banks to fill
mov ax,VGABufferSeg
mov es,ax
mov di,[OriginOffset] ; ES:DI -> video buffer
mov dl,[BYTE BankOffset]; DL := starting bank number
cld ; Moves go up in memory
; Fill all of the full 64k banks first
@@OuterLoop:
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,4000h ; Need to set 4000h double words per bank
rep stosd
inc dl
dec dh
jnz @@OuterLoop
; Now fill the last partial bank
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,bx
shr cx,2 ; CX := number of double words to set
rep stosd
pop di
ret
procend __clear64k
;----------------------------------------------------------------------------
; void clear16m(void)
;----------------------------------------------------------------------------
; Routine to clear the screen. Assumes pages begin on bank boundaries
; for simplicity of coding.
;----------------------------------------------------------------------------
procstart __clear16m
push di
mov ax,[_maxy]
inc ax
mul [_bytesperline] ; DX:AX := number of bytes to fill
mov bx,ax ; BX := bytes in last bank to fill
mov dh,dl ; DH := number of full banks to fill
mov ax,VGABufferSeg
mov es,ax
xor di,di ; ES:DI -> video buffer
mov dl,[BYTE BankOffset]; DL := starting bank number
cld ; Moves go up in memory
; Fill all of the full 64k banks first
@@OuterLoop:
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,4000h ; Need to set 4000h double words per bank
rep stosd
inc dl
dec dh
jnz @@OuterLoop
; Now fill the last partial bank
mov al,dl
call setBank
xor eax,eax ; Clear to black
mov cx,bx
shr cx,2 ; CX := number of double words to set
rep stosd
pop di
ret
procend __clear16m
;----------------------------------------------------------------------------
; void _copyTest16(void)
;----------------------------------------------------------------------------
; Routine to copy the top half of video memory to the bottom half of
; video memory. To ensure that we a moving across a bank boundary in
; 16 color modes, we copy the data to the second video page.
;----------------------------------------------------------------------------
procstart __copyTest16
push si ; Save registers
push di
push ds
mov ax,[_maxy]
inc ax
shr ax,1 ; AX := (Yres+1) / 2
mul [_bytesperline]
mov cx,ax ; CX := Number of bytes to move
; Set up graphics controller
mov dx,3CEh ; DX := Graphics Controller address port
mov ax,0105h ; AH := 1 (read mode 0, write mode 1)
; AL := 5 (Mode register number)
out dx,ax ; Set up mode
mov di,[WORD _pagesize] ; ES:DI := offset into destination buffer
mov ax,[WORD _pagesize+2]
add di,cx
adc al,0
call setBank ; Set the read/write bank number
xor si,si ; DS:SI := offset into source buffer
xor ax,ax
call setReadBank ; Set the read bank number
mov ax,VGABufferSeg
mov ds,ax ; DS:SI -> source buffer
mov es,ax ; ES:DI -> destination buffer
cld ; Moves go up in memory
rep movsb ; Move all data in bank FAST!
; Restore default graphics controller state
mov ax,0005h ; default mode register value
out dx,ax
pop ds
pop di
pop si
ret
procend __copyTest16
;----------------------------------------------------------------------------
; void _copyTest256(void)
;----------------------------------------------------------------------------
; Routine to copy the top half of video memory to the bottom half of
; video memory, to test moving data across bank boundaries using separate
; read/write banks. To simplify the coding we move the first 100 scan
; lines down to start at scanline 205. This ensure allows us to move data
; from bank 0 to bank 2 in 640x??? display modes.
;----------------------------------------------------------------------------
procstart __copyTest256
push si ; Save registers
push di
push ds
mov ax,100
mul [_bytesperline]
mov cx,ax ; CX := Number of bytes to move
shr cx,1 ; CX := Number of words to move
mov ax,205
mul [_bytesperline]
mov di,ax ; DI := offset into destination bank
mov al,dl
call setBank ; Set the read/write bank number
xor si,si ; DS:SI := offset into source buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -