/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Microsoft Corporation, 1989                                 */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/*****************************************************************************
 *
 * SOURCE FILE NAME = vdhxconf.c
 *
 * DESCRIPTIVE NAME = video adapter detection routines
 *
 *
 * VERSION = V2.0
 *
 * DATE
 *
 * DESCRIPTION    getVideoType, videoIoctl
 *
 * FUNCTIONS
 *
 * NOTES
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES  DosOpen,  DosDevConfig, DosDevIoctl,
 *                      PhysToUVirt, FreePhysToUvirt
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define  INCL_BASE                     /* ALL of OS/2 Base                  */
#define  INCL_DOSDEVICES               /* Device specific, ring 2 support   */
#define  INCL_OS2STD                   /* Needed for NULL definition in     */
                                       /* OS2STD.H                          */
#include <os2.h>
#include "vdhctl.h"                    /* Conditional compilation control   */
#include "vdh.h"                       /* Type definitions                  */

#if      !(VDH8514A)                   /* @MS00                             */
extern USHORT *hScreenDD;              /* SCREEM$ handle for DosDevIOCtl    */

  #if      VDHEGA                      /* @S40f,MS00                        */
extern MEMORYMAPS MemoryMaps[];        /* See VDHDATA.H for detail     @S40F*/
 #endif                                /* VDHEGA                            */
                                       /* @S40F,MS00                        */
#endif                                 /* !(VDH8514A)                       */
extern VIDEOHARDWARE VideoHardware;    /* Installed video hardware          */
                                       /* structure                         */

#if      VDHINIT                       /*                               @ISO*/
extern DMQSDATA *pDMQSdata;            /*                               @ISO*/
extern USHORT machinetype;             /* used by QueryXGA              @RAD*/
BIOSINFO biosinfo;                     /* to read in BIOS info          @RAD*/
#endif                                 /*                               @ISO*/

extern USHORT OEMFlags;                /* OEM specific features             */
void DetectOEM(void);                  /* OEM hardware detection            */

#ifdef   VDHVGA                        /* LCD                               */
extern USHORT SVGAPresent;             /* LCD                               */
#endif                                 /* LCD                               */

/*****************************************************************************
 *
 * SUBROUTINE NAME: getVideoType
 *
 * DESCRIPTIVE NAME: return the video hardware configuration
 *
 * FUNCTION: Determine adapters and monitors installed on target machine
 *  this function is called from both IDH and BVHs each of which use
 *  hardware configuration in different ways.  Thus, the video hardware
 *  configuration is returned differently when called from a BVH than
 *  when its called from the IDH.
 *
 *  IDHs only use the values filled in the
 *  videohardware data structure so no globals are filled for them
 *
 *  ENTRY POINT: getVideoType
 *    LINKAGE:   CALL FAR
 *
 *  INPUT: None
 *
 *  EXIT: return:  0 if video cannot be determined
 *
 * The global structure VideoHardware has fVideoType filled with:
 *
 *    MPA_BIT           1       bit 0, MPA adapter with MONO monitor
 *    CGA_BIT           2       bit 1, CGA adapter with COLOR monitor
 *    EGM_BIT           4       bit 2, EGA adapter with MONO monitor
 *    EGC_BIT           8       bit 3, EGA adapter with COLOR monitor
 *    EGA_BIT           0x10    bit 4, EGA adapter w/ ENH COLOR monitor
 *    VGP_BIT           0x20    bit 5, VGA plasma display
 *    VGM_BIT           0x40    bit 6, VGA adapter with MONO monitor
 *    VGC_BIT           0x80    bit 7, VGA adapter with COLOR monitor
 *    A8514M_BIT        0x100   bit 8, 8514A with 8507 monitor
 *    A8514C_BIT        0x200   bit 9, 8514A with 8512/3 monitor
 *    A8514A_BIT        0x400   bit 10, 8514A with 8514 monitor
 *    A8514_15_BIT      0x800   bit 11, 8514A with 8515 monitor
 *    A8514_03_BIT      0x1000  bit 12, 8514A with 8503 monitor
 *    NODISPLAY_BIT     0x2000  bit 13, no display present on VGA system
 *
 *    all bits off means adapter type could not be determined
 *
 * The filled memory gets:
 *     bits 0 and 1 reflect memory configuation for EGA or 8514A
 *          bit  0 1   - means
 *               ---------------
 *               0 0    - minimum memory, EGA = 64K, 8514A = .5M
 *               0 1    - EGA = 128K
 *               1 0    - EGA = 192K
 *               1 1    - maximum memory, EGA = 256K, 8514A = 1M
 *   EGA64K_BIT     0x0000
 *   EGA128K_BIT    0x0001
 *   EGA192K_BIT    0x0002
 *   EGA256K_BITS   0x0003
 *   A85141MEG_BITS 0x0003
 *
 *  EFFECTS: NONE
 *
 *  INTERNAL REFERENCES:
 *
 *    ROUTINES: videoIoctl
 *
 *  EXTERNAL REFERENCES:
 *
 ****************************************************************************/

