home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / OWLSCR / PCBIOS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-12  |  9.2 KB  |  365 lines

  1. /*
  2.     pcbios.c
  3.  
  4.     % pc BIOS device interface
  5.  
  6.     5/16/88  by Ted.
  7.  
  8.     OWL-PC 1.2
  9.     Copyright (c) 1988, by Oakland Group, Inc.
  10.     ALL RIGHTS RESERVED.
  11.  
  12.     Revision History:
  13.     -----------------
  14.      8/31/88 Ted    Added actual BIOS code.
  15.      1/10/89 ted    Removed redundant disp clip.
  16.      1/18/89 Ted    changed call to PlotText for simplified interface.
  17.      2/04/89 Ted    removed Read and Draw Pixmap functions.
  18.      7/12/89 ted    Added OSTATIC's and '_func' macros.
  19.  
  20.      3/28/90 jmd    ansi-fied
  21. */
  22.  
  23. #include "pcpriv.h"
  24.  
  25. OSTATIC dig_dControl_func        (text_bControl);
  26. OSTATIC dig_pPlotText_func        (text_bPlotText);
  27. OSTATIC dig_pClear_func            (text_bClear);
  28. OSTATIC dig_pScrollBoxHz_func    (text_bScrollBoxHz);
  29.  
  30. OSTATIC boolean DIGPRIV pc_OpenBIOS(dig_struct *digp, int mode);
  31. OSTATIC void     DIGPRIV text_bReadCharAttrbuf(ptd_struct *ptd, opcoord x, opcoord y, char *charbuf, byte *attrbuf, int slen);
  32. OSTATIC void     DIGPRIV bios_clearbox(opbox *scrboxp, opixval color);
  33. OSTATIC void     DIGPRIV bios_scrollhz(opbox *scrboxp, opcoord ncols);
  34. OSTATIC void     DIGPRIV bios_movebuf(opcoord x1, opcoord y1, opcoord x2, opcoord y2, int bwidth);
  35.  
  36. /* -------------------------------------------------------------------------- */
  37.  
  38. boolean pc_ModeBIOS(dig_struct *digp)
  39. {
  40.     boolean rval;
  41.  
  42.     if ((rval = pc_OpenBIOS(digp, 0x03)) != 0) {
  43.         return(rval);
  44.     }
  45.     else {
  46.         return(pc_OpenBIOS(digp, 0x07));
  47.     }
  48. }
  49.  
  50. boolean pc_ModeBIOS0(dig_struct *digp)
  51. {
  52.     return(pc_OpenBIOS(digp, 0x00));
  53. }
  54.  
  55. boolean pc_ModeBIOS1(dig_struct *digp)
  56. {
  57.     return(pc_OpenBIOS(digp, 0x01));
  58. }
  59.  
  60. boolean pc_ModeBIOS2(dig_struct *digp)
  61. {
  62.     return(pc_OpenBIOS(digp, 0x02));
  63. }
  64.  
  65. boolean pc_ModeBIOS3(dig_struct *digp)
  66. {
  67.     return(pc_OpenBIOS(digp, 0x03));
  68. }
  69.  
  70. boolean pc_ModeBIOS7(dig_struct *digp)
  71. {
  72.     return(pc_OpenBIOS(digp, 0x07));
  73. }
  74.  
  75. boolean pc_ModeBIOSEGA43(dig_struct *digp)
  76. {
  77.     return(pc_OpenBIOS(digp, PCMODE_EGA43));
  78. }
  79.  
  80. boolean pc_ModeBIOSVGA50(dig_struct *digp)
  81. {
  82.     return(pc_OpenBIOS(digp, PCMODE_VGA50));
  83. }
  84. /* -------------------------------------------------------------------------- */
  85.  
  86. static boolean DIGPRIV pc_OpenBIOS(dig_struct *digp, int mode)
  87. {
  88.     if (!pc_OpenDIG(digp, mode, text_setinfo)) {
  89.         return(FALSE);
  90.     }
  91.     text_setbiosfuncs(digp);
  92.     return(TRUE);
  93. }
  94. /* -------------------------------------------------------------------------- */
  95.  
  96. void text_setbiosfuncs(dig_struct *digp)
  97. /*
  98.     Set up the dig function ptrs for text mode BIOS operation.
  99. */
  100. {
  101.     digp->CloseDIG = pc_CloseDIG;
  102.     digp->dControl      = text_bControl;
  103.  
  104.     digp->pPlotText     = text_bPlotText;
  105.     digp->pDrawCursor   = pc_bDrawCursor;
  106.     digp->pClear        = text_bClear;
  107.     digp->pScrollBoxVt  = text_bScrollBoxVt;
  108.     digp->pScrollBoxHz  = text_bScrollBoxHz;
  109.  
  110.     /* in hardware cursor text modes, no pixmap funcs are needed */
  111.     digp->pDrawPixmap   = (dig_pDrawPixmap_func ((*)))pc_dDummy;
  112.     digp->pReadPixmap   = (dig_pReadPixmap_func ((*)))pc_dDummy;
  113.     digp->pControl      = (dig_pControl_func ((*)))pc_dDummy;
  114.  
  115.     digp->vtscroll = TRUE;
  116.     digp->hzscroll = TRUE;
  117.     digp->textfree = FALSE;
  118.     digp->evcheck  = TRUE;
  119.     digp->type = 0;
  120.     digp->version = 0;
  121. }
  122. /* -------------------------------------------------------------------------- */
  123.  
  124. static int text_bControl(dig_dcmsg msg, VOID *indata, VOID *outdata)
  125. {
  126.     switch (msg) {
  127.     case DC_READCHARATTR:
  128.         {    ptarg_struct *pta = (ptarg_struct *)indata;
  129.             text_bReadCharAttrbuf(pta->ptd, pta->x, pta->y,
  130.                                     pta->charbuf, pta->attrbuf, pta->slen);
  131.         }
  132.         break;
  133.     default:
  134.         return(pc_dControl(msg, indata, outdata));
  135.     }
  136.     return(TRUE);
  137. }
  138. /* -------------------------------------------------------------------------- */
  139.  
  140. static void text_bPlotText(ptd_struct *ptd, opcoord x, opcoord y, char *charbuf, char rchar, byte rattr, int slen)
  141. /*
  142.     Plot text/attribute buffers to screen at (x,y), clipped into ptd->relboxp.
  143. */
  144. {
  145.     win_type win;
  146.     opbox clipbox;
  147.     int delta;
  148.  
  149.     OREGS regs;
  150.     int orow, ocol;
  151.  
  152.     win = ptd->win;
  153.  
  154.     opbox_copy(&clipbox, ptd->relboxp);
  155.     opbox_trans(&clipbox, win_GetXmin(win), win_GetYmin(win));
  156.     x += win_GetXmin(win);
  157.     y += win_GetYmin(win);
  158.  
  159.     delta = opbox_clipstring(&clipbox, &x, &y, &slen, win_GetFont(win));
  160.     if (slen <= 0) {
  161.         return;
  162.     }
  163.     if (charbuf != NULL) charbuf += delta;
  164.     rattr = pcdata->attrmap[rattr];
  165.  
  166. /* Draw the string, plotting chars and attrs */
  167.     pc_bgetcursorpos(&orow, &ocol);
  168.  
  169.     for ( ; slen > 0; slen--) {
  170.  
  171.     /*    pc_bsetcursorpos(row, x++);   inline instead */
  172.         regs.h.dl = ((byte) x++);        /* set cursor xpos */
  173.         regs.h.dh = ((byte)(y-1));        /* set cursor ypos */
  174.         regs.h.ah = VIDINT_SETC;
  175.         regs.h.bh = TEXT_RPAGE;
  176.         oakint86(BIOS_VIDINT, ®s);
  177.  
  178.         if (charbuf != NULL) rchar = *charbuf++;
  179.  
  180.         regs.h.ah = VIDINT_WRTCHAR;
  181.         regs.h.bh = TEXT_RPAGE;
  182.         regs.x.cx = 1;
  183.         regs.h.al = rchar;
  184.         regs.h.bl = rattr;
  185.         oakint86(BIOS_VIDINT, ®s);
  186.     }
  187.     pc_bsetcursorpos(orow, ocol);
  188. }
  189. /* -------------------------------------------------------------------------- */
  190.  
  191. static void text_bClear(ptd_struct *ptd, opixval color)
  192. {
  193.     win_type win;
  194.     opbox scrbox;
  195.  
  196.     win = ptd->win;
  197.  
  198.     opbox_copy(&scrbox, ptd->relboxp);
  199.     opbox_trans(&scrbox, win_GetXmin(win), win_GetYmin(win));
  200.  
  201.     bios_clearbox(&scrbox, color);
  202. }
  203. /* -------------------------------------------------------------------------- */
  204.  
  205. static void text_bScrollBoxHz(ptd_struct *ptd, opcoord ncols)
  206. {
  207.     win_type win;
  208.     opbox scrbox;
  209.  
  210.     win = ptd->win;
  211.  
  212.     opbox_copy(&scrbox, ptd->relboxp);
  213.     opbox_trans(&scrbox, win_GetXmin(win), win_GetYmin(win));
  214.  
  215.     bios_scrollhz(&scrbox, ncols);
  216. }
  217. /* -------------------------------------------------------------------------- */
  218.  
  219. static void DIGPRIV text_bReadCharAttrbuf(ptd_struct *ptd, opcoord x, opcoord y, char *charbuf, byte *attrbuf, int slen)
  220. {
  221.     win_type win;
  222.     opbox clipbox;
  223.     int delta;
  224.     int orow, ocol;
  225.     OREGS regs;
  226.  
  227.     win = ptd->win;
  228.  
  229.     opbox_copy(&clipbox, ptd->relboxp);
  230.     opbox_trans(&clipbox, win_GetXmin(win), win_GetYmin(win));
  231.     x += win_GetXmin(win);
  232.     y += win_GetYmin(win);
  233.  
  234.     delta = opbox_clipstring(&clipbox, &x, &y, &slen, win_GetFont(win));
  235.     if (slen <= 0) {
  236.         return;
  237.     }
  238.     if (charbuf != NULL) charbuf += delta;
  239.     if (attrbuf != NULL) attrbuf += delta;
  240.  
  241.     if (attrbuf == NULL || charbuf == NULL) {
  242.         return;
  243.     }
  244. /* Read the string, plotting chars and attrs */
  245.     pc_bgetcursorpos(&orow, &ocol);
  246.  
  247.     for ( ; slen > 0; slen--) {
  248.         regs.h.dl = ((byte) x++);        /* set cursor xpos */
  249.         regs.h.dh = ((byte)(y-1));        /* set cursor ypos */
  250.         regs.h.ah = VIDINT_SETC;
  251.         regs.h.bh = TEXT_RPAGE;
  252.         oakint86(BIOS_VIDINT, ®s);
  253.  
  254.         regs.h.ah = VIDINT_RDCHAR;
  255.         regs.h.bh = TEXT_RPAGE;
  256.         oakint86(BIOS_VIDINT, ®s);
  257.         *(charbuf++) = regs.h.al;        /* char */
  258.         *(attrbuf++) = regs.h.ah;        /* attr */
  259.     }
  260.     pc_bsetcursorpos(orow, ocol);
  261. }
  262. /* -------------------------------------------------------------------------- */
  263. /* -------------------------------------------------------------------------- */
  264.  
  265. static void DIGPRIV bios_clearbox(opbox *scrboxp, opixval color)
  266. {
  267.     OREGS regs;
  268.  
  269.     regs.h.ah = VIDINT_SCRLDN;
  270.     regs.h.al = 0;
  271.     regs.x.bx = pc_wordcolor(color);    /* bh gets attr */
  272.  
  273.     regs.h.cl = (byte) scrboxp->xmin;
  274.     regs.h.ch = (byte) scrboxp->ymin;
  275.     regs.h.dl = (byte) (scrboxp->xmax-1);
  276.     regs.h.dh = (byte) (scrboxp->ymax-1);
  277.     oakint86(BIOS_VIDINT, ®s);
  278. }
  279. /* -------------------------------------------------------------------------- */
  280.  
  281. static void DIGPRIV bios_scrollhz(opbox *scrboxp, opcoord ncols)
  282. {
  283.     int bwidth;
  284.     opcoord x1, x2;
  285.  
  286.     if (ncols > 0) {
  287.         x1 = scrboxp->xmin + ncols;
  288.         x2 = scrboxp->xmin;
  289.     }
  290.     else if (ncols < 0) {
  291.         ncols = -ncols;
  292.         x1 = scrboxp->xmin;
  293.         x2 = scrboxp->xmin + ncols;
  294.     }
  295.     else return;                                /* quit if no scroll */
  296.  
  297.     if ((odim) ncols >= opbox_GetWidth(scrboxp)) {        /* quit if scroll all */
  298.         return;
  299.     }
  300.     bwidth = (opbox_GetWidth(scrboxp) - ncols) * 2;
  301.  
  302.     for (;;) {
  303.         bios_movebuf(x1, scrboxp->ymin, x2, scrboxp->ymin, bwidth);
  304.  
  305.         if (opbox_GetHeight(scrboxp) <= 1) {
  306.             break;
  307.         }
  308.         scrboxp->ymin += 1;
  309.     }
  310. }
  311. /* -------------------------------------------------------------------------- */
  312.  
  313. static void DIGPRIV bios_movebuf(opcoord x1, opcoord y1, opcoord x2, opcoord y2, int bwidth)
  314. {
  315.     int orow, ocol;
  316.     OREGS regs;
  317.     byte tchar, tattr;
  318.  
  319. /* Draw the string, plotting chars and attrs */
  320.     pc_bgetcursorpos(&orow, &ocol);
  321.  
  322.     if (x1 < x2) {
  323.         x1 += bwidth/2 - 1;
  324.         x2 += bwidth/2 - 1;
  325.     }
  326.     for ( ; bwidth > 0; bwidth -= 2) {
  327.         regs.h.dl = (byte) x1;        /* set cursor xpos */
  328.         regs.h.dh = (byte) y1;        /* set cursor ypos */
  329.         regs.h.ah = VIDINT_SETC;
  330.         regs.h.bh = TEXT_RPAGE;
  331.         oakint86(BIOS_VIDINT, ®s);
  332.  
  333.         regs.h.ah = VIDINT_RDCHAR;
  334.         regs.h.bh = TEXT_RPAGE;
  335.         oakint86(BIOS_VIDINT, ®s);
  336.         tchar = regs.h.al;        /* char */
  337.         tattr = regs.h.ah;        /* attr */
  338.  
  339.         regs.h.dl = (byte) x2;        /* set cursor xpos */
  340.         regs.h.dh = (byte) y2;        /* set cursor ypos */
  341.         regs.h.ah = VIDINT_SETC;
  342.         regs.h.bh = TEXT_RPAGE;
  343.         oakint86(BIOS_VIDINT, ®s);
  344.  
  345.         regs.h.ah = VIDINT_WRTCHAR;
  346.         regs.h.bh = TEXT_RPAGE;
  347.         regs.x.cx = 1;
  348.         regs.h.al = tchar;        /* char */
  349.         regs.h.bl = tattr;        /* attr */
  350.         oakint86(BIOS_VIDINT, ®s);
  351.         
  352.         if (x1 < x2) {
  353.             x1--;
  354.             x2--;
  355.         }
  356.         else {
  357.             x1++;
  358.             x2++;
  359.         }
  360.     }
  361.     pc_bsetcursorpos(orow, ocol);
  362. }
  363. /* -------------------------------------------------------------------------- */
  364.  
  365.