home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / PRINTING / SHOWGL10.ZIP / AUTOGRPH.C < prev    next >
C/C++ Source or Header  |  1991-08-22  |  8KB  |  237 lines

  1. /* autogrph.c */
  2.  
  3. /* identify type of video adapter being used (graphics types, only) and
  4. return the identification code for that adapter.  This module is designed
  5. to be compiled alone, and the object code bound into the auxgraph library
  6. file.
  7.  
  8. calling  unsigned video_test ();
  9.  
  10. returns disp_a + disp_b << 8 for primary and secondary displays, respectively.
  11. Returned codes as given below.
  12. */
  13.  
  14. /* copyright 1990, 1991  Robert C. Becker, Lantern Systems */
  15.  
  16. #include <stdio.h>
  17. #include <dos.h>
  18. #include <bios.h>
  19. #include <conio.h>
  20.  
  21. /* do some fancy bit setting to make detecting mono vs. color easier */
  22. /*          7        6        5        4        3        2        1        0   */
  23. /*  +--------+--------+--------+--------+--------+--------+--------+--------+  */
  24. /*  |Herc=1  | mono=1 |        |        |        Adapter ID code 0 - 0F     |  */
  25. /*  |        |        |        |        |                                   |  */
  26. /*  +--------+--------+--------+--------+--------+--------+--------+--------+  */
  27.  
  28. /* these are the returned video adapter ID code numbers */
  29.  
  30. #define VIDEO        0x10    /* video interrupt number */
  31. #define NOGRAPHICS    0    /* no supported graphics modes available */
  32. #define CGA        1    /* CGA */
  33. #define MEGA        0x42    /* EGA monochrome */
  34. #define CEGA        3    /* EGA color */
  35. #define PGC        4    /* PGC: not supported */
  36. #define MVGA        0x45    /* VGA monochrome */
  37. #define CVGA        6    /* VGA color */
  38. #define EMCGA        7    /* MCGA w/EGA color display */
  39. #define MMCGA        0x48    /* Mono MCGA */
  40. #define CMCGA        9    /* Color MCGA */
  41. #define ATT        0x0A    /* ATT  PC6300:  not known if DEB is present */
  42. #define HGC        0x0CB    /* Hercules graphics card */
  43. #define HGCPLUS        0x0CC    /* Hercules Plus card */
  44. #define INCOLOR        0x8D    /* Hercules InColor card */
  45.  
  46. unsigned video_test ();
  47. static int ps2_test ();
  48. static int ega_test ();
  49. static void cga_test ();
  50. static int herc_test ();
  51. static int att_test ();
  52.  
  53. static unsigned disp_a, disp_b, ega_mry;
  54. static unsigned ps2vid[] = { NOGRAPHICS, NOGRAPHICS, CGA, NOGRAPHICS, CEGA, MEGA,
  55.             PGC, MVGA, CVGA, NOGRAPHICS, EMCGA, CMCGA, CMCGA };
  56.  
  57. static unsigned ega_config[] = { CGA, CEGA, MEGA };    /* only need 3 of 6: order is same for last 3 configs */
  58.  
  59. static char attlogo[] = "OLIVETTI";
  60. static char far *romid;
  61. static char romstr [10];
  62.  
  63. static char copyright [] = "copyright 1990, 1991  Robert C. Becker, Lantern Systems";
  64.  
  65. static union REGS regs;
  66.  
  67. /*---------------------------------------*/
  68.  
  69. unsigned video_test ()
  70.     {
  71.     int j;
  72.  
  73.     disp_a = disp_b = NOGRAPHICS;    /* initialize: no supported video graphics modes */
  74.  
  75.     if (ps2_test () > 1) return ( disp_a + (disp_b << 8) );
  76.     /* done: VGA interrupt answered all questions */
  77.  
  78.     if ( !ega_test () )     /* returns 1 if EGA: if EGA, no CGA possible  */
  79.         if ( !att_test () ) cga_test ();
  80.  
  81.     /* The value of the adapter returned by ega_test () is one of CEGA, CGA, MEGA.
  82.     The CGA value is returned because an EGA adapter using a CGA monitor can't reproduce
  83.     the high resolution graphics modes.  Also, because the adapter port adr's are
  84.     programmable and change when using mono modes, we can't look for Herc cards if we
  85.     have a mono EGA adapter since the ports overlap.  We test first for an ATT graphics
  86.     adapter because it is basically a CGA adapter and will pass the CGA test.  By testing
  87.     first for the ATT card, we can separate them. */
  88.  
  89.     /* if either display is MONO, No Herc cards possible */
  90.     /* this includes the InColor card which uses the mono address space */
  91.     if (( disp_a  & 0x40 ) || ( disp_b & 0x40 )) return ( disp_a + (disp_b << 8) );
  92.     if ( j = herc_test () )
  93.         {
  94.         if ( disp_a == NOGRAPHICS )
  95.             disp_a = j;
  96.         else
  97.             disp_b = j;    /* never get here if disp_b already assigned */
  98.         }            /* (another type of mono display would be present) */
  99.  
  100.     /* a complete video test would also determine which adapter is presently the
  101.     primary display.  We don't care here, because we are going to take the highest
  102.     resolution display and switch to it for graphics */
  103.  
  104.     return ( disp_a + (disp_b << 8) );
  105.     }
  106.  
  107. /*---------------------------------------*/
  108.  
  109. int ps2_test ()    /* test for PS/2 VGA or MCGA  */
  110.     {    /* returns # of displays found: 0 for none/unsupported */
  111.     int i = 0;
  112.  
  113.     regs.x.ax = 0x1A00;        /* get video display configuration */
  114.     int86 (VIDEO, ®s, ®s);
  115.     if (regs.h.al != 0x1a)    return (0);    /* unsupported command */
  116.     if (regs.h.bl > 0 && regs.h.bl <= 0x0C )    /* active display */
  117.         {
  118.         ++i;    /* found one display */
  119.         disp_a = ps2vid [regs.h.bl];        /* type number */
  120.         }
  121.     if (regs.h.bh > 0 && regs.h.bh <= 0x0C )    /* inactive display */
  122.         {
  123.         disp_b = ps2vid [regs.h.bh];    /* type number */
  124.         return ( ++i);            /* found a display */
  125.         }
  126.     return (i);
  127.     }
  128.  
  129. /*---------------------------------------*/
  130.  
  131. int ega_test ()        /* test for EGA display */
  132.     {
  133.     unsigned i;
  134.  
  135.     regs.x.ax = 0x1200;    /* code for Alternate Select */
  136.     regs.h.bl = 0x10;    /* code for return EGA information */
  137.     int86 (VIDEO, ®s, ®s);
  138.  
  139.     if (regs.h.bl == 0x10 )    return ( 0 );    /* No EGA present */
  140.     i = regs.h.cl > 1;            /* bit 0 = don't care */
  141.     i = (i > 2) ? i - 3: i;            /* fold repeated pattern into 1st three types */
  142.     ega_mry = regs.h.bl;            /* EGA memory code */
  143.  
  144.     /* we have an EGA adapter, but find out how it is configured.  Need to
  145.     know if it is EGA color, CGA color, or BW graphics */
  146.  
  147.     if (disp_a == NOGRAPHICS )    /* no prior active display identified */
  148.         {
  149.         disp_a = ega_config[ i ];
  150.         return ( 1 );    /* return EGA found: do not test for CGA */
  151.         }
  152.     if ( disp_b == NOGRAPHICS )    /* no prior secondary display identified */
  153.         {
  154.         disp_b = ega_config[ i ];
  155.         return ( 1 );        /* this is the alternative adapter: done searching */
  156.         }
  157.     }
  158.  
  159. /*---------------------------------------*/
  160. void cga_test ()
  161.     {
  162.     unsigned cur_pos;
  163.     int i, j;
  164.  
  165.     /* test for CGA by testing for 6845 CRTC chip at 0x3d4 */
  166.     outp ( 0x3d4, 0x0F );    /* select cursor position low byte reg */
  167.     cur_pos = inp (0x3d5);    /* read current value of cursor low reg */
  168.     outp (0x3d5, 0x66);    /* arbitrary value */
  169.  
  170.  
  171.     for (i = 0; i < 100; ++i) j = inp (0x3d5);    /* kill time */
  172.  
  173.     if (inp (0x3d5) == 0x66 )    /* have CGA */
  174.         {
  175.         outp ( 0x3d5, cur_pos );    /* restore cursor position */
  176.         if (disp_a != NOGRAPHICS )
  177.             {
  178.             disp_b = CGA;
  179.             return;
  180.             }
  181.         disp_a = CGA;    /* if we got here, then there is no other primary display */
  182.         outp ( 0x3d5, cur_pos);    /* restore cursor position */
  183.         }
  184.     return;
  185.     }
  186.  
  187. /*---------------------------------------*/
  188.  
  189. int herc_test ()
  190.     {
  191.     unsigned st, st1, i;
  192.  
  193.     st = inp (0x3ba) & 0x70;    /* read Herc/MDA status reg. Get Herc ID bits */
  194.     if ( st == 0x50 )        /* InColor card */
  195.         return (INCOLOR);
  196.     if ( st == 0x10 )        /* Herc Plus card */
  197.         return (HGCPLUS);
  198.     st = (inp (0x3ba) );        /* read status port */
  199.     for (i = 0x3fff; i > 0; --i)    /* not a good idea to use clock speed dependent loops */
  200.         {
  201.         if ( (st ^ inp (0x3ba) ) & 0x80 )    /* test for changes in vert retrace bit (80h) */
  202.             return ( HGC );    /* bit 7 changes: must be ordinary Herc card */
  203.         }
  204.     return ( NOGRAPHICS );    /* bit 7 does not change -> MDA card */
  205.     }
  206.  
  207. /*---------------------------------------*/
  208.  
  209.  
  210. static int att_test ()
  211.     {
  212.     char *str;
  213.     int i;
  214.  
  215.     FP_SEG (romid) = 0x0fc00;
  216.     FP_OFF (romid) = 0x0050;
  217.     str = romstr;
  218.     for (i = 0; i < 8; ++i, ++str, ++romid) *str = *romid;
  219.     *str = '\0';    /* terminate string */
  220.  
  221. /*    printf ("ROM ID string = %s\n", romstr);    */
  222.     if ( !strcmp (romstr, attlogo) )    /* BIOS ROM logo matches */
  223.         {
  224.         if (disp_a != NOGRAPHICS )
  225.             {
  226.             disp_b = ATT;
  227.             return (1);
  228.             }
  229.         disp_a = ATT;    /* if we got here, then there is no other primary display */
  230.         return (1);
  231.         }
  232.     return (0);    /* not ATT */
  233.     }
  234.  
  235.  
  236. /*---------------------------------------*/
  237.