ast@cs.vu.nl (Andy Tanenbaum) (10/06/87)
64a65 > #define MAX_ESC_PARMS 2 /* number of escape sequence parameters allowed */ 74,75c75,80 < #define DEL_CODE (char) 83 /* DEL for use in CTRL-ALT-DEL reboot */ < #define AT_SIGN 0220 /* code to yield for CTRL-@ */ --- > #define AT_SIGN 0220 /* code to yield for CTRL-@ */ > #define SCODE1 71 /* scan code for Home on numeric pad */ > #define SCODE2 81 /* scan code for PgDn on numeric pad */ > #define DEL_CODE (char) 83 /* DEL for use in CTRL-ALT-DEL reboot */ > #define ESC (char) 033 /* escape */ > #define BRACKET '[' /* Part of the ESC [ letter escape seq */ 79c84,85 < #define F10 68 /* scan code for function key F9 */ --- > #define F9 67 /* scan code for function key F9 */ > #define F10 68 /* scan code for function key F10 */ 95,96c101,104 < char tty_esc_state; /* 0=normal, 1 = ESC seen, 2 = ESC + x seen */ < char tty_echar; /* first character following an ESC */ --- > char tty_esc_state; /* 0=normal, 1=ESC, 2=ESC[ */ > char tty_esc_intro; /* Distinguishing character following ESC */ > int tty_esc_parmv[MAX_ESC_PARMS]; /* list of escape parameters */ > int *tty_esc_parmp; /* pointer to current escape parameter */ 103c111 < int tty_row; /* current row (0 at bottom of screen) */ --- > int tty_row; /* current row (0 at top of screen) */ 152,153c160,164 < PUBLIC int color; /* 1 if console is color, 0 if it is mono */ < PUBLIC scan_code; /* scan code for '=' saved by bootstrap */ --- > PRIVATE caps_off = 1; /* 1 = normal position, 0 = depressed */ > PRIVATE num_off = 1; /* 1 = normal position, 0 = depressed */ > PUBLIC int color; /* 1 if console is color, 0 if it is mono */ > PUBLIC scan_code; /* scan code for '=' saved by bootstrap */ > 162c173 < ,0261, 0262,0263,'0',0177 --- > ,0261,0262,0263,'0',0177 172c183 < '2','3','0',177 --- > '2','3','0','.' 197a209 > char scode_map[] = {'H', 'A', 'V', 'S', 'D', 'G', 'C', 'T', 'Y', 'B', 'U'}; 290,291c302,305 < int mode, sig; < char make_break(); --- > int mode, sig, scode; > char make_break(); > > scode = ch; /* save the scan code */ 312,315c326,330 < chuck(tp); /* remove last char entered */ < echo(tp, '\b'); /* remove it from the screen */ < echo(tp, ' '); < echo(tp, '\b'); --- > if (chuck(tp) != -1) { /* remove last char entered */ > echo(tp, '\b'); /* remove it from the screen */ > echo(tp, ' '); > echo(tp, '\b'); > } 362,368c377 < tp->tty_inhibited = RUNNING; /* do implied CRTL-Q */ < finish(tp, EINTR); /* send reply */ < tp->tty_inhead = tp->tty_inqueue; /* discard input */ < tp->tty_intail = tp->tty_inqueue; < tp->tty_incount = 0; < tp->tty_lfct = 0; < cause_sig(LOW_USER + 1 + line, sig); --- > sigchar(tp, line, sig); 387a397,414 > > /* The numeric pad generates ASCII escape sequences: ESC [ letter */ > if (scode >= SCODE1 && scode <= SCODE2 && > shift1 == 0 && shift2 == 0 && numlock == 0 ) { > /* This key is to generate a three-character escape sequence. */ > *tp->tty_inhead++ = ESC; /* put ESC in the input queue */ > if (tp->tty_inhead == &tp->tty_inqueue[TTY_IN_BYTES]) > tp->tty_inhead = tp->tty_inqueue; /* handle wraparound */ > tp->tty_incount++; > echo(tp, 'E'); > *tp->tty_inhead++ = BRACKET; /* put ESC in the input queue */ > if (tp->tty_inhead == &tp->tty_inqueue[TTY_IN_BYTES]) > tp->tty_inhead = tp->tty_inqueue; /* handle wraparound */ > tp->tty_incount++; > echo(tp, BRACKET); > ch = scode_map[scode-SCODE1]; /* generate the letter */ > } > 415,422c442,451 < code = (shift1 || shift2 || capslock ? sh[c] : unsh[c]); < if (control && c < TOP_ROW) code = sh[c]; /* CTRL-(top row) */ < if (c > 70 && numlock) code = sh[c]; /* numlock depressed */ < } else { < /* (Olivetti M24 or AT&T 6300) with Olivetti-style keyboard. */ < code = (shift1 || shift2 || capslock ? m24[c] : unm24[c]); < if (control && c < TOP_ROW) code = sh[c]; /* CTRL-(top row) */ < if (c > 70 && numlock) code = m24[c]; /* numlock depressed */ --- > code = (shift1 || shift2 ? sh[c] : unsh[c]); > if (control && c < TOP_ROW) code = sh[c]; /* CTRL-(top row) */ > if (c > 70 && numlock) /* numlock depressed */ > code = (shift1 || shift2 ? unsh[c] : sh[c]); > } else { > /* (Olivetti M24 or AT&T 6300) with Olivetti-style keyboard. */ > code = (shift1 || shift2 ? m24[c] : unm24[c]); > if (control && c < TOP_ROW) code = sh[c]; /* CTRL-(top row) */ > if (c > 70 && numlock) /* numlock depressed */ > code = (shift1 || shift2 ? unm24[c] : m24[c]); 426a456,460 > if (capslock) > if (code >= 'A' && code <= 'Z') > code += 'a' - 'A'; > else if (code >= 'a' && code <= 'z') > code -= 'a' - 'A'; 440,441c474,479 < case 4: if (make) capslock = 1 - capslock; break; /* caps lock */ < case 5: if (make) numlock = 1 - numlock; break; /* num lock */ --- > case 4: if (make && caps_off) capslock = 1 - capslock; > caps_off = 1 - make; > break; /* caps lock */ > case 5: if (make && num_off) numlock = 1 - numlock; > num_off = 1 - make; > break; /* num lock */ 755a794,813 > /*===========================================================================* > * sigchar * > *===========================================================================*/ > PRIVATE sigchar(tp, line, sig) > register struct tty_struct *tp; /* pointer to tty_struct */ > int line; /* line on which signal arrived */ > int sig; /* SIGINT, SIGQUIT, or SIGKILL */ > { > /* Process a SIGINT, SIGQUIT or SIGKILL char from the keyboard */ > > tp->tty_inhibited = RUNNING; /* do implied CRTL-Q */ > finish(tp, EINTR); /* send reply */ > tp->tty_inhead = tp->tty_inqueue; /* discard input */ > tp->tty_intail = tp->tty_inqueue; > tp->tty_incount = 0; > tp->tty_lfct = 0; > cause_sig(LOW_USER + 1 + line, sig); > } > > 792a851 > #define EGA 0x3C0 /* port for EGA card */ 833c892 < * The shift-type keys, 29, 42, 54, 56, and 69 must be processed normally. --- > * The shift-type keys, 29, 42, 54, 56, 58, and 69 must be processed normally. 838c897 < if (k != 29 && k != 42 && k != 54 && k != 56 && k != 69) { --- > if (k != 29 && k != 42 && k != 54 && k != 56 && k != 58 && k != 69) { 926,936c985,988 < /* Output a character on the console. Check for escape sequences, including < * ESC 32+x 32+y to move cursor to (x, y) < * ESC ~ 0 to clear from cursor to end of screen < * ESC ~ 1 to reverse scroll the screen 1 line < * ESC z x to set the attribute byte to x (z is a literal here) < */ < < /* Check to see if we are part way through an escape sequence. */ < if (tp->tty_esc_state == 1) { < tp->tty_echar = c; < tp->tty_esc_state = 2; --- > /* Output a character on the console. Check for escape sequences first. */ > > if (tp->tty_esc_state > 0) { > parse_escape(tp, c); 940,945d991 < if (tp->tty_esc_state == 2) { < escape(tp, tp->tty_echar, c); < tp->tty_esc_state = 0; < return; < } < 953c999 < move_to(tp, tp->tty_column, tp->tty_row + 1); --- > move_to(tp, tp->tty_column, tp->tty_row - 1); 970,973c1016,1019 < if (tp->tty_row == 0) < scroll_screen(tp, GO_FORWARD); < else < tp->tty_row--; --- > if (tp->tty_row == SCR_LINES-1) > scroll_screen(tp, GO_FORWARD); > else > tp->tty_row++; 988c1034 < /* Ignore tab is XTABS is off--video RAM has no hardware tab */ --- > /* Ignore tab if XTABS is off--video RAM has no hardware tab */ 999c1045 < tp->tty_ramqueue[tp->tty_rwords++] = tp->tty_attribute | c; --- > tp->tty_ramqueue[tp->tty_rwords++]=tp->tty_attribute|(c & BYTE); 1005d1050 < 1013,1014c1058,1072 < int amount, offset; < --- > int amount, offset, bytes; > > bytes = 2 * (SCR_LINES - 1) * LINE_WIDTH; /* 2 * 24 * 80 bytes */ > #ifdef SOFTSCROLL > /* Software scrolling for non-IBM compatible EGA cards. */ > if (dir == GO_FORWARD) { > scr_up(vid_base); > vid_copy(NIL_PTR, vid_base, > tp->tty_org+bytes, LINE_WIDTH); > } else { > scr_down(vid_base); > vid_copy(NIL_PTR, vid_base, tp->tty_org, LINE_WIDTH); > } > #else > /* Normal scrolling using the 6845 registers. */ 1018c1076 < offset = (tp->tty_org + 2 * (SCR_LINES - 1) * LINE_WIDTH) & vid_mask; --- > offset = (tp->tty_org + bytes) & vid_mask; 1024a1083 > #endif 1052c1111 < int y; /* row (0 <= y <= 24, 0 at bottom) */ --- > int y; /* row (0 <= y <= 24, 0 at top) */ 1060c1119 < tp->tty_vid = (tp->tty_org + 2*(SCR_LINES-1-y)*LINE_WIDTH + 2*x); --- > tp->tty_vid = (tp->tty_org + 2*y*LINE_WIDTH + 2*x); 1068,1104c1127,1237 < PRIVATE escape(tp, x, y) < register struct tty_struct *tp; /* pointer to tty struct */ < char x; /* escape sequence is ESC x y; this is x */ < char y; /* escape sequence is ESC x y; this is y */ < { < /* Handle an escape sequence. */ < < int n, ct, vx; < < < /* Check for ESC z attribute - used to change attribute byte. */ < if (x == 'z') { < /* Set attribute byte */ < tp->tty_attribute = y << 8; < return; < } < /* Check for ESC ~ n - used for clear screen, reverse scroll. */ < if (x == '~') { < if (y == '0') { < /* Clear from cursor to end of screen */ < n = 2 * LINE_WIDTH * (tp->tty_row + 1) - 2 * tp->tty_column; < vx = tp->tty_vid; < while (n > 0) { < ct = MIN(n, vid_retrace); < vid_copy(NIL_PTR, vid_base, vx, ct/2); < vx += ct; < n -= ct; < } < } else if (y == '1') { < /* Reverse scroll. */ < scroll_screen(tp, GO_BACKWARD); < } < return; < } < < /* Must be cursor movement (or invalid). */ < move_to(tp, x - 32, y - 32); --- > > PRIVATE parse_escape(tp, c) > register struct tty_struct *tp; /* pointer to tty struct */ > char c; /* next character in escape sequence */ > { > /* The following ANSI escape sequences are currently supported: > * ESC M to reverse index the screen > * ESC [ y ; x H to move cursor to (x, y) [default (1,1)] > * ESC [ 0 J to clear from cursor to end of screen > * ESC [ n m to set the screen rendition > * n: 0 = normal [default] > * 7 = reverse > */ > > switch (tp->tty_esc_state) { > case 1: /* ESC seen */ > tp->tty_esc_intro = '\0'; > tp->tty_esc_parmp = tp->tty_esc_parmv; > tp->tty_esc_parmv[0] = tp->tty_esc_parmv[1] = 0; > switch (c) { > case '[': /* Control Sequence Introducer */ > tp->tty_esc_intro = c; > tp->tty_esc_state = 2; > break; > case 'M': /* Reverse Index */ > do_escape(tp, c); > break; > default: > tp->tty_esc_state = 0; > break; > } > break; > > case 2: /* ESC [ seen */ > if (c >= '0' && c <= '9') { > if (tp->tty_esc_parmp > < tp->tty_esc_parmv + MAX_ESC_PARMS) > *tp->tty_esc_parmp = > *tp->tty_esc_parmp * 10 + (c - '0'); > break; > } > else if (c == ';') { > if (++tp->tty_esc_parmp > < tp->tty_esc_parmv + MAX_ESC_PARMS) > *tp->tty_esc_parmp = 0; > break; > } > else { > do_escape(tp, c); > } > break; > default: /* illegal state */ > tp->tty_esc_state = 0; > break; > } > } > > PRIVATE do_escape(tp, c) > register struct tty_struct *tp; /* pointer to tty struct */ > char c; /* next character in escape sequence */ > { > int n, ct, vx; > > /* Handle a sequence beginning with just ESC */ > if (tp->tty_esc_intro == '\0') { > switch (c) { > case 'M': /* Reverse Index */ > if (tp->tty_row == 0) > scroll_screen(tp, GO_BACKWARD); > else > tp->tty_row--; > move_to(tp, tp->tty_column, tp->tty_row); > break; > default: break; > } > } > else > /* Handle a sequence beginning with ESC [ and parameters */ > if (tp->tty_esc_intro == '[') { > switch (c) { > case 'H': /* Position cursor */ > move_to(tp, > MAX(1, MIN(LINE_WIDTH, tp->tty_esc_parmv[1])) - 1, > MAX(1, MIN(SCR_LINES, tp->tty_esc_parmv[0])) - 1 ); > break; > case 'J': /* Clear from cursor to end of screen */ > if (tp->tty_esc_parmv[0] == 0) { > n = 2 * ((SCR_LINES - (tp->tty_row + 1)) * LINE_WIDTH > + LINE_WIDTH - (tp->tty_column + 1)); > vx = tp->tty_vid; > while (n > 0) { > ct = MIN(n, vid_retrace); > vid_copy(NIL_PTR, vid_base, vx, ct/2); > vx += ct; > n -= ct; > } > } > break; > case 'm': /* Set graphic rendition */ > switch (tp->tty_esc_parmv[0]) { > case 7: tp->tty_attribute = 0160 << 8; > break; > default: tp->tty_attribute = 0007 << 8; > break; > } > break; > default: > break; > } > } > tp->tty_esc_state = 0; 1168a1302,1305 > /* Tell the EGA card, if any, to simulate a 16K CGA card. */ > port_out(EGA + INDEX, 4); /* register select */ > port_out(EGA + DATA, 1); /* no extended memory to be used */ > 1199c1336 < move_to(&tty_struct[0], 0, 0); /* move cursor to lower left corner */ --- > move_to(&tty_struct[0], 0, SCR_LINES-1); /* move cursor to lower left corner */ 1237,1238c1374,1377 < } < #endif --- > if (ch == F9) sigchar(&tty_struct[0], 0, SIGKILL); /* issue SIGKILL */ > } > #endif >