;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
        PAGE    60,132
        TITLE   VDHIOPL.ASM -- Video Device Handler Ring 2 Routines
;/*****************************************************************************
;*
;* SOURCE FILE NAME = VDHIOPL.asm
;*
;* DESCRIPTIVE NAME = Video device handler ring 2 routines
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION  This module contains routines that run at ring 2 in
;*              order to directly access the hardware ( via IN and OUT
;*              instructions ).
;*
;* FUNCTIONS    ACCESSBLINK
;*              ACCESSCLUT
;*              ACCESSCURSORPOS
;*              ACCESSCURSORTYPE
;*              ACCESSDISPLAYMASK
;*              ACCESSHARDWARE
;*              ACCESSOVERSCAN
;*              ACCESSREGISTER
;*              ACCESSUNDERSCORE
;*              ACCESSVIDEOENABLE
;*              CHARFONTEND
;*              GetMonitorID
;*              QUERY132
;*              SET132
;*              SETMAPMASK
;*              VGAWait
;*              _CharFontBegin
;*              _DPRINTF
;*              _HardwareColor
;*              _HardwareColumns
;*              _Query8514A
;*              _QueryXGA
;*              inchr
;*              putchar
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVIY =
;*   DATE      FLAG        APAR    CHANGE DESCRIPTION
;*   --------  ----------  -----   --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx   xxxxxxx
;*   03/09/89  @D184       D184    STJ, Identify additional displays for 8514/A
;*   04/14/89  @S4         B701111 STJ, Remove negative logic,
;*   05/10/89  @C21        B701513 CJJ, Don't turn Video signal back on and reenable
;*             @C21                     reading of VideoEnable for VGA,
;*   06/29/89  @T39        B784056 TPL, Remove hardware dependencies in VDHINIT,
;*   07/31/89  @B705063    B705063 WKB, Decrease interrupt latency period as per spec
;*   08/08/89  @B19        B785016 WKB, Included OEM VGA enhancements, B785017 also.
;*   08/17/89  @S24        B706605 STJ, Restore undocumented 8514/A AI interfaces,
;*   09/11/89  @T47        B707464 TPL, Save/restore 3xBox (graphics) bit planes,
;*   09/13/89  @S28        B700010 STJ, Retain external clocking on VGA,
;*   09/14/89  @T49        B707543 TPL, Workaround for a 486 bug,
;*   10/25/89  @TL3        B708718 TPL, Setup bit mask register on restore,
;*   12/18/89  @tb25       AR05401 TLB, Don't do fixvgabug and sequencer enable unless
;*             @tb25                    in restore,
;*   04/03/90  @T57        B788756 TPL, Do not clear reserve bit when hidding cursor,
;*   06/08/90  @S28f       B789810 TPL, Do not preserve External Clock bit,
;*   06/14/90  @B72        B713826 WKB, Correct underscore problem from VioGetState,
;*   07/23/90  @T72        D1295   TPL, DCR 1295 - Support recognition of XGA device
;*   09/13/90  @D1085      D1085   WKB, DCR 1085 - Support 132 columns on appropriate h/w
;*   09/20/90  @B716255    B716255 TPL, Return XGA present for Kauai-HS
;*   10/17/90  @B717771    B717771 WKB, Reduce interrupt latency period,
;*   03/25/92  @DRW                     Skip sequencer 7 'fixups' for Tseng-based adapters
;*   09/28/93  J-TS0928    JS05992 TSO, Lapped cursor is not drawn correctly.
;*****************************************************************************/

.286p

;
;+----------------------------------------------------------------------------+
;|  Include files                                                             |
;+----------------------------------------------------------------------------+
;
        include struc.inc               ; Structured assembly macros
        include vdh.inc                 ; Definitions
        include vdhctl.inc
        include vgaemu.inc              ; VGA text emulation video buffer

TSENG_ADAPTER   EQU     3               ;                               ;@DRW
        extrn   _SVGAPresent:word       ; SVGA adapter type             ;@DRW

INSTSEG SEGMENT PARA PUBLIC 'DATA'
        extrn   CursorOffset : word
        extrn   CursorSel    : word
INSTSEG ENDS

_DATA   SEGMENT WORD PUBLIC 'DATA'
        extrn   VideoBuffSel    : word
        extrn   HardwareScroll  : word                                  ;J-TS00
        extrn   PrevLineComp    : word                                  ;J-TS00
        extrn   MaxLineComp     : word                                  ;J-TS00
_DATA   ENDS                                                            ;J-TS00

R2SEG   SEGMENT BYTE  PUBLIC  'CODE'
        ASSUME  CS: R2SEG, DS: DGROUP


        IFDEF   VDHVGA_OR_VDH8514A

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: Query8514A                                        */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Query 8514/A configuration                       */
;/*                                                                     */
;/*  FUNCTION: Verify presence of 8514/A adapter, query memory size,    */
;/*            and query display type.                                  */
;/*                                                                     */
;/*  ENTRY POINT: Query8514A                                            */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: None                                                        */
;/*                                                                     */
;/*  EXIT-NORMAL: AL = display type  ( Color8514, Color8512_8513, etc)  */
;/*               AH = memory size ( 0 - 512k, 1 - 1MB )                */
;/*                                                                     */
;/*  EXIT-ERROR:  AX = VDHERROR_NO_ADAPTER                              */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
        PUBLIC  _Query8514A
_Query8514A PROC FAR

        mov     cx, VDHERROR_NO_ADAPTER ; Initialize cx = 8514/A not found

        mov     dx, 9AE9h               ; High byte of status reg ;D184
        in      al, dx                  ; Read 8514 Queue Status Reg ;D184
        test    al, 20h                 ;D184
        .if     < z >                   ; Not busy
            mov     dx, 92E8h
            mov     ax, 5555h
            out     dx, ax
            in      ax, dx
            .if     < ax eq 5555h >     ; 8514 found
                mov     dx, 42E8h
                in      al, dx          ; Get display info

                mov     ah, al
                and     al, 70h
                .if     < al ne 70h >   ; Display attached to 8514/A
                    .if     < al eq 10h > ;D184
                        mov     cl, Mono8507_8604 ; 8514/A with 8507/8604 ;D184
                    .endif              ;D184
                    .if     < al eq 20h > ;D184
                        mov     cl, Color8514 ; 8514/A with 8514
                    .endif
                    .if     < al eq 30h > ;D184
                        mov     cl, Color8515 ; 8514/A with 8515 ;D184
                    .endif              ;D184
                    .if     < al eq 50h > ;D184
                        mov     cl, Mono8503 ; 8514/A with 8503
                    .endif
                    .if     < al eq 60h >
                        mov     cl, Color8512_8513 ; 8514/A with 8512/3
                    .endif

                    test    ah, 80h     ; 512k or 1MB ?
                    .if     < nz >
                        mov     ch, MEM_1MB
                    .endif
                .endif
            .endif
        .endif

        mov     ax, cx
        ret
_Query8514A ENDP

        ENDIF                           ; IFDEF VDHVGA_OR_VDH8514A

        IFDEF   VDH8514A                ;Start of @S24 changes

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: AccessDisplayMask                                 */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set or read physical display mask                */
;/*                                                                     */
;/*  FUNCTION: AccessDisplayMask is called to query or set the physical */
;/*            display mask setting.                                    */
;/*                                                                     */
;/*  ENTRY POINT: AccessDisplayMask                                     */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             WORD  Direction ( GET or SET )                          */
;/*             DWORD DisplayMask ( far pointer to dword )              */
;/*                                                                     */
;/*  EXIT-NORMAL: Display mask is set or returned                       */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
            PUBLIC  ACCESSDISPLAYMASK
ACCESSDISPLAYMASK PROC FAR

            enter   2, 0                ; Allocate 1 word temporary storage
            push    es
            push    di

            les     di, ParameterPacket ; es:di = underscore scan line

            .if     < Direction eq SET >

                mov     dx,02EAh        ; Set address
                mov     al,BYTE PTR es:[di].DisplayMask
                out     dx,al           ;Set the mask

            .else

                sub     ax,ax
                mov     dx,02EAh        ; Set address
                in      al,dx           ;Get the mask
                mov     WORD PTR es:[di].DisplayMask,ax
                sub     ax,ax
                mov     WORD PTR es:[di].DisplayMask+2,ax

            .endif

            pop     di
            pop     es
            leave
            ret     6

