home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c070 / 4.ddi / TOOLS.4 / TCTSRC1.EXE / SCEQUIP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  14.7 KB  |  502 lines

  1. /**
  2. *
  3. * Name        scequip -- Obtain video hardware environment & settings
  4. *
  5. * Synopsis    model = scequip();
  6. *
  7. *        char model     IBM Model code:
  8. *                  IBM_PC (0xff) if IBM PC
  9. *                  IBM_XT (0xfe) if IBM PC-XT
  10. *                        or Portable PC
  11. *                  IBM_JR (0xfd) if IBM PCjr
  12. *                  IBM_AT (0xfc) if IBM PC-AT
  13. *                  IBM_CV (0xf9) if IBM PC Convertible
  14. *                  IBM_30 (0xfa) if IBM PS/2 model 30
  15. *                  IBM_50 (0xfc) if IBM PS/2 models 50 or 60
  16. *                  IBM_80 (0xf8) if IBM PS/2 model 80
  17. *
  18. * Description    This function obtains information about the video
  19. *        adapters installed on this machine and their options.
  20. *        All of the results are available in global variables
  21. *        declared in BSCREENS.H, except for b_pcmodel, which is
  22. *        declared in BUTIL.H.
  23. *
  24. *        This function should need to be called only once during
  25. *        the execution of a program.  (If it is called again, it
  26. *        will examine the b_know_hw flag and skip most of its
  27. *        operations to save time.)
  28. *
  29. *        Use SCMODE to obtain video information that might be
  30. *        altered under software control (such as video mode or
  31. *        number of columns).  Use SCNEWDEV to switch to a given
  32. *        video adapter.
  33. *
  34. * Results    model        IBM Model code:
  35. *        b_pcmodel      IBM_PC (0xff) if IBM PC
  36. *                  IBM_XT (0xfe) if IBM PC-XT
  37. *                        or Portable PC
  38. *                  IBM_JR (0xfd) if IBM PCjr
  39. *                  IBM_AT (0xfc) if IBM PC-AT
  40. *                  IBM_CV (0xf9) if IBM PC Convertible
  41. *        (Also sets various global variables in BSCREENS.H)
  42. *
  43. * Version    6.00 (C)Copyright Blaise Computing Inc.  1986-1989
  44. *
  45. **/
  46.  
  47. #include <conio.h>
  48. #include <dos.h>
  49.  
  50. #include <bscreens.h>
  51.  
  52. int b_know_hw = 0;          /* Flag stating whether we have yet     */
  53.                   /*     run SCEQUIP:  0 if no, 1 if yes  */
  54.  
  55. int b_mdpa = SC_DONT_KNOW;/* Monochrome Display & Printer Adapter     */
  56.               /*   SC_DONT_KNOW, SC_ABSENT, or SC_MONO    */
  57.               /*   (SC_MONO if Hercules graphics adapter.)*/
  58.               /*                          */
  59. int b_cga = SC_DONT_KNOW; /* Color/Graphics Monitor Adapter          */
  60.               /*   SC_DONT_KNOW, SC_ABSENT, or SC_COLOR   */
  61.               /*                          */
  62. int b_ega = SC_DONT_KNOW; /* Enhanced Graphics Adapter: SC_DONT_KNOW, */
  63.               /*   SC_ABSENT, SC_MONO or SC_COLOR          */
  64.               /*                          */
  65. int b_mcga = SC_DONT_KNOW;/* Multicolor Graphics Array: SC_DONT_KNOW, */
  66.               /*   SC_ABSENT, or SC_COLOR              */
  67.               /*                          */
  68. int b_vga = SC_DONT_KNOW; /* Video Graphics Array:  SC_DONT_KNOW,     */
  69.               /*  SC_ABSENT, SC_MONO or SC_COLOR          */
  70.               /*                          */
  71. int b_herc = SC_DONT_KNOW;/* Hercules monochrome graphics adapter     */
  72.               /*   SC_DONT_KNOW, SC_ABSENT, or SC_MONO    */
  73.               /*                          */
  74. int b_pgc = SC_DONT_KNOW; /* Professional Graphics Controller:          */
  75.               /*   SC_DONT_KNOW, SC_ABSENT, SC_COLOR, or  */
  76.               /*   SC_HIFUNC                  */
  77.  
  78. int b_mem_ega = 0;          /* Amount of memory installed on EGA in */
  79.                   /* 1024-byte units:  64, 128, 192, 256  */
  80.  
  81. unsigned b_sw_ega = 0x0ffff;  /* Switch settings on EGA           */
  82.                   /* Low-order bit set means SW1 off, etc.*/
  83.                   /* (Bit value 1 implies that          */
  84.                   /* corresponding switch is off.)          */
  85.  
  86. static volatile int waiter;   /* Variable to assign to to wait for    */
  87.                   /* CGA and PGC to stabilize when using  */
  88.                   /* fast processors.              */
  89.  
  90. #define  PGC_SEG   0xc600     /* Segment of memory-mapped PGC ports.  */
  91.                   /* PGC port for presence test.          */
  92. #define  PGC_PRES_BYTE    (uttofar(PGC_SEG,0x03db,unsigned char))
  93. #define  PGC_INDEX 0x03d4     /* Offset of PGC/CGA index port          */
  94. #define  PGC_IND_BYTE    (uttofar(PGC_SEG,PGC_INDEX,unsigned char))
  95.  
  96. #define WAIT                                   \
  97.     {                                       \
  98.     waiter    = 0;                               \
  99.     waiter += 1;                               \
  100.     }
  101.  
  102. static void note_adapter(unsigned char,int); /* Internal function     */
  103. static int adap_present(int);          /* Internal function          */
  104. static int pgc_present(void);          /* Internal function          */
  105. static int pgc_emulating(void);       /* Internal function          */
  106. static int herc(void);              /* Internal function          */
  107.  
  108.     /* Internal variables containing interim knowledge of adapter     */
  109.     /* state and modes.                           */
  110.  
  111. #define _DONT_KNOW  (-1)
  112. #define _ABSENT       0
  113. #define _ACTIVE       1
  114. #define _ALTERNATE    2
  115. #define _PRESENT      3
  116.  
  117. static int pgc_state = _DONT_KNOW;
  118. static int vga_state;
  119.  
  120.  
  121. char scequip()
  122. {
  123.     union REGS inregs,outregs;          /* Registers for BIOS calls     */
  124.     unsigned   color_or_mono,mem;
  125.     int        pgc_emul_tested;
  126.     int        mode,columns,act_page;
  127.  
  128.     if (b_know_hw)
  129.     {
  130.     scmode(&mode,&columns,&act_page);   /* Check VGA state.       */
  131.     return b_pcmodel;     /* No need to do this work again          */
  132.     }
  133.  
  134.     if (utmodel() == IBM_JR)          /* Fetch & save model code.     */
  135.     {                      /* This is a PCjr           */
  136.     b_mdpa = SC_ABSENT;
  137.     b_cga  = SC_ABSENT;
  138.     b_ega  = SC_ABSENT;
  139.     b_pgc  = SC_ABSENT;
  140.     b_vga  = SC_ABSENT;
  141.     b_mcga = SC_ABSENT;
  142.     b_herc = SC_ABSENT;
  143.     }
  144.     else if (b_pcmodel == IBM_CV)
  145.     {                      /* IBM PC Convertible acts like */
  146.     b_mdpa = SC_MONO;          /* both MDPA & CGA.          */
  147.     b_cga  = SC_COLOR;
  148.     b_ega  = SC_ABSENT;
  149.     b_pgc  = SC_ABSENT;
  150.     b_vga  = SC_ABSENT;
  151.     b_mcga = SC_ABSENT;
  152.     b_herc = SC_ABSENT;
  153.     }
  154.     else
  155.     {                      /* Neither PCjr nor Convertible */
  156.  
  157.     /* First test for VGA or MCGA:  attempt BIOS video function 0x1a. */
  158.  
  159.     inregs.x.ax = 0x1a00;
  160.     int86(16,&inregs,&outregs);
  161.     if (outregs.h.al == 0x1a)
  162.     {
  163.         b_mdpa = SC_ABSENT;  /* Flag these devices as absent;     */
  164.         b_cga  = SC_ABSENT;  /* note_adapter will change the      */
  165.         b_ega  = SC_ABSENT;  /* value for devices actually found. */
  166.         b_mcga = SC_ABSENT;
  167.         b_vga  = SC_ABSENT;
  168.         b_pgc  = SC_ABSENT;
  169.         b_mcga = SC_ABSENT;
  170.         vga_state = _ABSENT;
  171.  
  172.                       /* Record the active adapter.   */
  173.         note_adapter(outregs.h.bl,_ACTIVE);
  174.                       /* Record the other adapter.    */
  175.         note_adapter(outregs.h.bh,_ALTERNATE);
  176.  
  177.         if (vga_state == _ABSENT)
  178.         b_vga = SC_ABSENT;
  179.         else
  180.         {                  /* Use current mode to learn    */
  181.                       /* whether VGA is monochrome or */
  182.                       /* color.               */
  183.         inregs.h.ah = 0x0f;
  184.         int86(16,&inregs,&outregs);
  185.         if (outregs.h.al == 7 || outregs.h.al == 15)
  186.                       /* Active adapter is SC_MONO.   */
  187.             b_vga = (vga_state == _ACTIVE ? SC_MONO : SC_COLOR);
  188.         else
  189.                       /* Active device is SC_COLOR.   */
  190.             b_vga = (vga_state == _ACTIVE ? SC_COLOR : SC_MONO);
  191.         }
  192.     }
  193.     else
  194.     {
  195.         b_mcga =
  196.         b_vga  = SC_ABSENT;
  197.     }
  198.  
  199.     /* Next test for the presence of an EGA:  attempt BIOS video      */
  200.     /* function 18, subfunction BL=0x10 ("Return EGA Information").   */
  201.     /* If any information returned is invalid, then the EGA must be   */
  202.     /* absent.                                  */
  203.  
  204.     if (b_ega != SC_ABSENT)
  205.     {
  206.         inregs.h.ah = 18;
  207.         inregs.x.bx = 0xff10;
  208.         inregs.x.cx = 0x000f;
  209.         int86(16,&inregs,&outregs);
  210.         color_or_mono = outregs.h.bh;
  211.         mem       = outregs.h.bl;
  212.         b_sw_ega      = outregs.h.cl;
  213.  
  214.         if (b_sw_ega >= 12 || color_or_mono > 1 || mem > 3)
  215.         b_ega      = SC_ABSENT;        /* Invalid value(s) found */
  216.         else
  217.         {                    /* EGA is present          */
  218.         b_ega      = (color_or_mono ? SC_MONO : SC_COLOR);
  219.         b_mem_ega = 64 * (mem + 1);
  220.         }
  221.     }
  222.  
  223.     /* If the EGA, VGA, or MCGA is emulating the MDPA or the CGA,     */
  224.     /* then the emulated board cannot itself be present, but the      */
  225.     /* other might be.                              */
  226.  
  227.     if (b_mdpa == SC_DONT_KNOW)
  228.         if (b_ega==SC_MONO || b_vga==SC_MONO || b_mcga==SC_MONO
  229.             || !adap_present(0))  /* Sense monochrome adapter */
  230.         b_mdpa = SC_ABSENT;
  231.         else
  232.         b_mdpa = SC_MONO;
  233.  
  234.     /* Further, if we sense a color adapter, then exactly one of the  */
  235.     /* following conditions must be true:  EGA, VGA, or MCGA is in    */
  236.     /* color mode; PGC is emulating the CGA; or a genuine CGA is      */
  237.     /* present.                               */
  238.  
  239.     pgc_emul_tested = 0;
  240.     if (b_cga == SC_DONT_KNOW)
  241.     {
  242.         if (b_ega==SC_COLOR || b_vga==SC_COLOR || b_mcga==SC_COLOR)
  243.         b_cga = SC_ABSENT;
  244.         else if (adap_present(1))           /* Sense color adapter */
  245.         {
  246.         if (pgc_emulating() == SC_COLOR)
  247.         {
  248.             b_pgc = SC_COLOR;
  249.             b_cga = SC_ABSENT;
  250.         }
  251.         else
  252.             b_cga = SC_COLOR;
  253.         pgc_emul_tested = 1;
  254.         }
  255.         else
  256.         b_cga = SC_ABSENT;
  257.     }
  258.  
  259.     /* If the PGC is present but not emulating the CGA, then it must  */
  260.     /* be in its high-function graphics mode.                  */
  261.  
  262.     if (b_pgc == SC_DONT_KNOW)
  263.     {
  264.         if (pgc_present())
  265.         b_pgc = (pgc_emul_tested ? SC_HIFUNC : pgc_emulating());
  266.         else
  267.         b_pgc = SC_ABSENT;
  268.     }
  269.  
  270.     }
  271.  
  272.     if (b_mdpa == SC_MONO && herc())  /* Hercules adapter may be      */
  273.     b_herc = SC_MONO;          /* emulating monochrome.          */
  274.     else
  275.     b_herc = SC_ABSENT;
  276.  
  277.     b_know_hw = 1;
  278.  
  279.     return b_pcmodel;
  280. }
  281.  
  282. /**
  283. *
  284. * Name        note_adapter -- Record installed adapters based on BIOS
  285. *                display combination code from video
  286. *                function 0x1a
  287. *
  288. * Synopsis    note_adapter(code,active_flag);
  289. *
  290. *        unsigned char code  Display code from BIOS video
  291. *                    function 0x1a.
  292. *        int active_flag     _ACTIVE or _ALTERNATE indicating
  293. *                    whether we are dealing with the
  294. *                    active or alternate adapter.
  295. *
  296. * Description    This function extracts adapter presence information from
  297. *        a display combination code from BIOS function 0x1a.
  298. *
  299. * Result    b_mdpa, b_cga, b_ega, vga_state, b_mcga, or pgc_state
  300. *                    (Depending on which adapter is
  301. *                    indicated by the code).
  302. *
  303. **/
  304.  
  305. static void note_adapter(code,active_flag)
  306. unsigned char code;
  307. int          active_flag;
  308. {
  309.     switch (code)
  310.     {
  311.     case 0x01:  b_mdpa     = SC_MONO;     break;
  312.     case 0x02:  b_cga      = SC_COLOR;    break;
  313.     case 0x04:  b_ega      = SC_COLOR;    break;
  314.     case 0x05:  b_ega      = SC_MONO;     break;
  315.     case 0x06:  pgc_state  = _PRESENT;    break;
  316.  
  317.     case 0x07:
  318.     case 0x08:  vga_state  = active_flag; break;
  319.  
  320.     case 0x0b:
  321.     case 0x0c:  b_mcga     = SC_COLOR;    break;
  322.     }
  323. }
  324.  
  325. /**
  326. *
  327. * Name        adap_present -- Test for Monochrome or Color/Graphics
  328. *                Adapter or emulator
  329. *
  330. * Synopsis    present = adap_present(adapter);
  331. *        int present        1 if present or being emulated,
  332. *                    0 if not.
  333. *        int adapter        0 if testing for Monochrome Adapter,
  334. *                    1 if Color/Graphics Adapter
  335. *
  336. * Description    This function tests for the presence of the IBM
  337. *        Monochrome Display and Printer Adapter or the IBM
  338. *        Color/Graphics Adapter or other device (such as the EGA
  339. *        or PGC) that may be emulating them.
  340. *
  341. *        We do an assignment between the UTINP and UTOUTP calls
  342. *        so that the device has time to properly stabilize
  343. *        when using slow devices with fast processors.
  344. *
  345. * Method    Write a bogus value into the cursor position register of
  346. *        the CRT controller chip, then read it back again.  If
  347. *        the same value is found in the register, then the CRTC
  348. *        must be present; if the value is different, then it must
  349. *        be absent.
  350. *
  351. * Result    present         1 if present or being emulated,
  352. *                    0 if not.
  353. *
  354. **/
  355.  
  356. static int adap_present(adapter)
  357. int adapter;
  358. {
  359.     int      crtc_there;
  360.     char     save_cursor;
  361.     unsigned int port;          /* Address of the CRT controller chip   */
  362.  
  363.     port = (adapter ? 0x03d4 : 0x03b4);
  364.  
  365.     utoutp(port++,0xf);           /* Set cursor register          */
  366.     WAIT
  367.                       /* Save previous contents       */
  368.     save_cursor = (unsigned char) utinp(port);
  369.  
  370.     utoutp(port,0x5a);              /* Set to column 90          */
  371.     WAIT
  372.     crtc_there = (utinp(port) == 0x5a);  /* Read the value back again */
  373.     WAIT
  374.     utoutp(port,save_cursor);          /* Restore previous contents    */
  375.     return crtc_there;
  376. }
  377.  
  378. /**
  379. *
  380. * Name        pgc_present -- Test for IBM Professional Graphics
  381. *                   Controller
  382. *
  383. * Synopsis    present = pgc_present();
  384. *        int present        1 if present, 0 if not.
  385. *
  386. * Description    This function tests for the presence of the IBM
  387. *        Professional Graphics Controller.
  388. *
  389. * Method    Write a bogus value into the supposed PGC, then read it
  390. *        back again.  If the same value is found, then the PGC
  391. *        must be present; if the value is different, then it must
  392. *        be absent.
  393. *
  394. * Result    present         1 if present, 0 if not.
  395. *
  396. **/
  397.  
  398. static int pgc_present()
  399. {
  400.     int  result;
  401.     char save,dummy;
  402.  
  403.     switch (pgc_state)
  404.     {
  405.     case _ABSENT:
  406.         result = 0;
  407.         break;
  408.     case _PRESENT:
  409.         result = 1;
  410.         break;
  411.  
  412.     case _DONT_KNOW:
  413.         save = utpeekb(PGC_PRES_BYTE);  /* Save previous contents */
  414.         WAIT
  415.         utpokeb(PGC_PRES_BYTE,0x5a);    /* Store dummy value      */
  416.         WAIT
  417.         dummy = utpeekb(PGC_PRES_BYTE); /* Read it back again     */
  418.         WAIT
  419.         utpokeb(PGC_PRES_BYTE,save); /* Restore previous contents */
  420.         result = (dummy == 0x5a);
  421.         break;
  422.     }
  423.     return result;
  424. }
  425.  
  426. /**
  427. *
  428. * Name        pgc_emulating -- Test for whether IBM Professional
  429. *            Graphics Controller is emulating the IBM
  430. *            Color/Graphics Adapter
  431. *
  432. * Synopsis    emulating = pgc_emulating();
  433. *        int emulating        SC_COLOR  if PGC emulating the CGA,
  434. *                    SC_HIFUNC if not.
  435. *
  436. * Description    This function tests for whether the IBM Professional
  437. *        Graphics Controller is emulating the IBM Color/Graphics
  438. *        Adapter.
  439. *
  440. * Method    Write a bogus value into the PGC through a memory
  441. *        address, then read it back again through an input port.
  442. *        If the same value is found, then the PGC must be present
  443. *        and in CGA emulation mode; if the value is different,
  444. *        then (if the PGC is indeed present) it must be in
  445. *        high-function graphics mode.
  446. *
  447. * Result    present         SC_COLOR  if PGC emulating the CGA,
  448. *                    SC_HIFUNC if not.
  449. *
  450. **/
  451.  
  452. static int pgc_emulating()
  453. {
  454.     char save,dummy;
  455.  
  456.     save = utpeekb(PGC_IND_BYTE);    /* Save previous contents     */
  457.     WAIT
  458.     utpokeb(PGC_IND_BYTE,0x28);     /* Store dummy value          */
  459.     WAIT
  460.     dummy = (char) utinp(PGC_INDEX);    /* Read it back again          */
  461.     WAIT
  462.     utpokeb(PGC_IND_BYTE,save);     /* Restore previous contents  */
  463.  
  464.     return (dummy == 0x28) ? SC_COLOR : SC_HIFUNC;
  465. }
  466.  
  467. /**
  468. *
  469. * Name        herc -- Sense presence of Hercules monochrome graphics
  470. *            adapter.
  471. *
  472. * Synopsis    present = herc();
  473. *
  474. *        int present        Zero if Hercules adapter absent,
  475. *                    nonzero if present.
  476. *
  477. * Description    This function reports whether the Hercules monochrome
  478. *        graphics adapter is present.
  479. *
  480. * Result    present         Zero if Hercules adapter absent,
  481. *                    nonzero if present.
  482. *
  483. **/
  484.  
  485. static int herc()
  486. {
  487.     unsigned char save;
  488.     unsigned int  i;
  489.     int       result;
  490.  
  491.     result = 0;
  492.     save = (unsigned char) (utinp(0x3ba) & 0x80);
  493.     for (i = 0; i < (unsigned int) 32768L; i++)
  494.     if (save != (unsigned char) (utinp(0x3ba) & 0x80))
  495.     {
  496.         result = 1;
  497.         break;
  498.     }
  499.  
  500.     return result;
  501. }
  502.