;*DDK*************************************************************************/
;
; 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    ,132
        TITLE   Virtual Video Misc. I/O Processing

;/*****************************************************************************
;*
;* SOURCE FILE NAME = VVMSCIO.ASM
;*
;* DESCRIPTIVE NAME = Virtual Video Device Driver Misc. I/O Processing 
;*
;*
;* VERSION      V2.0
;*
;* DATE         11/10/88
;*
;* DESCRIPTION  This module contains the VVD's Miscellaneous I/O handlers. 
;*
;* FUNCTIONS    
;*              VVReadModeFgnd() - Read MONO/CGA mode byte foreground
;*              VVReadModeBgnd() - Read MONO/CGA mode byte background
;*              VVWriteModeFgnd() - Write MONO/CGA mode byte foreground
;*              VVWriteModeBgnd() - Write MONO/CGA mode byte background
;*              VVReadCGAColorFgnd() - Read CGA color byte foreground
;*              VVReadCGAColorBgnd() - Read CGA color byte background
;*              VVWriteCGAColorFgnd() - Write CGA color byte foreground
;*              VVWriteCGAColorBgnd() - Write CGA color byte background
;*              VVReadStatus0Bgnd() - Read STATUS0 byte
;*              VVWriteMiscOutFgnd() - Write MISCOUT byte
;*              VVWriteMiscOutBgnd() - Write MISCOUT byte
;*              VVReadFeatureFgnd() - Read FEATURE byte
;*              VVReadFeatureBgnd() - Read FEATURE byte
;*              VVReadMiscOutFgnd() - Read MISCOUT byte
;*              VVReadMiscOutBgnd() - Read MISCOUT byte
;*              VVReadStatus1Fgnd() - Read STATUS1 byte
;*              VVReadStatus1Bgnd() - Read STATUS1 byte
;*              VVWriteFeatureFgnd() - Write FEATURE byte
;*              VVWriteFeatureBgnd() - Write FEATURE byte
;*              VVReadUnknownBgnd() - Read unknown byte background
;*              VVWriteUnknownBgnd() - Write unknown byte background
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*
;*   11/10/88                     JTP - Created.
;*
;*   05/09/91                     fix PM video corruption when session
;*                                switch back to PM while the VDM in a
;*                                multi-plane graphics mode.
;*                                (B790553, B722596)
;*
;*   02/20/92                     don't trash Sequencer reg 7, non-IBM
;*                                VGAs use it.
;*
;*   02/27/92                     B733211 - Performance enhancement to
;*                                320x200 mode.
;*
;*   02/29/92                     More selective Sequencer 7 zeroing.
;**************************************************************/


        .xlist
        include mvdm.inc
        include vddseg.inc
        .list
        include vvd.inc
        include vvdp.inc


        DefCode     EXPORT,SWAP,PASCAL

       IFDEF MONOCGA
        DefFn       VVReadModeFgnd
        DefFn       VVReadModeBgnd
        DefFn       VVWriteModeFgnd
        DefFn       VVWriteModeBgnd
       ENDIF
       IFDEF CGA
        DefFn       VVReadCGAColorFgnd
        DefFn       VVReadCGAColorBgnd
        DefFn       VVWriteCGAColorFgnd
        DefFn       VVWriteCGAColorBgnd
       ENDIF
       IFDEF EGAVGA
        DefFn       VVReadStatus0Bgnd
       ENDIF
       IFDEF EGAVGA                                                     ;          
        DefFn       VVWriteMiscOutFgnd
       ENDIF
       IFDEF EGAVGA
        DefFn       VVWriteMiscOutBgnd
       ENDIF
       IFDEF EGA
        DefFn       VVReadFeatureFgnd
       ENDIF
       IFDEF EGAVGA
        DefFn       VVReadFeatureBgnd
       ENDIF
       IFDEF EGA
        DefFn       VVReadMiscOutFgnd
       ENDIF
       IFDEF EGAVGA
        DefFn       VVReadMiscOutBgnd
       ENDIF
       IFDEF EGAVGA
        DefFn       VVReadStatus1Fgnd
       ENDIF
        DefFn       VVReadStatus1Bgnd
       IFDEF EGA
        DefFn       VVWriteFeatureFgnd
       ENDIF
       IFDEF EGAVGA
        DefFn       VVWriteFeatureBgnd
       ENDIF
       IFNDEF MONO
        DefFn       VVReadUnknownBgnd
       ENDIF
        DefFn       VVWriteUnknownBgnd


        DefData     IMPORT,SWAP,C

        _BYTE       abNextStatusState

       IFDEF SVGA                                                       ;          
        ULONG       ulSVGAAdapterType
        ULONG            fSeqFixups
       ENDIF                                                            ;          

        EndData


       IFDEF MONOCGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadModeFgnd()
