;****************************************************************************
;*
;*                        The Universal VESA VBE
;*
;*                  Copyright (C) 1993 Kendall Bennett.
;*                          All rights reserved.
;*
;* Filename:    $RCSfile: _trident.asm $
;* Version:     $Revision: 1.3 $
;*
;* Language:    8086 Assembler
;* Environment: IBM PC (MS DOS)
;*
;* Description: Assembly language support routines for Trident SuperVGA's.
;*
;*              Contains code to perform initialisation, bank switching
;*              and extended page flipping if possible.
;*
;* $Id: _trident.asm 1.3 1993/09/24 05:23:45 kjb release $
;*
;* Revision History:
;* -----------------
;*
;* $Log: _trident.asm $
;* Revision 1.3  1993/09/24  05:23:45  kjb
;* Fixed a number of bugs.
;*
;* Revision 1.2  1993/09/23  03:30:56  kjb
;* Fixed bug in initialising the Trident mode.
;*
;* Revision 1.1  1993/09/19  01:27:05  kjb
;* Initial revision
;*
;****************************************************************************

grTRIDENT_8800CS    =   0   ; Trident 8800CS SuperVGA chip
grTRIDENT_8900      =   1   ; Trident 8900 SuperVGA chip
grTRIDENT_8900C     =   1   ; Trident 8900C SuperVGA chip
grTRIDENT_9000      =   3   ; Trident 9000 SuperVGA chip

;----------------------------------------------------------------------------
; TRIDENT_bank  Change to a new 64k bank (reading and writing)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    TRIDENT_bank    far

		push    ax
        push    dx
        xor     al,2                ; Adjust page bit
        mov     ah,al
        mov     dx,3C4h
        mov     al,0Bh              ; Index of Chip Version register
        out     dx,al               ; Program index
        inc     dl
        xor     al,al
        out     dx,al               ; Force old definitions
        in      al,dx               ; Force new definitions
        dec     dl
        mov     al,0Eh              ; Index of New Mode Control Reg
        out     dx,ax               ; Program the page value
        pop     dx
        pop     ax
		ret

ENDP    TRIDENT_bank

TRIDENT_bank_len    =   ($-TRIDENT_bank)

;----------------------------------------------------------------------------
; TRIDENT88_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    TRIDENT88_page  far

        SetLowStartAddress
        mov     dx,3D4h             ; DX := CRTC I/O port
        mov     al,01Eh
		out     dx,al               ; Index module testing register
        inc     dx
		in      al,dx               ; Read current value
        and     al,0DFh             ; Mask out start address bit 5
        and     bl,1                ; Only want one bit
        shl     bl,5                ; Put into correct position
        or      al,bl               ; Or in the new start address
        or      al,80h              ; Set bit 7 for enable bit 16
        out     dx,al               ; Output the address
        ret

ENDP    TRIDENT88_page

TRIDENT88_page_len  =   ($-TRIDENT88_page)

;----------------------------------------------------------------------------
; TRIDENT89_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    TRIDENT89_page  far

        SetLowStartAddress
        push    bx
        mov     dx,3D4h             ; DX := CRTC I/O port
        mov     al,01Eh
		out     dx,al               ; Index module testing register
        inc     dx
        in      al,dx               ; Read current value
        and     al,05Fh             ; Mask out start address
        and     bl,1                ; Only want one bit
        shl     bl,5                ; Put into correct position
        or      al,bl               ; Or in new start address values
        or      al,80h              ; Set bit 7 for enable bit 16
        out     dx,al               ; Output the address
        mov     dx,3C4h
        mov     al,0Bh
        out     dx,al
        inc     dl
		xor     al,al
        out     dx,al               ; Select old mode control registers
        dec     dl
        mov     al,0Eh              ; Index old mode control register
        out     dx,al
        inc     dl
        in      al,dx               ; Read old value
        and     al,0FEh             ; Mask out old value
        pop     bx
        shr     bl,1
        and     bl,1                ; Mask out only bit 17 of address
        or      al,bl               ; Combine with old value
        out     dx,al               ; Output the address
        ret

ENDP    TRIDENT89_page

TRIDENT89_page_len  =   ($-TRIDENT89_page)

;----------------------------------------------------------------------------
; TRIDENT89_setup   Setup the SuperVGA for correct operation
;----------------------------------------------------------------------------
PROC    TRIDENT89_setup near

        modinx  3CEh, 6, 4, 4       ; Set pagesize to 64k
		ret

ENDP    TRIDENT89_setup

TRIDENT89_setup_len =   ($-TRIDENT89_setup)

;----------------------------------------------------------------------------
; TRIDENT_init
;----------------------------------------------------------------------------
; We have a Trident 8800 or 8900 SuperVGA. Setup for a pagesize of 64k
; before doing bank switching.
;----------------------------------------------------------------------------
PROC    TRIDENT_init

        mov     [WriteBank16],offset TRIDENT_bank
        mov     [WriteBank16Len],TRIDENT_bank_len
        mov     [WriteBank256],offset TRIDENT_bank
        mov     [WriteBank256Len],TRIDENT_bank_len
		mov     [NewPage16],offset TRIDENT88_page
		mov     [NewPage16Len],TRIDENT88_page_len
		mov     [NewPage256],offset TRIDENT88_page
        mov     [NewPage256Len],TRIDENT88_page_len
		cmp     [CntChipID],grTRIDENT_8800CS
        je      @@Exit

		mov     [NewPage16],offset TRIDENT89_page
		mov     [NewPage16Len],TRIDENT89_page_len
		mov     [NewPage256],offset TRIDENT89_page
        mov     [NewPage256Len],TRIDENT89_page_len
		mov     [SetupSVGA],offset TRIDENT89_setup
        mov     [SetupSVGALen],TRIDENT89_setup_len

@@Exit:
        ret

ENDP    TRIDENT_init
