⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svga.asm

📁 VESA 图形编程的汇编子程序库
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        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 + -