;*
;* DESCRIPTION   = Read MONO/CGA mode byte foreground
;*
;*                 This registered subroutine is called whenever a
;*                 foreground VDM reads a byte from the MONOMODE/CGAMODE
;*                 register (see VDHInstallIOHook for complete semantics).
;*
;*                 Note that the only real purpose this routine serves is
;*                 to enhance operation on MONO/CGA adapters, which are
;*                 normally not readable. This provides applications with
;*                 a benefit of operating in V86-mode that should in no
;*                 way affect compatibility.
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_MONOMODE or PORT_CGAMODE)
;*
;* OUTPUT        = AL  == data read                                      
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadModeFgnd
        FallInto VVReadModeBgnd
EndProc   VVReadModeFgnd

       ENDIF ;MONOCGA


       IFDEF MONOCGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadModeBgnd()
;*
;* DESCRIPTION   = Read MONO/CGA mode byte background 
;*
;*                 This registered subroutine is called whenever a background
;*                 VDM reads a byte from the MONOMODE/CGAMODE register (see
;*                 VDHInstallIOHook for complete semantics).
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_MONOMODE or PORT_CGAMODE)
;*
;* OUTPUT        = AL  == data read                                   
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadModeBgnd
        FallFrom VVReadModeFgnd
        mov     al,VDMData.regMode          ;return mode value
        ExitProc
EndProc   VVReadModeBgnd

       ENDIF ;MONOCGA


       IFDEF MONOCGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVWriteModeFgnd()
;*
;* DESCRIPTION   = Write MONO/CGA mode byte foreground
;*
;*                 This registered subroutine is called whenever a foreground
;*                 VDM writes a byte to the MONOMODE/CGAMODE register (see
;*                 VDHInstallIOHook for complete semantics).
;*
;* INPUT         = AL == data to write
;*                 EBX -> VDM register frame
;*                 EDX == port number (PORT_MONOMODE or PORT_CGAMODE)
;*
;* OUTPUT        = None
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;* PSEUDO-CODE
;*                 update hardware
;*                 update mode value
;*                        
;**************************************************************************/

        align   4                                                       ;          
Procedure VVWriteModeFgnd
        OUTB    dx,al                       ;output MONOMODE/CGAMODE value
        FallInto VVWriteModeBgnd
EndProc   VVWriteModeFgnd

       ENDIF ;MONOCGA


       IFDEF MONOCGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVWriteModeBgnd()
;*
;* DESCRIPTION   = Write MONO/CGA mode byte background 
;*
;*                 This registered subroutine is called whenever a background
;*                 VDM writes a byte to the MONOMODE/CGAMODE register (see
;*                 VDHInstallIOHook for complete semantics).
;*
;* INPUT         = AL == data to write
;*                 EBX -> VDM register frame
;*                 EDX == port number (PORT_MONOMODE or PORT_CGAMODE)
;*
;* OUTPUT        = None
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVWriteModeBgnd
        FallFrom VVWriteModeFgnd
        mov     VDMData.regMode,al          ;stash the MONOMODE/CGAMODE value
        ExitProc
EndProc   VVWriteModeBgnd

       ENDIF ;MONOCGA


       IFDEF CGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadCGAColorFgnd()
;*
;* DESCRIPTION   = Read CGA color byte foreground 
;*
;*                 This registered subroutine is called whenever a foreground
;*                 VDM reads a byte from the CGACOLOR register (see VDHInstallIOHook
;*                 for complete semantics).
;*
;*                 Note that the only real purpose this routine serves is to enhance
;*                 operation on CGA adapters, which are normally not readable.
;*                 This provides applications with a benefit of operating in V86-mode
;*                 that should in no way affect compatibility.
;*
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_CGACOLOR)
;*
;* OUTPUT        = AL  == data read                   
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadCGAColorFgnd
        FallInto VVReadCGAColorBgnd