USHORT near getVideoType(void)

{

#if      VDH8514A      || VDHINIT      /* @T72,MS00                         */

  union
  {                                    /* used to interpret 8514A           */
                                       /* information                       */
    USHORT Flags;
    struct
    {
      UCHAR Display;
      UCHAR Memory;
    }
    part;
  }
  A8514;

#endif                                 /* VDH8514A || VDHINIT               */
                                       /* @T72,MS00                         */

#if      !(VDH8514A)                   /* MS00                              */
  UCHAR videoType;                     /* possible VGA video type           */
  EGABIOSINFO EGAInfo;                 /* EGA information from 40:87 & 88   */
  UCHAR videoSW;                       /* EGA hardware switch settings      */

  #if      VDHEGA                      /* @S40f,MS00                        */
MEMORYMAPS far *MemMapPtr;             /* Pointer to MemoryMaps[]           */
 #endif                                /* VDHEGA                            */
                                       /* @S40f,MS00                        */

  VideoHardware.fVideoType = VDHERROR_NO_ADAPTER;/* assume no adapter       */

  /*
  ** Use the adapter information obtained from OEMHLP$ to determine
  ** the default video memory and display configurations
  */

  if (!videoIoctl(&videoType, NULL, OEMHLP_FUNCTION_ADAPTER))
  {                                    /* @T74                              */

    if (videoType&MPA_DEVICE)
    {                                  /* B0000 accessible?                 */

  #if      VDHMPA                      /* MS00                              */
      VideoHardware.memory = 4L*1024L; /* Default to 4K                     */
      VideoHardware.display = Mono5151;/* Default to MONO                   */
      VideoHardware.popupMode = 0;
 #endif                                /* VDHMPA                            */
                                       /* @MS00                             */
      VideoHardware.fVideoType |= MPA_BIT;/* mark MPA is present            */
    }

    if (videoType&CGA_DEVICE)
    {                                  /* B8000 accessible?                 */

  #if      VDHCGA                      /* MS00                              */
      VideoHardware.memory = 16L*1024L;/* Default to 16K                    */
      VideoHardware.display = Color5153;/* Default to Color                 */
      VideoHardware.popupMode = ModeIndex_CGA3;/* hi-res 80x25 text         */
 #endif                                /* VDHCGA                            */
                                       /* MS00                              */
      VideoHardware.fVideoType |= CGA_BIT;/* mark CGA is present            */
    }

    if (videoType&EGA_DEVICE)
    {                                  /* EGA present?                      */

      if (!getEGAinfo(&EGAInfo))
      {                                /* determine/record EGA info         */

        /*
        ** Form a 0 base value for the EGA switch settings
        ** by removing the primary/secondary information
        ** obtained from the BIOS data area
        */

        if ((videoSW = EGAInfo.BIOS_info3&0x0F) >= 6)
          videoSW -= 6;

               /* off = 1, sw1 = bit 0                                      */

        switch (videoSW)
        {
          case 0x0 :                   /* EGA in CGA 40x25 mode             */
          case 0x1 :                   /* EGA in CGA 80x25 mode             */
          case 0x2 :                   /* EGA in Enhanced display emulation */
                                       /* mode                              */

  #if      VDHEGA                      /* MS00                              */
            VideoHardware.display = Color5153;
            VideoHardware.popupMode = ModeIndex_EGC3;
 #endif                                /* VDHEGA                            */
                                       /* MS00                              */

            /*
            ** turn off CGA bit set by OEMHLP$ and turn on EGC bit
            */

            VideoHardware.fVideoType ^= CGA_BIT|EGC_BIT;
            break;

          case 0x3 :                   /* EGA in enhanced color modes       */

  #if      VDHEGA                      /* MS00                              */
               VideoHardware.display = EnColor5154;
            VideoHardware.popupMode = ModeIndex_EGA3;
  #endif                               /* VDHEGA                            */

            /*
            ** turn off CGA bit set by OEMHLP$ and turn on EGA bit
            */

            VideoHardware.fVideoType ^= CGA_BIT|EGA_BIT;
            break;

          case 0x4 :                   /* monochrome modes                  */
          case 0x5 :

  #if      VDHEGA                      /* MS00                              */
            VideoHardware.display = Mono5151;
            VideoHardware.popupMode = ModeIndex_EGM7;
  #endif                               /* VDHEGA                            */

                  /* turn off MPA bit set by OEMHLP$ and turn on EGM bit    */

            VideoHardware.fVideoType ^= MPA_BIT|EGM_BIT;
            break;

        }                              /* end of switch ( videoSW )          */

  #if      VDHEGA        || VDHINIT    /* @B18,@C31,MS00                     */

    #if    VDHEGA                    /* @S40f,MS00                           */
           MemMapPtr = (MEMORYMAPS far *)&MemoryMaps[MemMap_ModeD]; /* @S40f */
    #endif                             /* VDHEGA                             */
                                      /* @S40f,MS00                          */

        /*
        ** Since ROM BIOS already examines the card, use the memory
        ** size values found
        **
        ** BIOS_info BYTE:
        **      B7: High bit of mode set, clear/not clear regen
        **      B6: Memory  B6 B5 = 0 0 -  64k    0 1 - 128k
        **      B5: Memory          1 0 - 192k    1 1 - 256k
        **      B4: Reserved
        **      B3: 1 - EGA active monitor, 0 - not active
        **      B2: 1 - wait for display enable
        **      B1: 1 - EGA has monochrome attatched
        **      B0: 0 - set C_TYPE emulate active
        */

        switch (EGAInfo.BIOS_info&0x60)

        {                              /* Use memory size bits              */
          case 0x00 :
            VideoHardware.memory = 64L*1024L;/* 64K VRAM                    */
            break;

          case 0x20 :
            VideoHardware.memory = 128L*1024L;/* 128K VRAM                  */

    #if      VDHEGA                    /* @S40f,MS00                        */
            MemMapPtr->PageReal += 0x04000; /* @S40f                        */
            MemMapPtr->TotalReal += 0x10000L; /* @S40f                      */
            MemMapPtr = (MEMORYMAPS far *)&MemoryMaps[MemMap_ModeE]; /* @S40*/
            MemMapPtr->PageReal += 0x04000; /* @S40f                        */
            MemMapPtr->TotalReal += 0x10000L; /* @S40f                      */
            MemMapPtr = (MEMORYMAPS far *)&MemoryMaps[MemMap_ModeF];/* @S40f*/
            MemMapPtr->PageReal += 0x8000; /* @S40f                         */
            MemMapPtr->TotalReal += 0x10000L; /* @S40f                      */
            MemMapPtr = (MEMORYMAPS far *)&MemoryMaps[MemMap_Mode10];/*@S40f*/
            MemMapPtr->TotalSize += 56000L; /* @S40f                        */
            MemMapPtr->TotalReal += 0xE000L; /* @S40f                       */
            MemMapPtr->BitPlanes += 10; /* @S40f                            */
   #endif                              /* VDHEGA                            */
                                       /* @S40f,MS00                        */
            break;

          case 0x40 :
            VideoHardware.memory = 192L*1024L;/* 192K VRAM                  */

    #if      VDHEGA                    /* @S40f,MS00                        */
            MemMapPtr->PageReal += 0x08000; /* @S40f                        */
            MemMapPtr->TotalReal += 0x20000L; /* @S40f                      */
            MemMapPtr = (MEMORYMAPS far *)&MemoryMaps[MemMap_ModeE];/*@S40f */
            MemMapPtr->PageReal += 0x08000; /* @S40f                        */
            MemMapPtr->TotalReal += 0x20000L; /* @S40f                      */
            MemMapPtr = (MEMORYMAPS far *)&MemoryMaps[MemMap_ModeF];/* @S40f*/
            MemMapPtr->PageReal += 0x8000; /* @S40f                         */
            MemMapPtr->TotalReal += 0x10000L; /* @S40f                      */
            MemMapPtr = (MEMORYMAPS far *)&MemoryMaps[MemMap_Mode10];  /*40f*/
            MemMapPtr->PageReal += 0x4000; /* @S40f                         */
            MemMapPtr->TotalSize += 56000L; /* @S40f                        */
            MemMapPtr->TotalReal += 0x1E000L; /* @S40f                      */
            MemMapPtr->BitPlanes += 10; /* @S40f                            */
   #endif                              /* VDHEGA                            */
                                        /* @S40f,MS00                       */
            break;

          case 0x60 :
            VideoHardware.memory = 256L*1024L;/* 256K VRAM                  */

    #if      VDHEGA                    /* @S40f,MS00                        */
            MemMapPtr->PageReal += 0x0C000; /* @S40f                        */
            MemMapPtr->TotalReal += 0x30000L; /* @S40f                      */
            MemMapPtr = (MEMORYMAPS far *)&MemoryMaps[MemMap_ModeE];/*@S40f */
            MemMapPtr->PageReal += 0x0C000; /* @S40f                        */
            MemMapPtr->TotalReal += 0x30000L; /* @S40f                      */
            MemMapPtr = (MEMORYMAPS far *)&MemoryMaps[MemMap_ModeF];/*@S40f */
            MemMapPtr->PageReal += 0x8000; /* @S40f                         */
            MemMapPtr->TotalReal += 0x10000L; /* @S40f                      */
            MemMapPtr = (MEMORYMAPS far *)&MemoryMaps[MemMap_Mode10];/*@S40f*/
            MemMapPtr->PageReal += 0x8000; /* @S40f                         */
            MemMapPtr->TotalSize += 56000L; /* @S40f                        */
            MemMapPtr->TotalReal += 0x2E000L; /* @S40f                      */
            MemMapPtr->BitPlanes += 10; /* @S40f                            */
   #endif                               /* VDHEGA                           */
                                        /* @S40f,MS00                       */
            break;

        }                              /* end of switch ( EGAInfo.BIOS_info */
                                       /* )                                 */
 #endif                                /* VDHEGA || VDHINIT                 */
                                       /* @B18,@C31,MS00                    */
      }                                /* end of query EGA infor            */
    }

    else

      if (videoType&VGA_DEVICE)
   {                                   /* VGA present?                      */

        if (!(videoIoctl(&videoType, NULL, /* Get monitor type              */
           OEMHLP_FUNCTION_VIDEO)))
        {                              /* @T74                              */
          VideoHardware.memory = 256L*1024L;/* Default to 256K              */

          switch (videoType)
          {
            case  VGA_NODISPLAY :      /* MS28 - BEGIN                      */

  #ifdef   BUGBUG                      /* work around INT 10h               */
                                       /* incompatibility                   */

    #if      VDHVGA
              VideoHardware.display = NoDisplay;
              VideoHardware.popupMode = ModeIndex_VGA3p;
    #endif                             /* VDHVGA                            */

              VideoHardware.fVideoType = NODISPLAY_BIT; /* @T41             */
              break;

 #endif                                 /* BUGBUG                           */
                                        /* MS28 - END                       */
            case  VGA_COLOR :

  #if      VDHVGA                      /* MS00                              */
              VideoHardware.display = Color8512_8513;
              VideoHardware.popupMode = ModeIndex_VGA3p;
 #endif                                 /* VDHVGA                           */
                                        /* MS00                             */
              VideoHardware.fVideoType ^= CGA_BIT|VGC_BIT; /* @T41          */
              break;

            case  VGA_MONO :

              if (VideoHardware.fVideoType&MPA_BIT)
              {                        /* @T41                              */

  #if      VDHVGA                      /* MS00                              */
                VideoHardware.display = Mono8503;
                VideoHardware.popupMode = ModeIndex_VGM7p;
 #endif                                 /* VDHVGA                           */
                                        /* MS00                             */
                VideoHardware.fVideoType ^= MPA_BIT|VGM_BIT; /* @T41        */
              }

              else
              {                        /* @T41                              */

  #if      VDHVGA                      /* @T41,MS00                         */
                VideoHardware.display = Color8512_8513; /* @T44             */
                VideoHardware.popupMode = ModeIndex_VGA3p; /* @T41          */

 #endif                                 /* VDHVGA                           */
                                        /* @T41,MS00                        */
                VideoHardware.fVideoType ^= CGA_BIT|VGC_BIT; /* @T44        */
              }                        /* @T41                              */
              break;

          }                            /* end of switch ( videoType )       */

          /*
          ** see if a plasma display is present
          */

          if (!videoIoctl(&videoType, NULL, OEMHLP_FUNCTION_MISC))
          {                            /* @T71                              */

            if (videoType&0x40)
         {                             /* P70 video present?                */

  #if      VDHVGA                      /* MS00                              */
              VideoHardware.display = PlasmaDisplay;

              if (VideoHardware.fVideoType&VGM_BIT)
              {                        /* @T71                              */
                VideoHardware.popupMode = ModeIndex_VGP7p;
              }

              else
              {                        /* @T71                              */
                VideoHardware.popupMode = ModeIndex_VGC7p; /* @T71          */
              }                        /* @T71                              */
 #endif                                /* VDHVGA                            */
                                       /* MS00                              */
              VideoHardware.fVideoType |= VGP_BIT;
            }                          /* end of P70 present check          */
          }                            /* end of P70 query through OEMHLP$  */
        }                              /* end of VGA monitor query through  */
                                       /* OEMHLP$                           */
      }                                /* end of EGA/VGA present check      */
  }                                    /* end of video adapter query        */
                                       /* through OEMHLP$                   */
#endif                                 /* !(VDH8514A)                       */
                                       /* MS00                              */

#if      VDHINIT                       /* @T72,MS00                         */
    if (!videoIoctl(&biosinfo, NULL, OEMHLP_BIOSINFO))      /*          @RAD*/
       machinetype = biosinfo.ABIOSPresent;                 /*          @RAD*/

    if ((A8514.Flags = QueryXGA()) != VDHERROR_NO_ADAPTER)
    {                                  /* @T72                              */

      if ((A8514.part.Display) || (A8514.part.Memory&0x80) &&  /* B716255   */
         (VideoHardware.display == PlasmaDisplay))
      {                                /* B716255                           */
        VideoHardware.fVideoType |= XGA_BIT; /* @T72                        */

        if (!videoIoctl(&pDMQSdata, NULL, OEMHLP_DMQS_INFO))/*          @ISO*/

          if (pDMQSdata)
          {                            /*                               @ISO*/

            switch (pDMQSdata->monitor_id)
            {                          /*                               @ISO*/
                                       /*                               @ISO*/
              case  COMP_ID_9515 :     /*                               @ISO*/
                A8514.part.Display = color9515;/*                       @ISO*/
                break;                 /*                               @ISO*/
                                       /*                               @ISO*/
              case  COMP_ID_9517 :     /*                               @ISO*/
                A8514.part.Display = color9517;/*                       @ISO*/
                break;                 /*                               @ISO*/
                                       /*                               @ISO*/
              case  COMP_ID_9518 :     /*                               @ISO*/
                A8514.part.Display = color9518;/*                       @ISO*/
                break;                 /*                               @ISO*/
            }                          /*                               @ISO*/
          }                            /*                               @ISO*/
      }                                /* B716255                           */
    }                                  /* @T72                              */
#endif                                 /* VDHINIT                           */
                                       /* @T72,MS00                         */

#if      VDH8514A      || VDHINIT      /* record possible 8514 information  */
                                       /* MS00                              */

if ((VideoHardware.fVideoType&XGA_BIT) || /* XGA present?                   */
     ((A8514.Flags = Query8514A()) != VDHERROR_NO_ADAPTER))
  {                                    /* @T72                              */
    VideoHardware.popupMode = 0;
    VideoHardware.display = (USHORT)A8514.part.Display;

    switch (A8514.part.Display)
    {
      case  Mono8503 :
        VideoHardware.fVideoType |= A8514_03_BIT;/* 8514/A with 8503        */
        break;

      case  Color8514 :
        VideoHardware.fVideoType |= A8514A_BIT;/* 8514/A with 8514          */
        break;

      case  Color8515 :
        VideoHardware.fVideoType |= A8514_15_BIT;/* 8514/A with 8515        */
        break;

      case  Mono8507_8604 :
        VideoHardware.fVideoType |= A8514M_BIT;/* 8514/A with 8507/8604     */
        break;

      case  Color8512_8513 :
        VideoHardware.fVideoType |= A8514C_BIT;/* 8514/A with 8512/13       */
        break;
    }                                  /* end of monitor attachment to      */
                                       /* 8514A/XGA device                  */

    if (A8514.part.Memory == MEM_1MB)
    {
      VideoHardware.memory = 1024L*1024L;
    }

    else
    {
      VideoHardware.memory = 512L*1024L;
    }
  }                                    /* end of XGA present check          */
#endif                                 /* VDH8514A || VDHINIT               */
                                       /* MS00                              */

#if      !(VDH8514A)                   /* B724243,MS27                      */
    DetectOEM();                       /* MS27                              */
#endif                                 /* !(VDH8514A)                       */
                                       /* MS27                              */

  return (VideoHardware.fVideoType);
}

