/*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.                                */
/*                                                                           */
/*****************************************************************************/
/************************************************************************
 *
 * SOURCE FILE NAME = VVPORT.C
 *
 * DESCRIPTIVE NAME = Virtual Video Port Management
 *
 *
 * VERSION = V2.0
 *
 * DATE      11/10/88
 *
 * DESCRIPTION  This module contains the VVD's routines to install, remove,
 *              and otherwise generally tend to I/O hooks.
 *
 * FUNCTIONS
 *              vvSetIOHooks()         Install/remove I/O hooks
 *              VVSpecialCaseIO()      Enable/disable special-case I/O
 *                                     according to state
 *              vvEnableIO()           Enable I/O
 *              vvInput()
 *              vvOutput()
 *              vvDisableDisplay(hvdm) Disable display
 *              vvEnableDisplay()      Enable display
 *              VVForceDisplay()       Force display on (for VKBD)
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/


#define  IO8BIT           /* CL386 Version 6.00.054 FLAG:                   */
#include <mvdm.h>
#include <vvd.h>
#include "vvdp.h"

#ifdef   VDDSTRICT
MODNAME = __FILE__;
#endif
extern ULONG flVVD;

#pragma  BEGIN_SWAP_DATA

extern PSADAPTERINFO psCurAdapterInfo;

#ifdef MONOCGA                                                  /*          */
extern PLE pleCRTMode;                                          /*          */
#endif /* MONOCGA */                                            /*          */

extern PLE pleSEQIndx;                                          /*          */
extern PLE pleSEQData;                                          /*          */
extern PLE pleGDCIndx;                                          /*          */
extern PLE pleGDCData;                                          /*          */
extern PLE pleFeatureWrite;                                     /*          */
extern PLE pleATC0;                                             /*          */
extern PPLE appleAll [];                                        /*          */

#pragma  END_SWAP_DATA

#ifdef   EGAVGA
   #pragma  BEGIN_GLOBAL_DATA
extern VVDRQ vvdrqVideo;
   #pragma  END_GLOBAL_DATA
#endif
#pragma  BEGIN_SWAP_CODE

/***************************************************************************
 *
 * FUNCTION NAME = vvSetOneIOHook()
 *
 * DESCRIPTION   = Install/remove one I/O hook
 *
 *                 This routine
 *                 either installs or removes the hooks for the I/O port.
 *
 * INPUT         = port     == port to install for
 *                 pioh     == pointer to ioh
 *                 flOpt    == option flags for install
 *                 fInstall == TRUE to install, FALSE to remove
 *                 fWait    == TRUE to wait if out of memory, FALSE to return error
 *
 * OUTPUT        = TRUE if hooks installed, FALSE if error
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 * CALLED BY
 *      vvSetIOHooks
 *
 ****************************************************************************/

BOOL PRIVENTRY vvSetOneIOHook(
  PORT port,
  PIOH pioh,
  FLAGS flOpt,
  BOOL fInstall,
  BOOL fWait )
{
  if( pioh )
    if (fInstall)
    {
      while( !VDHInstallIOHook( CURRENT_VDM,
                                port,
                                1,
                                pioh,
                                flOpt ) )
      {
        if( !fWait
            || !vvFreezeVDM( CURRENT_VDM,
                             TRUE ) )
          return( FALSE );
      }
      /*
      ** the hook state, altough the install call was successful.
      ** Dale found it under the NOIOTRAPPING conditions, but I've
      ** encountered the     under INT10RESTORE conditions as well.
      ** Until a fix in VDH is available, do the overhead.
      */
      if( ((VDMData.flVDMXVideo & VDMX_NOIOTRAPPING) ||        /*          */
           (VDMData.flVDMXVideo & VDMX_INT10RESTORE))           /*            */
          && !(flOpt & VDHIIH_ALWAYS_TRAP) )
        /*
        ** Re-enable - VDHInstallIOHook() should do this.
        */
        VDHSetIOHookState( CURRENT_VDM,
                           port,
                           1,
                           pioh,
                           SETIO_TRAP );
    }
    else
      VDHRemoveIOHook( CURRENT_VDM,
                       port,
                       1,
                       pioh );
  return TRUE;                  /*            */
}