EndProc   VVReadCGAColorFgnd

       ENDIF ;CGA


       IFDEF CGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadCGAColorBgnd()
;*
;* DESCRIPTION   = Read CGA color byte background
;*
;*                 This registered subroutine is called whenever a
;*                 background VDM reads a byte from the CGACOLOR
;*                 register (see VDHInstallIOHook for complete
;*                 semantics).
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_CGACOLOR)
;*
;* OUTPUT        = AL  == data read                            
;*                                                             
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadCGAColorBgnd
        FallFrom VVReadCGAColorFgnd
        mov     al,VDMData.regColor         ;return color value
        ExitProc
EndProc   VVReadCGAColorBgnd

       ENDIF ;CGA


       IFDEF CGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVWriteCGAColorFgnd()
;*
;* DESCRIPTION   = Write CGA color byte foreground
;*
;*                 This registered subroutine is called whenever a foreground
;*                 VDM writes a byte to the CGACOLOR register (see VDHInstallIOHook
;*                 for complete semantics).
;*
;* INPUT         = AL == data to write
;*                 EBX -> VDM register frame
;*                 EDX == port number (PORT_CGACOLOR)
;*
;* OUTPUT        = None
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;* PSEUDO-CODE
;*                 update hardware
;*                 update color value
;*                                    
;**************************************************************************/

        align   4                                                       ;          
Procedure VVWriteCGAColorFgnd
        OUTB    dx,al                       ;output CGACOLOR value
        FallInto VVWriteCGAColorBgnd
EndProc   VVWriteCGAColorFgnd

       ENDIF ;CGA


       IFDEF CGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVWriteCGAColorBgnd()
;*
;* DESCRIPTION   = Write CGA color byte background
;*
;*                 This registered subroutine is called whenever a
;*                 background VDM writes a byte to the CGACOLOR register
;*                 (see VDHInstallIOHook for complete semantics).
;*
;* INPUT         = AL == data to write
;*                 EBX -> VDM register frame
;*                 EDX == port number (PORT_CGACOLOR)
;*
;* OUTPUT        = None                                 
;*                                                      
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVWriteCGAColorBgnd
        FallFrom VVWriteCGAColorFgnd
        mov     VDMData.regColor,al         ;stash the CGACOLOR value
        ExitProc
EndProc   VVWriteCGAColorBgnd

       ENDIF ;CGA


       IFDEF EGAVGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadStatus0Bgnd()
;*
;* DESCRIPTION   = Read STATUS0 byte
;*
;*                 This registered subroutine is called whenever a
;*                 background VDM reads a byte from the STATUS0 register
;*                 (see VDHInstallIOHook for complete semantics).
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_STATUS0)
;*
;* OUTPUT        = AL  == data read                       
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadStatus0Bgnd
;;;     FLAG:  05-Jan-89,<STATUS0 not well-simulated>
        mov     al,0                        ;return simulated hardware value
        ExitProc
EndProc   VVReadStatus0Bgnd

       ENDIF ;EGAVGA


       IFDEF EGAVGA                                                     ;          

;/***************************************************************************
;*
;* FUNCTION NAME = VVWriteMiscOutFgnd()
;*
;* DESCRIPTION   = Write MISCOUT byte
;*
;*                 This registered subroutine is called whenever a foreground
;*                 VDM writes a byte to the MISCOUT register (see VDHInstallIOHook
;*                 for complete semantics).
;*
;* INPUT         = AL == data to write
;*                 EBX -> VDM register frame
;*                 EDX == port number (PORT_MISCOUT)
;*
;* OUTPUT        = None
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;* PSEUDO-CODE
;*                 update hardware
;*                 update misc. output value
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVWriteMiscOutFgnd
       IFDEF VGA                                                        ;          
        mov     cx,ax                       ;save Misc Reg value        ;          
        cli                                                             ;          
        mov     dx,PORT_SEQINDX             ;Sequencer address port     ;          
        mov     ax,REG_SEQRESET + SEQRESET_ASYNC SHL 8                  ;          
        out     dx,ax                       ;Synchrouous reset          ;          
        mov     dx,PORT_MISCOUT                                         ;          
        mov     ax,cx                       ;get original Misc Reg value;          
       ENDIF                                                            ;          

        OUTB    dx,al                       ;output MISCOUT value

       IFDEF VGA                                                        ;          

;/*
;**
;**         IBM lab analysis and simulation revealed a problem in the IBM VGA
;**         due to narrow pulses on DRAM RAS and CAS control signals.  These
;**         pulses violated the DRAM timing specifications, and as a result,
;**         corrupted the memory contents.  The narrow RAS and CAS pulses were
;**         caused when one section of the VGA-LC re-synchronized to the
;**         start of a horizontal line, and another section missed the
;**         re-sync signal.  The two sections involved were the memory cycle
;**         generator, and the the memory cycle arbiter.  The short RAS and
;**         CAS pulses occurred when the memory cycle arbiter saw the reset
;**         command, and the memory cycle generator missed the command.
;**
;*/

