;****************************************************************************
;*
;*                        The Universal VESA VBE
;*
;*                  Copyright (C) 1993 Kendall Bennett.
;*                          All rights reserved.
;*
;* Filename:    $RCSfile: _ncr.asm $
;* Version:     $Revision: 1.2 $
;*
;* Language:    8086 Assembler
;* Environment: IBM PC (MS DOS)
;*
;* Description: Assembly language support routines for NCR SuperVGA's.
;*
;*              Contains code to perform initialisation, bank switching
;*              and extended page flipping if possible.
;*
;* $Id: _ncr.asm 1.2 1993/09/24 05:23:19 kjb release $
;*
;* Revision History:
;* -----------------
;*
;* $Log: _ncr.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
;*
;****************************************************************************

;----------------------------------------------------------------------------
; NCR_bank16    Change to a new 64k bank (reading and writing)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    NCR_bank16  far

		push    ax
        push    dx
        shl     al,4                ; Change 64k bank into 4k bank number
        mov     ah,al
        mov     al,18h
        mov     dx,3C4h
        out     dx,ax               ; Set write bank number
        mov     al,1Ch
        out     dx,ax               ; Set read bank number
        pop     dx
        pop     ax
		ret

ENDP    NCR_bank16

NCR_bank16_len  =   ($-NCR_bank16)

;----------------------------------------------------------------------------
; NCR_bank256   Change to a new 64k bank (reading and writing)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    NCR_bank256 far

		push    ax
        push    dx
        shl     al,2                ; Change 64k bank into 16k bank number
        mov     ah,al
        mov     al,18h
        mov     dx,3C4h
        out     dx,ax               ; Set write bank number
        mov     al,1Ch
        out     dx,ax               ; Set read bank number
        pop     dx
        pop     ax
		ret

ENDP    NCR_bank256

NCR_bank256_len =   ($-NCR_bank256)

;----------------------------------------------------------------------------
; NCR_rbank16   Change to a new 64k read bank (reading only)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    NCR_rbank16 far

		push    ax
        push    dx
        shl     al,4                ; Change 64k bank into 4k bank number
        mov     ah,al
        mov     al,1Ch
        mov     dx,3C4h
        out     dx,ax               ; Set read bank number
        pop     dx
        pop     ax
		ret

ENDP    NCR_rbank16

NCR_rbank16_len =   ($-NCR_rbank16)

;----------------------------------------------------------------------------
; NCR_rbank256  Change to a new 64k read bank (reading only)
;----------------------------------------------------------------------------
;
; Entry:        AX  - Number of 64k bank
;
; Registers:    All preserved!
;
;----------------------------------------------------------------------------
PROC    NCR_rbank256    far

		push    ax
        push    dx
        shl     al,2                ; Change 64k bank into 16k bank number
        mov     ah,al
        mov     al,1Ch
        mov     dx,3C4h
        out     dx,ax               ; Set read bank number
        pop     dx
        pop     ax
		ret

ENDP    NCR_rbank256

NCR_rbank256_len    =   ($-NCR_rbank256)

;----------------------------------------------------------------------------
; NCR_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    NCR_page    far

        SetLowStartAddress
        mov     dx,3C4h
        mov     al,31h              ; Index of start address register
        out     dx,al
        inc     dx
        in      al,dx               ; Read old value
        and     al,0F0h             ; Clear bottom four bits
        and     bl,0Fh              ; Mask out bottom four bits
        or      al,bl
        out     dx,al               ; Set the new value
        ret

ENDP

NCR_page_len    =   ($-NCR_page)

;----------------------------------------------------------------------------
; NCR_setup Setup the SuperVGA for correct operation
;----------------------------------------------------------------------------
PROC    NCR_setup   near

        wrinx   3C4h, 5, 5          ; Enable extended registers
        wrinx   3C4h, 18h, 0
        wrinx   3C4h, 19h, 0
        wrinx   3C4h, 1Ah, 0
        wrinx   3C4h, 1Bh, 0
        wrinx   3C4h, 1Dh, 0
        wrinx   3C4h, 1Ch, 0
        modinx  3C4h, 1Eh, 011100b, 011100b
        ret

ENDP    NCR_setup

NCR_setup_len   =   ($-NCR_setup)

;----------------------------------------------------------------------------
; NCR_exit  Return the SuperVGA to default operation
;----------------------------------------------------------------------------
PROC    NCR_exit    near

        wrinx   3C4h, 5, 0          ; Disable extended registers
        ret

ENDP    NCR_exit

NCR_exit_len    =   ($-NCR_exit)

;----------------------------------------------------------------------------
; NCR_init
;----------------------------------------------------------------------------
; We have an NCR 77C22E SuperVGA, so set up for dual banking mode of
; operation and extended page flipping. We also program the low portions
; of the bank switching registers with zeroes.
;----------------------------------------------------------------------------
PROC    NCR_init

        mov     [TwoBanks],true
        mov     [WriteBank16],offset NCR_bank16
        mov     [WriteBank16Len],NCR_bank16_len
        mov     [WriteBank256],offset NCR_bank256
        mov     [WriteBank256Len],NCR_bank256_len
        mov     [ReadBank16],offset NCR_rbank16
        mov     [ReadBank16Len],NCR_rbank16_len
        mov     [ReadBank256],offset NCR_rbank256
        mov     [ReadBank256Len],NCR_rbank256_len
		mov     [NewPage16],offset NCR_page
		mov     [NewPage16Len],NCR_page_len
		mov     [NewPage256],offset NCR_page
        mov     [NewPage256Len],NCR_page_len
		mov     [SetupSVGA],offset NCR_setup
        mov     [SetupSVGALen],NCR_setup_len
        mov     [ExitSVGA],offset NCR_exit
        mov     [ExitSVGALen],NCR_exit_len
        ret

ENDP    NCR_init
