home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 198_01 / ibmpc.c < prev    next >
C/C++ Source or Header  |  1990-01-23  |  12KB  |  510 lines

  1. /*
  2.  * The routines in this file provide support for the IBM-PC and other
  3.  * compatible terminals. It goes directly to the graphics RAM to do
  4.  * screen output. It compiles into nothing if not an IBM-PC driver
  5.  * Supported monitor cards include CGA, MONO and EGA.
  6.  */
  7.  
  8. #define    termdef    1            /* don't define "term" external */
  9.  
  10. #include        <stdio.h>
  11. #include    "estruct.h"
  12. #include        "edef.h"
  13.  
  14. #if     IBMPC
  15. #define NROW    43            /* Max Screen size.        */
  16. #define NCOL    80                      /* Edit if you want to.         */
  17. #define    MARGIN    8            /* size of minimim margin and    */
  18. #define    SCRSIZ    64            /* scroll size for extended lines */
  19. #define    NPAUSE    200            /* # times thru update to pause */
  20. #define BEL     0x07                    /* BEL character.               */
  21. #define ESC     0x1B                    /* ESC character.               */
  22. #define    SPACE    32            /* space character        */
  23.  
  24. #define    SCADC    0xb8000000L        /* CGA address of screen RAM    */
  25. #define    SCADM    0xb0000000L        /* MONO address of screen RAM    */
  26. #define SCADE    0xb8000000L        /* EGA address of screen RAM    */
  27.  
  28. #define MONOCRSR 0x0B0D            /* monochrome cursor        */
  29. #define CGACRSR 0x0607            /* CGA cursor            */
  30. #define EGACRSR 0x0709            /* EGA cursor            */
  31.  
  32. #define    CDCGA    0            /* color graphics card        */
  33. #define    CDMONO    1            /* monochrome text card        */
  34. #define    CDEGA    2            /* EGA color adapter        */
  35. #define    CDSENSE    9            /* detect the card type        */
  36.  
  37. #define NDRIVE    3            /* number of screen drivers    */
  38.  
  39. int dtype = -1;                /* current display type        */
  40. char drvname[][8] = {            /* screen resolution names    */
  41.     "CGA", "MONO", "EGA"
  42. };
  43. long scadd;                /* address of screen ram    */
  44. int *scptr[NROW];            /* pointer to screen lines    */
  45. unsigned int sline[NCOL];        /* screen line image        */
  46. int egaexist = FALSE;            /* is an EGA card available?    */
  47. extern union REGS rg;            /* cpu register for use of DOS calls */
  48.  
  49. extern  int     ttopen();               /* Forward references.          */
  50. extern  int     ttgetc();
  51. extern  int     ttputc();
  52. extern  int     ttflush();
  53. extern  int     ttclose();
  54. extern  int     ibmmove();
  55. extern  int     ibmeeol();
  56. extern  int     ibmeeop();
  57. extern  int     ibmbeep();
  58. extern  int     ibmopen();
  59. extern    int    ibmrev();
  60. extern    int    ibmcres();
  61. extern    int    ibmclose();
  62. extern    int    ibmputc();
  63. extern    int    ibmkopen();
  64. extern    int    ibmkclose();
  65.  
  66. #if    COLOR
  67. extern    int    ibmfcol();
  68. extern    int    ibmbcol();
  69.  
  70. int    cfcolor = -1;        /* current forground color */
  71. int    cbcolor = -1;        /* current background color */
  72. int    ctrans[] =        /* ansi to ibm color translation table */
  73.     {0, 4, 2, 6, 1, 5, 3, 7};
  74. #endif
  75.  
  76. /*
  77.  * Standard terminal interface dispatch table. Most of the fields point into
  78.  * "termio" code.
  79.  */
  80. TERM    term    = {
  81.     NROW-1,
  82.         NROW-1,
  83.         NCOL,
  84.         NCOL,
  85.     MARGIN,
  86.     SCRSIZ,
  87.     NPAUSE,
  88.         ibmopen,
  89.         ibmclose,
  90.     ibmkopen,
  91.     ibmkclose,
  92.         ttgetc,
  93.     ibmputc,
  94.         ttflush,
  95.         ibmmove,
  96.         ibmeeol,
  97.         ibmeeop,
  98.         ibmbeep,
  99.     ibmrev,
  100.     ibmcres
  101. #if    COLOR
  102.     , ibmfcol,
  103.     ibmbcol
  104. #endif
  105. };
  106.  
  107. #if    COLOR
  108. ibmfcol(color)        /* set the current output color */
  109.  
  110. int color;    /* color to set */
  111.  
  112. {
  113.     cfcolor = ctrans[color];
  114. }
  115.  
  116. ibmbcol(color)        /* set the current background color */
  117.  
  118. int color;    /* color to set */
  119.  
  120. {
  121.         cbcolor = ctrans[color];
  122. }
  123. #endif
  124.  
  125. ibmmove(row, col)
  126. {
  127.     rg.h.ah = 2;        /* set cursor position function code */
  128.     rg.h.dl = col;
  129.     rg.h.dh = row;
  130.     rg.h.bh = 0;        /* set screen page number */
  131.     int86(0x10, &rg, &rg);
  132. }
  133.  
  134. ibmeeol()    /* erase to the end of the line */
  135.  
  136. {
  137.     unsigned int attr;    /* attribute byte mask to place in RAM */
  138.     unsigned int *lnptr;    /* pointer to the destination line */
  139.     int i;
  140.     int ccol;    /* current column cursor lives */
  141.     int crow;    /*       row    */
  142.  
  143.     /* find the current cursor position */
  144.     rg.h.ah = 3;        /* read cursor position function code */
  145.     rg.h.bh = 0;        /* current video page */
  146.     int86(0x10, &rg, &rg);
  147.     ccol = rg.h.dl;        /* record current column */
  148.     crow = rg.h.dh;        /* and row */
  149.  
  150.     /* build the attribute byte and setup the screen pointer */
  151. #if    COLOR
  152.     if (dtype != CDMONO)
  153.         attr = (((cbcolor & 15) << 4) | (cfcolor & 15)) << 8;
  154.     else
  155.         attr = 0x0700;
  156. #else
  157.     attr = 0x0700;
  158. #endif
  159.     lnptr = &sline[0];
  160.     for (i=0; i < term.t_ncol; i++)
  161.         *lnptr++ = SPACE | attr;
  162.  
  163.     if (flickcode && (dtype == CDCGA)) {
  164.         /* wait for vertical retrace to be off */
  165.         while ((inp(0x3da) & 8))
  166.             ;
  167.     
  168.         /* and to be back on */
  169.         while ((inp(0x3da) & 8) == 0)
  170.             ;
  171.     }            
  172.  
  173.     /* and send the string out */
  174.     movmem(&sline[0], scptr[crow]+ccol, (term.t_ncol-ccol)*2);
  175.  
  176. }
  177.  
  178. ibmputc(ch)    /* put a character at the current position in the
  179.            current colors */
  180.  
  181. int ch;
  182.  
  183. {
  184.     rg.h.ah = 14;        /* write char to screen with current attrs */
  185.     rg.h.al = ch;
  186. #if    COLOR
  187.     if (dtype != CDMONO)
  188.         rg.h.bl = cfcolor;
  189.     else
  190.         rg.h.bl = 0x07;
  191. #else
  192.     rg.h.bl = 0x07;
  193. #endif
  194.     int86(0x10, &rg, &rg);
  195. }
  196.  
  197. ibmeeop()
  198. {
  199.     int attr;        /* attribute to fill screen with */
  200.  
  201.     rg.h.ah = 6;        /* scroll page up function code */
  202.     rg.h.al = 0;        /* # lines to scroll (clear it) */
  203.     rg.x.cx = 0;        /* upper left corner of scroll */
  204.     rg.x.dx = (term.t_nrow << 8) | (term.t_ncol - 1);
  205.                 /* lower right corner of scroll */
  206. #if    COLOR
  207.     if (dtype != CDMONO)
  208.         attr = ((ctrans[gbcolor] & 15) << 4) | (ctrans[gfcolor] & 15);
  209.     else
  210.         attr = 0;
  211. #else
  212.     attr = 0;
  213. #endif
  214.     rg.h.bh = attr;
  215.     int86(0x10, &rg, &rg);
  216. }
  217.  
  218. ibmrev(state)        /* change reverse video state */
  219.  
  220. int state;    /* TRUE = reverse, FALSE = normal */
  221.  
  222. {
  223.     /* This never gets used under the IBM-PC driver */
  224. }
  225.  
  226. ibmcres(res)    /* change screen resolution */
  227.  
  228. char *res;    /* resolution to change to */
  229.  
  230. {
  231.     int i;        /* index */
  232.  
  233.     for (i = 0; i < NDRIVE; i++)
  234.         if (strcmp(res, drvname[i]) == 0) {
  235.             scinit(i);
  236.             return(TRUE);
  237.         }
  238.     return(FALSE);
  239. }
  240.  
  241. spal(dummy)    /* reset the pallette registers */
  242. char *dummy;
  243. {
  244.     /* nothin here now..... */
  245. }
  246.  
  247. ibmbeep()
  248. {
  249. #if    MWC86
  250.     putcnb(BEL);
  251. #else
  252.     bdos(6, BEL, 0);
  253. #endif
  254. }
  255.  
  256. ibmopen()
  257. {
  258.     scinit(CDSENSE);
  259.     revexist = TRUE;
  260.         ttopen();
  261. }
  262.  
  263. ibmclose()
  264.  
  265. {
  266. #if    COLOR
  267.     ibmfcol(7);
  268.     ibmbcol(0);
  269. #endif
  270.     /* if we had the EGA open... close it */
  271.     if (dtype == CDEGA)
  272.         egaclose();
  273.  
  274.     ttclose();
  275. }
  276.  
  277. ibmkopen()    /* open the keyboard */
  278.  
  279. {
  280. }
  281.  
  282. ibmkclose()    /* close the keyboard */
  283.  
  284. {
  285. }
  286.  
  287. scinit(type)    /* initialize the screen head pointers */
  288.  
  289. int type;    /* type of adapter to init for */
  290.  
  291. {
  292.     union {
  293.         long laddr;    /* long form of address */
  294.         int *paddr;    /* pointer form of address */
  295.     } addr;
  296.     int i;
  297.  
  298.     /* if asked...find out what display is connected */
  299.     if (type == CDSENSE)
  300.         type = getboard();
  301.  
  302.     /* if we have nothing to do....don't do it */
  303.     if (dtype == type)
  304.         return(TRUE);
  305.  
  306.     /* if we try to switch to EGA and there is none, don't */
  307.     if (type == CDEGA && egaexist != TRUE)
  308.         return(FALSE);
  309.  
  310.     /* if we had the EGA open... close it */
  311.     if (dtype == CDEGA)
  312.         egaclose();
  313.  
  314.     /* and set up the various parameters as needed */
  315.     switch (type) {
  316.         case CDMONO:    /* Monochrome adapter */
  317.                 scadd = SCADM;
  318.                 newsize(TRUE, 25);
  319.                 break;
  320.  
  321.         case CDCGA:    /* Color graphics adapter */
  322.                 scadd = SCADC;
  323.                 newsize(TRUE, 25);
  324.                 break;
  325.  
  326.         case CDEGA:    /* Enhanced graphics adapter */
  327.                 scadd = SCADE;
  328.                 egaopen();
  329.                 newsize(TRUE, 43);
  330.                 break;
  331.     }
  332.  
  333.     /* reset the $sres environment variable */
  334.     strcpy(sres, drvname[type]);
  335.     dtype = type;
  336.  
  337.     /* initialize the screen pointer array */
  338.     for (i = 0; i < NROW; i++) {
  339.         addr.laddr = scadd + (long)(NCOL * i * 2);
  340.         scptr[i] = addr.paddr;
  341.     }
  342.     return(TRUE);
  343. }
  344.  
  345. /* getboard:    Determine which type of display board is attached.
  346.         Current known types include:
  347.  
  348.         CDMONO    Monochrome graphics adapter
  349.         CDCGA    Color Graphics Adapter
  350.         CDEGA    Extended graphics Adapter
  351. */
  352.  
  353. /* getbaord:    Detect the current display adapter
  354.         if MONO        set to MONO
  355.            CGA        set to CGA    EGAexist = FALSE
  356.            EGA        set to CGA    EGAexist = TRUE
  357. */
  358.  
  359. int getboard()
  360.  
  361. {
  362.     int type;    /* board type to return */
  363.  
  364.     type = CDCGA;
  365.     int86(0x11, &rg, &rg);
  366.     if ((((rg.x.ax >> 4) & 3) == 3))
  367.         type = CDMONO;
  368.  
  369.     /* test if EGA present */
  370.     rg.x.ax = 0x1200;
  371.     rg.x.bx = 0xff10;
  372.     int86(0x10,&rg, &rg);        /* If EGA, bh=0-1 and bl=0-3 */
  373.     egaexist = !(rg.x.bx & 0xfefc);    /* Yes, it's EGA */
  374.     return(type);
  375. }
  376.  
  377. egaopen()    /* init the computer to work with the EGA */
  378.  
  379. {
  380.     /* put the beast into EGA 43 row mode */
  381.     rg.x.ax = 3;
  382.     int86(16, &rg, &rg);
  383.  
  384.     rg.h.ah = 17;        /* set char. generator function code */
  385.     rg.h.al = 18;        /*  to 8 by 8 double dot ROM         */
  386.     rg.h.bl = 0;        /* block 0                           */
  387.     int86(16, &rg, &rg);
  388.  
  389.     rg.h.ah = 18;        /* alternate select function code    */
  390.     rg.h.al = 0;        /* clear AL for no good reason       */
  391.     rg.h.bl = 32;        /* alt. print screen routine         */
  392.     int86(16, &rg, &rg);
  393.  
  394.     rg.h.ah = 1;        /* set cursor size function code */
  395.     rg.x.cx = 0x0607;    /* turn cursor on code */
  396.     int86(0x10, &rg, &rg);
  397.  
  398.     outp(0x3d4, 10);    /* video bios bug patch */
  399.     outp(0x3d5, 6);
  400. }
  401.  
  402. egaclose()
  403.  
  404. {
  405.     /* put the beast into 80 column mode */
  406.     rg.x.ax = 3;
  407.     int86(16, &rg, &rg);
  408. }
  409.  
  410. scwrite(row, outstr, forg, bacg)    /* write a line out*/
  411.  
  412. int row;    /* row of screen to place outstr on */
  413. char *outstr;    /* string to write out (must be term.t_ncol long) */
  414. int forg;    /* forground color of string to write */
  415. int bacg;    /* background color */
  416.  
  417. {
  418.     unsigned int attr;    /* attribute byte mask to place in RAM */
  419.     unsigned int *lnptr;    /* pointer to the destination line */
  420.     int i;
  421.  
  422.     /* build the attribute byte and setup the screen pointer */
  423. #if    COLOR
  424.     if (dtype != CDMONO)
  425.         attr = (((ctrans[bacg] & 15) << 4) | (ctrans[forg] & 15)) << 8;
  426.     else
  427.         attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
  428. #else
  429.     attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
  430. #endif
  431.     lnptr = &sline[0];
  432.     for (i=0; i<term.t_ncol; i++)
  433.         *lnptr++ = (outstr[i] & 255) | attr;
  434.  
  435.     if (flickcode && (dtype == CDCGA)) {
  436.         /* wait for vertical retrace to be off */
  437.         while ((inp(0x3da) & 8))
  438.             ;
  439.     
  440.         /* and to be back on */
  441.         while ((inp(0x3da) & 8) == 0)
  442.             ;
  443.     }
  444.  
  445.     /* and send the string out */
  446.     movmem(&sline[0], scptr[row],term.t_ncol*2);
  447. }
  448.  
  449. #if    MENUS
  450.  
  451. menuwrite(row, col, outstr, len, forg, bacg)    /* write a line out*/
  452.  
  453. int row;    /* row of screen to place outstr on */
  454. int col;    /* col of screen */
  455. char *outstr;    /* string to write out */
  456. int len;    /* length of string */
  457. int forg;    /* forground color of string to write */
  458. int bacg;    /* background color */
  459.  
  460. {
  461.     unsigned int attr;    /* attribute byte mask to place in RAM */
  462.     unsigned int *lnptr;    /* pointer to the destination line */
  463.     int i;
  464.  
  465.     /* build the attribute byte and setup the screen pointer */
  466. #if    COLOR
  467.     if (dtype != CDMONO)
  468.         attr = (((ctrans[bacg] & 15) << 4) | (ctrans[forg] & 15)) << 8;
  469.     else
  470.         attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
  471. #else
  472.     attr = (((bacg & 15) << 4) | (forg & 15)) << 8;
  473. #endif
  474.     lnptr = &sline[0];
  475.     for (i=0; i<len; i++)
  476.         *lnptr++ = (outstr[i] & 255) | attr;
  477.  
  478.     if (flickcode && (dtype == CDCGA)) {
  479.         /* wait for vertical retrace to be off */
  480.         while ((inp(0x3da) & 8))
  481.             ;
  482.     
  483.         /* and to be back on */
  484.         while ((inp(0x3da) & 8) == 0)
  485.             ;
  486.     }
  487.  
  488.     /* and send the string out */
  489.     movmem(&sline[0], scptr[row]+col, len*2);
  490. }
  491.  
  492. #endif
  493.  
  494. #if    FLABEL
  495. fnclabel(f, n)        /* label a function key */
  496.  
  497. int f,n;    /* default flag, numeric argument [unused] */
  498.  
  499. {
  500.     /* on machines with no function keys...don't bother */
  501.     return(TRUE);
  502. }
  503. #endif
  504. #else
  505. ibmhello()
  506. {
  507. }
  508. #endif
  509.  
  510.