#if      !(VDH8514A)                   /* MS00                              */

/*****************************************************************************
 *
 * SUBROUTINE NAME: getEGAInfo
 *
 * DESCRIPTIVE NAME: return EGA information from the BIOS at 40:86,87
 *
 * FUNCTION:  get access to 40: upon the first call and return the data
 *            found at bytes 86h and 87h.
 *
 *  ENTRY POINT: getEGAInfo
 *    LINKAGE:   CALL FAR
 *
 *  INPUT: address of egainfo structure
 *
 *  EXIT:  egainfo structure filled with necessary values
 *
 *  EFFECTS: NONE
 *
 *  INTERNAL REFERENCES:
 *
 *    ROUTINES: PhysToUVirt, FreePhysToVirt
 *
 *  EXTERNAL REFERENCES:
 *
 ****************************************************************************/

USHORT PASCAL near getEGAinfo(egainfo)

  EGABIOSINFO *egainfo;

{
  FarAddress PhysAddress;              /* becomes virtual address of 40:    */
  unsigned rc;                         /* return code                       */


  /*
  ** Obtain addressability to the BIOS data area
  */


  PhysAddress.part.Selector = 0x0000;
  PhysAddress.part.Offset = 0x0400;

  if (!(rc = PhysToUVirt(PhysAddress, &PhysAddress, sizeof(VIDEO_BIOS))))
  {                                    /* access to 40: successful, return  */
                                       /* the parts for EGA type            */
                                       /* determination                     */

    egainfo->BIOS_info = ((VIDEO_BIOS far *)PhysAddress.FullAddress)->
                                            BIOS_info;

    egainfo->BIOS_info3 = ((VIDEO_BIOS far *)PhysAddress.FullAddress)->
                                             BIOS_info3;
    FreePhysToUVirt(PhysAddress.part.Selector);

  }

  return  rc;
}

