;****************************************************************************
;*
;*                        The Universal VESA VBE
;*
;*                  Copyright (C) 1993 Kendall Bennett.
;*                          All rights reserved.
;*
;* Filename:    $RCSfile: _paradis.asm $
;* Version:     $Revision: 1.2 $
;*
;* Language:    8086 Assembler
;* Environment: IBM PC (MS DOS)
;*
;* Description: Assembly language support routines for Paradise SuperVGA's.
;*
;*              Contains code to perform initialisation, bank switching
;*              and extended page flipping if possible.
;*
;* $Id: _paradis.asm 1.2 1993/09/24 05:23:19 kjb release $
;*
;* Revision History:
;* -----------------
;*
;* $Log: _paradis.asm $
;* Revision 1.2  1993/09/24  05:23:19  kjb
;* Fixed a number of bugs.
;*
;* Revision 1.1  1993/09/19  01:26:54  kjb
;* Initial revision
;*
;****************************************************************************

grPARA_PVGA1A       =   0   ; Paradise PVGA1A chipset
grPARA_90C00        =   1   ; Paradise WD90C00 chipset
grPARA_90C10        =   2   ; Paradise WD90C10 chipset
grPARA_90C11        =   3   ; Paradise WD90C11 chipset
grPARA_90C2x        =   4   ; Paradise WD90C2x chipset
grPARA_90C30        =   5   ; Paradise WD90C30 chipset
grPARA_90C31        =   6   ; Paradise WD90C31 chipset

;----------------------------------------------------------------------------
; PARADISEPVGA_bank Change to a new 64k bank (reading and writing)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    PARADISEPVGA_bank   far

		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
		ret

ENDP    PARADISEPVGA_bank

PARADISEPVGA_bank_len   =   ($-PARADISEPVGA_bank)

;----------------------------------------------------------------------------
; PARADISE_bank Change to a new 64k bank (reading and writing)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    PARADISE_bank   far

		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
		ret

ENDP    PARADISE_bank

PARADISE_bank_len   =   ($-PARADISE_bank)

;----------------------------------------------------------------------------
; PARADISE_rbank    Change to a new 64k read bank (reading only)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    PARADISE_rbank  far

		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
		ret

ENDP    PARADISE_rbank

PARADISE_rbank_len  =   ($-PARADISE_rbank)

;----------------------------------------------------------------------------
; PARADISE_page Set the extended CRT starting address.
;----------------------------------------------------------------------------
;
; Entry:        BL  - Index of start address low register
;               BH  - Bits 7-0 of new start address
;               CL  - Index of start address high register
;               CH  - Bits 15-8 of new start address
;               SI  - Bits 16+ for new start address
;
; Registers:    AX,BX,CX,DX,SI
;
;----------------------------------------------------------------------------
PROC    PARADISE_page   far

        SetLowStartAddress
        mov     dx,03CEh
        mov     al,0Dh
        out     dx,al               ; Index PR3 CRT Control register
        inc     dx
        in      al,dx               ; Read current value
        and     al,0E7h             ; Zero out bits 4-3
        and     bl,3                ; Mask out bottom 2 bits
        shl     bl,3                ; Shift into correct position
        or      al,bl               ; Or in the new start address
        out     dx,al               ; Output the address
        ret

ENDP    PARADISE_page

PARADISE_page_len   =   ($-PARADISE_page)

;----------------------------------------------------------------------------
; PARADISEPVGA_setup    Setup the SuperVGA for correct operation
;----------------------------------------------------------------------------
PROC    PARADISEPVGA_setup  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
        ret

ENDP    PARADISEPVGA_setup

PARADISEPVGA_setup_len  =   ($-PARADISEPVGA_setup)

;----------------------------------------------------------------------------
; PARADISE_setup    Setup the SuperVGA for correct operation
;----------------------------------------------------------------------------
PROC    PARADISE_setup  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

; Setup for dual banking operation

        modinx  3CEh, 0Bh, 8, 8     ; Enable both PROA and PROB
        modinx  3C4h, 11h, 80h, 80h ; Set PROA for read, PROB for write
        ret

ENDP    PARADISE_setup

PARADISE_setup_len  =   ($-PARADISE_setup)

;----------------------------------------------------------------------------
; PARADISE_exit Return the SuperVGA to default operation
;----------------------------------------------------------------------------
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
        modinx  3CEh, 0Bh, 8, 0     ; Disable PROB
        ret

ENDP    PARADISE_exit

PARADISE_exit_len   =   ($-PARADISE_exit)

;----------------------------------------------------------------------------
; 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

; Setup the correct vectors to use the Paradise bank switching and paging
; routines. The WD90C10 and above chipsets support the dual banking mode.

        mov     [TwoBanks],false
        mov     [WriteBank16],offset PARADISEPVGA_bank
        mov     [WriteBank16Len],PARADISEPVGA_bank_len
        mov     [WriteBank256],offset PARADISEPVGA_bank
        mov     [WriteBank256Len],PARADISEPVGA_bank_len
		mov     [NewPage16],offset PARADISE_page
		mov     [NewPage16Len],PARADISE_page_len
		mov     [NewPage256],offset PARADISE_page
        mov     [NewPage256Len],PARADISE_page_len
		mov     [SetupSVGA],offset PARADISEPVGA_setup
        mov     [SetupSVGALen],PARADISEPVGA_setup_len
        mov     [ExitSVGA],offset PARADISE_exit
        mov     [ExitSVGALen],PARADISE_exit_len

        cmp     [CntChipID],grPARA_90C10
        jl      @@Exit

; We have a WD90C1x/3x chipset, so set up for dual banking
; operation (read/write operation).

        mov     [TwoBanks],true
        mov     [WriteBank16],offset PARADISE_bank
        mov     [WriteBank16Len],PARADISE_bank_len
        mov     [WriteBank256],offset PARADISE_bank
        mov     [WriteBank256Len],PARADISE_bank_len
        mov     [ReadBank16],offset PARADISE_rbank
        mov     [ReadBank16Len],PARADISE_rbank_len
        mov     [ReadBank256],offset PARADISE_rbank
        mov     [ReadBank256Len],PARADISE_rbank_len
        mov     [SetupSVGA],offset PARADISE_setup
        mov     [SetupSVGALen],PARADISE_setup_len

@@Exit:
        ret

ENDP    PARADISE_init
