;*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.;
;*****************************************************************************/
;/*****************************************************************************
;*
;* SOURCE FILE NAME = BANK.INC
;*
;* DESCRIPTIVE NAME = Device specific bank selection code
;*
;*
;* VERSION      V2.0
;*
;* DATE         02/01/90
;*
;* DESCRIPTION  Device specific bank selection code
;*
;* FUNCTIONS    NONE
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   01/15/93              59385  Add Cirrus Logic support.
;*
;*****************************************************************************/

.DATA

EXTERNDEF       spdway_reg:WORD


bank_switch_rtns        dd      0
                        dd      offset video7_bank_switch_rtn
                        dd      offset trident_bank_switch_rtn
                        dd      offset tseng_bank_switch_rtn
                        dd      offset wd_bank_switch_rtn
                        dd      offset ati_bank_switch_rtn
                        dd      offset spdway_bank_switch_rtn
                        dd      offset cirrus_bank_switch_rtn   ;           

set_bank_select         dd      tseng_bank_switch_rtn

.CODE


;/*
;**       Set A000:0000 to point to a specific bank of 64K
;**
;**       Entry:  DL = bank select
;**       Exit:   none
;*/

public  far_bank_select

far_bank_select proc    far

        call    set_bank_select
        ret

far_bank_select endp



video7_bank_switch_rtn proc near
;/*
;**
;**       Assume: VRAM VGA in extended 256 color mode
;**               Extensions are enabled
;**
;*/
        push    ax
        push    dx
        shl     dl,4
        mov     ah,dl
        mov     dx,03c4h
        mov     al,0e8h
        out     dx,ax
        pop     dx
        pop     ax
        ret
video7_bank_switch_rtn  endp


wd_bank_switch_rtn proc near
        push    ax              ; 
        push    dx              ; 

        mov     ah,dl           ; 
        shl     ah,4            ;Move to upper nibble for 64k chunk.
        mov     dx,03Ceh        ; 
        mov     al,9
        out     dx,ax

        pop     dx              ; 
        pop     ax              ; 
        ret                     ; 
wd_bank_switch_rtn      endp

ati_bank_switch_rtn proc near
        push    ax
        push    dx
        mov     dh,dl
        shl     dh,4
        rol     dh,1
        shl     dl,1
        or      dh,dl
        mov     ah,dh
        mov     dx,01ceh
        mov     al,0b2h
        out     dx,ax
        pop     dx              ; 
        pop     ax              ; 
        ret                     ; 

ati_bank_switch_rtn     endp

trident_bank_switch_rtn proc near
        push    ax
        push    dx

        Mov       ah, dl
        Mov       DX, 03C4H
        Mov       AL, 0EH
        Out       DX, AL
        Inc       DX
        In        AL, DX
        And       AL, 0F0H
        Or        AL, ah
        Xor       AL, 2
        Out       DX, AL
        pop     dx
        pop     ax
        ret
trident_bank_switch_rtn endp

spdway_bank_switch_rtn proc near
        push    ax
        push    dx
        mov     al,dl
        mov     dx,spdway_reg
        out     dx,al
        pop     dx
        pop     ax
        ret
spdway_bank_switch_rtn  endp


tseng_bank_switch_rtn proc near
        push    ax
        push    dx
        mov     al,dl           ; 
        shl     al,4            ;Move to upper nibble for read segment.
        or      al,dl           ;Or in lower nibble for write segment.
        mov     dx,03CDh        ; 
        out     dx,al           ; 
        pop     dx              ; 
        pop     ax              ; 
        ret                     ; 
tseng_bank_switch_rtn endp

; start           
cirrus_bank_switch_rtn proc near

        push    ax              ; 
        push    dx              ; 

        mov     ah,dl           ; 
        shl     ah,4            ;Move to upper nibble for 64k chunk.
        mov     dx,03Ceh        ; 
        mov     al,9
        out     dx,ax

        pop     dx              ; 
        pop     ax              ; 
        ret                     ; 

cirrus_bank_switch_rtn endp
; end           


ifndef  one_window
        public  set_rw_bank
ifdef cross_seg
        public  inc_rwseg
        public  far_inc_rwseg, far_dec_rwseg
endif   ;cross_seg
endif   ;one_window


ifndef  one_window
ifdef cross_seg

inc_rwseg       proc    near

;/*
;** note: if set_bank_select tests a variable to decide whether changed
;** or not, update it
;*/

        push    ax
        push    dx
ifdef   ATI
        mov     dx,ATIRegister
        mov     al,0b2h
        out    dx,al
        inc     dx
        in      al,dx
        mov     ah,al
        and     ax,0e11eh
        add     al,2
        ror     ah,1
        add     ah,10h
        rol     ah,1
        and     ax,0e11eh
        or      ah,al
        dec     dx
        mov     al,0b2h
        out     dx,ax
else
ifdef   AHEAD
        mov     dx,3ceh
        mov     al,0dh
        out     dx,al
        inc     dx
        in      al,dx
        mov     ah,al
        inc     ah
        add     al,010h
        and     ax,0FF0h
        or      al,ah
        out     dx,al
else
        mov     dx,03CDh
        in      al,dx
        mov     ah,al
        inc     ah
        add     al,010h
        and     ax,0FF0h
        or      al,ah
        out     dx,al
endif   ;AHEAD
endif
        pop     dx
        pop     ax
        ret
inc_rwseg       endp

far_inc_rwseg   proc    far
        call    inc_rwseg
        ret
far_inc_rwseg   endp

far_dec_rwseg   proc    far
        push    ax
        push    dx
ifdef   ATI
        mov     dx,ATIRegister
        mov     al,0b2h
        out     dx,al
        inc     dx
        in      al,dx
        mov     ah,al
        and     ax,0e11eh
        sub     al,2
        ror     ah,1
        sub     ah,10h
        rol     ah,1
        and     ax,0e11eh
        or      ah,al
        dec     dx
        mov     al,0b2h
        out     dx,ax
else
ifdef   AHEAD
        mov     dx,3ceh
        mov     al,0dh
        out     dx,al
        inc     dx
        in      al,dx
        mov     ah,al
        dec     ah
        sub     al,010h
        and     ax,0FF0h
        or      al,ah
        out     dx,al
else
        mov     dx,03CDh
        in      al,dx
        mov     ah,al
        dec     ah
        sub     al,010h
        and     ax,0FF0h
        or      al,ah
        out     dx,al
endif   ;AHEAD
endif
        pop     dx
        pop     ax
        ret
far_dec_rwseg   endp

endif ;cross_seg

set_rw_bank     proc
        push    ax
        push    dx
ifdef   ATI
        shl     dh,4
        rol     dh,1
        shl     dl,1
        or      dh,dl
        mov     ah,dh
        mov     dx,ATIRegister
        mov     al,0b2h
        out     dx,ax
else
ifdef   AHEAD
        xchg    dl,dh
        shl     dh,4
        or      dh,dl
        mov     ah,dh
        mov     dx,3ceh
        mov     al,0dh
        out     dx,ax
else
        mov     al,dh
        shl     al,4
        or      al,dl
        mov     dx,03CDh
        out     dx,al
endif   ;AHEAD
endif
        pop     dx
        pop     ax
        ret
set_rw_bank     endp
endif   ;one_window

