;****************************************************************************
;*
;*                        The Universal VESA VBE
;*
;*                  Copyright (C) 1993 Kendall Bennett.
;*                          All rights reserved.
;*
;* Filename:    $RCSfile: _video7.asm $
;* Version:     $Revision: 1.2 $
;*
;* Language:    8086 Assembler
;* Environment: IBM PC (MS DOS)
;*
;* Description: Assembly language support routines for Video 7 SuperVGA's.
;*
;*              Contains code to perform initialisation, bank switching
;*              and extended page flipping if possible.
;*
;* $Id: _video7.asm 1.2 1993/09/24 05:23:45 kjb release $
;*
;* Revision History:
;* -----------------
;*
;* $Log: _video7.asm $
;* Revision 1.2  1993/09/24  05:23:45  kjb
;* Fixed a number of bugs.
;*
;* Revision 1.1  1993/09/19  01:27:05  kjb
;* Initial revision
;*
;****************************************************************************

grVIDEO7_V1         =   0       ; Video 7 version 1-4 chipsets
grVIDEO7_V5         =   1       ; Video 7 version 5 chipsets

;----------------------------------------------------------------------------
; VIDEO7V1_bank Change to a new 64k bank (reading and writing)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    VIDEO7V1_bank   far

		push    ax
        push    cx
        push    dx
        and     al,0Fh              ; Mask to 4 bits
        mov     ch,al
        mov     dx,3C4h
        mov     ah,ch
        and     ah,1
        mov     al,0F9h             ; Index of Extended Page Select register
        out     dx,ax               ; Program PS bit in register
        mov     al,ch
        and     al,1100b            ; Bits 3-2 for read field
        mov     ah,al
        shr     ah,2                ; Bits 1-0 for write field
        or      ah,al               ; Combine two values
        mov     al,0F6h
        out     dx,al               ; Index the bank select register
        inc     dl
        in      al,dx               ; Read old value
        and     al,11110000b        ; Zero out old bits
        or      al,ah               ; Combine with new values
        out     dx,al               ; Program the values
        mov     ah,ch
        and     ah,10b              ; Mask out bit 2
        shl     ah,4                ; Put into bit 5
        mov     dx,3CCh             ; Address Miscellaneous register
        in      al,dx               ; Read old value
        and     al,0DFh             ; Zero bit 5
        mov     dx,3C2h
        or      al,ah               ; Or in the page bit
        out     dx,al               ; Program the new value
        pop     dx
        pop     cx
        pop     ax
		ret

ENDP    VIDEO7V1_bank

VIDEO7V1_bank_len       =   ($-VIDEO7V1_bank)

;----------------------------------------------------------------------------
; VIDEO7V5_bank Change to a new 64k bank (reading and writing)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    VIDEO7V5_bank   far

		push    ax
        push    dx
        and     al,0Fh              ; Mask to 4 bits
        shl     al,4                ; Shift into bits 7-4
        mov     ah,al
        mov     dx,3C4h
        mov     al,0E8h             ; Index of write bank register
        out     dx,ax               ; Program the write bank
        mov     al,0E9h             ; Index of read bank register
        out     dx,ax               ; Program the read bank
        pop     dx
        pop     ax
		ret

ENDP    VIDEO7V5_bank

VIDEO7V5_bank_len       =   ($-VIDEO7V5_bank)

;----------------------------------------------------------------------------
; VIDEO7V5_rbank    Change to a new 64k read bank (reading only)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    VIDEO7V5_rbank  far

		push    ax
        push    dx
        and     al,0Fh              ; Mask to 4 bits
        shl     al,4                ; Shift into bits 7-4
        mov     ah,al
        mov     dx,3C4h
        mov     al,0E9h             ; Index of read bank register
        out     dx,al               ; Program the value
        pop     dx
        pop     ax
		ret

ENDP    VIDEO7V5_rbank

VIDEO7V5_rbank_len      =   ($-VIDEO7V5_rbank)

