home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_08_08 / 8n08115a < prev    next >
Text File  |  1990-07-18  |  15KB  |  313 lines

  1.  
  2. /*----------------------------------------------------------------------\
  3. |       Marcus W. Johnson 1990.                                         |
  4. |                                                                       |
  5. |       Code to identify video display adaptors and display devices     |
  6. |                                                                       |
  7. |       Adapted from:   Programmer's Guide to PC and PS/2 Video Systems |
  8. |                       Richard Wilton                                  |
  9. |                       Microsoft Press                                 |
  10. |                       Redmond, Washington                             |
  11. \----------------------------------------------------------------------*/
  12.  
  13. #include        <dos.h>
  14. #include        "video.h"
  15.  
  16. enum    boolean
  17.         {
  18.         NO,
  19.         YES
  20.         };
  21.  
  22. #define N_SYSTEMS       (2)
  23.  
  24. static struct video     Device[ N_SYSTEMS ];
  25.  
  26. /*----------------------------------------------------------------------\
  27. |       Detects whether or not a given I/O address is that of a CRT     |
  28. |       Controller; the Cursor Location Low register of the alleged     |
  29. |       CRTC is written with an arbitrary value (I used the one Wilton  |
  30. |       uses in his Find6845 procedure), we wait an arbitrary period of |
  31. |       time (I waited a millisecond), and we see if the value is still |
  32. |       there, then this is probably the CRTC.                          |
  33. \----------------------------------------------------------------------*/
  34.  
  35. static int      FindCRTC(int Port)
  36.         {
  37.         unsigned char   CursorLow;
  38.         unsigned char   NewCursorLow;
  39.  
  40.         outportb(Port++, 0x0F);
  41.         CursorLow = inportb(Port);
  42.         outportb(Port, 0x66);
  43.         delay(1);
  44.         NewCursorLow = inportb(Port);
  45.         outportb(Port, CursorLow);
  46.         return (NewCursorLow == 0x66);
  47.         }
  48.  
  49. /*----------------------------------------------------------------------\
  50. |       Places the specified adaptor and monitor data in the next       |
  51. |       unused element of the Device array.                             |
  52. \----------------------------------------------------------------------*/
  53.  
  54. static void     FoundDevice(enum adaptor AType, enum monitor MType)
  55.         {
  56.         if (Device[ 0 ].VideoAdaptor == UnknownAdaptor)
  57.                 {
  58.                 Device[ 0 ].VideoAdaptor = AType;
  59.                 Device[ 0 ].VideoMonitor = MType;
  60.                 }
  61.         else
  62.                 {
  63.                 Device[ 1 ].VideoAdaptor = AType;
  64.                 Device[ 1 ].VideoMonitor = MType;
  65.                 }
  66.         }
  67.  
  68. /*----------------------------------------------------------------------\
  69. |       Attempt to find a monochrome adaptor; attempts to detect a CRTC |
  70. |       at I/O address at 0x3B4.  If this is successful, we read the    |
  71. |       vertical sync bit, and wait a while to see a transition; if it  |
  72. |       occurs, it's a plain monochrome display adaptor, otherwise it's |
  73. |       a Hercules card of some sort.  What type is decided by bits 4-6 |
  74. |       of the CRTC port.                                               |
  75. \----------------------------------------------------------------------*/
  76.  
  77. static void     DetectMono(void)
  78.         {
  79.         if (FindCRTC(0x3B4))
  80.                 {
  81.                 auto unsigned char      VSync;
  82.                 auto unsigned int       k;
  83.                 auto enum boolean       FoundIt;
  84.  
  85.                 VSync = inportb(0x3BA) & 0x80;
  86.                 FoundIt = NO;
  87.                 for (k = 0; k < 0x8000; k++)
  88.                         {
  89.                         if (VSync != (inportb(0x3BA) & 0x80))
  90.                                 {
  91.                                 switch (inportb(0x3BA) & 0x70)
  92.                                         {
  93.                                         case    0x10:
  94.                                                 FoundDevice(HGCPlus, MDA);
  95.                                                 break;
  96.                                         case    0x50:
  97.                                                 FoundDevice(HerculesInColor,
  98.                                                         EGAColor);
  99.                                                 break;
  100.                                         default:
  101.                                                 FoundDevice(HGC, MDA);
  102.                                                 break;
  103.                                         }
  104.                                 FoundIt = YES;
  105.                                 break;
  106.                                 }
  107.                         }
  108.                 if (FoundIt == NO)
  109.                         FoundDevice(MDA, MDAMonochrome);
  110.                 }
  111.         }
  112.  
  113. /*----------------------------------------------------------------------\
  114. |       Attempt to find a CGA adaptor; if a CRTC is detected at I/O     |
  115. |       address 3D4, must be CGA...                                     |
  116. \----------------------------------------------------------------------*/
  117.  
  118. static void     DetectCGA(void)
  119.         {
  120.         if (FindCRTC(0x3D4))
  121.                 FoundDevice(CGA, CGAColor);
  122.         }
  123.  
  124. /*----------------------------------------------------------------------\
  125. |       Fills in the Device array and returns its address to the        |
  126. |       caller, who can then examine its contents.                      |
  127. \----------------------------------------------------------------------*/
  128.  
  129. struct video    *IdentifyVideo(void)
  130.         {
  131.         int             k;
  132.         union REGS      r;
  133.  
  134.         for (k = 0; k < N_SYSTEMS; k++)
  135.                 {
  136.                 Device[ k ].VideoAdaptor = UnknownAdaptor;
  137.                 Device[ k ].VideoMonitor = UnknownMonitor;
  138.                 }
  139.  
  140.         /*--------------------------------------------------------------\
  141.         |       Attempt to detect PS/2-type systems by making a BIOS    |
  142.         |       call to get the video display combination from the      |
  143.         |       video BIOS.  On return, the AL register is set to 1A,   |
  144.         |       BL will contain the display code for the active display |
  145.         |       and BH will contain the display code for the inactive   |
  146.         |       display.  The BL and BH registers are used to index     |
  147.         |       arrays containing codes for the appropriate display and |
  148.         |       display adaptor.                                        |
  149.         \--------------------------------------------------------------*/
  150.  
  151.         r.x.ax = 0x1A00;
  152.         int86(0x10, &r, &r);
  153.         if (r.h.al == 0x1A)
  154.                 {
  155.                 static struct video     DeviceList[ ] =
  156.                         {
  157.                         {       UnknownAdaptor, UnknownMonitor  },
  158.                         {       MDA,            MDAMonochrome   },
  159.                         {       CGA,            CGAColor        },
  160.                         {       UnknownAdaptor, UnknownMonitor  },
  161.                         {       EGA,            EGAColor        },
  162.                         {       EGA,            MDAMonochrome   },
  163.                         {       UnknownAdaptor, UnknownMonitor  },
  164.                         {       VGA,            PS2Monochrome   },
  165.                         {       VGA,            PS2Color        },
  166.                         {       UnknownAdaptor, UnknownMonitor  },
  167.                         {       MCGA,           EGAColor        },
  168.                         {       MCGA,           PS2Monochrome   },
  169.                         {       MCGA,           PS2Color        }
  170.                         };
  171.  
  172.                 if (r.h.bh != 0)
  173.                         {
  174.                         Device[ 1 ].VideoAdaptor =
  175.                                 DeviceList[ r.h.bh ].VideoAdaptor;
  176.                         Device[ 1 ].VideoMonitor =
  177.                                 DeviceList[ r.h.bh ].VideoMonitor;
  178.                         }
  179.                 Device[ 0 ].VideoAdaptor = DeviceList[ r.h.bl ].VideoAdaptor;
  180.                 Device[ 0 ].VideoMonitor = DeviceList[ r.h.bl ].VideoMonitor;
  181.                 if (Device[ 0 ].VideoAdaptor == MDA ||
  182.                         Device[ 1 ].VideoAdaptor == MDA)
  183.                         {
  184.  
  185.                         /*----------------------------------------------\
  186.                         |       If either the active display or the     |
  187.                         |       inactive display is identified as MDA,  |
  188.                         |       we clear the system and display         |
  189.                         |       information for that display; we need   |
  190.                         |       to further identify the system as       |
  191.                         |       possibly a Hercules card.               |
  192.                         \----------------------------------------------*/
  193.  
  194.                         if (Device[ 0 ].VideoAdaptor == MDA)
  195.                                 {
  196.                                 Device[ 0 ].VideoAdaptor = UnknownAdaptor;
  197.                                 Device[ 0 ].VideoMonitor = UnknownMonitor;
  198.                                 }
  199.                         else
  200.                                 {
  201.                                 Device[ 1 ].VideoAdaptor = UnknownAdaptor;
  202.                                 Device[ 1 ].VideoMonitor = UnknownMonitor;
  203.                                 }
  204.                         DetectMono();
  205.                         }
  206.                 }
  207.         else
  208.                 {
  209.  
  210.                 /*------------------------------------------------------\
  211.                 |       detect an EGA card; make a call to the BIOS to  |
  212.                 |       get the video subsystem configuration.  On      |
  213.                 |       return, BL will be set to 0, 1, 2 or 3 (which   |
  214.                 |       is the number of 64K blocks of RAM in addition  |
  215.                 |       to the default 64K block on the video card),    |
  216.                 |       and the least 4 bits of CL contain the          |
  217.                 |       configuration switch settings for the card.     |
  218.                 |       This includes information as to the display     |
  219.                 |       type.                                           |
  220.                 \------------------------------------------------------*/
  221.  
  222.                 r.h.bl = 0x10;
  223.                 r.h.ah = 0x12;
  224.                 int86(0x10, &r, &r);
  225.                 if (r.h.bl != 0x10)
  226.                         {
  227.                         auto enum monitor       Display;
  228.                         static enum monitor     EGADisplay[ ] =
  229.                                 {
  230.                                 CGAColor,       EGAColor,       MDAMonochrome
  231.                                 };
  232.  
  233.                         Display = EGADisplay[ (r.h.cl % 6) >> 1 ];
  234.                         FoundDevice(EGA, Display);
  235.  
  236.                         /*----------------------------------------------\
  237.                         |       If a monochrome display is found, any   |
  238.                         |       other system must be color, and         |
  239.                         |       vice-versa.                             |
  240.                         \----------------------------------------------*/
  241.  
  242.                         if (Display == MDAMonochrome)
  243.                                 DetectCGA();
  244.                         else
  245.                                 DetectMono();
  246.                         }
  247.                 else
  248.                         {
  249.                         DetectCGA();
  250.                         DetectMono();
  251.                         }
  252.                 }
  253.  
  254.         /*--------------------------------------------------------------\
  255.         |       Resolve discrepancies between systems with multiple     |
  256.         |       display types and the current video state; not a        |
  257.         |       problem if only one type was found, or one of the types |
  258.         |       found was MCGA or VGA.  Basically, the active display,  |
  259.         |       which is in Device[ 0 ], should match the color         |
  260.         |       specification of the current video mode.  Incidently,   |
  261.         |       the device swap is performed by the trick of using the  |
  262.         |       mathematical properties of the exclusive or operator to |
  263.         |       avoid having to declare a temporary holding variable.   |
  264.         \--------------------------------------------------------------*/
  265.  
  266.         if (Device[ 1 ].VideoAdaptor != UnknownAdaptor &&
  267.                 Device[ 0 ].VideoAdaptor != VGA &&
  268.                 Device[ 0 ].VideoAdaptor != MCGA &&
  269.                 Device[ 1 ].VideoAdaptor != VGA &&
  270.                 Device[ 1 ].VideoAdaptor != MCGA)
  271.                 {
  272.                 r.h.ah = 0x0F;
  273.                 int86(0x10, &r, &r);
  274.                 if ((r.h.al & 7) == 7)
  275.                         {
  276.                         if (Device[ 0 ].VideoMonitor != MDAMonochrome)
  277.                                 {
  278.                                 Device[ 0 ].VideoMonitor ^=
  279.                                         Device[ 1 ].VideoMonitor;
  280.                                 Device[ 1 ].VideoMonitor ^=
  281.                                         Device[ 0 ].VideoMonitor;
  282.                                 Device[ 0 ].VideoMonitor ^=
  283.                                         Device[ 1 ].VideoMonitor;
  284.                                 Device[ 0 ].VideoAdaptor ^=
  285.                                         Device[ 1 ].VideoAdaptor;
  286.                                 Device[ 1 ].VideoAdaptor ^=
  287.                                         Device[ 0 ].VideoAdaptor;
  288.                                 Device[ 0 ].VideoAdaptor ^=
  289.                                         Device[ 1 ].VideoAdaptor;
  290.                                 }
  291.                         }
  292.                 else
  293.                         {
  294.                         if (Device[ 0 ].VideoMonitor == MDAMonochrome)
  295.                                 {
  296.                                 Device[ 0 ].VideoMonitor ^=
  297.                                         Device[ 1 ].VideoMonitor;
  298.                                 Device[ 1 ].VideoMonitor ^=
  299.                                         Device[ 0 ].VideoMonitor;
  300.                                 Device[ 0 ].VideoMonitor ^=
  301.                                         Device[ 1 ].VideoMonitor;
  302.                                 Device[ 0 ].VideoAdaptor ^=
  303.                                         Device[ 1 ].VideoAdaptor;
  304.                                 Device[ 1 ].VideoAdaptor ^=
  305.                                         Device[ 0 ].VideoAdaptor;
  306.                                 Device[ 0 ].VideoAdaptor ^=
  307.                                         Device[ 1 ].VideoAdaptor;
  308.                                 }
  309.                         }
  310.                 }
  311.         return (Device);
  312.         }
  313.