Metropoli BBS
VIEWER: gp64vesa.asm MODE: TEXT (ASCII)
;============================================================================
;  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

[ RETURN TO DIRECTORY ]