;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
;       SCCSID = @(#)svgabank.asm       1.0 92/12/25
; ****************************************************************************
; *                                                                          *
; *                                                                          *
; *                                                                          *
; ****************************************************************************
        PAGE    58,132
        TITLE   Screen Device Driver - (svgabank.Asm)
        .286p                                                           ;@T30

;/***********************************************************************/
;/*                                                                     */
;/* SOURCE FILE NAME: svgabank.asm      STATUS: Version 1.1             */
;/*                                                                     */
;/* DESCRIPTIVE NAME:  Base Video Subsystem Screen Device Driver        */
;/*                                                                     */
;/* FUNCTION:   Provide SVGA bank routines, called by routines          */
;/*               GetSVGABank and                                       */
;/*               SetSVGABank                                           */
;/*                                                                     */
;/* NOTES:  Executes on Level 0                                         */
;/*                                                                     */
;/* ENTRY POINT:                                                        */
;/*   LINKAGE: Far Call                                                 */
;/*                                                                     */
;/* INPUT:  ES:BX = request packet address                              */
;/*       DS = BIODATA                                                  */
;/*                                                                     */
;/* EXIT-NORMAL:                                                        */
;/*                                                                     */
;/* EFFECTS:  None                                                      */
;/*                                                                     */
;/*   ROUTINES:                                                         */
;/*                                                                     */
;/************************ END OF SPECIFICATIONS ************************/
.xlist
        INCLUDE basemaca.inc            ;;;;;; 2.0 unique (dosmac replacement)
        INCLUDE DOSHLP.INC              ;          
        INCLUDE devhlp.inc              ; Define DevHlp functions
        INCLUDE devsym.inc              ; Define DOS equates
        INCLUDE error.inc               ; Define Error Messages
        INCLUDE ioctl.inc               ; Define IOCTL equates ;@@B
        INCLUDE struc.inc               ; Define STRUC macros
;        include iodelay.inc             ;          
.list

BioData SEGMENT WORD PUBLIC 'DATA'
        ASSUME  DS:BioData

; STACK FRAME for bank routines: to hold local variables
; Arguments are passed thru registers.
SaveIndex       EQU   <[bp-2]>          ;WORD
TempVar         EQU   <[bp-4]>          ;WORD
WriteBank       EQU   <[bp-4]>          ;WORD
TempFlag        EQU   <[bp-6]>          ;WORD
TempBank        EQU   <[bp-6]>          ;WORD
ReadBank        EQU   <[bp-6]>          ;WORD
CurrentBank     EQU   <[bp-8]>          ;WORD
VideoMode       EQU   <[bp-10]>         ;WORD
Direction       EQU   <[bp-11]>         ;BYTE
LockedState     EQU   <[bp-12]>         ;BYTE
STACK_BLOCK     EQU   11

READ_BANK               EQU    0H
WRITE_BANK              EQU    1H
MODE_TEXT               EQU    0H
MODE_PLANAR             EQU    1H
MODE_LINEAR             EQU    2H

SEQ_LOCKED              EQU    1H
GDC_LOCKED              EQU    2H
RETURN_SVGA_INFORMATION STRUC                   ;matches OEMSVGAINFO (bvhsvga)
        AdapterType     DW      0
        ChipType        DW      0
        Memory          DD      0100000H        ;no of bytes video RAM (1MB)
RETURN_SVGA_INFORMATION ENDS

        EXTRN SVGAInfo  : WORD
        EXTRN XGAInstance: WORD       ; XGA instance for Speedway
BioData ENDS
BiosSeg SEGMENT WORD Public 'CODE'
        ASSUME  CS:BiosSeg

PUBLIC  NOPSetBank
PUBLIC  Video7SetBank
PUBLIC  TridentSetBank
PUBLIC  TsengSetBank
PUBLIC  WDSetBank
PUBLIC  ATISetBank
PUBLIC  IBMSetBank
PUBLIC  CirrusSetBank
PUBLIC  S3SetBank                     ;             ;          
PUBLIC  NOPGetBank
PUBLIC  Video7GetBank
PUBLIC  TridentGetBank
PUBLIC  TsengGetBank
PUBLIC  WDGetBank
PUBLIC  ATIGetBank
PUBLIC  IBMGetBank
PUBLIC  CirrusGetBank
PUBLIC  S3GetBank                     ;             ;          

;/****************************************************************************
;*
;* FUNCTION NAME = NOPSetBank
;*
;* DESCRIPTION   = Set bank. No error checking or indication.
;*
;* INPUT         = CX Bank, DX Direction and DI video mode
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
NOPSetBank      PROC    NEAR
                ret
NOPSetBank      ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = Video7SetBank
;*
;* DESCRIPTION   = Set bank. No error checking or indication.
;*
;* INPUT         = CX Bank, DX Direction and DI video mode
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;*     We have two scenarios here, one for the HT205 chip
;*     (Version 3) and another for HT208/HT209 (Version 4/5)
;*     chips.
;*
;*     Version 4/5 are easy, a single register is dedicated to
;*     selecting the read bank and another to the write bank.
;*     The chip should first be set into single bank mode before
;*     setting these registers.
;*
;*     Version 3 chips are a nightmare.  There are different
;*     registers to be set according to whether the mode is
;*     16/256 colour and also for read/write bank selection.
;*
;****************************************************************************/
Video7SetBank   PROC    NEAR
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK                  ; reserve for the local variables.

                mov     Direction, dl                   ;set the direction
                mov     VideoMode, di                   ;set the mode
                mov     CurrentBank, cx                 ;set the bank

                mov     dx, 3c4H
                in      al, dx
                mov     SaveIndex, ax                    ; save the sequencer index
                mov     al, 6                            ; lock register
                out     dx, al
                inc     dx
                in      al, dx
                mov     BYTE PTR LockedState, al        ; if 1 it is unlocked
                .if     < al  e 0>                      ; unlock it
                        mov     al, 0eaH
                        out     dx, al
                .endif
                mov     al, BYTE PTR VideoMode
                .if <al eq MODE_PLANAR>
                        mov     ax, 0f6H                 ; get contents of Bank select
                        out     dx, al
                        inc     dx
                        in      al,dx
                        and     al, 0f0H                ; reset bites 0,1 for write and 2,3 for read
                        mov     BYTE PTR TempVar, al
                        mov     ax, WORD PTR CurrentBank; Bank to be set
                        and     ax, 1
                        mov     cx, ax
                        shl     al, 2                   ; set  read=write bank
                        or      al, BYTE PTR TempVar    ; for write and 2,3 for read
                        or      al, cl                  ; cl = bBank
                        out     dx, al                  ; dx = 3c5H
                        jmp     Video7EndSetBank
                .endif                                   ;other than planar mode
                .if  <SVGAInfo.ChipType eq 1>    ;HT_205
                        mov     ax, 0f9H
                        mov     dx, 3c4H
                        out     dx, al
                        mov     ax, WORD PTR CurrentBank
                        and     ax, 1             ; get first bit of the bank
                        inc     dx
                        out     dx, al
                        mov     dx, 3ccH
                        in      al, dx
                        and     al, 0dfH            ; clear bit 5 of misc.
                        mov     BYTE PTR TempVar, al
                        mov     ax, WORD PTR CurrentBank ; Bank that needs to be set.
                        and     ax, 2              ; move second bit into bit 5
                        shl     al, 4
                        or      al, BYTE PTR TempVar
                        mov     dx, 3c2H
                        out     dx, al             ; write new Misc Output reg value
                        mov     ax, 3c4H
                        mov     dx, 0f6h
                        out     dx, al
                        inc     dx
                        in      al,dx                ; get current value of the bank select
                        mov     BYTE PTR TempVar, al
                        mov     ax, WORD PTR CurrentBank
                        mov     BYTE PTR TempBank, al
                        mov     al, BYTE PTR Direction
                        .if  < al eq WRITE_BANK>
                                and     BYTE PTR TempVar, 0fcH ; clear bits 0,1
                                mov     al, BYTE PTR TempBank
                                shr     al, 2
                                and     al, 03H
                                mov     BYTE PTR TempBank, al ; isolate bits 0,1
                        .else
                                and     BYTE PTR TempVar, 0F3H ; clear bits 2,3
                                and     BYTE PTR TempBank, 0cH ; isolate bits 2,3
                        .endif
                        mov     al, BYTE PTR TempVar
                        or      al, BYTE PTR TempBank
                        mov     dx, 3c5H
                        out     dx, ax
                .else                           ; HT_208 and HT_209
                        mov     ax, 0E0H
                        mov     dx, 3C4H
                        out     dx, al          ; miscel. control
                        inc     dx
                        in      al,dx
                        and     al, 7FH
                        mov     BYTE PTR TempVar, al
                        out     dx, al          ; set single bank mode
                        mov     ax, WORD PTR CurrentBank
                        shl     al, 4
                        mov     BYTE PTR TempBank, al
                        mov     al, BYTE PTR VideoMode
                        .if <al eq MODE_TEXT>
                                or      BYTE PTR TempBank, 20H
                        .endif
                        mov     al, 0e8H         ; write bank select registers
                        mov     dx, 3c4H
                        out     dx, al
                        mov     al, BYTE PTR TempBank
                        inc     dx
                        out     dx, al
                        mov     cx, ax           ; preserve the bank
                        mov     al, 0e9H         ; read bank select reg
                        mov     dx, 3C4H
                        out     dx, al
                        mov     ax, cx
                        inc     dx
                        out     dx, al
                .endif
Video7EndSetBank:
                mov     BYTE PTR LockedState, al        ; if 1 it is unlocked
                .if     < al  e 0>                      ; lock it back
                        mov     dx, 3c4H
                        mov     al, 6
                        out     dx, al
                        inc     dx
                        mov     al, 0aeH
                .endif
                mov     al, BYTE PTR SaveIndex
                mov     dx, 3c4H
                out     dx, al

                mov     sp, bp
                pop     bp
                ret
Video7SetBank   ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = TridentSetBank
;*
;* DESCRIPTION   = Set bank. No error checking or indication.
;*
;*                 Register 0bh at port 3c4h (Hardware Version Register) is
;*                 read-only.
;*
;*                 BUT, By writing to the register the Mode Control
;*                      registers will assume their 'old' definitions.
;*                      Reading the register causes the Mode Control
;*                      registers to assume 'new' definitions.  The
;*                      register's previous state therefore can't be
;*                      restored.  All we need in a multi-tasking
;*                      environment......  Note also that Page bit (bit 1)
;*                      is inverted when setting the write bank and doesn't
;*                      read back as written.
;*
;*                 Mode Control registers 1 & 2 are at 3c4/5 index
;*                 0Dh and 0Eh.
;*
;*                 Write operations require bit 1 (Page Select) to be
;*                 inverted.
;*
;* INPUT         = CX Bank, DX Direction and DI video mode
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
TridentSetBank  PROC    NEAR
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK
                mov     Direction, dl                   ;set the direction
                mov     VideoMode, di                   ;set the mode
                mov     CurrentBank, cx                     ;set the bank

                .if <di b MODE_PLANAR>                  ;only grafix modes handled
                        jmp  ExitTrident
                .endif
                mov     dx, 3ceH
                in      al,dx
                mov     BYTE PTR TempVar, al            ; TempVar = GDC index
                mov     ax, 6
                out     dx, al
                inc     dx
                in      al,dx
                test    al, 8
                .if     <z>                            ; exit if A0000 not referenced
                        mov     dx, 3c4H
                        in      al,dx
                        mov     BYTE PTR SaveIndex, al
                        call    GETTRIDENTREGDEF      ; this destroys ax, dx, cx.
                        push    ax                      ;save the result AX=1 new mode.

                        mov     al, 6
                        mov     dx, 3ceH
                        out     dx, al

                        mov     al, 5
                        inc     dx                      ; memory addressing mode to 64K
                        out     dx, al

                        mov     ax, 0bH
                        mov     dx, 3c4H
                        out     dx, al

                        inc     dx
                        in      al,dx                   ; this changes mode control to new definition.

                        mov     al, 0eH
                        mov     dx, 3c4H
                        out     dx, al                  ; select mode ctrl #1 register

                        mov     al, BYTE PTR CurrentBank
                        xor     al, 2                   ; invert page bit
                        inc     dx
                        out     dx, al                  ; set the bank

                        pop     ax                      ; restore the reg definition
                        .if     <ax   e  0>             ; is definition old?
                                mov     ax, 0bH
                                mov     dx, 3c4H
                                out     dx, al

                                mov     ax, 1
                                inc     dx
                                out     dx, al          ; restore old definition
                        .endif
                        mov     al, BYTE PTR SaveIndex
                        mov     dx, 3c4H
                        out     dx, al

                .endif
                mov     al, BYTE PTR TempVar
                mov     dx, 3ceH
                out     dx, al
ExitTrident:
                mov     sp, bp
                pop     bp
                ret
TridentSetBank  ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = TsengSetBank
;*
;* DESCRIPTION   = Set bank. No error checking or indication.
;*
;* INPUT         = CX Bank, DX Direction and DI video mode
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
TsengSetBank    PROC    NEAR
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK

                and     cx, 0Fh                 ;prevent overrun in Bank
                mov     ax, cx
                mov     BYTE PTR WriteBank, al
                shl     al, 3
                mov     BYTE PTR ReadBank, al
                mov     cx, SVGAInfo.ChipType
                .if     <cx eq 2>               ; adjust for ET4000
                        shl     BYTE PTR ReadBank, 1
                .endif
                mov     al, BYTE PTR WriteBank
                or      al, BYTE PTR ReadBank
                mov     dx, 3cdH
                out     dx, al

                mov     sp, bp
                pop     bp
                ret
TsengSetBank    ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = WDSetBank
;*
;* DESCRIPTION   = Set bank. No error checking or indication.
;*
;* INPUT         = CX Bank, DX Direction and DI video mode
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
WDSetBank       PROC    NEAR
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK
                mov     Direction, dl           ;set the direction
                mov     VideoMode, di           ;set the mode
                mov     CurrentBank, cx         ;set the bank

                mov     dx, 3c4h
                in      al, dx
                mov     SaveIndex, al
                                                ;unlock the extension regs
                xor     ah, ah
                mov     BYTE PTR LockedState, ah
                mov     al, 12H
                out     dx, al
                in      al, dx                  ;seq reads as 3 bits if locked
                .if     <al ne 12H>             ;unlock the sequencers
                        mov     al, 06H
                        out     dx, al
                        inc     dx
                        mov     al, 48H
                        out     dx, al
                        or      BYTE PTR LockedState, SEQ_LOCKED
                .endif
                mov     dx, 3ceH
                in      al, dx
                push    ax                      ;save GDC index

                mov     al, 0fH                 ;are GDC's locked?
                out     dx, al
                inc     dx
                in      al, dx
                and     al, 5
                .if     <al ne 5>               ;GDC's locked
                        mov     al, 5H
                        out     dx, al
                        or      BYTE PTR LockedState, GDC_LOCKED
                .endif
                mov     ax, 11H
                mov     dx, 3ceH
                out     dx, al                  ;Fix System Interface reg
                inc     dx
                in      al,dx
                and     al, 7fH                 ;clear bit 7
                mov     WORD PTR TempVar, ax
                out     dx, al                  ;restore reg

                mov     ax, 0bH
                mov     dx, 3ceH
                out     dx, al                  ;fix memory size reg

                inc     dx
                in      al, dx
                and     ax, 0f7H                ;clear bit 3
                mov     WORD PTR TempVar, ax
                out     dx, al

                mov     ax, WORD PTR CurrentBank
                shl     ax, 4
                mov     WORD PTR TempBank, ax
                mov     ax, 9                   ;write PROA offset index
                mov     dx, 3ceH
                out     dx, al
                mov     ax, WORD PTR TempBank
                inc     dx
                out     dx, al                  ;set the bank

                mov     al, BYTE PTR LockedState; restore lock state if necessery
                .if     <al ne  0>
                        test    al, GDC_LOCKED
                        jz      LockSeq
                        mov     al, 0fH         ;lock GDC
                        mov     dx, 3ceH
                        out     dx, al
                        inc     dx
                        xor     al, al
                        out     dx, al
                        test    BYTE PTR LockedState, SEQ_LOCKED
                        jz      short @F
                LockSeq:
                        mov     al, 6H
                        mov     dx, 3c4H
                        out     dx, al
                        inc     dx
                        xor     al, al
                        out     dx, al          ;load with 0 will lock it
                .endif

@@:             pop     ax                      ;restore GDC index
                mov     dx, 3ceH
                out     dx, al

                mov     ax, SaveIndex           ;restore sequencer index
                mov     dx, 3c4H
                out     dx, al

                mov     sp, bp
                pop     bp
                ret
WDSetBank       ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = ATISetBank
;*
;* DESCRIPTION   = Set bank. No error checking or indication.
;*
;* INPUT         = CX Bank, DX Direction and DI video mode
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
ATISetBank      PROC    NEAR
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK
                mov     Direction, dl           ;set the direction
                mov     VideoMode, di           ;set the mode
                mov     CurrentBank, cx         ;set the bank

                mov     ax, 0beH
                mov     dx, 1ceH
                out     dx, al                  ;Miscellaneous register

                inc     dx
                in      al,dx
                mov     BYTE PTR TempVar, al
                mov     ax, 0beH
                mov     dx, 1ceH
                out     dx, al                  ;set for single bank mode

                mov     al, BYTE PTR TempVar
                and     al, 0f7H                ;clear bit 3
                inc     dx
                out     dx, al

                mov     ax, 0b2H                ;set back single page mode
                mov     dx, 1ceH
                out     dx, al                  ;memory page select

                inc     dx
                in      al,dx
                and     al, 0e1H                ;isolate bank select bits (4-1)
                mov     BYTE PTR TempVar, al
                mov     al, BYTE PTR CurrentBank
                shl     al, 1
                or      al, BYTE PTR TempVar
                mov     BYTE PTR TempBank, al

                mov     ax, 0b2H
                mov     dx, 1ceH
                out     dx, al
                mov     al, BYTE PTR TempBank
                inc     dx
                out     dx, al                  ;set the bank

                mov     sp, bp
                pop     bp
                ret
ATISetBank      ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = IBMSetBank
;*
;* DESCRIPTION   = Set bank. No error checking or indication.
;*
;* INPUT         = CX Bank, DX Direction and DI video mode
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
IBMSetBank      PROC    NEAR
                mov     ax, cx                  ;set the bank

                mov     dx, WORD PTR XGAInstance
                add     dx, 8                   ;offset register
                out     dx, al

                ret
IBMSetBank      ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = CirrusSetBank
;*
;* DESCRIPTION   = Set bank. No error checking or indication.
;*
;* INPUT         = CX Bank, DX Direction and DI video mode
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
CirrusSetBank   PROC    NEAR
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK

                mov     Direction, dl           ;set the direction
                mov     VideoMode, di           ;set the mode
                mov     CurrentBank, cx         ;set the bank

                mov     dx, 3ceH
                in      al,dx
                mov     BYTE PTR SaveIndex, al
                                                ;save seq index and unlock if nec.
                mov     dx, 3c4H
                in      al,dx
                push    ax                      ;save index
                mov     ax, 6
                out     dx, al
                inc     dx
                in      al, dx
                .if     <al ne 12H>
                        mov     BYTE PTR LockedState, 1
                        mov     al, 12
                        out     dx, al
                .endif

                mov     al, 9
                mov     dx, 3ceH
                out     dx, al
                inc     dx
                in      al,dx
                and     al, 0fH
                mov     cl, BYTE PTR CurrentBank
                shl     cl, 4
                or      al, cl
                out     dx, al                  ;set the bank
                                                ;restore the lock state
                mov     al, BYTE PTR LockedState
                .if     <al ne 12H>
                        mov     ax, 06H
                        mov     dx, 3c4H
                        out     dx, al
                        inc     dx
                        mov     al, 0fH
                        out     dx, al
                .endif
                pop     ax                      ;restore SEQ index
                mov     dx, 3c4H
                out     dx, al

                mov     al, BYTE PTR SaveIndex
                mov     dx, 3ceH
                out     dx, al

                mov     sp, bp
                pop     bp
                ret
CirrusSetBank   ENDP

;/****************************************************************************
;*
;* FUNCTION NAME = S3SetBank                                   
;*
;* DESCRIPTION   = Set bank. No error checking or indication.
;*
;* INPUT         = CX Bank, DX Direction and DI video mode
;* OUTPUT        = NONE
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
S3SetBank       PROC    NEAR                       ;           
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK

                mov     dx, 3d4h
                in      al, dx
                mov     BYTE PTR SaveIndex, al

                and     cx, 3Fh                 ;prevent overrun in Bank.
                mov     ah, cl                  ; supports up to 4 MB
                and     ah, 0fh
                mov     al, 35h
                mov     dx, 3d4h
                out     dx, ax
                and     cl, 30h                 ;get bits 4,5
                shr     cl, 2                   ;bits 4,5 of the bank into bits 2,3
                mov     al, 51h
                out     dx, al

                inc     dl
                in      al, dx
                and     al, 0F3h                ;clear bits 2,3
                or      al, cl                  ;set the extended bank bits
                out     dx, al                  ;write it

                mov     al, BYTE PTR SaveIndex
                mov     dx, 3d4h
                out     dx, al

                mov     sp, bp
                pop     bp
                ret
S3SetBank       ENDP

;/****************************************************************************  ;          
;*
;* FUNCTION NAME = NOPGetBank
;*
;* DESCRIPTION   = Get bank. No error checking or indication.
;*
;* INPUT         = DX Direction and DI video mode
;* OUTPUT        = AX Bank
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
NOPGetBank      PROC    NEAR
                mov     ax,0
                ret
NOPGetBank      ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = Video7GetBank
;*
;* DESCRIPTION   = Get bank. No error checking or indication.
;*
;* INPUT         = DX Direction and DI video mode
;* OUTPUT        = AX Bank
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
Video7GetBank   PROC    NEAR
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK
                mov     Direction, dl           ;set the direction
                mov     VideoMode, di           ;set the mode

                mov     dx, 3c4H
                in      al, dx
                mov     SaveIndex, ax           ; save the sequencer index
                mov     al, 6                   ; lock register
                out     dx, al
                inc     dx
                in      al, dx
                mov     BYTE PTR LockedState, al; if 1 it is unlocked
                .if     < al  e 0>              ; unlock it
                        mov     al, 0eaH
                        out     dx, al
                .endif
                                                ; chipset specific
                .if     <SVGAInfo.ChipType be 2>; HT205 or HT208
                        mov     al, BYTE PTR VideoMode
                        .if     <al e MODE_PLANAR>
                                mov     al, 0f6H
                                out     dx, al
                                inc     dx
                                in      al, dx  ; read bank select register
                                xor     ah, ah
                                mov     WORD PTR CurrentBank, ax
                                mov     al, Direction
                                .if     <al ne  WRITE_BANK>
                                        shr WORD PTR CurrentBank, 2     ;read bank bits are 2-3
                                .endif
                                 and WORD PTR CurrentBank, 3            ; isolate the bits
                        .else                   ; 256 color bank select
                                mov     al, 0f9H
                                mov     dx, 03c4H
                                out     dx, al
                                inc     dx
                                in      al, dx          ; read extended page select register
                                and     ax, 1           ; get first bit
                                mov     WORD PTR CurrentBank, ax
                                                        ; bit 5 in Misc. Output Reg is bit
                                mov     dx, 3ccH
                                in      al, dx
                                and     al, 20H
                                shr     al, 4
                                or      BYTE PTR CurrentBank, al
                                mov     al, 0f6H
                                mov     dx, 03c4H
                                out     dx, al
                                inc     dx
                                in      al, dx          ; read bank select register
                                xor     ah, ah
                                mov     WORD PTR TempBank, ax
                                mov     al, Direction
                                .if     <al e  WRITE_BANK>
                                        shl WORD PTR TempBank, 2     ;read bank bits are 2-3
                                .endif
                                and     BYTE PTR TempBank, 0cH   ; isolate bits 2-3
                                mov     ax, WORD PTR TempBank
                                or      WORD PTR CurrentBank, ax
                        .endif
                .else
                .if     <SVGAInfo.ChipType e 3>                ; HT 209 chip
                        mov     al, Direction
                        .if     <al e  WRITE_BANK>
                                mov     al, 0e8H                ;write bank sel
                                mov     dx, 03c4H
                                out     dx, al
                        .else
                                mov     al, 0e9H                ;read bank sel
                                mov     dx, 03c4H
                                out     dx, al
                        .endif
                        inc     dx
                        in      al, dx          ; get bank
                        xor     ah, ah
                        shr     ax, 4           ; 
                        mov     WORD PTR CurrentBank, ax
                        mov     al, BYTE PTR VideoMode
                        .if <al b MODE_PLANAR>   ;text mode, bit 1 must be reset
                                and     WORD PTR CurrentBank, 0fdH
                        .endif
                .endif
                .endif
                mov     BYTE PTR LockedState, al        ; if 1 it is unlocked
                .if     < al  e 0>                      ; lock it back
                        mov     dx, 3c4H
                        mov     al, 6
                        out     dx, al
                        inc     dx
                        mov     al, 0aeH
                .endif
                mov     dx, 3c4H
                mov     al, BYTE PTR SaveIndex
                out     dx, al                          ; restore the index
                mov     ax, WORD PTR CurrentBank        ; return the bank
                and     ax, 0fH

                mov     sp, bp
                pop     bp
                ret
Video7GetBank   ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = TridentGetBank
;*
;* DESCRIPTION   = Get bank. No error checking or indication.
;*
;* INPUT         = DX Direction and DI video mode
;* OUTPUT        = AX Bank
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
TridentGetBank  PROC    NEAR
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK
                mov     Direction, dl           ;set the direction
                mov     VideoMode, di           ;set the mode

                mov     WORD PTR CurrentBank, 0
                cmp     BYTE PTR VideoMode, MODE_PLANAR
                .if <ge>                        ;we process only graphic modes
                        mov     dx, 3c4H
                        in      al,dx
                        mov     BYTE PTR SaveIndex, al
                        call    GETTRIDENTREGDEF
                        mov     WORD PTR TempFlag, ax   ; TempFlag=TRUE is new definition, 0 old
                        mov     ax, 0bH
                        mov     dx, 3c4H
                        out     dx, al
                        inc     dx
                        in      al,dx           ; mode ctrl reg changed to new def
                        mov     al, 0eH
                        mov     dx, 3c4H
                        out     dx, al          ; select mode ctrl reg #1
                        inc     dx
                        in      al, dx
                        xor     ah, ah
                        mov     WORD PTR CurrentBank, ax
                        cmp     WORD PTR TempFlag, 0
                        .if <e>
                                mov     ax, 0bH ;restore old def
                                mov     dx, 3c4H
                                out     dx, al
                                inc     dx
                                mov     ax, 1
                                out     dx, al
                        .endif
                        mov     al, BYTE PTR SaveIndex
                        mov     dx, 3c4H
                        out     dx, al          ;restore seq index
                .endif
                mov     ax, WORD PTR CurrentBank
                and     ax, 0fH

                mov     sp, bp
                pop     bp
                ret
TridentGetBank  ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = TsengGetBank
;*
;* DESCRIPTION   = Get bank. No error checking or indication.
;*
;* INPUT         = DX Direction and DI video mode
;* OUTPUT        = AX Bank
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
TsengGetBank    PROC    NEAR

                mov     dx, 3cdH
                in      ax, dx                  ;read bank select register

                mov     cx, SVGAInfo.ChipType
                .if     <cx eq 2>               ;on ET4000 bits 0-3 write bank
                        and     ax, 0fH
                .else                           ;on ET3000 bits 0-2 write bank
                        and     ax, 07H
                .endif

                ret
TsengGetBank    ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = WDGetBank
;*
;* DESCRIPTION   = Get bank. No error checking or indication.
;*
;* INPUT         = DX Direction and DI video mode
;* OUTPUT        = AX Bank
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
WDGetBank       PROC    NEAR

                mov     dx, 3ceH
                in      ax, dx
                push    ax              ;save current index

                mov     al, 0fH         ; are GDC's locked?
                out     dx, al
                inc     dx
                in      al, dx
                and     al, 5
                push    ax              ; lock state
                .if     <al ne 5>       ; GDC's locked
                        mov     al, 5H
                        out     dx, al
                .endif

                mov     ax, 9
                mov     dx, 3ceH
                out     dx, al
                inc     dx
                in      al,dx           ; read bank select reg
                shr     al, 4
                mov     cx, ax          ; save the value

                pop     ax              ; restore the lock state
                .if     <al ne 5>       ; GDC's were locked
                        mov     ax, 0fH         ; lock GDC
                        mov     dx, 3ceH
                        out     dx, al
                        inc     dx
                        xor     al, al
                        out     dx, al
                .endif
                pop     ax              ; restore the index
                mov     dx, 3ceH
                out     dx, al
                mov     ax, cx          ; return the current bank

                ret
WDGetBank       ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = ATIGetBank
;*
;* DESCRIPTION   = Get bank. No error checking or indication.
;*
;* INPUT         = DX Direction and DI video mode
;* OUTPUT        = AX Bank
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
ATIGetBank      PROC    NEAR
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK
                mov     Direction, dl                   ;set the direction


                mov     ax, 0beH
                mov     dx, 1ceH
                out     dx, al                  ;miselc register

                inc     dx
                in      al,dx
                mov     WORD PTR TempBank, ax  ; get current contents

                mov     ax, 0b2H
                mov     dx, 01ceH
                out     dx, al                  ; memory page select

                inc     dx
                in      al,dx
                test    BYTE PTR TempBank, 8    ; if bit set, dual page mode
                .if <ne>
                        cmp     BYTE PTR Direction, WRITE_BANK
                        .if     <e>
                                shr     ax, 1
                        .else
                                shr     ax, 5
                        .endif
                .else                           ; single bank mode
                        shr     ax, 1
                .endif
                and     ax, 0fH

                mov     sp, bp
                pop     bp
                ret
ATIGetBank      ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = IBMGetBank
;*
;* DESCRIPTION   = Get bank. No error checking or indication.
;*
;* INPUT         = DX Direction and DI video mode
;* OUTPUT        = AX Bank
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
IBMGetBank      PROC    NEAR
                mov     dx, XGAInstance
                add     dx, 8           ; aperture index reg
                in      ax, dx          ; return current index value
                ret
IBMGetBank      ENDP
;/****************************************************************************
;*
;* FUNCTION NAME = CirrusGetBank
;*
;* DESCRIPTION   = Get bank. No error checking or indication.
;*
;* INPUT         = DX Direction and DI video mode
;* OUTPUT        = AX Bank
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
CirrusGetBank   PROC    NEAR
                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK
                mov     Direction, dl                   ;set the direction
                mov     VideoMode, di                   ;set the mode

                mov     dx, 3ceH
                in      al,dx
                mov     SaveIndex, ax
                                                        ; save seq index and unlock if nec.
                mov     dx, 3c4H
                in      al, dx
                push    ax                              ; save index
                mov     ax, 06H                         ; is it unlocked
                out     dx, al
                inc     dx
                in      al, dx
                .if     <al ne 12H>
                        mov     BYTE PTR LockedState, 1
                        mov     al, 12H
                        out     dx, al
                .endif

                mov     ax, 0BH                                 ;Mode extn register
                mov     dx, 3ceH
                out     dx, al
                inc     dx
                in      al,dx
                mov     BYTE PTR TempVar, al                    ; TempVar holds offset reg selected
                test    al, 20H
                je      short @F
                .if <SVGAInfo.ChipType eq 3 >                   ;if CIRRUS_GD5426
                        mov     BYTE PTR TempFlag, 1            ;TempFlag = 1 for 2 MB addressing
                .else
@@:
                        mov     BYTE PTR TempFlag, 0            ;TempFlag = 0 for 1 MB addressing
                .endif                                          ;handle 2 MB addressing before return.
                and     BYTE PTR TempVar, 1
                add     BYTE PTR TempVar, 9                     ; Offset reg 0 is at index 9, 1 at 10
                mov     al, BYTE PTR TempVar
                mov     dx, 3ceH
                out     dx, al                                  ; address the offset reg
                inc     dx
                in      al,dx
                mov     WORD PTR CurrentBank, ax                ; Current bank value

                                        ;restore the lock state
                mov     al, BYTE PTR LockedState
                .if     <al ne 12H>
                        mov     ax, 06H
                        mov     dx, 3c4H
                        out     dx, al
                        inc     dx
                        mov     al, 0fH
                        out     dx, al
                .endif
                pop     ax              ; restore SEQ index
                mov     dx, 3c4H
                out     dx, al

                mov     ax, WORD PTR SaveIndex                  ; restore the index
                mov     dx, 3ceH
                out     dx, al

                mov     al, BYTE PTR TempFlag
                .if <al eq 1>                                   ; 2 MB addressing
                        mov     ax, WORD PTR CurrentBank
                        and     ax, 7fh
                        shr     ax, 2
                .else
                        mov     ax, WORD PTR CurrentBank
                        shr     ax, 4
                .endif

                mov     sp, bp
                pop     bp
                ret
CirrusGetBank   ENDP


;/****************************************************************************
;*
;* FUNCTION NAME = S3GetBank                                   
;*
;* DESCRIPTION   = Get bank. No error checking or indication.
;*
;* INPUT         = DX Direction and DI video mode
;* OUTPUT        = AX Bank
;*
;* RETURN-NORMAL = NONE.
;* RETURN-ERROR  = NONE
;*
;****************************************************************************/
S3GetBank       PROC    NEAR                       ;           

                push    bp
                mov     bp,sp
                sub     sp,STACK_BLOCK

                mov     dx, 3d4H
                in      al,dx
                mov     SaveIndex, ax

                mov     al, 35h
                out     dx, al
                inc     dx
                in      al, dx                  ;read bank select register

                and     ax, 0fH
                mov     ah, al                  ;save in ah

                dec     dx
                mov     al, 51h
                out     dx, al
                inc     dx
                in      al, dx                  ;read ext system cntl reg

                test    al, 4
                je      short @F
                mov     al, 10h
                or      al, ah
                jmp     short finish

@@:
                mov     al, ah                  ;use non-extended reg value
finish:
                xor     ah, ah
                mov     WORD PTR CurrentBank, ax        ; Current bank value
                mov     ax, WORD PTR SaveIndex          ; restore the index
                mov     dx, 3d4H
                out     dx, al
                mov     ax, WORD PTR CurrentBank

                mov     sp, bp
                pop     bp
                ret

S3GetBank       ENDP

;/***************************************************************************  ;          
;*
;* FUNCTION NAME = GetTridentRegDef
;*
;* DESCRIPTION   = Return the current definition of the extended sequencer
;*                 registers.
;*
;* INPUT         = None
;*
;* OUTPUT        = AX = TRUE  - registers are in 'new' mode
;*                     = FALSE - registers are in 'old' mode
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

GetTridentRegDef      PROC      NEAR

                mov     dx, 3c4H
                cli
                in      al, dx
                mov     ah, al          ;save index
                mov     al, 0eh         ; 
                out     dx, al          ;select Mode Control Reg 1
                inc     dx              ; 
                in      al, dx          ;get current contents
                mov     cl, al          ; 
                out     dx, al          ;write out again
                in      al, dx          ;get contents
                out     dx, al          ;guarantee the same
                xor     ch, ch          ; 
                cmp     al, cl          ;reverse page bit ?
                jne     GetDefNew       ; 
                dec     dx              ; 
                mov     al, 0bh         ;read version => set 64K mode
                out     dx, al          ; 
                inc     dx              ; 
                in      al, dx          ; 
                jmp     short GetDefDone
GetDefNew:
                inc     ch              ; 
GetDefDone:
                dec     dx              ; 
                mov     al, ah          ; 
                out     dx, al          ; 

                mov     dl, 0cch        ; 
                in      al, dx          ; 

                mov     ah, al          ; 
                mov     dl, 0c2h        ; 
                or      al, 20h         ;select low page memory
                out     dx, al          ;set Misc Output

                sti                     ; 
                xor     ah, ah          ; 
                mov     al, ch          ;1 if new, 0 if old.

                ret
GetTridentRegDef         ENDP
BiosSeg ends
             end
;           12/28/92 SVGA support. File created.
;           06/04/94 F69306 Add support for S3
;           11/01/93 D75458 Merge r206v, r205, r206, r207 S3 code.
