2025-04-27 07:49:33 -04:00

346 lines
12 KiB
NASM

title "QVision ASM routines"
;
;++
;
; Copyright (c) 1992 Microsoft Corporation
; Copyright (c) 1993 Compaq Computer Corporation
;
; Module Name:
;
; qvhard.asm
;
; Abstract:
;
; This module implements the bank switching code for the QVision
; 1024 and 1280 boards. Normal banking is implemented for both
; the original QVision modes and the extended 1280 modes. For
; QVIsion modes the addressing granularity is 4k. For Orion
; extended modes, the addressing granularity is 16k.
;
; Only code for two 32k banks is implemented. HC Planar banking
; is not implemented.
;
;
; Environment:
;
; Kernel mode only.
;
; Revision History:
;;
;
;
;--
.386p
.xlist
include callconv.inc
.list
;----------------------------------------------------------------------------
;
; QVision banking control ports.
;
GRAPHICS_ADDRESS_PORT equ 03ceh ;banking control here
QV_BANKING_INDEX_PORT_0 equ 45h ;banking page register 0
QV_BANKING_INDEX_PORT_1 equ 46h ;banking page register 1
QV_BANKING_WINDOW_SIZE equ 06h ;banking window size
SEQ_ADDRESS_PORT equ 03C4h ;Sequencer Address register
IND_MEMORY_MODE equ 04h ;Memory Mode reg. index in Sequencer
CHAIN4_MASK equ 08h ;Chain4 bit in Memory Mode register
;----------------------------------------------------------------------------
_TEXT SEGMENT DWORD PUBLIC 'CODE'
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
;
;
; Input:
; EAX = desired read bank mapping
; EDX = desired write bank mapping
;
; Note: values must be correct, with no stray bits set; no error
; checking is performed.
;
public _QV4kAddrBankSwitchStart ; used for Aries modes
public _QV4kAddrBankSwitchEnd
public _QV4kAddrPlanarHCBankSwitchStart
public _QV4kAddrPlanarHCBankSwitchEnd
public _QV4kAddrEnablePlanarHCStart
public _QV4kAddrEnablePlanarHCEnd
public _QV4kAddrDisablePlanarHCStart
public _QV4kAddrDisablePlanarHCEnd
public _QV16kAddrBankSwitchStart ; used for Orion modes
public _QV16kAddrBankSwitchEnd
public _QV16kAddrPlanarHCBankSwitchStart
public _QV16kAddrPlanarHCBankSwitchEnd
public _QV16kAddrEnablePlanarHCStart
public _QV16kAddrEnablePlanarHCEnd
public _QV16kAddrDisablePlanarHCStart
public _QV16kAddrDisablePlanarHCEnd
align 4
;----------------------------------------------------------------------------
;
; _QV4kAddrBankSwitchStart()
;
;
; This function converts the 32k page numbers provided by the
; caller into the required format for the QVision page registers
; then maps the 2 32k pages. This function assumes that 4k page
; addressing granularity is used by the page registers.
;
;
;
; EAX = bank number to map to bank 1
; EDX = bank number to map to bank 2
;
;
;
;
;
;----------------------------------------------------------------------------
_QV4kAddrBankSwitchStart proc ; start of bank switch code
_QV4kAddrPlanarHCBankSwitchStart: ; start of planar HC bank switch code,
; which is the same code as normal
; bank switching
;
; The VGA256 .dll passes us 32k bank numbers - we need
; to convert these values to 4k page numbers for Aries modes.
;
shl eax,3 ; assume Aries 4k page
shl edx,3 ; resolution
;!!!! NOTE: The October 1992 release NT VGA driver assumes that the Graphics
; index is not changed by the bank switch code. We save it on the
; stack (and save the write bank value in the high order of edx)
; and restore it at the end of the routine. If the NT VGA driver
; changes so that it is the index need not be preserved, this code
; could be simplified (and speeded up!)
rol edx,16 ; save bank 0 write value
mov ah,al ; save bank 1 write value
mov dx,GRAPHICS_ADDRESS_PORT ; banking control port
in al,dx ; save graphics
push eax ; index register
mov al,QV_BANKING_INDEX_PORT_0 ; select the READ bank
out dx,ax ; write out READ bank and value
rol edx,16 ; restore data to original format
mov ah,dl ; get WRITE bank value
mov al,QV_BANKING_INDEX_PORT_1 ;
mov dx,GRAPHICS_ADDRESS_PORT ; banking control port
out dx,ax ; select the WRITE bank
pop eax ; restore the original
out dx,al ; graphics register index
ret
_QV4kAddrBankSwitchEnd:
_QV4kAddrPlanarHCBankSwitchEnd:
align 4
_QV4kAddrEnablePlanarHCStart:
mov dx,SEQ_ADDRESS_PORT
in al,dx
push eax ;preserve the state of the Seq Address
mov al,IND_MEMORY_MODE
out dx,al ;point to the Memory Mode register
inc edx
in al,dx ;get the state of the Memory Mode reg
and al,NOT CHAIN4_MASK ;turn off Chain4 to make memory planar
out dx,al
dec edx
pop eax
out dx,al ;restore the original Seq Address
ERA1_INDEX equ 0A1h
mov dx,GRAPHICS_ADDRESS_PORT
in al,dx
push eax ;preserve the Graphics Index
mov al,ERA1_INDEX
out dx,al ;point to ERA1
inc edx
in al,dx ; get ERA1
and al,not 30h ; turn off the shift bits
out dx,al
dec edx
pop eax
out dx,al ;restore the original Graphics Index
ret
_QV4kAddrEnablePlanarHCEnd:
align 4
_QV4kAddrDisablePlanarHCStart:
mov dx,SEQ_ADDRESS_PORT
in al,dx
push eax ;preserve the state of the Seq Address
mov al,IND_MEMORY_MODE
out dx,al ;point to the Memory Mode register
inc edx
in al,dx ;get the state of the Memory Mode reg
or al,CHAIN4_MASK ;turn on Chain4 to make memory linear
out dx,al
dec edx
pop eax
out dx,al ;restore the original Seq Address
mov dx,GRAPHICS_ADDRESS_PORT
in al,dx
push eax ;preserve the Graphics Index
mov al,ERA1_INDEX
out dx,al ;point to ERA1
inc edx
in al,dx ; get ERA1
and al,not 30h
or al,20h
out dx,al
dec edx
pop eax
out dx,al ;restore the original Graphics Index
ret
_QV4kAddrDisablePlanarHCEnd:
_QV4kAddrBankSwitchStart endp
;----------------------------------------------------------------------------
;
; _QV16kAddrBankSwitchStart()
;
;
; This function converts the 32k page numbers provided by the
; caller into the required format for the QVision page registers
; then maps the 2 32k pages. This function assumes that 16k page
; addressing granularity is used by the page registers.
;
;
; EAX = bank number to map to bank 1
; EDX = bank number to map to bank 2
;
;
;----------------------------------------------------------------------------
_QV16kAddrBankSwitchStart proc ; start of bank switch code
_QV16kAddrPlanarHCBankSwitchStart: ; start of planar HC bank switch code,
; which is the same code as normal
; bank switching
;
; The VGA256 .dll passes us 32k bank numbers - we need
; to convert these values to 16k page values for Orion modes.
;
shl eax,1 ; assume Orion 16k address
shl edx,1 ; resolution
;!!!! NOTE: The October 1992 release NT VGA driver assumes that the Graphics
; index is not changed by the bank switch code. We save it on the
; stack (and save the write bank value in the high order of edx)
; and restore it at the end of the routine. If the NT VGA driver
; changes so that it is the index need not be preserved, this code
; could be simplified (and speeded up!)
rol edx,16 ; save bank 0 write value
mov ah,al ; save bank 1 write value
mov dx,GRAPHICS_ADDRESS_PORT ; banking control port
in al,dx ; save graphics
push eax ; index register
mov al,QV_BANKING_INDEX_PORT_0 ; select the READ bank
out dx,ax ; write out READ bank and value
rol edx,16 ; restore data to original format
mov ah,dl ; get WRITE bank value
mov al,QV_BANKING_INDEX_PORT_1 ;
mov dx,GRAPHICS_ADDRESS_PORT ; banking control port
out dx,ax ; select the WRITE bank
pop eax ; restore the original
out dx,al ; graphics register index
ret
_QV16kAddrBankSwitchEnd:
_QV16kAddrPlanarHCBankSwitchEnd:
align 4
_QV16kAddrEnablePlanarHCStart:
mov dx,SEQ_ADDRESS_PORT
in al,dx
push eax ;preserve the state of the Seq Address
mov al,IND_MEMORY_MODE
out dx,al ;point to the Memory Mode register
inc edx
in al,dx ;get the state of the Memory Mode reg
and al,NOT CHAIN4_MASK ;turn off Chain4 to make memory planar
out dx,al
dec edx
pop eax
out dx,al ;restore the original Seq Address
ERA1_INDEX equ 0A1h
mov dx,GRAPHICS_ADDRESS_PORT
in al,dx
push eax ;preserve the Graphics Index
mov al,ERA1_INDEX
out dx,al ;point to ERA1
inc edx
in al,dx ; get ERA1
and al,not 30h ; turn off the shift bits
out dx,al
dec edx
pop eax
out dx,al ;restore the original Graphics Index
ret
_QV16kAddrEnablePlanarHCEnd:
align 4
_QV16kAddrDisablePlanarHCStart:
mov dx,SEQ_ADDRESS_PORT
in al,dx
push eax ;preserve the state of the Seq Address
mov al,IND_MEMORY_MODE
out dx,al ;point to the Memory Mode register
inc edx
in al,dx ;get the state of the Memory Mode reg
or al,CHAIN4_MASK ;turn on Chain4 to make memory linear
out dx,al
dec edx
pop eax
out dx,al ;restore the original Seq Address
mov dx,GRAPHICS_ADDRESS_PORT
in al,dx
push eax ;preserve the Graphics Index
mov al,ERA1_INDEX
out dx,al ;point to ERA1
inc edx
in al,dx ; get ERA1
and al,not 30h
or al,20h
out dx,al
dec edx
pop eax
out dx,al ;restore the original Graphics Index
ret
_QV16kAddrDisablePlanarHCEnd:
_QV16kAddrBankSwitchStart endp
_TEXT ends
end