IFDEF  SVGA
        cmp        fSeqFixups, 0                    ;Only do fixups if flag set
        jz        short @F                    ; 
        mov     dx,PORT_SEQINDX             ;Sequencer address port
        mov     ax,REG_SEQUNKNOWN_IBM1 + 0 SHL 8
        out     dx,ax                       ;clear horizontal counter
        test    cx,MISCOUT_COLRPORTS                                    ;          
        jz      mono                        ;Mono mode                  ;          
        mov     dx,PORT_COLRCRTINDX         ;CRT Index for Color        ;          
        jmp     short setreg                                            ;          
mono:                                                                   ;          
        mov     dx,PORT_MONOCRTINDX         ;CRT Index for Mono         ;          
setreg:                                                                 ;          
        mov     ax,REG_CRTUNKNOWN_IBM1 + 1 SHL 8                        ;          
        out     dx,ax                       ;set full cycles            ;          
@@:
ELSE
        mov     dx,PORT_SEQINDX             ;Sequencer address port     ;          
        mov     ax,REG_SEQUNKNOWN_IBM1 + 0 SHL 8                        ;          
        out     dx,ax                       ;clear horizontal counter   ;          
        test    cx,MISCOUT_COLRPORTS                                    ;          
        jz      mono                        ;Mono mode                  ;          
        mov     dx,PORT_COLRCRTINDX         ;CRT Index for Color        ;          
        jmp     short setreg                                            ;          
mono:                                                                   ;          
        mov     dx,PORT_MONOCRTINDX         ;CRT Index for Mono         ;          
setreg:                                                                 ;          
        mov     ax,REG_CRTUNKNOWN_IBM1 + 1 SHL 8                        ;          
        out     dx,ax                       ;set full cycles            ;          
ENDIF

        mov     al,REG_SEQRESET             ;restore original sequencer ;          
        mov     ah,VDMData.aregSEQData[0]   ; setting                   ;          
        or      ah,SEQRESET_ASYNC or SEQRESET_SYNC                      ;          
        mov     dx,PORT_SEQINDX                                         ;          
        out     dx,ax                                                   ;          
        sti                                                             ;          
        mov     ax,cx                                                   ;          
       ENDIF                                                            ;          

        FallInto VVWriteMiscOutBgnd

EndProc   VVWriteMiscOutFgnd

       ENDIF ;EGAVGA                                                    ;          


       IFDEF EGAVGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVWriteMiscOutBgnd()
;*
;* DESCRIPTION   = Write MISCOUT byte
;*
;*                 This registered subroutine is called whenever a background
;*                 VDM writes a byte to the MISCOUT register (see VDHInstallIOHook
;*                 for complete semantics).
;*
;* INPUT         = AL == data to write
;*                 EBX -> VDM register frame
;*                 EDX == port number (PORT_MISCOUT)
;*
;* OUTPUT        = None
;*                                                     
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVWriteMiscOutBgnd
;            IFDEF EGA
        FallFrom VVWriteMiscOutFgnd
;            ENDIF
        mov     VDMData.regMiscOut,al       ;stash the MISCOUT value
        ExitProc
EndProc   VVWriteMiscOutBgnd

       ENDIF ;EGAVGA


       IFDEF EGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadFeatureFgnd()
;*
;* DESCRIPTION   = Read FEATURE byte 
;*
;*                 This registered subroutine is called whenever a foreground
;*                 VDM reads a byte from the FEATURE register (see
;*                 VDHInstallIOHook for complete semantics).
;*
;*                 Note that the only real purpose this routine serves is to
;*                 enhance operation on EGA adapters, which are normally not
;*                 readable.  This provides applications with a benefit of
;*                 operating in V86-mode that should in no way affect
;*                 compatibility.
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_GDCPOS2)
;*
;* OUTPUT        = AL  == data read                 
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadFeatureFgnd
        FallInto VVReadFeatureBgnd          ;no different from background
