home *** CD-ROM | disk | FTP | other *** search
- ;****************************************************************************
- ;*
- ;* MegaGraph Graphics Library
- ;*
- ;* Copyright (C) 1993 Kendall Bennett.
- ;* All rights reserved.
- ;*
- ;* Filename: $RCSfile: sv_banks.asm $
- ;* Version: $Revision: 1.2 $
- ;*
- ;* Language: 80386 Assembler
- ;* Environment: IBM PC (MS DOS)
- ;*
- ;* Description: This source file contains the code needed to change banks
- ;* on supported SuperVGA adapters, along with tables to find
- ;* the correct routines for a specified video card.
- ;*
- ;* The code in here originally appeared in John Bridges
- ;* VGAKIT library, and has been modified to work with the
- ;* MGL. Specifically support for individually setting the
- ;* read and write banks has been included, along with adapter
- ;* initialisation code (such as accessing extended registers
- ;* etc).
- ;*
- ;* To set up separate read/write banks, you must first call
- ;* NewBank to set the read/write banks to the same value,
- ;* then call ReadBank to change the read bank value.
- ;*
- ;* $Id: sv_banks.asm 1.2 1993/03/07 04:05:36 kjb Exp $
- ;*
- ;* Revision History:
- ;* -----------------
- ;*
- ;* $Log: sv_banks.asm $
- ;* Revision 1.2 1993/03/07 04:05:36 kjb
- ;* Bug fixes.
- ;*
- ;* Revision 1.1 1993/03/03 10:26:52 kjb
- ;* Initial revision
- ;*
- ;****************************************************************************
-
- ; Table of SuperVGA bank switching routines by video card.
-
- SVGAInfoTable:
- dw false, VESA_bank, VESA_bank, VESA_init, NONE_exit
- dw true, ATI_bank, ATI_rbank, ATI_init, NONE_exit
- dw false, AHEADA_bank, AHEADA_bank, AHEAD_init, AHEAD_exit
- dw true, AHEADB_bank, AHEADB_rbank, AHEAD_init, AHEAD_exit
- dw false, CHIPS451_bank, CHIPS451_bank, CHIPS_init, CHIPS_exit
- dw false, EVEREX_bank, EVEREX_bank, EVEREX_init, NONE_exit
- dw true, GENOA_bank, GENOA_rbank, NONE_init, NONE_exit
- dw true, OAK_bank, OAK_rbank, NONE_init, NONE_exit
- dw true, PARADISE_bank, PARADISE_rbank, PARADISE_init, PARADISE_exit
- dw false, TRIDENT_bank, TRIDENT_bank, TRIDENT_init, NONE_exit
- dw false, TRIDENT_bank, TRIDENT_bank, TRIDENT_init, NONE_exit
- dw true, VIDEO7V5_bank, VIDEO7V5_rbank, VIDEO7_init, VIDEO7_exit
- dw true, ET3000_bank, ET3000_rbank, NONE_init, NONE_exit
- dw true, ET4000_bank, ET4000_rbank, ET4000_init, NONE_exit
- dw true, NCR_bank, NCR_rbank, NCR_init, NONE_exit
- dw false, S3_bank, S3_bank, S3_init, NONE_exit
- dw false, ACUMOS_bank, ACUMOS_bank, ACUMOS_init, ACUMOS_exit
- dw false, AL2101_bank, AL2101_bank, AL2101_init, NONE_exit
- dw true, MXIC_bank, MXIC_rbank, MXIC_init, MXIC_exit
- dw true, P2000_bank, P2000_rbank, NONE_init, NONE_exit
- dw true, RT3106_bank, RT3106_rbank, RT3106_init, NONE_exit
- dw false, CIRRUS_bank, CIRRUS_bank, CIRRUS_init, CIRRUS_exit
-
- SVGAInfo:
- TwoBanks dw 0 ; Flags if two banks available
- NewBank dw NONE_bank ; Address of read/write bank switch routine
- ReadBank dw NONE_bank ; Address of read bank routine
- InitSVGA dw NONE_init ; Address of card Init routine
- ExitSVGA dw NONE_exit ; Address of card close routine
- SVGAInfoSize = ($-SVGAInfo) ; Size of the above table
-
- CurBank dw 0FFh ; Currently active read/write bank
- VesaGran db 0 ; VESA Granularity
- VesaBank dd 0 ; Address of VESA bank switch routine
- VesaBuf db 256 dup (?) ; Place to store VESA Info
-
- VesaModes: dw 100h, grSVGA_640x400x256
- dw 101h, grSVGA_640x480x256
- dw 102h, grSVGA_800x600x16
- dw 103h, grSVGA_800x600x256
- dw 104h, grSVGA_1024x768x16
- dw 105h, grSVGA_1024x768x256
- dw 106h, grSVGA_1280x1024x16
- dw 107h, grSVGA_1280x1024x256
- dw 10Dh, grSVGA_320x200x32k
- dw 10Fh, grSVGA_320x200x16m
- dw 110h, grSVGA_640x480x32k
- dw 112h, grSVGA_640x480x16m
- dw 113h, grSVGA_800x600x32k
- dw 115h, grSVGA_800x600x16m
- dw 116h, grSVGA_1024x768x32k
- dw 118h, grSVGA_1024x768x16m
- dw 119h, grSVGA_1280x1024x32k
- dw 11Bh, grSVGA_1280x1024x16m
- dw 0
-
- ;----------------------------------------------------------------------------
- ; SetupBanks Setup the SuperVGA bank switching routines
- ;----------------------------------------------------------------------------
- ;
- ; Given the id of the SuperVGA card that is installed, this routine sets
- ; up the following bank switching code.
- ;
- ; Registers: AX,CX,SI,DI
- ;
- ;----------------------------------------------------------------------------
- PROC SetupBanks near
-
- mov [ReadBank],offset NONE_bank
- mov [InitSVGA],offset NONE_init
- mov ax,[CntDriver]
- cmp ax,grSVGA
- jl @@Exit ; Not a SuperVGA adapter
-
- mov si,offset SVGAInfoTable
- mov ax,[CntDriver] ; AX := number of current driver
- sub ax,grSVGA ; Adjust to start at 0 for SVGA's
- mov cx,SVGAInfoSize
- mul cx
- add si,ax ; SI := index into table of SVGA banks
- mov di,offset SVGAInfo
- push cs
- pop es
- rep movs [BYTE es:di],[BYTE es:si]
-
- @@Exit:
- mov [CurBank],0FFh ; Set the bank to nothing to start with
- ret
-
- ENDP SetupBanks
-
- ;----------------------------------------------------------------------------
- ; NewBank Change to a new 64k bank on a SuperVGA card (reading and writing)
- ;----------------------------------------------------------------------------
- ;
- ; Changes to a new 64k bank given the specified index. The global variable
- ; CurBank is updated to reflect the current bank number and can be used
- ; to avoid unnecessary bank switching.
- ;
- ; These routines should set both the read and write bank for cards that
- ; support multiple banks to the same bank number.
- ;
- ; Note that the value of all regs MUST be preserved across this call.
- ;
- ; Entry: AX - Number of 64k bank (0-15 for 1Mb cards)
- ;
- ; Registers: None.
- ;
- ;----------------------------------------------------------------------------
-
- NONE_bank:
- ret
-
- VESA_bank:
- mov [CurBank],ax ; Save the new bank number for later
- push ax
- push bx
- push dx
- mul [VesaGran] ; Adjust with granularity factor
- push ax
- mov dx,ax ; Select window position
- xor bx,bx ; BH := 0 (Select SVGA memory window)
- ; BL := 0 (window to set)
- call [VesaBank] ; Change bank A
- pop dx ; Select window position
- inc bx ; BL := 1 (window to set)
- call [VesaBank] ; Change bank B
- pop dx
- pop bx
- pop ax
- ret
-
- ATI_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- and al,0Fh ; Mask out bottom four bits
- mov ah,al
- shl ah,4 ; Shift read bank into position
- or ah,al ; AH := combined read/write register numbers
- rol ah,1 ; Shift banks numbers in position
- mov dx,1CEh ; Port of extended registers
- mov al,0B2h
- out dx,ax ; Set the ATI Bank Register
- pop dx
- pop ax
- sti
- ret
-
- AHEADA_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- push cx
- mov ch,al
- mov dx,03CCh ; bit 0 in bit 5 of Misc Output reg
- in al,dx ; Read Misc output register
- mov dl,0C2h
- and al,11011111b
- shr ch,1 ; Need to set the bit?
- jnc @@SkpA ; No, so skip it
- or al,00100000b
- @@SkpA: out dx,al ; Set the new value
- mov dx,3CEh ; bits 3-1 in bits 2-0 of Segment Reg
- mov al,0Dh ; Index 0Dh for segment reg
- mov ah,ch ; ch contains top three bits shr 1
- out dx,ax ; Set the new value
- pop cx
- pop dx
- pop ax
- sti
- ret
-
- AHEADB_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov ah,al ; Combine read/write bank numbers
- shl ah,4
- or ah,al
- mov al,0Dh ; Index of Bank Switch register
- mov dx,3CEh
- out dx,ax ; Set the register
- pop dx
- pop ax
- sti
- ret
-
- CHIPS451_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov ah,al
- mov al,0Bh ; Index of Single/Low Map register
- mov dx,3D6h
- out dx,ax ; Set the register value
- pop dx
- pop ax
- sti
- ret
-
- CHIPS452_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov ah,al
- shl ah,2 ; Change 64k bank into 16k bank number
- mov al,10h ; Index of Single/Low Map register
- mov dx,3D6h
- out dx,ax ; Set the register value
- pop dx
- pop ax
- sti
- ret
-
- CHIPS453_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov ah,al
- shl ah,4 ; Change 64k bank into 4k bank number
- mov al,10h ; Index of Single/Low Map register
- mov dx,3D6h
- out dx,ax ; Set the register value
- pop dx
- pop ax
- sti
- ret
-
- EVEREX_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- push cx
- mov cl,al
- mov dx,3C4h
- mov al,8
- out dx,al
- inc dl
- in al,dx
- dec dl
- shl al,1
- shr cl,1
- rcr al,1
- mov ah,al
- mov al,8
- out dx,ax ; Bit 0 stored in 3C4 index 8 bit 7
- mov dl,0CCh
- in al,dx
- mov dl,0C2h
- and al,0DFh
- shr cl,1
- jc @@Nob2
- or al,20h
- @@Nob2: out dx,al ; Bit 1 stored in 3C2 bit 5
- pop cx
- pop dx
- pop ax
- sti
- ret
-
- GENOA_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov ah,al ; Put read bank in bits 2-0 ...
- shl al,3 ; ... write bank in bits 5-3
- or ah,al
- or ah,40h ; Set MEM bit
- mov al,6 ; Index of Memory Segment Register
- mov dx,3C4h
- out dx,ax ; Set the read/write banks
- pop dx
- pop ax
- sti
- ret
-
- OAK_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- and al,15
- mov ah,al ; Combine read/write bank numbers
- shl al,4
- or ah,al
- mov al,11h ; Index of bank switch register
- mov dx,3DEh
- out dx,ax ; Set the register value
- pop dx
- pop ax
- sti
- ret
-
- PARADISEPVGA_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov dx,3CEh
- shl al,4 ; change 64k bank into 4k bank number
- mov ah,al
- mov al,9 ; Index of PROA register
- out dx,ax ; Program PROA register
- pop dx
- pop ax
- sti
- ret
-
- PARADISE_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov dx,3CEh
- shl al,4 ; change 64k bank into 4k bank number
- mov ah,al
- mov al,9 ; Index of PROA register (read bank)
- out dx,ax ; Program PROA register
- mov al,0Ah ; Index of PROB register (write bank)
- out dx,ax ; Program PROB register
- pop dx
- pop ax
- sti
- ret
-
- TRIDENT_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- 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
- sti
- ret
-
- NCR_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- shl al,2 ; Change 64k bank into 16k bank number
- cmp [CntColors],gr16Color
- jne @@NCR1
- shl al,2 ; Change 64k bank into 4k bank number
- @@NCR1: mov ah,al
- mov al,18h
- mov dx,3C4h
- out dx,ax ; Set write bank number
- mov al,1Ch
- out dx,ax ; Set read bank number
- pop dx
- pop ax
- sti
- ret
-
- VIDEO7_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- 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
- sti
- ret
-
- VIDEO7V5_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- 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
- sti
- ret
-
- ET3000_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- and al,7 ; Mask out bottom 3 bits
- mov ah,al ; Combine read and write bank values in al
- shl ah,3
- or al,ah
- or al,40h ; Set bit 6 to select 64k segments
- mov dx,3CDh ; Point to memory segment register
- out dx,al ; Set the new bank value
- pop dx
- pop ax
- sti
- ret
-
- ET4000_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- and al,0Fh ; Mask out bottom 4 bits
- mov ah,al ; Combine read and write values in al
- shl ah,4
- or al,ah
- mov dx,3CDh ; Point to memory segment register
- out dx,al ; Set the new bank value
- pop dx
- pop ax
- sti
- ret
-
- S3_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push cx
- push dx
- mov dx,3D4h
- cmp [CntColors],gr16Color
- jne @@S31
- shl al,2 ; bank = bank * 4 in 16 color modes
- @@S31: and al,0Fh ; Mask off all but bottom 4 bits
- mov cl,al
- mov ax,4838h ; Enable extended registers
- out dx,ax
- mov al,31h ; Index of S3R1
- out dx,al
- inc dl
- in al,dx ; Read value of S3R1
- or al,9 ; Set bits 0 and 3
- or al,1001b
- out dx,al ; Write value back again
- dec dl
- mov al,35h ; Index of S3R5
- out dx,al
- inc dl
- in al,dx ; Read value of S3R5
- and al,0F0h ; Mask off low nybble
- or al,cl ; Or in new bank number
- out dx,al ; Write the value back again
- dec dl
- mov ax,0038h ; Disable extended registers
- out dx,ax
- pop dx
- pop cx
- pop ax
- sti
- ret
-
- CIRRUS_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov dx,3CEh
- shl al,4 ; Convert to 4k bank number
- mov ah,al
- mov al,9
- out dx,ax
- pop dx
- pop ax
- sti
- ret
-
- ACUMOS_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov dx,3CEh
- shl al,4 ; Convert to 4k bank number
- mov ah,al
- mov al,9
- out dx,ax
- pop dx
- pop ax
- sti
- ret
-
- AL2101_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov dx,3D6h
- out dx,al ; Set read bank register
- inc dx
- out dx,al ; Set write bank
- pop dx
- pop ax
- sti
- ret
-
- MXIC_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- and al,0Fh ; Mask out all but 4 bottom bits
- mov ah,al ; Combine read/write bank numbers
- shl al,4
- or ah,al
- mov al,0C5h ; Index of bank switch register
- mov dx,3C4h
- out dx,ax ; Set the register value
- pop dx
- pop ax
- sti
- ret
-
- P2000_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov dx,3D6h
- out dx,al ; Set write bank register
- inc dx
- out dx,al ; Set read bank
- pop dx
- pop ax
- sti
- ret
-
- RT3106_bank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov dx,3D6h
- out dx,al ; Set write bank register
- inc dx
- out dx,al ; Set read bank
- pop dx
- pop ax
- sti
- ret
-
- ;----------------------------------------------------------------------------
- ; ReadBank Change to a new 64k read bank on a SuperVGA card
- ;----------------------------------------------------------------------------
- ;
- ; Changes to a new 64k bank for reading given the specified index. The write
- ; bank should be preserved across this call.We also trash the value in
- ; CurBank to indicate that bank switching needs to be done again to set
- ; the read and write banks to the same value.
- ;
- ; Note that the value of all regs MUST be preserved across this call.
- ;
- ; Entry: AX - Number of 64k bank (0-15 for 1Mb cards)
- ;
- ; Registers: None.
- ;
- ;----------------------------------------------------------------------------
-
- VESA_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- push ax
- push bx
- push dx
- mul [VesaGran] ; Adjust with granularity factor
- mov dx,ax ; Select window position
- xor bh,bh ; BH := 0 (Select SVGA memory window)
- mov bl,1 ; Window to set
- call [VesaBank] ; Change bank
- pop dx
- pop bx
- pop ax
- ret
-
- ATI_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- and al,0Fh ; Mask out bottom four bits
- rol al,5 ; Shift read bank into position
- mov ah,al
- mov dx,1CEh ; Port of extended registers
- mov al,0B2h
- out dx,al ; Index ATI bank register
- inc dl
- in al,dx
- and al,01Eh ; Zero out bits 7-5 and bit 0
- or ah,al ; AL := combined value
- mov al,0B2h
- out dx,ax ; Ouput the new value
- pop dx
- pop ax
- sti
- ret
-
- AHEADB_rbank:
- mov [CurBank],ax ; Save the new bank number for later
- cli
- push ax
- push dx
- mov ah,al ; Read bank number in bits 3-0
- mov al,0Dh ; Index of Bank Switch register
- mov dx,3CEh
- out dx,al
- inc dl
- in al,dx ; Read old register value
- and al,0F0h ; Mask out bits 3-0
- or al,ah ; Combine with new value
- out dx,al ; Set the new register value
- pop dx
- pop ax
- sti
- ret
-
- GENOA_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- and al,7 ; Mask out bottom three bits
- mov ah,al
- mov dx,3C4h
- mov al,6 ; Index of Memory Segment Register
- out dx,al ; Output index
- inc dl
- in al,dx ; Read current value
- and al,0F8h ; Zero bits 2-0
- or al,ah ; Or in new value
- out dx,al ; Output the new bank
- pop dx
- pop ax
- sti
- ret
-
- OAK_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- and al,15
- mov ah,al ; AH := read bank number
- mov al,11h ; Index of bank switch register
- mov dx,3DEh
- out dx,al
- inc dl
- in al,dx ; Read old value
- and al,0F0h ; Mask out read bank value
- or al,ah ; Or in new value
- out dx,al ; Program the new value
- pop dx
- pop ax
- sti
- ret
-
- PARADISE_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- mov dx,3CEh
- shl al,4 ; change 64k bank into 4k bank number
- mov ah,al
- mov al,09h ; Index of PROA register (read bank)
- out dx,ax ; Program PROA register
- pop dx
- pop ax
- sti
- ret
-
- NCR_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- shl al,2 ; Change 64k bank into 16k bank number
- cmp [CntColors],gr16Color
- jne @@NCR2
- shl al,2 ; Change 64k bank into 4k bank number
- @@NCR2: mov ah,al
- mov al,1Ch
- mov dx,3C4h
- out dx,ax ; Set read bank number
- pop dx
- pop ax
- sti
- ret
-
- VIDEO7V5_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- 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
- sti
- ret
-
- ET3000_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- mov ah,bl ; Save value of bl
- and al,7 ; Mask out bottom 3 bits
- shl al,3 ; Shift into position
- mov bl,al
- mov dx,3CDh
- in al,dx ; Read current value
- and al,0C7h ; Mask out read bank select value
- or al,bl ; Or in the new read bank value
- out dx,al ; Set the new bank value
- mov bl,ah ; Restore value of bl
- pop dx
- pop ax
- sti
- ret
-
- ET4000_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- mov ah,bl ; Save value of bl
- and al,0Fh ; Mask out bottom 4 bits
- shl al,4 ; Shift into position
- mov bl,al
- mov dx,3CDh
- in al,dx ; Read current value
- and al,00Fh ; Mask out read bank select bits 7-4
- or al,bl ; Or in the new read bank value
- out dx,al ; Set the new bank value
- mov bl,ah ; Restore value of bl
- pop dx
- pop ax
- sti
- ret
-
- AL2101_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- mov dx,3D6h
- out dx,al ; Set read bank register
- pop ax
- pop dx
- sti
- ret
-
- MXIC_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- and al,0Fh ; Mask out all but 4 bottom bits
- shl al,4
- mov ah,al
- mov al,0C5h ; Index of bank switch register
- mov dx,3C4h
- out dx,al
- inc dx
- in al,dx ; Read old value
- and al,0Fh ; Mask out old read bank values
- or al,ah
- out dx,al ; Set the register value
- pop dx
- pop ax
- sti
- ret
-
- P2000_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- mov dx,3D7h
- out dx,al ; Set read bank
- pop dx
- pop ax
- sti
- ret
-
- RT3106_rbank:
- mov [CurBank],0FFh ; Trash CurBank with invalid value
- cli
- push ax
- push dx
- mov dx,3D6h
- out dx,al ; Set read bank register
- pop ax
- pop dx
- sti
- ret
-
- ;----------------------------------------------------------------------------
- ; InitBank Initialise the SuperVGA card for bank switching if required
- ;----------------------------------------------------------------------------
- ;
- ; Peforms any initialisations required by the SuperVGA card prior to bank
- ; switching (accessing extended registers, setting the mode etc).
- ;
- ; Note: All register may be used without concern for saving their values
- ;
- ; Registers: All.
- ;
- ;----------------------------------------------------------------------------
-
- PROC NONE_init near
- ret
- ENDP NONE_init
-
- ;----------------------------------------------------------------------------
- ; VESA_init
- ;----------------------------------------------------------------------------
- ; We have a VESA SuperVGA adapter, so determine the granularity and address
- ; of the VESA bank switching routine. We simply determine whether we are
- ; in 16 or 256 color video modes, and get information about these modes.
- ;----------------------------------------------------------------------------
- PROC VESA_init near
-
- push cs
- pop es
- mov di,offset VesaBuf ; ES:DI -> Buffer for VESA info
- mov bx,[CntMode]
- mov si,offset VesaModes ; CS:SI -> Table of VESA video modes
-
- mov cx,102h ; 800 x 600 16 color
- cmp bx,grVGA_640x480x16
- jle @@NonVESA
- mov cx,101h ; 640 x 480 256 color
- cmp bx,grVGA_320x200x256
- je @@NonVESA
-
- @@ModeLoop:
- lods [WORD cs:si]
- mov cx,ax ; CX := VESA Mode Number
- jcxz @@Exit ; Fall through if no match
- lods [WORD cs:si]
- cmp ax,bx
- jne @@ModeLoop
-
- mov ax,4F01h
- int 10h ; Call the video BIOS to get info
-
- mov ax,[CntMode]
- mov bx,[WORD VesaBuf+16]
- call setBytesPerLine
- mov [BytesPerLine],bx
- jmp @@SaveValues
-
- @@NonVESA:
- mov ax,4F01h
- int 10h
-
- @@SaveValues:
- mov ax,[WORD VesaBuf+12]; Save pointer to bank switching routine
- mov [WORD VesaBank],ax
- mov ax,[WORD VesaBuf+14]
- mov [WORD VesaBank+2],ax
-
- mov cx,[WORD VesaBuf+4] ; Load VESA granularity value
- mov al,1
- cmp cx,0 ; Some BIOS'S fuck this up!
- je @@NoDivide
- mov ax,64
- div cl
- @@NoDivide:
- mov [VesaGran],al ; Save the granularity scale factor
-
- ; Now determine if this video card supports multiple banks
-
- mov ax,[WORD VesaBuf+2] ; Get Window attributes
- and ah,0111b ; Mask out appropriate bits
- cmp ah,0011b ; Check if second window is only readable
- jne @@Exit ; No, so we are done
-
- mov [TwoBanks],true
- mov [ReadBank],offset VESA_rbank
-
- @@Exit:
- ret
-
- ENDP VESA_init
-
- ;----------------------------------------------------------------------------
- ; ATI_init
- ;----------------------------------------------------------------------------
- ; We have an ATI video card. The 18800-1 and 28800 chips support the dual
- ; paging mode, but the old 18800 chip does not.
- ;----------------------------------------------------------------------------
- PROC ATI_init near
-
- push bp
-
- cmp [CntChipID],grATI_18800
- jne @@Not18800
-
- ; We have an 18800 based ATI SuperVGA, so modify to not use separate read
- ; write banks.
-
- mov [TwoBanks],false
- mov [ReadBank],offset ATI_bank
- jmp @@Exit
-
- ; We have an 18800-1 or 28800 Chip, so setup for dual bank mode
-
- @@Not18800:
- modinx 1CEh, 0BEh, 01000b, 01000b ; Set bit 3 ATI Register E
-
- @@Exit:
- pop bp
- ret
-
- ENDP ATI_init
-
- ;----------------------------------------------------------------------------
- ; AHEAD_init
- ;----------------------------------------------------------------------------
- ; We have an Ahead A or B SuperVGA. We simply enable the extended registers
- ; to save time during bank switching.
- ;----------------------------------------------------------------------------
- PROC AHEAD_init near
-
- outp 3CEh, 0Fh, 20h ; Enable extended registers
- modinx 3CEh, 0Ch, 20h, 20h ; Enable enhanced mode
- ret
-
- ENDP AHEAD_init
-
- ;----------------------------------------------------------------------------
- ; CHIPS_init
- ;----------------------------------------------------------------------------
- ; We have a Chips & Technologies 82c451/452/453. To save time during
- ; bank switching, we enable the SuperVGA extended registers here.
- ; We also determine the type of chipset installed and setup bank switching
- ; and page flipping according to the chip type.
- ;----------------------------------------------------------------------------
- PROC CHIPS_init near
-
- outp 46E8h, 1Eh ; Place chip in setup mode
- outp 103h, 80h ; Enable extended registers
- outp 46E8h, 0Eh ; Bring chip out of setup mode
- modinx 3D6h, 4, 4, 4 ; Enable bank access and extended CRTC
- modinx 3D6h, 0Dh, 3, 1 ; Enable extended paging
-
- ; Set the bank switching code according to the C&T chipset type
-
- mov bx,[CntChipID] ; BX := chip id
-
- cmp bx,grCHIPS_82c451
- je @@Chips451 ; Done for 82c451
- cmp bx,grCHIPS_82c452
- je @@Chips452
-
- mov [NewBank],offset CHIPS453_bank
- mov [ReadBank],offset CHIPS453_bank
- jmp @@Exit
-
- @@Chips452:
- mov [NewBank],offset CHIPS452_bank
- mov [ReadBank],offset CHIPS452_bank
- jmp @@Exit
-
- ; Extended page flipping is not available on 82c451 chips, so disable it
-
- @@Chips451:
- mov [WORD cs:CHIPSPageOfs],offset NONE_page
-
- @@Exit:
- ret
-
- ENDP CHIPS_init
-
- ;----------------------------------------------------------------------------
- ; EVEREX_init
- ;----------------------------------------------------------------------------
- ; Some Everex video boards are based on Trident or ET4000 chips. Detect
- ; them here, and setup to use the correct bank switching and page flipping
- ; routines.
- ;----------------------------------------------------------------------------
- PROC EVEREX_init near
-
- mov ax,[CntChipID] ; AX := chipset ID
- cmp ax,grEVEREX_Ev236 ; UltraGraphics - Trident Chip
- je @@TridentChip
- cmp ax,grEVEREX_Ev620 ; Vision VGA - Trident Chip
- je @@TridentChip
- cmp ax,grEVEREX_Ev629 ; ViewPoint TC - ET4000 Chip
- je @@ET4000Chip
- cmp ax,grEVEREX_Ev673 ; EVGA - Trident Chip
- je @@TridentChip
- cmp ax,grEVEREX_Ev678 ; Viewpoint - Trident Chip
- jne @@Exit ; Normal Everex chip, all done
-
- ; Based on Trident chip, so determine the type (8800 or 8900).
-
- @@TridentChip:
- mov [TwoBanks],false
- mov [NewBank],offset TRIDENT_bank
- mov [ReadBank],offset TRIDENT_bank
- mov [WORD cs:EVEREXPageOfs],offset TRIDENT88_page
-
- wrinx 3C4h, 0Bh, 0 ; Force old definitions
- inp 3C5h ; Force new definitions
- and al,0Fh
- cmp al,2
- je @@Exit ; Done for Trident 8800
- mov [WORD cs:EVEREXPageOfs],offset TRIDENT89_page
- jmp @@Exit
-
- @@ET4000Chip:
- mov [TwoBanks],true
- mov [NewBank],offset ET4000_bank
- mov [ReadBank],offset ET4000_rbank
- mov [WORD cs:EVEREXPageOfs],offset ET4000_page
- jmp @@Exit
-
- @@Exit:
- ret
-
- ENDP EVEREX_init
-
- ;----------------------------------------------------------------------------
- ; PARADISE_init
- ;----------------------------------------------------------------------------
- ; We have a Paradise PVGA1A or WD90Cxx SuperVGA. We simply enable access
- ; to the extended registers to save time during bank switching.
- ;----------------------------------------------------------------------------
- PROC PARADISE_init near
-
- ; Enable paradise extensions
-
- wrinx 3CEh, 0Fh, 5 ; Turn off write protect on VGA registers
- wrinx 3C4h, 6h, 48h ; Unlock extended sequencer regs
- wrinx 3D4h, 29h, 85h ; Turn on access to PR10-17
-
- ; Turn off the standard VGA mem bit, to allow access to all of the SuperVGA
- ; video memory for extended page flipping.
-
- modinx 3D4h, 2Fh, 2, 0 ; Clear out the VGA MEM bit
-
- ; Now determine the Paradise Chipset type. The WD90C10 and above chipsets
- ; support the dual banking mode.
-
- cmp [CntChipID],grPARA_90C10
- jge @@HaveDualMode
-
- ; Have an old PVGA1 or WD90C00 video card without dual banking support
-
- mov [TwoBanks],false
- mov [NewBank],offset PARADISEPVGA_bank
- mov [ReadBank],offset PARADISEPVGA_bank
- jmp @@Exit
-
- ; We have a WD90C1x/3x chipset, so set up for dual banking
- ; operation (read/write operation).
-
- @@HaveDualMode:
- modinx 3CEh, 0Bh, 8, 8 ; Enable both PROA and PROB
- modinx 3C4h, 11h, 80h, 80h ; Set PROA for read, PROB for write
-
- @@Exit:
- ret
-
- ENDP PARADISE_init
-
- ;----------------------------------------------------------------------------
- ; TRIDENT_init
- ;----------------------------------------------------------------------------
- ; We have a Trident 8800 or 8900 SuperVGA. Setup for a pagesize of 64k
- ; before doing bank switching.
- ;----------------------------------------------------------------------------
- PROC TRIDENT_init
-
- modinx 3CEh, 6, 4, 4 ; Set pagesize to 64k
- ret
-
- ENDP TRIDENT_init
-
- ;----------------------------------------------------------------------------
- ; VIDEO7_init
- ;----------------------------------------------------------------------------
- ; We have a Video7 V7VGA SuperVGA. Enable access to the extended registers
- ; to save time during bank switching.
- ;----------------------------------------------------------------------------
- PROC VIDEO7_init
-
- outp 3C4h, 6, 0EAh ; Enable extended registers
-
- ; Determine if the chip is revision five or later, so we can support
- ; dual read/write bank operation.
-
- rdinx 3C4h, 08Eh ; Read Chip Revision register
- cmp al,05Ah ; Is this a version 5 chip?
- jl @@HaveV5 ; We have a version 5 or later chip
-
- ; If the card is a 1024i, I am not sure if it has a version 4 or version 5
- ; chip in it. I assume here that it has a version 5 chip. If it does not,
- ; (or does not seem to work), uncomment the following code and replace
- ; the above line:
- ;
- ; jg @@NotV5 ; version 1-3 V7VGA's
- ; cmp al,050h
- ; jge @@HaveV5 ; Yes, version 5 chip
-
- @@NotV5:
- mov [TwoBanks],false
- mov [NewBank],offset VIDEO7_bank
- mov [ReadBank],offset VIDEO7_bank
- jmp @@Exit
-
- ; We have a V7VGA revision 5 or later chip, so setup for dual paging
- ; mode
-
- @@HaveV5:
- modinx 3C4h, 0E0h, 80h, 80h ; Set split bank mode
-
- @@Exit:
- ret
-
- ENDP VIDEO7_init
-
- ;----------------------------------------------------------------------------
- ; ET4000_init
- ;----------------------------------------------------------------------------
- ; We have an ET4000 video card, so enable access to extended registers
- ; before bank switching.
- ;----------------------------------------------------------------------------
- PROC ET4000_init
-
- outp 3BFh, 3
- outp 3D8h, 0A0h ; Enable ET4000 extensions
-
- ; Check the type of video board, modifying the 24 bit mode tables if
- ; we have a Speedstar 24 or Genoa 7900 board.
-
- cmp [CntChipID],grET4000_MEGAEVA
- je @@Done
-
- ; We have a Speedstar 24 or Genoa 7900, both which only support the
- ; 640x480 video modes. Note that on both these cards, the bytes per line
- ; value for the mode is 2048, not 1920 (so you don't have problems with
- ; pixels crossing bank boundaries!!).
-
- mov [DWORD cs:ET4_640x350x16m],0
- mov [DWORD cs:ET4_640x400x16m],0
- mov bx,2048
- mov ax,grSVGA_640x480x16m
- call setBytesPerLine
-
- cmp [CntChipID],grET4000_SPEEDSTAR
- jne @@HaveGenoa
-
- mov [DWORD cs:ET4_640x480x16m],02E10E0h
- jmp @@Done
-
- @@HaveGenoa:
- mov [DWORD cs:ET4_640x480x16m],03E10F0h
-
- @@Done:
- ret
-
- ENDP
-
- ;----------------------------------------------------------------------------
- ; NCR_init
- ;----------------------------------------------------------------------------
- ; We have an NCR 77C22E SuperVGA, so set up for dual banking mode of
- ; operation. We also program the low portions of the bank switching
- ; registers with zeroes.
- ;----------------------------------------------------------------------------
- PROC NCR_init
-
- modinx 3C4h, 1Eh, 010100b, 010100b
- wrinx 3C4h, 19h, 0 ; Set primary offset low to 0
- wrinx 3C4h, 1Dh, 0 ; Set secondary offset low to 0
- ret
-
- ENDP
-
- ;----------------------------------------------------------------------------
- ; S3_init
- ;----------------------------------------------------------------------------
- ; We have an S3 based video card, so set up a few things specific to this
- ; card.
- ;----------------------------------------------------------------------------
- PROC S3_init
-
- ; The S3 Chipset uses large bytes per line values in 256, 32k and 64k
- ; color video modes to make the copper's life a little easier (and ours
- ; a little harder :-). Change the bytes per line values in the table
- ; to the correct values.
-
- call ModifyS3BytesPerLine
- ret
-
- ENDP S3_init
-
- ;----------------------------------------------------------------------------
- ; CIRRUS_init
- ;----------------------------------------------------------------------------
- ; We have a Cirrus 5422 SuperVGA, so enable access to extended registers.
- ;----------------------------------------------------------------------------
- PROC CIRRUS_init
-
- wrinx 3C4h, 6, 12h ; Enable extended registers
- ret
-
- ENDP CIRRUS_init
-
- ;----------------------------------------------------------------------------
- ; ACUMOS_init
- ;----------------------------------------------------------------------------
- ; We have an AcuMos SuperVGA, so enable access to extended registers.
- ;----------------------------------------------------------------------------
- PROC ACUMOS_init
-
- wrinx 3C4h, 6, 12h ; Enable extended registers
- ret
-
- ENDP ACUMOS_init
-
- ;----------------------------------------------------------------------------
- ; AL2101_init
- ;----------------------------------------------------------------------------
- ; We have an Advance Logic 2101 SuperVGA, so set up for separate read
- ; write bank switching. This is supposed to work according to the
- ; docs on the AL2101, but it doesn't (it works for the RealTek instead!)
- ; Very wierd!!
- ;----------------------------------------------------------------------------
- PROC AL2101_init
-
- ; modinx 3CEh, 0Fh, 4, 4 ; Set bit 2 of Extended function register
- ret
-
- ENDP AL2101_init
-
- ;----------------------------------------------------------------------------
- ; MXIC_init
- ;----------------------------------------------------------------------------
- ; We have an MXIC SuperVGA, so enable access to extended registers.
- ;----------------------------------------------------------------------------
- PROC MXIC_init
-
- wrinx 3C4h, 0A7h, 087h ; Enable extended registers
- ret
-
- ENDP MXIC_init
-
- ;----------------------------------------------------------------------------
- ; RT3106_init
- ;----------------------------------------------------------------------------
- ; We have a RealTek 3106 SuperVGA. This code is supposed to work on the
- ; advance logic's ALG2101 chip, but apparantly works on the RT3106!
- ;----------------------------------------------------------------------------
- PROC RT3106_init
-
- modinx 3CEh, 0Fh, 4, 4 ; Set bit 2 of Extended function register
- ret
-
- ENDP RT3106_init
-
- ;----------------------------------------------------------------------------
- ; ExitBank Deinitialises the SuperVGA card back to normal operation.
- ;----------------------------------------------------------------------------
- ;
- ; Returns the SuperVGA card back to it's default state, such as turning
- ; off access to all extended registers that were set by the initialisation
- ; routines.
- ;
- ; Note: All register may be used without concern for saving their values
- ;
- ; Registers: All.
- ;
- ;----------------------------------------------------------------------------
-
- PROC NONE_exit near
- ret
- ENDP NONE_exit
-
- PROC AHEAD_exit near
-
- outp 3CEh, 0Fh, 0 ; Disable extended registers
- ret
-
- ENDP AHEAD_exit
-
- PROC CHIPS_exit near
-
- outp 46E8h, 1Eh ; Place chip in setup mode
- outp 103h, 0 ; Disable extended registers
- outp 46E8h, 0Eh ; Bring chip out of setup mode
- ret
-
- ENDP CHIPS_exit
-
- PROC PARADISE_exit near
-
- wrinx 3CEh, 0Fh, 0 ; Turn on write protect on VGA registers
- wrinx 3CEh, 6h, 0 ; Turn on write protect on extended seq
- ret
-
- ENDP PARADISE_exit
-
- PROC VIDEO7_exit
-
- outp 3C4h, 6, 0AEh ; Disable extended registers
- ret
-
- ENDP VIDEO7_exit
-
- PROC CIRRUS_exit
-
- wrinx 3C4h, 6, 0 ; Disable extended registers
- ret
-
- ENDP CIRRUS_exit
-
- PROC ACUMOS_exit
-
- wrinx 3C4h, 6, 0 ; Disable extended registers
- ret
-
- ENDP ACUMOS_exit
-
- PROC MXIC_exit
-
- wrinx 3C4h, 0A7h, 0 ; Disable extended registers
- ret
-
- ENDP MXIC_exit
-