/*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 */
#include <os2.h>
#include "svgadefs.h"                   /* SVGA definiton */            //J-TS0129
#undef SCREENDD_NAME                    /* To suspend the warning */    //J-TS0129

#include "vdhctl.h"                     /* Conditional compilation control */
#include "vdh.h"                        /* Type definitions             */

BOOL   PASCAL near memoryPresent(int);
UCHAR  PASCAL near VGAadapter(void);

extern USHORT hScreenDD;             /* Handle to screen device driver ( for DosDevIOCtl ) */

extern VIDEOHARDWARE VideoHardware;     /* installed video hardware */
#ifdef  J_INSTALL                                                       //J-TS00V
extern VIDEOHARDWAREJ VideoHardwareJ;   /* installed video hardware */  //J-TS00V
#endif  //J_INSTALL                                                     //J-TS00V

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

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/* 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:                                                */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT near getVideoType(void)
{
      UCHAR           videoType;       /* possible VGA video type */

      EGABIOSINFO     EGAInfo;         /* EGA information from 40:87 & 88 */
      UCHAR           videoSW;         /* EGA hardware switch settings */

      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? */

            VideoHardware.fVideoType |= MPA_BIT;      /* mark MPA is present */
         }

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

            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 */

                  /* 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 */

                  /* 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:

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

                  VideoHardware.fVideoType ^= MPA_BIT | EGM_BIT;
                  break;
               }  /* end of switch ( videoSW ) */

            } /* end of query EGA infor */

         } else if (videoType & VGA_DEVICE) {         /* VGA present? *///@T74

            if (!(videoIoctl(&videoType, NULL,        /* Get monitor type */
                             OEMHLP_FUNCTION_VIDEO))) {                 //@T74

               VideoHardware.memory  = 256L * 1024L;  /* Default to 256K */
               VideoHardware.popupMode  = ModeIndex_ATLASCO80VGA;   //J-TS00

               switch ( videoType ) {

               case VGA_COLOR:

                  VideoHardware.display     = Color8512_8513;
                  VideoHardware.fVideoType ^= CGA_BIT | VGC_BIT;        //@T41
                  break;

               case VGA_NODISPLAY:                                //MS28 - BEGIN
               case VGA_MONO:

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

                     VideoHardware.display     = Mono8503;
                     VideoHardware.fVideoType ^= MPA_BIT | VGM_BIT;     //@T41

                  } else {                                              //@T41

                     VideoHardware.display     = Color8512_8513;        //@T44
                     VideoHardware.popupMode   = ModeIndex_VGA3p;       //@T41
                     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? */   //@T71
                     if (VideoHardware.display == Color8512_8513) {     //J-TS00
                        VideoHardware.display  = ColorLCD;              //J-TS00
                     } else {                                           //J-TS00
                        VideoHardware.display  = PlasmaDisplay;         //J-TS00
                        VideoHardware.fVideoType |= VGP_BIT;
                     }                                                  //J-TS00
                  } /* 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$ */

      DetectOEM();                                                      //MS27

      return (VideoHardware.fVideoType);
}

#ifdef  J_INSTALL                                                       //J-TS00V
USHORT near getVideoTypeJ(void)                                         //J-TS00V
{                                                                       //J-TS00V
USHORT rc;                                                              //J-TS00V
                                                                        //J-TS00V
    register USHORT i, *pWord;                                          //J-TS00V
    struct ABIOS_Request_Block ReqBlk;                                  //J-TS00V
                                                                        //J-TS00V
    rc = CheckID();    /* Check DBCS Adapter Exist */                   //J-TS00V
    if (!rc) {                                                          //J-TS00V
    // Preset display type                                              //J-TS00V
        VideoHardwareJ.Display = 0xffff;                                //J-TS00V
                                                                        //J-TS00V
    // Get Hardware Configuration Data                                  //J-TS00V
        VideoHardwareJ.Configuration = GetHWConf();                     //J-TS00V
                                                                        //J-TS00V
    // Get Monitor ID                                                   //J-TS00V
        VideoHardwareJ.MonitorID = (UCHAR)(VideoHardwareJ.Configuration >> 8); //J-TS00V
        VideoHardwareJ.MonitorID &= 0x07;                               //J-TS00V
        if (VideoHardwareJ.Configuration & Mon_ID3)                     //J-TS00V
            VideoHardwareJ.MonitorID |= 0x08;                           //J-TS00V
                                                                        //J-TS00V
    // Get Color Information                                            //J-TS00V
        VideoHardwareJ.ColorDisp = FALSE;                               //J-TS00V
                                                                        //J-TS00V
        if (VideoHardwareJ.MonitorID == 0x0F) { // Monitor Not Attached //J-TS00V
                                /* see if a plasma display is present *///J-TS00V
            pWord=(USHORT *)&ReqBlk;                                    //J-TS00V
            for (i=0; i < (sizeof(ReqBlk)/2); i++) {                    //J-TS00V
                *pWord++=0;             /* Clear it */                  //J-TS00V
            }                                                           //J-TS00V
            ReqBlk.ABIOS_RB_Len = sizeof(ReqBlk);                       //J-TS00V
            ReqBlk.ABIOS_Func   = 3;    /* Read Device Parameters */    //J-TS00V
            if (!DosDevIOCtl((PVOID)NULL, (PVOID)&ReqBlk,               //J-TS00V
                             0x74, 0x3, (HFILE)hScreenDD)) {            //J-TS00V
                if (ReqBlk.ABIOS_MonitorType & 2) {                     //J-TS00V
                    VideoHardwareJ.Display = PlasmaDisplay;             //J-TS00V
                }                                                       //J-TS00V
            }                                                           //J-TS00V
        } else                                                          //J-TS00V
            if (VideoHardwareJ.Configuration & Mon_ID1) {   // Color ?  //J-TS00V
                VideoHardwareJ.ColorDisp = TRUE;                        //J-TS00V
            }                                                           //J-TS00V
                                                                        //J-TS00V
    // Get Memory Size                                                  //J-TS00V
        switch ( VideoHardwareJ.Configuration & 0x0007 ) {              //J-TS00V
        case Page_One:                                                  //J-TS00V
            VideoHardwareJ.Memory = 0x80000L;                           //J-TS00V
            break;                                                      //J-TS00V
        case Page_Two:                                                  //J-TS00V
            VideoHardwareJ.Memory = 0x100000L;                          //J-TS00V
            break;                                                      //J-TS00V
        case Page_Four:                                                 //J-TS00V
            VideoHardwareJ.Memory = 0x200000L;                          //J-TS00V
            break;                                                      //J-TS00V
        default:                                                        //J-TS00V
            VideoHardwareJ.Memory = 0x4000L;                            //J-TS00V
        }                                                               //J-TS00V
                                                                        //J-TS00V
    // set display type                                                 //J-TS00V
        if (VideoHardwareJ.Display == 0xFFFF) {     // Not Set Yet      //J-TS00V
            if (VideoHardwareJ.MonitorID == 0x0F)   // No Monitor or    //J-TS00V
                VideoHardwareJ.Display = NoDisplay; // VGA Display      //J-TS00V
            else                                                        //J-TS00V
                VideoHardwareJ.Display = VideoHardwareJ.ColorDisp ?     //J-TS00V
                                         Color8512_8513 : Mono8503;     //J-TS00V
        }                                                               //J-TS00V
                                                                        //J-TS00V
    }                                                                   //J-TS00V
                                                                        //J-TS00V
    return rc;                                                          //J-TS00V
}                                                                       //J-TS00V
#endif  //J_INSTALL                                                     //J-TS00V

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/* 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:                                                */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
   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;

   }

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/* SUBROUTINE NAME: VGAadapter                                          */
/*                                                                      */
/* DESCRIPTIVE NAME: return VGA or UNKNOWN adapter                      */
/*                                                                      */
/* FUNCTION:  The OS/2 Loader (OS2LDR) calls the BIOS INT 10h           */
/*            function 1Ah to see if VGA is present.                    */
/*                                                                      */
/*  ENTRY POINT: VGAadapter                                             */
/*    LINKAGE:   CALL FAR                                               */
/*                                                                      */
/*  INPUT: None                                                         */
/*                                                                      */
/*  EXIT:                                                               */
/*        -1 - unknown adapter present                                  */
/*        VGA_COLOR, VGA_MONO, VGA_NODISPLAY                            */
/*                                                                      */
/*  EFFECTS: NONE                                                       */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*                                                                      */
/*    ROUTINES: DosOpen, DosDevIOCtl, DosClose                          */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
   UCHAR PASCAL near VGAadapter(void)
   {
      UCHAR displayCode;                /* display code returned by OEMHLP$ */

      if (videoIoctl(&displayCode, NULL, OEMHLP_FUNCTION_VIDEO) ||
         (displayCode != VGA_COLOR && displayCode != VGA_MONO && displayCode != VGA_NODISPLAY)) {
         displayCode = (UCHAR)-1;       /* cannot determine type */
      }
      return displayCode;
   }

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/* SUBROUTINE NAME: memoryPresent                                       */
/*                                                                      */
/* DESCRIPTIVE NAME: return TRUE if specified memory is present         */
/*                                                                      */
/* FUNCTION:  Convert 32bit address from addressID to selector:offset.  */
/*            If successful, access memory to see if it is present.     */
/*                                                                      */
/*  ENTRY POINT: memoryPresent                                          */
/*    LINKAGE:   CALL near pascal                                       */
/*                                                                      */
/*  INPUT: addressID - ID 32bit physical address to validate            */
/*      MEM_A000, MEM_B800 or MEM_B000 proper accepted values           */
/*                      - other values are treated as MEM_B8000         */
/*  EXIT:                                                               */
/*      TRUE - named memory is present                                  */
/*                                                                      */
/*  EFFECTS: NONE                                                       */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*                                                                      */
/*    ROUTINES: PhysToUVirt, FreePhysToUVirt                            */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
BOOL PASCAL near memoryPresent(addressID)                   //B716827 Begin
int             addressID;
{
BOOL            fGoodMemory = FALSE;    // Assume no memory at location
FarAddress      PhysAddress;            // Video memory physical address
USHORT          *pVideoMemory1;         // Test address #1
USHORT          *pVideoMemory2;         // Test address #2
USHORT          originalValue1;         // Original value found at address #1
USHORT          originalValue2;         // Original value found at address #2
USHORT          testvalue1;             // Test value for address #1
USHORT          testvalue2;             // Test value for address #2

   PhysAddress.part.Selector = 0x0B;            // Assume B0000
   PhysAddress.part.Offset = 0x0000;

   if (addressID == MEM_B800) {
        PhysAddress.part.Offset = 0x8000;       // B8000
   } else if (addressID == MEM_A000) {
        PhysAddress.part.Selector = 0x0A;       // A0000
   }

   // Get selector to the first two paragraphs of video memory.
   if (!PhysToUVirt( PhysAddress, &PhysAddress, 32)) {
/*----------------------------------------------------------------------*/
/* Check for memory by writing test bit patterns into two video memory  */
/* addresses that are a paragraph (16 bytes) apart, then read them back */
/* to see if they match.  The paragraph separation forces each test to  */
/* use the same bus lines, thus preventing a false match that may occur */
/* when no memory is actually present and the "floating" value on the   */
/* bus from the previous write does not decay before reading it back.   */
/* For the same reason, test bit patterns and their complements should  */
/* all be distinct from one another.                                    */
/*----------------------------------------------------------------------*/

        pVideoMemory1 = (USHORT *)PhysAddress.FullAddress;
        pVideoMemory2 = pVideoMemory1 + 8;      // (8 words * 2) = paragraph
        testvalue1 = 0x005A;
        testvalue2 = 0x003C;

        // If test value matches original value found at address #1,
        // negate it.
        if ((originalValue1 = *pVideoMemory1) == testvalue1) {
                testvalue1 = 0x00A5;
        }
        *pVideoMemory1 = testvalue1;            // write out test value #1

        // If test value matches original value found at address #2,
        // negate it.
        if ((originalValue2 = *pVideoMemory2) == testvalue2) {
                testvalue2 = 0x00C3;
        }
        *pVideoMemory2 = testvalue2;            // write out test value #2

        // Check to see if test values were actually stored in memory.
        if (fGoodMemory = (( *pVideoMemory1 == testvalue1 )
                        && ( *pVideoMemory2 == testvalue2 ))) {
                // Memory present -- restore original values.
                *pVideoMemory1 = originalValue1;
                *pVideoMemory2 = originalValue2;
        }
        FreePhysToUVirt(PhysAddress.part.Selector);     // Deallocate selector
   }
   return fGoodMemory;
}                                                           //B716827 End

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/* 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:                                                */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
   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;
   }