ACCESSDISPLAYMASK ENDP

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: AccessCLUT for 8514/A                             */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set or read physical color lookup table          */
;/*                                                                     */
;/*  FUNCTION: AccessCLUT is called to query or set the physical        */
;/*            color lookup table.                                      */
;/*                                                                     */
;/*  ENTRY POINT: AccessCLUT                                            */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             WORD   Direction ( GET or SET )                         */
;/*             DWORD  ColorLookupTable  ( far pointer to structure )   */
;/*                      DWORD DataArea ( far pointer to table )        */
;/*                      WORD  FirstEntry                               */
;/*                      WORD  NumEntries                               */
;/*                                                                     */
;/*  EXIT-NORMAL: Color lookup table is altered or queried              */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/

paldata     equ     02EDh               ;Palette data Register ;@S24
paladdr     equ     02ECh               ;Palette Address Register ;@S24
rpaladdr    equ     02EBh               ;Palette Address Register ;@S24

            PUBLIC  ACCESSCLUT
ACCESSCLUT  PROC    FAR

            push    bp
            mov     bp, sp
            push    es
            push    di

            les     di, ParameterPacket ; es:di = palette packet

            mov     cx,WORD PTR es:[di].NumEntries ; # of RBGx entries
            mov     ax, WORD PTR es:[di].FirstEntry ; starting reg
            les     di, DWORD PTR es:[di].DataArea
            cld

            .if     < Direction eq SET >
                push    ds
                push    si
                mov     si,es
                mov     ds,si
                mov     si,di

                .repeat
                    mov     dx,paladdr  ;Palette address reg
                    cli
                    out     dx,al       ;Put out address
                    mov     dx,paldata  ;Point to data reg for RGB triplet
                    inc     ax          ;set next palette address
                    push    ax
                    lodsb
                    shr     al,1
                    shr     al,1        ;Reduce to hardware range
                    out     DX,AL       ;Put out the red
                    lodsb
                    shr     al,1
                    shr     al,1        ;Reduce to hardware range
                    xchg    AH,AL       ;Blue is first in the definition
                    lodsb
                    shr     al,1
                    shr     al,1        ;Reduce to hardware range
                    out     DX,AL       ;Put out the green
                    xchg    AH,AL       ;Get the blue back
                    out     DX,AL       ;Put out the blue
                    sti
                    lodsb               ;Discard extra byte
                    pop     ax
                .loop                   ;Go back for more

                pop     si
                pop     ds
            .else                       ;Read the color registers

                .repeat
                    mov     dx,rpaladdr ;Palette read address reg
                    cli
                    out     dx,al       ;Put out address
                    mov     dx,paldata  ;Point to data reg for RGB triplet
                    inc     ax          ;set next palette address
                    push    ax          ;save palette address
                    in      al,dx       ;do triplet - get RED
                    shl     al,1        ;Align Data
                    shl     al,1        ;Align Data
                    stosb               ;save RED
                    in      al,dx       ;- get GREEN
                    shl     al,1        ;Align Data
                    shl     al,1        ;Align Data
                    xchg    ah,al       ;keep GREEN
                    in      al,dx       ;- get BLUE
                    sti
                    shl     al,1        ;Align Data
                    shl     al,1        ;Align Data
                    stosb               ;save BLUE
                    xchg    ah,al       ;restore GREEN
                    stosb               ;save GREEN
                    mov     al,0        ;Setup 4th byte
                    stosb
                    pop     ax          ;restore palette address
                .loop

            .endif

            pop     di
            pop     es
            pop     bp
            ret     6

ACCESSCLUT  ENDP

        ELSE                            ; Not VDH8514A ;End of @S24 changes

            IFDEF   VDHVGA              ; Read/write hardware

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: _HardwareColumns                                  */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Get number of text columns in current mode       */
;/*                                                                     */
;/*  FUNCTION: _HardwareColumns is called by routines who need to know  */
;/*            whether the current mode has 40 or 80 character columns. */
;/*                                                                     */
;/*  ENTRY POINT: _HardwareColumns                                      */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: NONE                                                        */
;/*                                                                     */
;/*  EXIT-NORMAL: AX = Number of character columns ( 40 or 80 )         */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
                PUBLIC  _HardwareColumns
_HardwareColumns PROC   FAR

;
;+----------------------------------------------------------------------------+
;|  Determine number of character columns by reading Sequencer register       |
;|  Dot Clock bit (b3) of Clocking Mode Register: 0 = 80 col, 1 = 40 col      |
;+----------------------------------------------------------------------------+
;
                mov     dx, SeqAddressPort ; Sequencer address register
                mov     al, IndClockModeReg ; Clocking Mode index
                cli
                out     dx, al

                mov     dx, SeqDataPort ; Sequencer data register
                in      al, dx
                test    al, 8           ; Check Dot Clock bit
                .if     < z >
                    mov     ax, 80      ; 80 column mode
                .else
                    mov     ax, 40      ; 40 column mode
                .endif

                sti
                ret

_HardwareColumns ENDP

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: _HardwareColor                                    */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Determine if current mode is color or monochrome */
;/*                                                                     */
;/*  FUNCTION: _HardwareColor is called by routines who need to know    */
;/*            whether the current mode is color or monochrome.         */
;/*                                                                     */
;/*  ENTRY POINT: _HardwareColor                                        */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: NONE                                                        */
;/*                                                                     */
;/*  EXIT-NORMAL: AX = 1 - color, 0 - monochrome                        */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
                PUBLIC  _HardwareColor
_HardwareColor  PROC    FAR

;
;+----------------------------------------------------------------------------+
;|  Determine whether color or monochrome mode to determine which             |
;|  ports should be used.  This is done by checking the                       |
;|  I/O Address Select bit (b0) of the Miscellaneous Output Register:         |
;|      b0: 0 = Monochrome emulation mode, 1 = Color emulation mode           |
;+----------------------------------------------------------------------------+
;
                mov     dx, MiscOutputRegRead ; Read Miscellaneous Output Register
                in      al, dx
                and     ax, 1           ; Return 1 - color, 0 - monochrome

                ret

_HardwareColor  ENDP

            ENDIF                       ; IFDEF VDHVGA

            IFDEF VDHEGA_OR_VDHVGA                                      ;@T72

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: SetMapMask                                        */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Address select a bit plane to read or write      */
;/*                                                                     */
;/*  FUNCTION: SetMapMask is called by SaveRestorePVB in order to address*/
;/*            a specific bit plane in graphics mode during a 3xBox     */
;/*            display buffer save or restore                           */
;/*                                                                     */
;/*  ENTRY POINT: SetMapMask                                            */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             WORD ReadMapMask  ( 0 - 3, 4 = write )                  */
;/*             WORD WriteMapMask ( 1, 2, 4, or 8 )                     */
;/*                                                                     */
;/*  EXIT-NORMAL: Bit plane selected for read or write                  */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
            PUBLIC  SETMAPMASK
SETMAPMASK  PROC    FAR

; ENTRY: SS:SP = offset selector mask
            push    bp
            mov     bp, sp
            push    dx
            push    ax

            cli

            .if     < ReadMap eq 0 > or
            .if     < MapMask eq 1 >
;
;+----------------------------------------------------------------------------+
;|  Set graphics mode register just for the first bit plane                   |
;+----------------------------------------------------------------------------+
;
                mov     dx, GraphAddressPort
                mov     ax, 0001h       ; Start from Set/Reset regs.    ;@T47
                .repeat                 ;                               ;@T47
                    out     dx, al      ; Setup address port            ;@T47
                    inc     dx          ; Index to data port            ;@T47
                    inc     ax          ; Index to next address port    ;@T47
                    xchg    al,ah       ;                               ;@T47
                    out     dx,al       ; Clear Graphics register       ;@T47
                    dec     dx          ; Back to address port          ;@T47
                    xchg    al,ah       ;                               ;@T47
                    cmp     al,6        ;                               ;@T47
                .until  <z>             ;                               ;@T47

                .if     < MapMask eq 1 >; 1st write request?            ;@TL3
                    mov     al,8        ;                               ;@TL3
                    out     dx,al       ; Index to Bit Mask register    ;@TL3
                    inc     dx          ;                               ;@TL3
                    mov     al,0ffh     ;                               ;@TL3
                    out     dx,al       ; Allow write to all bits       ;@TL3
                .endif                  ;                               ;@TL3
            .endif                      ;                               ;@T47

            .if     < ReadMap ne WriteFunction >
;
;+----------------------------------------------------------------------------+
;|  Reading from display buffer, address select specified bit plane           |
;+----------------------------------------------------------------------------+
;
                mov     dx, SeqAddressPort
                mov     al, 02h         ; Memory map register in sequencer
                out     dx, al
                inc     dx
                mov     al, 0Fh
                out     dx, al          ; Memory map = 00001111

