4 Written Novemeber 1983 - July 1984 by Per Lindberg,
5 Stockholm University Computer Center (QZ), Sweden.
7 THE MAD PROGRAMMER STRIKES AGAIN!
9 This software is (c) 1984 by QZ
10 Non-commercial use and copying allowed.
12 If you are developing a commercial product, and use this program to do
13 it, and that product is successful, please send a sum of money of your
14 choice to the address below.
18 /* $FreeBSD: src/usr.sbin/pcvt/vttest/main.c,v 1.4.6.1 2000/12/11 01:03:35 obrien Exp $ */
19 /* $DragonFly: src/usr.sbin/pcvt/vttest/Attic/main.c,v 1.3 2004/01/23 19:57:41 joerg Exp $ */
23 char inchar(), *instr(), *lookup();
63 return(ioctl(fd, TIOCSETP, ptr));
71 return(ioctl(fd, TIOCGETP, ptr));
80 static char *mainmenu[] = {
82 "Test of cursor movements",
83 "Test of screen features",
84 "Test of character sets",
85 "Test of double-sized characters",
87 "Test of terminal reports",
89 "Test of VT102 features (Insert/Delete Char/Line)",
91 "Test of reset and self-test",
96 initterminal(setjmp(intrenv));
97 signal(SIGINT, onbrk);
98 signal(SIGTERM, onterm);
105 ttybin(1); /* set line to binary mode again. It's reset somehow!! */
108 cup(5,10); printf("VT100 test program, version %s", VERSION);
109 cup(7,10); println("Choose test type:");
110 menuchoice = menu(mainmenu);
111 switch (menuchoice) {
112 case 1: tst_movements(); break;
113 case 2: tst_screen(); break;
114 case 3: tst_characters(); break;
115 case 4: tst_doublesize(); break;
116 case 5: tst_keyboard(); break;
117 case 6: tst_reports(); break;
118 case 7: tst_vt52(); break;
119 case 8: tst_insdel(); break;
120 case 9: tst_bugs(); break;
121 case 10: tst_rst(); break;
123 } while (menuchoice);
131 CUB (Cursor Backward)
132 CUD (Cursor Down) IND (Index) NEL (Next Line)
133 CUU (Cursor Up) RI (Reverse Index)
134 CUP (Cursor Position) HVP (Horizontal and Vertical Position)
135 ED (Erase in Display)
137 DECALN (Screen Alignment Display)
139 Cursor control characters inside CSI sequences
142 int i, row, col, pass, width, hlfxtra;
143 char c, *ctext = "This is a correct sentence";
145 for (pass = 0; pass <= 1; pass++) {
146 if (pass == 0) { rm("?3"); width = 80; hlfxtra = 0; }
147 else { sm("?3"); width = 132; hlfxtra = 26; }
150 cup( 9,10+hlfxtra); ed(1);
151 cup(18,60+hlfxtra); ed(0); el(1);
152 cup( 9,71+hlfxtra); el(0);
153 for (row = 10; row <= 16; row++) {
154 cup(row, 10+hlfxtra); el(1);
155 cup(row, 71+hlfxtra); el(0);
158 for (col = 1; col <= width; col++) {
159 hvp(24, col); printf("*");
160 hvp( 1, col); printf("*");
163 for (row = 2; row <= 23; row++) {
169 for (row = 23; row >=2; row--) {
174 for (row = 2; row <= 23; row++) {
185 cub(42+hlfxtra); cuf(2);
186 for (col = 3; col <= width-2; col++) {
188 cuf(0); cub(2); cuf(1);
191 cuf(42+hlfxtra); cub(2);
192 for (col = width-2; col >= 3; col--) {
194 cub(1); cuf(1); cub(0); printf("%c", 8);
196 cup( 1, 1); cuu(10); cuu(1); cuu(0);
197 cup(24,width); cud(10); cud(1); cud(0);
200 for (row = 10; row <= 15; row++) {
201 for (col = 12+hlfxtra; col <= 69+hlfxtra; col++) printf(" ");
205 printf("The screen should be cleared, and have an unbroken bor-");
207 printf("der of *'s and +'s around the edge, and exactly in the");
209 printf("middle there should be a frame of E's around this text");
211 printf("with one (1) free position around it. ");
218 println("Test of cursor-control characters inside ESC sequences.");
219 println("Below should be two identical lines:");
221 println("A B C D E F G H I J K L M N O P Q R S");
222 for (i = 1; i < 20; i++) {
223 printf("%c", 64 + i);
224 brcstr("2\010", 'C'); /* Two forward, one backspace */
232 println("Test of leading zeros in ESC sequences.");
233 printf("Two lines below you should see the sentence \"%s\".",ctext);
234 for (col = 1; *ctext; col++)
235 printf("\033[00000000004;00000000%dH%c",col,*ctext++);
243 - DECSTBM (Set Top and Bottom Margins)
244 - TBC (Tabulation Clear)
245 - HTS (Horizontal Tabulation Set)
246 - SM RM (Set/Reset mode): - 80/132 chars
247 - Origin: Realtive/absolute
248 - Scroll: Smooth/jump
250 - SGR (Select Graphic Rendition)
251 - SM RM (Set/Reset Mode) - Inverse
252 - DECSC (Save Cursor)
253 - DECRC (Restore Cursor)
256 int i, j, cset, row, col, down, soft, background;
258 static char *tststr = "*qx`";
259 static char *attr[5] = { ";0", ";1", ";4", ";5", ";7" };
262 sm("?7"); /* Wrap Around ON */
263 for (col = 1; col <= 160; col++) printf("*");
264 rm("?7"); /* Wrap Around OFF */
266 for (col = 1; col <= 160; col++) printf("*");
267 sm("?7"); /* Wrap Around ON */
269 println("This should be three identical lines of *'s completely filling");
270 println("the top of the screen without any empty lines between.");
271 println("(Test of WRAP AROUND mode setting.)");
277 for (col = 1; col <= 78; col += 3) {
281 for (col = 4; col <= 78; col += 6) {
284 cup(1,7); tbc(1); tbc(2); /* no-op */
285 cup(1,1); for (col = 1; col <= 78; col += 6) printf("\t*");
286 cup(2,2); for (col = 2; col <= 78; col += 6) printf(" *");
288 println("Test of TAB setting/resetting. These two lines");
289 printf("should look the same. ");
291 for (background = 0; background <= 1; background++) {
292 if (background) rm("?5");
294 sm("?3"); /* 132 cols */
295 ed(2); /* VT100 clears screen on SM3/RM3, but not obviously, so... */
297 for (col = 1; col <= 132; col += 8) {
300 cup(1,1); for (col = 1; col <= 130; col += 10) printf("1234567890");
302 for (row = 3; row <= 20; row++) {
304 printf("This is 132 column mode, %s background.",
305 background ? "dark" : "light");
308 rm("?3"); /* 80 cols */
309 ed(2); /* VT100 clears screen on SM3/RM3, but not obviously, so... */
310 cup(1,1); for (col = 1; col <= 80; col += 10) printf("1234567890");
311 for (row = 3; row <= 20; row++) {
313 printf("This is 80 column mode, %s background.",
314 background ? "dark" : "light");
320 sm("?6"); /* Origin mode (relative) */
321 for (soft = -1; soft <= 0; soft++) {
324 for (row = 12; row >= 1; row -= 11) {
325 decstbm(row, 24-row+1);
327 for (down = 0; down >= -1; down--) {
330 for (i = 1; i <= 30; i++) {
331 printf("%s scroll %s region %d Line %d\n",
332 soft ? "Soft" : "Jump",
333 down ? "down" : "up",
335 if (down) { ri(); ri(); }
344 "\nOrigin mode test. This line should be at the bottom of the screen.");
347 "This line should be the one above the bottom of the screeen. ");
350 rm("?6"); /* Origin mode (absolute) */
353 "Origin mode test. This line should be at the bottom of the screen.");
355 printf("%s", "This line should be at the top if the screen. ");
360 cup( 1,20); printf("Graphic rendition test pattern:");
361 cup( 4, 1); sgr("0"); printf("vanilla");
362 cup( 4,40); sgr("0;1"); printf("bold");
363 cup( 6, 6); sgr(";4"); printf("underline");
364 cup( 6,45);sgr(";1");sgr("4");printf("bold underline");
365 cup( 8, 1); sgr("0;5"); printf("blink");
366 cup( 8,40); sgr("0;5;1"); printf("bold blink");
367 cup(10, 6); sgr("0;4;5"); printf("underline blink");
368 cup(10,45); sgr("0;1;4;5"); printf("bold underline blink");
369 cup(12, 1); sgr("1;4;5;0;7"); printf("negative");
370 cup(12,40); sgr("0;1;7"); printf("bold negative");
371 cup(14, 6); sgr("0;4;7"); printf("underline negative");
372 cup(14,45); sgr("0;1;4;7"); printf("bold underline negative");
373 cup(16, 1); sgr("1;4;;5;7"); printf("blink negative");
374 cup(16,40); sgr("0;1;5;7"); printf("bold blink negative");
375 cup(18, 6); sgr("0;4;5;7"); printf("underline blink negative");
376 cup(18,45); sgr("0;1;4;5;7"); printf("bold underline blink negative");
379 rm("?5"); /* Inverse video off */
380 cup(23,1); el(0); printf("Dark background. "); holdit();
381 sm("?5"); /* Inverse video */
382 cup(23,1); el(0); printf("Light background. "); holdit();
385 cup(8,12); printf("normal");
386 cup(8,24); printf("bold");
387 cup(8,36); printf("underscored");
388 cup(8,48); printf("blinking");
389 cup(8,60); printf("reversed");
390 cup(10,1); printf("stars:");
391 cup(12,1); printf("line:");
392 cup(14,1); printf("x'es:");
393 cup(16,1); printf("diamonds:");
394 for (cset = 0; cset <= 3; cset++) {
395 for (i = 0; i <= 4; i++) {
396 cup(10 + 2 * cset, 12 + 12 * i);
398 if (cset == 0 || cset == 2) scs(0,'B');
400 for (j = 0; j <= 4; j++) {
401 printf("%c", tststr[cset]);
404 cup(cset + 1, i + 1); sgr(""); scs(0,'B'); printf("A");
406 for (j = 0; j <= 4; j++) {
407 printf("%c", tststr[cset]);
411 sgr("0"); scs(0,'B'); cup(21,1);
412 println("Test of the SAVE/RESTORE CURSOR feature. There should");
413 println("be ten characters of each flavour, and a rectangle");
414 println("of 5 x 4 A's filling the top left of the screen.");
420 SCS (Select character Set)
424 char chcode[5], *setmsg[5];
431 setmsg[0] = "UK / national";
432 setmsg[1] = "US ASCII";
433 setmsg[2] = "Special graphics and line drawing";
434 setmsg[3] = "Alternate character ROM standard characters";
435 setmsg[4] = "Alternate character ROM special graphics";
437 cup(1,10); printf("Selected as G0 (with SI)");
438 cup(1,48); printf("Selected as G1 (with SO)");
439 for (cset = 0; cset <= 4; cset++) {
441 cup(3 + 4 * cset, 1);
443 printf("Character set %c (%s)",chcode[cset], setmsg[cset]);
445 for (g = 0; g <= 1; g++) {
447 for (i = 1; i <= 3; i++) {
448 cup(3 + 4 * cset + i, 10 + 38 * g);
449 for (j = 0; j <= 31; j++) {
450 printf("%c", i * 32 + j);
456 cup(24,1); printf("These are the installed character sets. ");
462 DECSWL (Single Width Line)
463 DECDWL (Double Width Line)
464 DECDHL (Double Height Line) (also implicit double width)
469 /* Print the test pattern in both 80 and 132 character width */
471 for(w = 0; w <= 1; w++) {
476 if (w) { sm("?3"); printf("132 column mode"); }
477 else { rm("?3"); printf(" 80 column mode"); }
480 printf("v------- left margin");
483 printf("This is a normal-sized line");
484 decdhl(0); decdhl(1); decdwl(); decswl();
487 printf("This is a Double-width line");
488 decswl(); decdhl(0); decdhl(1); decdwl();
491 decdwl(); decswl(); decdhl(1); decdhl(0);
492 printf("This is a Double-width-and-height line");
494 decdwl(); decswl(); decdhl(0); decdhl(1);
495 printf("This is a Double-width-and-height line");
498 decdwl(); decswl(); decdhl(1); decdhl(0); el(2);
499 printf("This is another such line");
501 decdwl(); decswl(); decdhl(0); decdhl(1);
502 printf("This is another such line");
505 printf("^------- left margin");
508 printf("This is not a double-width line");
509 for (i = 0; i <= 1; i++) {
511 if (i) { printf("**is**"); decdwl(); }
512 else { printf("is not"); decswl(); }
516 /* Set vanilla tabs for next test */
517 cup(1,1); tbc(3); for (col = 1; col <= 132; col += 8) { cuf(8); hts(); }
522 cup( 8,1); decdhl(0); printf("lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk");
523 cup( 9,1); decdhl(1); printf("lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk");
524 cup(10,1); decdhl(0); printf("x%c%c%c%c%cx",9,9,9,9,9);
525 cup(11,1); decdhl(1); printf("x%c%c%c%c%cx",9,9,9,9,9);
526 cup(12,1); decdhl(0); printf("x%c%c%c%c%cx",9,9,9,9,9);
527 cup(13,1); decdhl(1); printf("x%c%c%c%c%cx",9,9,9,9,9);
528 cup(14,1); decdhl(0); printf("x x");
529 cup(15,1); decdhl(1); printf("x x");
530 cup(16,1); decdhl(0); printf("mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj");
531 cup(17,1); decdhl(1); printf("mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj");
532 scs(0,'B'); sgr("1;5");
534 printf("* The mad programmer strikes again * ");
535 cup(13,3); printf("%c",9); cub(6);
536 printf("* The mad programmer strikes again *");
539 println("Another test pattern... a frame with blinking bold text,");
540 printf("all in double-height double-width size. ");
543 decstbm(8,24); /* Absolute origin mode, so cursor is set at (1,1) */
545 for (i = 1; i <= 12; i++)
547 decstbm(0,0); /* No scroll region */
549 printf("%s", "Exactly half of the box should remain. ");
557 - Keyboard return messages
558 - SM RM (Set/Reset Mode) - Cursor Keys
560 - DECKPAM (Keypad Application Mode)
561 - DECKPNM (Keypad Numeric Mode)
563 The standard VT100 keayboard layout:
567 ESC 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ `~ BS
569 TAB* qQ wW eE rR tT yY uU iI oO pP [{ ]} DEL
571 ** ** aA sS dD fF gG hH jJ kK lL ;: ," RETN \|
573 ** **** zZ xX cC vV bB nN mM ,< .> /? **** LF
575 ****************SPACE BAR****************
588 char *ledmsg[6], *ledseq[6];
596 char *curkeystr, *fnkeystr, *abmstr;
597 char arptstring[500];
606 { '1', 1, 6, "1" }, { '!', 1, 7, "!" },
607 { '2', 1, 11, "2" }, { '@', 1, 12, "@" },
608 { '3', 1, 16, "3" }, { '#', 1, 17, "#" },
609 { '4', 1, 21, "4" }, { '$', 1, 22, "$" },
610 { '5', 1, 26, "5" }, { '%', 1, 27, "%" },
611 { '6', 1, 31, "6" }, { '^', 1, 32, "^" },
612 { '7', 1, 36, "7" }, { '&', 1, 37, "&" },
613 { '8', 1, 41, "8" }, { '*', 1, 42, "*" },
614 { '9', 1, 46, "9" }, { '(', 1, 47, "(" },
615 { '0', 1, 51, "0" }, { ')', 1, 52, ")" },
616 { '-', 1, 56, "-" }, { '_', 1, 57, "_" },
617 { '=', 1, 61, "=" }, { '+', 1, 62, "+" },
618 { '`', 1, 66, "`" }, { '~', 1, 67, "~" },
620 { 9, 2, 0, " TAB " },
621 { 'q', 2, 8, "q" }, { 'Q', 2, 9, "Q" },
622 { 'w', 2, 13, "w" }, { 'W', 2, 14, "W" },
623 { 'e', 2, 18, "e" }, { 'E', 2, 19, "E" },
624 { 'r', 2, 23, "r" }, { 'R', 2, 24, "R" },
625 { 't', 2, 28, "t" }, { 'T', 2, 29, "T" },
626 { 'y', 2, 33, "y" }, { 'Y', 2, 34, "Y" },
627 { 'u', 2, 38, "u" }, { 'U', 2, 39, "U" },
628 { 'i', 2, 43, "i" }, { 'I', 2, 44, "I" },
629 { 'o', 2, 48, "o" }, { 'O', 2, 49, "O" },
630 { 'p', 2, 53, "p" }, { 'P', 2, 54, "P" },
631 { '[', 2, 58, "[" }, { '{', 2, 59, "{" },
632 { ']', 2, 63, "]" }, { '}', 2, 64, "}" },
633 { 127, 2, 71, "DEL" },
634 { 'a', 3, 10, "a" }, { 'A', 3, 11, "A" },
635 { 's', 3, 15, "s" }, { 'S', 3, 16, "S" },
636 { 'd', 3, 20, "d" }, { 'D', 3, 21, "D" },
637 { 'f', 3, 25, "f" }, { 'F', 3, 26, "F" },
638 { 'g', 3, 30, "g" }, { 'G', 3, 31, "G" },
639 { 'h', 3, 35, "h" }, { 'H', 3, 36, "H" },
640 { 'j', 3, 40, "j" }, { 'J', 3, 41, "J" },
641 { 'k', 3, 45, "k" }, { 'K', 3, 46, "K" },
642 { 'l', 3, 50, "l" }, { 'L', 3, 51, "L" },
643 { ';', 3, 55, ";" }, { ':', 3, 56, ":" },
644 {'\'', 3, 60, "'" }, { '"', 3, 61,"\"" },
645 { 13, 3, 65, "RETN"},
646 {'\\', 3, 71,"\\" }, { '|', 3, 72, "|" },
647 { 'z', 4, 12, "z" }, { 'Z', 4, 13, "Z" },
648 { 'x', 4, 17, "x" }, { 'X', 4, 18, "X" },
649 { 'c', 4, 22, "c" }, { 'C', 4, 23, "C" },
650 { 'v', 4, 27, "v" }, { 'V', 4, 28, "V" },
651 { 'b', 4, 32, "b" }, { 'B', 4, 33, "B" },
652 { 'n', 4, 37, "n" }, { 'N', 4, 38, "N" },
653 { 'm', 4, 42, "m" }, { 'M', 4, 43, "M" },
654 { ',', 4, 47, "," }, { '<', 4, 48, "<" },
655 { '.', 4, 52, "." }, { '>', 4, 53, ">" },
656 { '/', 4, 57, "/" }, { '?', 4, 58, "?" },
658 { ' ', 5, 13, " SPACE BAR "},
662 static struct natkey {
667 } natkeytab [][29] = {
675 { '+', 1, 56, "+" }, { '?', 1, 57, "?" },
676 { '`', 1, 61, "`" }, { '@', 1, 62, "@" },
677 { '<', 1, 66, "<" }, { '>', 1, 67, ">" },
678 { '}', 2, 58, "}" }, { ']', 2, 59, "]" },
679 { '^', 2, 63, "^" }, { '~', 2, 64, "~" },
680 { '|', 3, 55, "|" }, {'\\', 3, 56,"\\" },
681 { '{', 3, 60, "{" }, { '[', 3, 61, "[" },
682 {'\'', 3, 71, "'" }, { '*', 3, 72, "*" },
683 { ',', 4, 47, "," }, { ';', 4, 48, ";" },
684 { '.', 4, 52, "." }, { ':', 4, 53, ":" },
685 { '-', 4, 57, "-" }, { '_', 4, 58, "_" },
695 { '+', 1, 56, "+" }, { '?', 1, 57, "?" },
696 { '`', 1, 61, "`" }, { '@', 1, 62, "@" },
697 { '<', 1, 66, "<" }, { '>', 1, 67, ">" },
698 { '}', 2, 58, "}" }, { ']', 2, 59, "]" },
699 { '~', 2, 63, "~" }, { '^', 2, 64, "^" },
700 { '|', 3, 55, "|" }, {'\\', 3, 56,"\\" },
701 { '{', 3, 60, "{" }, { '[', 3, 61, "[" },
702 {'\'', 3, 71, "'" }, { '*', 3, 72, "*" },
703 { ',', 4, 47, "," }, { ';', 4, 48, ";" },
704 { '.', 4, 52, "." }, { ':', 4, 53, ":" },
705 { '-', 4, 57, "-" }, { '_', 4, 58, "_" },
710 static struct curkey {
718 /* A Reset, A Set, VT52 */
720 {{"\033[A","\033OA","\033A"}, 0, 56, "UP", "Up arrow" },
721 {{"\033[B","\033OB","\033B"}, 0, 61, "DN", "Down arrow" },
722 {{"\033[D","\033OD","\033D"}, 0, 66, "LT", "Left arrow" },
723 {{"\033[C","\033OC","\033C"}, 0, 71, "RT", "Right arrow"},
724 {{"", "", "" }, 0, 0, "", "" }
727 static struct fnkey {
735 /* ANSI-num,ANSI-app,VT52-nu,VT52-ap, r, c, symb name */
737 {{"\033OP","\033OP","\033P","\033P" }, 6, 59, "PF1", "PF1" },
738 {{"\033OQ","\033OQ","\033Q","\033Q" }, 6, 63, "PF2", "PF2" },
739 {{"\033OR","\033OR","\033R","\033R" }, 6, 67, "PF3", "PF3" },
740 {{"\033OS","\033OS","\033S","\033S" }, 6, 71, "PF4", "PF4" },
741 {{"7", "\033Ow","7", "\033?w"}, 7, 59, " 7 ", "Numeric 7" },
742 {{"8", "\033Ox","8", "\033?x"}, 7, 63, " 8 ", "Numeric 8" },
743 {{"9", "\033Oy","9", "\033?y"}, 7, 67, " 9 ", "Numeric 9" },
744 {{"-", "\033Om","-", "\033?m"}, 7, 71, " - ", "Minus" },
745 {{"4", "\033Ot","4", "\033?t"}, 8, 59, " 4 ", "Numeric 4" },
746 {{"5", "\033Ou","5", "\033?u"}, 8, 63, " 5 ", "Numeric 5" },
747 {{"6", "\033Ov","6", "\033?v"}, 8, 67, " 6 ", "Numeric 6" },
748 {{",", "\033Ol",",", "\033?l"}, 8, 71, " , ", "Comma" },
749 {{"1", "\033Oq","1", "\033?q"}, 9, 59, " 1 ", "Numeric 1" },
750 {{"2", "\033Or","2", "\033?r"}, 9, 63, " 2 ", "Numeric 2" },
751 {{"3", "\033Os","3", "\033?s"}, 9, 67, " 3 ", "Numeric 3" },
752 {{"0", "\033Op","0", "\033?p"},10, 59," O ","Numeric 0"},
753 {{".", "\033On",".", "\033?n"},10, 67, " . ", "Point" },
754 {{"\015", "\033OM","\015", "\033?M"},10, 71, "ENT", "ENTER" },
755 {{"","","",""}, 0, 0, "", "" }
762 { 0, "NUL (CTRL-@ or CTRL-Space)" },
763 { 0, "SOH (CTRL-A)" },
764 { 0, "STX (CTRL-B)" },
765 { 0, "ETX (CTRL-C)" },
766 { 0, "EOT (CTRL-D)" },
767 { 0, "ENQ (CTRL-E)" },
768 { 0, "ACK (CTRL-F)" },
769 { 0, "BEL (CTRL-G)" },
770 { 0, "BS (CTRL-H) (BACK SPACE)" },
771 { 0, "HT (CTRL-I) (TAB)" },
772 { 0, "LF (CTRL-J) (LINE FEED)" },
773 { 0, "VT (CTRL-K)" },
774 { 0, "FF (CTRL-L)" },
775 { 0, "CR (CTRL-M) (RETURN)" },
776 { 0, "SO (CTRL-N)" },
777 { 0, "SI (CTRL-O)" },
778 { 0, "DLE (CTRL-P)" },
779 { 0, "DC1 (CTRL-Q) (X-On)" },
780 { 0, "DC2 (CTRL-R)" },
781 { 0, "DC3 (CTRL-S) (X-Off)" },
782 { 0, "DC4 (CTRL-T)" },
783 { 0, "NAK (CTRL-U)" },
784 { 0, "SYN (CTRL-V)" },
785 { 0, "ETB (CTRL-W)" },
786 { 0, "CAN (CTRL-X)" },
787 { 0, "EM (CTRL-Y)" },
788 { 0, "SUB (CTRL-Z)" },
789 { 0, "ESC (CTRL-[) (ESCAPE)" },
790 { 0, "FS (CTRL-\\ or CTRL-? or CTRL-_)" },
791 { 0, "GS (CTRL-])" },
792 { 0, "RS (CTRL-^ or CTRL-~ or CTRL-`)" },
793 { 0, "US (CTRL-_ or CTRL-?)" }
796 static char *keyboardmenu[] = {
797 "Standard American ASCII layout",
798 "Swedish national layout D47",
799 "Swedish national layout E47",
800 /* add new keyboard layouts here */
804 static char *curkeymodes[3] = {
805 "ANSI / Cursor key mode RESET",
806 "ANSI / Cursor key mode SET",
810 static char *fnkeymodes[4] = {
812 "ANSI Application mode",
814 "VT52 Application mode"
817 ledmsg[0] = "L1 L2 L3 L4"; ledseq[0] = "1;2;3;4";
818 ledmsg[1] = " L2 L3 L4"; ledseq[1] = "1;0;4;3;2";
819 ledmsg[2] = " L2 L3"; ledseq[2] = "1;4;;2;3";
820 ledmsg[3] = "L1 L2"; ledseq[3] = ";;2;1";
821 ledmsg[4] = "L1"; ledseq[4] = "1";
822 ledmsg[5] = ""; ledseq[5] = "";
829 println("These LEDs (\"lamps\") on the keyboard should be on:");
830 for (i = 0; i <= 5; i++) {
831 cup(10,52); el(0); printf("%s", ledmsg[i]);
839 println("Test of the AUTO REPEAT feature");
841 println("Hold down an alphanumeric key for a while, then push RETURN.");
842 printf("%s", "Auto Repeat OFF: ");
844 inputline(arptstring);
845 if (strlen(arptstring) == 0) println("No characters read!??");
846 else if (strlen(arptstring) == 1) println("OK.");
847 else println("Too many characters read.");
849 println("Hold down an alphanumeric key for a while, then push RETURN.");
850 printf("%s", "Auto Repeat ON: ");
852 inputline(arptstring);
853 if (strlen(arptstring) == 0) println("No characters read!??");
854 else if (strlen(arptstring) == 1) println("Not enough characters read.");
861 println("Choose keyboard layout:");
862 kblayout = menu(keyboardmenu);
865 for (j = 0; natkeytab[kblayout][j].natc != '\0'; j++) {
866 for (i = 0; keytab[i].c != '\0'; i++) {
867 if (keytab[i].row == natkeytab[kblayout][j].natrow &&
868 keytab[i].col == natkeytab[kblayout][j].natcol) {
869 keytab[i].c = natkeytab[kblayout][j].natc;
870 keytab[i].symbol = natkeytab[kblayout][j].natsymbol;
878 for (i = 0; keytab[i].c != '\0'; i++) {
879 cup(1 + 2 * keytab[i].row, 1 + keytab[i].col);
881 printf("%s", keytab[i].symbol);
886 sgttyNew.sg_flags &= ~CRMOD;
887 sgttyNew.sg_flags &= ~ECHO;
891 printf("Press each key, both shifted and unshifted. Finish with RETURN:");
892 do { /* while (kbdc != 13) */
893 cup(23,1); kbdc = inchar();
895 sprintf(kbds, "%c", kbdc);
897 for (i = 0; keytab[i].c != '\0'; i++) {
898 if (keytab[i].c == kbdc) {
899 cup(1 + 2 * keytab[i].row, 1 + keytab[i].col);
900 printf("%s", keytab[i].symbol);
904 } while (kbdc != 13);
906 inchar(); /* Local hack: Read LF that TOPS-10 adds to CR */
910 for (ckeymode = 0; ckeymode <= 2; ckeymode++) {
911 if (ckeymode) sm("?1");
913 for (i = 0; curkeytab[i].curkeysymbol[0] != '\0'; i++) {
914 cup(1 + 2 * curkeytab[i].curkeyrow, 1 + curkeytab[i].curkeycol);
916 printf("%s", curkeytab[i].curkeysymbol);
919 cup(20,1); printf("<%s>%20s", curkeymodes[ckeymode], "");
921 cup(22,1); printf("%s", "Press each cursor key. Finish with TAB.");
924 if (ckeymode == 2) rm("?2"); /* VT52 mode */
926 esc("<"); /* ANSI mode */
928 cup(23,1); chrprint(curkeystr);
929 if (!strcmp(curkeystr,"\t")) break;
930 for (i = 0; curkeytab[i].curkeysymbol[0] != '\0'; i++) {
931 if (!strcmp(curkeystr,curkeytab[i].curkeymsg[ckeymode])) {
933 printf(" (%s key) ", curkeytab[i].curkeyname);
935 cup(1 + 2 * curkeytab[i].curkeyrow,
936 1 + curkeytab[i].curkeycol);
937 printf("%s", curkeytab[i].curkeysymbol);
941 if (i == sizeof(curkeytab) / sizeof(struct curkey) - 1) {
943 printf("%s", " (Unknown cursor key) ");
949 for (fkeymode = 0; fkeymode <= 3; fkeymode++) {
950 for (i = 0; fnkeytab[i].fnkeysymbol[0] != '\0'; i++) {
951 cup(1 + 2 * fnkeytab[i].fnkeyrow, 1 + fnkeytab[i].fnkeycol);
953 printf("%s", fnkeytab[i].fnkeysymbol);
956 cup(20,1); printf("<%s>%20s", fnkeymodes[fkeymode], "");
958 cup(22,1); printf("%s", "Press each function key. Finish with TAB.");
961 if (fkeymode >= 2) rm("?2"); /* VT52 mode */
962 if (fkeymode % 2) deckpam(); /* Application mode */
963 else deckpnm(); /* Numeric mode */
965 esc("<"); /* ANSI mode */
967 cup(23,1); chrprint(fnkeystr);
968 if (!strcmp(fnkeystr,"\t")) break;
969 for (i = 0; fnkeytab[i].fnkeysymbol[0] != '\0'; i++) {
970 if (!strcmp(fnkeystr,fnkeytab[i].fnkeymsg[fkeymode])) {
972 printf(" (%s key) ", fnkeytab[i].fnkeyname);
974 cup(1 + 2 * fnkeytab[i].fnkeyrow, 1 + fnkeytab[i].fnkeycol);
975 printf("%s", fnkeytab[i].fnkeysymbol);
979 if (i == sizeof(fnkeytab) / sizeof(struct fnkey) - 1) {
981 printf("%s", " (Unknown function key) ");
988 sgttyNew.sg_flags |= CRMOD;
993 println("Finally, a check of the ANSWERBACK MESSAGE, which can be sent");
994 println("by pressing CTRL-BREAK. The answerback message can be loaded");
995 println("in SET-UP B by pressing SHIFT-A and typing e.g.");
997 println(" \" H e l l o , w o r l d Return \"");
999 println("(the double-quote characters included). Do that, and then try");
1000 println("to send an answerback message with CTRL-BREAK. If it works,");
1001 println("the answerback message should be displayed in reverse mode.");
1002 println("Finish with a single RETURN.");
1005 sgttyNew.sg_flags &= ~CRMOD;
1015 } while (strcmp(abmstr,"\r"));
1018 for (i = 0; i < 32; i++) {
1019 cup(1 + (i % 16), 1 + 40 * (i / 16));
1021 printf("%s", ckeytab[i].csymbol);
1026 sgttyNew.sg_flags |= CRMOD;
1030 "Push each CTRL-key TWICE. Note that you should be able to send *all*");
1032 "CTRL-codes twice, including CTRL-S (X-Off) and CTRL-Q (X-Off)!");
1034 "Finish with DEL (also called DELETE or RUB OUT), or wait 1 minute.");
1037 sgttyNew.sg_flags &= ~CBREAK;
1040 sgttyNew.sg_flags |= RAW;
1045 page(0); /* Turn off all character processing at input */
1046 superbin(1); /* Turn off ^C (among others). Keep your fingers crossed!! */
1049 cup(23,1); kbdc = inchar();
1051 if (kbdc < 32) printf(" %s", ckeytab[kbdc].csymbol);
1053 sprintf(kbds, "%c", kbdc);
1055 printf("%s", " -- not a CTRL key");
1057 if (kbdc < 32) ckeytab[kbdc].ccount++;
1058 if (ckeytab[kbdc].ccount == 2) {
1059 cup(1 + (kbdc % 16), 1 + 40 * (kbdc / 16));
1060 printf("%s", ckeytab[kbdc].csymbol);
1062 } while (kbdc != '\177');
1064 sgttyNew.sg_flags &= ~RAW;
1065 sgttyNew.sg_flags |= ECHO;
1068 sgttyNew.sg_flags |= CBREAK;
1074 superbin(0); /* Puuuh! We made it!? */
1075 page(1); /* Back to normal input processing */
1076 ttybin(1); /* This must be the mode for DEC20 */
1080 for (i = 0; i < 32; i++) if (ckeytab[i].ccount < 2) okflag = 0;
1081 if (okflag) printf("%s", "OK. ");
1082 else printf("%s", "You have not been able to send all CTRL keys! ");
1088 <ENQ> (AnswerBack Message)
1089 SM RM (Set/Reset Mode) - LineFeed / Newline
1090 DSR (Device Status Report)
1091 DA (Device Attributes)
1092 DECREQTPARM (Request Terminal Parameters)
1095 int parity, nbits, xspeed, rspeed, clkmul, flags;
1097 char *report, *report2;
1098 static char *attributes[][2] = {
1099 { "\033[?1;0c", "No options (vanilla VT100)" },
1100 { "\033[?1;1c", "VT100 with STP" },
1101 { "\033[?1;2c", "VT100 with AVO (could be a VT102)" },
1102 { "\033[?1;3c", "VT100 with STP and AVO" },
1103 { "\033[?1;4c", "VT100 with GPO" },
1104 { "\033[?1;5c", "VT100 with STP and GPO" },
1105 { "\033[?1;6c", "VT100 with AVO and GPO" },
1106 { "\033[?1;7c", "VT100 with STP, AVO and GPO" },
1107 { "\033[?1;11c", "VT100 with PP and AVO" },
1108 { "\033[?1;15c", "VT100 with PP, GPO and AVO" },
1109 { "\033[?4;2c", "VT132 with AVO" },
1110 { "\033[?4;3c", "VT132 with AVO and STP" },
1111 { "\033[?4;6c", "VT132 with GPO and AVO" },
1112 { "\033[?4;7c", "VT132 with GPO, AVO, and STP" },
1113 { "\033[?4;11c", "VT132 with PP and AVO" },
1114 { "\033[?4;15c", "VT132 with PP, GPO and AVO" },
1115 { "\033[?7c", "VT131" },
1116 { "\033[?12;5c", "VT125" }, /* VT125 also has ROM version */
1117 { "\033[?12;7c", "VT125 with AVO" }, /* number, so this won't work */
1118 { "\033[?5;0c", "VK100 (GIGI)" },
1119 { "\033[?5c", "VK100 (GIGI)" },
1124 sgttyNew.sg_flags &= ~ECHO;
1128 println("This is a test of the ANSWERBACK MESSAGE. (To load the A.B.M.");
1129 println("see the TEST KEYBOARD part of this program). Below here, the");
1130 println("current answerback message in your terminal should be");
1131 println("displayed. Finish this test with RETURN.");
1134 printf("%c", 5); /* ENQ */
1143 println("Test of LineFeed/NewLine mode.");
1147 sgttyNew.sg_flags &= ~CRMOD;
1150 printf("NewLine mode set. Push the RETURN key: ");
1155 if (!strcmp(report, "\015\012")) printf(" -- OK");
1156 else printf(" -- Not expected");
1159 printf("NewLine mode reset. Push the RETURN key: ");
1164 if (!strcmp(report, "\015")) printf(" -- OK");
1165 else printf(" -- Not expected");
1168 sgttyNew.sg_flags |= CRMOD;
1175 printf("Test of Device Status Report 5 (report terminal status).");
1181 printf("Report is: ");
1183 if (!strcmp(report,"\033[0n")) printf(" -- means \"TERMINAL OK\"");
1184 else if (!strcmp(report,"\033[3n")) printf(" -- means \"TERMINAL OK\"");
1185 else printf(" -- Unknown response!");
1188 println("Test of Device Status Report 6 (report cursor position).");
1194 printf("Report is: ");
1196 if (!strcmp(report,"\033[5;1R")) printf(" -- OK");
1197 else printf(" -- Unknown response!");
1200 println("Test of Device Attributes report (what are you)");
1206 printf("Report is: ");
1208 for (i = 0; *attributes[i][0] != '\0'; i++) {
1209 if (!strcmp(report,attributes[i][0])) break;
1211 if (*attributes[i][0] == '\0')
1212 printf(" -- Unknown response, refer to the manual");
1214 printf(" -- means %s", attributes[i][1]);
1217 println("Legend: STP = Processor Option");
1218 println(" AVO = Advanced Video Option");
1219 println(" GPO = Graphics Processor Option");
1220 println(" PP = Printer Port");
1225 println("Test of the \"Request Terminal Parameters\" feature, argument 0.");
1231 printf("Report is: ");
1233 if (strlen(report) < 16
1234 || report[0] != '\033'
1237 || report[3] != ';')
1238 println(" -- Bad format");
1241 parity = scanto(report, &reportpos, ';');
1242 nbits = scanto(report, &reportpos, ';');
1243 xspeed = scanto(report, &reportpos, ';');
1244 rspeed = scanto(report, &reportpos, ';');
1245 clkmul = scanto(report, &reportpos, ';');
1246 flags = scanto(report, &reportpos, 'x');
1247 if (parity == 0 || nbits == 0 || clkmul == 0) println(" -- Bad format");
1248 else println(" -- OK");
1250 "This means: Parity %s, %s bits, xmitspeed %s, recvspeed %s.\n",
1251 lookup(paritytable, parity),
1252 lookup(nbitstable, nbits),
1253 lookup(speedtable, xspeed),
1254 lookup(speedtable, rspeed));
1255 printf("(CLoCk MULtiplier = %d, STP option flags = %d)\n", clkmul, flags);
1259 println("Test of the \"Request Terminal Parameters\" feature, argument 1.");
1261 decreqtparm(1); /* Does the same as decreqtparm(0), reports "3" */
1265 printf("Report is: ");
1267 if (strlen(report2) < 3
1268 || report2[2] != '3')
1269 println(" -- Bad format");
1272 if (!strcmp(report,report2)) println(" -- OK");
1273 else println(" -- Bad format");
1278 sgttyNew.sg_flags |= ECHO;
1285 static struct rtabl {
1289 { "\033/K", " -- OK (means Standard VT52)" },
1290 { "\033/Z", " -- OK (means VT100 emulating VT52)" },
1291 { "", " -- Unknown response"}
1297 rm("?2"); /* Reset ANSI (VT100) mode, Set VT52 mode */
1298 esc("H"); /* Cursor home */
1299 esc("J"); /* Erase to end of screen */
1300 esc("H"); /* Cursor home */
1301 for (i = 0; i <= 23; i++) {
1302 for (j = 0; j <= 9; j++)
1303 printf("%s", "FooBar ");
1306 esc("H"); /* Cursor home */
1307 esc("J"); /* Erase to end of screen */
1310 printf("nothing more.");
1311 for (i = 1; i <= 10; i++) printf("THIS SHOULD GO AWAY! ");
1312 for (i = 1; i <= 5; i++) {
1314 printf("%s", "Back scroll (this should go away)");
1315 esc("I"); /* Reverse LineFeed (with backscroll!) */
1318 esc("J"); /* Erase to end of screen */
1319 for (i = 2; i <= 6; i++) {
1321 esc("K"); /* Erase to end of line */
1324 for (i = 2; i <= 23; i++) {
1325 vt52cup(i,70); printf("%s", "**Foobar");
1328 for (i = 23; i >= 2; i--) {
1330 printf("%c", 8); /* BS */
1331 esc("I"); /* Reverse LineFeed (LineStarve) */
1334 for (i = 70; i >= 10; i--) {
1336 esc("D"); esc("D"); /* Cursor Left */
1339 for (i = 10; i <= 70; i++) {
1341 printf("%c", 8); /* BS */
1342 esc("C"); /* Cursor Right */
1345 for (i = 2; i <= 23; i++) {
1347 printf("%c", 8); /* BS */
1348 esc("B"); /* Cursor Down */
1351 for (i = 23; i >= 2; i--) {
1353 printf("%c", 8); /* BS */
1354 esc("A"); /* Cursor Up */
1356 for (i = 2; i <= 23; i++) {
1358 esc("K"); /* Erase to end of line */
1362 printf("%s", "The screen should be cleared, and have a centered");
1364 printf("%s", "rectangle of \"*\"s with \"!\"s on the inside to the");
1366 printf("%s", "left and right. Only this, and");
1370 esc("H"); /* Cursor home */
1371 esc("J"); /* Erase to end of screen */
1372 printf("%s", "This is the normal character set:");
1373 for (j = 0; j <= 1; j++) {
1375 for (i = 0; i <= 47; i++)
1376 printf("%c", 32 + i + 48 * j);
1379 printf("%s", "This is the special graphics character set:");
1380 esc("F"); /* Select Special Graphics character set */
1381 for (j = 0; j <= 1; j++) {
1383 for (i = 0; i <= 47; i++)
1384 printf("%c", 32 + i + 48 * j);
1386 esc("G"); /* Select ASCII character set */
1390 esc("H"); /* Cursor home */
1391 esc("J"); /* Erase to end of screen */
1392 println("Test of terminal response to IDENTIFY command");
1393 esc("Z"); /* Identify */
1396 printf("Response was");
1397 esc("<"); /* Enter ANSI mode (VT100 mode) */
1399 for(i = 0; resptable[i].rcode[0] != '\0'; i++)
1400 if (!strcmp(response, resptable[i].rcode))
1402 printf("%s", resptable[i].rmsg);
1411 SM/RM(4) (= IRM (Insertion/replacement mode))
1412 ICH (Insert Character)
1413 DCH (Delete character)
1418 int i, row, col, sw, dblchr, scr132;
1420 for(scr132 = 0; scr132 <= 1; scr132++) {
1421 if (scr132) { sm("?3"); sw = 132; }
1422 else { rm("?3"); sw = 80; }
1425 for (row=1; row<=24; row++) {
1427 for (col=1; col<=sw; col++)
1428 printf("%c", 'A'-1+row);
1431 printf("Screen accordion test (Insert & Delete Line). "); holdit();
1436 for (row=1; row<=24; row++) {
1444 "Top line: A's, bottom line: X's, this line, nothing more. ");
1451 for (col=2; col<=sw-1; col++)
1455 printf("Test of 'Insert Mode'. The top line should be 'A*** ... ***B'. ");
1456 holdit(); ri(); el(2);
1460 printf("Test of 'Delete Character'. The top line should be 'AB'. ");
1463 for(dblchr = 1; dblchr <= 2; dblchr++) {
1465 for (row=1; row<=24; row++) {
1467 if (dblchr == 2) decdwl();
1468 for (col=1; col<=sw/dblchr; col++)
1469 printf("%c", 'A'-1+row);
1470 cup(row,sw/dblchr-row);
1474 println("The right column should be staggered ");
1480 println("If your terminal has the ANSI 'Insert Character' function");
1481 println("(the VT102 does not), then you should see a line like this");
1482 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");
1485 for (i = 'Z'; i >= 'A'; i--) {
1492 if (sw == 132) rm("?3");
1496 dch(pn) int pn; { brc(pn, 'P'); } /* Delete character */
1497 ich(pn) int pn; { brc(pn, '@'); } /* Insert character -- not in VT102 */
1498 dl(pn) int pn; { brc(pn, 'M'); } /* Delete line */
1499 il(pn) int pn; { brc(pn, 'L'); } /* Insert line */
1501 /* Test of some known VT100 bugs and misfeatures */
1507 static char *menutable[] = {
1508 "Exit to main menu",
1509 "Bug A: Smooth scroll to jump scroll",
1510 "Bug B: Scrolling region",
1511 "Bug C: Wide to narrow screen",
1512 "Bug D: Narrow to wide screen",
1513 "Bug E: Cursor move from double- to single-wide line",
1514 "Bug F: Column mode escape sequence",
1515 "Wrap around with cursor addressing",
1516 "Erase right half of double width lines",
1517 "Funny scroll regions",
1522 static char *hmsg[] = {
1523 "Test of known bugs in the DEC VT100 series. The numbering of some of",
1524 "the bugs (A-F) refers to the article 'VT100 MAGIC' by Sami Tabih in",
1525 "the 'Proceedings of the DEC Users Society' at St. Louis, Missouri, May",
1526 "1983. To understand some of the tests, you have to look at the source",
1527 "code or the article. Of course, a good VT100-compatible terminal",
1528 "should not have these bugs (or have some means of disabling them)! If",
1529 "a bug appears, you might want to RESET the terminal before continuing",
1530 "the test. There is a test of the RESET function in the main menu.",
1535 for (i = 0; *hmsg[i]; i++) println(hmsg[i]);
1537 println(" Choose bug test number:");
1538 menuchoice = menu(menutable);
1539 switch (menuchoice) {
1540 case 1: bug_a(); break;
1541 case 2: bug_b(); break;
1542 case 3: bug_c(); break;
1543 case 4: bug_d(); break;
1544 case 5: bug_e(); break;
1545 case 6: bug_f(); break;
1546 case 7: bug_w(); break;
1547 case 8: bug_l(); break;
1548 case 9: bug_s(); break;
1550 } while (menuchoice);
1553 /* Bug A: Smooth scroll to jump scroll */
1559 println("This is a test of the VT100 'Scroll while toggle softscroll'");
1560 println("bug. The cursor may disappear, or move UP the screen, or");
1561 println("multiple copies of some lines may appear.");
1564 /* Invoke the bug */
1566 esc ("[24H"); /* Simplified cursor movement */
1567 rm("?4"); for (i = 1; i <= 20; i++) printf("\n");
1568 sm("?4"); for (i = 1; i <= 10; i++) printf("\n");
1569 rm("?4"); for (i = 1; i <= 5; i++) printf("\n");
1571 /* That should be enough to show the bug. But we'll try another way: */
1572 sm ("?4"); /* Set soft scroll */
1573 nel (); /* "NextLine", move down */
1574 rm ("?4"); /* Reset soft scroll */
1575 nel (); /* "NextLine", move down */
1576 for (i = 1; i <= 10; i++) { /* Show the bug */
1577 printf ("Softscroll bug test, line %d. ", i);
1580 println("That should have been enough to show the bug, if present.");
1584 /* Bug B: Scrolling region */
1591 printf("Line 11 should be double-wide, line 12 should be cleared.");
1593 printf("Then, the letters A-P should be written at the beginning");
1595 printf("of lines 12-24, and the empty line and A-E are scrolled away.");
1597 printf("If the bug is present, some lines are confused, look at K-P.");
1598 cup(11,1); decdwl();
1600 cup(12,1); el(0); printf("Here we go... "); holdit();
1601 cup(12,1); ri(); /* Bug comes here */
1602 for (c = 'A'; c <= 'P'; c++) printf("%c\n",c); /* Bug shows here */
1604 decstbm(0,0); /* No scr. region */
1607 /* Bug C: Wide to narrow screen */
1610 sm("?3"); /* 132 column mode */
1612 rm("?3"); /* 80 column mode */
1614 printf("Except for this line, the screen should be blank. ");
1618 /* Bug D: Narrow to wide screen */
1623 /* Make the bug appear */
1627 /* The original code in the article says
1628 * PRINT ESC$; "[13;1H"; CHR$(10%);
1629 * but I guess a cup(14,1); would do.
1630 * (To output a pure LF might be tricky).
1633 sm("?3"); /* Make the bug visible */
1635 println("You should see blinking text at the bottom line.");
1637 println("Enter 0 to exit, 1 to try to invoke the bug again.");
1638 cup(24,9); decdwl(); sgr("1;5;7");
1639 printf("If you can see this then the bug did not appear."); sgr("");
1641 result = inchar(); readnl();
1643 } while (result == '1');
1644 sm("?4"); /* Syrup scroll */
1646 for (i = 1; i <= 5; i++)
1647 println("If the bug is present, this should make things much worse!");
1649 rm("?4"); /* Jump scroll */
1652 /* Bug E: Cursor move from double- to single-wide line */
1656 static char *rend[2] = { "\033[m", "\033[7m" };
1659 println("This test should put an 'X' at line 3 column 100.");
1660 for (i = 1; i <= 12; i++) printf("1234567890%s",rend[i & 1]);
1661 cup(1,1); /* The bug appears when we jump from a dobule-wide line */
1662 cup(3,100); /* to a single-wide line, column > 66. */
1664 cup(4, 66); printf("! !");
1666 printf("--------------------------- The 'X' should NOT be above here -");
1667 printf("---+------------ but above here -----+");
1668 cup(10,1); decdwl(); holdit();
1672 /* Bug F: Column mode escape sequence */
1678 * VT100 "toggle origin mode, forget rest" bug. If you try to set
1679 * (or clear) parameters and one of them is the "origin mode"
1680 * ("?6") parameter, parameters that appear after the "?6"
1681 * remain unaffected. This is also true on CIT-101 terminals.
1683 sm ("?5"); /* Set reverse mode */
1684 sm ("?3"); /* Set 132 column mode */
1685 println("Test VT100 'Toggle origin mode, forget rest' bug, part 1.");
1686 println("The screen should be in reverse, 132 column mode.");
1689 rm ("?6;5;3"); /* Reset (origin, reverse, 132 col) */
1690 println("Test VT100 'Toggle origin mode, forget rest' bug, part 2.\n");
1691 println("The screen should be in non-reverse, 80 column mode.");
1696 * The dreaded "wraparound" bug! You CUP to col 80, write a char,
1697 * CUP to another line in col 80, write a char. And the brain-damaged
1698 * terminal thinks that "Hokay, so he's written a char in col 80, so
1699 * I stay in col 80 and wait for next character. Let's see now, here
1700 * comes another character, and I'm still in col 80, so I must make
1701 * a NewLine first." -- It doesn't clear that "still in col 80" flag
1709 println(" This illustrates the \"wrap around bug\" which exists on a");
1710 println(" standard VT100. At the top of the screen there should be");
1711 println(" a row of +'s, and the rightmost column should be filled");
1712 println(" with *'s. But if the bug is present, some of the *'s may");
1713 println(" be placed in other places, e.g. in the leftmost column,");
1714 println(" and the top line of +'s may be scrolled away.");
1717 for (col = 1; col <= 79; col++)
1719 for (row = 1; row <= 24; row++) {
1728 * Check if the right half of double-width lines comes back
1729 * when a line is first set to single-width, filled with stuff,
1730 * set to double-width, and finally reset to single-width.
1732 * A VT100 has this misfeature, and many others. Foo!
1737 printf("This-is-a-long-line-This-is-a-long-line-");
1738 printf("This-is-a-long-line-This-is-a-long-line-");
1740 printf("This is a test of what happens to the right half of double-width");
1742 printf("A common misfeature is that the right half does not come back");
1743 println(" when a long");
1744 printf("single-width line is set to double-width and then reset to");
1745 println(" single-width.");
1748 println("Now the line below should contain 80 characters in single width.");
1750 cup(15, 1); decdwl();
1752 println("Now the line below should contain 40 characters in double width.");
1754 cup(15, 1); decswl();
1756 println("Now the line below should contain 80 characters in single width.");
1759 /* ...and in 132 column mode */
1764 printf("This-is-a-long-line-This-is-a-long-line-");
1765 printf("This-is-a-long-line-This-is-a-long-line-");
1766 printf("This-is-a-long-line-This-is-a-long-line-");
1767 printf("ending-here-");
1770 printf("This is the same test in 132 column mode.");
1773 println("Now the line below should contain 132 characters in single width.");
1775 cup(15, 1); decdwl();
1777 println("Now the line below should contain 66 characters in double width.");
1779 cup(15, 1); decswl();
1781 println("Now the line below should contain 132 characters in single width.");
1788 decstbm(20,10); /* 20-10=-10, < 2, so no scroll region. */
1790 for (i=1; i<=20; i++)
1791 printf("This is 20 lines of text (line %d), no scroll region.\n", i);
1794 decstbm(0,1); /* Should be interpreted as decstbm(1,1) = none */
1796 for (i=1; i<=20; i++)
1797 printf("This is 20 lines of text (line %d), no scroll region.\n", i);
1799 decstbm(0,0); /* No scroll region (just in case...) */
1806 * - RIS (Reset to Initial State)
1807 * - DECTST (invoke terminal test)
1811 printf ("The terminal will now be RESET. ");
1817 zleep(5000); /* Wait 5.0 seconds */
1819 println("The terminal is now RESET. Next, the built-in confidence test");
1820 printf("%s", "will be invoked. ");
1827 zleep(5000); /* Wait 5.0 seconds */
1829 println("If the built-in confidence test found any errors, a code");
1830 printf("%s", "is visible above. ");
1834 initterminal(pn) int pn; {
1841 sgttyNew.sg_flags |= CBREAK;
1847 sgttyNew.sg_flags = sgttyOrg.sg_flags | CBREAK;
1852 open(_PATH_TTY,O_RDWR|O_NDELAY);
1856 /* Set up neccesary TOPS-10 terminal parameters */
1858 trmop(02041, `VT100`); /* tty type vt100 */
1859 trmop(02002, 0); /* tty no tape */
1860 trmop(02003, 0); /* tty lc */
1861 trmop(02005, 1); /* tty tab */
1862 trmop(02010, 1); /* tty no crlf */
1863 trmop(02020, 0); /* tty no tape */
1864 trmop(02021, 1); /* tty page */
1865 trmop(02025, 0); /* tty blanks */
1866 trmop(02026, 1); /* tty no alt */
1867 trmop(02040, 1); /* tty defer */
1870 ttybin(1); /* set line to binary mode */
1872 /* Set up my personal prejudices */
1874 esc("<"); /* Enter ANSI mode (if in VT52 mode) */
1875 rm("?1"); /* cursor keys normal */
1876 rm("?3"); /* 80 col mode */
1877 rm("?4"); /* Jump scroll */
1878 rm("?5"); /* Normal screen */
1879 rm("?6"); /* Absolute origin mode */
1880 sm("?7"); /* Wrap around on */
1881 rm("?8"); /* Auto repeat off */
1882 decstbm(0,0); /* No scroll region */
1883 sgr("0"); /* Normal character attributes */
1888 /* Force my personal prejudices upon the poor luser */
1890 esc("<"); /* Enter ANSI mode (if in VT52 mode) */
1891 rm("?1"); /* cursor keys normal */
1892 rm("?3"); /* 80 col mode */
1893 rm("?5"); /* Normal screen */
1894 rm("?6"); /* Absolute origin mode */
1895 sm("?7"); /* Wrap around on */
1896 sm("?8"); /* Auto repeat on */
1897 decstbm(0,0); /* No scroll region */
1898 sgr("0"); /* Normal character attributes */
1904 printf("That's all, folks!\n");
1908 ttybin(0); /* reset line to normal mode */
1919 signal(SIGINT, onbrk);
1923 longjmp(intrenv, 1);
1928 signal(SIGTERM, onterm);
1929 longjmp(intrenv, 1);
1935 printf("Push <RETURN>");
1945 do { read(0,&ch,1); } while(ch != '\n' && !brkrd);
1947 kill(getpid(), SIGTERM);
1951 while (getchar() != '\n')
1955 while (getchar() != '\n')
1960 scanto(str, pos, toc) char *str; int *pos; char toc; {
1964 while (toc != (c = str[(*pos)++])) {
1965 if (isdigit(c)) result = result * 10 + c - '0';
1968 if (c == toc) return(result);
1972 char *lookup(t, k) struct table t[]; int k; {
1975 for (i = 0; t[i].key != -1; i++) {
1976 if (t[i].key == k) return(t[i].msg);
1978 return("BAD VALUE");
1981 menu(table) char *table[]; {
1983 int i, tablesize, choice;
1989 for (i = 0; *table[i] != '\0'; i++) {
1990 printf(" %d. %s\n", i, table[i]);
1995 printf("\n Enter choice number (0 - %d): ", tablesize);
1999 while (c = *s++) choice = 10 * choice + c - '0';
2000 if (choice >= 0 && choice <= tablesize) {
2004 printf(" Bad choice, try again: ");
2008 chrprint (s) char *s; {
2015 for (i = 0; s[i] != '\0'; i++) {
2016 if (s[i] <= ' ' || s[i] == '\177')
2017 printf("<%d> ", s[i]);
2018 else printf("%c ", s[i]);