/*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 = VVEGA.C
 *
 * DESCRIPTIVE NAME = Virtual Video EGA Specific routines
 *
 *
 * VERSION = V2.0
 *
 * DATE      11/10/88
 *
 * DESCRIPTION
 *              This module contains the VVD's VGA specific routines and data.
 *
 *
 * FUNCTIONS
 *
 * 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

#pragma  BEGIN_SWAP_DATA

extern IOH aiohCGAUnknown [2];                                  /*          */

#ifdef EGA
#ifdef COMPAQ

IOH aiohCompaqCtrl [2] =                 /* 03c6 */
{
  {
    NULL,
  },
  {
    &VVReadCompaqCtrlBgnd,
    &VVWriteCompaqCtrlBgnd,
  },
};

#endif /* COMPAQ */
#endif /* EGA */

/*!!For these PORTF_TRAP effects only foreground */

IOH aiohATC0 [2] =                      /* 03c0 */
{
  {
#ifdef VGA
    NULL,
#else /* VGA */
    &VVReadATCFgnd,
#endif /* VGA */
    &VVWriteATCFgnd,
#ifndef VGA
    &VVReadATCFgndW,
    &VVWriteATCFgndW,
#endif /* !VGA */
  },
  {
    &VVReadATCBgnd,
    &VVWriteATCBgnd,
  },
};

IOH aiohATC1 [2] =                      /* 03c1 */
{
  {
#ifdef VGA
    NULL,
    NULL,
#else /* VGA */
    &VVReadATC1Fgnd,
    &VVWriteATCFgnd,
#endif /* VGA */
  },
  {
    &VVReadATC1Bgnd,
#ifdef VGA
    &VVWriteUnknownBgnd,
#else /* VGA */
    &VVWriteATCBgnd,
#endif /* VGA */
  },
};

IOH aiohMiscOutWrite [2] =              /* 03c2 */
{
  {
    NULL,
    &VVWriteMiscOutFgnd,
  },
  {
    &VVReadStatus0Bgnd,
    &VVWriteMiscOutBgnd,
  },
};

IOH aiohSEQIndx [2] =                   /* 03c4 */
{
  {
#ifdef VGA
    NULL,
#else /* VGA */
    &VVReadSEQIndxFgnd,
#endif /* VGA */
    &VVWriteSEQIndxFgnd,
#ifdef VGA
    NULL,
    NULL,
#else /* VGA */
    &VVReadSEQIndxFgndW,
    &VVWriteSEQIndxFgndW,
#endif /* VGA */
  },
  {
    &VVReadSEQIndxBgnd,
    &VVWriteSEQIndxBgnd,
  },
};

IOH aiohSEQData [2] =                   /* 03c5 */
{
  {
#ifdef VGA
    NULL,
#else /* VGA */
    &VVReadSEQDataFgnd,
#endif /* VGA */
    &VVWriteSEQDataFgnd,
  },
  {
    &VVReadSEQDataBgnd,
    &VVWriteSEQDataBgnd,
  },
};

IOH aiohGDCPos2 [2] =                   /* 03ca */
{
  {
#ifdef VGA
    NULL,
    NULL,
#else /* VGA */
    &VVReadFeatureFgnd,
    &VVWriteGDC2Fgnd,
#endif /* VGA */
  },
  {
    &VVReadFeatureBgnd,
#ifdef VGA
    NULL,
#else /* VGA */
    &VVWriteGDC2Bgnd,
#endif /* VGA */
  },
};

IOH aiohGDCPos1 [2] =                   /* 03cc */
{
  {
#ifdef VGA
    NULL,
    NULL,
#else /* VGA */
    &VVReadMiscOutFgnd,
    &VVWriteGDC1Fgnd,
#endif /* VGA */
  },
  {
    &VVReadMiscOutBgnd,
#ifdef VGA
    NULL,
#else /* VGA */
    &VVWriteGDC1Bgnd,
#endif /* VGA */
  },
};