;
;+----------------------------------------------------------------------------+
;|  Address select specified bit plane to read                                |
;+----------------------------------------------------------------------------+
;
                mov     dx, GraphAddressPort
                mov     al, 04h         ; Read map select register
                out     dx, al
                inc     dx
                mov     al, ReadMap
                out     dx, al          ; Read map select  = 0, 1, 2, 3
            .else
;
;+----------------------------------------------------------------------------+
;|  Writing to display buffer, address select specified bit plane             |
;+----------------------------------------------------------------------------+
;
                mov     dx, SeqAddressPort
                mov     al, 02h         ; Memory map register in sequencer
                out     dx, al
                inc     dx
                mov     al, MapMask
                out     dx, al          ; Memory map
            .endif

            sti

            pop     ax
            pop     dx
            pop     bp
            ret     4                   ; Remove 2 words from stack

SETMAPMASK  ENDP

            ENDIF  ; VDHEGA_OR_VDHVGA                                   ;@T72

;@T39       IFDEF  FONT_SUPPORT         ;@S4

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: _CharFontBegin                                    */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Address the font buffer                          */
;/*                                                                     */
;/*  FUNCTION: _CharFontBegin is called by routines in order to address */
;/*            the font buffer for writing or reading                   */
;/*                                                                     */
;/*  ENTRY POINT: _CharFontBegin                                        */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: NONE                                                        */
;/*                                                                     */
;/*  EXIT-NORMAL: Font buffer is address selected at A0000              */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
            PUBLIC  _CharFontBegin
_CharFontBegin PROC FAR

            push    dx
            mov     dx, GraphAddressPort
            mov     ax, 0204h

            cli
            out     dx, ax              ; Read Map Select register

            mov     ax, 0005h
            out     dx, ax              ; Graphics Mode register

            mov     ax, 0406h
            out     dx, ax              ; Graphics Misc register

            mov     dx, SeqAddressPort
            mov     ax, 0402h           ; write font to bp only bit plane 0
            out     dx, ax              ; Write Map Select

            mov     ax, 0404h
            out     dx, ax              ; Turn on odd/even

            sti

            pop     dx
            ret

_CharFontBegin ENDP

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME:  CharFontEnd                                      */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Deselect font buffer                             */
;/*                                                                     */
;/*  FUNCTION:  CharFontEnd and  CharFontEnd2 are called following      */
;/*            completion of accessing the font buffer.                 */
;/*                                                                     */
;/*  ENTRY POINTS:  CharFontEnd,  CharFontEnd2                          */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: NONE                                                        */
;/*                                                                     */
;/*  EXIT-NORMAL: font buffer address is deselected                     */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
            PUBLIC  CHARFONTEND
CHARFONTEND PROC    FAR
            push    bp
            mov     bp, sp
            mov     cx, 0A06h           ; Setup mono buffer with chaining
            .if     < ColorMonoMode eq COLOR_MODE >
                or      cx, 0400h       ; Setup color buffer
            .endif
            pop     bp

            PUBLIC  CHARFONTEND2
CHARFONTEND2 LABEL  FAR

            push    ax

            mov     dx, GraphAddressPort
            mov     ax, 0004h

            cli
            out     dx, ax              ; Read Map Select register

            mov     ax, 1005h
            out     dx, ax              ;Graphics Mode register

            mov     ax, cx
            out     dx, ax              ;Graphics Misc register


            mov     dx, SeqAddressPort
            mov     ax, 0302h
            out     dx, ax              ;Write Map Select

            mov     ax, 0004h
            out     dx, ax              ;Turn off odd/even

            sti
            pop     ax

            ret     2

CHARFONTEND ENDP

;@T39       ENDIF  FONT_SUPPORT


            IFDEF   BLINK_SUPPORT       ;@S4

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: AccessBlink                                       */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set or read physical blink vs. BG intensity      */
;/*                                                                     */
;/*  FUNCTION: AccessBlink is called to query or set the physical       */
;/*            blink versus background intensity setting                */
;/*                                                                     */
;/*  ENTRY POINT: AccessBlink                                           */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             WORD  Direction ( GET or SET )                          */
;/*             DWORD Blink ( far pointer to word )                     */
;/*                                                                     */
;/*  EXIT-NORMAL: Blink vs. BG intensity is set or returned             */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
                PUBLIC  ACCESSBLINK
ACCESSBLINK     PROC    FAR

                push    bp
                mov     bp, sp
                push    es
                push    di

                les     di, ParameterPacket ;es:di = Blink setting
;
;+----------------------------------------------------------------------------+
;|  Address Attribute Mode Control Register in Attribute Controller Registers |
;+----------------------------------------------------------------------------+
;
                @SetAttAddressPort      ; Attribute Address Register
                mov     al, IndAttModeCtl ; Address Attribute Mode Control Register
                out     dx, al          ; Set up for get mode ctl color
;
;+----------------------------------------------------------------------------+
;|  Set/Read Attribute Mode Control Register                                  |
;+----------------------------------------------------------------------------+
;
                mov     dx, AttDataReadPort ; Read current mode ctl setting

                IFDEF   VDHVGA          ; Read/write hardware

                    in      al, dx      ; Read reserved bits

                ELSE

                    xor     al, al      ; Zero reserved bits

                ENDIF                   ; IFDEF VDHVGA

                .if     < Direction eq SET >

                    and     al, 11110111B ; Select background intensity
                    .if     < <WORD PTR es:[di].Blink> eq 0 >
                        or      al, 00001000B ; Enable blink
                    .endif

                    mov     dx, AttDataWritePort ; Set the hardware
                    out     dx, al

                    IFDEF   VDHVGA      ; Read/write hardware

                    .else
                        test    al, 00001000B ; Check setting
                        .if     < z >
                            mov     WORD PTR es:[di].Blink, 1 ; Report background intensity
                        .else
                            mov     WORD PTR es:[di].Blink, 0 ; Report blink enable
                        .endif

                    ENDIF               ; IFDEF VDHVGA

                .endif

                @VideoOn

                sti

                pop     di
                pop     es
                pop     bp
                ret     8

ACCESSBLINK     ENDP

            ENDIF

            IFDEF   OVERSCAN_SUPPORT    ;@S4

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: AccessOverscan                                    */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set or read physical border color                */
;/*                                                                     */
;/*  FUNCTION: AccessOverscan is called to query or set the physical    */
;/*            overscan color                                           */
;/*                                                                     */
;/*  ENTRY POINT: AccessOverscan                                        */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             WORD  Direction ( GET or SET )                          */
;/*             DWORD Overscan ( far pointer to word )                  */
;/*                                                                     */
;/*  EXIT-NORMAL: Overscan color is set or returned                     */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
                PUBLIC  ACCESSOVERSCAN
ACCESSOVERSCAN  PROC    FAR

                push    bp
                mov     bp, sp
                push    es
                push    di

                les     di, ParameterPacket ; es:di = Overscan color
;
;+----------------------------------------------------------------------------+
;|  Address Overscan Color Register in Attribute Controller Registers         |
;+----------------------------------------------------------------------------+
;
                @SetAttAddressPort      ; Attribute Address Register
                mov     al, IndOverscanColor ; Address Overscan Color Register
                out     dx, al          ; Set up for get mode ctl color
;
;+----------------------------------------------------------------------------+
;|  Set/Read Overscan Color Register                                          |
;+----------------------------------------------------------------------------+
;
                .if     < Direction eq SET >

                    mov     al, BYTE PTR es:[di].Overscan

                    mov     dx, AttDataWritePort ; Set the hardware
                    out     dx, al

                    IFDEF   VDHVGA      ; Read/write hardware

                    .else
                        mov     dx, AttDataReadPort ; Read current setting
                        in      al, dx

                     ;;;mov     BYTE PTR es:[di].Overscan, al           ;@B72
                        xor     ah,ah                                   ;@B72
                        mov     WORD PTR es:[di].Overscan, ax           ;@B72

                    ENDIF               ; IFDEF VDHVGA

                .endif

                @VideoOn

                sti

                pop     di
                pop     es
                pop     bp
                ret     8

