Return to BSD News archive
Received: by minnie.vk1xwt.ampr.org with NNTP id AA6781 ; Fri, 15 Jan 93 10:32:26 EST Xref: sserve comp.unix.bsd:9962 alt.sources:4986 Path: sserve!manuel.anu.edu.au!munnari.oz.au!spool.mu.edu!umn.edu!lynx.unm.edu!fmsrl7!destroyer!gumby!yale!yale.edu!ira.uka.de!Germany.EU.net!hcshh!hm From: hm@hcshh.hcs.de (Hellmuth Michaelis) Newsgroups: comp.unix.bsd,alt.sources Subject: [386BSD] pcvt 2.00 - VT220 console driver (part 04/11) Summary: 386BSD 0.1 VT220 console device driver source code Keywords: 386BSD console driver VT220 Message-ID: <1620@hcshh.hcs.de> Date: 15 Jan 93 13:02:18 GMT Followup-To: comp.unix.bsd Organization: HCS GmbH, Hamburg, Europe Lines: 2070 Submitted-by: hm@hcshh.hcs.de (Hellmuth Michaelis) Archive-name: pcvt-2.00/part04 ---- Cut Here and unpack ---- #!/bin/sh # This is part 04 of pcvt-2.00 if touch 2>&1 | fgrep '[-amc]' > /dev/null then TOUCH=touch else TOUCH=true fi # ============= Support/vttest/main.c ============== if test X"$1" != X"-c" -a -f 'Support/vttest/main.c'; then echo "File already exists: skipping 'Support/vttest/main.c'" else echo "x - extracting Support/vttest/main.c (Text)" sed 's/^X//' << 'SHAR_EOF' > Support/vttest/main.c && X/* X VTTEST.C X X Written Novemeber 1983 - July 1984 by Per Lindberg, X Stockholm University Computer Center (QZ), Sweden. X X THE MAD PROGRAMMER STRIKES AGAIN! X X This software is (c) 1984 by QZ X Non-commercial use and copying allowed. X XIf you are developing a commercial product, and use this program to do Xit, and that product is successful, please send a sum of money of your Xchoice to the address below. X X*/ X X#include "header.h" X Xchar inchar(), *instr(), *lookup(); X Xstruct table { X int key; X char *msg; X} paritytable[] = { X { 1, "NONE" }, X { 4, "ODD" }, X { 5, "EVEN" }, X { -1, "" } X},nbitstable[] = { X { 1, "8" }, X { 2, "7" }, X { -1,"" } X},speedtable[] = { X { 0, "50" }, X { 8, "75" }, X { 16, "110" }, X { 24, "132.5"}, X { 32, "150" }, X { 40, "200" }, X { 48, "300" }, X { 56, "600" }, X { 64, "1200" }, X { 72, "1800" }, X { 80, "2000" }, X { 88, "2400" }, X { 96, "3600" }, X { 104, "4800" }, X { 112, "9600" }, X { 120, "19200" }, X { -1, "" } X}; X X#ifdef USEMYSTTY Xint stty(fd,ptr) Xint fd; Xstruct sgttyb *ptr; X{ X return(ioctl(fd, TIOCSETP, ptr)); X} Xint gtty(fd,ptr) Xint fd; Xstruct sgttyb *ptr; X{ X return(ioctl(fd, TIOCGETP, ptr)); X} X#endif X Xmain() { X X int menuchoice; X X static char *mainmenu[] = { X "Exit", X "Test of cursor movements", X "Test of screen features", X "Test of character sets", X "Test of double-sized characters", X "Test of keyboard", X "Test of terminal reports", X "Test of VT52 mode", X "Test of VT102 features (Insert/Delete Char/Line)", X "Test of known bugs", X "Test of reset and self-test", X "" X }; X X#ifdef UNIX X initterminal(setjmp(intrenv)); X signal(SIGINT, onbrk); X signal(SIGTERM, onterm); X reading = 0; X#else X initterminal(0); X#endif X do { X#ifdef SARG20 X ttybin(1); /* set line to binary mode again. It's reset somehow!! */ X#endif X ed(2); X cup(5,10); printf("VT100 test program, version %s", VERSION); X cup(7,10); println("Choose test type:"); X menuchoice = menu(mainmenu); X switch (menuchoice) { X case 1: tst_movements(); break; X case 2: tst_screen(); break; X case 3: tst_characters(); break; X case 4: tst_doublesize(); break; X case 5: tst_keyboard(); break; X case 6: tst_reports(); break; X case 7: tst_vt52(); break; X case 8: tst_insdel(); break; X case 9: tst_bugs(); break; X case 10: tst_rst(); break; X } X } while (menuchoice); X bye(); X} X Xtst_movements() { X X /* Test of: X CUF (Cursor Forward) X CUB (Cursor Backward) X CUD (Cursor Down) IND (Index) NEL (Next Line) X CUU (Cursor Up) RI (Reverse Index) X CUP (Cursor Position) HVP (Horizontal and Vertical Position) X ED (Erase in Display) X EL (Erase in Line) X DECALN (Screen Alignment Display) X <CR> <BS> X Cursor control characters inside CSI sequences X */ X X int i, row, col, pass, width, hlfxtra; X char c, *ctext = "This is a correct sentence"; X X for (pass = 0; pass <= 1; pass++) { X if (pass == 0) { rm("?3"); width = 80; hlfxtra = 0; } X else { sm("?3"); width = 132; hlfxtra = 26; } X X decaln(); X cup( 9,10+hlfxtra); ed(1); X cup(18,60+hlfxtra); ed(0); el(1); X cup( 9,71+hlfxtra); el(0); X for (row = 10; row <= 16; row++) { X cup(row, 10+hlfxtra); el(1); X cup(row, 71+hlfxtra); el(0); X } X cup(17,30); el(2); X for (col = 1; col <= width; col++) { X hvp(24, col); printf("*"); X hvp( 1, col); printf("*"); X } X cup(2,2); X for (row = 2; row <= 23; row++) { X printf("+"); X cub(1); X ind(); X } X cup(23,width-1); X for (row = 23; row >=2; row--) { X printf("+"); X cub(1); ri(); X } X cup(2,1); X for (row = 2; row <= 23; row++) { X printf("*"); X cup(row, width); X printf("*"); X cub(10); X if(row < 10) X nel(); X else X printf("\n"); X } X cup(2,10); X cub(42+hlfxtra); cuf(2); X for (col = 3; col <= width-2; col++) { X printf("+"); X cuf(0); cub(2); cuf(1); X } X cup(23,70+hlfxtra); X cuf(42+hlfxtra); cub(2); X for (col = width-2; col >= 3; col--) { X printf("+"); X cub(1); cuf(1); cub(0); printf("%c", 8); X } X cup( 1, 1); cuu(10); cuu(1); cuu(0); X cup(24,width); cud(10); cud(1); cud(0); X X cup(10,12+hlfxtra); X for (row = 10; row <= 15; row++) { X for (col = 12+hlfxtra; col <= 69+hlfxtra; col++) printf(" "); X cud(1); cub(58); X } X cuu(5); cuf(1); X printf("The screen should be cleared, and have an unbroken bor-"); X cup(12,13+hlfxtra); X printf("der of *'s and +'s around the edge, and exactly in the"); X cup(13,13+hlfxtra); X printf("middle there should be a frame of E's around this text"); X cup(14,13+hlfxtra); X printf("with one (1) free position around it. "); X holdit(); X } X rm("?3"); X X ed(2); X cup(1,1); X println("Test of cursor-control characters inside ESC sequences."); X println("Below should be two identical lines:"); X println(""); X println("A B C D E F G H I J K L M N O P Q R S"); X for (i = 1; i < 20; i++) { X printf("%c", 64 + i); X brcstr("2\010", 'C'); /* Two forward, one backspace */ X } X println(""); X println(""); X holdit(); X X ed(2); X cup(1,1); X println("Test of leading zeros in ESC sequences."); X printf("Two lines below you should see the sentence \"%s\".",ctext); X for (col = 1; *ctext; col++) X printf("\033[00000000004;00000000%dH%c",col,*ctext++); X cup(20,1); X holdit(); X} X Xtst_screen() { X X /* Test of: X - DECSTBM (Set Top and Bottom Margins) X - TBC (Tabulation Clear) X - HTS (Horizontal Tabulation Set) X - SM RM (Set/Reset mode): - 80/132 chars X - Origin: Realtive/absolute X - Scroll: Smooth/jump X - Wraparound X - SGR (Select Graphic Rendition) X - SM RM (Set/Reset Mode) - Inverse X - DECSC (Save Cursor) X - DECRC (Restore Cursor) X */ X X int i, j, cset, row, col, down, soft, background; X X static char *tststr = "*qx`"; X static char *attr[5] = { ";0", ";1", ";4", ";5", ";7" }; X X cup(1,1); X sm("?7"); /* Wrap Around ON */ X for (col = 1; col <= 160; col++) printf("*"); X rm("?7"); /* Wrap Around OFF */ X cup(3,1); X for (col = 1; col <= 160; col++) printf("*"); X sm("?7"); /* Wrap Around ON */ X cup(5,1); X println("This should be three identical lines of *'s completely filling"); X println("the top of the screen without any empty lines between."); X println("(Test of WRAP AROUND mode setting.)"); X holdit(); X X ed(2); X tbc(3); X cup(1,1); X for (col = 1; col <= 78; col += 3) { X cuf(3); hts(); X } X cup(1,4); X for (col = 4; col <= 78; col += 6) { X tbc(0); cuf(6); X } X cup(1,7); tbc(1); tbc(2); /* no-op */ X cup(1,1); for (col = 1; col <= 78; col += 6) printf("\t*"); X cup(2,2); for (col = 2; col <= 78; col += 6) printf(" *"); X cup(4,1); X println("Test of TAB setting/resetting. These two lines"); X printf("should look the same. "); X holdit(); X for (background = 0; background <= 1; background++) { X if (background) rm("?5"); X else sm("?5"); X sm("?3"); /* 132 cols */ X ed(2); /* VT100 clears screen on SM3/RM3, but not obviously, so... */ X cup(1,1); tbc(3); X for (col = 1; col <= 132; col += 8) { X cuf(8); hts(); X } X cup(1,1); for (col = 1; col <= 130; col += 10) printf("1234567890"); X printf("12"); X for (row = 3; row <= 20; row++) { X cup(row,row); X printf("This is 132 column mode, %s background.", X background ? "dark" : "light"); X } X holdit(); X rm("?3"); /* 80 cols */ X ed(2); /* VT100 clears screen on SM3/RM3, but not obviously, so... */ X cup(1,1); for (col = 1; col <= 80; col += 10) printf("1234567890"); X for (row = 3; row <= 20; row++) { X cup(row,row); X printf("This is 80 column mode, %s background.", X background ? "dark" : "light"); X } X holdit(); X } X X ed(2); X sm("?6"); /* Origin mode (relative) */ X for (soft = -1; soft <= 0; soft++) { X if (soft) sm("?4"); X else rm("?4"); X for (row = 12; row >= 1; row -= 11) { X decstbm(row, 24-row+1); X ed(2); X for (down = 0; down >= -1; down--) { X if (down) cuu(24); X else cud(24); X for (i = 1; i <= 30; i++) { X printf("%s scroll %s region %d Line %d\n", X soft ? "Soft" : "Jump", X down ? "down" : "up", X 2*(13-row), i); X if (down) { ri(); ri(); } X } X } X holdit(); X } X } X ed(2); X decstbm(23,24); X printf( X "\nOrigin mode test. This line should be at the bottom of the screen."); X cup(1,1); X printf("%s", X "This line should be the one above the bottom of the screeen. "); X holdit(); X ed(2); X rm("?6"); /* Origin mode (absolute) */ X cup(24,1); X printf( X "Origin mode test. This line should be at the bottom of the screen."); X cup(1,1); X printf("%s", "This line should be at the top if the screen. "); X holdit(); X decstbm(1,24); X X ed(2); X cup( 1,20); printf("Graphic rendition test pattern:"); X cup( 4, 1); sgr("0"); printf("vanilla"); X cup( 4,40); sgr("0;1"); printf("bold"); X cup( 6, 6); sgr(";4"); printf("underline"); X cup( 6,45);sgr(";1");sgr("4");printf("bold underline"); X cup( 8, 1); sgr("0;5"); printf("blink"); X cup( 8,40); sgr("0;5;1"); printf("bold blink"); X cup(10, 6); sgr("0;4;5"); printf("underline blink"); X cup(10,45); sgr("0;1;4;5"); printf("bold underline blink"); X cup(12, 1); sgr("1;4;5;0;7"); printf("negative"); X cup(12,40); sgr("0;1;7"); printf("bold negative"); X cup(14, 6); sgr("0;4;7"); printf("underline negative"); X cup(14,45); sgr("0;1;4;7"); printf("bold underline negative"); X cup(16, 1); sgr("1;4;;5;7"); printf("blink negative"); X cup(16,40); sgr("0;1;5;7"); printf("bold blink negative"); X cup(18, 6); sgr("0;4;5;7"); printf("underline blink negative"); X cup(18,45); sgr("0;1;4;5;7"); printf("bold underline blink negative"); X sgr(""); X X rm("?5"); /* Inverse video off */ X cup(23,1); el(0); printf("Dark background. "); holdit(); X sm("?5"); /* Inverse video */ X cup(23,1); el(0); printf("Light background. "); holdit(); X rm("?5"); X ed(2); X cup(8,12); printf("normal"); X cup(8,24); printf("bold"); X cup(8,36); printf("underscored"); X cup(8,48); printf("blinking"); X cup(8,60); printf("reversed"); X cup(10,1); printf("stars:"); X cup(12,1); printf("line:"); X cup(14,1); printf("x'es:"); X cup(16,1); printf("diamonds:"); X for (cset = 0; cset <= 3; cset++) { X for (i = 0; i <= 4; i++) { X cup(10 + 2 * cset, 12 + 12 * i); X sgr(attr[i]); X if (cset == 0 || cset == 2) scs(0,'B'); X else scs(0,'0'); X for (j = 0; j <= 4; j++) { X printf("%c", tststr[cset]); X } X decsc(); X cup(cset + 1, i + 1); sgr(""); scs(0,'B'); printf("A"); X decrc(); X for (j = 0; j <= 4; j++) { X printf("%c", tststr[cset]); X } X } X } X sgr("0"); scs(0,'B'); cup(21,1); X println("Test of the SAVE/RESTORE CURSOR feature. There should"); X println("be ten characters of each flavour, and a rectangle"); X println("of 5 x 4 A's filling the top left of the screen."); X holdit(); X} X Xtst_characters() { X /* Test of: X SCS (Select character Set) X */ X X int i, j, g, cset; X char chcode[5], *setmsg[5]; X X chcode[0] = 'A'; X chcode[1] = 'B'; X chcode[2] = '0'; X chcode[3] = '1'; X chcode[4] = '2'; X setmsg[0] = "UK / national"; X setmsg[1] = "US ASCII"; X setmsg[2] = "Special graphics and line drawing"; X setmsg[3] = "Alternate character ROM standard characters"; X setmsg[4] = "Alternate character ROM special graphics"; X X cup(1,10); printf("Selected as G0 (with SI)"); X cup(1,48); printf("Selected as G1 (with SO)"); X for (cset = 0; cset <= 4; cset++) { X scs(1,'B'); X cup(3 + 4 * cset, 1); X sgr("1"); X printf("Character set %c (%s)",chcode[cset], setmsg[cset]); X sgr("0"); X for (g = 0; g <= 1; g++) { X scs(g,chcode[cset]); X for (i = 1; i <= 3; i++) { X cup(3 + 4 * cset + i, 10 + 38 * g); X for (j = 0; j <= 31; j++) { X printf("%c", i * 32 + j); X } X } X } X } X scs(1,'B'); X cup(24,1); printf("These are the installed character sets. "); X holdit(); X} X Xtst_doublesize() { X /* Test of: X DECSWL (Single Width Line) X DECDWL (Double Width Line) X DECDHL (Double Height Line) (also implicit double width) X */ X X int col, i, w, w1; X X /* Print the test pattern in both 80 and 132 character width */ X X for(w = 0; w <= 1; w++) { X w1 = 13 * w; X X ed(2); X cup(1, 1); X if (w) { sm("?3"); printf("132 column mode"); } X else { rm("?3"); printf(" 80 column mode"); } X X cup( 5, 3 + 2 * w1); X printf("v------- left margin"); X X cup( 7, 3 + 2 * w1); X printf("This is a normal-sized line"); X decdhl(0); decdhl(1); decdwl(); decswl(); X X cup( 9, 2 + w1); X printf("This is a Double-width line"); X decswl(); decdhl(0); decdhl(1); decdwl(); X X cup(11, 2 + w1); X decdwl(); decswl(); decdhl(1); decdhl(0); X printf("This is a Double-width-and-height line"); X cup(12, 2 + w1); X decdwl(); decswl(); decdhl(0); decdhl(1); X printf("This is a Double-width-and-height line"); X X cup(14, 2 + w1); X decdwl(); decswl(); decdhl(1); decdhl(0); el(2); X printf("This is another such line"); X cup(15, 2 + w1); X decdwl(); decswl(); decdhl(0); decdhl(1); X printf("This is another such line"); X X cup(17, 3 + 2 * w1); X printf("^------- left margin"); X X cup(21, 1); X printf("This is not a double-width line"); X for (i = 0; i <= 1; i++) { X cup(21,6); X if (i) { printf("**is**"); decdwl(); } X else { printf("is not"); decswl(); } X cup(23,1); holdit(); X } X } X /* Set vanilla tabs for next test */ X cup(1,1); tbc(3); for (col = 1; col <= 132; col += 8) { cuf(8); hts(); } X rm("?3"); X ed(2); X scs(0,'0'); X X cup( 8,1); decdhl(0); printf("lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk"); X cup( 9,1); decdhl(1); printf("lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk"); X cup(10,1); decdhl(0); printf("x%c%c%c%c%cx",9,9,9,9,9); X cup(11,1); decdhl(1); printf("x%c%c%c%c%cx",9,9,9,9,9); X cup(12,1); decdhl(0); printf("x%c%c%c%c%cx",9,9,9,9,9); X cup(13,1); decdhl(1); printf("x%c%c%c%c%cx",9,9,9,9,9); X cup(14,1); decdhl(0); printf("x x"); X cup(15,1); decdhl(1); printf("x x"); X cup(16,1); decdhl(0); printf("mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj"); X cup(17,1); decdhl(1); printf("mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj"); X scs(0,'B'); sgr("1;5"); X cup(12,3); X printf("* The mad programmer strikes again * "); X cup(13,3); printf("%c",9); cub(6); X printf("* The mad programmer strikes again *"); X sgr("0"); X cup(22,1); X println("Another test pattern... a frame with blinking bold text,"); X printf("all in double-height double-width size. "); X holdit(); X X decstbm(8,24); /* Absolute origin mode, so cursor is set at (1,1) */ X cup(8,1); X for (i = 1; i <= 12; i++) X ri(); X decstbm(0,0); /* No scroll region */ X cup(1,1); X printf("%s", "Exactly half of the box should remain. "); X holdit(); X} X Xtst_keyboard() { X X/* Test of: X - DECLL (Load LEDs) X - Keyboard return messages X - SM RM (Set/Reset Mode) - Cursor Keys X - Auto repeat X - DECKPAM (Keypad Application Mode) X - DECKPNM (Keypad Numeric Mode) X XThe standard VT100 keayboard layout: X X UP DN LE RI X XESC 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ `~ BS X XTAB* qQ wW eE rR tT yY uU iI oO pP [{ ]} DEL X X** ** aA sS dD fF gG hH jJ kK lL ;: ," RETN \| X X** **** zZ xX cC vV bB nN mM ,< .> /? **** LF X X ****************SPACE BAR**************** X X PF1 PF2 PF3 PF4 X X *7* *8* *9* *-* X X *4* *5* *6* *,* X X *1* *2* *3* X X ***0*** *.* ENT X*/ X X char *ledmsg[6], *ledseq[6]; X X int i, j, okflag; X int kblayout; X int ckeymode; X int fkeymode; X char kbdc; X char *kbds = " "; X char *curkeystr, *fnkeystr, *abmstr; X char arptstring[500]; X X static struct key { X char c; X int row; X int col; X char *symbol; X } keytab [] = { X { 27, 1, 0, "ESC" }, X { '1', 1, 6, "1" }, { '!', 1, 7, "!" }, X { '2', 1, 11, "2" }, { '@', 1, 12, "@" }, X { '3', 1, 16, "3" }, { '#', 1, 17, "#" }, X { '4', 1, 21, "4" }, { '$', 1, 22, "$" }, X { '5', 1, 26, "5" }, { '%', 1, 27, "%" }, X { '6', 1, 31, "6" }, { '^', 1, 32, "^" }, X { '7', 1, 36, "7" }, { '&', 1, 37, "&" }, X { '8', 1, 41, "8" }, { '*', 1, 42, "*" }, X { '9', 1, 46, "9" }, { '(', 1, 47, "(" }, X { '0', 1, 51, "0" }, { ')', 1, 52, ")" }, X { '-', 1, 56, "-" }, { '_', 1, 57, "_" }, X { '=', 1, 61, "=" }, { '+', 1, 62, "+" }, X { '`', 1, 66, "`" }, { '~', 1, 67, "~" }, X { 8, 1, 70, "BS" }, X { 9, 2, 0, " TAB " }, X { 'q', 2, 8, "q" }, { 'Q', 2, 9, "Q" }, X { 'w', 2, 13, "w" }, { 'W', 2, 14, "W" }, X { 'e', 2, 18, "e" }, { 'E', 2, 19, "E" }, X { 'r', 2, 23, "r" }, { 'R', 2, 24, "R" }, X { 't', 2, 28, "t" }, { 'T', 2, 29, "T" }, X { 'y', 2, 33, "y" }, { 'Y', 2, 34, "Y" }, X { 'u', 2, 38, "u" }, { 'U', 2, 39, "U" }, X { 'i', 2, 43, "i" }, { 'I', 2, 44, "I" }, X { 'o', 2, 48, "o" }, { 'O', 2, 49, "O" }, X { 'p', 2, 53, "p" }, { 'P', 2, 54, "P" }, X { '[', 2, 58, "[" }, { '{', 2, 59, "{" }, X { ']', 2, 63, "]" }, { '}', 2, 64, "}" }, X { 127, 2, 71, "DEL" }, X { 'a', 3, 10, "a" }, { 'A', 3, 11, "A" }, X { 's', 3, 15, "s" }, { 'S', 3, 16, "S" }, X { 'd', 3, 20, "d" }, { 'D', 3, 21, "D" }, X { 'f', 3, 25, "f" }, { 'F', 3, 26, "F" }, X { 'g', 3, 30, "g" }, { 'G', 3, 31, "G" }, X { 'h', 3, 35, "h" }, { 'H', 3, 36, "H" }, X { 'j', 3, 40, "j" }, { 'J', 3, 41, "J" }, X { 'k', 3, 45, "k" }, { 'K', 3, 46, "K" }, X { 'l', 3, 50, "l" }, { 'L', 3, 51, "L" }, X { ';', 3, 55, ";" }, { ':', 3, 56, ":" }, X {'\'', 3, 60, "'" }, { '"', 3, 61,"\"" }, X { 13, 3, 65, "RETN"}, X {'\\', 3, 71,"\\" }, { '|', 3, 72, "|" }, X { 'z', 4, 12, "z" }, { 'Z', 4, 13, "Z" }, X { 'x', 4, 17, "x" }, { 'X', 4, 18, "X" }, X { 'c', 4, 22, "c" }, { 'C', 4, 23, "C" }, X { 'v', 4, 27, "v" }, { 'V', 4, 28, "V" }, X { 'b', 4, 32, "b" }, { 'B', 4, 33, "B" }, X { 'n', 4, 37, "n" }, { 'N', 4, 38, "N" }, X { 'm', 4, 42, "m" }, { 'M', 4, 43, "M" }, X { ',', 4, 47, "," }, { '<', 4, 48, "<" }, X { '.', 4, 52, "." }, { '>', 4, 53, ">" }, X { '/', 4, 57, "/" }, { '?', 4, 58, "?" }, X { 10, 4, 69, "LF" }, X { ' ', 5, 13, " SPACE BAR "}, X {'\0', 0, 0, "" } X }; X X static struct natkey { X char natc; X int natrow; X int natcol; X char *natsymbol; X } natkeytab [][29] = { X { X { '"', 1, 12, "\""}, X { '&', 1, 32, "&" }, X { '/', 1, 37, "/" }, X { '(', 1, 42, "(" }, X { ')', 1, 47, ")" }, X { '=', 1, 52, "=" }, X { '+', 1, 56, "+" }, { '?', 1, 57, "?" }, X { '`', 1, 61, "`" }, { '@', 1, 62, "@" }, X { '<', 1, 66, "<" }, { '>', 1, 67, ">" }, X { '}', 2, 58, "}" }, { ']', 2, 59, "]" }, X { '^', 2, 63, "^" }, { '~', 2, 64, "~" }, X { '|', 3, 55, "|" }, {'\\', 3, 56,"\\" }, X { '{', 3, 60, "{" }, { '[', 3, 61, "[" }, X {'\'', 3, 71, "'" }, { '*', 3, 72, "*" }, X { ',', 4, 47, "," }, { ';', 4, 48, ";" }, X { '.', 4, 52, "." }, { ':', 4, 53, ":" }, X { '-', 4, 57, "-" }, { '_', 4, 58, "_" }, X {'\0', 0, 0, "" } X }, X { X { '"', 1, 12, "\""}, X { '&', 1, 32, "&" }, X { '/', 1, 37, "/" }, X { '(', 1, 42, "(" }, X { ')', 1, 47, ")" }, X { '=', 1, 52, "=" }, X { '+', 1, 56, "+" }, { '?', 1, 57, "?" }, X { '`', 1, 61, "`" }, { '@', 1, 62, "@" }, X { '<', 1, 66, "<" }, { '>', 1, 67, ">" }, X { '}', 2, 58, "}" }, { ']', 2, 59, "]" }, X { '~', 2, 63, "~" }, { '^', 2, 64, "^" }, X { '|', 3, 55, "|" }, {'\\', 3, 56,"\\" }, X { '{', 3, 60, "{" }, { '[', 3, 61, "[" }, X {'\'', 3, 71, "'" }, { '*', 3, 72, "*" }, X { ',', 4, 47, "," }, { ';', 4, 48, ";" }, X { '.', 4, 52, "." }, { ':', 4, 53, ":" }, X { '-', 4, 57, "-" }, { '_', 4, 58, "_" }, X {'\0', 0, 0, "" } X } X }; X X static struct curkey { X char *curkeymsg[3]; X int curkeyrow; X int curkeycol; X char *curkeysymbol; X char *curkeyname; X } curkeytab [] = { X X /* A Reset, A Set, VT52 */ X X {{"\033[A","\033OA","\033A"}, 0, 56, "UP", "Up arrow" }, X {{"\033[B","\033OB","\033B"}, 0, 61, "DN", "Down arrow" }, X {{"\033[D","\033OD","\033D"}, 0, 66, "LT", "Left arrow" }, X {{"\033[C","\033OC","\033C"}, 0, 71, "RT", "Right arrow"}, X {{"", "", "" }, 0, 0, "", "" } X }; X X static struct fnkey { X char *fnkeymsg[4]; X int fnkeyrow; X int fnkeycol; X char *fnkeysymbol; X char *fnkeyname; X } fnkeytab [] = { X X /* ANSI-num,ANSI-app,VT52-nu,VT52-ap, r, c, symb name */ X X {{"\033OP","\033OP","\033P","\033P" }, 6, 59, "PF1", "PF1" }, X {{"\033OQ","\033OQ","\033Q","\033Q" }, 6, 63, "PF2", "PF2" }, X {{"\033OR","\033OR","\033R","\033R" }, 6, 67, "PF3", "PF3" }, X {{"\033OS","\033OS","\033S","\033S" }, 6, 71, "PF4", "PF4" }, X {{"7", "\033Ow","7", "\033?w"}, 7, 59, " 7 ", "Numeric 7" }, X {{"8", "\033Ox","8", "\033?x"}, 7, 63, " 8 ", "Numeric 8" }, X {{"9", "\033Oy","9", "\033?y"}, 7, 67, " 9 ", "Numeric 9" }, X {{"-", "\033Om","-", "\033?m"}, 7, 71, " - ", "Minus" }, X {{"4", "\033Ot","4", "\033?t"}, 8, 59, " 4 ", "Numeric 4" }, X {{"5", "\033Ou","5", "\033?u"}, 8, 63, " 5 ", "Numeric 5" }, X {{"6", "\033Ov","6", "\033?v"}, 8, 67, " 6 ", "Numeric 6" }, X {{",", "\033Ol",",", "\033?l"}, 8, 71, " , ", "Comma" }, X {{"1", "\033Oq","1", "\033?q"}, 9, 59, " 1 ", "Numeric 1" }, X {{"2", "\033Or","2", "\033?r"}, 9, 63, " 2 ", "Numeric 2" }, X {{"3", "\033Os","3", "\033?s"}, 9, 67, " 3 ", "Numeric 3" }, X {{"0", "\033Op","0", "\033?p"},10, 59," O ","Numeric 0"}, X {{".", "\033On",".", "\033?n"},10, 67, " . ", "Point" }, X {{"\015", "\033OM","\015", "\033?M"},10, 71, "ENT", "ENTER" }, X {{"","","",""}, 0, 0, "", "" } X }; X X static struct ckey { X int ccount; X char *csymbol; X } ckeytab [] = { X { 0, "NUL (CTRL-@ or CTRL-Space)" }, X { 0, "SOH (CTRL-A)" }, X { 0, "STX (CTRL-B)" }, X { 0, "ETX (CTRL-C)" }, X { 0, "EOT (CTRL-D)" }, X { 0, "ENQ (CTRL-E)" }, X { 0, "ACK (CTRL-F)" }, X { 0, "BEL (CTRL-G)" }, X { 0, "BS (CTRL-H) (BACK SPACE)" }, X { 0, "HT (CTRL-I) (TAB)" }, X { 0, "LF (CTRL-J) (LINE FEED)" }, X { 0, "VT (CTRL-K)" }, X { 0, "FF (CTRL-L)" }, X { 0, "CR (CTRL-M) (RETURN)" }, X { 0, "SO (CTRL-N)" }, X { 0, "SI (CTRL-O)" }, X { 0, "DLE (CTRL-P)" }, X { 0, "DC1 (CTRL-Q) (X-On)" }, X { 0, "DC2 (CTRL-R)" }, X { 0, "DC3 (CTRL-S) (X-Off)" }, X { 0, "DC4 (CTRL-T)" }, X { 0, "NAK (CTRL-U)" }, X { 0, "SYN (CTRL-V)" }, X { 0, "ETB (CTRL-W)" }, X { 0, "CAN (CTRL-X)" }, X { 0, "EM (CTRL-Y)" }, X { 0, "SUB (CTRL-Z)" }, X { 0, "ESC (CTRL-[) (ESCAPE)" }, X { 0, "FS (CTRL-\\ or CTRL-? or CTRL-_)" }, X { 0, "GS (CTRL-])" }, X { 0, "RS (CTRL-^ or CTRL-~ or CTRL-`)" }, X { 0, "US (CTRL-_ or CTRL-?)" } X }; X X static char *keyboardmenu[] = { X "Standard American ASCII layout", X "Swedish national layout D47", X "Swedish national layout E47", X /* add new keyboard layouts here */ X "" X }; X X static char *curkeymodes[3] = { X "ANSI / Cursor key mode RESET", X "ANSI / Cursor key mode SET", X "VT52 Mode" X }; X X static char *fnkeymodes[4] = { X "ANSI Numeric mode", X "ANSI Application mode", X "VT52 Numeric mode", X "VT52 Application mode" X }; X X ledmsg[0] = "L1 L2 L3 L4"; ledseq[0] = "1;2;3;4"; X ledmsg[1] = " L2 L3 L4"; ledseq[1] = "1;0;4;3;2"; X ledmsg[2] = " L2 L3"; ledseq[2] = "1;4;;2;3"; X ledmsg[3] = "L1 L2"; ledseq[3] = ";;2;1"; X ledmsg[4] = "L1"; ledseq[4] = "1"; X ledmsg[5] = ""; ledseq[5] = ""; X X#ifdef UNIX X fflush(stdout); X#endif X ed(2); X cup(10,1); X println("These LEDs (\"lamps\") on the keyboard should be on:"); X for (i = 0; i <= 5; i++) { X cup(10,52); el(0); printf("%s", ledmsg[i]); X decll("0"); X decll(ledseq[i]); X cup(12,1); holdit(); X } X X ed(2); X cup(10,1); X println("Test of the AUTO REPEAT feature"); X println(""); X println("Hold down an alphanumeric key for a while, then push RETURN."); X printf("%s", "Auto Repeat OFF: "); X rm("?8"); X inputline(arptstring); X if (strlen(arptstring) == 0) println("No characters read!??"); X else if (strlen(arptstring) == 1) println("OK."); X else println("Too many characters read."); X println(""); X println("Hold down an alphanumeric key for a while, then push RETURN."); X printf("%s", "Auto Repeat ON: "); X sm("?8"); X inputline(arptstring); X if (strlen(arptstring) == 0) println("No characters read!??"); X else if (strlen(arptstring) == 1) println("Not enough characters read."); X else println("OK."); X println(""); X holdit(); X X ed(2); X cup(5,10); X println("Choose keyboard layout:"); X kblayout = menu(keyboardmenu); X if (kblayout) { X kblayout--; X for (j = 0; natkeytab[kblayout][j].natc != '\0'; j++) { X for (i = 0; keytab[i].c != '\0'; i++) { X if (keytab[i].row == natkeytab[kblayout][j].natrow && X keytab[i].col == natkeytab[kblayout][j].natcol) { X keytab[i].c = natkeytab[kblayout][j].natc; X keytab[i].symbol = natkeytab[kblayout][j].natsymbol; X break; X } X } X } X } X X ed(2); X for (i = 0; keytab[i].c != '\0'; i++) { X cup(1 + 2 * keytab[i].row, 1 + keytab[i].col); X sgr("7"); X printf("%s", keytab[i].symbol); X sgr(""); X } X cup(22,1); X#ifdef UNIX X sgttyNew.sg_flags &= ~CRMOD; X sgttyNew.sg_flags &= ~ECHO; X stty(0, &sgttyNew); X#endif X inflush(); X printf("Press each key, both shifted and unshifted. Finish with RETURN:"); X do { /* while (kbdc != 13) */ X cup(23,1); kbdc = inchar(); X cup(23,1); el(0); X sprintf(kbds, "%c", kbdc); X chrprint(kbds); X for (i = 0; keytab[i].c != '\0'; i++) { X if (keytab[i].c == kbdc) { X cup(1 + 2 * keytab[i].row, 1 + keytab[i].col); X printf("%s", keytab[i].symbol); X break; X } X } X } while (kbdc != 13); X#ifdef SARG10 X inchar(); /* Local hack: Read LF that TOPS-10 adds to CR */ X#endif X cup(23,1); el(0); X X for (ckeymode = 0; ckeymode <= 2; ckeymode++) { X if (ckeymode) sm("?1"); X else rm("?1"); X for (i = 0; curkeytab[i].curkeysymbol[0] != '\0'; i++) { X cup(1 + 2 * curkeytab[i].curkeyrow, 1 + curkeytab[i].curkeycol); X sgr("7"); X printf("%s", curkeytab[i].curkeysymbol); X sgr(""); X } X cup(20,1); printf("<%s>%20s", curkeymodes[ckeymode], ""); X cup(22,1); el(0); X cup(22,1); printf("%s", "Press each cursor key. Finish with TAB."); X for(;;) { X cup(23,1); X if (ckeymode == 2) rm("?2"); /* VT52 mode */ X curkeystr = instr(); X esc("<"); /* ANSI mode */ X cup(23,1); el(0); X cup(23,1); chrprint(curkeystr); X if (!strcmp(curkeystr,"\t")) break; X for (i = 0; curkeytab[i].curkeysymbol[0] != '\0'; i++) { X if (!strcmp(curkeystr,curkeytab[i].curkeymsg[ckeymode])) { X sgr("7"); X printf(" (%s key) ", curkeytab[i].curkeyname); X sgr(""); X cup(1 + 2 * curkeytab[i].curkeyrow, X 1 + curkeytab[i].curkeycol); X printf("%s", curkeytab[i].curkeysymbol); X break; X } X } X if (i == sizeof(curkeytab) / sizeof(struct curkey) - 1) { X sgr("7"); X printf("%s", " (Unknown cursor key) "); X sgr(""); X } X } X } X X for (fkeymode = 0; fkeymode <= 3; fkeymode++) { X for (i = 0; fnkeytab[i].fnkeysymbol[0] != '\0'; i++) { X cup(1 + 2 * fnkeytab[i].fnkeyrow, 1 + fnkeytab[i].fnkeycol); X sgr("7"); X printf("%s", fnkeytab[i].fnkeysymbol); X sgr(""); X } X cup(20,1); printf("<%s>%20s", fnkeymodes[fkeymode], ""); X cup(22,1); el(0); X cup(22,1); printf("%s", "Press each function key. Finish with TAB."); X for(;;) { X cup(23,1); X if (fkeymode >= 2) rm("?2"); /* VT52 mode */ X if (fkeymode % 2) deckpam(); /* Application mode */ X else deckpnm(); /* Numeric mode */ X fnkeystr = instr(); X esc("<"); /* ANSI mode */ X cup(23,1); el(0); X cup(23,1); chrprint(fnkeystr); X if (!strcmp(fnkeystr,"\t")) break; X for (i = 0; fnkeytab[i].fnkeysymbol[0] != '\0'; i++) { X if (!strcmp(fnkeystr,fnkeytab[i].fnkeymsg[fkeymode])) { X sgr("7"); X printf(" (%s key) ", fnkeytab[i].fnkeyname); X sgr(""); X cup(1 + 2 * fnkeytab[i].fnkeyrow, 1 + fnkeytab[i].fnkeycol); X printf("%s", fnkeytab[i].fnkeysymbol); X break; X } X } X if (i == sizeof(fnkeytab) / sizeof(struct fnkey) - 1) { X sgr("7"); X printf("%s", " (Unknown function key) "); X sgr(""); X } X } X } X X#ifdef UNIX X sgttyNew.sg_flags |= CRMOD; X stty(0, &sgttyNew); X#endif X ed(2); X cup(5,1); X println("Finally, a check of the ANSWERBACK MESSAGE, which can be sent"); X println("by pressing CTRL-BREAK. The answerback message can be loaded"); X println("in SET-UP B by pressing SHIFT-A and typing e.g."); X println(""); X println(" \" H e l l o , w o r l d Return \""); X println(""); X println("(the double-quote characters included). Do that, and then try"); X println("to send an answerback message with CTRL-BREAK. If it works,"); X println("the answerback message should be displayed in reverse mode."); X println("Finish with a single RETURN."); X X#ifdef UNIX X sgttyNew.sg_flags &= ~CRMOD; X stty(0, &sgttyNew); X#endif X do { X cup(17,1); X inflush(); X abmstr = instr(); X cup(17,1); X el(0); X chrprint(abmstr); X } while (strcmp(abmstr,"\r")); X X ed(2); X for (i = 0; i < 32; i++) { X cup(1 + (i % 16), 1 + 40 * (i / 16)); X sgr("7"); X printf("%s", ckeytab[i].csymbol); X sgr("0"); X } X cup(19,1); X#ifdef UNIX X sgttyNew.sg_flags |= CRMOD; X stty(0, &sgttyNew); X#endif X println( X "Push each CTRL-key TWICE. Note that you should be able to send *all*"); X println( X "CTRL-codes twice, including CTRL-S (X-Off) and CTRL-Q (X-Off)!"); X println( X "Finish with DEL (also called DELETE or RUB OUT), or wait 1 minute."); X#ifdef UNIX X#ifdef SIII X sgttyNew.sg_flags &= ~CBREAK; X stty(0, &sgttyNew); X#endif X sgttyNew.sg_flags |= RAW; X stty(0, &sgttyNew); X#endif X ttybin(1); X#ifdef SARG20 X page(0); /* Turn off all character processing at input */ X superbin(1); /* Turn off ^C (among others). Keep your fingers crossed!! */ X#endif X do { X cup(23,1); kbdc = inchar(); X cup(23,1); el(0); X if (kbdc < 32) printf(" %s", ckeytab[kbdc].csymbol); X else { X sprintf(kbds, "%c", kbdc); X chrprint(kbds); X printf("%s", " -- not a CTRL key"); X } X if (kbdc < 32) ckeytab[kbdc].ccount++; X if (ckeytab[kbdc].ccount == 2) { X cup(1 + (kbdc % 16), 1 + 40 * (kbdc / 16)); X printf("%s", ckeytab[kbdc].csymbol); X } X } while (kbdc != '\177'); X#ifdef UNIX X sgttyNew.sg_flags &= ~RAW; X sgttyNew.sg_flags |= ECHO; X stty(0, &sgttyNew); X#ifdef SIII X sgttyNew.sg_flags |= CBREAK; X stty(0, &sgttyNew); X#endif X#endif X ttybin(0); X#ifdef SARG20 X superbin(0); /* Puuuh! We made it!? */ X page(1); /* Back to normal input processing */ X ttybin(1); /* This must be the mode for DEC20 */ X#endif X cup(24,1); X okflag = 1; X for (i = 0; i < 32; i++) if (ckeytab[i].ccount < 2) okflag = 0; X if (okflag) printf("%s", "OK. "); X else printf("%s", "You have not been able to send all CTRL keys! "); X holdit(); X} X Xtst_reports() { X /* Test of: X <ENQ> (AnswerBack Message) X SM RM (Set/Reset Mode) - LineFeed / Newline X DSR (Device Status Report) X DA (Device Attributes) X DECREQTPARM (Request Terminal Parameters) X */ X X int parity, nbits, xspeed, rspeed, clkmul, flags; X int i, reportpos; X char *report, *report2; X static char *attributes[][2] = { X { "\033[?1;0c", "No options (vanilla VT100)" }, X { "\033[?1;1c", "VT100 with STP" }, X { "\033[?1;2c", "VT100 with AVO (could be a VT102)" }, X { "\033[?1;3c", "VT100 with STP and AVO" }, X { "\033[?1;4c", "VT100 with GPO" }, X { "\033[?1;5c", "VT100 with STP and GPO" }, X { "\033[?1;6c", "VT100 with AVO and GPO" }, X { "\033[?1;7c", "VT100 with STP, AVO and GPO" }, X { "\033[?1;11c", "VT100 with PP and AVO" }, X { "\033[?1;15c", "VT100 with PP, GPO and AVO" }, X { "\033[?4;2c", "VT132 with AVO" }, X { "\033[?4;3c", "VT132 with AVO and STP" }, X { "\033[?4;6c", "VT132 with GPO and AVO" }, X { "\033[?4;7c", "VT132 with GPO, AVO, and STP" }, X { "\033[?4;11c", "VT132 with PP and AVO" }, X { "\033[?4;15c", "VT132 with PP, GPO and AVO" }, X { "\033[?7c", "VT131" }, X { "\033[?12;5c", "VT125" }, /* VT125 also has ROM version */ X { "\033[?12;7c", "VT125 with AVO" }, /* number, so this won't work */ X { "\033[?5;0c", "VK100 (GIGI)" }, X { "\033[?5c", "VK100 (GIGI)" }, X { "", "" } X }; X X#ifdef UNIX X sgttyNew.sg_flags &= ~ECHO; X stty(0, &sgttyNew); X#endif X cup(5,1); X println("This is a test of the ANSWERBACK MESSAGE. (To load the A.B.M."); X println("see the TEST KEYBOARD part of this program). Below here, the"); X println("current answerback message in your terminal should be"); X println("displayed. Finish this test with RETURN."); X cup(10,1); X inflush(); X printf("%c", 5); /* ENQ */ X report = instr(); X cup(10,1); X chrprint(report); X cup(12,1); X holdit(); X X ed(2); X cup(1,1); X println("Test of LineFeed/NewLine mode."); X cup(3,1); X sm("20"); X#ifdef UNIX X sgttyNew.sg_flags &= ~CRMOD; X stty(0, &sgttyNew); X#endif X printf("NewLine mode set. Push the RETURN key: "); X report = instr(); X cup(4,1); X el(0); X chrprint(report); X if (!strcmp(report, "\015\012")) printf(" -- OK"); X else printf(" -- Not expected"); X cup(6,1); X rm("20"); X printf("NewLine mode reset. Push the RETURN key: "); X report = instr(); X cup(7,1); X el(0); X chrprint(report); X if (!strcmp(report, "\015")) printf(" -- OK"); X else printf(" -- Not expected"); X cup(9,1); X#ifdef UNIX X sgttyNew.sg_flags |= CRMOD; X stty(0, &sgttyNew); X#endif X holdit(); X X ed(2); X cup(1,1); X printf("Test of Device Status Report 5 (report terminal status)."); X cup(2,1); X dsr(5); X report = instr(); X cup(2,1); X el(0); X printf("Report is: "); X chrprint(report); X if (!strcmp(report,"\033[0n")) printf(" -- means \"TERMINAL OK\""); X else if (!strcmp(report,"\033[3n")) printf(" -- means \"TERMINAL OK\""); X else printf(" -- Unknown response!"); X X cup(4,1); X println("Test of Device Status Report 6 (report cursor position)."); X cup(5,1); X dsr(6); X report = instr(); X cup(5,1); X el(0); X printf("Report is: "); X chrprint(report); X if (!strcmp(report,"\033[5;1R")) printf(" -- OK"); X else printf(" -- Unknown response!"); X X cup(7,1); X println("Test of Device Attributes report (what are you)"); X cup(8,1); X da(0); X report = instr(); X cup(8,1); X el(0); X printf("Report is: "); X chrprint(report); X for (i = 0; *attributes[i][0] != '\0'; i++) { X if (!strcmp(report,attributes[i][0])) break; X } X if (*attributes[i][0] == '\0') X printf(" -- Unknown response, refer to the manual"); X else { X printf(" -- means %s", attributes[i][1]); X if (i) { X cup(9,1); X println("Legend: STP = Processor Option"); X println(" AVO = Advanced Video Option"); X println(" GPO = Graphics Processor Option"); X println(" PP = Printer Port"); X } X } X X cup(14,1); X println("Test of the \"Request Terminal Parameters\" feature, argument 0."); X cup(15,1); X decreqtparm(0); X report = instr(); X cup(15,1); X el(0); X printf("Report is: "); X chrprint(report); X if (strlen(report) < 16 X || report[0] != '\033' X || report[1] != '[' X || report[2] != '2' X || report[3] != ';') X println(" -- Bad format"); X else { X reportpos = 4; X parity = scanto(report, &reportpos, ';'); X nbits = scanto(report, &reportpos, ';'); X xspeed = scanto(report, &reportpos, ';'); X rspeed = scanto(report, &reportpos, ';'); X clkmul = scanto(report, &reportpos, ';'); X flags = scanto(report, &reportpos, 'x'); X if (parity == 0 || nbits == 0 || clkmul == 0) println(" -- Bad format"); X else println(" -- OK"); X printf( X "This means: Parity %s, %s bits, xmitspeed %s, recvspeed %s.\n", X lookup(paritytable, parity), X lookup(nbitstable, nbits), X lookup(speedtable, xspeed), X lookup(speedtable, rspeed)); X printf("(CLoCk MULtiplier = %d, STP option flags = %d)\n", clkmul, flags); X } X X cup(19,1); X println("Test of the \"Request Terminal Parameters\" feature, argument 1."); X cup(20,1); X decreqtparm(1); /* Does the same as decreqtparm(0), reports "3" */ X report2 = instr(); X cup(20,1); X el(0); X printf("Report is: "); X chrprint(report2); X if (strlen(report2) < 3 X || report2[2] != '3') X println(" -- Bad format"); X else { X report2[2] = '2'; X if (!strcmp(report,report2)) println(" -- OK"); X else println(" -- Bad format"); X } X cup(24,1); X holdit(); X#ifdef UNIX X sgttyNew.sg_flags |= ECHO; X stty(0, &sgttyNew); X#endif X} X Xtst_vt52() { X X static struct rtabl { X char *rcode; X char *rmsg; X } resptable[] = { X { "\033/K", " -- OK (means Standard VT52)" }, X { "\033/Z", " -- OK (means VT100 emulating VT52)" }, X { "", " -- Unknown response"} X }; X X int i,j; X char *response; X X rm("?2"); /* Reset ANSI (VT100) mode, Set VT52 mode */ X esc("H"); /* Cursor home */ X esc("J"); /* Erase to end of screen */ X esc("H"); /* Cursor home */ X for (i = 0; i <= 23; i++) { X for (j = 0; j <= 9; j++) X printf("%s", "FooBar "); X println("Bletch"); X } X esc("H"); /* Cursor home */ X esc("J"); /* Erase to end of screen */ X X vt52cup(7,47); X printf("nothing more."); X for (i = 1; i <= 10; i++) printf("THIS SHOULD GO AWAY! "); X for (i = 1; i <= 5; i++) { X vt52cup(1,1); X printf("%s", "Back scroll (this should go away)"); X esc("I"); /* Reverse LineFeed (with backscroll!) */ X } X vt52cup(12,60); X esc("J"); /* Erase to end of screen */ X for (i = 2; i <= 6; i++) { X vt52cup(i,1); X esc("K"); /* Erase to end of line */ X } X X for (i = 2; i <= 23; i++) { X vt52cup(i,70); printf("%s", "**Foobar"); X } X vt52cup(23,10); X for (i = 23; i >= 2; i--) { X printf("%s", "*"); X printf("%c", 8); /* BS */ X esc("I"); /* Reverse LineFeed (LineStarve) */ X } X vt52cup(1,70); X for (i = 70; i >= 10; i--) { X printf("%s", "*"); X esc("D"); esc("D"); /* Cursor Left */ X } X vt52cup(24,10); X for (i = 10; i <= 70; i++) { X printf("%s", "*"); X printf("%c", 8); /* BS */ X esc("C"); /* Cursor Right */ X } X vt52cup(2,11); X for (i = 2; i <= 23; i++) { X printf("%s", "!"); X printf("%c", 8); /* BS */ X esc("B"); /* Cursor Down */ X } X vt52cup(23,69); X for (i = 23; i >= 2; i--) { X printf("%s", "!"); X printf("%c", 8); /* BS */ X esc("A"); /* Cursor Up */ X } X for (i = 2; i <= 23; i++) { X vt52cup(i,71); X esc("K"); /* Erase to end of line */ X } X X vt52cup(10,16); X printf("%s", "The screen should be cleared, and have a centered"); X vt52cup(11,16); X printf("%s", "rectangle of \"*\"s with \"!\"s on the inside to the"); X vt52cup(12,16); X printf("%s", "left and right. Only this, and"); X vt52cup(13,16); X holdit(); X X esc("H"); /* Cursor home */ X esc("J"); /* Erase to end of screen */ X printf("%s", "This is the normal character set:"); X for (j = 0; j <= 1; j++) { X vt52cup(3 + j, 16); X for (i = 0; i <= 47; i++) X printf("%c", 32 + i + 48 * j); X } X vt52cup(6,1); X printf("%s", "This is the special graphics character set:"); X esc("F"); /* Select Special Graphics character set */ X for (j = 0; j <= 1; j++) { X vt52cup(8 + j, 16); X for (i = 0; i <= 47; i++) X printf("%c", 32 + i + 48 * j); X } X esc("G"); /* Select ASCII character set */ X vt52cup(12,1); X holdit(); X X esc("H"); /* Cursor home */ X esc("J"); /* Erase to end of screen */ X println("Test of terminal response to IDENTIFY command"); X esc("Z"); /* Identify */ X response = instr(); X println(""); X printf("Response was"); X esc("<"); /* Enter ANSI mode (VT100 mode) */ X chrprint(response); X for(i = 0; resptable[i].rcode[0] != '\0'; i++) X if (!strcmp(response, resptable[i].rcode)) X break; X printf("%s", resptable[i].rmsg); X println(""); X println(""); X holdit(); X} X Xtst_insdel() { X X /* Test of: X SM/RM(4) (= IRM (Insertion/replacement mode)) X ICH (Insert Character) X DCH (Delete character) X IL (Insert line) X DL (Delete line) X */ X X int i, row, col, sw, dblchr, scr132; X X for(scr132 = 0; scr132 <= 1; scr132++) { X if (scr132) { sm("?3"); sw = 132; } X else { rm("?3"); sw = 80; } X ed(2); X cup(1,1); X for (row=1; row<=24; row++) { X cup(row,1); X for (col=1; col<=sw; col++) X printf("%c", 'A'-1+row); X } X cup(4,1); X printf("Screen accordion test (Insert & Delete Line). "); holdit(); X ri(); el(2); X decstbm( 2,23); X sm("?6"); X cup(1,1); X for (row=1; row<=24; row++) { X il(row); X dl(row); X } X rm("?6"); X decstbm( 0, 0); X cup(2,1); X printf( X "Top line: A's, bottom line: X's, this line, nothing more. "); X holdit(); X cup(2,1); ed(0); X cup(1,2); X printf("B"); X cub(1); X sm("4"); X for (col=2; col<=sw-1; col++) X printf("*"); X rm("4"); X cup(4,1); X printf("Test of 'Insert Mode'. The top line should be 'A*** ... ***B'. "); X holdit(); ri(); el(2); X cup(1,2); X dch(sw-2); X cup(4,1); X printf("Test of 'Delete Character'. The top line should be 'AB'. "); X holdit(); X X for(dblchr = 1; dblchr <= 2; dblchr++) { X ed(2); X for (row=1; row<=24; row++) { X cup(row,1); X if (dblchr == 2) decdwl(); X for (col=1; col<=sw/dblchr; col++) X printf("%c", 'A'-1+row); X cup(row,sw/dblchr-row); X dch(row); X } X cup(4,1); X println("The right column should be staggered "); X printf("by one. "); X holdit(); X } X ed(2); X cup(1,1); X println("If your terminal has the ANSI 'Insert Character' function"); X println("(the VT102 does not), then you should see a line like this"); X println(" A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"); X println("below:"); X println(""); X for (i = 'Z'; i >= 'A'; i--) { X printf("%c\010",i); X ich(2); X } X cup(10,1); X holdit(); X X if (sw == 132) rm("?3"); X } X} X Xdch(pn) int pn; { brc(pn, 'P'); } /* Delete character */ Xich(pn) int pn; { brc(pn, '@'); } /* Insert character -- not in VT102 */ Xdl(pn) int pn; { brc(pn, 'M'); } /* Delete line */ Xil(pn) int pn; { brc(pn, 'L'); } /* Insert line */ X X/* Test of some known VT100 bugs and misfeatures */ X Xtst_bugs() { X X int i, menuchoice; X X static char *menutable[] = { X "Exit to main menu", X "Bug A: Smooth scroll to jump scroll", X "Bug B: Scrolling region", X "Bug C: Wide to narrow screen", X "Bug D: Narrow to wide screen", X "Bug E: Cursor move from double- to single-wide line", X "Bug F: Column mode escape sequence", X "Wrap around with cursor addressing", X "Erase right half of double width lines", X "Funny scroll regions", X /* Add more here */ X "" X }; X X static char *hmsg[] = { X "Test of known bugs in the DEC VT100 series. The numbering of some of", X "the bugs (A-F) refers to the article 'VT100 MAGIC' by Sami Tabih in", X "the 'Proceedings of the DEC Users Society' at St. Louis, Missouri, May", X "1983. To understand some of the tests, you have to look at the source", X "code or the article. Of course, a good VT100-compatible terminal", X "should not have these bugs (or have some means of disabling them)! If", X "a bug appears, you might want to RESET the terminal before continuing", X "the test. There is a test of the RESET function in the main menu.", X "" }; X X do { X ed(2); cup(1,1); X for (i = 0; *hmsg[i]; i++) println(hmsg[i]); X println(""); X println(" Choose bug test number:"); X menuchoice = menu(menutable); X switch (menuchoice) { X case 1: bug_a(); break; X case 2: bug_b(); break; X case 3: bug_c(); break; X case 4: bug_d(); break; X case 5: bug_e(); break; X case 6: bug_f(); break; X case 7: bug_w(); break; X case 8: bug_l(); break; X case 9: bug_s(); break; X } X } while (menuchoice); X} X X/* Bug A: Smooth scroll to jump scroll */ X Xbug_a() { X int i; X X cup (10, 1); X println("This is a test of the VT100 'Scroll while toggle softscroll'"); X println("bug. The cursor may disappear, or move UP the screen, or"); X println("multiple copies of some lines may appear."); X holdit(); X X /* Invoke the bug */ X X esc ("[24H"); /* Simplified cursor movement */ X rm("?4"); for (i = 1; i <= 20; i++) printf("\n"); X sm("?4"); for (i = 1; i <= 10; i++) printf("\n"); X rm("?4"); for (i = 1; i <= 5; i++) printf("\n"); X X /* That should be enough to show the bug. But we'll try another way: */ X sm ("?4"); /* Set soft scroll */ X nel (); /* "NextLine", move down */ X rm ("?4"); /* Reset soft scroll */ X nel (); /* "NextLine", move down */ X for (i = 1; i <= 10; i++) { /* Show the bug */ X printf ("Softscroll bug test, line %d. ", i); X holdit(); X } X println("That should have been enough to show the bug, if present."); X holdit(); X} X X/* Bug B: Scrolling region */ X Xbug_b() { X char c; X X decaln(); X cup( 1,1); el(0); X printf("Line 11 should be double-wide, line 12 should be cleared."); X cup( 2,1); el(0); X printf("Then, the letters A-P should be written at the beginning"); X cup( 3,1); el(0); X printf("of lines 12-24, and the empty line and A-E are scrolled away."); X cup( 4,1); el(0); X printf("If the bug is present, some lines are confused, look at K-P."); X cup(11,1); decdwl(); X decstbm(12,24); X cup(12,1); el(0); printf("Here we go... "); holdit(); X cup(12,1); ri(); /* Bug comes here */ X for (c = 'A'; c <= 'P'; c++) printf("%c\n",c); /* Bug shows here */ X holdit(); X decstbm(0,0); /* No scr. region */ X} X X/* Bug C: Wide to narrow screen */ X Xbug_c() { X sm("?3"); /* 132 column mode */ X cup(1,81); X rm("?3"); /* 80 column mode */ X cup(12,5); X printf("Except for this line, the screen should be blank. "); X holdit(); X} X X/* Bug D: Narrow to wide screen */ X Xbug_d() { X int i; X char result; X /* Make the bug appear */ X do { X cup(14,1); X X /* The original code in the article says X * PRINT ESC$; "[13;1H"; CHR$(10%); X * but I guess a cup(14,1); would do. X * (To output a pure LF might be tricky). X */ X X sm("?3"); /* Make the bug visible */ X cup(1,9); decdwl(); X println("You should see blinking text at the bottom line."); X cup(3,9); decdwl(); X println("Enter 0 to exit, 1 to try to invoke the bug again."); X cup(24,9); decdwl(); sgr("1;5;7"); X printf("If you can see this then the bug did not appear."); sgr(""); X cup(4,9); decdwl(); X result = inchar(); readnl(); X rm("?3"); X } while (result == '1'); X sm("?4"); /* Syrup scroll */ X cup(23,1); X for (i = 1; i <= 5; i++) X println("If the bug is present, this should make things much worse!"); X holdit(); X rm("?4"); /* Jump scroll */ X} X X/* Bug E: Cursor move from double- to single-wide line */ X Xbug_e() { X int i; X static char *rend[2] = { "\033[m", "\033[7m" }; X sm("?3"); X cup(1,1); decdwl(); X println("This test should put an 'X' at line 3 column 100."); X for (i = 1; i <= 12; i++) printf("1234567890%s",rend[i & 1]); X cup(1,1); /* The bug appears when we jump from a dobule-wide line */ X cup(3,100); /* to a single-wide line, column > 66. */ X printf("X"); X cup(4, 66); printf("! !"); X cup(5,1); X printf("--------------------------- The 'X' should NOT be above here -"); X printf("---+------------ but above here -----+"); X cup(10,1); decdwl(); holdit(); X rm("?3"); X} X X/* Bug F: Column mode escape sequence */ X Xbug_f() { X int i, row, col; X X /* X * VT100 "toggle origin mode, forget rest" bug. If you try to set X * (or clear) parameters and one of them is the "origin mode" X * ("?6") parameter, parameters that appear after the "?6" X * remain unaffected. This is also true on CIT-101 terminals. X */ X sm ("?5"); /* Set reverse mode */ X sm ("?3"); /* Set 132 column mode */ X println("Test VT100 'Toggle origin mode, forget rest' bug, part 1."); X println("The screen should be in reverse, 132 column mode."); X holdit(); X ed (2); X rm ("?6;5;3"); /* Reset (origin, reverse, 132 col) */ X println("Test VT100 'Toggle origin mode, forget rest' bug, part 2.\n"); X println("The screen should be in non-reverse, 80 column mode."); X holdit(); X} X X /* Bug W: X * The dreaded "wraparound" bug! You CUP to col 80, write a char, X * CUP to another line in col 80, write a char. And the brain-damaged X * terminal thinks that "Hokay, so he's written a char in col 80, so X * I stay in col 80 and wait for next character. Let's see now, here X * comes another character, and I'm still in col 80, so I must make X * a NewLine first." -- It doesn't clear that "still in col 80" flag X * on a CUP. Argh! X */ X Xbug_w() { X int row, col; X X cup (16,1); X println(" This illustrates the \"wrap around bug\" which exists on a"); X println(" standard VT100. At the top of the screen there should be"); X println(" a row of +'s, and the rightmost column should be filled"); X println(" with *'s. But if the bug is present, some of the *'s may"); X println(" be placed in other places, e.g. in the leftmost column,"); X println(" and the top line of +'s may be scrolled away."); X X cup(1,1); X for (col = 1; col <= 79; col++) X printf ("+"); X for (row = 1; row <= 24; row++) { X hvp (row, 80); X printf ("*"); X } X cup(24,1); X holdit(); X} X X /* Bug L: X * Check if the right half of double-width lines comes back X * when a line is first set to single-width, filled with stuff, X * set to double-width, and finally reset to single-width. X * X * A VT100 has this misfeature, and many others. Foo! X */ X Xbug_l() { X cup(15, 1); X printf("This-is-a-long-line-This-is-a-long-line-"); X printf("This-is-a-long-line-This-is-a-long-line-"); X cup(1, 1); X printf("This is a test of what happens to the right half of double-width"); X println(" lines."); X printf("A common misfeature is that the right half does not come back"); X println(" when a long"); X printf("single-width line is set to double-width and then reset to"); X println(" single-width."); X X cup(5, 1); X println("Now the line below should contain 80 characters in single width."); X holdit(); X cup(15, 1); decdwl(); X cup(8, 1); X println("Now the line below should contain 40 characters in double width."); X holdit(); X cup(15, 1); decswl(); X cup(11, 1); X println("Now the line below should contain 80 characters in single width."); X holdit(); X X /* ...and in 132 column mode */ X X sm("?3"); X ed(2); X cup(15, 1); X printf("This-is-a-long-line-This-is-a-long-line-"); X printf("This-is-a-long-line-This-is-a-long-line-"); X printf("This-is-a-long-line-This-is-a-long-line-"); X printf("ending-here-"); X X cup(1, 1); X printf("This is the same test in 132 column mode."); X X cup(5, 1); X println("Now the line below should contain 132 characters in single width."); X holdit(); X cup(15, 1); decdwl(); X cup(8, 1); X println("Now the line below should contain 66 characters in double width."); X holdit(); X cup(15, 1); decswl(); X cup(11, 1); X println("Now the line below should contain 132 characters in single width."); X holdit(); X rm("?3"); X} X Xbug_s() { X int i; X decstbm(20,10); /* 20-10=-10, < 2, so no scroll region. */ X cup(1,1); X for (i=1; i<=20; i++) X printf("This is 20 lines of text (line %d), no scroll region.\n", i); X holdit(); X ed(2); X decstbm(0,1); /* Should be interpreted as decstbm(1,1) = none */ X cup(1,1); X for (i=1; i<=20; i++) X printf("This is 20 lines of text (line %d), no scroll region.\n", i); X holdit(); X decstbm(0,0); /* No scroll region (just in case...) */ X} X Xtst_rst() { X X /* X * Test of X * - RIS (Reset to Initial State) X * - DECTST (invoke terminal test) X */ X X cup(10,1); X printf ("The terminal will now be RESET. "); X holdit(); X ris(); X#ifdef UNIX X fflush(stdout); X#endif X zleep(5000); /* Wait 5.0 seconds */ X cup(10,1); X println("The terminal is now RESET. Next, the built-in confidence test"); X printf("%s", "will be invoked. "); X holdit(); X ed(2); X dectst(1); X#ifdef UNIX X fflush(stdout); X#endif X zleep(5000); /* Wait 5.0 seconds */ X cup(10,1); X println("If the built-in confidence test found any errors, a code"); X printf("%s", "is visible above. "); X holdit(); X} X Xinitterminal(pn) int pn; { X X#ifdef UNIX X if (pn==0) { X fflush(stdout); X gtty(0,&sgttyOrg); X gtty(0,&sgttyNew); X sgttyNew.sg_flags |= CBREAK; X } X else { X fflush(stdout); X inflush(); X sleep(2); X sgttyNew.sg_flags = sgttyOrg.sg_flags | CBREAK; X } X stty(0,&sgttyNew); X#ifdef SIII X close(2); X open("/dev/tty",O_RDWR|O_NDELAY); X#endif X#endif X#ifdef SARG10 X /* Set up neccesary TOPS-10 terminal parameters */ X X trmop(02041, `VT100`); /* tty type vt100 */ X trmop(02002, 0); /* tty no tape */ X trmop(02003, 0); /* tty lc */ X trmop(02005, 1); /* tty tab */ X trmop(02010, 1); /* tty no crlf */ X trmop(02020, 0); /* tty no tape */ X trmop(02021, 1); /* tty page */ X trmop(02025, 0); /* tty blanks */ X trmop(02026, 1); /* tty no alt */ X trmop(02040, 1); /* tty defer */ X#endif X#ifdef SARG20 X ttybin(1); /* set line to binary mode */ X#endif X /* Set up my personal prejudices */ X X esc("<"); /* Enter ANSI mode (if in VT52 mode) */ X rm("?1"); /* cursor keys normal */ X rm("?3"); /* 80 col mode */ X rm("?4"); /* Jump scroll */ X rm("?5"); /* Normal screen */ X rm("?6"); /* Absolute origin mode */ X sm("?7"); /* Wrap around on */ X rm("?8"); /* Auto repeat off */ X decstbm(0,0); /* No scroll region */ X sgr("0"); /* Normal character attributes */ X X} X Xbye () { X /* Force my personal prejudices upon the poor luser */ X X esc("<"); /* Enter ANSI mode (if in VT52 mode) */ X rm("?1"); /* cursor keys normal */ X rm("?3"); /* 80 col mode */ X rm("?5"); /* Normal screen */ X rm("?6"); /* Absolute origin mode */ X sm("?7"); /* Wrap around on */ X sm("?8"); /* Auto repeat on */ X decstbm(0,0); /* No scroll region */ X sgr("0"); /* Normal character attributes */ X X /* Say goodbye */ X X ed(2); X cup(12,30); X printf("That's all, folks!\n"); X printf("\n\n\n"); X inflush(); X#ifdef SARG20 X ttybin(0); /* reset line to normal mode */ X#endif X#ifdef UNIX X stty(0,&sgttyOrg); X#endif X exit(); X} X X#ifdef UNIX Xonbrk() { X signal(SIGINT, onbrk); X if (reading) X brkrd = 1; X else X longjmp(intrenv, 1); X} X Xonterm() { X signal(SIGTERM, onterm); X longjmp(intrenv, 1); X} X#endif X Xholdit() { X inflush(); X printf("Push <RETURN>"); X readnl(); X} X Xreadnl() { X#ifdef UNIX X char ch; X fflush(stdout); X brkrd = 0; X reading = 1; X do { read(0,&ch,1); } while(ch != '\n' && !brkrd); X if (brkrd) X kill(getpid(), SIGTERM); X reading = 0; X#endif X#ifdef SARG10 X while (getchar() != '\n') X ; X#endif X#ifdef SARG20 X while (getchar() != '\n') X ; X#endif X} X Xscanto(str, pos, toc) char *str; int *pos; char toc; { X char c; X int result = 0; X X while (toc != (c = str[(*pos)++])) { X if (isdigit(c)) result = result * 10 + c - '0'; X else break; X } X if (c == toc) return(result); X else return(0); X} X Xchar *lookup(t, k) struct table t[]; int k; { X X int i; X for (i = 0; t[i].key != -1; i++) { X if (t[i].key == k) return(t[i].msg); X } X return("BAD VALUE"); X} X Xmenu(table) char *table[]; { X X int i, tablesize, choice; X char c; X char storage[80]; X char *s = storage; X println(""); X tablesize = 0; X for (i = 0; *table[i] != '\0'; i++) { X printf(" %d. %s\n", i, table[i]); X tablesize++; X } X tablesize--; X X printf("\n Enter choice number (0 - %d): ", tablesize); X for(;;) { X inputline(s); X choice = 0; X while (c = *s++) choice = 10 * choice + c - '0'; X if (choice >= 0 && choice <= tablesize) { X ed(2); X return (choice); X } X printf(" Bad choice, try again: "); X } X} X Xchrprint (s) char *s; { X X int i; X X printf(" "); X sgr("7"); X printf(" "); X for (i = 0; s[i] != '\0'; i++) { X if (s[i] <= ' ' || s[i] == '\177') X printf("<%d> ", s[i]); X else printf("%c ", s[i]); X } X sgr(""); X} SHAR_EOF $TOUCH -am 0112125693 Support/vttest/main.c && chmod 0640 Support/vttest/main.c || echo "restore of Support/vttest/main.c failed" set `wc -c Support/vttest/main.c`;Wc_c=$1 if test "$Wc_c" != "57952"; then echo original size 57952, current size $Wc_c fi fi # ============= Support/vttest/vttest.1 ============== if test X"$1" != X"-c" -a -f 'Support/vttest/vttest.1'; then echo "File already exists: skipping 'Support/vttest/vttest.1'" else echo "x - extracting Support/vttest/vttest.1 (Text)" sed 's/^X//' << 'SHAR_EOF' > Support/vttest/vttest.1 && X.TH VTTEST 1 "LOCAL" X.SH NAME Xvttest \- test VT100-type terminal X.SH SYNOPSIS X.B vttest X.SH DESCRIPTION X.I Vttest Xis a program designed to test the functionality of a VT100 terminal X(or emulator thereof). XIt tests both display (escape sequence handling) and keyboard. X.PP XThe program is menu\-driven and contains full on\-line operating Xinstructions. SHAR_EOF $TOUCH -am 0112125693 Support/vttest/vttest.1 && chmod 0640 Support/vttest/vttest.1 || echo "restore of Support/vttest/vttest.1 failed" set `wc -c Support/vttest/vttest.1`;Wc_c=$1 if test "$Wc_c" != "351"; then echo original size 351, current size $Wc_c fi fi echo "End of part 4, continue with part 5" exit 0 -- hellmuth michaelis HCS Hanseatischer Computerservice GmbH hamburg, europe hm@hcshh.hcs.de tel: +49/40/55903-170 fax: +49/40/5591486