home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / convergent / ctvt10.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  27KB  |  1,204 lines

  1. #if NCR
  2. char *ckvt100v = "CTOS VT101 Emulation-1.05 NCR Kbd, January 1988";
  3. #else
  4. char *ckvt100v = "CTOS VT101 Emulation-1.05 CT Kbd, January 1988";
  5. #endif
  6.  
  7. /*  C K V T 1 0 0  --  DEC VT101 terminal emulation */
  8.  
  9. /*  Joel Dunn, UNC-CH, June 1987 */
  10.  
  11. /*    Modifications -- August 1987, v1.02, Joel Dunn UNC-CH
  12.         - add support for G0 and G1 character sets
  13.         - support some VT100 graphic sequences
  14.         - change VT100 alternate keypad to be on CT physical keypad
  15.         - set up compile option for NCR or CT keypad codes
  16.  
  17.     Modifications -- September 1987, v1.03, Joel Dunn UNC-CH
  18.         - try again to get tab stops working properly
  19.  
  20.     Modifications -- September 1987, v1.04, Joel Dunn UNC-CH
  21.         - add F8 function to reset terminal to original values
  22.           in case emulation is screwed up by line garbage, etc.
  23.  
  24.     Modifications -- January 1988, v1.05, Joel Dunn UNC-CH
  25.         - change delete key to send 0x7f instead of a "break",
  26.           use S + delete to send a "break"
  27.         - change variable "c" in kbdin to int, was char and having
  28.           problems with sign promotion
  29. */
  30.  
  31. #include "ctermi.h"
  32.  
  33. /* from ckmain.c */
  34. extern int local, speed, escape, duplex, parity, flow, seslog, mdmtyp,
  35.             termtype;
  36. extern char ttname[], sesfil[];
  37.  
  38. /* from CTOS */
  39. extern char bsvid[130];
  40.  
  41. /* from ckconu.c */
  42. extern int c;            /* c is a character, but must be signed 
  43.                    integer to pass thru -1, which is the
  44.                    modem disconnection signal, and is
  45.                    different from the character 0377 */
  46. extern int i, active;
  47.  
  48. /* global variables declared in this module */
  49. int escapeset=0, altkeypad=0;
  50. int modecursor=0, modescreen=0, modecrlf=0;
  51. int bracket=0, question=0, semicolon=0;
  52. int value[2] = {0,0};
  53. int valuef[2] = {0,0};
  54. int openparen=0, closeparen=0, shiftflag=0;
  55. int scursorl=0, scursorc=0, sattr=0;
  56. int xon=1;
  57. int topmar=1, botmar=24;
  58. char vidstate[16];
  59. int tabstop[80] =
  60.     {
  61.     1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,
  62.     0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
  63.     1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,
  64.     0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0
  65.     };
  66. int g0[128] = {
  67.   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
  68.   26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
  69.   50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,
  70.   74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,
  71.   98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,
  72.   116,117,118,119,120,121,122,123,124,125,126,127};
  73. int g1[128] = {
  74.   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
  75.   26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
  76.   50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,
  77.   74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,
  78.   98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,
  79.   116,117,118,119,120,121,122,123,124,125,126,127};
  80. int us[128] = {
  81.   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
  82.   26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
  83.   50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,
  84.   74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,
  85.   98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,
  86.   116,117,118,119,120,121,122,123,124,125,126,127};
  87. int uk[128] = {
  88.   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
  89.   26,27,28,29,30,31,32,33,34,177,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
  90.   50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,
  91.   74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,
  92.   98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,
  93.   116,117,118,119,120,121,122,123,124,125,126,127};
  94. int sc[128] = {
  95.   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
  96.   26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
  97.   50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,
  98.   74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,32,27,255,
  99.   32,32,32,32,178,30,32,32,238,240,239,237,219,218,218,218,218,218,
  100.   226,227,221,220,225,29,31,26,24,177,61,127};
  101.  
  102. /*  C O N V T 1 0 0 --  Connect in VT100 mode */
  103. convt100()
  104.  
  105. {
  106.  
  107.     /* setup of VT100 session */
  108.     setkbdled(0,0x00); /* set F10 LED off (cr/lf set to lf only) */
  109.     setkbdled(1,0x00); /* set F9 LED off (screen in green on black) */
  110.     printf("\n\nConnected in VT100 Emulation Mode\n");
  111.     active = 1;
  112.     while (((c = ttinc(0)) >= 0) & active)
  113.         {
  114.  
  115. /* read, prints port input */
  116.  
  117.         if (c > 0)
  118.             {
  119.             /* log if session log on */
  120.             if (seslog) zchout(ZSFILE,c);
  121.             linein(c);
  122.             }
  123.  
  124. /* read, prints keyboard input */
  125.  
  126.         c = 0;
  127.         if (xon) c = coninc(0); /* allow all 256 keyboard characters */
  128.         if (c == escape) 
  129.             {       /* Look for local escape char */
  130.                 c = coninc(9999) & 0177;
  131.                 doesc(c);
  132.             } 
  133.         else if ((c > 0x1f) && (c < 0x7f))
  134.                 {    /* Ordinary ascii character */
  135.                 ttoc(dopar(c));    /* Send with desired parity */
  136.                     if (duplex)
  137.                     {    /* Half duplex? */
  138.                     conoc(c); /* Yes, also echo it. */
  139.                     if (seslog) zchout(ZSFILE,c);
  140.                     /* and log it, if logging */
  141.                         }            
  142.                 }
  143.         /* process control and special characters */
  144.         else if (c) kbdin(c);
  145.  
  146.         }
  147.         if (c < 0) 
  148.             { /* Comm line hangup detected*/
  149.                 printf("\r\nCommunications line failure\r\n");
  150.             }
  151.         conres();            /* Reset the console. */
  152.         setkbdled(0,0x00);    /* set F10 LED off */
  153.         setkbdled(1,0x00);    /* set F9 LED off */
  154.         printf("\nVT100 Emulation Disconnected\n");
  155.         return(0);
  156. }
  157. /*  K b d i n */
  158. kbdin(c)
  159.  
  160.     int c;
  161.  
  162. {
  163.     switch (c)
  164.         {
  165.         /* alternate keypad */
  166.         case 0xb0:        /* S - SS - num 0 = AKP 0 */
  167.             if (altkeypad)
  168.                 {
  169.                 ttoc(dopar(033));
  170.                 ttoc(dopar(0117));
  171.                 ttoc(dopar(0160));
  172.                 }
  173.             break;
  174. #if NCR
  175.         case 0xbc:        /* S - SS - num 1 = AKP 1 */
  176. #else
  177.         case 0xe0:        /* S - SS - num 1 = AKP 1 */
  178. #endif
  179.             if (altkeypad)
  180.                 {
  181.                 ttoc(dopar(033));
  182.                 ttoc(dopar(0117));
  183.                 ttoc(dopar(0161));
  184.                 }
  185.             break;
  186. #if NCR
  187.         case 0xbe:        /* S - SS - num 2 = AKP 2 */
  188. #else
  189.         case 0xb2:        /* S - SS - num 2 = AKP 2 */
  190. #endif
  191.             if (altkeypad)
  192.                 {
  193.                 ttoc(dopar(033));
  194.                 ttoc(dopar(0117));
  195.                 ttoc(dopar(0162));
  196.                 }
  197.             break;
  198. #if NCR
  199.         case 0xfc:        /* S - SS - num 3 = AKP 3 */
  200. #else
  201.         case 0xb3:        /* S - SS - num 3 = AKP 3 */
  202. #endif
  203.             if (altkeypad)
  204.                 {
  205.                 ttoc(dopar(033));
  206.                 ttoc(dopar(0117));
  207.                 ttoc(dopar(0163));
  208.                 }
  209.             break;
  210. #if NCR
  211.         case 0xdb:        /* S - SS - num 4 = AKP 4 */
  212. #else
  213.         case 0xfb:        /* S - SS - num 4 = AKP 4 */
  214. #endif
  215.             if (altkeypad)
  216.                 {
  217.                 ttoc(dopar(033));
  218.                 ttoc(dopar(0117));
  219.                 ttoc(dopar(0164));
  220.                 }
  221.             break;
  222. #if NCR
  223.         case 0xdd:        /* S - SS - num 5 = AKP 5 */
  224. #else
  225.         case 0xfd:        /* S - SS - num 5 = AKP 5 */
  226. #endif
  227.             if (altkeypad)
  228.                 {
  229.                 ttoc(dopar(033));
  230.                 ttoc(dopar(0117));
  231.                 ttoc(dopar(0165));
  232.                 }
  233.             break;
  234. #if NCR
  235.         case 0xdc:        /* S - SS - num 6 = AKP 6 */
  236. #else
  237.         case 0xb6:        /* S - SS - num 6 = AKP 6 */
  238. #endif
  239.             if (altkeypad)
  240.                 {
  241.                 ttoc(dopar(033));
  242.                 ttoc(dopar(0117));
  243.                 ttoc(dopar(0166));
  244.                 }
  245.             break;
  246. #if NCR
  247.         case 0xfb:        /* S - SS - num 7 = AKP 7 */
  248. #else
  249.         case 0xfc:        /* S - SS - num 7 = AKP 7 */
  250. #endif
  251.             if (altkeypad)
  252.                 {
  253.                 ttoc(dopar(033));
  254.                 ttoc(dopar(0117));
  255.                 ttoc(dopar(0167));
  256.                 }
  257.             break;
  258. #if NCR
  259.         case 0xfd:        /* S - SS - num 8 = AKP 8 */
  260. #else
  261.         case 0xdc:        /* S - SS - num 8 = AKP 8 */
  262. #endif
  263.             if (altkeypad)
  264.                 {
  265.                 ttoc(dopar(033));
  266.                 ttoc(dopar(0117));
  267.                 ttoc(dopar(0170));
  268.                 }
  269.             break;
  270. #if NCR
  271.         case 0x85:        /* S - SS - num 9 = AKP 9 */
  272. #else
  273.         case 0xb9:        /* S - SS - num 9 = AKP 9 */
  274. #endif
  275.             if (altkeypad)
  276.                 {
  277.                 ttoc(dopar(033));
  278.                 ttoc(dopar(0117));
  279.                 ttoc(dopar(0171));
  280.                 }
  281.             break;
  282. #if NCR
  283.         case 0x8c:        /* S - SS - GO = AKP DASH */
  284. #else
  285.         case 0xc9:        /* S - SS - GO = AKP DASH */
  286. #endif
  287.             if (altkeypad)
  288.                 {
  289.                 ttoc(dopar(033));
  290.                 ttoc(dopar(0117));
  291.                 ttoc(dopar(0155));
  292.                 }
  293.             break;
  294. #if NCR
  295.         case 0xac:        /* S - SS - num dash = AKP COMMA */
  296. #else
  297.         case 0xad:        /* S - SS - num dash = AKP COMMA */
  298. #endif
  299.             if (altkeypad)
  300.                 {
  301.                 ttoc(dopar(033));
  302.                 ttoc(dopar(0117));
  303.                 ttoc(dopar(0154));
  304.                 }
  305.             break;
  306. #if NCR
  307.         case 0xc9:        /* S - SS - num next = AKP ENTER */
  308. #else
  309.         case 0x8a:        /* S - SS - num next = AKP ENTER */
  310. #endif
  311.             if (altkeypad)
  312.                 {
  313.                 ttoc(dopar(033));
  314.                 ttoc(dopar(0117));
  315.                 ttoc(dopar(0115));
  316.                 }
  317.             break;
  318.         case 0xae:        /* S - SS - num . = AKP PERIOD */
  319.             if (altkeypad)
  320.                 {
  321.                 ttoc(dopar(033));
  322.                 ttoc(dopar(0117));
  323.                 ttoc(dopar(0156));
  324.                 }
  325.             break;
  326.         case 0xd5:        /* S - SS - F1 = F1 */
  327.             if (altkeypad)
  328.                 {
  329.                 ttoc(dopar(033));
  330.                 ttoc(dopar(0117));
  331.                 ttoc(dopar(0120));
  332.                 }
  333.             break;
  334.         case 0xd6:        /* S - SS - F2 = F2 */
  335.             if (altkeypad)
  336.                 {
  337.                 ttoc(dopar(033));
  338.                 ttoc(dopar(0117));
  339.                 ttoc(dopar(0121));
  340.                 }
  341.             break;
  342.         case 0xd7:        /* S - SS - F3 = F3 */
  343.             if (altkeypad)
  344.                 {
  345.                 ttoc(dopar(033));
  346.                 ttoc(dopar(0117));
  347.                 ttoc(dopar(0122));
  348.                 }
  349.             break;
  350.         case 0xd8:        /* S - SS - F3 = F3 */
  351.             if (altkeypad)
  352.                 {
  353.                 ttoc(dopar(033));
  354.                 ttoc(dopar(0117));
  355.                 ttoc(dopar(0123));
  356.                 }
  357.             break;
  358.         case 0x01:        /* up arrow */
  359.             if (modecursor)
  360.                 {
  361.                 ttoc(dopar(033));
  362.                 ttoc(dopar(0117));
  363.                 ttoc(dopar(0101));
  364.                 }
  365.             else
  366.                 {
  367.                 ttoc(dopar(033));
  368.                 ttoc(dopar(0133));
  369.                 ttoc(dopar(0101));
  370.                 }
  371.             break;
  372.         case 0x0b:        /* down arrow */
  373.             if (modecursor)
  374.                 {
  375.                 ttoc(dopar(033));
  376.                 ttoc(dopar(0117));
  377.                 ttoc(dopar(0102));
  378.                 }
  379.             else
  380.                 {
  381.                 ttoc(dopar(033));
  382.                 ttoc(dopar(0133));
  383.                 ttoc(dopar(0102));
  384.                 }
  385.             break;
  386.         case 0x0e:        /* left arrow */
  387.             if (modecursor)
  388.                 {
  389.                 ttoc(dopar(033));
  390.                 ttoc(dopar(0117));
  391.                 ttoc(dopar(0104));
  392.                 }
  393.             else
  394.                 {
  395.                 ttoc(dopar(033));
  396.                 ttoc(dopar(0133));
  397.                 ttoc(dopar(0104));
  398.                 }
  399.             break;
  400.         case 0x12:        /* right arrow */
  401.             if (modecursor)
  402.                 {
  403.                 ttoc(dopar(033));
  404.                 ttoc(dopar(0117));
  405.                 ttoc(dopar(0103));
  406.                 }
  407.             else
  408.                 {
  409.                 ttoc(dopar(033));
  410.                 ttoc(dopar(0133));
  411.                 ttoc(dopar(0103));
  412.                 }
  413.             break;
  414.         case 0x15:                    /* F1 */
  415.             ttoc(dopar(033));
  416.             ttoc(dopar(0117));
  417.             ttoc(dopar(0120));
  418.             break;
  419.         case 0x16:                    /* F2 */
  420.             ttoc(dopar(033));
  421.             ttoc(dopar(0117));
  422.             ttoc(dopar(0121));
  423.             break;
  424.         case 0x17:                    /* F3 */
  425.             ttoc(dopar(033));
  426.             ttoc(dopar(0117));
  427.             ttoc(dopar(0122));
  428.             break;
  429.         case 0x18:                    /* F4 */
  430.             ttoc(dopar(033));
  431.             ttoc(dopar(0117));
  432.             ttoc(dopar(0123));
  433.             break;
  434.         case 0x1d:        /* emergency reset, F8 */
  435.             resetflags();
  436.             resetmode();
  437.             break;
  438.         case 0x1e:        /* toggle screen mode, F9 */
  439.             if (modescreen)
  440.                 {
  441.                 modescreen = 0;
  442.                 conol("\377RF");
  443.                 setkbdled(1,0x00); /* set F9 LED off */
  444.                 }
  445.             else
  446.                 {
  447.                 modescreen = 1;
  448.                 conol("\377RN");
  449.                 setkbdled(1,0xff); /* set F9 LED on */
  450.                 }
  451.             break;
  452.         case 0x1f:        /* toggle cr/lf mode, F10 */
  453.             if (modecrlf)
  454.                 {
  455.                 modecrlf = 0;
  456.                 setkbdled(0,0x00); /* set F10 LED off */
  457.                 }
  458.             else
  459.                 {
  460.                 modecrlf = 1;
  461.                 setkbdled(0,0xff); /* set F10 LED on */
  462.                 }
  463.             break;
  464.         case 0x7f:        /* delete */
  465.             ttoc(dopar(177));
  466.             break;
  467.         case 0xa0:        /* CTRL (SS) - spacebar */
  468.             ttoc(dopar(000));
  469.             break;
  470.         case 0xaf:        /* CTRL (SS) - ? */
  471.             ttoc(dopar(037));
  472.             break;
  473.         case 0xb8:        /* CTRL (SS) - \ */
  474.             ttoc(dopar(034));
  475.             break;
  476.         case 0xc8:        /* S - delete = long break disconnect */
  477.             ttsndb();
  478.             break;
  479.         case 0xde:        /* CTRL (SS) - ~ */
  480.             ttoc(dopar(036));
  481.             break;
  482.         case 0xe1:        /* CTRL (SS) - a */
  483.             ttoc(dopar(001));
  484.             break;
  485.         case 0xe2:        /* CTRL (SS) - b */
  486.             ttoc(dopar(002));
  487.             break;
  488.         case 0xe3:        /* CTRL (SS) - c */
  489.             ttoc(dopar(003));
  490.             break;
  491.         case 0xe4:        /* CTRL (SS) - d */
  492.             ttoc(dopar(004));
  493.             break;
  494.         case 0xe5:        /* CTRL (SS) - e */
  495.             ttoc(dopar(005));
  496.             break;
  497.         case 0xe6:        /* CTRL (SS) - f */
  498.             ttoc(dopar(006));
  499.             break;
  500.         case 0xe7:        /* CTRL (SS) - g */
  501.             ttoc(dopar(007));
  502.             break;
  503.         case 0x08:        /* backtab */
  504.         case 0xe8:        /* CTRL (SS) - h */
  505.             ttoc(dopar(010));
  506.             break;
  507.         case 0x09:        /* tab */    
  508.         case 0xe9:        /* CTRL (SS) - i */
  509.             ttoc(dopar(011));
  510.             break;
  511.         case 0xea:        /* CTRL (SS) - j */
  512.             ttoc(dopar(012));
  513.             break;
  514.         case 0xeb:        /* CTRL (SS) - k */
  515.             ttoc(dopar(013));
  516.             break;
  517.         case 0xec:        /* CTRL (SS) - l */
  518.             ttoc(dopar(014));
  519.             break;
  520.         case 0x0d:        /* return */
  521.         case 0xed:        /* CTRL (SS) - m */
  522.             if (modecrlf)
  523.                 {
  524.                 ttoc(dopar(015));
  525.                 ttoc(dopar(012));
  526.                 }
  527.             else
  528.                 ttoc(dopar(015));
  529.             break;
  530.         case 0xee:        /* CTRL (SS) - n */
  531.             ttoc(dopar(016));
  532.             break;
  533.         case 0xef:        /* CTRL (SS) - o */
  534.             ttoc(dopar(017));
  535.             break;
  536.         case 0xf0:        /* CTRL (SS) - p */
  537.             ttoc(dopar(020));
  538.             break;
  539.         case 0xf1:        /* CTRL (SS) - q */
  540.             ttoc(dopar(021));
  541.             break;
  542.         case 0xf2:        /* CTRL (SS) - r */
  543.             ttoc(dopar(022));
  544.             break;
  545.         case 0xf3:        /* CTRL (SS) - s */
  546.             ttoc(dopar(023));
  547.             break;
  548.         case 0xf4:        /* CTRL (SS) - t */
  549.             ttoc(dopar(024));
  550.             break;
  551.         case 0xf5:        /* CTRL (SS) - u */
  552.             ttoc(dopar(025));
  553.             break;
  554.         case 0xf6:        /* CTRL (SS) - v */
  555.             ttoc(dopar(026));
  556.             break;
  557.         case 0xf7:        /* CTRL (SS) - w */
  558.             ttoc(dopar(027));
  559.             break;
  560.         case 0xf8:        /* CTRL (SS) - x */
  561.             ttoc(dopar(030));
  562.             break;
  563.         case 0xf9:        /* CTRL (SS) - y */
  564.             ttoc(dopar(031));
  565.             break;
  566.         case 0xfa:        /* CTRL (SS) - z */
  567.             ttoc(dopar(032));
  568.             break;
  569.         case 0xff:    /* SS - delete = send answerback message */
  570.             break;
  571.         default:
  572.             break;
  573.         }
  574. }
  575.  
  576. /*  L i n e i n -- Receive characters in VT100 mode */
  577. linein(c)
  578.  
  579. char c;
  580.  
  581. {
  582.     if (c <= 0x1b) vt100cc(c);
  583.     else if (escapeset) vt100esc(c);
  584.     else
  585.         {
  586.         if (shiftflag) conoc(g1[c]);
  587.         else conoc(g0[c]);
  588.         }
  589. }
  590.  
  591. /*  V T 1 0 0 C C -- Process VT100 control characters */
  592. vt100cc(c)
  593.  
  594. char c;
  595.  
  596. {
  597.     char nexttab;
  598.  
  599.     switch (c)
  600.         {
  601.         case 0x00:        /* null */
  602.             break;
  603.         case 0x05:        /* transmit answerback message -- not implemented */
  604.             break;
  605.         case 0x07:        /* bell */
  606.             conoc(0x07);
  607.             break;
  608.         case 0x08:        /* backspace, nondescructive */
  609.             queryvidbs(&bsvid[0], &vidstate[0]);
  610.             if (vidstate[4]) conoc(0x0e);
  611.             break;
  612.         case 0x09: /* tab to next stop, go to EOL if no stops */
  613.             queryvidbs(&bsvid[0], &vidstate[0]);
  614.             for (nexttab=vidstate[4]+1; nexttab<80; nexttab++)
  615.                 if (tabstop[nexttab]) break;
  616.             conol("\377C");
  617.             conoc(nexttab);
  618.             conoc(vidstate[3]);
  619.             break;
  620.         case 0x0b:        /* vertical tab -- as line feed */
  621.         case 0x0c:        /* form feed -- process as line feed */
  622.         case 0x0a:        /* line feed */
  623.             if (modecrlf) conoc(0x0a);
  624.             else
  625.                 {
  626.                 /* scroll up or move down cursor */
  627.                 queryvidbs(&bsvid[0], &vidstate[0]);
  628.                 if ((botmar-1) == vidstate[3])
  629.                     {
  630.                     conxo(2,"\377S");
  631.                     conoc(topmar-1);
  632.                     conoc(botmar);
  633.                     conxo(2,"\001U");
  634.                     }
  635.                 else conoc(0x0b);
  636.                 }
  637.             break;
  638.         case 0x0d:                /* carriage return */
  639.             queryvidbs(&bsvid[0], &vidstate[0]);
  640.             conxo(3,"\377C\000");
  641.             conoc(vidstate[3]);
  642.             break;
  643.         case 0x0e:                /* shift out */
  644.             shiftflag = 1;
  645.             break;
  646.         case 0x0f:                /* shift in */
  647.             shiftflag = 0;
  648.             break;
  649.         case 0x11:                /* XON */
  650.             xon = 1;
  651.             break;
  652.         case 0x13:                /* XOFF */
  653.             xon = 0;
  654.             break;
  655.         case 0x19:                /* cancel */
  656.         case 0x1a:                /* substitute */
  657.             resetflags();
  658.             break;
  659.         case 0x1b:                /* escape */
  660.             escapeset = 1;
  661.             break;
  662.         
  663.         }
  664. }
  665.  
  666. /*  V T 1 0 0 E S C -- Process VT100 escape sequences */
  667. vt100esc(c)
  668.  
  669. char c;
  670.  
  671. {
  672.  
  673.     /* set special grouping flags */
  674.     if (c == '[')
  675.         {
  676.         bracket = 1;
  677.         return(0);
  678.         }
  679.     else if (c == '?')
  680.         {
  681.         question = 1;
  682.         return(0);
  683.         }
  684.     else if (c == ';')
  685.         {
  686.         semicolon = 1;
  687.         valuef[0] = 1;
  688.         return(0);
  689.         }
  690.     else if (c == '(')
  691.         {
  692.         openparen = 1;
  693.         return(0);
  694.         }
  695.     else if (c == ')')
  696.         {
  697.         closeparen = 1;
  698.         return(0);
  699.         }
  700.     /* collect numeric values */
  701.     else if ((isdigit(c)) && ((bracket) || (question)))
  702.         {
  703.         value[semicolon] *= 10;
  704.         value[semicolon] += (c - '0');
  705.         valuef[semicolon] = 1;
  706.         return(0);
  707.         }
  708.  
  709.     /* Escape-openparen sequences */
  710.     if (openparen)
  711.         {
  712.         switch (c)
  713.             {
  714.             case 'A':
  715.             for (i=0;i<128;i++) g0[i] = uk[i];
  716.             break;
  717.             case 'B':
  718.             for (i=0;i<128;i++) g0[i] = us[i];
  719.             break;
  720.             case '0':
  721.             for (i=0;i<128;i++) g0[i] = sc[i];
  722.             break;
  723.             }
  724.         resetflags();
  725.         return(0);
  726.         }
  727.  
  728.     /* Escape-closeparen sequences */
  729.     if (closeparen)
  730.         {
  731.         switch (c)
  732.             {
  733.             case 'A':
  734.             for (i=0;i<128;i++) g1[i] = uk[i];
  735.             break;
  736.             case 'B':
  737.             for (i=0;i<128;i++) g1[i] = us[i];
  738.             break;
  739.             case '0':
  740.             for (i=0;i<128;i++) g1[i] = sc[i];
  741.             break;
  742.             }
  743.         resetflags();
  744.         return(0);
  745.         }
  746.  
  747.     /* ANSI compatible sequences */
  748.     if ((bracket) && (question) && (valuef[0]))
  749.         {
  750.         ansiseq(c);
  751.         resetflags();
  752.         return(0);
  753.         }
  754.  
  755.     /* two value sequences */
  756.     if ((bracket) && (semicolon))
  757.         {
  758.         nnformat(c);
  759.         resetflags();
  760.         return(0);
  761.         }
  762.  
  763.     /* Escape-bracket-value sequences */
  764.     if ((bracket) && (valuef[0]))
  765.         {
  766.         brval(c);
  767.         resetflags();
  768.         return(0);
  769.         }
  770.  
  771.     /* Escape-bracket sequences */
  772.     if (bracket)
  773.         {
  774.         bracketset(c);
  775.         resetflags();
  776.         return(0);
  777.         }
  778.  
  779.     /* Two character escapes */
  780.     switch (c)
  781.         {
  782.         case '=':        /* alternate keypad mode */
  783.             altkeypad = 1;
  784.             break;
  785.         case '>':        /* numeric keypad mode */
  786.             altkeypad = 0;
  787.             break;
  788.         case 'D': /* index (move down one line, w/scroll up */
  789.             queryvidbs(&bsvid[0], &vidstate[0]);
  790.             if (vidstate[3] < botmar) conoc(0x0b);
  791.             else
  792.                 {
  793.                 conxo(2,"\377S");
  794.                 conoc(topmar-1);
  795.                 conoc(botmar);
  796.                 conxo(2,"\001U");
  797.                 }
  798.             break;
  799.         case 'M': /* index (move up one line, w/scroll down */
  800.             queryvidbs(&bsvid[0], &vidstate[0]);
  801.             if (vidstate[3] > (topmar-1)) conoc(0x01);
  802.             else
  803.                 {
  804.                 conxo(2,"\377S");
  805.                 conoc(topmar-1);
  806.                 conoc(botmar);
  807.                 conxo(2,"\001D");
  808.                 }
  809.             break;
  810.         case 'E':        /* next line */
  811.             conoc(0x0a);
  812.             break;
  813.         case '7':        /* save cursor position */
  814.             queryvidbs(&bsvid[0], &vidstate[0]);
  815.             scursorl = vidstate[3];
  816.             scursorc = vidstate[4];
  817.             sattr = vidstate[7];
  818.             break;
  819.         case '8':        /* restore cursor position */
  820.             conol("\377C");
  821.             conoc(scursorc);
  822.             conoc(scursorl);
  823.             conol("\377A");
  824.             conoc(sattr);
  825.             break;
  826.         case 'c':        /* reset to initial state */
  827.             resetflags();
  828.             resetmode();
  829.             break;
  830.         case 'Z':        /* identify terminal */
  831.             ttoc(dopar(033)); /* I am a VT101 */
  832.             ttoc(dopar(0133));
  833.             ttoc(dopar(077));
  834.             ttoc(dopar(061));
  835.             ttoc(dopar(073));
  836.             ttoc(dopar(060));
  837.             ttoc(dopar(0143));
  838.             break;
  839.         case 'H':        /* set tab stop at column */
  840.             queryvidbs(&bsvid[0], &vidstate[0]);
  841.             tabstop[(vidstate[4])] = 1;
  842.             break;
  843.         }
  844.     resetflags();
  845.     return(0);            
  846. }
  847.  
  848. /* R e s e t f l a g s --
  849.    Reset flags for escape sequences
  850. */
  851. resetflags()
  852.  
  853. {
  854.     escapeset=0;
  855.     bracket=0;
  856.     question=0;
  857.     semicolon=0;
  858.     valuef[0]=0;
  859.     valuef[1]=0;
  860.     value[0]=0;
  861.     value[1]=0;
  862.     openparen=0;
  863.     closeparen=0;
  864. }
  865.  
  866. /* R e s e t m o d e -- Reset to initial mode state */
  867. resetmode()
  868.  
  869. {
  870.     modecursor=0;            /* ansi cursor sequences */
  871.     modescreen=0;            /* green on black */
  872.     conol("\377RF");        /* normal screen escape */
  873.     modecrlf=0;            /* lf, not cr/lf */
  874.     setkbdled(0,0x00);        /* set F10 LED off */
  875.     setkbdled(1,0x00);        /* set F9 LED off */
  876.     shiftflag=0;            /* set to G0 character set */
  877.     for (i=0;i<128;i++) g0[i] = us[i]; /* set G0 set to US ASCII */
  878.     for (i=0;i<128;i++) g1[i] = us[i]; /* set G1 set to US ASCII */
  879.     for (i=0;i<80;i++)        /* reset tab stops */
  880.         {
  881.         if (i % 8) tabstop[i] = 1;
  882.         else tabstop[i] = 0;
  883.         }
  884.     tabstop[1] = 1;            /* might not be needed */
  885. }
  886.  
  887. /* A n s i s e q -- ANSI compatible sequences */
  888. ansiseq(c)
  889.  
  890. char c;
  891.  
  892. {
  893.     switch (c)
  894.         {
  895.         case 'l':
  896.             switch (value[0])
  897.                 {
  898.                 case 1:    /* set cursor mode */
  899.                     modecursor=0;
  900.                     break;
  901.                 case 2:    /* ANSI vs. VT52 - not implemented */
  902.                     break;
  903.                 /* 80 vs. 132 columns - not implemented */
  904.                 case 3:
  905.                     break;
  906.                 /* jump vs. smooth scroll - not implemented */
  907.                 case 4:
  908.                     break;
  909.                 case 5:    /* set screen mode */
  910.                     modescreen=0;
  911.                     /* normal screen escape */
  912.                     conol("\377RF");
  913.                     setkbdled(1,0x00); /* set F9 LED off */
  914.                     break;
  915.                 case 6:    /* origin - not implemented */
  916.                     break;
  917.                 case 7:    /* autowrap - not implemented */
  918.                     break;
  919.                 case 8:    /* autorepeat - not implemented */
  920.                     break;
  921.                 }
  922.             break;
  923.         case 'h':
  924.             switch (value[0])
  925.                 {
  926.                 case 1:    /* set cursor mode */
  927.                     modecursor=1;
  928.                     break;
  929.                 case 2:    /* ANSI vs. VT52 - not implemented */
  930.                     break;
  931.                 /* 80 vs. 132 columns - not implemented */
  932.                 case 3:    
  933.                     break;
  934.                 /* jump vs. smooth scroll - not implemented */
  935.                 case 4:    
  936.                     break;
  937.                 case 5:    /* set screen mode */
  938.                     modescreen=1;
  939.                     /* reverse screen escape */
  940.                     conol("\377RN"); 
  941.                     setkbdled(1,0xff); /* set F9 LED on */
  942.                     break;
  943.                 case 6:    /* origin - not implemented */
  944.                     break;
  945.                 case 7:    /* autowrap - not implemented */
  946.                     break;
  947.                 case 8:    /* autorepeat - not implemented */
  948.                     break;
  949.                 }
  950.             break;
  951.         }
  952. }
  953.  
  954. /* B r v a l-- Process escape sequences introduced by '[' and a
  955.                             numeric value */
  956. brval(c)
  957.  
  958. char c;
  959.  
  960. {
  961.     switch (c)
  962.         {
  963.         case 'h':                /* set new line */
  964.             if (value[0] == 20)
  965.                 {
  966.                 setkbdled(0,0xff); /* set F10 LED off */
  967.                 modecrlf = 1;
  968.                 }
  969.             break;
  970.         case 'l'        : /* set line feed */
  971.             if (value[0] == 20)
  972.                 {
  973.                 setkbdled(0,0x00); /* set F10 LED off */
  974.                 modecrlf = 0;
  975.                 }
  976.             break;
  977.         case 'm':        /* select graphic rendition */
  978.             switch (value[0])
  979.                 {
  980.                 case 0:
  981.                     /* no attributes for new characters */
  982.                     conxo(3,"\377B\000"); 
  983.                     break;
  984.                 case 4:
  985.                 case 7:
  986.                     /* reverse video for new characters */
  987.                     conol("\377B\004"); 
  988.                     break;
  989.                 }
  990.             break;
  991.         case 'A':        /* cursor up, stop at top */
  992.             queryvidbs(&bsvid[0], &vidstate[0]);
  993.             if (value[0] > vidstate[3]) value[0] = vidstate[3];
  994.             for (i=0; i < value[0]; i++) conoc(0x01);
  995.             break;
  996.         case 'B':        /* cursor down, stop at bottom */
  997.             queryvidbs(&bsvid[0], &vidstate[0]);
  998.             i = (botmar-1) - vidstate[3];
  999.             if (value[0] > i) value[0] = i;
  1000.             for (i=0; i < value[0]; i++) conoc(0x0b);
  1001.             break;
  1002.         case 'C':           /* cursor right, stop at right margin */
  1003.             queryvidbs(&bsvid[0], &vidstate[0]);
  1004.             i = 79 - vidstate[4];
  1005.             if (value[0] > i) value[0] = i;
  1006.             for (i=0; i < value[0]; i++) conoc(0x12);
  1007.             break;
  1008.         case 'D':        /* cursor left, stop at left margin */
  1009.             queryvidbs(&bsvid[0], &vidstate[0]);
  1010.             if (value[0] > vidstate[4]) value[0] = vidstate[4];
  1011.             for (i=0; i < value[0]; i++) conoc(0x0e);
  1012.             break;
  1013.         case 'K':                /* line erase */
  1014.             switch (value[0])
  1015.                 {
  1016.                 case 0:        /* to end of line */
  1017.                     conol("\377EL"); /*  */
  1018.                     break;
  1019.                 case 1:        /* to beginning of line */
  1020.                     queryvidbs(&bsvid[0], &vidstate[0]);
  1021.                     conxo(4,"\377F\000\000");
  1022.                     conoc(vidstate[3]);
  1023.                     conoc(vidstate[4]+1);
  1024.                     conoc(0x01);
  1025.                     break;
  1026.                 case 2:        /* entire line */
  1027.                     queryvidbs(&bsvid[0], &vidstate[0]);
  1028.                     conxo(4,"\377F\000\000");
  1029.                     conoc(vidstate[3]);
  1030.                     conol("\377\001");
  1031.                     break;
  1032.                 }
  1033.             break;
  1034.         case 'J':                /* screen erase */
  1035.             switch (value[0])
  1036.                 {
  1037.                 case 0:    /* to end of display */
  1038.                     conol("\377EF");
  1039.                     break;
  1040.                 case 1:    /* to beginning of screen */
  1041.                     queryvidbs(&bsvid[0], &vidstate[0]);
  1042.                     conxo(6,"\377F\000\000\000\377");
  1043.                     conoc(vidstate[3]);
  1044.                     conxo(4,"\377F\000\000");
  1045.                     conoc(vidstate[3]);
  1046.                     conoc(vidstate[4]);
  1047.                     conol("\001");
  1048.                     break;
  1049.                 case 2:        /* entire screen */
  1050.                     conxo(7,"\377F\000\000\000\377\377");
  1051.                     break;
  1052.                 }
  1053.             break;
  1054.         case 'c':            /* what am I? */
  1055.             ttoc(dopar(033)); /* I am a VT101 */
  1056.             ttoc(dopar(0133));
  1057.             ttoc(dopar(077));
  1058.             ttoc(dopar(061));
  1059.             ttoc(dopar(073));
  1060.             ttoc(dopar(060));
  1061.             ttoc(dopar(0143));
  1062.             break;
  1063.         case 'n':        /* report requests */
  1064.             switch (value[0])
  1065.                 {
  1066.                 case 5:    /* am I OK? */
  1067.                     ttoc(dopar(033)); /* I am OK */
  1068.                     ttoc(dopar(0133));
  1069.                     ttoc(dopar(0160));
  1070.                     ttoc(dopar(0156));
  1071.                     break;
  1072.                 case 6:    /* where is cursor? */
  1073.                     queryvidbs(&bsvid[0], &vidstate[0]);
  1074.                     ttoc(dopar(033)); /* here, dammit */
  1075.                     ttoc(dopar(0133));
  1076.                     ttoc(dopar(vidstate[3]+1));
  1077.                     ttoc(dopar(073));
  1078.                     ttoc(dopar(vidstate[4]+1));
  1079.                     ttoc(dopar(0122));
  1080.                     break;
  1081.                 }
  1082.             break;
  1083.         case 'g':        /* manipulate tab stops */
  1084.             switch (value[0])
  1085.                 {
  1086.                 case 0:    /* clear tab at current column */
  1087.                     queryvidbs(&bsvid[0], &vidstate[0]);
  1088.                     tabstop[(vidstate[4])] = 0;
  1089.                     break;
  1090.                 case 3:            /* clear all tabs */
  1091.                     for (i=0;i<80;i++) tabstop[i] = 0;
  1092.                     break;
  1093.                 }
  1094.             break;
  1095.         case 'H':        /* position cursor */
  1096.             if (value[0]) value[0] -= 1;
  1097.             if (value[1]) value[1] -= 1;
  1098.             conol("\377C");
  1099.             conoc(value[1]);
  1100.             conoc(value[0]);
  1101.             break;
  1102.         }
  1103. }
  1104.  
  1105. /* B r a c k e t s e t -- Process escape sequences introduced by  a '[' */
  1106. bracketset(c)
  1107.  
  1108. char c;
  1109.  
  1110. {
  1111.     switch (c)
  1112.         {
  1113.         case 'm':        /* select graphic rendition */
  1114.             /* no attributes for new characters */
  1115.             conxo(3,"\377B\000"); 
  1116.             break;
  1117.         case 'f':
  1118.         case 'H':
  1119.             conxo(4,"\377C\000\000"); /* position cursor to 0,0 */
  1120.             break;
  1121.         case 'K':
  1122.             conol("\377EL"); /* erase to end of line */
  1123.             break;
  1124.         case 'J':
  1125.             conol("\377EF"); /* erase to end of display frame */
  1126.             break;
  1127.         case 'c':        /* what am I? */
  1128.             ttoc(dopar(033)); /* I am a VT101 */
  1129.             ttoc(dopar(0133));
  1130.             ttoc(dopar(077));
  1131.             ttoc(dopar(061));
  1132.             ttoc(dopar(073));
  1133.             ttoc(dopar(060));
  1134.             ttoc(dopar(0143));
  1135.             break;
  1136.         case 'g':        /* clear tab at current col */
  1137.             queryvidbs(&bsvid[0], &vidstate[0]);
  1138.             tabstop[(vidstate[4])] = 0;
  1139.             break;
  1140.         case 'A':        /* cursor up, stop at top */
  1141.             queryvidbs(&bsvid[0], &vidstate[0]);
  1142.             if (vidstate[3]) conoc(0x01);
  1143.             break;
  1144.         case 'B':        /* cursor down, stop at bottom */
  1145.             queryvidbs(&bsvid[0], &vidstate[0]);
  1146.             if (vidstate[3] < (botmar-1)) conoc(0x0b);
  1147.             break;
  1148.         case 'C':           /* cursor right, stop at right margin */
  1149.             queryvidbs(&bsvid[0], &vidstate[0]);
  1150.             if (vidstate[4] < 79) conoc(0x12);
  1151.             break;
  1152.         case 'D':        /* cursor left, stop at left margin */
  1153.             queryvidbs(&bsvid[0], &vidstate[0]);
  1154.             if (vidstate[4]) conoc(0x0e);
  1155.             break;
  1156.         }
  1157. }
  1158.  
  1159. /* N n f o r m a t -- Process sequences of n;n format */
  1160. nnformat(c)
  1161.  
  1162. char c;
  1163.  
  1164. {
  1165.  
  1166.     switch (c)
  1167.         {
  1168.         case 'H':        
  1169.         case 'f':                /* position cursor */
  1170.             if (value[0]) value[0] -= 1;
  1171.             if (value[1]) value[1] -= 1;
  1172.             conol("\377C");
  1173.             conoc(value[1]);
  1174.             conoc(value[0]);
  1175.             break;
  1176.         case 'r':        /* set top and bottom margin */
  1177.             topmar = value[0];
  1178.             botmar = value[1];
  1179.             break;    
  1180. /* I am unsure of the following code.  I am working from a VT101 manual,
  1181.    and I am trying to empirically implement some VT100 graphics sequences.
  1182.    This will work with my case, but until I get the VT100 manual, I'm not
  1183.    positive that this will work all the time. -- RJD */
  1184.         case 'm':        /* select graphic rendition */
  1185.             switch (value[1])
  1186.                 {
  1187.                 case 0:
  1188.                     /* no attributes for new characters */
  1189.                     conxo(3,"\377B\000");
  1190.                     break;
  1191.                 case 1:
  1192.                     /* bold video for new characters */
  1193.                     conol("\377B\020");
  1194.                     break;
  1195.                 case 4:
  1196.                 case 7:
  1197.                     /* reverse video for new characters */
  1198.                     conol("\377B\004");
  1199.                     break;
  1200.                 }
  1201.             break;
  1202.         }
  1203. }
  1204.