/***************************************************************************
 *
 * FUNCTION NAME = vvSetIOHooks()
 *
 * DESCRIPTION   = Install/remove I/O hooks
 *
 *                 This routine walks through the appropriate I/O port list,
 *                 either installing or removing the set of hooks for every
 *                 I/O port listed.  The appropriate I/O list is determined
 *                 by the current session state.
 *
 * INPUT         = fBgnd    == TRUE if background hooks, FALSE if foreground
 *                 fInstall == TRUE to install, FALSE to remove
 *                 fWait    == TRUE to wait if out of memory, FALSE to return error
 *
 * OUTPUT        = TRUE if hooks installed, FALSE if error
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

BOOL PRIVENTRY vvSetIOHooks(
  BOOL fBgnd,
  BOOL fInstall,
  BOOL fWait )
{
  PORT port;
  INT nHooks;
  FLAGS flOpt;
  register PPLE *ppple;
  register INT i;
  if( !fBgnd                                      /*          *//*          */
      && (VDMData.flVDMXVideo & VDMX_NOIOTRAPPING) )            /*          */
    return( TRUE );                                             /*          */

  /*
  ** Walk the list of ports
  */

  for( ppple = appleAll;                                        /*          */
       *ppple;                                                  /*          */
       ppple++ )                                                /*          */
    if( !((*ppple)->sTrapBRegInfo.fTrapType & PORTF_NOTVALIDSVGAPORT)     /*                      */
        && (*ppple)->sTrapBRegInfo.piohTrap )                   /*          */
    {
      /*
      ** Determine the hook-type
      */
      flOpt = 0;
      if( !((*ppple)->sTrapBRegInfo.fTrapType & PORTF_CHOOK) )  /*          */
        flOpt |= VDHIIH_ASM_HOOK;
      if( (*ppple)->sTrapBRegInfo.piohTrap [fBgnd]              /*          */
            .ioh_pwihWordInput                                  /*          */
          || (*ppple)->sTrapBRegInfo.piohTrap [fBgnd]           /*          */
               .ioh_pwohWordOutput  )                           /*          */
        flOpt |= VDHIIH_NO_SIMULATE;
      /*
      ** Install/remove the hook
      */
      port = ((PSCGAINFO) psCurAdapterInfo)->                   /*          */
               pportfnCGAAdjustedPort(                          /*          */
                 &(*ppple)->sTrapBRegInfo );                    /*          */
      if (!vvSetOneIOHook(                                           /*          */
        port,                                                   /*          */
        &(*ppple)->sTrapBRegInfo.piohTrap [fBgnd],              /*          */
        flOpt,                                                  /*          */
        fInstall,                                               /*          */
        fWait ))                                                /*          */
          return FALSE;                                         /*            */

#ifdef EGAVGA                                                   /*          */
      if( ((*ppple)->sTrapBRegInfo.fTrapType & PORTF_COLRMONO ) /*          */
          && !(flVVD & VVD_MONOPRESENT) )                       /*          */
        /* Trap both color and mono */                          /*          */
        /* These ports not installed within the VMONO driver */ /*          */
        if (!vvSetOneIOHook(                                         /*          */
          port                                                  /*          */
          ^ (PORT_COLRCRTINDX                                   /*          */
             ^ PORT_MONOCRTINDX),                               /*          */
          &(*ppple)->sTrapBRegInfo.piohTrap [fBgnd],            /*          */                  /*          */
          flOpt,                                                /*          */
          fInstall,                                             /*          */
          fWait ))
          return FALSE;                                         /*            */
#endif /* EGAVGA */                                             /*          */
    } /* endif piohTrap */                                      /*          */
  /* endfor ppple */                                            /*          */