IOH aiohGDCIndx [2] =                   /* 03ce */
{
  {
#ifdef VGA
    NULL,
#else /* VGA */
    &VVReadGDCIndxFgnd,
#endif /* VGA */
    &VVWriteGDCIndxFgnd,
#ifdef VGA
    NULL,
    NULL,
#else /* VGA */
    &VVReadGDCIndxFgndW,
    &VVWriteGDCIndxFgndW,
#endif /* VGA */
  },
  {
    &VVReadGDCIndxBgnd,
    &VVWriteGDCIndxBgnd,
  },
};

IOH aiohGDCData [2] =                   /* 03cf */
{
  {
#ifdef VGA
    NULL,
#else /* VGA */
    &VVReadGDCDataFgnd,
#endif /* VGA */
    &VVWriteGDCDataFgnd,
  },
  {
    &VVReadGDCDataBgnd,
    &VVWriteGDCDataBgnd,
  },
};

#ifdef EGA
#ifdef ATI

/* R/W, not saved on screen-switch */
/*  (because we don't know the format) */

IOH aiohATIEGAIndx [2] =                /* 03cb */
{
  {
    NULL,
  },
  {
    &VVReadATIIndxBgnd,
    &VVWriteATIIndxBgnd,
  },
};

IOH aiohATIEGAData [2] =                /* 03cd */
{
  {
    NULL,
  },
  {
    &VVReadATIDataBgnd,
    &VVWriteATIDataBgnd,
  },
};

#endif /* ATI */
#endif /* EGA */

#ifdef SVGA
 /*
 **
 **  These bit masks determine which indexed registers in each group
 **  are saved/restored. They are initialised to standard VGA registers
 **  and modified during the PMI file parsing to reflect the particular
 **  adapter's extended registers. Note, each array must end with a zero
 **  which will fill the un-initialised elements.
 **  Bit masks are changed to byte masks to represent specific     @V3.0YEE01
 **  bits for selective restore.                                   @V3.0YEE01
 */

//@V3.0YEE01 BYTE    abGDCMask[32] = {0xff, 0x01, 0};            /*  9                     */
//@V3.0YEE01 BYTE    abSEQMask[32] = {0x1f, 0};                  /*  5 registers           */
//@V3.0YEE01 BYTE    abATCMask[32] = {0xff, 0xff, 0x1f, 0};      /* 21                     */
BYTE abGDCMask [MAX_GDCREGS] =          /* 9 EGA/VGA regs */
{
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0x00
};

BYTE abSEQMask [MAX_SEQREGS] =          /* 5 EGA/VGA regs */
{
  0xff, 0xff, 0xff, 0xff, 0xff, 0x00
};

BYTE abATCMask [MAX_ATCREGS] =          /* 21 EGA/VGA regs */
{
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x00 */
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x08 */
  0xff, 0xff, 0xff, 0xff, 0xff, 0x00              /* 0x10 */
};
#endif /* SVGA */

PLE pleATC0 =                                                   /*          */
{
  {                                                             /*          */
    PORT_ATC0,                          /* 3C0h (R/W) */
    &VDMData.regATCIndx,                                        /*          */
    &VDMData.regATCIndx,                                        /*          */
    PORTF_INDEXDATA                     /* both Index & Data */
      | WRITE_MANY | READ_MANY | R_EQ_W,                        /*          */
    aiohATC0,                                                   /*          */
  },                                                            /*          */
  0,                                    /* 15h registers */
  NULL,                                                         /*          */
#ifdef SVGA                                                     /*          */
  NULL,
  NULL,                                                         /*            */
#endif /* SVGA */                                               /*          */
  0,
  PLE_WAITVERT << REG_ATCMODECTRL,
};