ACCESSOVERSCAN  ENDP

            ENDIF

            IFDEF   UNDERSCORE_SUPPORT  ;@S4

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: AccessUnderscore                                  */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set or read physical underscore scan line no.    */
;/*                                                                     */
;/*  FUNCTION: AccessUnderscore is called to query or set the physical  */
;/*            underscore scan line                                     */
;/*                                                                     */
;/*  ENTRY POINT: AccessUnderscore                                      */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             WORD  Direction ( GET or SET )                          */
;/*             DWORD Underscore ( far pointer to word )                */
;/*                                                                     */
;/*  EXIT-NORMAL: Underscore scan line is set or returned               */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
                PUBLIC  ACCESSUNDERSCORE
ACCESSUNDERSCORE PROC   FAR

                enter   2, 0            ; Allocate 1 word of temporary storage
                push    es
                push    di

                les     di, ParameterPacket ; es:di = underscore scan line

                .if     < ColorMode eq TRUE > ; Determine port address fixup
                    mov     ColorMonoFixup, ColorAdjustment
                .else
                    mov     ColorMonoFixup, MonoAdjustment
                .endif

;
;+----------------------------------------------------------------------------+
;|  Address Underline Location Register in CRT Controller Registers           |
;+----------------------------------------------------------------------------+
;
                mov     dx, CRTCtlAddressReg ; CRT Controller Address Register
                add     dx, ColorMonoFixup ; Port address fixup
                mov     al, IndUnderlineLoc ; Address Underline Location Register
                cli
                out     dx, al

;
;+----------------------------------------------------------------------------+
;|  Set/Read Underline Location Register                                      |
;+----------------------------------------------------------------------------+
;
                mov     dx, CRTCtlDataReg ; CRT Controller Data Register
                add     dx, ColorMonoFixup ; Port address fixup         ;@B72

                IFDEF   VDHVGA          ; Read/write hardware

                    in      al, dx      ; Read reserved bits

                ELSE

                    xor     al, al      ; Zero reserved bits

                ENDIF                   ; IFDEF VDHVGA

                .if     < Direction eq SET >

                    and     al, 11100000B ; Clear bits we will set

                    or      al, BYTE PTR es:[di].Underscore ; Set the hardware
                    out     dx, al

                    IFDEF   VDHVGA      ; Read/write hardware

                    .else
                        and     al, 00011111B ; Isolate underscore scan line
                     ;;;mov     BYTE PTR es:[di].Underscore, al         ;@B72
                        xor     ah,ah                                   ;@B72
                        mov     WORD PTR es:[di].Underscore, ax         ;@B72

                    ENDIF               ; IFDEF VDHVGA

                .endif

                sti

                pop     di
                pop     es
                leave                   ; Deallocate temporary storage
                ret     8

ACCESSUNDERSCORE ENDP

            ENDIF

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: AccessVideoEnable                                 */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set or read physical video enable                */
;/*                                                                     */
;/*  FUNCTION: AccessVideoEnable is called to query or set the physical */
;/*            video enable setting.                                    */
;/*                                                                     */
;/*  ENTRY POINT: AccessVideoEnable                                     */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             WORD  Direction ( GET or SET )                          */
;/*             DWORD VideoEnable ( far pointer to word )               */
;/*                                                                     */
;/*  EXIT-NORMAL: Video enable is set or returned                       */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
            PUBLIC  ACCESSVIDEOENABLE
ACCESSVIDEOENABLE PROC FAR

            push    bp
            mov     bp, sp
            push    es
            push    di

            les     di, ParameterPacket ; es:di = underscore scan line

            cli                         ; clear interrupts

;IFDEF   VDHVGA                          ; Read/write hardware

;        mov     dx, SeqAddressPort      ; Sequencer Address Register
;        mov     al, IndClockModeReg     ; Clocking mode register
;        out     dx, al

;        mov     dx, SeqDataPort         ; Sequencer Data Register

;        in      al, dx                  ; Read reserved bits

;        .if     < Direction eq SET >

;            and     al, 11011111B       ; Enable video

;            .if     < <WORD PTR es:[di].VideoEnable> eq 0 >
;                or      al, 00100000B   ; Disable video
;            .endif

;            out     dx, al              ; Set the hardware
;        .else
;            mov     WORD PTR es:[di].VideoEnable, 0 ; Preset Report Disable video
;            test    al, 00100000B
;            .if     < z >
;                inc     WORD PTR es:[di].VideoEnable ; Set Report Enable video
;            .endif
;        .endif

;ELSE

            IFDEF   VDHEGA_OR_VDHVGA

                @SetAttAddressPort      ;Set the Attribute Address Port

                IFDEF   VDHVGA          ;@C21

                    .if     < Direction eq GET > ;@C21
                        mov     dx,AttDataReadPort ;@C21
                        in      al,dx   ;@C21
                        mov     WORD PTR es:[di].VideoEnable, 0 ;Disabled  @C21
                        test    al, 20h ;@C21
                        .if     < nz >  ;@C21
                            inc     WORD PTR es:[di].VideoEnable ;Enabled   @C21
                        .endif          ;@C21
                    .else               ;@C21

                    ENDIF               ;@C21

                    sub     ax,ax       ;Preset Disable video
                    .if     < <WORD PTR es:[di].VideoEnable> ne ax >
                        mov     al, 20h ;Set Enable video
                    .endif
                    out     dx, al      ;Write to the port

                    IFDEF   VDHVGA      ;@C21
                    .endif              ;@C21
                ENDIF                   ;@C21

            ENDIF                       ; IFDEF VDHEGA

;ENDIF                                   ; IFDEF VDHVGA

            sti
            pop     di
            pop     es
            pop     bp
            ret     8

ACCESSVIDEOENABLE ENDP

            IFDEF   VDHVGA

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: AccessCLUT for VGA                        @S24    */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set or read physical color lookup table          */
;/*                                                                     */
;/*  FUNCTION: AccessCLUT is called to query or set the physical        */
;/*            color lookup table.                                      */
;/*                                                                     */
;/*  ENTRY POINT: AccessCLUT                                            */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             WORD   Direction ( GET or SET )                         */
;/*             DWORD  ColorLookupTable  ( far pointer to structure )   */
;/*                      DWORD DataArea ( far pointer to table )        */
;/*                      WORD  FirstEntry                               */
;/*                      WORD  NumEntries                               */
;/*                                                                     */
;/*  EXIT-NORMAL: Color lookup table is altered or queried              */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/

                PUBLIC  ACCESSCLUT
ACCESSCLUT      PROC    FAR

                push    bp
                mov     bp, sp
                push    es
                push    di

                les     di, ParameterPacket ; es:di = palette packet

                mov     cx,WORD PTR es:[di].NumEntries ; # of triplets  ;B705063
                mov     ax, WORD PTR es:[di].FirstEntry ; starting reg  ;B705063
                les     di, DWORD PTR es:[di].DataArea

                .if     < Direction eq SET > ;B705063
                    mov     dx, PELAddressWrite ;B705063
                    cli                 ;B705063
                    out     dx, al      ;B705063
                    mov     dx, PELDataRegister ; Get data register ;B705063
                    .repeat             ;B705063
                        cli             ;B705063
                        mov     al, BYTE PTR es:[di] ;B705063
                        out     dx, al  ; Set register value ;B705063
                        inc     di      ;B705063
                        mov     al, BYTE PTR es:[di] ;B705063
                        out     dx, al  ; Set register value ;B705063
                        inc     di      ;B705063
                        mov     al, BYTE PTR es:[di] ;B705063
                        out     dx, al  ; Set register value ;B705063
                        sti             ;B705063
                        inc     di      ;B705063
                    .loop               ;B705063
                .else                   ;B705063
                    cld                 ;B705063
                    mov     dx, PELAddressRead ;B705063
                    cli                 ;B705063
                    out     dx, al      ;B705063
                    mov     dx, PELDataRegister ; Get data register ;B705063
                    .repeat             ;B705063
                        cli             ;B705063
                        in      al, dx  ; Set register value ;B705063
                        and     al, 3Fh ; Isolate color ( 6 bits ) ;B705063
                        stosb           ;B705063
                        in      al, dx  ; Set register value ;B705063
                        and     al, 3Fh ; Isolate color ( 6 bits ) ;B705063
                        stosb           ;B705063
                        in      al, dx  ; Set register value ;B705063
                        sti             ;B705063
                        and     al, 3Fh ; Isolate color ( 6 bits ) ;B705063
                        stosb           ;B705063
                    .loop               ;B705063
                .endif

                pop     di
                pop     es
                pop     bp
                ret     6