#ifdef   VGA
  /*
  ** Re-installing/de-installing hooks always re-enables trapping
  */
  VDMData.flVDMVideo |= (VDM_MOTIONTRAP | VDM_SPECIALTRAP);
#endif

  VDMData.flVDMXVideo |= VDMX_RTRCTRAP;
  return  TRUE;                                                     
}

/***************************************************************************
 *
 * FUNCTION NAME = VVSpecialCaseIO()
 *
 * DESCRIPTION   = Enable/disable special-case I/O according to state
 *
 *
 * INPUT         = hhook == hook handle (NULL if none)
 *                 pcrf  -> VDM register frame (NULL if called from VDD)
 *
 * OUTPUT        = None
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 * CALLED BY
 *      vvInt10SetMode (NULL, NULL)
 *      vvFaultHook    (NULL, NULL)
 *      vvSetRetraceEmulation passes to ALLOCHOOK
 *      vvBgndContext  (NULL, NULL)
 *      vvUpdateAll    (NULL, NULL)
 *      vvEnableIO     (NULL, NULL)
 *
 ****************************************************************************/

VOID EXPENTRY VVSpecialCaseIO(
  HHOOK hhook,
  PCRF pcrf )
{
  PPLE *ppple;
  BOOL fTrap;

#ifdef   VGA
  static PPLE appleSpecial [] =
  {
    &pleSEQIndx,
    &pleSEQData,
    &pleGDCIndx,
    &pleGDCData,
    NULL
  };

  if (VDMData.flVDMXVideo & VDMX_NOIOTRAPPING)                  /*          */
    return;
  /*
  ** If a VDM was suspended/frozen while an int10 hook was being processed,
  ** the foreground context hook will not fire off before the first hook 
  ** has returned, so we are clearly in danger of not having the foreground
  ** IO hooks installed. Lets try to repair the damage, until the kernel
  ** lets us do this kind of stuff.
  */
  if((VDMData.flVDMVideo & VDM_FGND) && (VDMData.flVDMVideo&VDM_BGNDREADY) &&
     !(VDMData.flVDMVideo & VDM_FGNDREADY) )                 /*           */
  {
      vvSetIOHooks( TRUE,               /* Bgnd */              /*          */
                    FALSE,              /* Remove */
                    TRUE );             /* Wait */
      VDMData.flVDMVideo &= ~VDM_BGNDREADY;
      vvSetIOHooks( FALSE,              /* Fgnd */              /*          */
                    TRUE,               /* Install */
                    TRUE );             /* Wait */
      VDMData.flVDMVideo |= VDM_FGNDREADY;                   /*           */
  }

  fTrap = (VDMData.mstateVideo <= MEMORY_FONT);

  if( fTrap != TESTBIT( VDMData.flVDMVideo,
                        VDM_SPECIALTRAP ) )
  {
    SETBIT( VDMData.flVDMVideo,
            VDM_SPECIALTRAP,
            fTrap );
    if( VDMData.flVDMVideo & VDM_FGND )
      for( ppple = appleSpecial;
           *ppple;
           ppple++ )
        VDHSetIOHookState(
          CURRENT_VDM,
          ((PSCGAINFO) psCurAdapterInfo)->                      /*          */
            pportfnCGAAdjustedPort( *ppple ),                   /*          */
          1,
          (*ppple)->sTrapBRegInfo.piohTrap,                     /*          */
          fTrap );
  }
  fTrap = TESTBIT( VDMData.flVDMVideo,
                   VDM_UNKNOWNFAULT );
  if( fTrap != TESTBIT( VDMData.flVDMVideo,
                        VDM_MOTIONTRAP ) )
  {
    SETBIT( VDMData.flVDMVideo,
            VDM_MOTIONTRAP,
            fTrap );
    if( VDMData.flVDMVideo & VDM_FGND )
      /*
      ** Note the 2: only fiddle with GDC ports for this case
      */
      for( ppple = &appleSpecial [2];
           *ppple;
           ppple++)
        VDHSetIOHookState(
          CURRENT_VDM,
          ((PSCGAINFO) psCurAdapterInfo)->                      /*          */
            pportfnCGAAdjustedPort( *ppple ),                   /*          */
          1,
          (*ppple)->sTrapBRegInfo.piohTrap,                     /*          */
          fTrap );
  }
#endif
  fTrap = TESTBIT( VDMData.flVDMXVideo,
                   VDMX_RTRCEMULATE );
  if( fTrap != TESTBIT( VDMData.flVDMXVideo,
                        VDMX_RTRCTRAP ) )
  {
    SETBIT( VDMData.flVDMXVideo,
            VDMX_RTRCTRAP,
            fTrap );

    if( VDMData.flVDMVideo & VDM_FGND )
    {
      VDHSetIOHookState(
        CURRENT_VDM,
        ((PSCGAINFO) psCurAdapterInfo)->                        /*          */
           pportfnCGAAdjustedPort(                              /*          */
             &pleFeatureWrite ),        /* Status1 */           /*          */
        1,
        pleFeatureWrite.sTrapBRegInfo.piohTrap,                 /*          */
        fTrap );

    }

  }
  if (hhook)
    FREEHOOK(hhook);
}