PLE pleATCx =                                                   /*          */
{                                                               /*          */
  {                                                             /*          */
    PORT_ATC0,                          /* 3C0h (R/W) */
    &VDMData.aregATCData[0],                                    /*          */
    &VDMData.aregATCData[0],                                    /*          */
    PORTF_INDEXDATA                     /* both Index & Data */
      | WRITE_MANY | READ_MANY | R_EQ_W,                        /*          */
    aiohATC0,                                                   /*          */
  },                                                            /*          */
#ifdef EGA                                                      /*          */
  TOTAL_EGA_ATCREGS,                                            /*          */
#else /* EGA */                                                 /*          */
  TOTAL_IBM_ATCREGS,                    /* 15h registers */     /*          */
#endif /* EGA */                                                /*          */
  &pleATC0,                                                     /*          */
#ifdef SVGA                                                     /*          */
  &abATCMask[0],                                                /*          */
  &abATCMask[0],                                                /*           */
#endif /* SVGA */                                               /*          */
  0,                                                            /*          */
  PLE_WAITVERT << REG_ATCMODECTRL,                              /*          */
};                                                              /*          */

PLE pleATC1 =                                                   /*          */
{                                                               /*          */
  {                                                             /*          */
    PORT_ATC1,                          /* 3C1h (R/O) */        /*          */
    &VDMData.aregATCData[0],                                    /*          */
    &VDMData.aregATCData[0],            /* Not ever written */  /*          */
    WRITE_NONE | READ_INDX | R_NE_W,                            /*          */
    aiohATC1,                                                   /*          */
  },                                                            /*          */
  TOTAL_EGA_ATCREGS,                                            /*          */
  &pleATC0,                                                     /*          */
#ifdef SVGA                                                     /*          */
  &abATCMask[0],                                                /*          */
  &abATCMask[0],                                                /*           */
#endif /* SVGA */                                               /*          */
};                                                              /*          */

PLE pleMiscOutWrite =                   /* 03c2 (R/O) */        /*          */
{
  {                                                             /*          */
    PORT_MISCOUT,
    &VDMData.regMiscOut,                /* R_NE_W! */
    &VDMData.regStatus0,
    WRITE_MANY | READ_MANY | R_NE_W,                            /*          */
    aiohMiscOutWrite,                                           /*          */
  },                                                            /*          */
  0,
  NULL,
};

PLE pleSEQIndx =                        /* 03c4 (R/W) */        /*          */
{
  {                                                             /*          */
    PORT_SEQINDX,
    &VDMData.regSEQIndx,                                        /*          */
    &VDMData.regSEQIndx,                                        /*          */
#ifdef SVGA                                                     /*          */
    PORTF_SPECIAL |                                             /*          */
#endif /* SVGA */                                               /*          */
    WRITE_MANY | READ_MANY | R_EQ_W,                            /*          */
    aiohSEQIndx,                                                /*          */
  },                                                            /*          */
  0,                                                            /*          */
  NULL,                                                         /*          */
#ifdef SVGA                                                     /*          */
  NULL,                                                         /*          */
  NULL,                                                         /*           */
#endif /* SVGA */                                               /*          */
  PLE_RESETSEQ << REG_SEQCLKMODE |
    PLE_RESETSEQ << REG_SEQMEMMODE,
};

PLE pleSEQData =                        /* 03c5 (R/W) */        /*          */
{                                                               /*          */
  {                                                             /*          */
    PORT_SEQDATA,                                               /*          */
    &VDMData.aregSEQData[0],                                    /*          */
    &VDMData.aregSEQData[0],                                    /*          */
#ifdef SVGA                                                     /*          */
    PORTF_SPECIAL |                                             /*          */
#endif /* SVGA */                                               /*          */
    WRITE_INDX | READ_INDX | R_EQ_W,                            /*          */
    aiohSEQData,                                                /*          */
  },                                                            /*          */
  /* SVGA grows this during PMI TRAPREGS processing */          /*          */
  /* VGA changes this to TOTAL_TSENG == MAX if needed */        /*          */
  TOTAL_IBM_SEQREGS,                                            /*          */
  &pleSEQIndx,                                                  /*          */
#ifdef SVGA                                                     /*          */
  &abSEQMask[0],                                                /*          */
  &abSEQMask[0],                                                /*          */
#endif /* SVGA */                                               /*          */
  PLE_RESETSEQ << REG_SEQCLKMODE |
    PLE_RESETSEQ << REG_SEQMEMMODE,
};