ACCESSCLUT      ENDP

            ENDIF

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: AccessHardware                                    */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set or read physical indexed registers           */
;/*                                                                     */
;/*  FUNCTION: AccessHardware is called to query or set the physical    */
;/*            indexed registers - Sequencers, Attributes, CRTs, or     */
;/*            Graphics                                                 */
;/*                                                                     */
;/*  ENTRY POINT: AccessHardware                                        */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             DWORD  RegAddress ( far pointer to structure )          */
;/*                       WORD RegAddressPort                           */
;/*                       WORD RegDataPort                              */
;/*                       WORD RegColorAdjust                           */
;/*                       WORD RegFlags                                 */
;/*             WORD   DataType ( BYTES or WORDS )                      */
;/*             WORD   Direction ( GET or SET )                         */
;/*             DWORD  RegData ( far pointer to structure )             */
;/*                       DWORD DataArea  ( far pointer to data table ) */
;/*                       WORD  FirstEntry                              */
;/*                       WORD  NumEntries                              */
;/*                                                                     */
;/*  EXIT-NORMAL: Indexed registers are altered or queried              */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
            PUBLIC  ACCESSHARDWARE
ACCESSHARDWARE PROC FAR

            push    bp
            mov     bp, sp
            push    es
            push    di
            push    ds
            push    si

            les     di, ParameterPacket ; es:di = data packet
            lds     si, AddressPacket   ; ds:di = address packet

            mov     bx, WORD PTR  es:[di].FirstEntry ; Get starting reg
            mov     cx, WORD PTR  es:[di].NumEntries ; Get number of regs
            les     di, DWORD PTR es:[di].DataArea

;B717771    cli

            .if     < ds:[si].RegFlags eq Attributes_CMD >
;
;+----------------------------------------------------------------------------+
;|  To access the attribute address register, an 'in' must be issued to       |
;|  the Attribute Controller at address 03BA for mono or 03DA for color.      |
;+----------------------------------------------------------------------------+
;
                mov     dx, AttCtlInitializeReg ; Feature Control Register - init AttCtl flip-flop
                .if     < ColorMode eq TRUE >
                    add     dx, ColorAdjustment
                .endif
            .endif

            push    dx                  ;@B19

HARDWARE_REG:
            cli                         ;B717771
            .if     < ds:[si].RegFlags eq Attributes_CMD >
                pop     dx              ;@B19
                in      al, dx          ; Read port to reset flip-flop
                push    dx              ;@B19
            .endif

;@B19       push    dx                  ; Save reset flip-flop port

            mov     dx, ds:[si].RegAddressPort ; Address Register
            .if     < ColorMode eq TRUE >
                add     dx, ds:[si].RegColorAdjust
            .endif
            mov     al, bl              ; Address Palette Reg ( 00 - 0F )

;MJS P VGA                                                      ;@B19
IFDEF       VDHVGA                      ;@B19
                                        ; wait for vertical retrace to avoid glitching VRAM ;@B19
            .if     <al EQ 10h> AND     ;@B19
            .if     <dx EQ AttAddressPort> ;@B19
                call    VGAWait         ;@B19
            .endif                      ;@B19
ENDIF                                   ;@B19
;MJS P VGA                                                      ;@B19

            out     dx, al              ; Set up for get palette reg

            mov     dx, ds:[si].RegDataPort ; Address Register
            .if     < ColorMode eq TRUE >
                add     dx, ds:[si].RegColorAdjust
            .endif

            .if     < Direction eq SET >
                mov     al, BYTE PTR es:[di]
                out     dx, al
            .else

                IFDEF   VDHVGA          ; Read/write hardware

                    in      al, dx
                    .if     < WordByte eq WORDS >
                        xor     ah, ah
                        mov     WORD PTR es:[di], ax
                    .else
                        mov     BYTE PTR es:[di], al
                    .endif

                ENDIF                   ; IFDEF VDHVGA

            .endif

            inc     bx
            .if     < WordByte eq WORDS >
                inc     di              ; Point to next byte
            .endif
            inc     di                  ; Point to next byte

;@B19       pop     dx                  ; Retrieve reset flip-flop port
            sti                         ;B717771
            loop    HARDWARE_REG


            pop     dx                  ;@B19

            cli                         ;B717771

            .if     < ds:[si].RegFlags eq Sequencers_CMD > AND  ; @tb25
            .if     < Direction eq SET >                        ; @tb25

;J-TS00 IF VDHVGA AND (1 - VDHINIT)                                             ;@DRW
            push    ds                                                  ;@DRW
            mov     ax, seg _SVGAPresent
            mov     ds, ax
            cmp     _SVGAPresent, TSENG_ADAPTER                         ;@DRW
            pop     ds                                                  ;@DRW
            je      @F                                                  ;@DRW
            @FixVGABug
@@:
;J-TS00 ENDIF   ;VDHVGA                                                         ;MS00

                mov     dx, SeqAddressPort ; Sequencer address port
                mov     al, 0           ; Reset register index
                out     dx, al
                mov     dx, SeqDataPort ; Sequencer data port
                mov     al, 3           ; Enable Sequencers again
                out     dx, al
            .endif

;@C21 ******.if     < ds:[si].RegFlags eq Attributes_CMD >
;@C21 ******    @VideoOn
;@C21 ******.endif

            sti

            pop     si
            pop     ds
            pop     di
            pop     es
            pop     bp
            ret     14

ACCESSHARDWARE ENDP

; MJS P VGA
IFDEF       VDHVGA
;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: VGAWait                                           */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: wait for video retrace before a write to port    */
;/*                    3C0h, register 10h                               */
;/*                                                                     */
;/*  FUNCTION:                                                          */
;/*                                                                     */
;/*  ENTRY POINT: VGAWait                                               */
;/*    LINKAGE:   CALL NEAR                                             */
;/*                                                                     */
;/*  INPUT: none                                                        */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
            PUBLIC  VGAWait
VGAWait     PROC    NEAR                ;@B19
            sti
            push    ax
            push    cx
            push    dx
            mov     dx, FeatureControlWrite
            .if     < ColorMode eq TRUE >
                add     dx, 20h         ; use color ports
            .endif
            xor     cx,cx               ;time out in case a card never sets this bit
VGAWait1:
            in      al,dx
            test    al,8                ; look for retrace bit
            loopnz  VGAWait1            ; wait for retrace to end
            xor     cx,cx               ; time out in case a card never sets this bit
VGAWait2:
            sti
            nop
            nop                         ;486     work around            ;@T49
            cli
            in      al,dx
            test    al,8                ; look for retrace bit
            loopz   VGAWait2            ;wait for retrace to begin again

            pop     dx
            pop     cx
            pop     ax
            ret
VGAWait     ENDP
ENDIF
; MJS P VGA

        ENDIF                           ; IFDEF VDH8514A

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: AccessRegister                                    */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set or read physical non-indexed register        */
;/*                                                                     */
;/*  FUNCTION: AccessRegister is called to query or set the physical    */
;/*            non-indexed register specified                           */
;/*                                                                     */
;/*  ENTRY POINT: AccessRegister                                        */
;/*    LINKAGE:   CALL FAR                                              */
;/*                                                                     */
;/*  INPUT: (Passed on stack)                                           */
;/*             DWORD  RegAddress ( far pointer to structure )          */
;/*                       WORD RegAddressPort                           */
;/*                       WORD RegDataPort                              */
;/*                       WORD RegColorAdjust                           */
;/*                       WORD RegFlags                                 */
;/*             WORD   Direction ( GET or SET or SETWORD )              */
;/*             DWORD  RegData ( far pointer to data )                  */
;/*                                                                     */
;/*  EXIT-NORMAL: Non-indexed register is altered or queried            */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: NONE                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
        PUBLIC  ACCESSREGISTER
ACCESSREGISTER PROC FAR

        push    bp
        mov     bp, sp
        push    es
        push    di
        push    ds
        push    si

        les     di, ParameterPacket     ; es:di = data packet
        lds     si, AddressPkt          ; ds:si = address packet

        mov     dx, ds:[si].RegDataPort ; Register port

        cli

        .if     < Direction eq SET >

            IFNDEF  VDHMPA_OR_VDHCGA
                IFNDEF  VDH8514A

                    .if     < ds:[si].RegDataPort eq MiscOutputRegWrite >
                        push    dx      ; Save register address
                        mov     dx, SeqAddressPort ; Sequencer address port
                        mov     al, 0   ; Reset register index
                        out     dx, al
                        mov     dx, SeqDataPort ; Sequencer data port
                        mov     al, 1   ; Synchronous reset
                        out     dx, al

;@S28f                  IFDEF   VDHVGA  ;@S28