EndProc   VVReadFeatureFgnd

       ENDIF ;EGA


       IFDEF EGAVGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadFeatureBgnd()
;*
;* DESCRIPTION   = Read FEATURE byte
;*
;*                 This registered subroutine is called whenever a
;*                 background VDM reads a byte from the FEATURE register
;*                 (see VDHInstallIOHook for complete semantics).
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_GDCPOS2)
;*
;* OUTPUT        = AL  == data read
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadFeatureBgnd
       IFDEF EGA
        FallFrom VVReadFeatureFgnd
       ENDIF
        mov     al,VDMData.regFeature       ;return feature port value
        ExitProc
EndProc   VVReadFeatureBgnd

       ENDIF ;EGAVGA


       IFDEF EGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadMiscOutFgnd()
;*
;* DESCRIPTION   = Read MISCOUT byte
;*
;*                 This registered subroutine is called whenever a foreground
;*                 VDM reads a byte from the MISCOUT register
;*                 (see VDHInstallIOHook for complete semantics).
;*
;*                 Note that the only real purpose this routine serves is to
;*                 enhance operation on EGA adapters, which are normally not
;*                 readable.  This provides applications with a benefit of
;*                 operating in V86-mode that should in no way affect
;*                 compatibility.
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_GDCPOS1)
;*
;* OUTPUT        = AL  == data read 
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadMiscOutFgnd
        FallInto VVReadMiscOutBgnd          ;no different from background
EndProc   VVReadMiscOutFgnd

       ENDIF ;EGA


       IFDEF EGAVGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadMiscOutBgnd()
;*
;* DESCRIPTION   = Read MISCOUT byte
;*
;*                 This registered subroutine is called whenever a
;*                 background VDM reads a byte from the MISCOUT register
;*                 (see VDHInstallIOHook for complete semantics).
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_GDCPOS1)
;* OUTPUT        =                                   
;*                 AL  == data read                  
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadMiscOutBgnd
       IFDEF EGA
        FallFrom VVReadMiscOutFgnd
       ENDIF
        mov     al,VDMData.regMiscOut       ;return misc. output port value
        ExitProc
EndProc   VVReadMiscOutBgnd

       ENDIF ;EGAVGA


       IFDEF EGAVGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadStatus1Fgnd()
;*
;* DESCRIPTION   = Read STATUS1 byte
;*
;*                 This registered subroutine is called whenever a
;*                 foreground VDM reads a byte from the STATUS1 register
;*                 (see VDHInstallIOHook for complete semantics).
;*
;*                 Note that the only need for this service is to track
;*                 a side-effect of reading the STATUS1 port;  namely,
;*                 that the ATC's INDEX/DATA state is reset to INDEX.
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_MONOSTATUS1 or PORT_COLRSTATUS1)
;*
;* OUTPUT        = AL  == data read
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;* PSEUDO-CODE
;*                 clear ATC flip-flop
;*                 read hardware status
;*                           
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadStatus1Fgnd
        mov     VDMData.stateATC,ATC_INDEX  ;reset ATC back to INDEX state
        INB     al,dx                       ;read initial value from hardware
       IFNDEF CGA
        test    VDMData.flVDMXVideo,VDMX_RTRCEMULATE
        jnz     short vvSimulateStatus1     ;now simulate the retrace bits....
       ENDIF
vvreadstatus1_exit:
        ExitProc
EndProc   VVReadStatus1Fgnd

       ENDIF ;EGAVGA


