home *** CD-ROM | disk | FTP | other *** search
/ Der Mediaplex Sampler - Die 6 von Plex / 6_v_plex.zip / 6_v_plex / DISK2 / MULTI_04 / SHOWGL15.ZIP / AUTOGR.C < prev    next >
C/C++ Source or Header  |  1991-12-27  |  10KB  |  318 lines

  1. /* autogrph.c V. 2.0*/
  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. Version 1.0
  11.     returns disp_a + disp_b << 8 for primary and secondary displays, 
  12.     respectively.
  13.  
  14. Version 2.0
  15.     changed header files and return variable for video_test () from
  16.     unsigned to struct *.
  17.  
  18.     added code to detect ATT Display Enhancement Board
  19. */
  20.  
  21. /* copyright 1990, 1991  Robert C. Becker, Lantern Systems */
  22.  
  23. #include <stdio.h>
  24. #include <dos.h>
  25. #include <string.h>
  26. #include <conio.h>
  27. #include "graph.h"
  28. #include "hpgl.h"
  29.  
  30.  
  31. #define        DEB_PORT    0x3da        /* port # for ATT graphics controller status port */
  32.  
  33. /* this structure is made visible to all other programs that use the
  34. video_test () function call.  It is necessary because the function returns
  35. a display type number which references an index into this table. */
  36.  
  37. struct video_type__ display_adapter__ [Num_Adapters];
  38.  
  39.  
  40.  
  41. static struct video_display video_adapter;
  42.  
  43. static int ps2_test ( void );
  44. static int ega_test ( void );
  45. static void cga_test ( void );
  46. static int herc_test ( void );
  47. static int att_test ( void );
  48. static void assign_video_a ( unsigned );
  49. static void assign_video_b ( unsigned );
  50. static void init_videostr ( void );
  51. static void init_adapters ( unsigned adr, unsigned type, struct _vid_x_parm_ *vid_mode, char * display);
  52.  
  53. static unsigned 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. struct video_display *video_test ( void )
  70.     {
  71.     int j;
  72.  
  73.     init_videostr ();
  74.  
  75.     video_adapter.disp_a = video_adapter.disp_b = NOGRAPHICS;    /* initialize: no supported video graphics modes */
  76.  
  77.     if (ps2_test () > 1) return ( &video_adapter );
  78.     /* done: VGA interrupt answered all questions */
  79.  
  80.     if ( !ega_test () )     /* returns 1 if EGA: if EGA, no CGA possible  */
  81.         if ( !att_test () ) cga_test ();
  82.  
  83.     /* The value of the adapter returned by ega_test () is one of CEGA, CGA, MEGA.
  84.     The CGA value is returned because an EGA adapter using a CGA monitor can't reproduce
  85.     the high resolution graphics modes.  Also, because the adapter port adr's are
  86.     programmable and change when using mono modes, we can't look for Herc cards if we
  87.     have a mono EGA adapter since the ports overlap.  We test first for an ATT graphics
  88.     adapter because it is basically a CGA adapter and will pass the CGA test.  By testing
  89.     first for the ATT card, we can separate them. */
  90.  
  91.     /* if either display is MONO, No Herc cards possible */
  92.     /* this includes the InColor card which uses the mono address space */
  93.     if (( video_adapter.disp_a != NOGRAPHICS ) || ( video_adapter.disp_b != NOGRAPHICS )) return ( &video_adapter );
  94.     if ( j = herc_test () )
  95.         {
  96.         if ( video_adapter.disp_a == NOGRAPHICS )
  97.             assign_video_a (j);
  98.         else
  99.             /* never get here if disp_b already assigned */
  100.             /* (another type of mono display would be present) */
  101.             assign_video_b (j);
  102.         }
  103.  
  104.     /* a complete video test would also determine which adapter is presently the
  105.     primary display.  We don't care here, because we are going to take the highest
  106.     resolution display and switch to it for graphics */
  107.  
  108.     return ( &video_adapter );
  109.     }
  110.  
  111. /*---------------------------------------*/
  112.  
  113. int ps2_test ( void )    /* test for PS/2 VGA or MCGA  */
  114.     {    /* returns # of displays found: 0 for none/unsupported */
  115.     int i = 0;
  116.  
  117.     regs.x.ax = 0x1A00;        /* get video display configuration */
  118.     int86 (VIDEO, ®s, ®s);
  119.     if (regs.h.al != 0x1a)    return (0);    /* unsupported command */
  120.     if (regs.h.bl > 0 && regs.h.bl <= 0x0C )    /* active display */
  121.         {
  122.         ++i;    /* found one display */
  123.         assign_video_b (ps2vid [regs.h.bl] );    /* type number */
  124.         }
  125.     if (regs.h.bh > 0 && regs.h.bh <= 0x0C )    /* inactive display */
  126.         {
  127.         assign_video_b (ps2vid [regs.h.bh]);    /* type number */
  128.         return ( ++i);            /* found a display */
  129.         }
  130.     return (i);
  131.     }
  132.  
  133. /*---------------------------------------*/
  134.  
  135. int ega_test ( void )        /* test for EGA display */
  136.     {
  137.     unsigned i;
  138.  
  139.     regs.x.ax = 0x1200;    /* code for Alternate Select */
  140.     regs.h.bl = 0x10;    /* code for return EGA information */
  141.     int86 (VIDEO, ®s, ®s);
  142.  
  143.     if (regs.h.bl == 0x10 )    return ( 0 );    /* No EGA present */
  144.     i = regs.h.cl > 1;            /* bit 0 = don't care */
  145.     i = (i > 2) ? i - 3: i;            /* fold repeated pattern into 1st three types */
  146.     ega_mry = regs.h.bl;            /* EGA memory code */
  147.  
  148.     /* we have an EGA adapter, but find out how it is configured.  Need to
  149.     know if it is EGA color, CGA color, or BW graphics */
  150.  
  151.     if (video_adapter.disp_a == NOGRAPHICS )    /* no prior active display identified */
  152.         {
  153.         assign_video_a ( ega_config [i] );
  154.         return ( 1 );    /* return EGA found: do not test for CGA */
  155.         }
  156.     if ( video_adapter.disp_b == NOGRAPHICS )    /* no prior secondary display identified */
  157.         {
  158.         assign_video_b ( ega_config [i] );
  159.         return ( 1 );        /* this is the alternative adapter: done searching */
  160.         }
  161.     return (0);
  162.     }
  163.  
  164. /*---------------------------------------*/
  165. void cga_test ( void )
  166.     {
  167.     unsigned cur_pos;
  168.     int i, j;
  169.  
  170.     /* test for CGA by testing for 6845 CRTC chip at 0x3d4 */
  171.     outp ( 0x3d4, 0x0F );    /* select cursor position low byte reg */
  172.     cur_pos = (unsigned) inp (0x3d5);    /* read current value of cursor low reg */
  173.     outp (0x3d5, 0x66);    /* arbitrary value */
  174.  
  175.  
  176.     for (i = 0; i < 100; ++i) j = inp (0x3d5);    /* kill time */
  177.  
  178.     if (inp (0x3d5) == 0x66 )    /* have CGA */
  179.         {
  180.         outp ( 0x3d5, cur_pos );    /* restore cursor position */
  181.         if (video_adapter.disp_a == NOGRAPHICS )
  182.             {
  183.             assign_video_a (CGA);
  184.             assign_video_b (CGAM);
  185.             return;
  186.             }
  187.         assign_video_b (CGA);    /* if we got here, then there is one other primary display */
  188.         outp ( 0x3d5, cur_pos);    /* restore cursor position */
  189.         }
  190.     return;
  191.     }
  192.  
  193. /*---------------------------------------*/
  194.  
  195. int herc_test ( void )
  196.     {
  197.     unsigned st, i;
  198.  
  199.     st = ( (unsigned) inp (0x3ba) ) & 0x70;    /* read Herc/MDA status reg. Get Herc ID bits */
  200.     if ( st == 0x50 )        /* InColor card */
  201.         return (INCOLOR);
  202.     if ( st == 0x10 )        /* Herc Plus card */
  203.         return (HGCPLUS);
  204.     st = (unsigned) inp (0x3ba);    /* read status port */
  205.     for (i = 0x3fff; i > 0; --i)    /* not a good idea to use clock speed dependent loops */
  206.         {
  207.         if ( (st ^ inp (0x3ba) ) & 0x80 )    /* test for changes in vert retrace bit (80h) */
  208.             return ( HGC );    /* bit 7 changes: must be ordinary Herc card */
  209.         }
  210.     return ( NOGRAPHICS );    /* bit 7 does not change -> MDA card */
  211.     }
  212.  
  213. /*---------------------------------------*/
  214.  
  215.  
  216. static int att_test ( void )
  217.     {
  218.     char *str;
  219.     int i;
  220.     unsigned char c;
  221.     unsigned type;
  222.  
  223.     FP_SEG (romid) = 0x0fc00;
  224.     FP_OFF (romid) = 0x0050;
  225.     str = romstr;
  226.     for (i = 0; i < 8; ++i, ++str, ++romid) *str = *romid;
  227.     *str = '\0';    /* terminate string */
  228.  
  229. /*    printf ("ROM ID string = %s\n", romstr);    */
  230.     if ( !strcmp (romstr, attlogo) )    /* BIOS ROM logo matches */
  231.         {
  232.         type = ATT;
  233.         c = 0xFF & inp (DEB_PORT);        /* ATT CRT controller status reg */
  234.         if ( !(c & 0x0c) ) type = ATT_DEB;    /* found a DEB */
  235.         if (video_adapter.disp_a != NOGRAPHICS )
  236.             {
  237.             assign_video_b (type);
  238.             return (1);
  239.             }
  240.         /* if we got here, then there is no other primary display */
  241.         assign_video_a (type);
  242.         return (1);
  243.         }
  244.     return (0);    /* not ATT */
  245.     }
  246.  
  247.  
  248. /*---------------------------------------*/
  249.  
  250. static void assign_video_a (unsigned type)
  251.     {
  252.     int adr;
  253.  
  254.     adr = 0x3f & type;
  255.     /* trim off top two bits ( 0x80 = monochrome bit, 0x40 = reserved) */
  256.  
  257.     video_adapter.disp_a = (display_adapter__ [adr]).type;
  258.     video_adapter.vid_mode_a = (display_adapter__ [adr]).vid_mode;
  259.     video_adapter.display_a = (display_adapter__ [adr]).display;
  260.  
  261.     return;
  262.     }
  263.  
  264. /*---------------------------------------*/
  265.  
  266. static void assign_video_b (unsigned type)
  267.     {
  268.  
  269.     video_adapter.disp_b = (display_adapter__ [type]).type;
  270.     video_adapter.vid_mode_b = (display_adapter__ [type]).vid_mode;
  271.     video_adapter.display_b = (display_adapter__ [type]).display;
  272.  
  273.     return;
  274.     }
  275.  
  276. /*---------------------------------------*/
  277.  
  278. static void init_videostr ( void )
  279.     {
  280.  
  281.     init_adapters (NOGRAPHICS, NOGRAPHICS, CGA_320x200, "No Graphics" );
  282.     init_adapters (CGA, CGA, CGA_320x200, "CGA 320x200" );
  283.     init_adapters (CGAM, CGAM, CGA_640x200, "CGA 640x200, BW" );
  284.     init_adapters (MEGA, MEGA, MEGA_640x350, "EGA 640x350, BW" );
  285.     init_adapters (CEGA, CEGA, EGA_640x350, "EGA 640x350, 16 color" );
  286.     init_adapters (MVGA, MVGA, MCGA_640x480, "VGA 640x480, BW" );    /* Mono MCGA */
  287.     init_adapters (CVGA, CVGA, VGA_640x480, "VGA 640x480, 16 color" );
  288.     init_adapters (EMCGA, EMCGA, MCGA_640x480, "MCGA w/ EGA monitor" );    /* MCGA w/ EGA monitor */
  289.     init_adapters (MMCGA, MMCGA, MCGA_640x480, "MCGA 640x480, BW" );    /* Mono MCGA */
  290.     init_adapters (CMCGA, CMCGA, MCGA_640x480, "MCGA 640x480, BW" );    /* Color MCGA */
  291.     init_adapters (ATT, ATT, ATT_640x400, "ATT 640x400, BW" );
  292.     init_adapters (ATT_DEB, ATT_DEB, ATTDEB_640x400, "ATT 640x400, 16 color" );
  293.     init_adapters (PGC, NOGRAPHICS, VGA_640x480, "No Graphics" );    /* use VGA mode to fill struct */
  294.     init_adapters (HGC, NOGRAPHICS, HGC_720x348, "Hercules" );
  295.     init_adapters (HGCPLUS, NOGRAPHICS, HGC_720x348, "Hercules+" );
  296.     init_adapters (INCOLOR, NOGRAPHICS, HGC_720x348, "Hercules InColor" );
  297.  
  298.     return;
  299.     }
  300.  
  301. /*---------------------------------------*/
  302.  
  303. static void init_adapters ( unsigned adr, unsigned type, struct _vid_x_parm_ *vid_mode, char * display)
  304.     {
  305.  
  306.     /* trim off top two bits ( 0x80 = monochrome bit, 0x40 = reserved) */
  307.  
  308.     adr &= 0x3F;
  309.  
  310.     (display_adapter__ [adr]).type = type;
  311.     (display_adapter__ [adr]).vid_mode = vid_mode;
  312.     (display_adapter__ [adr]).display = display;
  313.  
  314.     return;
  315.     }
  316.  
  317. /*---------------------------------------*/
  318.