;****************************************************************************
;*
;*                        The Universal VESA VBE
;*
;*                  Copyright (C) 1993 Kendall Bennett.
;*                          All rights reserved.
;*
;* Filename:    $RCSfile: _mxic.asm $
;* Version:     $Revision: 1.2 $
;*
;* Language:    8086 Assembler
;* Environment: IBM PC (MS DOS)
;*
;* Description: Assembly language support routines for MXIC SuperVGA's.
;*
;*              Contains code to perform initialisation, bank switching
;*              and extended page flipping if possible.
;*
;* $Id: _mxic.asm 1.2 1993/09/24 05:23:19 kjb release $
;*
;* Revision History:
;* -----------------
;*
;* $Log: _mxic.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
;*
;****************************************************************************

;----------------------------------------------------------------------------
; MXIC_bank Change to a new 64k bank (reading and writing)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    MXIC_bank   far

		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
		ret

ENDP    MXIC_bank

MXIC_bank_len       =   ($-MXIC_bank)

;----------------------------------------------------------------------------
; MXIC_rbank    Change to a new 64k read bank (reading only)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    MXIC_rbank  far

		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
		ret

ENDP    MXIC_rbank

MXIC_rbank_len      =   ($-MXIC_rbank)

;----------------------------------------------------------------------------
; MXIC_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    MXIC_page   far

        SetLowStartAddress
        mov     dx,3C4h             ; DX := SEQUENCER I/O port
        mov     al,0F1h             ; Index extended start address
        out     dx,al
        inc     dx
        in      al,dx               ; Read current value
        and     al,0FCh             ; Zero out start address
        and     bl,3                ; Mask out all but bottom 2 bits
        or      al,bl               ; Or in new start address
        out     dx,al               ; Output the address
        ret

ENDP    MXIC_page

MXIC_page_len       =   ($-MXIC_page)

;----------------------------------------------------------------------------
; MXIC_setup    Setup the SuperVGA for correct operation
;----------------------------------------------------------------------------
PROC    MXIC_setup  near

        modinx  3C4h, 065h, 040h, 040h  ; Enable access to registers
        wrinx   3C4h, 0A7h, 087h        ; Enable extended registers
        modinx  3C4h, 0C3h, 4, 4        ; Enable banking operation
        modinx  3C4h, 0F0h, 8, 8        ; Enable extended CRT addressing
        ret

ENDP    MXIC_setup

MXIC_setup_len  =   ($-MXIC_setup)

;----------------------------------------------------------------------------
; MXIC_exit Return the SuperVGA to default operation
;----------------------------------------------------------------------------
PROC    MXIC_exit   near

        wrinx   3C4h, 0A7h, 0       ; Disable extended registers
        ret

ENDP    MXIC_exit

MXIC_exit_len   =   ($-MXIC_exit)

;----------------------------------------------------------------------------
; MXIC_init
;----------------------------------------------------------------------------
; We have an MXIC SuperVGA, so set up vectors for this video board.
;----------------------------------------------------------------------------
PROC    MXIC_init

        mov     [TwoBanks],true
        mov     [WriteBank16],offset MXIC_bank
        mov     [WriteBank16Len],MXIC_bank_len
        mov     [WriteBank256],offset MXIC_bank
        mov     [WriteBank256Len],MXIC_bank_len
        mov     [ReadBank16],offset MXIC_rbank
        mov     [ReadBank16Len],MXIC_rbank_len
        mov     [ReadBank256],offset MXIC_rbank
        mov     [ReadBank256Len],MXIC_rbank_len
		mov     [NewPage16],offset MXIC_page
		mov     [NewPage16Len],MXIC_page_len
		mov     [NewPage256],offset MXIC_page
		mov     [NewPage256Len],MXIC_page_len
		mov     [SetupSVGA],offset MXIC_setup
        mov     [SetupSVGALen],MXIC_setup_len
        mov     [ExitSVGA],offset MXIC_exit
        mov     [ExitSVGALen],MXIC_exit_len
        ret

ENDP    MXIC_init
