📄 svga.asm
字号:
xor al,al
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 movsw ; Move all data in bank FAST!
pop ds
pop di
pop si
ret
procend __copyTest256
;----------------------------------------------------------------------------
; void setActivePage(int which)
;----------------------------------------------------------------------------
; Routine to set the video page for active output.
;
; Entry: page - Page number of page to use
;
;----------------------------------------------------------------------------
procstart _setActivePage
ARG which:WORD
push bp ; Set up stack frame
mov bp,sp
; Calculate 18 bit address of page in video memory
xor eax,eax
mov ax,[which] ; EAX := page number
mul [_pagesize] ; EDX:EAX := result
mov [OriginOffset],ax ; Save video buffer offset
shr eax,16
mov [BankOffset],ax ; Save video bank offset
pop bp
ret
procend _setActivePage
;----------------------------------------------------------------------------
; void setVisualPage(int which)
;----------------------------------------------------------------------------
; Routine to set the visible video page.
;
; Entry: page - Page number of page to use
;
;----------------------------------------------------------------------------
procstart _setVisualPage
ARG which:WORD
push bp ; Set up stack frame
mov bp,sp
push si
; Calculate 18 bit address of page in video memory
xor eax,eax
mov ax,[which] ; EAX := page number
mul [_pagesize] ; EAX := starting address in memory
mov edx,eax
shr edx,16 ; DX:AX := starting address in memory
cmp [_extendedflipping],0
je @@VGAFlip ; We have no extended page flipping
cmp [WORD _pageFlip+2],0
je @@VBEFlip
; Set up to call the relocated version of the page flip routine loaded
; on the heap. This allows us to bypass the int10h interface for speed
; (well, not much different in real mode, but in protected mode this
; will be significant).
cmp [WORD _maxColor],15
je @@Colors16
shr eax,2 ; Adjust to lie on plane boundary
mov edx,eax
shr edx,16 ; DX:AX := starting address in memory
@@Colors16:
push dx ; Save top bits of address
; Wait for display enable to be active (active low), to be sure that
; both halves of the start address will take place in one frame. We
; preload a few values here to save time after the DE has been
; detected.
mov cl,0Ch ; CL := Start Address High register
mov ch,ah ; CH := high byte of new address
mov bh,al ; BH := low byte of new address
mov bl,0Dh ; BL := Start Address Low register
mov dx,03DAh ; DX := video status port
@@WaitDE:
in al,dx
test al,1
jnz @@WaitDE ; Wait for Display Enable
cli
pop si ; SI := Bits 16+ for SuperVGA's
call [_pageFlip] ; Program the start address
sti
jmp @@Done
@@VBEFlip:
div [_bytesperline] ; AX := starting scanline,
; DX := starting byte
mov cx,dx
cmp [WORD _maxcolor],0Fh
je @@16Color
cmp [WORD _maxcolor],0FFh
je @@SetIt
cmp [WORD _maxcolor+2],0FFh
je @@16MColor
shr cx,1 ; CX := starting pixel in buffer
jmp @@SetIt
@@16Color:
shl cx,3 ; CX := starting pixel in buffer
jmp @@SetIt
@@16MColor:
xor dx,dx
mov ax,cx
mov cx,3
div cx
mov cx,ax ; CX := starting pixel in buffer
@@SetIt:
mov bx,ax ; BX := starting scanline in buffer
; Wait for display enable to be active (active low), to be sure that
; both halves of the start address will take place in one frame.
mov dx,03DAh ; DX := video status port
@@WaitDEVBE:
in al,dx
test al,1
jnz @@WaitDEVBE ; Wait for Display Enable
mov ax,04F07h
mov dx,bx ; DX := starting scanline number
xor bx,bx ; BX := 0 - set display start
int 10h ; Set the display start address
jmp @@Done
@@VGAFlip:
mov bx,ax ; BX := bottom 16 bits of address
; Wait for display enable to be active (active low), to be sure that
; both halves of the start address will take place in one frame. We
; preload a few values here to save time after the DE has been
; detected.
mov cl,0Ch ; CL := Start Address High register
mov ch,bh ; CH := high byte of new address
mov bh,bl ; BH := low byte of new address
mov bl,0Dh ; BL := Start Address Low register
mov dx,03DAh ; DX := video status port
@@WaitDEVGA:
in al,dx
test al,1
jnz @@WaitDEVGA ; Wait for Display Enable
cli
mov dx,03D4h ; DX := CRTC I/O port (3D4h)
mov ax,bx
out dx,ax
mov ax,cx
out dx,ax
sti
; Now wait for the start of the vertical sync, to ensure that the old
; page will be invisible before anything is drawn on it.
@@Done:
mov dx,03DAh ; DX := video status port
@@WaitStartVert:
in al,dx ; Wait for start of vertical retrace
test al,8
jz @@WaitStartVert
@@Exit:
pop si
pop bp
ret
procend _setVisualPage
;----------------------------------------------------------------------------
; setBank Sets the read/write bank from assembly language
;----------------------------------------------------------------------------
;
; Entry: AX - New read/write bank number
;
; Exit: AX - New read/write bank number
;
; Registers: All preserved!
;
;----------------------------------------------------------------------------
procstart setBank
mov [_curBank],ax ; Save current write bank number
cmp [WORD _writeBank+2],0
je @@VESABank
call [_writeBank] ; Call relocated version
ret
@@VESABank:
push ax
push bx
push dx
mul [_bankAdjust] ; Adjust to VESA granularity
push ax
mov dx,ax ; DX := bank number
xor bx,bx ; BX := select window A
call [_bankSwitch] ; Set write window
; Note that some VESA BIOSes and TSR's set the first window to be
; write only and the second window to be read only, so we need to set both
; windows for most common operations to the same value. The Universal
; VESA VBE sets both the read and write banks to the same value for
; Window A, and changed the read bank only for Window B, hence the second
; call is _not_ required when the Universal VESA VBE is installed. You can
; determine what the window does by looking at the WindowAAttributes in
; the SuperVGAInfo block returned by function 00h. You could use this
; information to optimise bank switching when using faster VBE's like
; the Universal VESA VBE (but I have no bothered to do that here).
pop dx
inc bx
call [_bankSwitch] ; Set read window
pop dx
pop bx
pop ax
ret
procend setBank
;----------------------------------------------------------------------------
; setReadBank Sets the read bank from assembly language
;----------------------------------------------------------------------------
;
; Entry: AX - New read bank number
;
; Exit: AX - New read bank number
;
; Registers: All preserved!
;
;----------------------------------------------------------------------------
procstart setReadBank
mov [_curBank],-1 ; Ensure banking will be re-loaded
cmp [WORD _readBank+2],0
je @@VESABank
call [_readBank] ; Call relocated version
ret
@@VESABank:
push ax
push bx
push dx
mov dx,ax ; DX := bank number
mov bx,1 ; BX := select window B
call [_bankSwitch]
pop dx
pop bx
pop ax
ret
procend setReadBank
;----------------------------------------------------------------------------
; void setBank(int bank)
;----------------------------------------------------------------------------
; Sets the new read/write bank number from C
;----------------------------------------------------------------------------
procstart _setBank
ARG bank:WORD
push bp
mov bp,sp
mov ax,[bank]
call setBank
pop bp
ret
procend _setBank
;----------------------------------------------------------------------------
; void setReadBank(int bank)
;----------------------------------------------------------------------------
; Sets the new reading bank number from C
;----------------------------------------------------------------------------
procstart _setReadBank
ARG bank:WORD
push bp
mov bp,sp
mov ax,[bank]
call setReadBank
pop bp
ret
procend _setReadBank
;----------------------------------------------------------------------------
; void *getFontVec(void)
;----------------------------------------------------------------------------
; Gets a pointer to the currently installed bitmap font from the BIOS.
;----------------------------------------------------------------------------
procstart _getFontVec
push bp
mov ax,1130h
mov bx,0600h
int 10h
mov dx,es
mov ax,bp ; DX:AX -> installed font
pop bp
ret
procend _getFontVec
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -