home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / NETMAIL / MSGD2SRC.ZIP / SCREEN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-07  |  14.7 KB  |  826 lines

  1. /*
  2.  
  3. Title:  MsgEd
  4.  
  5. File:   Screen.c
  6.  
  7. Author: Jim Nutt
  8.  
  9. Copr:    released into the PUBLIC DOMAIN 30 jul 1990 by jim nutt
  10.  
  11. Description:
  12.  
  13.     Screen handling functions for MsgEd.
  14.  
  15.     if you need to port this... remember, msged uses a 1 based coordinate
  16.     system (i.e. top left is (1,1) NOT (0,0)).
  17.  
  18. */
  19.  
  20. #include "pascal.h"
  21.  
  22. #include <dos.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include <stdarg.h>
  27. #if !defined(__TURBOC__)
  28. #include <conio.h>
  29. #else
  30. int kbhit(void);
  31. int getch(void);
  32. #endif
  33. #ifndef MK_FP
  34. #include "mkfp.h"
  35. #endif
  36. #include "screen.h"
  37. #include "vfossil.h"
  38.  
  39. #ifndef _MSC_VER
  40. #include "screen2.h"
  41. #endif
  42.  
  43. static void pascal vfossil_cursor (int st);
  44. static void pascal vfossil_init (void);
  45. static void pascal vfossil_open (void);
  46. static void pascal vfossil_close (void);
  47.  
  48. void pascal strins(char *l, char c, int x);
  49. void pascal strdel(char *l, int x);
  50.  
  51. #define FALSE 0
  52. #define TRUE !FALSE
  53. #define TEXTLEN 256
  54.  
  55. int int86(int intnum,union REGS *i, union REGS *o);
  56. int int86x(int intnum,union REGS *i, union REGS *o,struct SREGS *s);
  57.  
  58. unsigned int *macros[41];     /* function key macros + 1 for autostart */
  59.  
  60. int maxx;               /* maximum screen columns */
  61. int maxy;               /* maximum screen rows */
  62. int videomethod;        /* how to write to the screen */
  63. unsigned int vbase;     /* where screen memory is located */
  64. unsigned char current_color;    /* current screen attribute */
  65.  
  66. /* keyboard control values */
  67.  
  68. static int autostart = 0;
  69. static unsigned int * macro = (void *) NULL;
  70.  
  71. static char s[TEXTLEN];
  72.  
  73. static unsigned int *screen = NULL;
  74. static unsigned int cx = 1;
  75. static unsigned int cy = 1;
  76. static int desqview = 0;
  77.  
  78. static unsigned char scroll_fill [2];
  79. static VIOMODEINFO fossil_data;
  80.  
  81.  
  82. void pascal video_init()
  83. {
  84.     union REGS r;
  85.     struct SREGS sr;
  86.     int vmode = 0;
  87.  
  88.     if (videomethod == ANSI) {
  89.         maxx = 80;
  90.         maxy = 25;
  91.         desqview = 0;
  92.         return;
  93.     }
  94.  
  95.     if (videomethod == FOSSIL) {
  96.         vfossil_init ();                /* Start Video FOSSIL */
  97.         fossil_data.cb = 2 * sizeof (VIOMODEINFO);
  98.         VioGetMode ((PVIOMODEINFO) &fossil_data,0);    /* Get mode info      */
  99.         maxx = fossil_data.col;        /* Maximum 'X' value  */
  100.         maxy = fossil_data.row;        /* Maximum 'Y' value  */
  101.     }
  102.     else {
  103.         r.h.ah = 0x0f;
  104.         int86(0x10,&r,&r);
  105.         vmode = r.h.al;
  106.         if (maxx == 0)
  107.             maxx = (int) r.h.ah;
  108.  
  109.         if (maxy == 0) {
  110.             r.x.ax = 0x1130;
  111.             r.x.dx = maxy;
  112.             int86(0x10,&r,&r);
  113.             maxy = (r.x.dx == 0) ? 25 : (r.x.dx + 1);
  114.         }
  115.  
  116.         if (videomethod == DIRECT) {
  117.             if (vbase == 0)
  118.                 if (vmode == 0x07)
  119.                     vbase = 0xb000;
  120.                 else
  121.                     vbase = 0xb800;
  122.  
  123.             r.h.ah = 0xfe;
  124.             sr.es = vbase;
  125.             r.x.di = 0;
  126.             int86x(0x10,&r,&r,&sr);
  127.             desqview = (vbase != sr.es);
  128.             vbase = sr.es;
  129.             screen = (unsigned int *) MK_FP(vbase,r.x.di);
  130.         }
  131.     }
  132. }
  133.  
  134. int  *getrgn(int x1,int y1,int x2,int y2)
  135.  
  136. {
  137.     if ((x1 < 0) || (x2 > maxx) || (y1 < 0) || (y2 > maxy))
  138.         return(NULL);
  139.  
  140.     return(NULL);
  141. }
  142.  
  143. void putrgn(int x1,int y1,int x2,int y2,int *rgn)
  144.  
  145. {
  146.     if ((x1 < 0) || (x2 > maxx) || (y1 < 0) || (y2 > maxy))
  147.         return;
  148.  
  149.     if (!rgn)
  150.         return;
  151. }
  152.  
  153.  
  154. void pascal video_end()
  155. {
  156.     if (videomethod == FOSSIL)
  157.         vfossil_close ();
  158. }
  159.  
  160. void pascal video_update()
  161. {
  162.     if (videomethod == ANSI) {
  163.         printf("\033[%d;%dH",cy,cx);
  164.     }
  165.     else if (videomethod == FOSSIL)
  166.         VioSetCurPos (cy - 1, cx - 1, 0);
  167.     else {
  168.         union REGS r;
  169.  
  170.         r.h.ah = 2;
  171.         r.h.bh = 0;
  172.         r.h.dh = (char) (cy - 1);
  173.         r.h.dl = (char) (cx - 1);
  174.         int86(0x10, &r, &r);
  175.     }
  176. }
  177.  
  178. void pascal scrollup(int x1, int y1, int x2, int y2, int lines)
  179.  
  180. {
  181.     if (videomethod == ANSI) {
  182.         printf("\033[%d;%dH\033F",y1,x1);
  183.         printf("\033[%d;%dH\033G",y2,x2);
  184.         printf("\033[%dS",lines);
  185.         printf("\033[%d;%dH\033F",1,1);
  186.         printf("\033[%d;%dH\033G",maxy,maxx);
  187.         return;
  188.     }
  189.  
  190.     y2 = min(y2,maxy);
  191.     y1 = min(y1,maxy);
  192.     x1 = min(x1,maxx);
  193.     x2 = min(x2,maxx);
  194.  
  195.     if (videomethod == FOSSIL) {
  196.         scroll_fill [0] = ' ';
  197.         scroll_fill [1] = current_color;
  198.         if (lines == 0)
  199.             lines = -1;
  200.  
  201.         VioScrollUp (y1-1,x1-1,y2-1,x2-1,lines,(unsigned char *) scroll_fill,0);
  202.     }
  203.     else if (videomethod == BIOS) {
  204.         union REGS      r;
  205.  
  206.         r.h.ah = 6;
  207.         r.h.al = (char) lines;
  208.         r.h.ch = (char) (y1-1);
  209.         r.h.cl = (char) (x1-1);
  210.         r.h.dh = (char) (y2-1);
  211.         r.h.dl = (char) (x2-1);
  212.         r.h.bh = current_color;
  213.         int86(0x10, &r, &r);
  214.     }
  215.     else {
  216.         while (lines--) {
  217. #ifndef ASM
  218.             int *scrptr = MK_FP(vbase,((y1-1) * maxx + (x1-1)) << 1);
  219.             int ny = y1-1;
  220.             int l = ((x2 - x1) + 1);
  221.  
  222.             while (ny++ < y2) {
  223.                 memcpy(scrptr,scrptr + maxx,l<<1);
  224.                 scrptr += maxx;
  225.             }
  226.             while (l)
  227.                 *(scrptr + --l) = 0x20 | (current_color << 8);
  228. #else
  229.             if (y1 != y2)
  230.                 dscrollup(x1,y1,x2,y2);
  231.             else
  232.                 dclrwnd(x1,y1,x2,y2);
  233. #endif
  234.         }
  235.     }
  236. }
  237.  
  238. void pascal scrolldown(int x1, int y1, int x2, int y2, int lines)
  239.  
  240. {
  241.     if (videomethod == ANSI) {
  242.         printf("\033[%d;%dH\033F",y1,x1);
  243.         printf("\033[%d;%dH\033G",y2,x2);
  244.         printf("\033[%dT",lines);
  245.         printf("\033[%d;%dH\033F",1,1);
  246.         printf("\033[%d;%dH\033G",maxy,maxx);
  247.         return;
  248.     }
  249.  
  250.     y2 = min(y2,maxy);
  251.     y1 = min(y1,maxy);
  252.     x1 = min(x1,maxx);
  253.     x2 = min(x2,maxx);
  254.  
  255.     if (videomethod == FOSSIL) {
  256.         scroll_fill [0] = ' ';
  257.         scroll_fill [1] = current_color;
  258.         VioScrollDn (y1-1,x1-1,y2-1,x2-1,lines,(unsigned char *) scroll_fill,0);
  259.     }
  260.     else if (videomethod == BIOS) {
  261.         union REGS      r;
  262.  
  263.         r.h.ah = 7;
  264.         r.h.al = (char) lines;
  265.         r.h.ch = (char) (y1-1);
  266.         r.h.cl = (char) (x1-1);
  267.         r.h.dh = (char) (y2-1);
  268.         r.h.dl = (char) (x2-1);
  269.         r.h.bh = current_color;
  270.         int86(0x10, &r, &r);
  271.     }
  272.     else {
  273.         while (lines--) {
  274. #ifndef ASM
  275.             int ny = y2-1;
  276.             int l = ((x2 - x1) + 1);
  277.             int *scrptr = MK_FP(vbase,((y2-1) * maxx + (x1-1)) << 1);
  278.             while (ny-- >= y1) {
  279.                 memcpy(scrptr,scrptr - maxx,l<<1);
  280.                 scrptr -= maxx;
  281.             }
  282.             while (l)
  283.                 *(scrptr + --l) = 0x20 | (current_color << 8);
  284. #else
  285.             if (y1 != y2)
  286.                 dscrolldn(x1,y1,x2,y2);
  287.             else
  288.                 dclrwnd(x1,y1,x2,y2);
  289. #endif
  290.         }
  291.     }
  292. }
  293.  
  294. void pascal bputc(int c)
  295.  
  296. {
  297. #ifndef ASM
  298.     union REGS r;
  299. #endif
  300.  
  301.     unsigned int d = 0;
  302.  
  303.     if (videomethod == ANSI) {
  304.         printf("\033[%d;%dH\033[%d;%dm%c",cy,cx,
  305.             30+(current_color & 0x7),
  306.             40+(current_color>>4),c&0x7f);
  307.         return;
  308.     }
  309.  
  310. #ifndef ASM
  311.     if (videomethod == DIRECT) {
  312.         *(screen + ((((cy - 1) * maxx) + (cx - 1)))) = d;
  313. #else
  314.     if ((videomethod == DIRECT) || (videomethod == BIOS)) {
  315.         dputc(cx,cy,c);
  316. #endif
  317.     }
  318.     else if (videomethod == FOSSIL) {
  319.         d = ((unsigned) c & 0xff) | (current_color << 8);
  320.         VioWrtCellStr ((unsigned int *) &d, 2, cy - 1, cx - 1, 0);
  321.     }
  322. #ifndef ASM
  323.     else {
  324.         video_update();
  325.         r.h.ah = 0x9;
  326.         r.h.bh = 0;
  327.         r.h.al = (unsigned char) c;
  328.         r.h.bl = current_color;
  329.         r.x.cx = 1;
  330.         int86(0x10,&r,&r);
  331.     }
  332. #endif
  333.     if (++cx > (unsigned) maxx) {
  334.         cx = 1;
  335.         if (++cy > (unsigned) maxy)
  336.             cy = 1;
  337.     }
  338. }
  339.  
  340. void pascal gotoxy(int x, int y)
  341.  
  342. {
  343.     cx = min(x,maxx);
  344.     cy = min(y,maxy);
  345. }
  346.  
  347. int pascal wherex()
  348.  
  349. {
  350.     return (cx);
  351. }
  352.  
  353. int pascal wherey()
  354.  
  355. {
  356.     return(cy);
  357. }
  358.  
  359. unsigned int pascal keyhit()
  360.  
  361. {
  362.     union REGS r;
  363.  
  364.     if (macro)      /* always return no keypress during macros */
  365.         return(0);
  366.  
  367.     if (videomethod == FOSSIL) {
  368.         r.x.ax = 0x0d00;
  369.         int86(0x14,&r,&r);
  370.         if (r.x.ax == 0xffff)
  371.             return(0);
  372.     }
  373.     else {
  374.         r.h.ah = 1;
  375.         int86(0x16,&r,&r);
  376. #if defined(_MSC_VER)
  377.         if (r.x.cflag)
  378. #else
  379.         if (r.x.flags & 64)
  380. #endif
  381.             return(0);
  382.     }
  383.  
  384.     if (r.h.al)                     /* Must use FOSSIL keymap,   */
  385.         r.h.ah = 0;             /* No scan code if have char */
  386.  
  387.     return r.x.ax;
  388. }
  389.  
  390. unsigned int pascal getkey()
  391.  
  392. {
  393.     union REGS r;
  394.  
  395.     if ((macros[0] != (void *) NULL) && !autostart) {
  396.         autostart = 1;
  397.         macro = macros[0];
  398.     }
  399.  
  400.     if (macro != (void *) NULL) {
  401.         if (*(++macro))
  402.             return(*macro);
  403.  
  404.         macro = (void *) NULL;
  405.     }
  406.  
  407.     if (videomethod == FOSSIL) {
  408.         r.h.ah = 0x0e;
  409.         int86 (0x14,&r,&r);
  410.     }
  411.     else {
  412.         r.h.ah = 0;
  413.         int86(0x16,&r,&r);
  414.     }
  415.  
  416.     if (r.h.al) {                    /* Must use FOSSIL keymap,   */
  417.         r.h.ah = 0;             /* No scan code if have char */
  418.         return(r.x.ax);
  419.     }
  420.  
  421.     if ((r.h.ah >= 0x3b) && (r.h.ah <= 0x44))
  422.         macro = macros[r.h.ah - 0x3a];
  423.     else if ((r.h.ah >= 0x54) && (r.h.ah <= 0x71))
  424.         macro = macros[r.h.ah - 0x49];
  425.  
  426.     if (macro != (void *) NULL) {
  427.         if (*macro)
  428.             return(*macro);
  429.  
  430.         macro = (void *) NULL;
  431.     }
  432.  
  433.     return(r.x.ax);
  434. }
  435.  
  436. void pascal bputs(char *s)
  437.  
  438. {
  439. #ifndef ASM
  440.     unsigned int *linebase = screen + ((((cy - 1) * maxx) + (cx - 1)));
  441.     unsigned int d;
  442. #endif
  443.     char *t = s;
  444.     char ch = '\0';
  445.     unsigned int a = current_color;
  446.     unsigned int l = 0,l1 = 0;
  447.  
  448.     if (s == NULL)
  449.         return;
  450.  
  451.     if (videomethod == ANSI) {
  452.         printf("\033[%d;%dH\033[%d;%dm%0.79s",cy,cx,
  453.             30+(current_color & 0x7),
  454.             40+(current_color>>4),s);
  455.             return;
  456.     }
  457.  
  458.     if ((t = strchr(s,'\n')) != NULL) {
  459.         ch = *t;
  460.         *t = '\0';
  461.     }
  462.  
  463.     if ((strlen(s) + cx) > (size_t) maxx) {
  464.         if (t) *t = ch;
  465.         ch = *(t = s + maxx - cx + 1);
  466.         *t = '\0';
  467.     }
  468.  
  469. #ifdef ASM
  470.     if ((videomethod == DIRECT) || (videomethod == BIOS)) {
  471.         cx += dputs(cx,cy,s);
  472.         if (t) *t = ch;
  473.         return;
  474.     }
  475. #endif
  476.  
  477.     if (strlen(s)) {
  478.         l1 = l = (((strlen(s) + cx) < (size_t) maxx)?strlen(s):maxx - cx + 1);
  479.  
  480.         if (videomethod == FOSSIL)
  481.             VioWrtCharStrAtt((char *) s,l,cy - 1,cx - 1, (unsigned char *) &a,0);
  482. #ifndef ASM
  483.         else
  484.             if (videomethod == DIRECT) {
  485.                 d = current_color << 8;
  486.                 while (l--)
  487.                     *linebase++ = (unsigned int) (*s++ & 0xff) | d;
  488.             }
  489.             else
  490.                 while (l--)
  491.                     bputc(*s++);
  492. #endif
  493.     }
  494.  
  495.     if (t) *t = ch;
  496.     if (videomethod != BIOS)
  497.         cx += l1;
  498. }
  499.  
  500. void pascal cls()
  501.  
  502. {
  503.     if (videomethod == ANSI) {
  504.         fputs("\033[2J",stdout);
  505.         return;
  506.     }
  507.  
  508.     if (videomethod == DIRECT) {
  509.  
  510. #ifndef ASM
  511.         int ny = 0;
  512.         int *scrptr = MK_FP(vbase,0);
  513.         while (ny++ < maxy) {
  514.             int l = maxx;
  515.             while (l)
  516.                 *(scrptr + --l) = 0x20 | (current_color << 8);
  517.             scrptr += maxx;
  518.         }
  519. #else
  520.         dcls();
  521. #endif
  522.     }
  523.     else {
  524.         scrollup(1, 1, maxx, maxy, 0);
  525.         gotoxy(1, 1);
  526.     }
  527. }
  528.  
  529. void pascal clrwnd(int x1, int y1, int x2, int y2)
  530.  
  531. {
  532.     if (videomethod == ANSI) {
  533.         printf("\033[%d;%dH\033F",y1,x1);
  534.         printf("\033[%d;%dH\033G",y2,x2);
  535.         printf("\033[O");
  536.         printf("\033[%d;%dH\033F",1,1);
  537.         printf("\033[%d;%dH\033G",maxy,maxx);
  538.         return;
  539.     }
  540.     if (videomethod == DIRECT) {
  541. #ifndef ASM
  542.         int ny = y1-1;
  543.         int *scrptr = MK_FP(vbase,((y1-1) * maxx + (x1-1)) * 2);
  544.  
  545.         while (ny++ <= (y2-1)) {
  546.             int l = (((x2-1) - (x1-1)) + 1);
  547.             while (l)
  548.                 *(scrptr + --l) = 0x20 | (current_color << 8);
  549.             scrptr += maxx;
  550.         }
  551. #else
  552.         dclrwnd(x1,y1,x2,y2);
  553. #endif
  554.     }
  555.     else {
  556.         scrollup(x1, y1, x2, y2, 0);
  557.         gotoxy(x1,y1);
  558.     }
  559. }
  560.  
  561. void pascal clreol()
  562. {
  563.     int x = cx;
  564.  
  565.     if (videomethod == ANSI) {
  566.         fputs("\033[K",stdout);
  567.     }
  568.     else if (videomethod == BIOS) {
  569.         union REGS r;
  570.  
  571.         video_update();
  572.         r.h.ah = 0x9;
  573.         r.h.bh = 0;
  574.         r.h.al = 0x20;
  575.         r.h.bl = current_color;
  576.         r.x.cx = (maxx - cx + 1);
  577.         int86(0x10,&r,&r);
  578.     }
  579.     else
  580.         clrwnd(x,cy,maxx,cy);
  581.     cx = x;
  582. }
  583.  
  584. int pascal bgets(char *s, int c, int w)
  585.  
  586. {
  587.     int x1,x2,y,ch,tx,m=1;
  588.     char *o,fmt[10],*p;
  589.     static ins = 1;
  590.     
  591.     w = min(c,w);
  592.     x1 = max(0,cx); y = min(maxy,max(0,cy)); x2 = min(cx + w,(unsigned) maxx);
  593.     o = strdup(s);
  594.     p = s;
  595.     sprintf(fmt,"%%-%d.%ds",w,w);
  596.     cx = x1 + strlen(s);
  597.     if (cx > (unsigned) x2) {
  598.         p = s + (cx - x2);
  599.         cx = x2;
  600.     }
  601.  
  602.     for (;;) {
  603.         if (m) {
  604.             tx = cx;
  605.             clrwnd(x1,y,x2,y);
  606.             cx = x1; bprintf(fmt,p); 
  607.             cx = tx; m = 0;
  608.         }
  609.  
  610.         video_update();
  611.         switch (ch = getkey()) {
  612.             case UP:
  613.             case DOWN:
  614.             case ENTER:
  615.                 free(o);
  616.                 return(ch);
  617.  
  618.             case GOBOL:
  619.                 cx = x1;
  620.                 p = s;
  621.                 m = 1;
  622.                 break;
  623.     
  624.  
  625.             case GOEOL:
  626.                 cx = x1 + strlen(p);
  627.                 if (cx > (unsigned) x2) {
  628.                     p += cx - x2;
  629.                     cx = x2 - 1;
  630.                 }
  631.                 m = 1;
  632.                 break;
  633.  
  634.             case ABORT:
  635.                 strcpy(s,o);
  636.                 free(o);
  637.                 return(ch);
  638.  
  639.             case INSERT:
  640.                 ins = !ins;
  641.                 break;
  642.  
  643.             case BKSPC:
  644.                 if (cx > (unsigned) x1) {
  645.                     cx--;
  646.                     strdel(p,cx - x1 + 1);            
  647.                     m = 1;
  648.                 }
  649.                 else if (p > s) {
  650.                     p--;
  651.                     strdel(p,1);
  652.                     m = 1;
  653.                 }
  654.                 break;
  655.  
  656.             case WORDLT:
  657.                 break;
  658.  
  659.             case WORDRT:
  660.                 break;
  661.  
  662.             case LEFT:
  663.                 if (cx > (unsigned) x1) cx--;
  664.                 else if (p > s) { p--; m = 1; }
  665.                 break;
  666.  
  667.             case RIGHT:
  668.                 if (cx < (unsigned) (x2-1)) {
  669.                     if ((cx-x1) < strlen(p)) cx++;
  670.                 }
  671.                 else if ((unsigned) w < strlen(p)) { p++; m = 1; }
  672.                 break;
  673.  
  674.             case DELCHR:
  675.                 strdel(p,cx - x1 + 1);
  676.                 m = 1;
  677.                 break;
  678.  
  679.             case CANCEL:
  680.                 p = s; m = 1; cx = x1;
  681.                 strset(s,0);
  682.                 break;
  683.  
  684.             default:
  685.                 if (!(ch & 0xff))
  686.                     break;
  687.  
  688.                 if (ins)
  689.                     if (strlen(s) >= (unsigned) c) break;
  690.                     else strins(p,(char) (ch & 0xff), (int) cx - x1 + 1);
  691.                 else
  692.                     *(p + cx - x1) = (char) (ch & 0xff);
  693.                 
  694.                 if (cx < (unsigned) x2)
  695.                     cx++;
  696.                 else if ((unsigned) w < strlen(p)) p++;
  697.  
  698.                 m = 1;
  699.  
  700.                 break;
  701.             }
  702.     }
  703. }
  704.  
  705. int pascal getnum(int l, int h, int value)
  706.  
  707. {
  708.     int     i, x;
  709.     char    s[TEXTLEN];
  710.  
  711.     i = value;
  712.     x = wherex();
  713.  
  714.     do {
  715.         memset(s, 0, sizeof(s));
  716.         itoa(i, s, 10);
  717.         gotoxy(x, wherey());
  718.         bgets(s, sizeof s << 1,min(maxx - x, sizeof s << 1));
  719.         i = atoi(s);
  720.  
  721.     } while ((i < l) || (i > h));
  722.  
  723.     return (i);
  724. }
  725.  
  726. void pascal set_color(unsigned int attr)
  727.  
  728. {
  729.     current_color = (unsigned char) attr;
  730. }
  731.  
  732. unsigned pascal get_color()
  733.  
  734. {
  735.     return(current_color);
  736. }
  737.  
  738. int cdecl bprintf(char *f,...)
  739.  
  740. {
  741.     va_list params;
  742.     int     i;
  743.  
  744.     va_start(params, f);
  745.     i = vsprintf(s, f, params);
  746.     bputs(s);
  747.     return (i);
  748. }
  749.  
  750. VFOSSIL v;
  751.  
  752. static void pascal vfossil_init ()
  753.  
  754. {
  755.     char *q;
  756.     union REGS r;
  757.     struct SREGS s;
  758.  
  759.     v.vfossil_size = sizeof (VFOSSIL);
  760.     q = (char *) &v;
  761.  
  762.     r.h.ah = 0x81;
  763.     r.h.al = 0;
  764.  
  765.     segread (&s);
  766.     s.es = FP_SEG (q);
  767.     r.x.di = FP_OFF (q);
  768.     int86x (0x14, &r, &r, &s);
  769.  
  770.     if (r.x.ax == 0x1954)
  771.     /* There is a VFOSSIL out there, so set it up for use */
  772.         vfossil_open ();
  773.     else {
  774.         fputs ("No Video FOSSIL installed, aborting....\n\n",stderr);
  775.         exit (255);
  776.     }
  777. }
  778.  
  779. CURSOR _cursor;
  780.  
  781. static void pascal vfossil_cursor (int st)
  782.  
  783. {
  784.     CURSOR *q;
  785.  
  786.     q = (CURSOR *) &_cursor;
  787.     /* We can make the cursor go away */
  788.     VioGetCurType (q, 0);
  789.     _cursor.cur_attr = st ? 0 : -1;
  790.     VioSetCurType (q, 0);
  791. }
  792.  
  793. static void pascal vfossil_open ()
  794.  
  795. {
  796.     char *q;
  797.     union REGS r;
  798.     struct SREGS s;
  799.  
  800.     segread (&s);
  801.     r.h.ah = 0x81;
  802.     r.h.al = 1;
  803.     r.x.cx = 80;
  804.     q = (char *) &vfossil_funcs;
  805.     r.x.di = FP_OFF (q);
  806.     s.es = FP_SEG (q);
  807.     int86x (0x14, &r, &r, &s);
  808.     if ((r.x.ax != 0x1954) || (r.x.bx < 14)) {
  809.         fputs ("Unable to initialize Video FOSSIL, aborting....\n\n",stderr);
  810.         exit (255);
  811.     }
  812. }
  813.  
  814. static void pascal vfossil_close ()
  815.  
  816. {
  817.    union REGS r;
  818.  
  819.    vfossil_cursor (1);
  820.  
  821.    r.h.ah = 0x81;
  822.    r.h.al = 2;
  823.  
  824.    int86 (0x14, &r, &r);
  825. }
  826.