;@S28f                      mov     dx,MiscOutputRegRead ;@S28
;@S28f                      in      al,dx ;@S28
;@S28f                      and     al,08h ;@S28

;@S28f                      pop     dx  ; Retrieve register address ;@S28
;@S28f                      or      al, BYTE PTR es:[di] ; Set miscoutput reg ;@S28

;@S28f                  ELSE            ;not VDHVGA ;@S28

                            pop     dx  ; Retrieve register address
                            mov     al, BYTE PTR es:[di] ; Set miscoutput register

;@S28f                  ENDIF           ;@S28

                        out     dx, al

;J-TS00 IF VDHVGA AND (1 - VDHINIT)                                             ;@DRW
                push    ds                                              ;@DRW
                mov     ax, seg _SVGAPresent                            ;@DRW
                mov     ds, ax                                          ;@DRW
                cmp     _SVGAPresent, TSENG_ADAPTER                     ;@DRW
                pop     ds                                              ;@DRW
                je      @F                                              ;@DRW
                @FixVGABug
@@:
;J-TS00 ENDIF   ;VDHVGA                                                         ;MS00

                        mov     dx, SeqAddressPort ; Sequencer address port
                        mov     al, 0   ; Reset register index
                        out     dx, al
                        mov     dx, SeqDataPort ; Sequencer data port
                        mov     al, 3   ; Normal operation
                        out     dx, al
                    .else

                    ENDIF
                ENDIF

                mov     al, BYTE PTR es:[di]
                out     dx, al

                IFNDEF  VDHMPA_OR_VDHCGA
                    IFNDEF  VDH8514A

                    .endif

                ENDIF
            ENDIF

        .else
            .if     < Direction eq SETWORD >

                mov     ax, word ptr es:[di]
                out     dx,ax

            .else                       ;< Direction eq GET >

                in      al, dx
                stosb

            .endif
        .endif

        sti

        pop     si
        pop     ds
        pop     di
        pop     es
        pop     bp
        ret     10

ACCESSREGISTER ENDP

LG_SET_RESET            EQU     00H
LG_ENABLE_SET_RESET     EQU     01H
LG_COMP                 EQU     02H
LG_FUNCTION             EQU     03H
LG_MODE                 EQU     05H
LG_READ_MAP             EQU     04H
LG_BIT_MASK             EQU     08H
LG_COMMAND              EQU     0BH

LS_CLOCK_MODE           EQU     01H
LS_MAP_MASK             EQU     02H

LC_OVERFLOW             EQU     07H
LC_MAX_SCAN_LINE        EQU     09H
LC_START_HIGH           EQU     0CH
LC_START_LOW            EQU     0DH
LC_LINE_COMP            EQU     18H


;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: SetupAPAWrite                                     */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Setup VGA registers to update APA.               */
;/*                                                                     */
;/*  INPUT: None                                                        */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
SetupAPAWrite   proc    far
        public  SetupAPAWrite

        push    ax                      ; save ax, dx
        push    dx

        mov     dx, GraphAddressPort    ; set VGA port address
        mov     al, LG_FUNCTION         ; set rotate 0
        mov     ah, 0
        out     dx, ax
        mov     al, LG_BIT_MASK         ; set bit mask ffh
        mov     ah, 0ffh
        out     dx, ax

        mov     dx, SeqAddressPort      ; set VGA port address
        mov     al, LS_MAP_MASK         ; set map mask ffh
        mov     ah, 0ffh
        out     dx, ax

        pop     dx                      ; restore ax, dx
        pop     ax
        ret

SetupAPAWrite   endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: SetupAPAMove                                      */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Setup VGA registers to move APA.                 */
;/*                                                                     */
;/*  INPUT: None                                                        */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
SetupAPAMove    proc    far
        public  SetupAPAMove

        push    ax                      ; save ax, dx
        push    dx

        mov     dx, GraphAddressPort    ; set VGA port address
        mov     al, LG_MODE             ; set write mode 1
        mov     ah, 01h
        out     dx, ax

        mov     dx, SeqAddressPort      ; set VGA port address
        mov     al, LS_MAP_MASK         ; set map mask ffh
        mov     ah, 0ffh
        out     dx, ax

        pop     dx                      ; restore ax, dx
        pop     ax
        ret

SetupAPAMove    endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: SetAPAColor                                       */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set APA write colors.                            */
;/*                                                                     */
;/*  INPUT:                                                             */
;/*     AL      = Foreground (0-3 bit) and Background (4-7) Colors      */
;/*     ES:DI --> Target APA address
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
SetAPAColor proc    far
        public  SetAPAColor

        push    bx                      ; save bx, dx
        push    dx                      ; 

        mov     dx, GraphAddressPort    ; set VGA port address

        mov     bl, al                  ; save color

        mov     al, LG_MODE             ; set write mode 3
        mov     ah, 03h
        out     dx, ax

        mov     al, LG_SET_RESET        ; set background color
        mov     ah, bl                  ; 
        shr     ah, 4                   ; get background color
        out     dx, ax

        mov     byte ptr es:[di], 0ffh  ; clear APA with background color
        mov     al, es:[di]             ; set complement register

        mov     al, LG_SET_RESET        ; set foreground color
        mov     ah, bl                  ; 
        and     ah, 0fh                 ; get foreground color
        out     dx, ax

        pop     dx                      ; restore bx, dx
        pop     bx                      ; 

        ret

SetAPAColor endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: SetClsColor                                       */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set APA clear colors.                            */
;/*                                                                     */
;/*  INPUT:                                                             */
;/*     AL      = Foreground Color                                      */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
SetClsColor proc    far
        public  SetClsColor

        jmp     SetGridColor
        ret

SetClsColor endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: SetGridColor                                      */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set APA grid write colors.                       */
;/*                                                                     */
;/*  INPUT:                                                             */
;/*     AL      = Grid Color                                            */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
SetGridColor    proc    far
        public  SetGridColor

        push    ax                      ; save ax, dx
        push    dx

        push    ax                      ; save grid color

        mov     dx, GraphAddressPort    ; set VGA port address

        mov     al, LG_MODE             ; set write mode 3
        mov     ah, 03h
        out     dx, ax

        pop     ax                      ; restore grid color
        mov     ah, al

        mov     al, LG_SET_RESET        ; set grid color
        and     ah, 0fh                 ; get foreground color
        out     dx, ax

        pop     dx                      ; restore ax,dx
        pop     ax

        ret

SetGridColor    endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: DrawCursorToAPA                                   */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Draw character cursor on APA.                    */
;/*                                                                     */
;/*  INPUT:                                                             */
;/*     AL      = Cursor Color                                          */
;/*     AH      = Character Foreground Color (0-3 bit) and              */
;/*                         Background Color (4-7 bit)                  */
;/*     BX      = one scan line length                                  */
;/*     CX      = Cursor Height (scan lines)                            */
;/*     SI      = Offset to charactor top                               */ ;J-TS0928
;/*     ES:DI --> Cursor Start APA Address                              */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
DrawCursorToAPA proc    near
        public  DrawCursorToAPA

        push    bp                      ; save scan line length
        mov     bp, bx

        mov     dx, GraphAddressPort    ; set VGA port address
        mov     bx, ax                  ; save colors
        mov     al, LG_COMP             ; set color comp
        out     dx, ax
        mov     ax, bx                  ; restore colors
        shr     ah, 4                   ; if char back color = cursor color
        .if     <ah eq al>              ; cursor color is reversed.
            xor     al, 0fh
        .endif
        mov     ah, al                  ; set set/reset register (cursor color)
        mov     al, LG_SET_RESET
        out     dx, ax
        mov     al, LG_MODE             ; set read mode 1, write mode 3
        mov     ah, 03h+08h
        out     dx, ax
        mov     al, LG_FUNCTION         ; set rotate 0
        mov     ah, 0
        out     dx, ax
        mov     al, LG_BIT_MASK         ; set bit mask ffh
        mov     ah, 0ffh
        out     dx, ax

        mov     bl, bh                  ; if char back color = char fore color
        shr     bl, 4                   ; foreground color is ignored.
        and     bh, 0fh

DrawCursorLap:                                                      ;J-TS0928
        push    cx                                                  ;J-TS0928
        xor     ch, ch                                              ;J-TS0928

        .if     <bh eq bl>              ; back = fore

            mov     al, 0ffh
DrawCursorLoop1:
            mov     es:[di], al         ; draw cursor
            add     di, bp
            loop    DrawCursorLoop1

        .else                           ; back != fore