/************************************************************************/
/*                                                                      */
   void DetectOEM(void)
/*                                                                      */
/* 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                                                    */
/*                                                                      */
/* Returns:     None                                                    */
/*                                                                      */
/************************************************************************/
{
REGADDRESS      RegAddress;
REGDATA         RegData;
UCHAR           byt, sbyt;
USHORT          i, j;
UCHAR           *pchar;
USHORT          *pword;
FarAddress      PhysAddress;

extern VIDEOMODE        Modes[];

if (VideoHardware.fVideoType & VGA_BITS) {

// Check C000, C800, E000, E800 for OEM video ROM.

   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;


        }
        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;

                else {
                        byt = ReadCMOS(CMOS_SYS_ID);


                        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;
                                }
                        }
                }
        }
   }
}
}

// @drw Add SVGA detection

/***    GetSVGAConfig()
 *
 *      On Entry: Nothing
 *
 *      On Exit:  TRUE  - SVGA Hardware present
 *                FALSE - No SVGA Hardware.
 *
 *      Note: SVGA support in OEMHLP$ is returned by function 8.
 *
 */

USHORT PASCAL NEAR GetSVGAConfig(VOID)
{
//J-TS0129        USHORT          rc = FALSE;
//J-TS0129        struct _OEMSVGAINFO {
//J-TS0129            USHORT      AdapterType;
//J-TS0129            USHORT      ChipType;
//J-TS0129            ULONG       Memory;
//J-TS0129        } SVGAHardware;
//J-TS0129
//J-TS0129        if ( !videoIoctl((UCHAR *)&SVGAHardware, NULL, 8) ) {
//J-TS0129
//J-TS0129            rc = SVGAHardware.AdapterType;      // If we have SVGA installed
//J-TS0129                                                // return adapter type.
//J-TS0129
//J-TS0129        }
//J-TS0129          return(rc);

    USHORT      rc = FALSE;                                             //J-TS0129
    OEMSVGAINFO SVGAHardware;           // installed SVGA hardware      //J-TS0129
                                                                        //J-TS0129
    if (!DosDevIOCtl(&SVGAHardware, NULL,                               //J-TS0129
                     SVGA_ID, SCREENDD_CATEGORY, (HFILE)hScreenDD)) {   //J-TS0129
        rc = SVGAHardware.AdapterType;  // If we have SVGA installed    //J-TS0129
                                        // return adapter type.         //J-TS0129
    }                                                                   //J-TS0129
    return(rc);                                                         //J-TS0129
}
