home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c185 / 2.ddi / OWLSRC.EXE / CSCAPE / SOURCE / PCMODE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-06  |  9.7 KB  |  398 lines

  1. /*
  2.     pcmode.c
  3.  
  4.     % pc_ mode routines
  5.  
  6.     7/9/88  by Ted.
  7.  
  8.     OWL 1.1
  9.     Copyright (c) 1988, by Oakland Group, Inc.
  10.     ALL RIGHTS RESERVED.
  11.  
  12.     Revision History:
  13.     -----------------
  14.      1/31/89 ted    Changed pc_ModeSupport so it supports mode 7 even when an
  15.                     EGA/VGA is installed.
  16.      6/29/89 ted    Converted pcinfo.asm to C; moved it here from pcinfo.asm.
  17.      7/12/89 ted    Added OSTATIC's and '_func' macros.
  18.      7/17/89 ted    Fixed newbios_modesupport: modebyte = 40 +, not 0x40 +.
  19.      8/01/89 ted    Moved pc_init/restoremode to pcdisp.c.
  20. */
  21.  
  22. #include "pcpriv.h"
  23.  
  24. OSTATIC boolean DIGPRIV ega_modesupport(_arg1(int));
  25. OSTATIC boolean DIGPRIV ega_ismono(_arg1(byte));
  26. OSTATIC boolean DIGPRIV newbios(_arg1(void));
  27. OSTATIC boolean DIGPRIV newbios_modesupport(_arg1(int));
  28. OSTATIC void    DIGPRIV pc_sethflag(_arg1(byte));
  29. OSTATIC boolean DIGPRIV vga_getinfo(_arg1(byte *bufaddr));
  30. OSTATIC boolean DIGPRIV ram_testword(_arg2(unsigned, unsigned));
  31. OSTATIC boolean DIGPRIV cursport_test(_arg1(int));
  32. /* -------------------------------------------------------------------------- */
  33.  
  34. void pc_SetMode(mode)
  35.     int mode;
  36. /*
  37.     Sets the current video mode of the display adapter to the given mode. 
  38.     Clears the screen in the new mode.
  39. */
  40. {
  41.     OREGS regs;
  42.     
  43.     switch (mode) {
  44.     default:
  45.         if (mode == 0x07) {
  46.             pc_sethflag(PCHFLAG_MONO);
  47.             if (pc_IsHerc()) {    /* Restore herc card to text mode */
  48.                 herc_settmode();
  49.             }
  50.         }
  51.         else {
  52.             pc_sethflag(PCHFLAG_COLO);
  53.         }
  54.         if (mode == PCMODE_CPQ40) {
  55.             mode = 0x40;
  56.         }
  57.         regs.h.al = (byte)mode;
  58.         regs.h.ah = VIDINT_SETVM;
  59.         regs.h.bh = TEXT_RPAGE;
  60.         oakint86(BIOS_VIDINT, ®s);
  61.         break;
  62.     case PCMODE_EGA43:
  63.     case PCMODE_VGA50:
  64.         pc_sethflag(PCHFLAG_COLO);
  65.  
  66.         /* In case this is a VGA, set the proper number of scanlines */
  67.         /* (EGA will not respond to this call and stay at 350) */
  68.         regs.h.ah = VIDINT_ALTSEL;        /* alternate select */
  69.         regs.h.bl = ALTSEL_SETLINES;        /* set # of scanlines */
  70.         if (mode == PCMODE_EGA43) {
  71.             regs.h.al = SETLINES_350;
  72.         }
  73.         else {
  74.             regs.h.al = SETLINES_400;
  75.         }
  76.         oakint86(BIOS_VIDINT, ®s);
  77.  
  78.         regs.h.al = 0x03;            /* These modes are based on mode 3 */
  79.         regs.h.bh = TEXT_RPAGE;
  80.         regs.h.ah = VIDINT_SETVM;            /* reset video mode (see ega docs) */
  81.         oakint86(BIOS_VIDINT, ®s);
  82.  
  83.         regs.h.ah = VIDINT_CHARGEN;        /* character generator command */
  84.         regs.h.al = CHARGEN_ROM8X8;        /* choose 8x8 cell */
  85.         regs.h.bl = 0;
  86.         oakint86(BIOS_VIDINT, ®s); /* setup 43/50 line */
  87.         
  88.         regs.h.ah = VIDINT_ALTSEL;        /* alternate select */
  89.         regs.h.bl = ALTSEL_NEWPRTSCR;        /* new print screen routine */
  90.         oakint86(BIOS_VIDINT, ®s);    /* setup new prt scrn */
  91.  
  92.         break;
  93.     case PCMODE_HERC0:
  94.     case PCMODE_HERC1:
  95.         herc_setgmode(mode != PCMODE_HERC0);
  96.         break;
  97.     }
  98. }
  99. /* -------------------------------------------------------------------------- */
  100.  
  101. int pc_GetMode()
  102. /*
  103.     effects:    gets the current video mode of the display adapter.
  104.     returns:    bits 0-7 return the current video mode.
  105.                 bits 8-15 returns the video display width.
  106. */
  107. {
  108.     OREGS regs;
  109.     int mode;
  110.     byte rows;
  111.  
  112.     regs.h.ah = VIDINT_GETVM;
  113.     oakint86(BIOS_VIDINT, ®s);
  114.     mode = (int)(regs.h.al & 0x7F);    /* knock out hi noclear bit */
  115.  
  116. /* Check for 43 or 50 line mode */
  117.     if (mode == 0x03) {
  118.         if (pc_IsEGA()) {
  119.             ram_segtomem(0x40, 0x84, &rows, 1);    /* Get Rows from BIOS data area */
  120.             if (rows == 43-1) mode = PCMODE_EGA43;
  121.             if (rows == 50-1) mode = PCMODE_VGA50;
  122.         }
  123.     }
  124. /* Check for herc graphics mode */
  125.     if (mode == 0x05 || mode == 0x06 || mode == 0x07) {
  126.         if (pc_IsHerc()) {
  127.             if (herc_getlines() > 0xF00) {
  128.                 ram_segtomem(0x40, 0x49, &rows, 1);    /* Get vidmode from BIOS */
  129.                 if (rows != 5) {
  130.                     mode = PCMODE_HERC0;
  131.                 }
  132.                 else mode = PCMODE_HERC1;
  133.             }
  134.         }
  135.     }
  136. /* Check for Compaq mode 40 */
  137.     if (mode == 0x40) {
  138.         mode = PCMODE_CPQ40;
  139.     }
  140.     return(mode);
  141. }
  142. /* -------------------------------------------------------------------------- */
  143.  
  144. boolean pc_ModeSupport(mode)
  145.     int mode;
  146. /* Return TRUE if mode is supported on current hardware */
  147. {
  148.     if (mode == PCMODE_HERC0 || mode == PCMODE_HERC1) {
  149.         return(pc_IsHerc());
  150.     }
  151.     if (mode == PCMODE_CPQ40) {
  152.         return(pc_IsCompaqPlasma() && !pc_IsEGA());
  153.     }
  154.     if (newbios()) {    /* vga/mcga bios gives supported modes */
  155.         if (newbios_modesupport(mode)) {
  156.             return(TRUE);
  157.         }
  158.     }
  159.     if (pc_IsEGA()) {
  160.         if (ega_modesupport(mode)) {
  161.             return(TRUE);
  162.         }
  163.     }
  164.     switch(mode) {
  165.     case 0x02:
  166.     case 0x03:
  167.     case 0x04:
  168.     case 0x05:
  169.     case 0x06:
  170.         return(pc_IsCGA());
  171.     case 0x07:
  172.         return(pc_IsMDA());
  173.     default:
  174.         return(FALSE);
  175.     }
  176. }
  177. /* -------------------------------------------------------------------------- */
  178.  
  179. boolean pc_IsHerc()
  180. {
  181.     return(herc_present());
  182. }
  183. /* -------------------------------------------------------------------------- */
  184.  
  185. boolean pc_IsMDA()
  186. {
  187.     return(ram_testword(VID_MONOADDR, 4000) && cursport_test(VID_MDAPORT));
  188. }
  189. /* -------------------------------------------------------------------------- */
  190.  
  191. boolean pc_IsCGA()
  192. {
  193.     return(ram_testword(VID_CGAADDR, 16000) && cursport_test(VID_CGAPORT));
  194. }
  195. /* -------------------------------------------------------------------------- */
  196.  
  197. boolean pc_IsEGA()
  198. {
  199.     if (!ega_ismono(1)) {
  200.         return(TRUE);                    /* ega is present, not mono */
  201.     }
  202.     else {
  203.         if (ega_ismono(0)) {
  204.             return(TRUE);                /* ega is present */
  205.         }
  206.     }
  207.     return(FALSE);                        /* ega not present */
  208. }
  209. /* -------------------------------------------------------------------------- */
  210.  
  211. boolean pc_IsMCGA()
  212. {
  213.     return(newbios_modesupport(0x13));
  214. }
  215. /* -------------------------------------------------------------------------- */
  216.  
  217. boolean pc_IsVGA()
  218. {
  219.     return(newbios_modesupport(0x12));
  220. }
  221. /* -------------------------------------------------------------------------- */
  222.  
  223. boolean pc_IsCompaqPlasma()
  224. {
  225.     OREGS regs;
  226.  
  227.     if (!pc_IsCompaq()) {
  228.         return(FALSE);
  229.     }
  230.     regs.h.ah = VIDINT_CPQINFO;            /* alternate select function */
  231.     regs.h.al = 3;
  232.     oakint86(BIOS_VIDINT, ®s);
  233.  
  234.     return((regs.h.cl & CPQINFO_PLASMABIT) != 0);
  235. }
  236. /* -------------------------------------------------------------------------- */
  237. /* -------------------------------------------------------------------------- */
  238.  
  239. static void DIGPRIV pc_sethflag(vf)
  240.     byte vf;
  241. {
  242.     byte hf;
  243.  
  244. /* Put Hardware Equip Flag Video bits to BIOS data area */
  245.     ram_segtomem(0x40, 0x10, &hf, 1);
  246.     hf &= ~0x30;
  247.     hf |= vf & 0x30;
  248.     ram_memtoseg(0x40, 0x10, &hf, 1);
  249. }
  250. /* -------------------------------------------------------------------------- */
  251.  
  252. static boolean DIGPRIV ega_ismono(inbh)
  253.     byte inbh;
  254. {
  255.     OREGS regs;
  256.  
  257.     regs.h.ah = VIDINT_ALTSEL;            /* alternate select function */
  258.     regs.h.bl = ALTSEL_GETINFO;            /* return ega info */
  259.     regs.h.bh = inbh;
  260.     oakint86(BIOS_VIDINT, ®s);
  261.  
  262.     return(regs.h.bh == 1);
  263. }
  264. /* -------------------------------------------------------------------------- */
  265.  
  266. static boolean DIGPRIV ega_modesupport(mode)
  267.     int mode;
  268. {
  269.     switch(mode) {
  270.     case 0x02:
  271.     case 0x03:
  272.     case 0x04:
  273.     case 0x05:
  274.     case 0x06:
  275.     case 0x0D:
  276.     case 0x0E:
  277.     case 0x10:
  278.     case PCMODE_EGA43:
  279.         return(!ega_ismono(0));
  280.     case 0x07:
  281.     case 0x0F:
  282.         return(ega_ismono(0));
  283.     default:
  284.         return(FALSE);
  285.     }
  286. }
  287. /* -------------------------------------------------------------------------- */
  288.  
  289. static boolean DIGPRIV newbios()
  290. {
  291.     byte info[0x50];
  292.  
  293.     return(vga_getinfo(info));
  294. }
  295. /* -------------------------------------------------------------------------- */
  296.  
  297. static boolean DIGPRIV newbios_modesupport(mode)
  298.     int mode;
  299. {
  300.     byte info[0x50];
  301.     unsigned modebit;
  302.     int modebyte;
  303.  
  304.     if (vga_getinfo(info)) {
  305.         if (mode == PCMODE_EGA43 || mode == PCMODE_VGA50) mode = 0x03;
  306.         if (mode <= 0x13) {
  307.             modebyte = 0x40 + mode/8;
  308.             modebit = 1 << (mode % 8);
  309.             return((boolean)(info[modebyte] & modebit));
  310.         }
  311.     }
  312.     return(FALSE);
  313. }
  314. /* -------------------------------------------------------------------------- */
  315.  
  316. static boolean DIGPRIV vga_getinfo(buf)
  317.     byte *buf;
  318. /*
  319.     Load up a 50-byte buffer with vga mode info.
  320. */
  321. {
  322.     OREGS regs;
  323.     unsigned seg, offs;
  324.     
  325.     /* Call BIOS get-mode-info function to read info into buf */
  326.     regs.a.esdx = buf;
  327.     regs.x.di = regs.x.dx;
  328.     regs.h.ah = VIDINT_MODEINFO;        
  329.     regs.h.al = 0;        
  330.     regs.x.bx = 0;
  331.     oakint86es(BIOS_VIDINT, ®s, 0x40);
  332.  
  333.     if (regs.h.al == VIDINT_MODEINFO && regs.x.bx == 0) {
  334.         /* Move extra info into end of buf using pointer from start of buf */
  335.         offs = ((unsigned short *) buf)[0];
  336.         seg  = ((unsigned short *) buf)[1];
  337.         ram_segtomem(seg, offs, &buf[0x40], 0x10);
  338.         return(TRUE);
  339.     }
  340.     else return(FALSE);
  341. }
  342. /* -------------------------------------------------------------------------- */
  343. #define TESTVAL        0x56D4
  344.  
  345. static boolean DIGPRIV ram_testword(seg, offs)
  346.     unsigned seg;
  347.     unsigned offs;
  348. {
  349.     unsigned saveword, testword, testval;
  350.  
  351.     testval = TESTVAL;
  352.  
  353.     ram_segtomem(seg, offs, (byte *)&saveword, 2);
  354.     if (saveword == testval) testval++;
  355.     testword = testval;
  356.     ram_memtoseg(seg, offs, (byte *)&testword, 2);
  357.     testword = 0;        /* kill time, settle bus */
  358.     ram_segtomem(seg, offs, (byte *)&testword, 2);
  359.  
  360.     if (testword == testval) {
  361.         ram_memtoseg(seg, offs, (byte *)&saveword, 2);
  362.         return(TRUE);
  363.     }
  364.     else return(FALSE);
  365. }
  366. /* -------------------------------------------------------------------------- */
  367. #define TESTPOS    4
  368.  
  369. static boolean DIGPRIV cursport_test(port)
  370.     int port;
  371. {
  372.     int oaddr, taddr, tpos;
  373.  
  374.     tpos = TESTPOS;
  375.  
  376.     outp(port, 0x0F);
  377.     oaddr = inp(port+1);
  378.  
  379.     if (oaddr == tpos) tpos++;
  380.     taddr = tpos;
  381.  
  382.     outp(port, 0x0F);
  383.     outp(port+1, taddr);
  384.  
  385.     taddr = 0;
  386.     outp(port, 0x0F);
  387.     taddr = inp(port+1);
  388.  
  389.     if (taddr == tpos) {
  390.         outp(port, 0x0F);
  391.         outp(port+1, oaddr);
  392.         return(TRUE);
  393.     }
  394.     else return(FALSE);
  395. }
  396. /* -------------------------------------------------------------------------- */
  397.  
  398.