;============================================================================
; GP64VESA.COM A Fast Genoa Phantom 64 VESA Bank Switcher
;
; Made in Finland Copyright (c) 1995 Patrick Aalto (ap@jyu.fi)
;
; FreeWare Program
;
.MODEL tiny
.CODE
org 100h
.8086
;-------
; COM program entry point is here.
; When we get control, the registers are as follows:
;
; AX = BX = DX = SI = DI = BP = 0
; CX = 81h (?)
; CS = DS = ES = SS = @CODE
; SP = 0FFFEh
;-------
Entry:
jmp init
;-------
; VESA Bank Switch Routine
; Input:
; BH = 0/1 (0=Set Bank, 1=Get Bank)
; BL = Window Number (we only have 1 window)
; DX = Window Position (if BH==0)
; Output:
; AX = Status
; DX = Window Position (if BH==1)
;-------
EVEN
VESABANK PROC FAR
push ax
and bh,bh ; Is BH==0 = Set Bank ?
jne bank_get
;-------
; Set Bank Routine
;-------
push dx
mov ah,dl ; AH = Window Number
MOV DX,03D4h ; We always assume color mode
db 0C0h, 0E4h ; SHL AH,2 / SHL AH,0
sm1 db 2
MOV AL,6Ah
OUT DX,AX ; Output index 6A
pop dx
pop ax
retf
;-------
; Get Bank Routine
;-------
EVEN
bank_get:
MOV AL,6Ah
MOV DX,03D4h ; We always assume color mode
out dx,al
inc dx
jmp short $+2
in al,dx
xor dx,dx
mov dl,al
db 0C0h, 0EAh ; SHR DL,2 / SHR DL,0
sm2 db 2
pop ax
retf
VESABANK ENDP
EVEN
INT10R PROC FAR
cmp ax,4F05h ; Video Memory Window Control ?
je short I10_4F05 ; Yep
cmp ax,4F01h ; Return SVGA Mode Information ?
je short I10_4F01 ; Yep
cmp ax,4F02h ; Set SVGA Mode ?
je short I10_4F02 ; Yep
db 0EAh ; JMP FAR 0000:0000
I10orig LABEL DWORD
I10low0 dw 0
I10hig0 dw 0
;-------
; Video Memory Window Control. If a badly written VESA program
; uses Bank Switching via INT 10h instead of using the Window
; Pointer, we'll try to speed that up too. (Though why bother
; actually, that kind of program is probably MEANT to be slow.)
;-------
EVEN
I10_4F05:
call VESABANK
mov ax,004Fh ; Indicate success return
iret
;-------
; Return SVGA Mode Information. Here we must store a pointer
; to our new VESABANK routine instead of to the BIOS Bank
; Switch routine.
;-------
EVEN
I10_4F01:
pushf
db 9Ah ; CALL 0000:0000
I10low1 dw 0
I10hig1 dw 0
mov es:[di+12],OFFSET VESABANK
mov es:[di+14],cs
iret
;-------
; Set SVGA Mode. We need this, because we'll do all the
; necessary setup (like unlocking the registers) here,
; instead of in the Bank Switch routine.
;-------
EVEN
I10_4F02:
pushf
db 9Ah ; CALL 0000:0000
I10low2 dw 0
I10hig2 dw 0
push dx
push ax
mov dx,03D4h ; We always assume color mode
mov ax,4838h ; Unlock Register Lock 1
out dx,ax
MOV AX,0A539h ; Unlock Register Lock 2
OUT DX,AX
mov al,31h
out dx,al
inc dx
jmp short $+2
in al,dx
or al,1 ; AL |= 1
out dx,al ; Enable CPU access to whole RAM
dec dx
mov al,34h
out dx,al
inc dx
jmp short $+2
in al,dx
dec dx
test al,2 ; Is AL bit 2 on ?
mov cs:[sm1],2 ; SHL AH,2
mov cs:[sm2],2 ; SHR DL,2
jnz short I10_do4 ; Nope
mov cs:[sm1],0 ; SHL AH,0
mov cs:[sm2],0 ; SHR DL,0
I10_do4:
mov ax,0038h ; Lock Register Lock 1
out dx,ax
pop ax
pop dx
iret
INT10R ENDP
last_saved LABEL UNKNOWN
;-------
; From here on, this memory is freed when we Terminate
; and Stay Resident.
;-------
banner db 'GP64VESA: A Fast Genoa Phantom 64 VESA Bank Switch installed.',0dh,0ah
db 'This program is FreeWare, Copyright 1995 Patrick Aalto (ap@jyu.fi).'
db 0dh,0ah,0dh,0ah
db 'For optimum performance load this program last, after all other TSRs.'
db 0dh,0ah,'$'
EVEN
init:
cld
push ds
push cs
pop es
XOR AX,AX
MOV DS,AX
mov si,10h*4
LODSW
mov es:[I10low0],ax
mov es:[I10low1],ax
mov es:[I10low2],ax
LODSW
mov es:[I10hig0],ax
mov es:[I10hig1],ax
mov es:[I10hig2],ax
pop ds
xor ax,ax
mov es,ax
mov di,10h*4
MOV AX,OFFSET CS:INT10R ; setvect(INT10, INT10R);
STOSW
MOV AX,CS
STOSW
;-------
; Write string to STDOUT
;-------
mov ah,09h
mov dx,OFFSET banner
int 21h
;-------
; Free the environment block
;-------
mov es,cs:[002Ch] ; ES = Environment Segment
mov ah,49h
int 21h
;-------
; Terminate and stay resident
;-------
mov dx,15+OFFSET last_saved
.186
shr dx,4
.8086
mov ax,3100h
int 21h
END Entry