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.4 2005/02/20 17:19:11 asmodai 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",
95 initterminal(setjmp(intrenv));
96 signal(SIGINT, onbrk);
97 signal(SIGTERM, onterm);
101 cup(5,10); printf("VT100 test program, version %s", VERSION);
102 cup(7,10); println("Choose test type:");
103 menuchoice = menu(mainmenu);
104 switch (menuchoice) {
105 case 1: tst_movements(); break;
106 case 2: tst_screen(); break;
107 case 3: tst_characters(); break;
108 case 4: tst_doublesize(); break;
109 case 5: tst_keyboard(); break;
110 case 6: tst_reports(); break;
111 case 7: tst_vt52(); break;
112 case 8: tst_insdel(); break;
113 case 9: tst_bugs(); break;
114 case 10: tst_rst(); break;
116 } while (menuchoice);
124 CUB (Cursor Backward)
125 CUD (Cursor Down) IND (Index) NEL (Next Line)
126 CUU (Cursor Up) RI (Reverse Index)
127 CUP (Cursor Position) HVP (Horizontal and Vertical Position)
128 ED (Erase in Display)
130 DECALN (Screen Alignment Display)
132 Cursor control characters inside CSI sequences
135 int i, row, col, pass, width, hlfxtra;
136 char c, *ctext = "This is a correct sentence";
138 for (pass = 0; pass <= 1; pass++) {
139 if (pass == 0) { rm("?3"); width = 80; hlfxtra = 0; }
140 else { sm("?3"); width = 132; hlfxtra = 26; }
143 cup( 9,10+hlfxtra); ed(1);
144 cup(18,60+hlfxtra); ed(0); el(1);
145 cup( 9,71+hlfxtra); el(0);
146 for (row = 10; row <= 16; row++) {
147 cup(row, 10+hlfxtra); el(1);
148 cup(row, 71+hlfxtra); el(0);
151 for (col = 1; col <= width; col++) {
152 hvp(24, col); printf("*");
153 hvp( 1, col); printf("*");
156 for (row = 2; row <= 23; row++) {
162 for (row = 23; row >=2; row--) {
167 for (row = 2; row <= 23; row++) {
178 cub(42+hlfxtra); cuf(2);
179 for (col = 3; col <= width-2; col++) {
181 cuf(0); cub(2); cuf(1);
184 cuf(42+hlfxtra); cub(2);
185 for (col = width-2; col >= 3; col--) {
187 cub(1); cuf(1); cub(0); printf("%c", 8);
189 cup( 1, 1); cuu(10); cuu(1); cuu(0);
190 cup(24,width); cud(10); cud(1); cud(0);
193 for (row = 10; row <= 15; row++) {
194 for (col = 12+hlfxtra; col <= 69+hlfxtra; col++) printf(" ");
198 printf("The screen should be cleared, and have an unbroken bor-");
200 printf("der of *'s and +'s around the edge, and exactly in the");
202 printf("middle there should be a frame of E's around this text");
204 printf("with one (1) free position around it. ");
211 println("Test of cursor-control characters inside ESC sequences.");
212 println("Below should be two identical lines:");
214 println("A B C D E F G H I J K L M N O P Q R S");
215 for (i = 1; i < 20; i++) {
216 printf("%c", 64 + i);
217 brcstr("2\010", 'C'); /* Two forward, one backspace */
225 println("Test of leading zeros in ESC sequences.");
226 printf("Two lines below you should see the sentence \"%s\".",ctext);
227 for (col = 1; *ctext; col++)
228 printf("\033[00000000004;00000000%dH%c",col,*ctext++);
236 - DECSTBM (Set Top and Bottom Margins)
237 - TBC (Tabulation Clear)
238 - HTS (Horizontal Tabulation Set)
239 - SM RM (Set/Reset mode): - 80/132 chars
240 - Origin: Realtive/absolute
241 - Scroll: Smooth/jump
243 - SGR (Select Graphic Rendition)
244 - SM RM (Set/Reset Mode) - Inverse
245 - DECSC (Save Cursor)
246 - DECRC (Restore Cursor)
249 int i, j, cset, row, col, down, soft, background;
251 static char *tststr = "*qx`";
252 static char *attr[5] = { ";0", ";1", ";4", ";5", ";7" };
255 sm("?7"); /* Wrap Around ON */
256 for (col = 1; col <= 160; col++) printf("*");
257 rm("?7"); /* Wrap Around OFF */
259 for (col = 1; col <= 160; col++) printf("*");
260 sm("?7"); /* Wrap Around ON */
262 println("This should be three identical lines of *'s completely filling");
263 println("the top of the screen without any empty lines between.");
264 println("(Test of WRAP AROUND mode setting.)");
270 for (col = 1; col <= 78; col += 3) {
274 for (col = 4; col <= 78; col += 6) {
277 cup(1,7); tbc(1); tbc(2); /* no-op */
278 cup(1,1); for (col = 1; col <= 78; col += 6) printf("\t*");
279 cup(2,2); for (col = 2; col <= 78; col += 6) printf(" *");
281 println("Test of TAB setting/resetting. These two lines");
282 printf("should look the same. ");
284 for (background = 0; background <= 1; background++) {
285 if (background) rm("?5");
287 sm("?3"); /* 132 cols */
288 ed(2); /* VT100 clears screen on SM3/RM3, but not obviously, so... */
290 for (col = 1; col <= 132; col += 8) {
293 cup(1,1); for (col = 1; col <= 130; col += 10) printf("1234567890");
295 for (row = 3; row <= 20; row++) {
297 printf("This is 132 column mode, %s background.",
298 background ? "dark" : "light");
301 rm("?3"); /* 80 cols */
302 ed(2); /* VT100 clears screen on SM3/RM3, but not obviously, so... */
303 cup(1,1); for (col = 1; col <= 80; col += 10) printf("1234567890");
304 for (row = 3; row <= 20; row++) {
306 printf("This is 80 column mode, %s background.",
307 background ? "dark" : "light");
313 sm("?6"); /* Origin mode (relative) */
314 for (soft = -1; soft <= 0; soft++) {
317 for (row = 12; row >= 1; row -= 11) {
318 decstbm(row, 24-row+1);
320 for (down = 0; down >= -1; down--) {
323 for (i = 1; i <= 30; i++) {
324 printf("%s scroll %s region %d Line %d\n",
325 soft ? "Soft" : "Jump",
326 down ? "down" : "up",
328 if (down) { ri(); ri(); }
337 "\nOrigin mode test. This line should be at the bottom of the screen.");
340 "This line should be the one above the bottom of the screeen. ");
343 rm("?6"); /* Origin mode (absolute) */
346 "Origin mode test. This line should be at the bottom of the screen.");
348 printf("%s", "This line should be at the top if the screen. ");
353 cup( 1,20); printf("Graphic rendition test pattern:");
354 cup( 4, 1); sgr("0"); printf("vanilla");
355 cup( 4,40); sgr("0;1"); printf("bold");
356 cup( 6, 6); sgr(";4"); printf("underline");
357 cup( 6,45);sgr(";1");sgr("4");printf("bold underline");
358 cup( 8, 1); sgr("0;5"); printf("blink");
359 cup( 8,40); sgr("0;5;1"); printf("bold blink");
360 cup(10, 6); sgr("0;4;5"); printf("underline blink");
361 cup(10,45); sgr("0;1;4;5"); printf("bold underline blink");
362 cup(12, 1); sgr("1;4;5;0;7"); printf("negative");
363 cup(12,40); sgr("0;1;7"); printf("bold negative");
364 cup(14, 6); sgr("0;4;7"); printf("underline negative");
365 cup(14,45); sgr("0;1;4;7"); printf("bold underline negative");
366 cup(16, 1); sgr("1;4;;5;7"); printf("blink negative");
367 cup(16,40); sgr("0;1;5;7"); printf("bold blink negative");
368 cup(18, 6); sgr("0;4;5;7"); printf("underline blink negative");
369 cup(18,45); sgr("0;1;4;5;7"); printf("bold underline blink negative");
372 rm("?5"); /* Inverse video off */
373 cup(23,1); el(0); printf("Dark background. "); holdit();
374 sm("?5"); /* Inverse video */
375 cup(23,1); el(0); printf("Light background. "); holdit();
378 cup(8,12); printf("normal");
379 cup(8,24); printf("bold");
380 cup(8,36); printf("underscored");
381 cup(8,48); printf("blinking");
382 cup(8,60); printf("reversed");
383 cup(10,1); printf("stars:");
384 cup(12,1); printf("line:");
385 cup(14,1); printf("x'es:");
386 cup(16,1); printf("diamonds:");
387 for (cset = 0; cset <= 3; cset++) {
388 for (i = 0; i <= 4; i++) {
389 cup(10 + 2 * cset, 12 + 12 * i);
391 if (cset == 0 || cset == 2) scs(0,'B');
393 for (j = 0; j <= 4; j++) {
394 printf("%c", tststr[cset]);
397 cup(cset + 1, i + 1); sgr(""); scs(0,'B'); printf("A");
399 for (j = 0; j <= 4; j++) {
400 printf("%c", tststr[cset]);
404 sgr("0"); scs(0,'B'); cup(21,1);
405 println("Test of the SAVE/RESTORE CURSOR feature. There should");
406 println("be ten characters of each flavour, and a rectangle");
407 println("of 5 x 4 A's filling the top left of the screen.");
413 SCS (Select character Set)
417 char chcode[5], *setmsg[5];
424 setmsg[0] = "UK / national";
425 setmsg[1] = "US ASCII";
426 setmsg[2] = "Special graphics and line drawing";
427 setmsg[3] = "Alternate character ROM standard characters";
428 setmsg[4] = "Alternate character ROM special graphics";
430 cup(1,10); printf("Selected as G0 (with SI)");
431 cup(1,48); printf("Selected as G1 (with SO)");
432 for (cset = 0; cset <= 4; cset++) {
434 cup(3 + 4 * cset, 1);
436 printf("Character set %c (%s)",chcode[cset], setmsg[cset]);
438 for (g = 0; g <= 1; g++) {
440 for (i = 1; i <= 3; i++) {
441 cup(3 + 4 * cset + i, 10 + 38 * g);
442 for (j = 0; j <= 31; j++) {
443 printf("%c", i * 32 + j);
449 cup(24,1); printf("These are the installed character sets. ");
455 DECSWL (Single Width Line)
456 DECDWL (Double Width Line)
457 DECDHL (Double Height Line) (also implicit double width)
462 /* Print the test pattern in both 80 and 132 character width */
464 for(w = 0; w <= 1; w++) {
469 if (w) { sm("?3"); printf("132 column mode"); }
470 else { rm("?3"); printf(" 80 column mode"); }
473 printf("v------- left margin");
476 printf("This is a normal-sized line");
477 decdhl(0); decdhl(1); decdwl(); decswl();
480 printf("This is a Double-width line");
481 decswl(); decdhl(0); decdhl(1); decdwl();
484 decdwl(); decswl(); decdhl(1); decdhl(0);
485 printf("This is a Double-width-and-height line");
487 decdwl(); decswl(); decdhl(0); decdhl(1);
488 printf("This is a Double-width-and-height line");
491 decdwl(); decswl(); decdhl(1); decdhl(0); el(2);
492 printf("This is another such line");
494 decdwl(); decswl(); decdhl(0); decdhl(1);
495 printf("This is another such line");
498 printf("^------- left margin");
501 printf("This is not a double-width line");
502 for (i = 0; i <= 1; i++) {
504 if (i) { printf("**is**"); decdwl(); }
505 else { printf("is not"); decswl(); }
509 /* Set vanilla tabs for next test */
510 cup(1,1); tbc(3); for (col = 1; col <= 132; col += 8) { cuf(8); hts(); }
515 cup( 8,1); decdhl(0); printf("lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk");
516 cup( 9,1); decdhl(1); printf("lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk");
517 cup(10,1); decdhl(0); printf("x%c%c%c%c%cx",9,9,9,9,9);
518 cup(11,1); decdhl(1); printf("x%c%c%c%c%cx",9,9,9,9,9);
519 cup(12,1); decdhl(0); printf("x%c%c%c%c%cx",9,9,9,9,9);
520 cup(13,1); decdhl(1); printf("x%c%c%c%c%cx",9,9,9,9,9);
521 cup(14,1); decdhl(0); printf("x x");
522 cup(15,1); decdhl(1); printf("x x");
523 cup(16,1); decdhl(0); printf("mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj");
524 cup(17,1); decdhl(1); printf("mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj");
525 scs(0,'B'); sgr("1;5");
527 printf("* The mad programmer strikes again * ");
528 cup(13,3); printf("%c",9); cub(6);
529 printf("* The mad programmer strikes again *");
532 println("Another test pattern... a frame with blinking bold text,");
533 printf("all in double-height double-width size. ");
536 decstbm(8,24); /* Absolute origin mode, so cursor is set at (1,1) */
538 for (i = 1; i <= 12; i++)
540 decstbm(0,0); /* No scroll region */
542 printf("%s", "Exactly half of the box should remain. ");
550 - Keyboard return messages
551 - SM RM (Set/Reset Mode) - Cursor Keys
553 - DECKPAM (Keypad Application Mode)
554 - DECKPNM (Keypad Numeric Mode)
556 The standard VT100 keayboard layout:
560 ESC 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ `~ BS
562 TAB* qQ wW eE rR tT yY uU iI oO pP [{ ]} DEL
564 ** ** aA sS dD fF gG hH jJ kK lL ;: ," RETN \|
566 ** **** zZ xX cC vV bB nN mM ,< .> /? **** LF
568 ****************SPACE BAR****************
581 char *ledmsg[6], *ledseq[6];
589 char *curkeystr, *fnkeystr, *abmstr;
590 char arptstring[500];
599 { '1', 1, 6, "1" }, { '!', 1, 7, "!" },
600 { '2', 1, 11, "2" }, { '@', 1, 12, "@" },
601 { '3', 1, 16, "3" }, { '#', 1, 17, "#" },
602 { '4', 1, 21, "4" }, { '$', 1, 22, "$" },
603 { '5', 1, 26, "5" }, { '%', 1, 27, "%" },
604 { '6', 1, 31, "6" }, { '^', 1, 32, "^" },
605 { '7', 1, 36, "7" }, { '&', 1, 37, "&" },
606 { '8', 1, 41, "8" }, { '*', 1, 42, "*" },
607 { '9', 1, 46, "9" }, { '(', 1, 47, "(" },
608 { '0', 1, 51, "0" }, { ')', 1, 52, ")" },
609 { '-', 1, 56, "-" }, { '_', 1, 57, "_" },
610 { '=', 1, 61, "=" }, { '+', 1, 62, "+" },
611 { '`', 1, 66, "`" }, { '~', 1, 67, "~" },
613 { 9, 2, 0, " TAB " },
614 { 'q', 2, 8, "q" }, { 'Q', 2, 9, "Q" },
615 { 'w', 2, 13, "w" }, { 'W', 2, 14, "W" },
616 { 'e', 2, 18, "e" }, { 'E', 2, 19, "E" },
617 { 'r', 2, 23, "r" }, { 'R', 2, 24, "R" },
618 { 't', 2, 28, "t" }, { 'T', 2, 29, "T" },
619 { 'y', 2, 33, "y" }, { 'Y', 2, 34, "Y" },
620 { 'u', 2, 38, "u" }, { 'U', 2, 39, "U" },
621 { 'i', 2, 43, "i" }, { 'I', 2, 44, "I" },
622 { 'o', 2, 48, "o" }, { 'O', 2, 49, "O" },
623 { 'p', 2, 53, "p" }, { 'P', 2, 54, "P" },
624 { '[', 2, 58, "[" }, { '{', 2, 59, "{" },
625 { ']', 2, 63, "]" }, { '}', 2, 64, "}" },
626 { 127, 2, 71, "DEL" },
627 { 'a', 3, 10, "a" }, { 'A', 3, 11, "A" },
628 { 's', 3, 15, "s" }, { 'S', 3, 16, "S" },
629 { 'd', 3, 20, "d" }, { 'D', 3, 21, "D" },
630 { 'f', 3, 25, "f" }, { 'F', 3, 26, "F" },
631 { 'g', 3, 30, "g" }, { 'G', 3, 31, "G" },
632 { 'h', 3, 35, "h" }, { 'H', 3, 36, "H" },
633 { 'j', 3, 40, "j" }, { 'J', 3, 41, "J" },
634 { 'k', 3, 45, "k" }, { 'K', 3, 46, "K" },
635 { 'l', 3, 50, "l" }, { 'L', 3, 51, "L" },
636 { ';', 3, 55, ";" }, { ':', 3, 56, ":" },
637 {'\'', 3, 60, "'" }, { '"', 3, 61,"\"" },
638 { 13, 3, 65, "RETN"},
639 {'\\', 3, 71,"\\" }, { '|', 3, 72, "|" },
640 { 'z', 4, 12, "z" }, { 'Z', 4, 13, "Z" },
641 { 'x', 4, 17, "x" }, { 'X', 4, 18, "X" },
642 { 'c', 4, 22, "c" }, { 'C', 4, 23, "C" },
643 { 'v', 4, 27, "v" }, { 'V', 4, 28, "V" },
644 { 'b', 4, 32, "b" }, { 'B', 4, 33, "B" },
645 { 'n', 4, 37, "n" }, { 'N', 4, 38, "N" },
646 { 'm', 4, 42, "m" }, { 'M', 4, 43, "M" },
647 { ',', 4, 47, "," }, { '<', 4, 48, "<" },
648 { '.', 4, 52, "." }, { '>', 4, 53, ">" },
649 { '/', 4, 57, "/" }, { '?', 4, 58, "?" },
651 { ' ', 5, 13, " SPACE BAR "},
655 static struct natkey {
660 } natkeytab [][29] = {
668 { '+', 1, 56, "+" }, { '?', 1, 57, "?" },
669 { '`', 1, 61, "`" }, { '@', 1, 62, "@" },
670 { '<', 1, 66, "<" }, { '>', 1, 67, ">" },
671 { '}', 2, 58, "}" }, { ']', 2, 59, "]" },
672 { '^', 2, 63, "^" }, { '~', 2, 64, "~" },
673 { '|', 3, 55, "|" }, {'\\', 3, 56,"\\" },
674 { '{', 3, 60, "{" }, { '[', 3, 61, "[" },
675 {'\'', 3, 71, "'" }, { '*', 3, 72, "*" },
676 { ',', 4, 47, "," }, { ';', 4, 48, ";" },
677 { '.', 4, 52, "." }, { ':', 4, 53, ":" },
678 { '-', 4, 57, "-" }, { '_', 4, 58, "_" },
688 { '+', 1, 56, "+" }, { '?', 1, 57, "?" },
689 { '`', 1, 61, "`" }, { '@', 1, 62, "@" },
690 { '<', 1, 66, "<" }, { '>', 1, 67, ">" },
691 { '}', 2, 58, "}" }, { ']', 2, 59, "]" },
692 { '~', 2, 63, "~" }, { '^', 2, 64, "^" },
693 { '|', 3, 55, "|" }, {'\\', 3, 56,"\\" },
694 { '{', 3, 60, "{" }, { '[', 3, 61, "[" },
695 {'\'', 3, 71, "'" }, { '*', 3, 72, "*" },
696 { ',', 4, 47, "," }, { ';', 4, 48, ";" },
697 { '.', 4, 52, "." }, { ':', 4, 53, ":" },
698 { '-', 4, 57, "-" }, { '_', 4, 58, "_" },
703 static struct curkey {
711 /* A Reset, A Set, VT52 */
713 {{"\033[A","\033OA","\033A"}, 0, 56, "UP", "Up arrow" },
714 {{"\033[B","\033OB","\033B"}, 0, 61, "DN", "Down arrow" },
715 {{"\033[D","\033OD","\033D"}, 0, 66, "LT", "Left arrow" },
716 {{"\033[C","\033OC","\033C"}, 0, 71, "RT", "Right arrow"},
717 {{"", "", "" }, 0, 0, "", "" }
720 static struct fnkey {
728 /* ANSI-num,ANSI-app,VT52-nu,VT52-ap, r, c, symb name */
730 {{"\033OP","\033OP","\033P","\033P" }, 6, 59, "PF1", "PF1" },
731 {{"\033OQ","\033OQ","\033Q","\033Q" }, 6, 63, "PF2", "PF2" },
732 {{"\033OR","\033OR","\033R","\033R" }, 6, 67, "PF3", "PF3" },
733 {{"\033OS","\033OS","\033S","\033S" }, 6, 71, "PF4", "PF4" },
734 {{"7", "\033Ow","7", "\033?w"}, 7, 59, " 7 ", "Numeric 7" },
735 {{"8", "\033Ox","8", "\033?x"}, 7, 63, " 8 ", "Numeric 8" },
736 {{"9", "\033Oy","9", "\033?y"}, 7, 67, " 9 ", "Numeric 9" },
737 {{"-", "\033Om","-", "\033?m"}, 7, 71, " - ", "Minus" },
738 {{"4", "\033Ot","4", "\033?t"}, 8, 59, " 4 ", "Numeric 4" },
739 {{"5", "\033Ou","5", "\033?u"}, 8, 63, " 5 ", "Numeric 5" },
740 {{"6", "\033Ov","6", "\033?v"}, 8, 67, " 6 ", "Numeric 6" },
741 {{",", "\033Ol",",", "\033?l"}, 8, 71, " , ", "Comma" },
742 {{"1", "\033Oq","1", "\033?q"}, 9, 59, " 1 ", "Numeric 1" },
743 {{"2", "\033Or","2", "\033?r"}, 9, 63, " 2 ", "Numeric 2" },
744 {{"3", "\033Os","3", "\033?s"}, 9, 67, " 3 ", "Numeric 3" },
745 {{"0", "\033Op","0", "\033?p"},10, 59," O ","Numeric 0"},
746 {{".", "\033On",".", "\033?n"},10, 67, " . ", "Point" },
747 {{"\015", "\033OM","\015", "\033?M"},10, 71, "ENT", "ENTER" },
748 {{"","","",""}, 0, 0, "", "" }
755 { 0, "NUL (CTRL-@ or CTRL-Space)" },
756 { 0, "SOH (CTRL-A)" },
757 { 0, "STX (CTRL-B)" },
758 { 0, "ETX (CTRL-C)" },
759 { 0, "EOT (CTRL-D)" },
760 { 0, "ENQ (CTRL-E)" },
761 { 0, "ACK (CTRL-F)" },
762 { 0, "BEL (CTRL-G)" },
763 { 0, "BS (CTRL-H) (BACK SPACE)" },
764 { 0, "HT (CTRL-I) (TAB)" },
765 { 0, "LF (CTRL-J) (LINE FEED)" },
766 { 0, "VT (CTRL-K)" },
767 { 0, "FF (CTRL-L)" },
768 { 0, "CR (CTRL-M) (RETURN)" },
769 { 0, "SO (CTRL-N)" },
770 { 0, "SI (CTRL-O)" },
771 { 0, "DLE (CTRL-P)" },
772 { 0, "DC1 (CTRL-Q) (X-On)" },
773 { 0, "DC2 (CTRL-R)" },
774 { 0, "DC3 (CTRL-S) (X-Off)" },
775 { 0, "DC4 (CTRL-T)" },
776 { 0, "NAK (CTRL-U)" },
777 { 0, "SYN (CTRL-V)" },
778 { 0, "ETB (CTRL-W)" },
779 { 0, "CAN (CTRL-X)" },
780 { 0, "EM (CTRL-Y)" },
781 { 0, "SUB (CTRL-Z)" },
782 { 0, "ESC (CTRL-[) (ESCAPE)" },
783 { 0, "FS (CTRL-\\ or CTRL-? or CTRL-_)" },
784 { 0, "GS (CTRL-])" },
785 { 0, "RS (CTRL-^ or CTRL-~ or CTRL-`)" },
786 { 0, "US (CTRL-_ or CTRL-?)" }
789 static char *keyboardmenu[] = {
790 "Standard American ASCII layout",
791 "Swedish national layout D47",
792 "Swedish national layout E47",
793 /* add new keyboard layouts here */
797 static char *curkeymodes[3] = {
798 "ANSI / Cursor key mode RESET",
799 "ANSI / Cursor key mode SET",
803 static char *fnkeymodes[4] = {
805 "ANSI Application mode",
807 "VT52 Application mode"
810 ledmsg[0] = "L1 L2 L3 L4"; ledseq[0] = "1;2;3;4";
811 ledmsg[1] = " L2 L3 L4"; ledseq[1] = "1;0;4;3;2";
812 ledmsg[2] = " L2 L3"; ledseq[2] = "1;4;;2;3";
813 ledmsg[3] = "L1 L2"; ledseq[3] = ";;2;1";
814 ledmsg[4] = "L1"; ledseq[4] = "1";
815 ledmsg[5] = ""; ledseq[5] = "";
820 println("These LEDs (\"lamps\") on the keyboard should be on:");
821 for (i = 0; i <= 5; i++) {
822 cup(10,52); el(0); printf("%s", ledmsg[i]);
830 println("Test of the AUTO REPEAT feature");
832 println("Hold down an alphanumeric key for a while, then push RETURN.");
833 printf("%s", "Auto Repeat OFF: ");
835 inputline(arptstring);
836 if (strlen(arptstring) == 0) println("No characters read!??");
837 else if (strlen(arptstring) == 1) println("OK.");
838 else println("Too many characters read.");
840 println("Hold down an alphanumeric key for a while, then push RETURN.");
841 printf("%s", "Auto Repeat ON: ");
843 inputline(arptstring);
844 if (strlen(arptstring) == 0) println("No characters read!??");
845 else if (strlen(arptstring) == 1) println("Not enough characters read.");
852 println("Choose keyboard layout:");
853 kblayout = menu(keyboardmenu);
856 for (j = 0; natkeytab[kblayout][j].natc != '\0'; j++) {
857 for (i = 0; keytab[i].c != '\0'; i++) {
858 if (keytab[i].row == natkeytab[kblayout][j].natrow &&
859 keytab[i].col == natkeytab[kblayout][j].natcol) {
860 keytab[i].c = natkeytab[kblayout][j].natc;
861 keytab[i].symbol = natkeytab[kblayout][j].natsymbol;
869 for (i = 0; keytab[i].c != '\0'; i++) {
870 cup(1 + 2 * keytab[i].row, 1 + keytab[i].col);
872 printf("%s", keytab[i].symbol);
876 sgttyNew.sg_flags &= ~CRMOD;
877 sgttyNew.sg_flags &= ~ECHO;
880 printf("Press each key, both shifted and unshifted. Finish with RETURN:");
881 do { /* while (kbdc != 13) */
882 cup(23,1); kbdc = inchar();
884 sprintf(kbds, "%c", kbdc);
886 for (i = 0; keytab[i].c != '\0'; i++) {
887 if (keytab[i].c == kbdc) {
888 cup(1 + 2 * keytab[i].row, 1 + keytab[i].col);
889 printf("%s", keytab[i].symbol);
893 } while (kbdc != 13);
896 for (ckeymode = 0; ckeymode <= 2; ckeymode++) {
897 if (ckeymode) sm("?1");
899 for (i = 0; curkeytab[i].curkeysymbol[0] != '\0'; i++) {
900 cup(1 + 2 * curkeytab[i].curkeyrow, 1 + curkeytab[i].curkeycol);
902 printf("%s", curkeytab[i].curkeysymbol);
905 cup(20,1); printf("<%s>%20s", curkeymodes[ckeymode], "");
907 cup(22,1); printf("%s", "Press each cursor key. Finish with TAB.");
910 if (ckeymode == 2) rm("?2"); /* VT52 mode */
912 esc("<"); /* ANSI mode */
914 cup(23,1); chrprint(curkeystr);
915 if (!strcmp(curkeystr,"\t")) break;
916 for (i = 0; curkeytab[i].curkeysymbol[0] != '\0'; i++) {
917 if (!strcmp(curkeystr,curkeytab[i].curkeymsg[ckeymode])) {
919 printf(" (%s key) ", curkeytab[i].curkeyname);
921 cup(1 + 2 * curkeytab[i].curkeyrow,
922 1 + curkeytab[i].curkeycol);
923 printf("%s", curkeytab[i].curkeysymbol);
927 if (i == sizeof(curkeytab) / sizeof(struct curkey) - 1) {
929 printf("%s", " (Unknown cursor key) ");
935 for (fkeymode = 0; fkeymode <= 3; fkeymode++) {
936 for (i = 0; fnkeytab[i].fnkeysymbol[0] != '\0'; i++) {
937 cup(1 + 2 * fnkeytab[i].fnkeyrow, 1 + fnkeytab[i].fnkeycol);
939 printf("%s", fnkeytab[i].fnkeysymbol);
942 cup(20,1); printf("<%s>%20s", fnkeymodes[fkeymode], "");
944 cup(22,1); printf("%s", "Press each function key. Finish with TAB.");
947 if (fkeymode >= 2) rm("?2"); /* VT52 mode */
948 if (fkeymode % 2) deckpam(); /* Application mode */
949 else deckpnm(); /* Numeric mode */
951 esc("<"); /* ANSI mode */
953 cup(23,1); chrprint(fnkeystr);
954 if (!strcmp(fnkeystr,"\t")) break;
955 for (i = 0; fnkeytab[i].fnkeysymbol[0] != '\0'; i++) {
956 if (!strcmp(fnkeystr,fnkeytab[i].fnkeymsg[fkeymode])) {
958 printf(" (%s key) ", fnkeytab[i].fnkeyname);
960 cup(1 + 2 * fnkeytab[i].fnkeyrow, 1 + fnkeytab[i].fnkeycol);
961 printf("%s", fnkeytab[i].fnkeysymbol);
965 if (i == sizeof(fnkeytab) / sizeof(struct fnkey) - 1) {
967 printf("%s", " (Unknown function key) ");
973 sgttyNew.sg_flags |= CRMOD;
977 println("Finally, a check of the ANSWERBACK MESSAGE, which can be sent");
978 println("by pressing CTRL-BREAK. The answerback message can be loaded");
979 println("in SET-UP B by pressing SHIFT-A and typing e.g.");
981 println(" \" H e l l o , w o r l d Return \"");
983 println("(the double-quote characters included). Do that, and then try");
984 println("to send an answerback message with CTRL-BREAK. If it works,");
985 println("the answerback message should be displayed in reverse mode.");
986 println("Finish with a single RETURN.");
988 sgttyNew.sg_flags &= ~CRMOD;
997 } while (strcmp(abmstr,"\r"));
1000 for (i = 0; i < 32; i++) {
1001 cup(1 + (i % 16), 1 + 40 * (i / 16));
1003 printf("%s", ckeytab[i].csymbol);
1007 sgttyNew.sg_flags |= CRMOD;
1010 "Push each CTRL-key TWICE. Note that you should be able to send *all*");
1012 "CTRL-codes twice, including CTRL-S (X-Off) and CTRL-Q (X-Off)!");
1014 "Finish with DEL (also called DELETE or RUB OUT), or wait 1 minute.");
1015 sgttyNew.sg_flags |= RAW;
1019 cup(23,1); kbdc = inchar();
1021 if (kbdc < 32) printf(" %s", ckeytab[kbdc].csymbol);
1023 sprintf(kbds, "%c", kbdc);
1025 printf("%s", " -- not a CTRL key");
1027 if (kbdc < 32) ckeytab[kbdc].ccount++;
1028 if (ckeytab[kbdc].ccount == 2) {
1029 cup(1 + (kbdc % 16), 1 + 40 * (kbdc / 16));
1030 printf("%s", ckeytab[kbdc].csymbol);
1032 } while (kbdc != '\177');
1033 sgttyNew.sg_flags &= ~RAW;
1034 sgttyNew.sg_flags |= ECHO;
1039 for (i = 0; i < 32; i++) if (ckeytab[i].ccount < 2) okflag = 0;
1040 if (okflag) printf("%s", "OK. ");
1041 else printf("%s", "You have not been able to send all CTRL keys! ");
1047 <ENQ> (AnswerBack Message)
1048 SM RM (Set/Reset Mode) - LineFeed / Newline
1049 DSR (Device Status Report)
1050 DA (Device Attributes)
1051 DECREQTPARM (Request Terminal Parameters)
1054 int parity, nbits, xspeed, rspeed, clkmul, flags;
1056 char *report, *report2;
1057 static char *attributes[][2] = {
1058 { "\033[?1;0c", "No options (vanilla VT100)" },
1059 { "\033[?1;1c", "VT100 with STP" },
1060 { "\033[?1;2c", "VT100 with AVO (could be a VT102)" },
1061 { "\033[?1;3c", "VT100 with STP and AVO" },
1062 { "\033[?1;4c", "VT100 with GPO" },
1063 { "\033[?1;5c", "VT100 with STP and GPO" },
1064 { "\033[?1;6c", "VT100 with AVO and GPO" },
1065 { "\033[?1;7c", "VT100 with STP, AVO and GPO" },
1066 { "\033[?1;11c", "VT100 with PP and AVO" },
1067 { "\033[?1;15c", "VT100 with PP, GPO and AVO" },
1068 { "\033[?4;2c", "VT132 with AVO" },
1069 { "\033[?4;3c", "VT132 with AVO and STP" },
1070 { "\033[?4;6c", "VT132 with GPO and AVO" },
1071 { "\033[?4;7c", "VT132 with GPO, AVO, and STP" },
1072 { "\033[?4;11c", "VT132 with PP and AVO" },
1073 { "\033[?4;15c", "VT132 with PP, GPO and AVO" },
1074 { "\033[?7c", "VT131" },
1075 { "\033[?12;5c", "VT125" }, /* VT125 also has ROM version */
1076 { "\033[?12;7c", "VT125 with AVO" }, /* number, so this won't work */
1077 { "\033[?5;0c", "VK100 (GIGI)" },
1078 { "\033[?5c", "VK100 (GIGI)" },
1082 sgttyNew.sg_flags &= ~ECHO;
1085 println("This is a test of the ANSWERBACK MESSAGE. (To load the A.B.M.");
1086 println("see the TEST KEYBOARD part of this program). Below here, the");
1087 println("current answerback message in your terminal should be");
1088 println("displayed. Finish this test with RETURN.");
1091 printf("%c", 5); /* ENQ */
1100 println("Test of LineFeed/NewLine mode.");
1103 sgttyNew.sg_flags &= ~CRMOD;
1105 printf("NewLine mode set. Push the RETURN key: ");
1110 if (!strcmp(report, "\015\012")) printf(" -- OK");
1111 else printf(" -- Not expected");
1114 printf("NewLine mode reset. Push the RETURN key: ");
1119 if (!strcmp(report, "\015")) printf(" -- OK");
1120 else printf(" -- Not expected");
1122 sgttyNew.sg_flags |= CRMOD;
1128 printf("Test of Device Status Report 5 (report terminal status).");
1134 printf("Report is: ");
1136 if (!strcmp(report,"\033[0n")) printf(" -- means \"TERMINAL OK\"");
1137 else if (!strcmp(report,"\033[3n")) printf(" -- means \"TERMINAL OK\"");
1138 else printf(" -- Unknown response!");
1141 println("Test of Device Status Report 6 (report cursor position).");
1147 printf("Report is: ");
1149 if (!strcmp(report,"\033[5;1R")) printf(" -- OK");
1150 else printf(" -- Unknown response!");
1153 println("Test of Device Attributes report (what are you)");
1159 printf("Report is: ");
1161 for (i = 0; *attributes[i][0] != '\0'; i++) {
1162 if (!strcmp(report,attributes[i][0])) break;
1164 if (*attributes[i][0] == '\0')
1165 printf(" -- Unknown response, refer to the manual");
1167 printf(" -- means %s", attributes[i][1]);
1170 println("Legend: STP = Processor Option");
1171 println(" AVO = Advanced Video Option");
1172 println(" GPO = Graphics Processor Option");
1173 println(" PP = Printer Port");
1178 println("Test of the \"Request Terminal Parameters\" feature, argument 0.");
1184 printf("Report is: ");
1186 if (strlen(report) < 16
1187 || report[0] != '\033'
1190 || report[3] != ';')
1191 println(" -- Bad format");
1194 parity = scanto(report, &reportpos, ';');
1195 nbits = scanto(report, &reportpos, ';');
1196 xspeed = scanto(report, &reportpos, ';');
1197 rspeed = scanto(report, &reportpos, ';');
1198 clkmul = scanto(report, &reportpos, ';');
1199 flags = scanto(report, &reportpos, 'x');
1200 if (parity == 0 || nbits == 0 || clkmul == 0) println(" -- Bad format");
1201 else println(" -- OK");
1203 "This means: Parity %s, %s bits, xmitspeed %s, recvspeed %s.\n",
1204 lookup(paritytable, parity),
1205 lookup(nbitstable, nbits),
1206 lookup(speedtable, xspeed),
1207 lookup(speedtable, rspeed));
1208 printf("(CLoCk MULtiplier = %d, STP option flags = %d)\n", clkmul, flags);
1212 println("Test of the \"Request Terminal Parameters\" feature, argument 1.");
1214 decreqtparm(1); /* Does the same as decreqtparm(0), reports "3" */
1218 printf("Report is: ");
1220 if (strlen(report2) < 3
1221 || report2[2] != '3')
1222 println(" -- Bad format");
1225 if (!strcmp(report,report2)) println(" -- OK");
1226 else println(" -- Bad format");
1230 sgttyNew.sg_flags |= ECHO;
1236 static struct rtabl {
1240 { "\033/K", " -- OK (means Standard VT52)" },
1241 { "\033/Z", " -- OK (means VT100 emulating VT52)" },
1242 { "", " -- Unknown response"}
1248 rm("?2"); /* Reset ANSI (VT100) mode, Set VT52 mode */
1249 esc("H"); /* Cursor home */
1250 esc("J"); /* Erase to end of screen */
1251 esc("H"); /* Cursor home */
1252 for (i = 0; i <= 23; i++) {
1253 for (j = 0; j <= 9; j++)
1254 printf("%s", "FooBar ");
1257 esc("H"); /* Cursor home */
1258 esc("J"); /* Erase to end of screen */
1261 printf("nothing more.");
1262 for (i = 1; i <= 10; i++) printf("THIS SHOULD GO AWAY! ");
1263 for (i = 1; i <= 5; i++) {
1265 printf("%s", "Back scroll (this should go away)");
1266 esc("I"); /* Reverse LineFeed (with backscroll!) */
1269 esc("J"); /* Erase to end of screen */
1270 for (i = 2; i <= 6; i++) {
1272 esc("K"); /* Erase to end of line */
1275 for (i = 2; i <= 23; i++) {
1276 vt52cup(i,70); printf("%s", "**Foobar");
1279 for (i = 23; i >= 2; i--) {
1281 printf("%c", 8); /* BS */
1282 esc("I"); /* Reverse LineFeed (LineStarve) */
1285 for (i = 70; i >= 10; i--) {
1287 esc("D"); esc("D"); /* Cursor Left */
1290 for (i = 10; i <= 70; i++) {
1292 printf("%c", 8); /* BS */
1293 esc("C"); /* Cursor Right */
1296 for (i = 2; i <= 23; i++) {
1298 printf("%c", 8); /* BS */
1299 esc("B"); /* Cursor Down */
1302 for (i = 23; i >= 2; i--) {
1304 printf("%c", 8); /* BS */
1305 esc("A"); /* Cursor Up */
1307 for (i = 2; i <= 23; i++) {
1309 esc("K"); /* Erase to end of line */
1313 printf("%s", "The screen should be cleared, and have a centered");
1315 printf("%s", "rectangle of \"*\"s with \"!\"s on the inside to the");
1317 printf("%s", "left and right. Only this, and");
1321 esc("H"); /* Cursor home */
1322 esc("J"); /* Erase to end of screen */
1323 printf("%s", "This is the normal character set:");
1324 for (j = 0; j <= 1; j++) {
1326 for (i = 0; i <= 47; i++)
1327 printf("%c", 32 + i + 48 * j);
1330 printf("%s", "This is the special graphics character set:");
1331 esc("F"); /* Select Special Graphics character set */
1332 for (j = 0; j <= 1; j++) {
1334 for (i = 0; i <= 47; i++)
1335 printf("%c", 32 + i + 48 * j);
1337 esc("G"); /* Select ASCII character set */
1341 esc("H"); /* Cursor home */
1342 esc("J"); /* Erase to end of screen */
1343 println("Test of terminal response to IDENTIFY command");
1344 esc("Z"); /* Identify */
1347 printf("Response was");
1348 esc("<"); /* Enter ANSI mode (VT100 mode) */
1350 for(i = 0; resptable[i].rcode[0] != '\0'; i++)
1351 if (!strcmp(response, resptable[i].rcode))
1353 printf("%s", resptable[i].rmsg);
1362 SM/RM(4) (= IRM (Insertion/replacement mode))
1363 ICH (Insert Character)
1364 DCH (Delete character)
1369 int i, row, col, sw, dblchr, scr132;
1371 for(scr132 = 0; scr132 <= 1; scr132++) {
1372 if (scr132) { sm("?3"); sw = 132; }
1373 else { rm("?3"); sw = 80; }
1376 for (row=1; row<=24; row++) {
1378 for (col=1; col<=sw; col++)
1379 printf("%c", 'A'-1+row);
1382 printf("Screen accordion test (Insert & Delete Line). "); holdit();
1387 for (row=1; row<=24; row++) {
1395 "Top line: A's, bottom line: X's, this line, nothing more. ");
1402 for (col=2; col<=sw-1; col++)
1406 printf("Test of 'Insert Mode'. The top line should be 'A*** ... ***B'. ");
1407 holdit(); ri(); el(2);
1411 printf("Test of 'Delete Character'. The top line should be 'AB'. ");
1414 for(dblchr = 1; dblchr <= 2; dblchr++) {
1416 for (row=1; row<=24; row++) {
1418 if (dblchr == 2) decdwl();
1419 for (col=1; col<=sw/dblchr; col++)
1420 printf("%c", 'A'-1+row);
1421 cup(row,sw/dblchr-row);
1425 println("The right column should be staggered ");
1431 println("If your terminal has the ANSI 'Insert Character' function");
1432 println("(the VT102 does not), then you should see a line like this");
1433 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");
1436 for (i = 'Z'; i >= 'A'; i--) {
1443 if (sw == 132) rm("?3");
1447 dch(pn) int pn; { brc(pn, 'P'); } /* Delete character */
1448 ich(pn) int pn; { brc(pn, '@'); } /* Insert character -- not in VT102 */
1449 dl(pn) int pn; { brc(pn, 'M'); } /* Delete line */
1450 il(pn) int pn; { brc(pn, 'L'); } /* Insert line */
1452 /* Test of some known VT100 bugs and misfeatures */
1458 static char *menutable[] = {
1459 "Exit to main menu",
1460 "Bug A: Smooth scroll to jump scroll",
1461 "Bug B: Scrolling region",
1462 "Bug C: Wide to narrow screen",
1463 "Bug D: Narrow to wide screen",
1464 "Bug E: Cursor move from double- to single-wide line",
1465 "Bug F: Column mode escape sequence",
1466 "Wrap around with cursor addressing",
1467 "Erase right half of double width lines",
1468 "Funny scroll regions",
1473 static char *hmsg[] = {
1474 "Test of known bugs in the DEC VT100 series. The numbering of some of",
1475 "the bugs (A-F) refers to the article 'VT100 MAGIC' by Sami Tabih in",
1476 "the 'Proceedings of the DEC Users Society' at St. Louis, Missouri, May",
1477 "1983. To understand some of the tests, you have to look at the source",
1478 "code or the article. Of course, a good VT100-compatible terminal",
1479 "should not have these bugs (or have some means of disabling them)! If",
1480 "a bug appears, you might want to RESET the terminal before continuing",
1481 "the test. There is a test of the RESET function in the main menu.",
1486 for (i = 0; *hmsg[i]; i++) println(hmsg[i]);
1488 println(" Choose bug test number:");
1489 menuchoice = menu(menutable);
1490 switch (menuchoice) {
1491 case 1: bug_a(); break;
1492 case 2: bug_b(); break;
1493 case 3: bug_c(); break;
1494 case 4: bug_d(); break;
1495 case 5: bug_e(); break;
1496 case 6: bug_f(); break;
1497 case 7: bug_w(); break;
1498 case 8: bug_l(); break;
1499 case 9: bug_s(); break;
1501 } while (menuchoice);
1504 /* Bug A: Smooth scroll to jump scroll */
1510 println("This is a test of the VT100 'Scroll while toggle softscroll'");
1511 println("bug. The cursor may disappear, or move UP the screen, or");
1512 println("multiple copies of some lines may appear.");
1515 /* Invoke the bug */
1517 esc ("[24H"); /* Simplified cursor movement */
1518 rm("?4"); for (i = 1; i <= 20; i++) printf("\n");
1519 sm("?4"); for (i = 1; i <= 10; i++) printf("\n");
1520 rm("?4"); for (i = 1; i <= 5; i++) printf("\n");
1522 /* That should be enough to show the bug. But we'll try another way: */
1523 sm ("?4"); /* Set soft scroll */
1524 nel (); /* "NextLine", move down */
1525 rm ("?4"); /* Reset soft scroll */
1526 nel (); /* "NextLine", move down */
1527 for (i = 1; i <= 10; i++) { /* Show the bug */
1528 printf ("Softscroll bug test, line %d. ", i);
1531 println("That should have been enough to show the bug, if present.");
1535 /* Bug B: Scrolling region */
1542 printf("Line 11 should be double-wide, line 12 should be cleared.");
1544 printf("Then, the letters A-P should be written at the beginning");
1546 printf("of lines 12-24, and the empty line and A-E are scrolled away.");
1548 printf("If the bug is present, some lines are confused, look at K-P.");
1549 cup(11,1); decdwl();
1551 cup(12,1); el(0); printf("Here we go... "); holdit();
1552 cup(12,1); ri(); /* Bug comes here */
1553 for (c = 'A'; c <= 'P'; c++) printf("%c\n",c); /* Bug shows here */
1555 decstbm(0,0); /* No scr. region */
1558 /* Bug C: Wide to narrow screen */
1561 sm("?3"); /* 132 column mode */
1563 rm("?3"); /* 80 column mode */
1565 printf("Except for this line, the screen should be blank. ");
1569 /* Bug D: Narrow to wide screen */
1574 /* Make the bug appear */
1578 /* The original code in the article says
1579 * PRINT ESC$; "[13;1H"; CHR$(10%);
1580 * but I guess a cup(14,1); would do.
1581 * (To output a pure LF might be tricky).
1584 sm("?3"); /* Make the bug visible */
1586 println("You should see blinking text at the bottom line.");
1588 println("Enter 0 to exit, 1 to try to invoke the bug again.");
1589 cup(24,9); decdwl(); sgr("1;5;7");
1590 printf("If you can see this then the bug did not appear."); sgr("");
1592 result = inchar(); readnl();
1594 } while (result == '1');
1595 sm("?4"); /* Syrup scroll */
1597 for (i = 1; i <= 5; i++)
1598 println("If the bug is present, this should make things much worse!");
1600 rm("?4"); /* Jump scroll */
1603 /* Bug E: Cursor move from double- to single-wide line */
1607 static char *rend[2] = { "\033[m", "\033[7m" };
1610 println("This test should put an 'X' at line 3 column 100.");
1611 for (i = 1; i <= 12; i++) printf("1234567890%s",rend[i & 1]);
1612 cup(1,1); /* The bug appears when we jump from a dobule-wide line */
1613 cup(3,100); /* to a single-wide line, column > 66. */
1615 cup(4, 66); printf("! !");
1617 printf("--------------------------- The 'X' should NOT be above here -");
1618 printf("---+------------ but above here -----+");
1619 cup(10,1); decdwl(); holdit();
1623 /* Bug F: Column mode escape sequence */
1629 * VT100 "toggle origin mode, forget rest" bug. If you try to set
1630 * (or clear) parameters and one of them is the "origin mode"
1631 * ("?6") parameter, parameters that appear after the "?6"
1632 * remain unaffected. This is also true on CIT-101 terminals.
1634 sm ("?5"); /* Set reverse mode */
1635 sm ("?3"); /* Set 132 column mode */
1636 println("Test VT100 'Toggle origin mode, forget rest' bug, part 1.");
1637 println("The screen should be in reverse, 132 column mode.");
1640 rm ("?6;5;3"); /* Reset (origin, reverse, 132 col) */
1641 println("Test VT100 'Toggle origin mode, forget rest' bug, part 2.\n");
1642 println("The screen should be in non-reverse, 80 column mode.");
1647 * The dreaded "wraparound" bug! You CUP to col 80, write a char,
1648 * CUP to another line in col 80, write a char. And the brain-damaged
1649 * terminal thinks that "Hokay, so he's written a char in col 80, so
1650 * I stay in col 80 and wait for next character. Let's see now, here
1651 * comes another character, and I'm still in col 80, so I must make
1652 * a NewLine first." -- It doesn't clear that "still in col 80" flag
1660 println(" This illustrates the \"wrap around bug\" which exists on a");
1661 println(" standard VT100. At the top of the screen there should be");
1662 println(" a row of +'s, and the rightmost column should be filled");
1663 println(" with *'s. But if the bug is present, some of the *'s may");
1664 println(" be placed in other places, e.g. in the leftmost column,");
1665 println(" and the top line of +'s may be scrolled away.");
1668 for (col = 1; col <= 79; col++)
1670 for (row = 1; row <= 24; row++) {
1679 * Check if the right half of double-width lines comes back
1680 * when a line is first set to single-width, filled with stuff,
1681 * set to double-width, and finally reset to single-width.
1683 * A VT100 has this misfeature, and many others. Foo!
1688 printf("This-is-a-long-line-This-is-a-long-line-");
1689 printf("This-is-a-long-line-This-is-a-long-line-");
1691 printf("This is a test of what happens to the right half of double-width");
1693 printf("A common misfeature is that the right half does not come back");
1694 println(" when a long");
1695 printf("single-width line is set to double-width and then reset to");
1696 println(" single-width.");
1699 println("Now the line below should contain 80 characters in single width.");
1701 cup(15, 1); decdwl();
1703 println("Now the line below should contain 40 characters in double width.");
1705 cup(15, 1); decswl();
1707 println("Now the line below should contain 80 characters in single width.");
1710 /* ...and in 132 column mode */
1715 printf("This-is-a-long-line-This-is-a-long-line-");
1716 printf("This-is-a-long-line-This-is-a-long-line-");
1717 printf("This-is-a-long-line-This-is-a-long-line-");
1718 printf("ending-here-");
1721 printf("This is the same test in 132 column mode.");
1724 println("Now the line below should contain 132 characters in single width.");
1726 cup(15, 1); decdwl();
1728 println("Now the line below should contain 66 characters in double width.");
1730 cup(15, 1); decswl();
1732 println("Now the line below should contain 132 characters in single width.");
1739 decstbm(20,10); /* 20-10=-10, < 2, so no scroll region. */
1741 for (i=1; i<=20; i++)
1742 printf("This is 20 lines of text (line %d), no scroll region.\n", i);
1745 decstbm(0,1); /* Should be interpreted as decstbm(1,1) = none */
1747 for (i=1; i<=20; i++)
1748 printf("This is 20 lines of text (line %d), no scroll region.\n", i);
1750 decstbm(0,0); /* No scroll region (just in case...) */
1757 * - RIS (Reset to Initial State)
1758 * - DECTST (invoke terminal test)
1762 printf ("The terminal will now be RESET. ");
1766 zleep(5000); /* Wait 5.0 seconds */
1768 println("The terminal is now RESET. Next, the built-in confidence test");
1769 printf("%s", "will be invoked. ");
1774 zleep(5000); /* Wait 5.0 seconds */
1776 println("If the built-in confidence test found any errors, a code");
1777 printf("%s", "is visible above. ");
1781 initterminal(pn) int pn; {
1787 sgttyNew.sg_flags |= CBREAK;
1793 sgttyNew.sg_flags = sgttyOrg.sg_flags | CBREAK;
1796 /* Set up my personal prejudices */
1798 esc("<"); /* Enter ANSI mode (if in VT52 mode) */
1799 rm("?1"); /* cursor keys normal */
1800 rm("?3"); /* 80 col mode */
1801 rm("?4"); /* Jump scroll */
1802 rm("?5"); /* Normal screen */
1803 rm("?6"); /* Absolute origin mode */
1804 sm("?7"); /* Wrap around on */
1805 rm("?8"); /* Auto repeat off */
1806 decstbm(0,0); /* No scroll region */
1807 sgr("0"); /* Normal character attributes */
1812 /* Force my personal prejudices upon the poor luser */
1814 esc("<"); /* Enter ANSI mode (if in VT52 mode) */
1815 rm("?1"); /* cursor keys normal */
1816 rm("?3"); /* 80 col mode */
1817 rm("?5"); /* Normal screen */
1818 rm("?6"); /* Absolute origin mode */
1819 sm("?7"); /* Wrap around on */
1820 sm("?8"); /* Auto repeat on */
1821 decstbm(0,0); /* No scroll region */
1822 sgr("0"); /* Normal character attributes */
1828 printf("That's all, folks!\n");
1837 signal(SIGINT, onbrk);
1841 longjmp(intrenv, 1);
1846 signal(SIGTERM, onterm);
1847 longjmp(intrenv, 1);
1852 printf("Push <RETURN>");
1861 do { read(0,&ch,1); } while(ch != '\n' && !brkrd);
1863 kill(getpid(), SIGTERM);
1867 scanto(str, pos, toc) char *str; int *pos; char toc; {
1871 while (toc != (c = str[(*pos)++])) {
1872 if (isdigit(c)) result = result * 10 + c - '0';
1875 if (c == toc) return(result);
1879 char *lookup(t, k) struct table t[]; int k; {
1882 for (i = 0; t[i].key != -1; i++) {
1883 if (t[i].key == k) return(t[i].msg);
1885 return("BAD VALUE");
1888 menu(table) char *table[]; {
1890 int i, tablesize, choice;
1896 for (i = 0; *table[i] != '\0'; i++) {
1897 printf(" %d. %s\n", i, table[i]);
1902 printf("\n Enter choice number (0 - %d): ", tablesize);
1906 while (c = *s++) choice = 10 * choice + c - '0';
1907 if (choice >= 0 && choice <= tablesize) {
1911 printf(" Bad choice, try again: ");
1915 chrprint (s) char *s; {
1922 for (i = 0; s[i] != '\0'; i++) {
1923 if (s[i] <= ' ' || s[i] == '\177')
1924 printf("<%d> ", s[i]);
1925 else printf("%c ", s[i]);