/*****************************************************************************
 *
 * SUBROUTINE NAME: videoIoctl
 *
 * DESCRIPTIVE NAME: perform requested IOCTL request
 *
 * FUNCTION:  Issue generic IOCTL, use strong error checking
 *
 *  ENTRY POINT: videoIoctl
 *    LINKAGE:   CALL NEAR
 *
 *  INPUT: data - data from IOCTL request
 *         parm - parameter to IOCTL request
 *         function - function requested
 *
 *  EXIT:  error code from DosOpen or DosDevIoctl
 *
 *  EFFECTS: determined by request
 *
 *  INTERNAL REFERENCES:
 *
 *    ROUTINES: DosOpen, DosDevIoctl
 *
 *  EXTERNAL REFERENCES:
 *
 ****************************************************************************/

int PASCAL near videoIoctl(data,parm,function)

  UCHAR *data,*parm;
  unsigned function;

{

  unsigned hOemhlp;                    /* handle of OEMHLP$ device driver   */
  unsigned OpenAction;                 /* action taken to open device       */
  unsigned rc;                         /* function return code              */


  if (!(rc = DosOpen(OEMHLPDD_NAME, (PHFILE)&hOemhlp, (PUSHORT)&OpenAction,
     NO_SIZE, NO_ATTRIBUTES, OPEN_IF_EXISTS, NO_INHERIT+DENY_NONE+READ_WRITE,
     RESERVED_LONG)))

  {
    rc = DosDevIOCtl(data,
                     parm,
                     function,
                     OEMHLP_CATEGORY,
                     (HFILE)hOemhlp);
    DosClose(hOemhlp);
  }

  return  rc;

}