DrawCursorLoop2:
            mov     al, es:[di]         ; get font pattern
            not     al
            mov     es:[di], al         ; draw cursor
            add     di, bp
            loop    DrawCursorLoop2

        .endif

        pop     cx                                                  ;J-TS0928
        .if     <ch ne 0>                                           ;J-TS0928
            mov     cl, ch                                          ;J-TS0928
            xor     ch, ch                                          ;J-TS0928
            sub     di, si                                          ;J-TS0928
            jmp     DrawCursorLap                                   ;J-TS0928
        .endif                                                      ;J-TS0928

        pop     bp

        ret

DrawCursorToAPA endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: XorCursorToAPA                                    */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Xor character cursor on APA.                     */
;/*                                                                     */
;/*  INPUT:                                                             */
;/*     BX      = one scan line length                                  */
;/*     CX      = Cursor Height (scan lines)                            */
;/*     ES:DI --> Cursor Start APA Address                              */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
XorCursorToAPA  proc    near
        public  XorCursorToAPA

        push    bp
        mov     bp, bx

        mov     dx, GraphAddressPort    ; set VGA port address

        mov     al, LG_MODE             ; set read mode 0 / write mode 0
        mov     ah, 00h
        out     dx, ax

        mov     al, LG_BIT_MASK         ; set bit mask ffh
        mov     ah, 0ffh
        out     dx, ax

        mov     al, LG_ENABLE_SET_RESET ; set set/reset enable
        mov     ah, 0
        out     dx, ax

        mov     al, LG_FUNCTION         ; set rotate 0
        mov     ah, 0
        out     dx, ax

        mov     bh, 4                   ; plane count
        mov     bl, 1000b

XorCsrLoop1:
        mov     dx, GraphAddressPort    ; set VGA port address
        mov     al, LG_READ_MAP         ; set read map
        mov     ah, bh
        dec     ah
        out     dx, ax

        mov     dx, SeqAddressPort      ; set VGA port address
        mov     al, LS_MAP_MASK         ; select write map
        mov     ah, bl
        out     dx, ax

        push    cx
        push    di

XorCsrLoop2:
        mov     al, es:[di]             ; xor one scan line
        xor     al, 0ffh
        mov     es:[di], al
        add     di, bp
        loop    XorCsrLoop2

        pop     di
        pop     cx
        shr     bl, 1
        dec     bh
        jnz     XorCsrLoop1             ; next plane

        pop     bp

        ret

XorCursorToAPA endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: SaveFont                                          */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Save character images from APA to local buffer.  */
;/*                                                                     */
;/*  INPUT:                                                             */
;/*     DS:SI --> local buffer                                          */
;/*     ES:DI --> character start APA address                           */
;/*     AX    --> one scan line length (bytes)                          */
;/*     BL    --> number of APA                                         */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
SaveFont        proc    far
        public  SaveFont
        pusha

        mov     bp, ax                  ; move scan line length

        mov     dx, SeqAddressPort      ; set VGA port address
        mov     al, LS_MAP_MASK         ; set map mask ffh
        mov     ah, 0ffh
        out     dx, ax

        mov     dx, GraphAddressPort    ; set VGA port address
        mov     al, LG_MODE             ; set read mode 0
        mov     ah, 00h
        out     dx, ax

SaveFontLoop1:
        mov     al, LG_READ_MAP         ; set read map
        mov     ah, bl
        dec     ah
        out     dx, ax

        mov     cx, FONT_HEIGHT         ; set font height loop counter

SaveFontLoop2:
        mov     al, es:[di]             ; get one line
        mov     ds:[si], al             ; save one line
        inc     si                      ; inc pointers
        add     di, bp
        loop    SaveFontLoop2

        mov     ax, bp                  ; restore APA pointer
        mov     ah, FONT_HEIGHT
        mul     ah
        sub     di, ax
        dec     bl

        jnz     SaveFontLoop1

        popa
        ret

SaveFont        endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: RestoreFont                                       */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Restore character images from APA to local buffer*/
;/*                                                                     */
;/*  INPUT:                                                             */
;/*     DS:SI --> Local Buffer                                          */
;/*     ES:DI --> Character Start APA Address                           */
;/*     AX    --> one scan line length (bytes)                          */
;/*     BL    --> number of APA                                         */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
RestoreFont     proc    far
        public  RestoreFont
        pusha

        mov     bp, ax                  ; move scan line length

        mov     dx, GraphAddressPort    ; set VGA port address
        mov     al, LG_MODE             ; set write mode 0
        mov     ah, 00h
        out     dx, ax
        mov     al, LG_FUNCTION         ; set rotate 0
        mov     ah, 0
        out     dx, ax
        mov     al, LG_BIT_MASK         ; set bit mask ffh
        mov     ah, 0ffh
        out     dx, ax
        mov     al, LG_ENABLE_SET_RESET ; set set/reset enable
        mov     ah, 0
        out     dx, ax

        mov     dx, SeqAddressPort      ; set VGA port address

RestoreFontLoop1:
        mov     al, LS_MAP_MASK         ; select restore map
        mov     cl, bl
        mov     ah, 10000000b
        rol     ah, cl
        out     dx, ax

        mov     cx, FONT_HEIGHT

RestoreFontLoop2:
        mov     al, ds:[si]
        mov     es:[di], al
        inc     si
        add     di, bp
        loop    RestoreFontLoop2

        mov     ax, bp                  ; restore APA pointer
        mov     ah, FONT_HEIGHT
        mul     ah
        sub     di, ax
        dec     bl

        jnz     RestoreFontLoop1

        popa
        ret

RestoreFont     endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     DrawCursor                                      *
;*                                                                      *
;* DESCRIPTIVE NAME:    Draw cursor with no condition                   *
;*                                                                      *
;* INPUT:       DS:     Video Buffer Selector                           *
;*                                                                      *
;* OUTPUT:      None                                                    *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: SaveFont, DrawCursorToAPA                       *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
DrawCursor      proc    far
        public  DrawCursor

        cli

        ; save currently displayed font

        mov     si, VGA_SaveChar            ; set save area pointer

        mov     ax, ds:VGA_CsrScrWidth      ; set shadow buffer pointer
        mul     ds:VGA_CsrRow
        add     ax, ds:VGA_CsrCol
        shl     ax, 2
        mov     bx, ax

        mov     ax, INSTSEG                 ; set APA pointer
        mov     es, ax
        mov     es, es:CursorSel
        mov     ax, APA_WIDTH*FONT_HEIGHT
        mul     ds:VGA_CsrRow
        add     ax, ds:VGA_CsrCol
        add     ax, ds:VGA_APAStart
        mov     di, ax

        push    bx                          ; save shadow buffer pointer
        push    di                          ; save APA pointer for latter use
        mov     ax, APA_WIDTH               ; set scan line length
        mov     bl, 4                       ; set number of planes
        call    SaveFont                    ; save font image

        .if     <ds:VGA_CsrWidth eq 2>      ; cursor is DBCS width ?
            add     si, FONT_HEIGHT*4       ; set save area pointer
            inc     di                      ; set APA pointer

            mov     ax, APA_WIDTH           ; set scan line length
            mov     bl, 4                   ; set number of planes
            call    SaveFont                ; save font image
        .endif

        ; draw cursor

        pop     di                          ; restore APA pointer
        pop     bx                          ; restore shadow buffer pointer

        mov     ax, APA_WIDTH               ; inc ptr to cursor start line
        mul     ds:VGA_CsrStart
        add     di, ax

        mov     cx, ds:VGA_CsrEnd           ; get cursor height
        .if     <cx ge ds:VGA_CsrStart>                             ;J-TS0928
            sub     cx, ds:VGA_CsrStart
            inc     cx
        .else                                                       ;J-TS0928
            mov     cx, FONT_HEIGHT                                 ;J-TS0928
            sub     cx, ds:VGA_CsrStart                             ;J-TS0928
            inc     cx                                              ;J-TS0928
            mov     ch, byte ptr ds:VGA_CsrEnd                      ;J-TS0928
            inc     ch                                              ;J-TS0928
        .endif                                                      ;J-TS0928

        push    bx
        push    cx
        push    di

        mov     al, byte ptr ds:VGA_CsrColor ; get cursor color
        mov     ah, ds:shadow[bx+1]         ; get font color
        mov     bx, APA_WIDTH               ; set scan line length
        mov     si, APA_WIDTH*FONT_HEIGHT   ; off to char box top   ;J-TS0928
        call    DrawCursorToAPA             ; draw cursor to APA

        pop     di
        pop     cx
        pop     bx

        .if     <ds:VGA_CsrWidth eq 2>      ; cursor is DBCS width ?
            inc     di                      ; set APA pointer
            mov     al, byte ptr ds:VGA_CsrColor ; get cursor color
            mov     ah, ds:shadow[bx+5]     ; get font color
            mov     bx, APA_WIDTH           ; set scan line length
            mov     si, APA_WIDTH*FONT_HEIGHT ; off to char box top ;J-TS0928
            call    DrawCursorToAPA         ; draw cursor to APA
        .endif

        mov     ds:VGA_SaveFlag, 1          ; char is saved

        sti

        ret