/***************************************************************************
 *
 * FUNCTION NAME = vvEnableIO()
 *
 * DESCRIPTION   = Enable I/O
 *
 *                 This routine walks through the foreground I/O hook list,
 *                 enabling VDM I/O access for every I/O port so privileged
 *                 (flagged PORTF_SPECIAL).  It is assumed that all ports are
 *                 currently being trapped by default.
 *
 * INPUT         = None
 *
 * OUTPUT        = None
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

VOID PRIVENTRY vvEnableIO()
{
  register INT i;
  register PPLE *ppple;
  PORT port;

  if (VDMData.flVDMXVideo & VDMX_NOIOTRAPPING)                  /*          */
    return;                                                     /*          */

  /*
  ** Walk the foreground hook list
  */
  for( ppple = appleAll;                                        /*          */
       *ppple;                                                  /*          */
       ppple++ )                                                /*          */
    if( !((*ppple)->sTrapBRegInfo.fTrapType & PORTF_NOTVALIDSVGAPORT)     /*                      */
        && (*ppple)->sTrapBRegInfo.piohTrap )                   /*          */
    {
      /*
      ** If don't want trapping, or no foreground hook function defined
      */
      IOH *piohTrap = &(*ppple)->sTrapBRegInfo.piohTrap[0]; /* foreground hook           */
      if(((*ppple)->sTrapBRegInfo.fTrapType & PORTF_SPECIAL) ||   /*          */
         (!piohTrap[0].ioh_pbihByteInput &&                     /*            */   
          !piohTrap[0].ioh_pbohByteOutput &&
          !piohTrap[0].ioh_pwihWordInput &&
          !piohTrap[0].ioh_pwohWordOutput &&
          !piohTrap[0].ioh_pothOther )) 
      {
        port = ((PSCGAINFO) psCurAdapterInfo)->                 /*          */
                 pportfnCGAAdjustedPort(                        /*          */
                   &(*ppple)->sTrapBRegInfo );                  /*          */
        /*
        ** Then undo the default state (trapping enabled)
        */
        VDHSetIOHookState( CURRENT_VDM,
                           port,
                           1,
                           (*ppple)->sTrapBRegInfo.piohTrap,
                           SETIO_NOTRAP );
#ifdef EGAVGA                                                   /*          */
        if( ((*ppple)->sTrapBRegInfo.fTrapType                  /*          */
             & PORTF_COLRMONO )                                 /*          */
            && !(flVVD & VVD_MONOPRESENT) )                     /*          */
          /* Undo trap for both color and mono */               /*          */
          /* These ports not installed within VMONO driver */   /*          */
          VDHSetIOHookState( CURRENT_VDM,                       /*          */
                             port                               /*          */
                             ^ (PORT_COLRCRTINDX                /*          */
                                ^ PORT_MONOCRTINDX),            /*          */
                             1,                                 /*          */
                             (*ppple)->sTrapBRegInfo.piohTrap,  /*          */
                             SETIO_NOTRAP );                    /*          */
#endif /* EGAVGA */                                             /*          */
      } /* endif hooks defined */
    } /* endif piohTrap */
  /* endfor ppple */

