home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / memacs / ue311c.arc / HP150.C < prev    next >
C/C++ Source or Header  |  1990-08-16  |  13KB  |  568 lines

  1. /*
  2.  * The routines in this file provide support for HP150 screens
  3.  * and routines to access the Keyboard through KEYCODE mode.
  4.  * It compiles into nothing if not an HP150 screen device.
  5.  * added by Daniel Lawrence
  6.  */
  7.  
  8. #define    termdef    1            /* don't define "term" external */
  9.  
  10. #include        <stdio.h>
  11. #include        "estruct.h"
  12. #include    "eproto.h"
  13. #include    "edef.h"
  14. #include    "elang.h"
  15.  
  16. #if     HP150
  17.  
  18. #define NROW    24                      /* Screen size.                 */
  19. #define NCOL    80                      /* Edit if you want to.         */
  20. #define    MARGIN    8            /* size of minimim margin and    */
  21. #define    SCRSIZ    64            /* scroll size for extended lines */
  22. #define    NPAUSE    15            /* # times thru update to pause */
  23. #define BEL     0x07                    /* BEL character.               */
  24. #define ESC     0x1B                    /* ESC character.               */
  25.  
  26. extern int PASCAL NEAR  openhp();    /* Forward references.          */
  27. extern int PASCAL NEAR    hpflush();
  28. extern int PASCAL NEAR  closehp();
  29. extern int PASCAL NEAR    hp15kopen();
  30. extern int PASCAL NEAR    hp15kclose();
  31. extern int PASCAL NEAR  hp15move();
  32. extern int PASCAL NEAR  hp15eeol();
  33. extern int PASCAL NEAR  hp15eeop();
  34. extern int PASCAL NEAR  hp15beep();
  35. extern int PASCAL NEAR    gethpkey();
  36. extern int PASCAL NEAR    hp15rev();
  37. extern int PASCAL NEAR    hp15cres();
  38. #if    COLOR
  39. extern int PASCAL NEAR    hp15fcol();
  40. extern int PASCAL NEAR    hp15bcol();
  41. #endif
  42.  
  43. PASCAL NEAR hp15parm();
  44. PASCAL NEAR rawon();
  45. PASCAL NEAR rawoff();
  46. PASCAL NEAR ckeyoff();
  47. PASCAL NEAR ckeyon();
  48. PASCAL NEAR agios();
  49. PASCAL NEAR keycon();
  50. PASCAL NEAR keycoff();
  51. PASCAL NEAR defkey();
  52. PASCAL NEAR undefkey();
  53. PASCAL NEAR dsplbls();
  54.  
  55. /*    Some needed locals    */
  56.  
  57. union REGS r;        /* register set for bios and dos (AGIOS) calls */
  58. int capslock = 0;    /* caps lock flag */
  59.  
  60. /*
  61.  * Standard terminal interface dispatch table. Most of the fields point into
  62.  * "termio" code.
  63.  */
  64. TERM    term    = {
  65.     NROW-1,
  66.         NROW-1,
  67.         NCOL,
  68.         NCOL,
  69.     MARGIN,
  70.     SCRSIZ,
  71.     NPAUSE,
  72.     openhp,
  73.         closehp,
  74.     hp15kopen,
  75.     hp15kclose,
  76.     gethpkey,
  77.         ttputc,
  78.         hpflush,
  79.         hp15move,
  80.         hp15eeol,
  81.         hp15eeop,
  82.         hp15beep,
  83.         hp15rev,
  84.         hp15cres
  85. #if    COLOR
  86.     , hp15fcol,
  87.     hp15bcol
  88. #endif
  89. };
  90.  
  91. PASCAL NEAR hp15move(row, col)
  92. {
  93.         ttputc(ESC);
  94.         ttputc('&');
  95.         ttputc('a');
  96.         hp15parm(col);
  97.         ttputc('c');
  98.         hp15parm(row);
  99.         ttputc('R');
  100. }
  101.  
  102. PASCAL NEAR hpflush()
  103.  
  104. {
  105.  
  106. }
  107.  
  108. PASCAL NEAR hp15eeol()
  109. {
  110.         ttputc(ESC);
  111.         ttputc('K');
  112. }
  113.  
  114. PASCAL NEAR hp15eeop()
  115. {
  116.         ttputc(ESC);
  117.         ttputc('J');
  118. }
  119.  
  120. PASCAL NEAR hp15rev(status)    /* change the reverse video status */
  121.  
  122. int status;    /* TRUE = on, FALSE = off */
  123.  
  124. {
  125.     ttputc(ESC);
  126.     ttputc('&');
  127.     ttputc('d');
  128.     ttputc((status != FALSE) ? 'B': '@');
  129. }
  130.  
  131. PASCAL NEAR hp15cres()    /* change screen resolution */
  132.  
  133. {
  134.     return(TRUE);
  135. }
  136.  
  137. PASCAL NEAR spal()        /* change pallette register */
  138.  
  139. {
  140.     /*   not here */
  141. }
  142.  
  143. PASCAL NEAR hp15beep()
  144. {
  145.         ttputc(BEL);
  146.         ttflush();
  147. }
  148.  
  149. PASCAL NEAR hp15parm(n)
  150.  
  151. register int    n;
  152.  
  153. {
  154.         register int    q;
  155.  
  156.         q = n/10;
  157.         if (q != 0)
  158.                 hp15parm(q);
  159.         ttputc((n%10) + '0');
  160. }
  161.  
  162. #if    COLOR
  163. PASCAL NEAR hp15fcol()    /* we really can't do colors here, so just ignore it */
  164. {
  165. }
  166.  
  167. PASCAL NEAR hp15bcol()    /* we really can't do colors here, so just ignore it */
  168. {
  169. }
  170. #endif
  171.  
  172. PASCAL NEAR gethpkey()    /* get a key from the HP keyboard while in keycode mode */
  173.  
  174. {
  175.     unsigned c;        /* character to translate */
  176.     int devid;        /* device ID */
  177.     int ctype;        /* type of character gotten */
  178.     unsigned shiftb;    /* state of shift keys */
  179.     int i;            /* index in first translation loop */
  180.  
  181.     /* return any keystrokes waiting in the
  182.        type ahead buffer */
  183.     if (in_check())
  184.         return(in_get());
  185.  
  186.     /* grab the next 4 char sequence */
  187. next:    shiftb = ttgetc();
  188.     devid = ttgetc();
  189.     c = ttgetc();
  190.     ttgetc();        /* skip null byte */
  191.  
  192.     /* make sure we are from the keyboard */
  193.     if (devid != 192)
  194.         goto next;
  195.  
  196.     /* if normal ascii, return it */
  197.     if ((shiftb & 0x80) == 0) {
  198.         if (capslock && c >= 'a' && c <= 'z')
  199.             c -= 32;
  200.         return(c);
  201.     }
  202.  
  203.     /* check specifically for the caps lock key */
  204.     if (c == 0x56) {
  205.         capslock = ~capslock;
  206.         goto next;
  207.     }
  208.  
  209.     /* interpet it as an extended HP sequence */
  210.     c = extcode(shiftb, c);
  211.  
  212.     /* if it becomes standard ascii... just return it */
  213.     if ((c >> 8) == 0)
  214.         return(c & 255);
  215.  
  216.     /* or return it as en extended emacs internal sequence */
  217.     in_put(c >> 8);        /* prefix byte */
  218.     in_put(c & 255);    /* event code byte */
  219.     return(0);        /* extended escape sequence */
  220. }
  221.  
  222. /*    extcode:    resolve MSDOS extended character codes
  223.             encoding the proper sequences into emacs
  224.             printable character specifications
  225. */
  226.  
  227. int extcode(shiftb, c)
  228.  
  229. unsigned shiftb;    /* shift flag */
  230. unsigned c;        /* byte following a zero extended char byte */
  231.  
  232. {
  233.     int sstate;    /* state of the various shift keys */
  234.  
  235.     /* remember if we are shifted */
  236.     if ((shiftb & 0x04) != 0)
  237.         sstate = SHFT;
  238.     else
  239.         sstate = 0;
  240.  
  241.     /* remember if we are alted (extended char keys) */
  242.     if ((shiftb & 0x30) != 0)
  243.         sstate |= ALTD;
  244.  
  245.     /* remember if we are controled */
  246.     if ((shiftb & 0x08) != 0)
  247.         sstate |= CTRL;
  248.  
  249.     /* function keys 1 through 9 */
  250.     if (c >= 0 && c < 9)
  251.         return(sstate | SPEC | c + 1 + '0');
  252.  
  253.     /* function key 10 */
  254.     if (c == 9)
  255.         return(sstate | SPEC | '0');
  256.  
  257.     /* function key 11 */
  258.     if (c == 10)
  259.         return(sstate | SPEC | 'E');
  260.  
  261.     /* function key 12 */
  262.     if (c == 11)
  263.         return(sstate | SPEC | 'T');
  264.  
  265.     /* some others as well */
  266.     switch (c) {
  267.  
  268.         case 36:    return(sstate | 9);    /* tab */
  269.         case 37:    return(sstate | 13);    /* ret */
  270.         case 39:    return(sstate | 8);    /* backspace */
  271.         case 48:    return(sstate | 48);    /* zero */
  272.         case 49:    return(sstate | 49);    /* one */
  273.         case 50:    return(sstate | 50);    /* two */
  274.         case 51:    return(sstate | 51);    /* three */
  275.         case 52:    return(sstate | 52);    /* four */
  276.         case 53:    return(sstate | 53);    /* five */
  277.         case 54:    return(sstate | 54);    /* six */
  278.         case 55:    return(sstate | 55);    /* seven */
  279.         case 56:    return(sstate | 56);    /* eight */
  280.         case 57:    return(sstate | 57);    /* nine */
  281.         case 80:    return(sstate | 13);    /* enter */
  282.         case 84:    return(sstate | 27);    /* break -> ESC */
  283.         case 85:    return(sstate | 27);    /* esc */
  284.         case 88:    return(sstate | 24);    /* stop -> ^X */
  285.         case 112:    return(sstate | 45);    /* N-minus */
  286.         case 113:    return(sstate | 42);    /* N-asterisk */
  287.         case 114:    return(sstate | 43);    /* N-plus */
  288.         case 115:    return(sstate | 47);    /* N-slash */
  289.         case 116:    return(sstate | 44);    /* N-comma */
  290.         case 117:    return(sstate | 13);    /* N-enter */
  291.         case 118:    return(sstate | 9);    /* N-tab */
  292.         case 119:    return(sstate | 46);    /* N-period */
  293.  
  294.         case 44:
  295.         case 45:
  296.         case 110:    return(sstate | SPEC | '<');    /* HOME */
  297.  
  298.         case 32:
  299.         case 41:
  300.         case 101:    return(sstate | SPEC | 'P');    /* cursor up */
  301.  
  302.         case 47:    return(sstate | SPEC | 'Z');    /* page up */
  303.  
  304.         case 35:
  305.         case 42:
  306.         case 97:    return(sstate | SPEC | 'B');    /* cursor left */
  307.  
  308.         case 34:
  309.         case 43:
  310.         case 99:    return(sstate | SPEC | 'F');    /* cursor right */
  311.  
  312.         case 82:    return(sstate | SPEC | '>');    /* end */
  313.  
  314.         case 33:
  315.         case 40:
  316.         case 98:    return(sstate | SPEC | 'N');    /* cursor down */
  317.  
  318.         case 46:
  319.         case 108:    return(sstate | SPEC | 'V');    /* page down */
  320.  
  321.         case 64:
  322.         case 70:
  323.         case 107:    return(sstate | SPEC | 'C');    /* insert */
  324.  
  325.         case 65:
  326.         case 71:
  327.         case 109:    return(sstate | SPEC | 'D');    /* delete */
  328.  
  329.         /* the HP has some extra keys we need to map */
  330.  
  331.         case 83:
  332.         case 89:    return(sstate | SPEC | 'Q');    /* reformat paragraph */
  333.         case 81:    return(sstate | CTLX | 'C');    /* shell up to system */
  334.         case 67:    return(sstate | SPEC | CTRL | 'L'); /* center display */
  335.         case 68:    return(sstate | CTRL | 'O');    /* open line */
  336.         case 69:    return(sstate | CTRL | 'K');    /* Kill to end of line */
  337.     }
  338.  
  339.     return(sstate | c);
  340. }
  341.  
  342. PASCAL NEAR openhp()        /* open the HP150 screen for input */
  343.  
  344. {
  345.     strcpy(sres, "NORMAL");
  346.     revexist = TRUE;
  347. }
  348.  
  349. PASCAL NEAR closehp()        /* close the HP150 screen for input */
  350.  
  351. {
  352. }
  353.  
  354. PASCAL NEAR hp15kopen()        /* open the HP150 keyboard for input */
  355.  
  356. {
  357.     /* define key charectoristics with AGIOS call (0, 40) */
  358.     defkey();
  359.  
  360.     /* Turn on RAW mode with MSDOS call 44h */
  361.     rawon();
  362.  
  363.     /* Turn off Control-C checking  MS-DOS 33h */
  364.     ckeyoff();
  365.  
  366.     /* Turn on keycode mode with AGIOS call (0,43) */
  367.     keycon();
  368.  
  369.     /* display the application softkey labels */
  370.     dsplbls();
  371. }
  372.  
  373. PASCAL NEAR hp15kclose()    /* close the HP150 keyboard for input */
  374.  
  375. {
  376.     /* define key charectoristics with AGIOS call (0, 40) */
  377.     undefkey();
  378.     
  379.     /* Turn off RAW mode with MSDOS call 44h */
  380.     rawoff();
  381.  
  382.     /* Turn on Control-C checking  MS-DOS 33h */
  383.     ckeyon();
  384.  
  385.     /* Turn off keycode mode with AGIOS call (0,43) */
  386.     keycoff();
  387. }
  388.  
  389. PASCAL NEAR rawon()    /* put the HP150 keyboard into RAW mode */
  390.  
  391. {
  392.     /* get the IO control info */
  393.  
  394.     r.x.ax = 0x4400;    /* IO ctrl get device information */
  395.     r.x.bx = 0x0001;    /* File handle; 1 for console */
  396.     intdos(&r, &r);        /* go fer it */
  397.  
  398.     r.h.dh = 0;        /* clear high byte for put */
  399.     r.h.dl |= 0x20;        /* set raw bit */
  400.  
  401.     /* and put it back */
  402.  
  403.     r.x.ax = 0x4401;    /* IO ctrl put device information */
  404.     r.x.bx = 0x0001;    /* File handle; 1 for console */
  405.     intdos(&r, &r);        /* go fer it */
  406. }
  407.  
  408. PASCAL NEAR rawoff()    /* put the HP150 keyboard into COOKED mode */
  409.  
  410. {
  411.     /* get the IO control info */
  412.  
  413.     r.x.ax = 0x4400;    /* IO ctrl get device information */
  414.     r.x.bx = 0x0001;    /* File handle; 1 for console */
  415.     intdos(&r, &r);        /* go fer it */
  416.  
  417.     r.h.dh = 0;        /* clear high byte for put */
  418.     r.h.dl &= 0xdf;        /* set raw bit */
  419.  
  420.     /* and put it back */
  421.  
  422.     r.x.ax = 0x4401;    /* IO ctrl put device information */
  423.     r.x.bx = 0x0001;    /* File handle; 1 for console */
  424.     intdos(&r, &r);        /* go fer it */
  425. }
  426.  
  427. PASCAL NEAR ckeyoff()    /* turn control-C trapping off */
  428.  
  429. {
  430.     r.h.ah = 0x33;    /* ctrl-break check */
  431.     r.h.al = 1;    /* set the state of the ctrl-break check */
  432.     r.h.dl = 0;    /* turn it off */
  433.     intdos(&r, &r);
  434. }
  435.  
  436. PASCAL NEAR ckeyon()    /* turn control-C trapping on */
  437.  
  438. {
  439.     r.h.ah = 0x33;    /* ctrl-break check */
  440.     r.h.al = 1;    /* set the state of the ctrl-break check */
  441.     r.h.dl = 1;    /* turn it on */
  442.     intdos(&r, &r);
  443. }
  444.  
  445. #ifdef    unsigned
  446. #undef    unsigned
  447. #endif
  448.  
  449. PASCAL NEAR agios(buf, len)    /* perform an AGIOS call */
  450.  
  451. char *buf;    /* sequence of bytes in command */
  452. int len;    /* length of command in bytes */
  453.  
  454. {
  455.     r.x.ax = 0x4403;    /* I/O ctrl write */
  456.     r.x.bx = 1;        /* console handle */
  457.     r.x.cx = len;        /* buffer length */
  458.     r.x.dx = (unsigned)buf;    /* buffer address */
  459.     return(intdos(&r, &r));    /* do it */
  460. }
  461.  
  462. PASCAL NEAR keycon()    /* turn keycode mode on */
  463.  
  464. {
  465.     static char cmd[] = {43, 0, 1};
  466.  
  467.     return(agios(&cmd[0], 3));
  468. }
  469.  
  470. PASCAL NEAR keycoff()    /* turn keycode mode off */
  471.  
  472. {
  473.     static char cmd[] = {43, 0, 0};
  474.  
  475.     return(agios(&cmd[0], 3));
  476. }
  477.  
  478. PASCAL NEAR defkey()    /* change all special keys to intercept mode */
  479.  
  480. {
  481.     static char cmd[] = {40, 0, 2, 0, 0xfe, 0};
  482.  
  483.     return(agios(&cmd[0], 6));
  484. }
  485.  
  486. PASCAL NEAR undefkey()    /* change all special keys to intercept mode */
  487.  
  488. {
  489.     static char cmd[] = {40, 0, 0, 0, 0xfe, 0};
  490.  
  491.     return(agios(&cmd[0], 6));
  492. }
  493.  
  494. PASCAL NEAR dsplbls()    /* display the application softkey labels on the screen */
  495.  
  496. {
  497.     static char cmd[] = {11, 0};
  498.  
  499.     return(agios(&cmd[0], 2));
  500. }
  501.  
  502. #if    FLABEL
  503. PASCAL NEAR fnclabel(f, n)        /* label a function key */
  504.  
  505. int f,n;    /* default flag, numeric argument */
  506.  
  507. {
  508.     register int status;    /* return status */
  509.     register int i;        /* loop index */
  510.     char lbl[17];    /* returned label contents */
  511.     /* AGIOS command buffer */
  512.     static char cmd[] = {8, 0, 1, 0, 7, 7, 7, 7, 10, 0, 10, 0};
  513.     /*                   code  key#  ptr to      top    bottom
  514.                                      label string  attribute */
  515.     union {        /* union to cast ptr into AGIOS arg string */
  516.         char *ptr;    /* pointer to arg string */
  517.         char cstr[4];
  518.     } ptru;
  519.  
  520.     /* must have a numeric argument */
  521.     if (f == FALSE) {
  522.         mlwrite(TEXT159);
  523. /*                      "%Need function key number" */
  524.         return(FALSE);
  525.     }
  526.  
  527.     /* and it must be a legal key number */
  528.     if (n < 1 || n > 8) {
  529.         mlwrite(TEXT160);
  530. /*                      "%Function key number out of range" */
  531.         return(FALSE);
  532.     }
  533.  
  534.     /* get the string to send */
  535.     status = mlreply(TEXT161, &lbl[0], 17);
  536. /*                       "Label contents: " */
  537.     if (status != TRUE)
  538.         return(status);
  539.  
  540.     /* pad the label out */
  541.     for (i=0; i < 17; i++) {
  542.         if (lbl[i] == 0)
  543.             break;
  544.     }
  545.     for (; i < 16; i++)
  546.         lbl[i] = ' ';
  547.     lbl[16] = 0;
  548.  
  549.     /* set up the parameters */
  550.     cmd[2] = n;            /* function key number */
  551.     ptru.ptr = &lbl[0];        /* set up pointer to label string */
  552. force:    cmd[4] = ptru.cstr[0];
  553.     cmd[5] = ptru.cstr[1];
  554.     cmd[6] = ptru.cstr[2];
  555.     cmd[7] = ptru.cstr[3];
  556.  
  557.     /* and send it out */
  558.     agios(&cmd[0], 12);
  559.     return(TRUE);
  560. }
  561. #endif
  562. #else
  563. PASCAL NEAR h15hello()
  564.  
  565. {
  566. }
  567. #endif
  568.