PLE pleGDCPos2 =                        /* pleFeatureRead */    /*          */
{
  {                                                             /*          */
    PORT_GDCPOS2,                       /* 3CA */
    &VDMData.regGDCPos2,                /* R_NE_W! */
    &VDMData.regFeature,
    WRITE_MANY | READ_MANY | R_NE_W,                            /*          */
    aiohGDCPos2,                                                /*          */
  },                                                            /*          */
  0,
  NULL,
};

PLE pleGDCPos1 =                        /* pleMiscOutRead */    /*          */
{
  {                                                             /*          */
    PORT_GDCPOS1,                       /* 3CC (R/O) */
    &VDMData.regGDCPos1,                /* R_NE_W! */
    &VDMData.regMiscOut,
    WRITE_MANY | READ_MANY | R_NE_W,                            /*          */
    aiohGDCPos1,                                                /*          */
  },                                                            /*          */
  0,
  NULL,
};

PLE pleGDCIndx =                                                /*          */
{
  {                                                             /*          */
    PORT_GDCINDX,                       /* 3CEh (R/W) */
    &VDMData.regGDCIndx,                                        /*          */
    &VDMData.regGDCIndx,                                        /*          */
#ifdef SVGA                                                     /*          */
    PORTF_SPECIAL |                                             /*          */
#endif /* SVGA */                                               /*          */
    WRITE_MANY | READ_MANY | R_EQ_W,                            /*          */
    aiohGDCIndx,                                                /*          */
  },                                                            /*          */
  0,                                                            /*          */
  NULL,                                                         /*          */
#ifdef SVGA                                                     /*          */
  NULL,                                                         /*          */
  NULL,                                                         /*@Vsenja*/
#endif /* SVGA */                                               /*          */
  PLE_RESETSEQ << REG_GDCMISC,
  PLE_WAITVERT << REG_GDCMISC,
};

PLE pleGDCData =                                                /*          */
{                                                               /*          */
  {                                                             /*          */
    PORT_GDCDATA,                       /* 3CFh (R/W) */        /*          */
    &VDMData.aregGDCData[0],                                    /*          */
    &VDMData.aregGDCData[0],                                    /*          */
#ifdef SVGA                                                     /*          */
    PORTF_SPECIAL |                                             /*          */
#endif /* SVGA */                                               /*          */
    WRITE_INDX | READ_INDX | R_EQ_W,                            /*          */
    aiohGDCData,                                                /*          */
  },                                                            /*          */
  /* SVGA grows this during PMI TRAPREGS processing */          /*          */
  /* VGA changes this to TOTAL_TSENG == MAX if needed */        /*          */
  TOTAL_IBM_GDCREGS,                    /* 09h registers */     /*          */
  &pleGDCIndx,                                                  /*          */
#ifdef SVGA                                                     /*          */
  &abGDCMask[0],                                                /*          */
  &abGDCMask[0],                                                /*          */
#endif /* SVGA */                                               /*          */
  PLE_RESETSEQ << REG_GDCMISC,
  PLE_WAITVERT << REG_GDCMISC,
};

#ifdef EGA
#ifdef COMPAQ

PLE pleCompaqCtrl =                     /* 03c6 */              /*          */
{
  {                                                             /*          */
    PORT_COMPAQ_CTRL,
    &VDMData.regCompaqCtrl,
    &VDMData.regCompaqCtrl,
    WRITE_MANY | READ_MANY | R_EQ_W,                            /*          */
    aiohCompaqCtrl,                                             /*          */
  },                                                            /*          */
  0,
  NULL,
};

PLE pleCompaqEnv =                      /* 07c6 */              /*          */
{                                                               /*          */
  {                                                             /*          */
    PORT_COMPAQ_ENV,                                            /*          */
    NULL,                                                       /*          */
    NULL,                                                       /*          */
    WRITE_MANY | READ_MANY | R_EQ_W,                            /*          */
    aiohCGAUnknown,                                             /*          */
  },                                                            /*          */
  0,                                                            /*          */
  NULL,                                                         /*          */
};                                                              /*          */