#ifdef   VGA
  VDMData.flVDMVideo &= ~ (VDM_MOTIONTRAP | VDM_SPECIALTRAP);
#endif
  VVSpecialCaseIO( NULL,
                   NULL );
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvInput()
 *
 * DESCRIPTION   = Input virtual register byte
 *
 * INPUT         =
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

BYTE PRIVENTRY vvInput(                                         /*          */
  HVDM hvdm,
  PPLE pple )                                                   /*          */
{
  register BYTE bInput;
  register PBYTE pbShadowAddr;
  register PORT port;                                           /*          */

  if( pple )                                                    /*          */
  {                                                             /*          */
    port = ((PSCGAINFO) psCurAdapterInfo)->                     /*          */
              pportfnCGAAdjustedPort( &pple->sTrapBRegInfo );   /*          */
    if( hvdm == INVALID_HVDM )                                  /*          */
      bInput = INB( port );                                     /*          */
    else                                                        /*          */
    {                                                           /*          */
      pbShadowAddr =
        pVDM( hvdm,                                             /*          */
              PBYTE,                                            /*          */
              pple->sTrapBRegInfo.pvTrapReadShadow );           /*          */
      if( pple->sTrapBRegInfo.fTrapType & READ_INDX_FLAG)       /*          */
        pbShadowAddr +=                                         /*          */
          *pVDM(                                                /*          */
             hvdm,                                              /*          */
             PBYTE,                                             /*          */
             pple->ppleBRegIndx->                               /*          */
               sTrapBRegInfo.pvTrapWriteShadow );               /*          */
      if( pVDMData( hvdm )->flVDMVideo & VDM_FGND )
        *pbShadowAddr = INB( port );
      bInput = *pbShadowAddr;
    }                                                           /*          */
  }
  return( bInput );                                             /*          */
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvOutput()
 *
 * DESCRIPTION   = Output virtual register byte
 *
 * INPUT         =
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

VOID PRIVENTRY vvOutput(                                        /*          */
  HVDM hvdm,
  PPLE pple,                                                    /*          */
  BYTE bData )
{
  register PBYTE pbShadowAddr;
  register PORT port;                                           /*          */

  if( pple )                                                    /*          */
  {                                                             /*          */
    port = ((PSCGAINFO) psCurAdapterInfo)->                     /*          */
              pportfnCGAAdjustedPort( &pple->sTrapBRegInfo );   /*          */
    if( hvdm == INVALID_HVDM )                                  /*          */
      OUTB( port, bData );                                      /*          */
    else                                                        /*          */
    {                                                           /*          */
      pbShadowAddr =
        pVDM( hvdm,                                             /*          */
              PBYTE,                                            /*          */
              pple->sTrapBRegInfo.pvTrapWriteShadow );          /*          */
      if( pple->sTrapBRegInfo.fTrapType & WRITE_INDX_FLAG)      /*          */
        pbShadowAddr +=                                         /*          */
          *pVDM(                                                /*          */
             hvdm,                                              /*          */
             PBYTE,                                             /*          */
             pple->ppleBRegIndx->                               /*          */
               sTrapBRegInfo.pvTrapWriteShadow );               /*          */
      if( pVDMData( hvdm )->flVDMVideo & VDM_FGND )
        OUTB( port, bData );
      *pbShadowAddr = bData;                                    /*          */
    }                                                           /*          */
  }
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvInputWord()
 *
 * DESCRIPTION   = Input virtual register word
 *
 * INPUT         =
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

WORD PRIVENTRY vvInputWord(
  HVDM hvdm,
  PSTRAPREGINFO psTrapRegInfo )
{
  WORD wInput;
  register PWORD pwShadowAddr;
  PORT port;

  if( psTrapRegInfo )
  {
    port = psTrapRegInfo->portTrap;                             /*          */
    if( hvdm == INVALID_HVDM )                                  /*          */
      _asm
      {
        mov  dx, word ptr port
        in   ax, dx
        mov  wInput, ax
      }
    else
    {                                                           /*          */
      pwShadowAddr =                                            /*          */
        pVDM( hvdm,                                             /*          */
              PWORD,                                            /*          */
              psTrapRegInfo->pvTrapReadShadow );                /*          */
      if( pVDMData( hvdm )->flVDMVideo & VDM_FGND )             /*          */
      {                                                         /*          */
        _asm                                                    /*          */
        {                                                       /*          */
          mov  dx, word ptr port                                /*          */
          in   ax, dx                                           /*          */
          mov  wInput, ax                                       /*          */
        }                                                       /*          */
        *pwShadowAddr = wInput;                                 /*          */
      }                                                         /*          */
      else                                                      /*          */
        wInput = *pwShadowAddr;                                 /*          */
    }                                                           /*          */
  }
  return( wInput );
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvOutputWord()
 *
 * DESCRIPTION   = Output virtual register word
 *
 * INPUT         =
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

VOID PRIVENTRY vvOutputWord(
  HVDM hvdm,
  PSTRAPREGINFO psTrapRegInfo,
  WORD wOutput )
{
  PORT port;

  if( psTrapRegInfo )
  {
    if( (hvdm == INVALID_HVDM)
        || (pVDMData( hvdm )->flVDMVideo & VDM_FGND) )
    {
      port = psTrapRegInfo->portTrap;
      _asm
      {
        mov  dx, word ptr port
        mov  ax, wOutput
        out  dx, ax
      };
    }
    if( hvdm != INVALID_HVDM )
      *pVDM( hvdm,
             PWORD,
             psTrapRegInfo->pvTrapWriteShadow ) = wOutput;
  }
}

/***************************************************************************
 *
 * FUNCTION NAME = vvDisableDisplay(hvdm)
 *
 * DESCRIPTION   = Disable display
 *
 *                 This turns the video signal off, helping to hide
 *                 unsightly adapter reprogramming.  A side-effect of this
 *                 service is that the VDM's virtual MISCOUT register (for
 *                 EGA/VGA) is transferred to the physical hardware, so that
 *                 we can make at least a *few* assumptions about the
 *                 hardware state.
 *
 * INPUT         = hvdm -> VDM
 *
 * OUTPUT        = None
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

VOID PRIVENTRY vvDisableDisplay(
  register HVDM hvdm )
{
  register PVDMDATA pvd = pVDMData(hvdm);

  if( pvd->flVDMVideo & VDM_FGND )
  {

#ifdef MONOCGA
    vvOutput( INVALID_HVDM,             /* Don't change shadow! */
              &pleCRTMode,
              (BYTE) (pvd->regMode & ~CGAMODE_ENABLE) );
                  /* Same as MONOMODE_ENABLE */
#else /* MONOCGA */
    /*
    ** If we're the display owner, insure any 8514/A is disabled
    */
    if( pvd->flVDMXVideo & VDMX_DSPOWNER )
      if( flVVD & VVD_8514PRESENT )               /*          *//*          */
        OUTW( A8514_ADVCTRL,
              !ADVCTRL_VGADISABLE | ADVCTRL_OUTPUTPIN | !ADVCTRL_DOTCLOCK );
    /* reset the ATC to index-state first  */
    vvInput( INVALID_HVDM,              /* Don't change shadow! */
             &pleFeatureWrite );        /* Status1 for read! */
    vvOutput( INVALID_HVDM,
              &pleATC0,
              (BYTE) (pvd->regATCIndx & ~ATCPAL_ENABLE) );
#ifdef MONOCGA
#else /* MONOCGA */
#endif /* MONOCGA */
#endif /* MONOCGA */
  }
}

