home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / VILE327.ZIP / VILE327.TAR / vile3.27 / ibmpc.c < prev    next >
Text File  |  1992-12-14  |  12KB  |  553 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.  * Modified by Pete Ruczynski (pjr) for auto-sensing and selection of
  7.  * display type.
  8.  *
  9.  * $Log: ibmpc.c,v $
  10.  * Revision 1.10  1992/08/20  23:40:48  foxharp
  11.  * typo fixes -- thanks, eric
  12.  *
  13.  * Revision 1.9  1992/07/08  08:23:57  foxharp
  14.  * set screen attributes correctly in ibmeeop()
  15.  *
  16.  * Revision 1.8  1992/07/01  17:06:32  foxharp
  17.  * pgf cleanup (in general I can't leave well enough alone...).  somewhere
  18.  * along the way I made it work properly -- I think the problem was a missing
  19.  * page number in ibmputc() -- but it might have been a badly calculated
  20.  * attribute byte somewhere else...
  21.  *
  22.  * Revision 1.7  1992/06/25  23:00:50  foxharp
  23.  * changes for dos/ibmpc
  24.  *
  25.  * Revision 1.4  1991/09/10  01:19:35  pgf
  26.  * re-tabbed, and moved ESC and BEL to estruct.h
  27.  *
  28.  * Revision 1.3  1991/08/07  12:35:07  pgf
  29.  * added RCS log messages
  30.  *
  31.  * revision 1.2
  32.  * date: 1990/10/01 12:24:47;
  33.  * changed newsize to newscreensize
  34.  * 
  35.  * revision 1.1
  36.  * date: 1990/09/21 10:25:27;
  37.  * initial vile RCS revision
  38.  */
  39.  
  40. #define    termdef    1            /* don't define "term" external */
  41.  
  42. #include        <stdio.h>
  43. #include        "estruct.h"
  44. #include        "edef.h"
  45.  
  46.  
  47. #if     IBMPC
  48.  
  49. #define NROW    50            /* Max Screen size.        */
  50. #define NCOL    80                      /* Edit if you want to.         */
  51. #define    MARGIN    8            /* size of minimim margin and    */
  52. #define    SCRSIZ    64            /* scroll size for extended lines */
  53. #define    NPAUSE    200            /* # times thru update to pause */
  54. #define    SPACE    32            /* space character        */
  55.  
  56. #define    SCADC    0xb8000000L        /* CGA address of screen RAM    */
  57. #define    SCADM    0xb0000000L        /* MONO address of screen RAM    */
  58. #define SCADE    0xb8000000L        /* EGA address of screen RAM    */
  59.  
  60. #define MONOCRSR 0x0B0D            /* monochrome cursor        */
  61. #define CGACRSR 0x0607            /* CGA cursor            */
  62. #define EGACRSR 0x0709            /* EGA cursor            */
  63.  
  64. #define NDRIVE    4            /* number of screen drivers    upped to 4 (vga) */
  65.  
  66.  
  67. int dtype = -1;                /* current display type        */
  68. char drvname[][8] = {            /* screen resolution names    */
  69.     "CGA", "MONO", "EGA", "VGA"
  70. };
  71. long scadd;                /* address of screen ram    */
  72. short *scptr[NROW];            /* pointer to screen lines    */
  73. unsigned short sline[NCOL];        /* screen line image        */
  74. int egaexist = FALSE;            /* is an EGA card available?    */
  75. union REGS rg;                /* cpu register for use of DOS calls */
  76.  
  77. extern  void     ttopen();               /* Forward references.          */
  78. extern  int     ttgetc();
  79. extern  void     ttputc();
  80. extern  void     ttflush();
  81. extern  void     ttclose();
  82. extern  int     ibmmove();
  83. extern  int     ibmeeol();
  84. extern  int     ibmeeop();
  85. extern  int     ibmbeep();
  86. extern  int     ibmopen();
  87. extern    int     ibmrev();
  88. extern    int        ibmcres();
  89. extern    int        ibmclose();
  90. extern    int        ibmputc();
  91. extern    int        ibmkopen();
  92. extern    int        ibmkclose();
  93.  
  94. #if    COLOR
  95. extern    int    ibmfcol();
  96. extern    int    ibmbcol();
  97.  
  98. int    cfcolor = -1;        /* current forground color */
  99. int    cbcolor = -1;        /* current background color */
  100. int    ctrans[] =        /* ansi to ibm color translation table */
  101.     {0, 4, 2, 6, 1, 5, 3, 7};
  102. #endif
  103.  
  104. int ibmtype;        /* pjr - what to do about screen resolution */
  105.  
  106. /*
  107.  * Standard terminal interface dispatch table. Most of the fields point into
  108.  * "termio" code.
  109.  */
  110. TERM    term    = {
  111.         NROW-1,
  112.         NROW-1,
  113.         NCOL,
  114.         NCOL,
  115.         MARGIN,
  116.         SCRSIZ,
  117.         NPAUSE,
  118.         ibmopen,
  119.         ibmclose,
  120.         ibmkopen,
  121.         ibmkclose,
  122.         ttgetc,
  123.         ibmputc,
  124.         ttflush,
  125.         ibmmove,
  126.         ibmeeol,
  127.         ibmeeop,
  128.         ibmbeep,
  129.         ibmrev,
  130.         ibmcres,
  131. #if    COLOR
  132.         ibmfcol,
  133.         ibmbcol,
  134. #endif
  135.     NULL
  136. };
  137.  
  138. #if    COLOR
  139. ibmfcol(color)        /* set the current output color */
  140. int color;    /* color to set */
  141. {
  142.         cfcolor = ctrans[color];
  143. }
  144.  
  145. ibmbcol(color)        /* set the current background color */
  146. int color;    /* color to set */
  147. {
  148.         cbcolor = ctrans[color];
  149. }
  150. #endif
  151.  
  152. ibmmove(row, col)
  153. {
  154.     rg.h.ah = 2;        /* set cursor position function code */
  155.     rg.h.dl = col;
  156.     rg.h.dh = row;
  157.     rg.h.bh = 0;        /* set screen page number */
  158.     int86(0x10, &rg, &rg);
  159. }
  160.  
  161. /* erase to the end of the line */
  162. ibmeeol()
  163. {
  164.     unsigned short *lnptr;    /* pointer to the destination line */
  165.     int i;
  166.     int ccol,crow;    /* current column,row for cursor */
  167.  
  168.     /* find the current cursor position */
  169.     rg.h.ah = 3;        /* read cursor position function code */
  170.     rg.h.bh = 0;        /* current video page */
  171.     int86(0x10, &rg, &rg);
  172.     ccol = rg.h.dl;        /* record current column */
  173.     crow = rg.h.dh;        /* and row */
  174.  
  175.     scwrite(crow, ccol, term.t_ncol-ccol, NULL, gfcolor, gbcolor);
  176.  
  177. }
  178.  
  179. /* put a character at the current position in the current colors */
  180. ibmputc(ch)
  181. int ch;
  182. {
  183.     rg.h.ah = 14;        /* write char to screen with current attrs */
  184.     rg.h.al = ch;
  185. #if    COLOR
  186.     if (dtype != CDMONO)
  187.         rg.h.bl = cfcolor;
  188.     else
  189. #endif
  190.      rg.h.bl = 0x07;
  191.     rg.h.bh = 0;        /* current video page */
  192.     int86(0x10, &rg, &rg);
  193.  
  194. }
  195.  
  196. ibmeeop()
  197. {
  198.     int attr;        /* attribute to fill screen with */
  199.  
  200.     rg.h.ah = 6;        /* scroll page up function code */
  201.     rg.h.al = 0;        /* # lines to scroll (clear it) */
  202.     rg.x.cx = 0;        /* upper left corner of scroll */
  203.     rg.h.dh = term.t_nrow;  /* lower right corner of scroll */
  204.     rg.h.dl = term.t_ncol - 1;
  205. #if    COLOR
  206.     if (dtype != CDMONO)
  207.         attr = ((ctrans[gbcolor] & 15) << 4) | (ctrans[gfcolor] & 15);
  208.     else
  209. #endif
  210.      attr = 0x07;
  211.     rg.h.bh = attr;
  212.     int86(0x10, &rg, &rg);
  213. }
  214.  
  215.  
  216. ibmrev(state)        /* change reverse video state */
  217. int state;    /* TRUE = reverse, FALSE = normal */
  218. {
  219.     /* This never gets used under the IBM-PC driver */
  220. }
  221.  
  222.  
  223. ibmcres(res)    /* change screen resolution */
  224. int res;    /* resolution to change to */
  225. {
  226.     int i;        /* index */
  227.  
  228.     for (i = 0; i < NDRIVE; i++)
  229.         if (strcmp(drvname[res], drvname[i]) == 0) {
  230.             scinit(i);
  231.             return(TRUE);
  232.         }
  233.     return(FALSE);
  234. }
  235.  
  236. void
  237. spal()    /* reset the palette registers */
  238. {
  239.     /* nothing here now..... */
  240. }
  241.  
  242. ibmbeep()
  243. {
  244. #if    MWC86
  245.     putcnb(BEL);
  246. #else
  247.     bdos(6, BEL, 0);    /* annoying!! */
  248. #endif
  249. }
  250.  
  251. ibmopen()
  252. {
  253.     scinit(ibmtype);
  254.     revexist = TRUE;
  255.         ttopen();
  256. }
  257.  
  258. ibmclose()
  259.  
  260. {
  261. #if    COLOR
  262.     ibmfcol(7);
  263.     ibmbcol(0);
  264. #endif
  265.     if (dtype == CDEGA) /* if we had the EGA open... close it */
  266.         egaclose();
  267.     else if (dtype == CDVGA) /* if we had the VGA open... close it */
  268.         vgaclose();
  269. }
  270.  
  271. ibmkopen()    /* open the keyboard */
  272. {
  273. }
  274.  
  275. ibmkclose()    /* close the keyboard */
  276. {
  277. }
  278.  
  279. scinit(type)    /* initialize the screen head pointers */
  280. int type;    /* type of adapter to init for */
  281. {
  282.     union {
  283.         long laddr;    /* long form of address */
  284.         short *paddr;    /* pointer form of address */
  285.     } addr;
  286.     int i;
  287.  
  288.     /* if asked...find out what display is connected */
  289.     if (type == CDSENSE)
  290.         type = getboard();
  291.     else
  292.         /* otherwise set up params as requested */
  293.         type = setboard(type);
  294.  
  295.     /* if we have nothing to do....don't do it */
  296.     if (dtype == type)
  297.         return(TRUE);
  298.  
  299.     /* if we try to switch to EGA and there is none, don't */
  300.     if ((type != CDVGA) && (type == CDEGA && egaexist != TRUE))
  301.         return(FALSE);
  302.  
  303.     if (dtype == CDEGA) /* if we had the EGA open... close it */
  304.         egaclose();
  305.     else if (dtype == CDVGA) /* if we had the VGA open... close it */
  306.         vgaclose();
  307.  
  308.     /* and set up the various parameters as needed */
  309.     switch (type) {
  310.         case CDMONO:    /* Monochrome adapter */
  311.                 scadd = SCADM;
  312.                 newscreensize(25, term.t_ncol);
  313.                 break;
  314.  
  315.         case CDCGA:    /* Color graphics adapter */
  316.                 scadd = SCADC;
  317.                 newscreensize(25, term.t_ncol);
  318.                 break;
  319.  
  320.         case CDEGA:    /* Enhanced graphics adapter */
  321.                 scadd = SCADE;
  322.                 egaopen();
  323.                 newscreensize(43, term.t_ncol);
  324.                 break;
  325.  
  326.         case CDVGA:    /* VGA adapter */
  327.                 scadd = SCADE;
  328.                 vgaopen();
  329.                 newscreensize(50, term.t_ncol);
  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.     addr.laddr = scadd;
  339.     for (i = 0; i < NROW; i++) {
  340.         scptr[i] = addr.paddr + NCOL * i;
  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.         CDVGA    VGA graphics Adapter
  352. */
  353.  
  354. /* getboard:    Detect the current display adapter
  355.         if MONO        set to MONO
  356.            CGA        set to CGA    EGAexist = FALSE
  357.            EGA        set to CGA    EGAexist = TRUE
  358. */
  359.  
  360. int getboard()
  361.  
  362. {
  363.     int type;    /* board type to return */
  364.  
  365.     type = CDCGA;
  366.     egaexist = FALSE;
  367.  
  368.     /* check for VGA or MCGA */
  369.     rg.h.ah = 0x1a;
  370.     rg.h.bl = 0x00;
  371.     int86(0x10,&rg, &rg);
  372.  
  373.     if (rg.h.al == 0x1a) { /* its a VGA or MCGA */
  374.         if (rg.h.bl < 0x0a)
  375.             type = CDVGA;
  376.         else
  377.             type = CDCGA;
  378.  
  379.         return(type);
  380.     }
  381.     
  382.     /* check for MONO board first */
  383.     int86(0x11, &rg, &rg);
  384.     if (((rg.x.ax & 0x30) == 0x30))
  385.         return(CDMONO);
  386.  
  387.     /* test if EGA present */
  388.     rg.h.ah = 0x12;
  389.     rg.h.bl = 0x10;
  390.     int86(0x10,&rg, &rg);
  391.  
  392.     if (rg.h.bl != 0x10) { /* its an EGA */
  393.         egaexist = TRUE;
  394.         return(CDEGA);
  395.     }
  396.  
  397.     return(type);
  398.  
  399. }
  400.  
  401. /*
  402.  * setboard() - added by pjr
  403.  *
  404.  * This allows the user to set the monitor type by hand by using a set
  405.  * variable in the rc file rather than trying to figure out automatically
  406.  * which board is present, anyhow people may prefer 25 lines!
  407.  */
  408. int setboard(type)
  409. int type;    /* board requested and type to return */
  410. {
  411.  
  412.     switch (type)
  413.     {
  414.     case CDMONO:    /* 25 lines */
  415.         if (dtype == CDMONO)
  416.             type = CDMONO;
  417.         else
  418.             type = CDCGA;
  419.  
  420.         egaexist = FALSE;
  421.         break;
  422.     case CDCGA:    /* 25 lines */
  423.         egaexist = FALSE;
  424.         break;
  425.     case CDEGA:    /* 43 lines */
  426.         egaexist = TRUE;
  427.         break;
  428.     case CDVGA:    /* 50 lines */
  429.         egaexist = FALSE;
  430.         break;
  431.     default:
  432.         egaexist = FALSE;
  433.     } /* end of switch */
  434.     
  435.     return(type);
  436. }
  437.  
  438. egaopen()    /* init the computer to work with the EGA */
  439.  
  440. {
  441.     /* put the beast into EGA 43 row mode */
  442.     rg.x.ax = 3;
  443.     int86(16, &rg, &rg);
  444.  
  445.     rg.h.ah = 17;        /* set char. generator function code */
  446.     rg.h.al = 18;        /*  to 8 by 8 double dot ROM         */
  447.     rg.h.bl = 0;        /* block 0                           */
  448.     int86(16, &rg, &rg);
  449.  
  450.     rg.h.ah = 18;        /* alternate select function code    */
  451.     rg.h.al = 0;        /* clear AL for no good reason       */
  452.     rg.h.bl = 32;        /* alt. print screen routine         */
  453.     int86(16, &rg, &rg);
  454.  
  455.     rg.h.ah = 1;        /* set cursor size function code */
  456.     rg.x.cx = 0x0607;    /* turn cursor on code */
  457.     int86(0x10, &rg, &rg);
  458.  
  459.     outp(0x3d4, 10);    /* video bios bug patch */
  460.     outp(0x3d5, 6);
  461. }
  462.  
  463. egaclose()
  464.  
  465. {
  466.     /* put the beast into 80 column mode */
  467.     rg.x.ax = 3;
  468.     int86(16, &rg, &rg);
  469. }
  470.  
  471. vgaopen()    /* init the computer to work with the VGA */
  472. {
  473.     /* put the beast into VGA 50 row mode */
  474.     rg.x.ax = 0x1202;
  475.     rg.h.bl = 30;
  476.     int86(16, &rg, &rg);
  477.  
  478.     rg.x.ax = 3;
  479.     int86(16, &rg, &rg);
  480.  
  481.     rg.x.ax = 0x1112;    /*  to 8 by 8 double dot ROM         */
  482.     rg.h.bl = 0;        /* block 0                           */
  483.     int86(16, &rg, &rg);
  484. }
  485.  
  486. vgaclose()
  487. {
  488.     /* put the beast back into normal 80 column mode */
  489.     rg.x.ax = 3;
  490.     int86(16, &rg, &rg);
  491. }
  492.  
  493. scwrite(row, col, nchar, outstr, forg, bacg)    /* write a line out*/
  494. int row, col, nchar;    /* row,col of screen to place outstr (len nchar) on */
  495. char *outstr;    /* string to write out (must be term.t_ncol long) */
  496. int forg;    /* forground color of string to write */
  497. int bacg;    /* background color */
  498. {
  499.     unsigned short attr;    /* attribute byte mask to place in RAM */
  500.     unsigned short *lnptr;    /* pointer to the destination line */
  501.     int i;
  502.  
  503.     /* build the attribute byte and setup the screen pointer */
  504. #if    COLOR
  505.     if (dtype != CDMONO)
  506.         attr = ((ctrans[bacg] & 15) << 4) | (ctrans[forg] & 15);
  507.     else
  508. #endif
  509.      attr = ((bacg & 15) << 4) | (forg & 15);
  510.     attr <<= 8;
  511.  
  512.     if (flickcode && (dtype == CDCGA))
  513.         lnptr = &sline[0];
  514.     else
  515.         lnptr = scptr[row]+col;
  516.  
  517.     if (outstr) {
  518.         for (i = 0; i < nchar; i++) {
  519.             *lnptr++ = (outstr[i] & 255) | attr;
  520.         }
  521.     } else {
  522.         for (i = 0; i < nchar; i++) {
  523.             *lnptr++ = (SPACE & 255) | attr;
  524.         }
  525.     }
  526.  
  527.     if (flickcode && (dtype == CDCGA)) {
  528.         /* wait for vertical retrace to be off */
  529.         while ((inp(0x3da) & 8))
  530.             ;
  531.         /* and to be back on */
  532.         while ((inp(0x3da) & 8) == 0)
  533.             ;
  534.         /* and send the string out */
  535.         movmem(&sline[0], scptr[row], nchar*sizeof(short));
  536.     }
  537. }
  538.  
  539. #if    FLABEL
  540. fnclabel(f, n)        /* label a function key */
  541. int f,n;    /* default flag, numeric argument [unused] */
  542. {
  543.     /* on machines with no function keys...don't bother */
  544.     return(TRUE);
  545. }
  546. #endif
  547.  
  548. #else
  549. ibmhello()
  550. {
  551. }
  552. #endif
  553.