PLE pleCompaqDsp =                      /* 0bc6 */              /*          */
{                                                               /*          */
  {                                                             /*          */
    PORT_COMPAQ_DSP,                                            /*          */
    NULL,                                                       /*          */
    NULL,                                                       /*          */
    WRITE_MANY | READ_MANY | R_EQ_W,                            /*          */
    aiohCGAUnknown,                                             /*          */
  },                                                            /*          */
  0,                                                            /*          */
  NULL,                                                         /*          */
};                                                              /*          */

PLE pleCompaqMode =                     /* 0fc6 */              /*          */
{                                                               /*          */
  {                                                             /*          */
    PORT_COMPAQ_MODE,                                           /*          */
    NULL,                                                       /*          */
    NULL,                                                       /*          */
    WRITE_MANY | READ_MANY | R_EQ_W,                            /*          */
    aiohCGAUnknown,                                             /*          */
  },                                                            /*          */
  0,                                                            /*          */
  NULL,                                                         /*          */
};                                                              /*          */

#endif /* COMPAQ */

#ifdef ATI

PLE pleATIEGAIndx =                     /* 03cb */              /*          */
{                                                               /*          */
  {                                                             /*          */
    PORT_ATIEGA_INDX,                                           /*          */
    NULL,                                                       /*          */
    NULL,                                                       /*          */
    WRITE_MANY | READ_MANY | R_EQ_W,                            /*          */
    aiohATIEGAIndx,                                             /*          */
  },                                                            /*          */
  0,                                                            /*          */
  NULL,                                                         /*          */
};                                                              /*          */

PLE pleATIEGAData =                     /* 03cd */              /*          */
{                                                               /*          */
  {                                                             /*          */
    PORT_ATIEGA_DATA,                                           /*          */
    NULL,                                                       /*          */
    NULL,                                                       /*          */
    WRITE_MANY | READ_MANY | R_EQ_W,                            /*          */
    aiohATIEGAData,                                             /*          */
  },                                                            /*          */
  0,                                                            /*          */
  NULL,                                                         /*          */
};                                                              /*          */

#endif /* ATI */
#endif /* EGA */

SEGAINFO sEGAAdapterInfo;               /* Forward */           /*          */

#ifdef EGA                                                      /*          */
PSADAPTERINFO psCurAdapterInfo = &sEGAAdapterInfo;              /*          */
#else /* EGA */                                                 /*          */
extern PSADAPTERINFO psCurAdapterInfo;                          /*          */
#endif /* EGA */                                                /*          */

#pragma  END_SWAP_DATA

#pragma  BEGIN_SWAP_CODE

/***************************************************************************
 *
 * FUNCTION NAME = vvEGAAdjustedPort()
 *
 * DESCRIPTION   = Adjust given port # for current state
 *
 *                 Strips off flags attached to port #, if any, and adjusts
 *                 the value of the port, if necessary.
 *
 * INPUT         = psTrapRegInfo contains port #
 *
 * OUTPUT        = port (possibly unchanged)
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

PORT PRIVENTRY vvEGAAdjustedPort(
  PSTRAPREGINFO psTrapRegInfo )
{
  return( ((psTrapRegInfo->fTrapType & PORTF_COLRMONO)
                                        /* Make mono first */
           ? (((psTrapRegInfo->portTrap & ~ 0x0040) | 0x0020)   /*          */
              + ((INB( PORT_GDCPOS1 )   /* Add in color */      /*          */
                  & MISCOUT_COLRPORTS)                          /*          */
                 << 5))                                         /*          */
  /*          ^ Definitely PLUS and not OR!    */               /*          */
           : psTrapRegInfo->portTrap) );                        /*          */
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvEGAOddEvenMode
 *
 * DESCRIPTION   = Get CGA odd even mode
 *
 * INPUT         = hvdm
 *
 * OUTPUT        = True = 320x200 graphics mode/MEMORY_CGAX
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