/***************************************************************************
 *
 * FUNCTION NAME = vvEnableDisplay()
 *
 * DESCRIPTION   = Enable display
 *
 *                 This turns the video signal on, after all video adapter
 *                 reprogramming is complete.  Also, since vvRestoreIOState
 *                 could not properly update the particular register involved
 *                 (lest it re-enable the screen before we're ready), we take
 *                 care of that last little "bit" of virtual-to-physical
 *                 restoration here.
 *
 * INPUT         = hvdm -> VDM
 *
 * OUTPUT        = None
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

VOID PRIVENTRY vvEnableDisplay(
  register HVDM hvdm )
{
  register PVDMDATA pvd = pVDMData(hvdm);
  BYTE bSaveIndex, bSaveData;

  if( pvd->flVDMVideo & VDM_FGND )
  {

#ifdef   MONO
    vvOutput( INVALID_HVDM,
              &pleCRTMode,
              /* pvd->regMode ); */                                  /*73042*/
              (BYTE) (pvd->regMode | MONOMODE_ENABLE) );             /*73042*/
#endif

#ifdef   CGA
    vvOutput( INVALID_HVDM,
              &pleCRTMode,
              pvd->regMode );
#endif

#ifdef   EGAVGA
    /* reset the ATC to index-state first  */
    vvInput( INVALID_HVDM,              /* Don't change shadow! */
             &pleFeatureWrite );        /* Status1 for read! */
    vvOutput( INVALID_HVDM,
              &pleATC0,
              pvd->regATCIndx );        /* store it in the ATC index register     */
    /*
    ** If not in DATA mode, cycle back to INDEX mode
    */
    if( pvd->stateATC != ATC_DATA )
      /* reset the ATC to index-state first  */
      vvInput( INVALID_HVDM,            /* Don't change shadow! */
               &pleFeatureWrite );      /* Status1 for read! */
    /*
    ** If seq 1 has video disabled, enable it.          //          
    */
    if( pvd->aregSEQData[1] & 0x20 )
    {
      bSaveIndex = vvInput( INVALID_HVDM,
                            &pleSEQIndx );
      vvOutput( INVALID_HVDM,
                &pleSEQIndx,
                0x01 );
      bSaveData = vvInput( INVALID_HVDM,
                            &pleSEQData);
      vvOutput( INVALID_HVDM,
                &pleSEQData,
                (BYTE) (bSaveData & ~ 0x20) );                  /*          */
      vvOutput( INVALID_HVDM,
                &pleSEQIndx,
                bSaveIndex );
    }
#endif
  }
}

#ifdef   CGA

/***************************************************************************
 *
 * FUNCTION NAME = VVForceDisplay()
 *
 * DESCRIPTION   = Force display on (for VKBD)
 *
 *                 This forces the video signal on, on request from VKBD (to
 *                 insure that the screen is not left indefinitely disabled
 *                 while in a keyboard-paused state).
 *
 * INPUT         = None
 *
 * OUTPUT        = None
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 * PSEUDO-CODE
 *                 set virtual enable bit
 *                 turn on the physical enable bit
 *
 ****************************************************************************/

VOID EXPENTRY VVForceDisplay()
{
  VDMData.regMode |= CGAMODE_ENABLE;
  vvOutput( INVALID_HVDM,                                       /*          */
            &pleCRTMode,                                        /*          */
            VDMData.regMode );
}

#endif /* CGA */

#pragma  END_SWAP_CODE