DrawCursor      endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     EraseCursor                                     *
;*                                                                      *
;* DESCRIPTIVE NAME:    Erase cursor with no condition                  *
;*                                                                      *
;* INPUT:       DS:     Video Buffer Selector                           *
;*                                                                      *
;* OUTPUT:      None                                                    *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: RestoreFont                                     *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
EraseCursor     proc    far
        public  EraseCursor

        cli

        mov     si, VGA_SaveChar            ; set save area pointer

        mov     ax, INSTSEG                 ; set APA pointer
        mov     es, ax
        mov     es, es:CursorSel
        mov     ax, APA_WIDTH*FONT_HEIGHT
        mul     ds:VGA_CsrRow
        add     ax, ds:VGA_CsrCol
        add     ax, ds:VGA_APAStart
        mov     di, ax

        push    si
        push    di

        mov     ax, APA_WIDTH               ; set scan line length
        mov     bl, 4                       ; set number of planes
        call    RestoreFont                 ; hide cursor from APA
        pop     di
        pop     si

        .if     <ds:VGA_CsrWidth eq 2>      ; cursor is DBCS width ?
            add     si, FONT_HEIGHT*4       ; set save area pointer
            inc     di                      ; set APA pointer
            mov     ax, APA_WIDTH           ; set scan line length
            mov     bl, 4                   ; set number of planes
            call    RestoreFont             ; hide cursor from APA
        .endif

        mov     ds:VGA_SaveFlag, 0          ; char is restored

        sti

        ret

EraseCursor     endp

;********************** START OF SPECIFICATIONS *************************
;*                                                                      *
;* SUBROUTINE NAME:     XorCursor                                       *
;*                                                                      *
;* DESCRIPTIVE NAME:    Xor cursor based on XVIO request                *
;*                                                                      *
;* INPUT:       DS:     Video Buffer Selector                           *
;*                                                                      *
;* OUTPUT:      None                                                    *
;*                                                                      *
;* INTERNAL REFERENCES: None                                            *
;*                                                                      *
;* EXTERNAL REFERENCES: None                                            *
;*                                                                      *
;********************** END OF SPECIFICATIONS ***************************
XorCursor   proc    far
        public  XorCursor

        cli

        mov     ax, INSTSEG                 ; set APA pointer
        mov     es, ax
        mov     es, es:CursorSel
        mov     ax, SCREEN_WIDTH*FONT_HEIGHT
        mul     ds:VGA_CsrRow
        add     ax, ds:VGA_CsrCol
        mov     di, ax

        mov     ax, SCREEN_WIDTH            ; inc ptr to cursor start line
        mul     ds:VGA_CsrStart
        add     di, ax
        mov     cx, ds:VGA_CsrEnd           ; get cursor height
        sub     cx, ds:VGA_CsrStart
        inc     cx

        mov     bx, SCREEN_WIDTH            ; set scan line length

        .if     <ds:VGA_CsrColor ne 0>      ; not black
            call    XorCursorToAPA          ; xor cursor to APA
        .endif

        sti

        ret

XorCursor   endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: SetAPAStart                                       */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set APA start address register on VGA to support */
;/*                    hardware scroll.                                 */
;/*                                                                     */
;/*  INPUT:                                                             */
;/*     AX      = APA Start Address                                     */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
SetAPAStart proc    far
        public  SetAPAStart
        pusha

        push    ds
        push    _DATA
        pop     ds
        mov     si, ds:PrevLineComp         ; get hardware scroll params.
        mov     di, ds:MaxLineComp
        mov     bp, ds:HardwareScroll       ; get hardware scroll flag
        pop     ds

        push    ax
                                            ; calc line compare reg
        not     ax                          ; ax = 10000h - ax
        inc     ax
        shr     ax, 7                       ; line count in ax
        .if     <ax gt FONT_HEIGHT*SCREEN_HEIGHT>
            mov     ax, FONT_HEIGHT*SCREEN_HEIGHT
        .endif
        dec     ax                          ; 
        mov     cx, ax                      ; line compare reg value in cx

        mov     dx, MiscOutputRegRead       ; Read Miscellaneous Output Register
        in      al, dx
        mov     bx, InputStatusReg1
        mov     dx, CRTCtlAddressReg
        .if     <bit ax and 01h>            ; bit 0 = 1 - color, 0 - monochrome
            add     bx, ColorAdjustment
            add     dx, ColorAdjustment
        .else
            add     bx, MonoAdjustment
            add     dx, MonoAdjustment
        .endif

        pop     ax

        .if     <bp eq PROTECT_HS_LC>       ; line compare scroll
            .if     <si b di> and           ; LineComp already enabled
            .if     <cx b si>               ; scroll up
                push    ax
                call    SetLineCompGale
                pop     ax
                call    SetCRTStartGale
            .else                           ; scroll down
                call    SetCRTStartGale
                call    SetLineCompGale
            .endif
        .else                               ; only start address scroll
            call    SetCRTStartGale
        .endif

        popa
        ret
SetAPAStart endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: SetCRTStartGale                                   */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set CRT start address register on VGA to support */
;/*                    hardware scroll.                                 */
;/*                                                                     */
;/*  INPUT:                                                             */
;/*     AX      = APA Start Address                                     */
;/*     BX      = InputStatusReg1                                       */
;/*     CX      = New Line Compare                                      */
;/*     DX      = CRTCtlAddressReg                                      */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/

SetCRTStartGale proc    near

        push    ax
        mov     al, LC_START_HIGH           ; set new start address
        out     dx, ax
        pop     ax

        mov     ah, al
        mov     al, LC_START_LOW
        out     dx, ax

        ret
SetCRTStartGale endp

;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: SetLineCompGale                                   */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Set Line compare register on VGA to support      */
;/*                    hardware scroll.                                 */
;/*                                                                     */
;/*  INPUT:                                                             */
;/*     AX      = APA Start Address                                     */
;/*     BX      = InputStatusReg1                                       */
;/*     CX      = New Line Compare                                      */
;/*     DX      = CRTCtlAddressReg                                      */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/

SetLineCompGale proc    near

        xchg    bx, dx

CRTStartLoop:                               ; wait until entering in vertical retrace
        sti
        nop
        cli
        in      al, dx
        test    al, 08h
        jz      CRTStartLoop

        xchg    bx, dx

        mov     al, LC_LINE_COMP            ; set lower 8 bit value
        mov     ah, cl
        out     dx, ax

        mov     al, LC_OVERFLOW             ; set bit 8 value
        out     dx, al
        inc     dx
        in      al, dx
        dec     dx
        and     al, 0efh
        mov     ah, ch
        and     ah, 01h
        shl     ah, 4
        or      ah, al
        mov     al, LC_OVERFLOW
        out     dx, ax

        mov     al, LC_MAX_SCAN_LINE        ; set bit 9 value
        out     dx, al
        inc     dx
        in      al, dx
        dec     dx
        and     al, 0bfh
        mov     ah, ch
        and     ah, 02h
        shl     ah, 5
        or      ah, al
        mov     al, LC_MAX_SCAN_LINE
        out     dx, ax

        push    ds
        push    _DATA
        pop     ds
        mov     PrevLineComp, cx
        pop     ds

        ret
SetLineCompGale endp


;/**********************  START OF SPECIFICATIONS  **********************/
;/*                                                                     */
;/*  SUBROUTINE NAME: Enable/DisableInt                                 */
;/*                                                                     */
;/*  DESCRIPTIVE NAME: Enable/Disable interrrupt.                       */
;/*                                                                     */
;/*  INPUT: None                                                        */
;/*                                                                     */
;/*  INTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/*  EXTERNAL REFERENCES:                                               */
;/*    ROUTINES: None                                                   */
;/*                                                                     */
;/***********************  END OF SPECIFICATIONS  ***********************/
EnableInt   proc    far
        public  EnableInt
        sti
        ret
EnableInt   endp

DisableInt  proc    far
        public  DisableInt
        cli
        ret
DisableInt   endp

R2SEG   ENDS
END