;/***************************************************************************
;*
;* FUNCTION NAME = VVReadStatus1Bgnd()
;*
;* DESCRIPTION   = Read STATUS1 byte
;*
;*                 This registered subroutine is called whenever a
;*                 background VDM reads a byte from the STATUS1 register
;*                 (see VDHInstallIOHook for complete semantics).
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (PORT_MONOSTATUS1 or PORT_COLRSTATUS1)
;*
;* OUTPUT        = AL  == data read
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;* PSEUDO-CODE
;*                 clear ATC flip-flop
;*                 create dummy status, returning retrace bits
;*                   clear 1 out of every N reads, and set the other
;*                   N-1 times
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadStatus1Bgnd
       IFDEF EGAVGA
        mov     VDMData.stateATC,ATC_INDEX  ;reset ATC back to INDEX state
        sub     al,al
       ENDIF

Entry vvSimulateStatus1
        mov     ecx,VDMData.stateStatus1    ;ECX == state index
        align   4                                                       ;          
vvSimulateRetry:
        mov     ah,abNextStatusState[ecx]   ;get the next state byte
        or      ah,ah                       ;at the 0xff end-of-table marker?
        jns     short vvSimulateCont        ;no
        sub     ecx,ecx                     ;yes, time to wrap to top of table
        jmp     short vvSimulateRetry
vvSimulateCont:
        inc     ecx
        mov     VDMData.stateStatus1,ecx    ;advance state for next I/O op.
        and     al,NOT (STATUS1_HORZRTRC OR STATUS1_VERTRTRC)
        or      al,ah
        ExitProc
EndProc   VVReadStatus1Bgnd


       IFDEF EGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVWriteFeatureFgnd()
;*
;* DESCRIPTION   = Write FEATURE byte 
;*
;*                 This registered subroutine is called whenever a
;*                 foreground VDM writes a byte to the FEATURE register
;*                 (see VDHInstallIOHook for complete semantics).
;*
;* INPUT         = AL == data to write
;*                 EBX -> VDM register frame
;*                 EDX == port number (PORT_MONOFEATURE or PORT_COLRFEATURE)
;*
;* OUTPUT        =
;*
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;* PSEUDO-CODE
;*     update hardware
;*     update feature value
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVWriteFeatureFgnd
        OUTB    dx,al                       ;output FEATURE value
        FallInto VVWriteFeatureBgnd
EndProc   VVWriteFeatureFgnd

       ENDIF ;EGA


       IFDEF EGAVGA

;/***************************************************************************
;*
;* FUNCTION NAME = VVWriteFeatureBgnd()
;*
;* DESCRIPTION   = Write FEATURE byte
;*
;*                 This registered subroutine is called whenever a
;*                 background VDM writes a byte to the FEATURE register
;*                 (see VDHInstallIOHook for complete semantics).
;*
;* INPUT         = AL == data to write
;*                 EBX -> VDM register frame
;*                 EDX == port number (PORT_MONOFEATURE or PORT_COLRFEATURE)
;*
;* OUTPUT        = None                                                      
;*                                                                           
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVWriteFeatureBgnd
       IFDEF EGA
        FallFrom VVWriteFeatureFgnd
       ENDIF
        mov     VDMData.regFeature,al       ;stash the FEATURE value
        ExitProc
EndProc   VVWriteFeatureBgnd

       ENDIF ;EGAVGA


       IFNDEF MONO

;/***************************************************************************
;*
;* FUNCTION NAME = VVReadUnknownBgnd()
;*
;* DESCRIPTION   = Read unknown byte background 
;*
;*                 This registered subroutine is called whenever a
;*                 background VDM reads a byte from an unknown register,
;*                 such as the CGA light- pen registers (see
;*                 VDHInstallIOHook for complete semantics).
;*
;* INPUT         = EBX -> VDM register frame
;*                 EDX == port number (varies)
;*
;* OUTPUT        = AL  == data read              
;*                                               
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVReadUnknownBgnd
;;;     FLAG:  16-Jan-89,<CGA light-pen regs not well-simulated>
        mov     al,0                        ;return simulated hardware value
        ExitProc
EndProc   VVReadUnknownBgnd

       ENDIF ;!MONO


;/***************************************************************************
;*
;* FUNCTION NAME = VVWriteUnknownBgnd()
;*
;* DESCRIPTION   = Write unknown byte background 
;*
;*                 This registered subroutine is called whenever a
;*                 background VDM writes a byte to an unknown register,
;*                 such as MONO and CGA STATUS1 registers, and light-pen
;*                 registers (see VDHInstallIOHook for complete semantics).
;*
;* INPUT         = AL == data to write
;*                 EBX -> VDM register frame
;*                 EDX == port number (varies)
;*
;* OUTPUT        = None
;*                                                
;* RETURN-NORMAL =
;* RETURN-ERROR  =
;*
;**************************************************************************/

        align   4                                                       ;          
Procedure VVWriteUnknownBgnd
        ExitProc
EndProc   VVWriteUnknownBgnd


        EndCode     EXPORT,SWAP,PASCAL


        END