;----------------------------------------------------------------------------
; VIDEO7_page   Set the extended CRT starting address.
;----------------------------------------------------------------------------
;
; Entry:        BL  - Index of start address low register
;               BH  - Bits 7-0 of new start address
;               CL  - Index of start address high register
;               CH  - Bits 15-8 of new start address
;               SI  - Bits 16+ for new start address
;
; Registers:    AX,BX,CX,DX,SI
;
;----------------------------------------------------------------------------
PROC    VIDEO7_page far

        SetLowStartAddress
        mov     dx,3C4h
        mov     al,0F6h
        out     dx,al               ; Index extended start address
        inc     dx
        in      al,dx               ; Read current value
        and     al,0CFh             ; Zero out start address 17-16 bit 5-4
        and     bl,3                ; Mask out all but bottom 2 bits
        shl     bl,4                ; Shift left into correct position
        or      al,bl               ; Or in the new start address
        out     dx,al               ; Output the address
        ret

ENDP    VIDEO7_page

VIDEO7_page_len     =   ($-VIDEO7_page)

;----------------------------------------------------------------------------
; VIDEO7V1_setup    Setup the SuperVGA for correct operation
;----------------------------------------------------------------------------
PROC    VIDEO7V1_setup  near

        outp    3C4h, 6, 0EAh       ; Enable extended registers
        ret

ENDP    VIDEO7V1_setup

VIDEO7V1_setup_len  =   ($-VIDEO7V1_setup)

;----------------------------------------------------------------------------
; VIDEO7V5_setup    Setup the SuperVGA for correct operation
;----------------------------------------------------------------------------
PROC    VIDEO7V5_setup  near

        outp    3C4h, 6, 0EAh       ; Enable extended registers
        modinx  3C4h, 0E0h, 80h, 80h; Set split bank mode
        ret

ENDP    VIDEO7V5_setup

VIDEO7V5_setup_len  =   ($-VIDEO7V5_setup)

;----------------------------------------------------------------------------
; VIDEO7_exit   Return the SuperVGA to default operation
;----------------------------------------------------------------------------
PROC    VIDEO7_exit near

        outp    3C4h, 6, 0AEh       ; Disable extended registers
        modinx  3C4h, 0E0h, 80h, 0  ; Disable split bank mode
        ret

ENDP    VIDEO7_exit

VIDEO7_exit_len =   ($-VIDEO7_exit)

;----------------------------------------------------------------------------
; VIDEO7_init
;----------------------------------------------------------------------------
; We have a Video7 V7VGA SuperVGA, so set up vectors for this card.
;----------------------------------------------------------------------------
PROC    VIDEO7_init

; Setup the correct vectors to use the Video7 bank switching and paging
; routines. The version 5 chipsets support the dual banking mode.

        mov     [TwoBanks],false
        mov     [WriteBank16],offset VIDEO7V1_bank
        mov     [WriteBank16Len],VIDEO7V1_bank_len
        mov     [WriteBank256],offset VIDEO7V1_bank
        mov     [WriteBank256Len],VIDEO7V1_bank_len
		mov     [NewPage16],offset VIDEO7_page
		mov     [NewPage16Len],VIDEO7_page_len
		mov     [NewPage256],offset VIDEO7_page
        mov     [NewPage256Len],VIDEO7_page_len
		mov     [SetupSVGA],offset VIDEO7V1_setup
        mov     [SetupSVGALen],VIDEO7V1_setup_len
        mov     [ExitSVGA],offset VIDEO7_exit
        mov     [ExitSVGALen],VIDEO7_exit_len

        cmp     [CntChipID],grVIDEO7_V5
        jl      @@Exit

        mov     [TwoBanks],true
        mov     [WriteBank16],offset VIDEO7V5_bank
        mov     [WriteBank16Len],VIDEO7V5_bank_len
        mov     [WriteBank256],offset VIDEO7V5_bank
        mov     [WriteBank256Len],VIDEO7V5_bank_len
        mov     [ReadBank16],offset VIDEO7V5_rbank
        mov     [ReadBank16Len],VIDEO7V5_rbank_len
        mov     [ReadBank256],offset VIDEO7V5_rbank
        mov     [ReadBank256Len],VIDEO7V5_rbank_len
        mov     [SetupSVGA],offset VIDEO7V5_setup
        mov     [SetupSVGALen],VIDEO7V5_setup_len

@@Exit:
        ret

ENDP    VIDEO7_init