BOOL PRIVENTRY vvEGAOddEvenMode(
  HVDM hvdm )
{
  register PVDMDATA pvd = pVDMData(hvdm);

  /*
  ** Check requirements for being in CGAX-mode
  */
//#ifdef   EGAVGA                                               /*          */
//  if( !(pvd->aregCRTData [REG_CRTMODECTRL] & CRTMCTRL_COMPAT) )
//  {                                                           /*          */
//#else /* MONOCGA */                                           /*          */
//#endif /* EGAVGA */                                           /*          */
//if( ul == (((SEQMAP_PLANE0 | SEQMAP_PLANE1)
//            << SEQMAPMASK_SHIFT)
//           | ((GDCMODE_ODDEVENDIFF | GDCMODE_ODDEVENBITS)
//              << GDCMODE_SHIFT)
//           | ((GDCMISC_ODDTOEVEN | GDCMISC_NOCHARGEN)
//              << GDCMISC_SHIFT)) )
//return( (pvd->aregGDCData[REG_GDCMODE] & GDCMODE_ODDEVENBITS) /*          */
//        >> ZEROBITS( GDCMODE_ODDEVENBITS ) );                 /*          */
  return( (pvd->aregGDCData [REG_GDCMISC] & GDCMISC_ALL)        /*          */
          == GDCMISC_ALL );                                     /*          */
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvEGAHighResMode
 *
 * DESCRIPTION   = Get CGA high res mode
 *
 * INPUT         = hvdm
 *
 * OUTPUT        = True = 640x200 graphics mode/MEMORY_GRFX2
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

BOOL PRIVENTRY vvEGAHighResMode(
  HVDM hvdm )
{
  register PVDMDATA pvd = pVDMData(hvdm);

  /*
  ** Check requirements for being in GRFX2-mode
  */
//#ifdef   EGAVGA                                               /*          */
//  if( !(pvd->aregCRTData [REG_CRTMODECTRL] & CRTMCTRL_COMPAT) )
//  {                                                           /*          */
//#else /* MONOCGA */                                           /*          */
//#endif /* EGAVGA */                                           /*          */
//if( (ul == ((SEQMAP_PLANE0 << SEQMAPMASK_SHIFT)               /*          */
//            | (SEQMEM_ODDEVENSAME << SEQMEMMODE_SHIFT)        /*          */
//            | (GDCMISC_NOCHARGEN << GDCMISC_SHIFT)))          /*          */
//    && ((pvd->aregATCData [REG_ATCPLANEENABLE] & SEQMAP_ALL)  /*          */
//        == SEQMAP_PLANE0) )                                   /*          */
//return( (pvd->aregGDCData[REG_GDCMISC] & GDCMISC_NOCHARGEN)   /*          */
//        >> ZEROBITS( GDCMISC_NOCHARGEN ) );                   /*          */
  return( (pvd->aregGDCData[REG_GDCMISC] & GDCMISC_ALL)         /*          */
          == (GDCMISC_32K_B8000 | GDCMISC_NOCHARGEN) );         /*          */
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvEGAHorzDspEnd
 *
 * DESCRIPTION   = Get Horizontal Display Width
 *
 * INPUT         = hvdm
 *
 * OUTPUT        = Horizontal Display Width
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT PRIVENTRY vvEGAHorzDspEnd(
  HVDM hvdm )
{
  return( vvCGAHorzDspEnd( hvdm ) + 1 );
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvEGAHorzLogEnd
 *
 * DESCRIPTION   = Get Horizontal Logical End
 *
 * INPUT         = hvdm
 *
 * OUTPUT        = Horizontal Logical End in BYTES!!!!
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT PRIVENTRY vvEGAHorzLogEnd(
  HVDM hvdm )
{
  register PVDMDATA pvd = pVDMData(hvdm);
  USHORT usLogEndBytes = pvd->aregCRTData [REG_CRTOFFSET]
                        << (1
                        + ((pvd->aregCRTData[REG_CRTUNDLINELOC])
                           ? 2
                           : !(pvd->aregCRTData [REG_CRTMODECTRL] & 0x40)));
  return( usLogEndBytes );                   /*                      */
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvEGAVertDspEnd
 *
 * DESCRIPTION   = Get Vertical Display Length
 *
 * INPUT         = hvdm
 *
 * OUTPUT        = Vertical Display Width
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT PRIVENTRY vvEGAVertDspEnd(
  HVDM hvdm )
{
  register PVDMDATA pvd = pVDMData(hvdm);

  return( (pvd->aregCRTData [REG_CRTVERTDSPEND] + 1)
          + ((pvd->aregCRTData [REG_CRTOVERFLOW] & CRTOVFL_VERTDSPEND)
             >> ZEROBITS( CRTOVFL_VERTDSPEND ) << 8) );
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvEGABitsPerPixel
 *
 * DESCRIPTION   = Get Bits Per Pixel
 *
 * INPUT         = hvdm
 *
 * OUTPUT        = Bits Per Pixel
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT PRIVENTRY vvEGABitsPerPixel(
  HVDM hvdm )
{
  register PVDMDATA pvd = pVDMData(hvdm);

          /* Apparently some superEGAs have a packed mode! */   /*          */
  return( (((PSEGAINFO) psCurAdapterInfo)->                     /*          */
             pbfnEGAPackedMode( hvdm )                          /*          */
           ? 8
           : vvCGABitsPerPixel( hvdm )) );
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvEGAPackedMode
 *
 * DESCRIPTION   = Get SVGA packed pixel mode.
 *
 *                 This req'd because the GDC Mode reg doesn't reflect
 *                 256-colour modes.
 *
 *                 ATI has bits in extended 'ATI registers'.
 *                 Video7 have bits in extended sequencer 0xfc.
 *
 * INPUT         = hvdm
 *
 * OUTPUT        = True = 256 colour mode
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 * REMARK: More on the fault hook processing...
 *         Page mapping depends on the state evaluated from the
 *         shadow registers,
 *         which has to represent the true state of the hardware.
 *         If the register is not added to the aprleMemory structure,
 *         its shadow value represents the true state
 *         only after the mode set has returned,
 *         when vvUpdateAll will refresh them all.
 *         If the page mappings are believed to be       at that time,
 *         they will be invalidated and fault hooks enabled again.
 *         However, if evaluating 256-color (i.e. packed) mode
 *         is essential before the mode set returns,
 *         ensure that the register which is being evaluated is added
 *         to the aprleMemory struc.
 *
 ****************************************************************************/

BOOL PRIVENTRY vvEGAPackedMode(
  HVDM hvdm )
{
  register PVDMDATA pvd = pVDMData(hvdm);

  return( (pvd->aregGDCData [REG_GDCMODE] & GDCMODE_256COLOR)
          >> ZEROBITS( GDCMODE_256COLOR ) );
}
                                                                /*          */
/***************************************************************************
 *
 * FUNCTION NAME = vvEGAVertLineCmp
 *
 * DESCRIPTION   = Get Vertical Display Compare
 *
 * INPUT         = hvdm
 *
 * OUTPUT        = Vertical Line Compare (for split screen)
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT PRIVENTRY vvEGAVertLineCmp(
  HVDM hvdm )
{
  register PVDMDATA pvd = pVDMData(hvdm);

  return( (pvd->aregCRTData [REG_CRTLINECMP] + 1)
          + ((pvd->aregCRTData [REG_CRTOVERFLOW] & CRTOVFL_LINECMP)
             >> ZEROBITS( CRTOVFL_LINECMP ) << 8) );
}

#pragma  END_SWAP_CODE

#pragma  BEGIN_SWAP_DATA                                        /*          */

SEGAINFO sEGAAdapterInfo =                                      /*          */
{
  { /* SCGAINFO */
    &vvEGAAdjustedPort,
    &vvCGAStartAddr,
    &vvEGAOddEvenMode,
    &vvEGAHighResMode,
    &vvEGAHorzDspEnd,
    &vvEGAHorzLogEnd,
    &vvEGAVertDspEnd,
    &vvEGABitsPerPixel,
    &vvCGAPrepareSetMode,
  },
  &vvEGAPackedMode,
  &vvEGAVertLineCmp,
};

#pragma  END_SWAP_DATA                                          /*          */
