#if NCR char *ckvt100v = "CTOS VT101 Emulation-1.05 NCR Kbd, January 1988"; #else char *ckvt100v = "CTOS VT101 Emulation-1.05 CT Kbd, January 1988"; #endif /* C K V T 1 0 0 -- DEC VT101 terminal emulation */ /* Joel Dunn, UNC-CH, June 1987 */ /* Modifications -- August 1987, v1.02, Joel Dunn UNC-CH - add support for G0 and G1 character sets - support some VT100 graphic sequences - change VT100 alternate keypad to be on CT physical keypad - set up compile option for NCR or CT keypad codes Modifications -- September 1987, v1.03, Joel Dunn UNC-CH - try again to get tab stops working properly Modifications -- September 1987, v1.04, Joel Dunn UNC-CH - add F8 function to reset terminal to original values in case emulation is screwed up by line garbage, etc. Modifications -- January 1988, v1.05, Joel Dunn UNC-CH - change delete key to send 0x7f instead of a "break", use S + delete to send a "break" - change variable "c" in kbdin to int, was char and having problems with sign promotion */ #include "ctermi.h" /* from ckmain.c */ extern int local, speed, escape, duplex, parity, flow, seslog, mdmtyp, termtype; extern char ttname[], sesfil[]; /* from CTOS */ extern char bsvid[130]; /* from ckconu.c */ extern int c; /* c is a character, but must be signed integer to pass thru -1, which is the modem disconnection signal, and is different from the character 0377 */ extern int i, active; /* global variables declared in this module */ int escapeset=0, altkeypad=0; int modecursor=0, modescreen=0, modecrlf=0; int bracket=0, question=0, semicolon=0; int value[2] = {0,0}; int valuef[2] = {0,0}; int openparen=0, closeparen=0, shiftflag=0; int scursorl=0, scursorc=0, sattr=0; int xon=1; int topmar=1, botmar=24; char vidstate[16]; int tabstop[80] = { 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0 }; int g0[128] = { 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, 26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49, 50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73, 74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97, 98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115, 116,117,118,119,120,121,122,123,124,125,126,127}; int g1[128] = { 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, 26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49, 50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73, 74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97, 98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115, 116,117,118,119,120,121,122,123,124,125,126,127}; int us[128] = { 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, 26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49, 50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73, 74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97, 98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115, 116,117,118,119,120,121,122,123,124,125,126,127}; int uk[128] = { 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, 26,27,28,29,30,31,32,33,34,177,36,37,38,39,40,41,42,43,44,45,46,47,48,49, 50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73, 74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97, 98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115, 116,117,118,119,120,121,122,123,124,125,126,127}; int sc[128] = { 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, 26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49, 50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73, 74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,32,27,255, 32,32,32,32,178,30,32,32,238,240,239,237,219,218,218,218,218,218, 226,227,221,220,225,29,31,26,24,177,61,127}; /* C O N V T 1 0 0 -- Connect in VT100 mode */ convt100() { /* setup of VT100 session */ setkbdled(0,0x00); /* set F10 LED off (cr/lf set to lf only) */ setkbdled(1,0x00); /* set F9 LED off (screen in green on black) */ printf("\n\nConnected in VT100 Emulation Mode\n"); active = 1; while (((c = ttinc(0)) >= 0) & active) { /* read, prints port input */ if (c > 0) { /* log if session log on */ if (seslog) zchout(ZSFILE,c); linein(c); } /* read, prints keyboard input */ c = 0; if (xon) c = coninc(0); /* allow all 256 keyboard characters */ if (c == escape) { /* Look for local escape char */ c = coninc(9999) & 0177; doesc(c); } else if ((c > 0x1f) && (c < 0x7f)) { /* Ordinary ascii character */ ttoc(dopar(c)); /* Send with desired parity */ if (duplex) { /* Half duplex? */ conoc(c); /* Yes, also echo it. */ if (seslog) zchout(ZSFILE,c); /* and log it, if logging */ } } /* process control and special characters */ else if (c) kbdin(c); } if (c < 0) { /* Comm line hangup detected*/ printf("\r\nCommunications line failure\r\n"); } conres(); /* Reset the console. */ setkbdled(0,0x00); /* set F10 LED off */ setkbdled(1,0x00); /* set F9 LED off */ printf("\nVT100 Emulation Disconnected\n"); return(0); } /* K b d i n */ kbdin(c) int c; { switch (c) { /* alternate keypad */ case 0xb0: /* S - SS - num 0 = AKP 0 */ if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0160)); } break; #if NCR case 0xbc: /* S - SS - num 1 = AKP 1 */ #else case 0xe0: /* S - SS - num 1 = AKP 1 */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0161)); } break; #if NCR case 0xbe: /* S - SS - num 2 = AKP 2 */ #else case 0xb2: /* S - SS - num 2 = AKP 2 */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0162)); } break; #if NCR case 0xfc: /* S - SS - num 3 = AKP 3 */ #else case 0xb3: /* S - SS - num 3 = AKP 3 */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0163)); } break; #if NCR case 0xdb: /* S - SS - num 4 = AKP 4 */ #else case 0xfb: /* S - SS - num 4 = AKP 4 */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0164)); } break; #if NCR case 0xdd: /* S - SS - num 5 = AKP 5 */ #else case 0xfd: /* S - SS - num 5 = AKP 5 */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0165)); } break; #if NCR case 0xdc: /* S - SS - num 6 = AKP 6 */ #else case 0xb6: /* S - SS - num 6 = AKP 6 */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0166)); } break; #if NCR case 0xfb: /* S - SS - num 7 = AKP 7 */ #else case 0xfc: /* S - SS - num 7 = AKP 7 */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0167)); } break; #if NCR case 0xfd: /* S - SS - num 8 = AKP 8 */ #else case 0xdc: /* S - SS - num 8 = AKP 8 */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0170)); } break; #if NCR case 0x85: /* S - SS - num 9 = AKP 9 */ #else case 0xb9: /* S - SS - num 9 = AKP 9 */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0171)); } break; #if NCR case 0x8c: /* S - SS - GO = AKP DASH */ #else case 0xc9: /* S - SS - GO = AKP DASH */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0155)); } break; #if NCR case 0xac: /* S - SS - num dash = AKP COMMA */ #else case 0xad: /* S - SS - num dash = AKP COMMA */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0154)); } break; #if NCR case 0xc9: /* S - SS - num next = AKP ENTER */ #else case 0x8a: /* S - SS - num next = AKP ENTER */ #endif if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0115)); } break; case 0xae: /* S - SS - num . = AKP PERIOD */ if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0156)); } break; case 0xd5: /* S - SS - F1 = F1 */ if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0120)); } break; case 0xd6: /* S - SS - F2 = F2 */ if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0121)); } break; case 0xd7: /* S - SS - F3 = F3 */ if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0122)); } break; case 0xd8: /* S - SS - F3 = F3 */ if (altkeypad) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0123)); } break; case 0x01: /* up arrow */ if (modecursor) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0101)); } else { ttoc(dopar(033)); ttoc(dopar(0133)); ttoc(dopar(0101)); } break; case 0x0b: /* down arrow */ if (modecursor) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0102)); } else { ttoc(dopar(033)); ttoc(dopar(0133)); ttoc(dopar(0102)); } break; case 0x0e: /* left arrow */ if (modecursor) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0104)); } else { ttoc(dopar(033)); ttoc(dopar(0133)); ttoc(dopar(0104)); } break; case 0x12: /* right arrow */ if (modecursor) { ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0103)); } else { ttoc(dopar(033)); ttoc(dopar(0133)); ttoc(dopar(0103)); } break; case 0x15: /* F1 */ ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0120)); break; case 0x16: /* F2 */ ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0121)); break; case 0x17: /* F3 */ ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0122)); break; case 0x18: /* F4 */ ttoc(dopar(033)); ttoc(dopar(0117)); ttoc(dopar(0123)); break; case 0x1d: /* emergency reset, F8 */ resetflags(); resetmode(); break; case 0x1e: /* toggle screen mode, F9 */ if (modescreen) { modescreen = 0; conol("\377RF"); setkbdled(1,0x00); /* set F9 LED off */ } else { modescreen = 1; conol("\377RN"); setkbdled(1,0xff); /* set F9 LED on */ } break; case 0x1f: /* toggle cr/lf mode, F10 */ if (modecrlf) { modecrlf = 0; setkbdled(0,0x00); /* set F10 LED off */ } else { modecrlf = 1; setkbdled(0,0xff); /* set F10 LED on */ } break; case 0x7f: /* delete */ ttoc(dopar(177)); break; case 0xa0: /* CTRL (SS) - spacebar */ ttoc(dopar(000)); break; case 0xaf: /* CTRL (SS) - ? */ ttoc(dopar(037)); break; case 0xb8: /* CTRL (SS) - \ */ ttoc(dopar(034)); break; case 0xc8: /* S - delete = long break disconnect */ ttsndb(); break; case 0xde: /* CTRL (SS) - ~ */ ttoc(dopar(036)); break; case 0xe1: /* CTRL (SS) - a */ ttoc(dopar(001)); break; case 0xe2: /* CTRL (SS) - b */ ttoc(dopar(002)); break; case 0xe3: /* CTRL (SS) - c */ ttoc(dopar(003)); break; case 0xe4: /* CTRL (SS) - d */ ttoc(dopar(004)); break; case 0xe5: /* CTRL (SS) - e */ ttoc(dopar(005)); break; case 0xe6: /* CTRL (SS) - f */ ttoc(dopar(006)); break; case 0xe7: /* CTRL (SS) - g */ ttoc(dopar(007)); break; case 0x08: /* backtab */ case 0xe8: /* CTRL (SS) - h */ ttoc(dopar(010)); break; case 0x09: /* tab */ case 0xe9: /* CTRL (SS) - i */ ttoc(dopar(011)); break; case 0xea: /* CTRL (SS) - j */ ttoc(dopar(012)); break; case 0xeb: /* CTRL (SS) - k */ ttoc(dopar(013)); break; case 0xec: /* CTRL (SS) - l */ ttoc(dopar(014)); break; case 0x0d: /* return */ case 0xed: /* CTRL (SS) - m */ if (modecrlf) { ttoc(dopar(015)); ttoc(dopar(012)); } else ttoc(dopar(015)); break; case 0xee: /* CTRL (SS) - n */ ttoc(dopar(016)); break; case 0xef: /* CTRL (SS) - o */ ttoc(dopar(017)); break; case 0xf0: /* CTRL (SS) - p */ ttoc(dopar(020)); break; case 0xf1: /* CTRL (SS) - q */ ttoc(dopar(021)); break; case 0xf2: /* CTRL (SS) - r */ ttoc(dopar(022)); break; case 0xf3: /* CTRL (SS) - s */ ttoc(dopar(023)); break; case 0xf4: /* CTRL (SS) - t */ ttoc(dopar(024)); break; case 0xf5: /* CTRL (SS) - u */ ttoc(dopar(025)); break; case 0xf6: /* CTRL (SS) - v */ ttoc(dopar(026)); break; case 0xf7: /* CTRL (SS) - w */ ttoc(dopar(027)); break; case 0xf8: /* CTRL (SS) - x */ ttoc(dopar(030)); break; case 0xf9: /* CTRL (SS) - y */ ttoc(dopar(031)); break; case 0xfa: /* CTRL (SS) - z */ ttoc(dopar(032)); break; case 0xff: /* SS - delete = send answerback message */ break; default: break; } } /* L i n e i n -- Receive characters in VT100 mode */ linein(c) char c; { if (c <= 0x1b) vt100cc(c); else if (escapeset) vt100esc(c); else { if (shiftflag) conoc(g1[c]); else conoc(g0[c]); } } /* V T 1 0 0 C C -- Process VT100 control characters */ vt100cc(c) char c; { char nexttab; switch (c) { case 0x00: /* null */ break; case 0x05: /* transmit answerback message -- not implemented */ break; case 0x07: /* bell */ conoc(0x07); break; case 0x08: /* backspace, nondescructive */ queryvidbs(&bsvid[0], &vidstate[0]); if (vidstate[4]) conoc(0x0e); break; case 0x09: /* tab to next stop, go to EOL if no stops */ queryvidbs(&bsvid[0], &vidstate[0]); for (nexttab=vidstate[4]+1; nexttab<80; nexttab++) if (tabstop[nexttab]) break; conol("\377C"); conoc(nexttab); conoc(vidstate[3]); break; case 0x0b: /* vertical tab -- as line feed */ case 0x0c: /* form feed -- process as line feed */ case 0x0a: /* line feed */ if (modecrlf) conoc(0x0a); else { /* scroll up or move down cursor */ queryvidbs(&bsvid[0], &vidstate[0]); if ((botmar-1) == vidstate[3]) { conxo(2,"\377S"); conoc(topmar-1); conoc(botmar); conxo(2,"\001U"); } else conoc(0x0b); } break; case 0x0d: /* carriage return */ queryvidbs(&bsvid[0], &vidstate[0]); conxo(3,"\377C\000"); conoc(vidstate[3]); break; case 0x0e: /* shift out */ shiftflag = 1; break; case 0x0f: /* shift in */ shiftflag = 0; break; case 0x11: /* XON */ xon = 1; break; case 0x13: /* XOFF */ xon = 0; break; case 0x19: /* cancel */ case 0x1a: /* substitute */ resetflags(); break; case 0x1b: /* escape */ escapeset = 1; break; } } /* V T 1 0 0 E S C -- Process VT100 escape sequences */ vt100esc(c) char c; { /* set special grouping flags */ if (c == '[') { bracket = 1; return(0); } else if (c == '?') { question = 1; return(0); } else if (c == ';') { semicolon = 1; valuef[0] = 1; return(0); } else if (c == '(') { openparen = 1; return(0); } else if (c == ')') { closeparen = 1; return(0); } /* collect numeric values */ else if ((isdigit(c)) && ((bracket) || (question))) { value[semicolon] *= 10; value[semicolon] += (c - '0'); valuef[semicolon] = 1; return(0); } /* Escape-openparen sequences */ if (openparen) { switch (c) { case 'A': for (i=0;i<128;i++) g0[i] = uk[i]; break; case 'B': for (i=0;i<128;i++) g0[i] = us[i]; break; case '0': for (i=0;i<128;i++) g0[i] = sc[i]; break; } resetflags(); return(0); } /* Escape-closeparen sequences */ if (closeparen) { switch (c) { case 'A': for (i=0;i<128;i++) g1[i] = uk[i]; break; case 'B': for (i=0;i<128;i++) g1[i] = us[i]; break; case '0': for (i=0;i<128;i++) g1[i] = sc[i]; break; } resetflags(); return(0); } /* ANSI compatible sequences */ if ((bracket) && (question) && (valuef[0])) { ansiseq(c); resetflags(); return(0); } /* two value sequences */ if ((bracket) && (semicolon)) { nnformat(c); resetflags(); return(0); } /* Escape-bracket-value sequences */ if ((bracket) && (valuef[0])) { brval(c); resetflags(); return(0); } /* Escape-bracket sequences */ if (bracket) { bracketset(c); resetflags(); return(0); } /* Two character escapes */ switch (c) { case '=': /* alternate keypad mode */ altkeypad = 1; break; case '>': /* numeric keypad mode */ altkeypad = 0; break; case 'D': /* index (move down one line, w/scroll up */ queryvidbs(&bsvid[0], &vidstate[0]); if (vidstate[3] < botmar) conoc(0x0b); else { conxo(2,"\377S"); conoc(topmar-1); conoc(botmar); conxo(2,"\001U"); } break; case 'M': /* index (move up one line, w/scroll down */ queryvidbs(&bsvid[0], &vidstate[0]); if (vidstate[3] > (topmar-1)) conoc(0x01); else { conxo(2,"\377S"); conoc(topmar-1); conoc(botmar); conxo(2,"\001D"); } break; case 'E': /* next line */ conoc(0x0a); break; case '7': /* save cursor position */ queryvidbs(&bsvid[0], &vidstate[0]); scursorl = vidstate[3]; scursorc = vidstate[4]; sattr = vidstate[7]; break; case '8': /* restore cursor position */ conol("\377C"); conoc(scursorc); conoc(scursorl); conol("\377A"); conoc(sattr); break; case 'c': /* reset to initial state */ resetflags(); resetmode(); break; case 'Z': /* identify terminal */ ttoc(dopar(033)); /* I am a VT101 */ ttoc(dopar(0133)); ttoc(dopar(077)); ttoc(dopar(061)); ttoc(dopar(073)); ttoc(dopar(060)); ttoc(dopar(0143)); break; case 'H': /* set tab stop at column */ queryvidbs(&bsvid[0], &vidstate[0]); tabstop[(vidstate[4])] = 1; break; } resetflags(); return(0); } /* R e s e t f l a g s -- Reset flags for escape sequences */ resetflags() { escapeset=0; bracket=0; question=0; semicolon=0; valuef[0]=0; valuef[1]=0; value[0]=0; value[1]=0; openparen=0; closeparen=0; } /* R e s e t m o d e -- Reset to initial mode state */ resetmode() { modecursor=0; /* ansi cursor sequences */ modescreen=0; /* green on black */ conol("\377RF"); /* normal screen escape */ modecrlf=0; /* lf, not cr/lf */ setkbdled(0,0x00); /* set F10 LED off */ setkbdled(1,0x00); /* set F9 LED off */ shiftflag=0; /* set to G0 character set */ for (i=0;i<128;i++) g0[i] = us[i]; /* set G0 set to US ASCII */ for (i=0;i<128;i++) g1[i] = us[i]; /* set G1 set to US ASCII */ for (i=0;i<80;i++) /* reset tab stops */ { if (i % 8) tabstop[i] = 1; else tabstop[i] = 0; } tabstop[1] = 1; /* might not be needed */ } /* A n s i s e q -- ANSI compatible sequences */ ansiseq(c) char c; { switch (c) { case 'l': switch (value[0]) { case 1: /* set cursor mode */ modecursor=0; break; case 2: /* ANSI vs. VT52 - not implemented */ break; /* 80 vs. 132 columns - not implemented */ case 3: break; /* jump vs. smooth scroll - not implemented */ case 4: break; case 5: /* set screen mode */ modescreen=0; /* normal screen escape */ conol("\377RF"); setkbdled(1,0x00); /* set F9 LED off */ break; case 6: /* origin - not implemented */ break; case 7: /* autowrap - not implemented */ break; case 8: /* autorepeat - not implemented */ break; } break; case 'h': switch (value[0]) { case 1: /* set cursor mode */ modecursor=1; break; case 2: /* ANSI vs. VT52 - not implemented */ break; /* 80 vs. 132 columns - not implemented */ case 3: break; /* jump vs. smooth scroll - not implemented */ case 4: break; case 5: /* set screen mode */ modescreen=1; /* reverse screen escape */ conol("\377RN"); setkbdled(1,0xff); /* set F9 LED on */ break; case 6: /* origin - not implemented */ break; case 7: /* autowrap - not implemented */ break; case 8: /* autorepeat - not implemented */ break; } break; } } /* B r v a l-- Process escape sequences introduced by '[' and a numeric value */ brval(c) char c; { switch (c) { case 'h': /* set new line */ if (value[0] == 20) { setkbdled(0,0xff); /* set F10 LED off */ modecrlf = 1; } break; case 'l' : /* set line feed */ if (value[0] == 20) { setkbdled(0,0x00); /* set F10 LED off */ modecrlf = 0; } break; case 'm': /* select graphic rendition */ switch (value[0]) { case 0: /* no attributes for new characters */ conxo(3,"\377B\000"); break; case 4: case 7: /* reverse video for new characters */ conol("\377B\004"); break; } break; case 'A': /* cursor up, stop at top */ queryvidbs(&bsvid[0], &vidstate[0]); if (value[0] > vidstate[3]) value[0] = vidstate[3]; for (i=0; i < value[0]; i++) conoc(0x01); break; case 'B': /* cursor down, stop at bottom */ queryvidbs(&bsvid[0], &vidstate[0]); i = (botmar-1) - vidstate[3]; if (value[0] > i) value[0] = i; for (i=0; i < value[0]; i++) conoc(0x0b); break; case 'C': /* cursor right, stop at right margin */ queryvidbs(&bsvid[0], &vidstate[0]); i = 79 - vidstate[4]; if (value[0] > i) value[0] = i; for (i=0; i < value[0]; i++) conoc(0x12); break; case 'D': /* cursor left, stop at left margin */ queryvidbs(&bsvid[0], &vidstate[0]); if (value[0] > vidstate[4]) value[0] = vidstate[4]; for (i=0; i < value[0]; i++) conoc(0x0e); break; case 'K': /* line erase */ switch (value[0]) { case 0: /* to end of line */ conol("\377EL"); /* */ break; case 1: /* to beginning of line */ queryvidbs(&bsvid[0], &vidstate[0]); conxo(4,"\377F\000\000"); conoc(vidstate[3]); conoc(vidstate[4]+1); conoc(0x01); break; case 2: /* entire line */ queryvidbs(&bsvid[0], &vidstate[0]); conxo(4,"\377F\000\000"); conoc(vidstate[3]); conol("\377\001"); break; } break; case 'J': /* screen erase */ switch (value[0]) { case 0: /* to end of display */ conol("\377EF"); break; case 1: /* to beginning of screen */ queryvidbs(&bsvid[0], &vidstate[0]); conxo(6,"\377F\000\000\000\377"); conoc(vidstate[3]); conxo(4,"\377F\000\000"); conoc(vidstate[3]); conoc(vidstate[4]); conol("\001"); break; case 2: /* entire screen */ conxo(7,"\377F\000\000\000\377\377"); break; } break; case 'c': /* what am I? */ ttoc(dopar(033)); /* I am a VT101 */ ttoc(dopar(0133)); ttoc(dopar(077)); ttoc(dopar(061)); ttoc(dopar(073)); ttoc(dopar(060)); ttoc(dopar(0143)); break; case 'n': /* report requests */ switch (value[0]) { case 5: /* am I OK? */ ttoc(dopar(033)); /* I am OK */ ttoc(dopar(0133)); ttoc(dopar(0160)); ttoc(dopar(0156)); break; case 6: /* where is cursor? */ queryvidbs(&bsvid[0], &vidstate[0]); ttoc(dopar(033)); /* here, dammit */ ttoc(dopar(0133)); ttoc(dopar(vidstate[3]+1)); ttoc(dopar(073)); ttoc(dopar(vidstate[4]+1)); ttoc(dopar(0122)); break; } break; case 'g': /* manipulate tab stops */ switch (value[0]) { case 0: /* clear tab at current column */ queryvidbs(&bsvid[0], &vidstate[0]); tabstop[(vidstate[4])] = 0; break; case 3: /* clear all tabs */ for (i=0;i<80;i++) tabstop[i] = 0; break; } break; case 'H': /* position cursor */ if (value[0]) value[0] -= 1; if (value[1]) value[1] -= 1; conol("\377C"); conoc(value[1]); conoc(value[0]); break; } } /* B r a c k e t s e t -- Process escape sequences introduced by a '[' */ bracketset(c) char c; { switch (c) { case 'm': /* select graphic rendition */ /* no attributes for new characters */ conxo(3,"\377B\000"); break; case 'f': case 'H': conxo(4,"\377C\000\000"); /* position cursor to 0,0 */ break; case 'K': conol("\377EL"); /* erase to end of line */ break; case 'J': conol("\377EF"); /* erase to end of display frame */ break; case 'c': /* what am I? */ ttoc(dopar(033)); /* I am a VT101 */ ttoc(dopar(0133)); ttoc(dopar(077)); ttoc(dopar(061)); ttoc(dopar(073)); ttoc(dopar(060)); ttoc(dopar(0143)); break; case 'g': /* clear tab at current col */ queryvidbs(&bsvid[0], &vidstate[0]); tabstop[(vidstate[4])] = 0; break; case 'A': /* cursor up, stop at top */ queryvidbs(&bsvid[0], &vidstate[0]); if (vidstate[3]) conoc(0x01); break; case 'B': /* cursor down, stop at bottom */ queryvidbs(&bsvid[0], &vidstate[0]); if (vidstate[3] < (botmar-1)) conoc(0x0b); break; case 'C': /* cursor right, stop at right margin */ queryvidbs(&bsvid[0], &vidstate[0]); if (vidstate[4] < 79) conoc(0x12); break; case 'D': /* cursor left, stop at left margin */ queryvidbs(&bsvid[0], &vidstate[0]); if (vidstate[4]) conoc(0x0e); break; } } /* N n f o r m a t -- Process sequences of n;n format */ nnformat(c) char c; { switch (c) { case 'H': case 'f': /* position cursor */ if (value[0]) value[0] -= 1; if (value[1]) value[1] -= 1; conol("\377C"); conoc(value[1]); conoc(value[0]); break; case 'r': /* set top and bottom margin */ topmar = value[0]; botmar = value[1]; break; /* I am unsure of the following code. I am working from a VT101 manual, and I am trying to empirically implement some VT100 graphics sequences. This will work with my case, but until I get the VT100 manual, I'm not positive that this will work all the time. -- RJD */ case 'm': /* select graphic rendition */ switch (value[1]) { case 0: /* no attributes for new characters */ conxo(3,"\377B\000"); break; case 1: /* bold video for new characters */ conol("\377B\020"); break; case 4: case 7: /* reverse video for new characters */ conol("\377B\004"); break; } break; } }