#endif                                 /*        ! VDH8514A   @MS00         */

#if      !(VDH8514A)                   /* B724243 //MS27 - BEGIN            */

/***************************************************************************
 *
 * FUNCTION NAME = DetectOEM(void)
 *
 * DESCRIPTION   =
 *
 *     This routine detects OEM video hardware and features.
 *     Some or all of the following variables are (re)set to reflect the
 *     hardware detected:
 *          OEMFlags
 *          VideoHardware.display
 *          VideoHardware.popupMode
 *          VideoHardware.fVideoType
 *
 * INPUT         = NONE
 * OUTPUT        = NONE
 *
 * RETURN-NORMAL = NONE
 * RETURN-ERROR  = NONE
 *
 **************************************************************************/

void DetectOEM(void)

{

  REGADDRESS RegAddress;
  REGDATA RegData;
  UCHAR byt,sbyt;
  USHORT i,j;
  UCHAR *pchar;
  USHORT *pword;
  FarAddress PhysAddress;
  extern VIDEOMODE Modes[];

  #if      !(VDHINIT)                  /* B724243                           */

    #if      VDHVGA

  if (VideoHardware.fVideoType & VGA_BITS)
  {

    /*
    **  Check C000, C800, E000, E800 for OEM video RO
    */

    i = 0;
    j = 0;

    do
    {
      PhysAddress.part.Selector = (i < 2)?0x0C:0x0E;
      PhysAddress.part.Offset = (i&1)?0x8000:0x0000;

      if (!PhysToUVirt(PhysAddress, &PhysAddress, 0x0))
      {
        pword = (USHORT *)PhysAddress.FullAddress;
                /* Check for option ROM signature                           */

        if (*pword == 0xAA55)
        {
          pchar = (char *)pword;
          j = *(pword+1);              /* Get length/512                    */
          pchar += (j << 9)-0x16;      /* Calc Offset                       */
                        /* Scan for OEM ID                                  */
          j = 0;

          while ((j < 6) && (*(pchar+j) == "COMPAQ"[j]))
            j++;
        }

        FreePhysToUVirt(PhysAddress.part.Selector);
      }
      i++;
    }

    while ((i < 4) && (j != 6));

    /*
    ** If OEM video ROM present, detect and flag OEM VGA specific features.
    */

    if (j == 6)
    {
      RegAddress.DataPort = 0x03BA;    /* Input Status 1 Port               */

      if (VideoHardware.popupMode != ModeIndex_VGM7p)
          RegAddress.DataPort += ColorAdjustment;

      AccessRegister(&RegAddress, GET, &byt);

      if (byt & PARADISE_ID)
      {
        OEMFlags |= PARADISE_VGA;

        /*
        ** Paradise     fix:
        ** Search through mode table to find CRTCtlRegs_CMD with horizontal
        ** blanking start/end data and decrement them by one row.
        ** 0x2 -> start
        */

        for (j = 0; j < NUM_MODES; j++)
        {
          i = 0;

          while ((Modes[j].ModeRegs[i].Command !=
                  CRTCtlRegs_CMD) ||
                  (Modes[j] .ModeRegs[i].RegData.NumEntries < 0x0C))
             i++;
             Modes[j].ModeRegs[i].RegData.DataArea[0x03]--;
             Modes[j].ModeRegs[i].RegData.DataArea[0x02]--;
        }
      }

      else
      {
        RegAddress.AddressPort = GraphAddressPort;
        RegAddress.DataPort = GraphDataPort;
        RegAddress.Flags = NONE;
        RegData.NumEntries = 1;
        RegData.DataArea = &byt;
                /* Open access to extended VGA registers                    */

        RegData.FirstEntry = VGA_ENV_REG;
        byt = VGA_UNLOCK;
        AccessHardware(&RegAddress, BYTES, NONE, SET, &RegData);
                /* Read project/version byte                                */

        RegData.FirstEntry = VGA_VERSION_REG;
        AccessHardware(&RegAddress, BYTES, NONE, GET, &RegData);
        sbyt = byt;
                /* Close access to extended VGA registers                   */

        RegData.FirstEntry = VGA_ENV_REG;
        byt = VGA_LOCK;
        AccessHardware(&RegAddress, BYTES, NONE, SET, &RegData);

        if (sbyt == STARLIGHT132_ID)
          OEMFlags |= STARLIGHT_VGA;

        else

          if ((sbyt & PROJECT_MASK) == STARDUST_ID)
          {
            OEMFlags |= STARDUST_VGA;
            VideoHardware.memory = 512L*1024L;
          }

          else
          {
            byt = ReadCMOS(CMOS_SYS_ID);

            /*
            **  We need to add one more step to detecting the CRYSTAL VGA.
            **  Specifically, we need to check if the LTE 386s/20 is plugged into
            **  an expansion base and, if it is, check for a video card in the
            **  base.  If a video card is detected, DON'T report back a CRYSTAL
            **  VGA (the LTE internal VGA ASIC) because it is disabled whenever
            **  a video card is present in the expansion base.  Also, for LCD
            **  displays, use 640 pixel text modes for popups.
            */

            if ((byt == TRIUMPH_ID) || (byt == TARGA_ID))
            {
              OEMFlags |= PRISM_VGA;
              VideoHardware.popupMode = ModeIndex_VGP3p;
            }

            else

              if (byt == CALYPSO_ID)
              {
                /*
                ** Verify that CRYSTAL ASIC is active,
                ** instead of a card in the expansion
                ** base, by checking if the internal
                ** VGA is enabled (C67 bit 5 = 1).
                */
                RegAddress.DataPort = 0x0C67;
                AccessRegister(&RegAddress, GET, &byt);

                if (byt&0x20)
                {
                  OEMFlags |= CRYSTAL_VGA;
                  VideoHardware.popupMode = ModeIndex_VGP3p;
                }
              }
          }
      }
    }

    else

      if (VideoHardware.Reg_132 = QUERY132())
      {                                /* IBM VGA-E? //MS??                 */

        if (VideoHardware.display == PlasmaDisplay)
        {                              /* LCD                               */
          VideoHardware.Reg_132 = FALSE; /* LCD                             */
          SVGAPresent = FALSE;         /* LCD                               */
        }

        else
        {                              /* LCD                               */
          OEMFlags |= VGA_E;           /* 132 col. capable  @MS??           */
        }                              /* LCD                               */
      }
  }
    #endif                             /* VDHVGA                            */
  #endif                  /*(VDHINIT)   B724243                             */

  #if      (VDHCGA       || VDHINIT)   /* B724243                           */

  if (VideoHardware.fVideoType&CGA_BIT)

  {
    /*
    ** Check for OEM system ROM.
    */

    PhysAddress.part.Selector = 0xF;
    PhysAddress.part.Offset = 0xFFEA;

    j = 0;

    if (!PhysToUVirt(PhysAddress, &PhysAddress, 6))
    {
      pchar = (UCHAR *)PhysAddress.FullAddress;

      while ((j < 6) && (*(pchar+j) == "COMPAQ"[j]))
        j++;

      FreePhysToUVirt(PhysAddress.part.Selector);
    }

    /*
    ** If OEM system ROM present, detect and flag OEM CGA specific features.
    */
    if (j == 6)
    {
      RegAddress.DataPort = IDCEnvironReg;
      AccessRegister(&RegAddress, GET, &byt);

      if (byt == IDC_SIGNATURE)
      {
        RegAddress.DataPort = IDCMasterModeReg;
        AccessRegister(&RegAddress, GET, &byt);
                /* IDC in CGA (color) mode?                                 */

        if (!(byt & 0x07))
        {

    #if      !(VDHINIT)                /* B724243                           */
          OEMFlags |= IDC_CGA;
    #endif

          /*
          ** If internal plasma display enabled then check
          */

          /*
          ** display type thru the IDCDisplayType register
          */

          if (byt & 0x08)
          {                            /* B724243                           */
            RegAddress.DataPort = IDCDisplayType; /* B724243                */
            AccessRegister(&RegAddress, GET, &byt); /* B724243              */

            if (byt & 0x40)
            {                          /* B724243                           */
              VideoHardware.display = PlasmaDisplay; /* B724243             */
            }                          /* B724243                           */
          }                            /* B724243                           */

          /*
          ** Read current attribute setting from extended mode
          ** register.  (bits 5-7 = attribute).
          */

          RegAddress.DataPort = IDCExtendedModeReg;
          AccessRegister(&RegAddress, GET, &byt);

          /*
          ** If attribute is alternate character set, use
          ** half-intensity instead (preserve other bits).
          */

          if ((byt & 0xE0) == 0x60)
          {
            byt ^= 0xE0;
            AccessRegister(&RegAddress, SET, &byt);
          }
        }
      }

    #if      !(VDHINIT)                /* B724243                           */

      else
      {
        byt = ReadCMOS(CMOS_VCFG);

        if (byt & VDU_VCFG)
          OEMFlags |= VDU_CGA;

        if (byt & DSM_VCFG)
        {
          OEMFlags |= DSM_MONITOR;

          if (OEMFlags & VDU_CGA)
            VideoHardware.popupMode = ModeIndex_VDUDSM3;
        }
      }
    #endif        /*        !(VDHINIT)   B724243                            */
    }
  }
  #endif          /*      (VDHCGA || VDHINIT), B724243  */
}

/*
** @drw Add SVGA detection
*/

/***************************************************************************
 *
 * FUNCTION NAME = GetSVGAConfig()
 *
 * DESCRIPTION   = detects whether SVGA is present
 *                 Note: SVGA support in OEMHLP$ is returned by function 8.
 *
 * INPUT         = NONE
 * OUTPUT        = TRUE  - SVGA Hardware present
 *                 FALSE - No SVGA Hardware.
 *
 * RETURN-NORMAL = NONE
 * RETURN-ERROR  = NONE
 *
 **************************************************************************/

USHORT PASCAL NEAR GetSVGAConfig(VOID)

{
  USHORT rc = FALSE;
  struct _OEMSVGAINFO

  {
    USHORT AdapterType;
    USHORT ChipType;
    ULONG Memory;
  }

  SVGAHardware;


  if (!videoIoctl((UCHAR *)&SVGAHardware, NULL, 8))
  {
    rc = SVGAHardware.AdapterType;     /* If we have SVGA installed         */
                                       /* return adapter type.              */
  }

  return (rc);
}

/*
** @drw Add SVGA detection
*/

#endif  /* !(VDH8514A)                           @MS27 - END B724243        */
