[comp.os.minix] Major improvement to 1.3 kernel

ast@cs.vu.nl (Andy Tanenbaum) (10/13/88)

Once again I had sealed the box with the 1.3 distribution.  This time I
even careful typed out the DHL airbill to send it off to P-H.  I was going
to send it off today.  Then I got Charles Hedrick's improvements to the
RS232/EGA code.  Since there is so much interest in getting this stuff
right, I once again unsealed the box and changed the code, including 
these new fixes.  I changed the buffer sizes slightly, to keep the kernel
size from becoming too unwieldly.  As is, it has grown by 2K, about 4K
of which is larger buffers (to prevent RS232 overrun at high speeds) and
-2K of which is simpler code.  I have tested it on 3 machines, and it seems to
be ok, but I would greatly appreciate it if more people could test it and
report back fast. I really want to get this thing out the door FAST.  Below
are cdif's for modified files (relative to the current 1.3, plus a new 
console.c, which was radically gutted).  I also enclosed the crc listing for
the kernel directory.  Nothing else has been changed.

To repeat, please apply these cdiffs to your current 1.3 system, test and
let me know about problems.

Andy Tanenbaum (ast@cs.vu.nl)

: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
: --------------------------- cut here --------------------------
PATH=/bin:/usr/bin:/usr/ucb
echo Extracting 'crc'
sed 's/^X//' > 'crc' << '+ END-OF-FILE ''crc'
X50110   3188 at_makefile
X64098  16075 at_wini.c
X11053   9335 clock.c
X01201  33549 console.c
X46559   2880 const.h
X09961   3543 dmp.c
X37030  26551 floppy.c
X39457    881 glo.h
X29135  26496 klib88.s
X01335  11156 main.c
X36060   5296 memory.c
X09331  13834 mpx88.s
X65108   3375 pc_makefile
X56408   9952 printer.c
X10507  13753 proc.c
X21644   2324 proc.h
X12176  18813 ps_wini.c
X59321  19053 rs232.c
X61988  19960 system.c
X38305   3634 table.c
X03407  28073 tty.c
X34455   7485 tty.h
X44806   4708 ttymaps.h
X27554    742 type.h
X14198  26433 xt_wini.c
+ END-OF-FILE crc
chmod 'u=rw,g=r,o=r' 'crc'
set `wc -c 'crc'`
count=$1
case $count in
537)	:;;
*)	echo 'Bad character count in ''crc' >&2
		echo 'Count should be 537' >&2
esac
echo Extracting 'console.c'
sed 's/^X//' > 'console.c' << '+ END-OF-FILE ''console.c'
X/* Code and data for the IBM console driver. */
X
X#include "../h/const.h"
X#include "../h/type.h"
X#include "../h/callnr.h"
X#include "../h/com.h"
X#include "../h/error.h"
X#include "../h/sgtty.h"
X#include "../h/signal.h"
X#include "const.h"
X#include "type.h"
X#include "glo.h"
X#include "proc.h"
X#include "tty.h"
X
Xextern char alt_c[], unsh[], sh[], unm24[], m24[];
Xextern char dutch_unsh[], dutch_sh[], dutch_alt[];
Xextern char unsh_usx[], sh_usx[], scode_map[];
X
X/* Definitions used by the console driver. */
X#define COLOR_BASE    0xB800	/* video ram paragraph for color display */
X#define MONO_BASE     0xB000	/* video ram address for mono display */
X#define C_VID_MASK    0x3FFF	/* mask for 16K video RAM */
X#define M_VID_MASK    0x0FFF	/* mask for  4K video RAM */
X#define C_RETRACE     0x0300	/* how many characters to display at once */
X#define M_RETRACE     0x7000	/* how many characters to display at once */
X#define BEEP_FREQ     0x0533	/* value to put into timer to set beep freq */
X#define B_TIME		   3	/* length of CTRL-G beep is ticks */
X#define BLANK         0x0700	/* determines  cursor color on blank screen */
X#define LINE_WIDTH        80	/* # characters on a line */
X#define SCR_LINES         25	/* # lines on the screen */
X#define SCR_BYTES	8000	/* size video RAM. multiple of 2*LINE_WIDTH */
X#define CTRL_S            31	/* scan code for letter S (for CRTL-S) */
X#define MONOCHROME         1	/* value for tty_ioport tells color vs. mono */
X#define CONSOLE            0	/* line number for console */
X#define GO_FORWARD         0	/* scroll forward */
X#define GO_BACKWARD        1	/* scroll backward */
X#define TIMER2          0x42	/* I/O port for timer channel 2 */
X#define TIMER3          0x43	/* I/O port for timer channel 3 */
X#define KEYBD           0x60	/* I/O port for keyboard data */
X#define PORT_B          0x61	/* I/O port for 8255 port B */
X#define KBIT            0x80	/* bit used to ack characters to keyboard */
X#define LED_CODE        0xED	/* command to keyboard to set LEDs */
X#define LED_DELAY       0x80	/* device dependent delay needed */
X
X/* Constants relating to the video RAM and 6845. */
X#define M_6845         0x3B0	/* port for 6845 mono */
X#define C_6845         0x3D0	/* port for 6845 color */
X#define EGA            0x3C0	/* port for EGA card */
X#define INDEX              4	/* 6845's index register */
X#define DATA               5	/* 6845's data register */
X#define OVRFL_REG	   7    /* EGA overflow register */
X#define CUR_SIZE          10	/* 6845's cursor size register */
X#define VID_ORG           12	/* 6845's origin register */
X#define CURSOR            14	/* 6845's cursor register */
X#define LINE_CMP	0x18	/* EGA line compare register */
X
X/* Definitions used for determining if the keyboard is IBM or Olivetti type. */
X#define KB_STATUS	0x64	/* Olivetti keyboard status port */
X#define BYTE_AVAIL	0x01	/* there is something in KEYBD port */
X#define KB_BUSY	        0x02	/* KEYBD port ready to accept a command */
X#define DELUXE		0x01	/* this bit is set up iff deluxe keyboard */
X#define GET_TYPE	   5	/* command to get keyboard type */
X#define STANDARD_SCAN	  13
X#define OLIVETTI_SCAN     12	/* the '=' key is 12 on olivetti, 13 on IBM */
X#define DUTCH_EXT_SCAN	  32	/* scan code of 'd' */
X#define US_EXT_SCAN	  22	/* scan code of 'u' */
X#define SPACE_SCAN	  57	/* a space */
X#define PS_LED_DELAY    1200	/* delay for PS/2 */
X#define PS_KEYBD	0x68	/* I/O port for data on ps/2 */
X
X/* Scan codes to ASCII for IBM DUTCH extended keyboard */
X#define MINUS_DU      0x0035	/* scan code of '-' on Dutch extended keybd */
X#define NUM_SLASH_DU  0x0057	/* scan code of numeric keypad slash */
X
X#define ESCAPE_CODE   0x00E0	/* escape scan code */
X
X/* Global variables used by the console driver. */
XPUBLIC  message keybd_mess;	/* message used for console input chars */
XPUBLIC int vid_mask;		/* 037777 for color (16K) or 07777 for mono */
XPUBLIC int vid_port;		/* I/O port for accessing 6845 */
XPUBLIC int blank_color = 0x0700; /* display code for blank */
XPRIVATE vid_retrace;		/* how many characters to display per burst */
XPRIVATE unsigned vid_base;	/* base of video ram (0xB000 or 0xB800) */
XPRIVATE int esc;		/* escape scan code detected? */
X
X/* Map from ANSI colors to the attributes used by the PC */
XPRIVATE int ansi_colors[8] = {0, 4, 2, 6, 1, 5, 3, 7};
X
X/*===========================================================================*
X *				keyboard				     *
X *===========================================================================*/
XPUBLIC keyboard()
X{
X/* A keyboard interrupt has occurred.  Process it. */
X
X  int val, code, k, raw_bit;
X  char stopc;
X
X  /* Fetch the character from the keyboard hardware and acknowledge it. */
X  if (ps) {
X	port_in(PS_KEYBD, &code);	/* get the scan code for key struck */
X	ack_char();			/* acknowledge the character */
X  } else {
X	port_in(KEYBD, &code);	/* get the scan code for the key struck */
X	port_in(PORT_B, &val);	/* strobe the keyboard to ack the char */
X	port_out(PORT_B, val | KBIT);	/* strobe the bit high */
X	port_out(PORT_B, val);	/* now strobe it low */
X  }
X
X  /* The IBM keyboard interrupts twice per key, once when depressed, once when
X   * released.  Filter out the latter, ignoring all but the shift-type keys.
X   * The shift-type keys 29, 42, 54, 56, 58, and 69 must be processed normally.
X   */
X
X  if (keyb_type == DUTCH_EXT)
X	if (esc) {
X		/* Numeric slash gives scan codes 0xE0 0x35. */
X		if (code == minus_code) code = num_slash;
X		esc = FALSE;
X	} else 
X		esc = (code == ESCAPE_CODE);
X
X  k = code - 0200;		/* codes > 0200 mean key release */
X  if (k > 0) {
X	/* A key has been released. */
X	if (k != 29 && k != 42 && k != 54 && k != 56 && k != 58 && k != 69) {
X		port_out(INT_CTL, ENABLE);	/* re-enable interrupts */
X	 	return;		/* don't call tty_task() */
X	}
X  } else {
X	/* Check to see if character is CTRL-S, to stop output. Setting xoff
X	 * to anything other than CTRL-S will not be detected here, but will
X	 * be detected later, in the driver.  A general routine to detect any
X	 * xoff character here would be complicated since we only have the
X	 * scan code here, not the ASCII character.
X	 */
X	raw_bit = tty_struct[CONSOLE].tty_mode & RAW;
X	stopc = tty_struct[CONSOLE].tty_xoff;
X	if (raw_bit == 0 && control && code == CTRL_S && stopc == XOFF_CHAR) {
X		tty_struct[CONSOLE].tty_inhibited = STOPPED;
X		port_out(INT_CTL, ENABLE);
X		return;
X	}
X  }
X
X  /* Check for CTRL-ALT-DEL, and if found, reboot the computer. */
X  if (control && alt && code == DEL_CODE) reboot();	/* CTRL-ALT-DEL */
X
X  /* Store the character in memory so the task can get at it later.
X   * tty_driver_buf[0] is the current count, and tty_driver_buf[2] is the
X   * maximum allowed to be stored.
X   */
X  if ( (k = tty_buf_count(tty_driver_buf)) < tty_buf_max(tty_driver_buf)) {
X	/* There is room to store this character; do it. */
X	k = k + k;			/* each entry contains two bytes */
X	tty_driver_buf[k+4] = code;	/* store the scan code */
X	tty_driver_buf[k+5] = CONSOLE;	/* tell which line it came from */
X	tty_buf_count(tty_driver_buf)++;		/* increment counter */
X
X	/* Build and send the interrupt message. */
X	keybd_mess.m_type = TTY_CHAR_INT;
X	keybd_mess.ADDRESS = tty_driver_buf;
X	interrupt(TTY, &keybd_mess);	/* send a message to the tty task */
X  } else {
X	/* Too many characters have been buffered.  Discard excess. */
X	port_out(INT_CTL, ENABLE);	/* re-enable 8259A controller */
X  }
X}
X
X
X/*===========================================================================*
X *				console					     *
X *===========================================================================*/
XPRIVATE console(tp)
Xregister struct tty_struct *tp;	/* tells which terminal is to be used */
X{
X/* Copy as much data as possible to the output queue, then start I/O.  On
X * memory-mapped terminals, such as the IBM console, the I/O will also be
X * finished, and the counts updated.  Keep repeating until all I/O done.
X */
X
X  extern char get_byte();
X  int count;
X  char c;
X  unsigned segment, offset, offset1;
X
X  /* Loop over the user bytes one at a time, outputting each one. */
X  segment = (tp->tty_phys >> 4) & WORD_MASK;
X  offset = tp->tty_phys & OFF_MASK;
X  offset1 = offset;
X  count = 0;
X
X  while (tp->tty_outleft > 0 && tp->tty_inhibited == RUNNING) {
X	c = get_byte(segment, offset);	/* fetch 1 byte from user space */
X	out_char(tp, c);	/* write 1 byte to terminal */
X	offset++;		/* advance one character in user buffer */
X	tp->tty_outleft--;	/* decrement count */
X  }
X  flush(tp);			/* clear out the pending characters */
X
X  /* Update terminal data structure. */
X  count = offset - offset1;	/* # characters printed */
X  tp->tty_phys += count;	/* advance physical data pointer */
X  tp->tty_cum += count;		/* number of characters printed */
X
X  /* If all data has been copied to the terminal, send the reply. */
X  if (tp->tty_outleft == 0) finish(tp, tp->tty_cum);
X}
X
X
X/*===========================================================================*
X *				out_char				     *
X *===========================================================================*/
XPUBLIC out_char(tp, c)
Xregister struct tty_struct *tp;	/* pointer to tty struct */
Xchar c;				/* character to be output */
X{
X/* Output a character on the console.  Check for escape sequences first. */
X
X  if (tp->tty_esc_state > 0) {
X	parse_escape(tp, c);
X	return;
X  }
X
X  switch(c) {
X	case 000:		/* null is typically used for padding */
X		return;		/* better not do anything */
X	case 007:		/* ring the bell */
X		flush(tp);	/* print any chars queued for output */
X		beep(BEEP_FREQ);/* BEEP_FREQ gives bell tone */
X		return;
X
X	case 013:		/* CTRL-K */
X		move_to(tp, tp->tty_column, tp->tty_row - 1);
X		return;
X
X	case 014:		/* CTRL-L */
X		move_to(tp, tp->tty_column + 1, tp->tty_row);
X		return;
X
X	case 016:		/* CTRL-N */
X		move_to(tp, tp->tty_column + 1, tp->tty_row);
X		return;
X
X	case '\b':		/* backspace */
X		move_to(tp, tp->tty_column - 1, tp->tty_row);
X		return;
X
X	case '\n':		/* line feed */
X		if (tp->tty_mode & CRMOD) out_char(tp, '\r');
X		if (tp->tty_row == SCR_LINES-1)
X			scroll_screen(tp, GO_FORWARD);
X		else
X			tp->tty_row++;
X
X		move_to(tp, tp->tty_column, tp->tty_row);
X		return;
X
X	case '\r':		/* carriage return */
X		move_to(tp, 0, tp->tty_row);
X		return;
X
X	case '\t':		/* tab */
X		if ( (tp->tty_mode & XTABS) == XTABS) {
X			do {
X				out_char(tp, ' ');
X			} while (tp->tty_column & TAB_MASK);
X			return;
X		}
X		/* Ignore tab if XTABS is off--video RAM has no hardware tab */
X		return;
X
X	case 033:		/* ESC - start of an escape sequence */
X		flush(tp);	/* print any chars queued for output */
X		tp->tty_esc_state = 1;	/* mark ESC as seen */
X		return;
X
X	default:		/* printable chars are stored in ramqueue */
X#ifndef LINEWRAP
X		if (tp->tty_column >= LINE_WIDTH) return;	/* long line */
X#endif
X		if (tp->tty_rwords == TTY_RAM_WORDS) flush(tp);
X		tp->tty_ramqueue[tp->tty_rwords++]=tp->tty_attribute|(c&BYTE);
X		tp->tty_column++;	/* next column */
X#ifdef LINEWRAP
X 		if (tp->tty_column >= LINE_WIDTH) {
X 			flush(tp);
X 			if (tp->tty_row == SCR_LINES-1)
X 				scroll_screen(tp, GO_FORWARD);
X 			else
X 				tp->tty_row++;
X 			move_to(tp, 0, tp->tty_row);
X 		}
X#endif /* LINEWRAP */
X		return;
X  }
X}
X
X/*===========================================================================*
X *				scroll_screen				     *
X *===========================================================================*/
XPRIVATE scroll_screen(tp, dir)
Xregister struct tty_struct *tp;	/* pointer to tty struct */
Xint dir;			/* GO_FORWARD or GO_BACKWARD */
X{
X  int amount, offset, bytes, old_state;
X
X  flush(tp);
X  bytes = 2 * (SCR_LINES - 1) * LINE_WIDTH;	/* 2 * 24 * 80 bytes */
X
X  /* Scrolling the screen is a real nuisance due to the various incompatible
X   * video cards.  This driver supports hardware scrolling (mono and CGA cards)
X   * and software scrolling (EGA cards).
X   */
X  if (softscroll) {
X	/* Software scrolling for non-IBM compatible EGA cards. */
X	if (dir == GO_FORWARD) {
X		scr_up(vid_base, LINE_WIDTH * 2, 0,
X		       (SCR_LINES - 1) * LINE_WIDTH);
X		vid_copy(NIL_PTR, vid_base, tp->tty_org+bytes, LINE_WIDTH);
X	} else {
X		scr_down(vid_base,
X			 (SCR_LINES - 1) * LINE_WIDTH * 2 - 2,
X			 SCR_LINES * LINE_WIDTH * 2 - 2,
X			 (SCR_LINES - 1) * LINE_WIDTH);
X		vid_copy(NIL_PTR, vid_base, tp->tty_org, LINE_WIDTH);
X	}
X  } else if (ega) {
X	/* Use video origin, but don't assume the hardware can wrap */
X	if (dir == GO_FORWARD) {
X		/* after we scroll by one line, end of screen */
X		offset = tp->tty_org + (SCR_LINES + 1) * LINE_WIDTH * 2;
X		if (offset > vid_mask) {
X			scr_up(vid_base, tp->tty_org + LINE_WIDTH * 2, 0, 
X			       (SCR_LINES - 1) * LINE_WIDTH);
X			tp->tty_org = 0;
X		} else
X			tp->tty_org += 2 * LINE_WIDTH;
X		offset = tp->tty_org + bytes;
X	} else {  /* scroll backwards */
X		offset = tp->tty_org - 2 * LINE_WIDTH;
X		if (offset < 0) {
X			scr_down(vid_base, 
X			   tp->tty_org + (SCR_LINES - 1) * LINE_WIDTH * 2 - 2,
X			   vid_mask - 1,
X			   (SCR_LINES - 1) * LINE_WIDTH);
X			tp->tty_org = vid_mask + 1 - SCR_LINES*LINE_WIDTH * 2;
X		} else
X			tp->tty_org -= 2 * LINE_WIDTH;
X		offset = tp->tty_org;
X	}			
X	/* Blank the new line at top or bottom. */
X	vid_copy(NIL_PTR, vid_base, offset, LINE_WIDTH);
X	set_6845(VID_ORG, tp->tty_org >> 1);	/* 6845 thinks in words */
X  } else {
X	/* Normal scrolling using the 6845 registers. */
X	amount = (dir == GO_FORWARD ? 2 * LINE_WIDTH : -2 * LINE_WIDTH);
X	tp->tty_org = (tp->tty_org + amount) & vid_mask;
X	if (dir == GO_FORWARD)
X		offset = (tp->tty_org + bytes) & vid_mask;
X	else
X		offset = tp->tty_org;
X
X	/* Blank the new line at top or bottom. */
X	vid_copy(NIL_PTR, vid_base, offset, LINE_WIDTH);
X	set_6845(VID_ORG, tp->tty_org >> 1);	/* 6845 thinks in words */
X  }
X}
X
X/*===========================================================================*
X *				flush					     *
X *===========================================================================*/
XPUBLIC flush(tp)
Xregister struct tty_struct *tp;	/* pointer to tty struct */
X{
X/* Have the characters in 'ramqueue' transferred to the screen. */
X
X  if (tp->tty_rwords == 0) return;
X  vid_copy((char *)tp->tty_ramqueue, vid_base, tp->tty_vid, tp->tty_rwords);
X
X  /* Update the video parameters and cursor. */
X  tp->tty_vid = (tp->tty_vid + 2 * tp->tty_rwords);
X  set_6845(CURSOR, tp->tty_vid >> 1);	/* cursor counts in words */
X  tp->tty_rwords = 0;
X}
X
X
X/*===========================================================================*
X *				move_to					     *
X *===========================================================================*/
XPRIVATE move_to(tp, x, y)
Xstruct tty_struct *tp;		/* pointer to tty struct */
Xint x;				/* column (0 <= x <= 79) */
Xint y;				/* row (0 <= y <= 24, 0 at top) */
X{
X/* Move the cursor to (x, y). */
X
X  flush(tp);			/* flush any pending characters */
X  if (x < 0 || x >= LINE_WIDTH || y < 0 || y >= SCR_LINES) return;
X  tp->tty_column = x;		/* set x co-ordinate */
X  tp->tty_row = y;		/* set y co-ordinate */
X  tp->tty_vid = (tp->tty_org + 2*y*LINE_WIDTH + 2*x);
X
X  set_6845(CURSOR, tp->tty_vid >> 1);	/* cursor counts in words */
X}
X
X
X/*===========================================================================*
X *				parse_escape				     *
X *===========================================================================*/
XPRIVATE parse_escape(tp, c)
Xregister struct tty_struct *tp;	/* pointer to tty struct */
Xchar c;				/* next character in escape sequence */
X{
X/* The following ANSI escape sequences are currently supported.
X * If n and/or m are omitted, they default to 1.
X *   ESC [nA moves up n lines
X *   ESC [nB moves down n lines
X *   ESC [nC moves right n spaces
X *   ESC [nD moves left n spaces
X *   ESC [m;nH" moves cursor to (m,n)
X *   ESC [J clears screen from cursor
X *   ESC [K clears line from cursor
X *   ESC [nL inserts n lines ar cursor
X *   ESC [nM deletes n lines at cursor
X *   ESC [nP deletes n chars at cursor
X *   ESC [n@ inserts n chars at cursor
X *   ESC [nm enables rendition n (0=normal, 4=bold, 5=blinking, 7=reverse)
X *   ESC M scrolls the screen backwards if the cursor is on the top line
X */
X
X  switch (tp->tty_esc_state) {
X	case 1: 		/* ESC seen */
X		tp->tty_esc_intro = '\0';
X		tp->tty_esc_parmp = tp->tty_esc_parmv;
X		tp->tty_esc_parmv[0] = tp->tty_esc_parmv[1] = 0;
X		switch (c) {
X		  case '[': 	/* Control Sequence Introducer */
X			tp->tty_esc_intro = c;
X			tp->tty_esc_state = 2; 
X			break;
X		  case 'M': 	/* Reverse Index */
X			do_escape(tp, c);
X			break;
X		  default: 
X			tp->tty_esc_state = 0; 
X			break;
X		}
X		break;
X
X	case 2: 		/* ESC [ seen */
X		if (c >= '0' && c <= '9') {
X			if (tp->tty_esc_parmp 
X					< tp->tty_esc_parmv + MAX_ESC_PARMS)
X				*tp->tty_esc_parmp =
X				  *tp->tty_esc_parmp * 10 + (c - '0');
X			break;
X		}
X		else if (c == ';') {
X			if (++tp->tty_esc_parmp 
X					< tp->tty_esc_parmv + MAX_ESC_PARMS)
X				*tp->tty_esc_parmp = 0;
X			break;
X		}
X		else {
X			do_escape(tp, c);
X		}
X		break;
X	default:		/* illegal state */
X		tp->tty_esc_state = 0;
X		break;
X  }
X}
X
X/*===========================================================================*
X *				do_escape				     *
X *===========================================================================*/
XPRIVATE do_escape(tp, c)
Xregister struct tty_struct *tp;	/* pointer to tty struct */
Xchar c;				/* next character in escape sequence */
X{
X  int n, ct, vx, value, attr, src, dst, count, limit, m;
X
X  /* Some of these things hack on screen RAM, so it had better be up to date */
X  flush(tp);
X
X  /* Handle a sequence beginning with just ESC */
X  if (tp->tty_esc_intro == '\0') {
X	switch (c) {
X		case 'M':		/* Reverse Index */
X			if (tp->tty_row == 0)
X				scroll_screen(tp, GO_BACKWARD);
X			else
X				tp->tty_row--;
X			move_to(tp, tp->tty_column, tp->tty_row);
X			break;
X
X		default: break;
X	}
X  } else {
X	/* Handle a sequence beginning with ESC [ and parameters */
X	if (tp->tty_esc_intro == '[') {
X		value = tp->tty_esc_parmv[0];
X		attr = tp->tty_attribute;
X		switch (c) {
X		    case 'A': 		/* ESC [nA moves up n lines */
X			n = (value == 0 ? 1 : value);
X			move_to(tp, tp->tty_column, tp->tty_row - n);
X			break;
X
X	    	    case 'B':		/* ESC [nB moves down n lines */
X			n = (value == 0 ? 1 : value);
X			move_to(tp, tp->tty_column, tp->tty_row + n);
X			break;
X
X		    case 'C':		/* ESC [nC moves right n spaces */
X			n = (value == 0 ? 1 : value);
X			move_to(tp, tp->tty_column + n, tp->tty_row);
X			break;
X
X		    case 'D':		/* ESC [nD moves left n spaces */
X			n = (value == 0 ? 1 : value);
X			move_to(tp, tp->tty_column - n, tp->tty_row);
X			break;
X
X		    case 'H':		/* ESC [m;nH" moves cursor to (m,n) */
X			move_to(tp, MAX(1, MIN(LINE_WIDTH, 
X			    tp->tty_esc_parmv[1])) - 1,
X			    MAX(1, MIN(SCR_LINES, tp->tty_esc_parmv[0])) - 1 );
X			break;
X
X		    case 'J':		/* ESC [J clears screen from cursor */
X			if (value == 0) {
X				n=2*((SCR_LINES-(tp->tty_row+1))*LINE_WIDTH
X					      + LINE_WIDTH - (tp->tty_column));
X				vx = tp->tty_vid;
X				long_vid_copy(NIL_PTR,vid_base,vx,n/2);
X			}
X			break;
X
X		    case 'K':		/* ESC [K clears line from cursor */
X			if (value == 0) {
X				n = 2 * (LINE_WIDTH - (tp->tty_column));
X				vid_copy(NIL_PTR, vid_base, tp->tty_vid, n/2);
X			}
X			break;
X
X		    case 'L':		/* ESC [nL inserts n lines ar cursor */
X			n = value;
X			if (n < 1) n = 1;
X			if (n > (SCR_LINES - tp->tty_row)) 
X				n = SCR_LINES - tp->tty_row;
X
X			src = tp->tty_org+(SCR_LINES - n) * LINE_WIDTH * 2 - 2;
X			dst = tp->tty_org+SCR_LINES * LINE_WIDTH * 2 - 2;
X			count = (SCR_LINES - n - tp->tty_row) * LINE_WIDTH;
X			l_scr_down(vid_base, src, dst, count);
X			dst = tp->tty_org + tp->tty_row * LINE_WIDTH * 2;
X			long_vid_copy(NIL_PTR, vid_base, dst, n * LINE_WIDTH);
X			break;
X
X		    case 'M':		/* ESC [nM deletes n lines at cursor */
X			n = value;
X			if (n < 1) n = 1;
X			if (n > (SCR_LINES - tp->tty_row)) 
X				n = SCR_LINES - tp->tty_row;
X
X			src = tp->tty_org + (tp->tty_row + n) * LINE_WIDTH * 2;
X			dst = tp->tty_org + (tp->tty_row) * LINE_WIDTH * 2;
X			count = (SCR_LINES - n - tp->tty_row) * LINE_WIDTH;
X			l_scr_up(vid_base, src, dst, count);
X			dst = tp->tty_org + (SCR_LINES - n) * LINE_WIDTH * 2;
X		        long_vid_copy(NIL_PTR, vid_base, dst, n * LINE_WIDTH);
X			break;
X
X		    case 'P':		/* ESC [nP deletes n chars at cursor */
X			n = value;
X			if (n < 1) n = 1;
X			if (n > (LINE_WIDTH - tp->tty_column))
X				n = LINE_WIDTH - tp->tty_column;
X			src = (tp->tty_row * LINE_WIDTH + tp->tty_column+n) *2;
X			dst = (tp->tty_row * LINE_WIDTH + tp->tty_column) * 2;
X			count = LINE_WIDTH - tp->tty_column - n;
X			src += tp->tty_org;
X			dst += tp->tty_org;
X			scr_up(vid_base, src, dst, count);
X			vid_copy(NIL_PTR, vid_base, dst + count * 2, n);
X			break;
X
X		    case '@':  		/* ESC [n@ inserts n chars at cursor */
X			n = value;
X			if (n < 1) n = 1;
X			if (n > (LINE_WIDTH - tp->tty_column))
X				n = LINE_WIDTH - tp->tty_column;
X			src = (tp->tty_row * LINE_WIDTH + LINE_WIDTH- n-1) * 2;
X			dst = (tp->tty_row * LINE_WIDTH + LINE_WIDTH - 1) * 2;
X			count = LINE_WIDTH - tp->tty_column - n;
X			src += tp->tty_org;
X			dst += tp->tty_org;
X			scr_down(vid_base, src, dst, count);
X			dst = (tp->tty_row * LINE_WIDTH + tp->tty_column) * 2;
X			dst += tp->tty_org;
X			vid_copy(NIL_PTR, vid_base, dst, n);
X			break;
X
X	   	    case 'm':		/* ESC [nm enables rendition n */
X	 		switch (value) {
X 			    case 1: /*  BOLD  */
X				if (color)
X	 				tp->tty_attribute = /* red fg */
X					 	(attr & 0xf0ff) | 0x0400;
X				else
X		 			tp->tty_attribute |= 0x0800; /* inten*/
X 				break;
X 
X 			    case 4: /*  UNDERLINE */
X				if (color)
X					tp->tty_attribute = /* blue fg */
X					 (attr & 0xf0ff) | 0x0100;
X				else
X					tp->tty_attribute = /* ul */
X					 (attr & 0x8900);
X 				break;
X 
X 			    case 5: /*  BLINKING */
X				if (color) /* can't blink color */
X					tp->tty_attribute = /* magenta fg */
X					 (attr & 0xf0ff) | 0x0500;
X				else
X		 			tp->tty_attribute |= /* blink */
X					 0x8000;
X 				break;
X 
X 			    case 7: /*  REVERSE  (black on light grey)  */
X				if (color)
X	 				tp->tty_attribute = 
X					 ((attr & 0xf000) >> 4) |
X					 ((attr & 0x0f00) << 4);
X				else if ((attr & 0x7000) == 0)
X					tp->tty_attribute =
X					 (attr & 0x8800) | 0x7000;
X				else
X					tp->tty_attribute =
X					 (attr & 0x8800) | 0x0700;
X  				break;
X
X 			    default: if (value >= 30 && value <= 37) {
X					tp->tty_attribute = 
X					 (attr & 0xf0ff) |
X					 (ansi_colors[(value - 30)] << 8);
X					blank_color = 
X					 (blank_color & 0xf0ff) |
X					 (ansi_colors[(value - 30)] << 8);
X				} else if (value >= 40 && value <= 47) {
X					tp->tty_attribute = 
X					 (attr & 0x0fff) |
X					 (ansi_colors[(value - 40)] << 12);
X					blank_color =
X					 (blank_color & 0x0fff) |
X					 (ansi_colors[(value - 40)] << 12);
X				} else
X	 				tp->tty_attribute = blank_color;
X  				break;
X	 		}
X			break;
X
X	   	    default:
X			break;
X		}	/* closes switch(c) */
X	}	/* closes if (tp->tty_esc_intro == '[') */
X  }
X  tp->tty_esc_state = 0;
X}
X
X/*===========================================================================*
X *				long_vid_copy				     *
X *===========================================================================*/
XPRIVATE long_vid_copy(src, base, offset, count)
Xchar *src;
Xunsigned int base, offset, count;
X{
X  int ct;	
X/*
X * break up a call to vid_copy for machines that can only write
X * during vertical retrace.  Vid_copy itself does the wait.
X */
X
X  while (count > 0) {
X	ct = MIN (count, vid_retrace >> 1);
X	vid_copy(src, base, offset, ct);
X	if (src != NIL_PTR) src += ct * 2;
X	offset += ct * 2;
X	count -= ct;
X  }
X}
X
X/*===========================================================================*
X *				long_src_up				     *
X *===========================================================================*/
XPRIVATE l_scr_up(base, src, dst, count)
Xunsigned int base, src, dst, count;
X{
X  int ct, old_state, wait;
X
X  /*
X   * Break up a call to scr_up for machines that can only write
X   * during vertical retrace.  scr_up doesn't do the wait, so we do.
X   * Note however that we keep interrupts on during the scr_up.  This
X   * could lead to snow if an interrupt happens while we are doing
X   * the display.  Sorry, but I don't see any good alternative.
X   * Turning off interrupts makes us loses RS232 input chars.
X   */
X
X  wait = color && ! ega;
X  while (count > 0) {
X	if (wait) {
X		old_state = wait_retrace();
X		restore(old_state);
X	}
X	ct = MIN (count, vid_retrace >> 1);
X	scr_up(base, src, dst, ct);
X	src += ct * 2;
X	dst += ct * 2;
X	count -= ct;
X  }
X}
X
X/*===========================================================================*
X *				long_scr_down				     *
X *===========================================================================*/
XPRIVATE l_scr_down(base, src, dst, count)
Xunsigned int base, src, dst, count;
X{
X  int ct, old_state, wait;
X
X  /* Break up a call to scr_down for machines that can only write
X   * during vertical retrace.  scr_down doesn't do the wait, so we do.
X   * Note however that we keep interrupts on during the scr_down.  This
X   * could lead to snow if an interrupt happens while we are doing
X   * the display.  Sorry, but I don't see any good alternative.
X   * Turning off interrupts makes us loses RS232 input chars.
X   */
X
X  wait = color && ! ega;
X  while (count > 0) {
X	if (wait) {
X		old_state = wait_retrace();
X		restore(old_state);
X	}
X	ct = MIN (count, vid_retrace >> 1);
X	scr_down(base, src, dst, ct);
X	src -= ct * 2;
X	dst -= ct * 2;
X	count -= ct;
X  }
X}
X
X/*===========================================================================*
X *				set_6845				     *
X *===========================================================================*/
XPRIVATE set_6845(reg, val)
Xint reg;			/* which register pair to set */
Xint val;			/* 16-bit value to set it to */
X{
X/* Set a register pair inside the 6845.  
X * Registers 10-11 control the format of the cursor (how high it is, etc).
X * Registers 12-13 tell the 6845 where in video ram to start (in WORDS)
X * Registers 14-15 tell the 6845 where to put the cursor (in WORDS)
X *
X * Note that registers 12-15 work in words, i.e. 0x0000 is the top left
X * character, but 0x0001 (not 0x0002) is the next character.  This addressing
X * is different from the way the 8088 addresses the video ram, where 0x0002
X * is the address of the next character.
X */
X  port_out(vid_port + INDEX, reg);	/* set the index register */
X  port_out(vid_port + DATA, (val>>8) & BYTE);	/* output high byte */
X  port_out(vid_port + INDEX, reg + 1);	/* again */
X  port_out(vid_port + DATA, val&BYTE);	/* output low byte */
X}
X
X/*===========================================================================*
X *				beep					     *
X *===========================================================================*/
XPRIVATE int beeping = 0;
XPRIVATE int stopbeep();
X
XPRIVATE beep(f)
Xint f;				/* this value determines beep frequency */
X{
X/* Making a beeping sound on the speaker (output for CRTL-G).  The beep is
X * kept short, because interrupts must be disabled during beeping, and it
X * is undesirable to keep them off too long.  This routine works by turning
X * on the bits in port B of the 8255 chip that drive the speaker.
X */
X
X  int k, s, x;
X  message mess;
X
X  if (beeping) return;
X  s = lock();			/* disable interrupts */
X  port_out(TIMER3,0xB6);	/* set up timer channel 2 mode */
X  port_out(TIMER2, f&BYTE);	/* load low-order bits of frequency in timer */
X  port_out(TIMER2,(f>>8)&BYTE);	/* now high-order bits of frequency in timer */
X  port_in(PORT_B,&x);		/* acquire status of port B */
X  port_out(PORT_B, x|3);	 /* turn bits 0 and 1 on to beep */
X  beeping = 1;
X  restore(s);			/* re-enable interrupts to previous state */
X
X  mess.m_type = SET_ALARM;
X  mess.CLOCK_PROC_NR = TTY;
X  mess.DELTA_TICKS = B_TIME;
X  mess.FUNC_TO_CALL = stopbeep;
X  sendrec(CLOCK, &mess);
X}
X
Xstopbeep() {
X  int s, x;
X
X  s = lock();			/* disable interrupts */
X  port_in(PORT_B,&x);		/* acquire status of port B */
X  port_out(PORT_B, x & 0xfffc);	/* turn bits 0 and 1 on to beep */
X  beeping = 0;
X  restore(s);			/* re-enable interrupts to previous state */
X}
X
X/*===========================================================================*
X *				set_leds				     *
X *===========================================================================*/
XPUBLIC set_leds()
X{
X/* Set the LEDs on the caps lock and num lock keys */
X
X  int count, leds, dummy, i, port;
X
X  if (pc_at == 0 && !ps) return;	/* PC/XT doesn't have LEDs */
X  leds = (numlock<<1) | (capslock<<2);	/* encode LED bits */
X
X  if (ps) {
X	port = PS_KEYBD;
X	count = PS_LED_DELAY;
X  } else {
X	count = LED_DELAY;
X	port = KEYBD;
X  }
X
X  port_out(port, LED_CODE);	/* prepare keyboard to accept LED values */
X  port_in(port, &dummy);	/* keyboard sends ack; accept it */
X  for (i = 0; i < count; i++) ;	/* delay needed */
X  port_out(port, leds);		/* give keyboard LED values */
X  port_in(port, &dummy);	/* keyboard sends ack; accept it */
X}
X
X/*===========================================================================*
X *				tty_init				     *
X *===========================================================================*/
XPUBLIC tty_init()
X{
X/* Initialize the tty tables. */
X
X  register struct tty_struct *tp;
X
X  /* Set initial values. */
X  caps_off = 1;
X  num_off = 1;
X
X  /* Tell the EGA card, if any, to simulate a 16K CGA card. */
X  port_out(EGA + INDEX, 4);	/* register select */
X  port_out(EGA + DATA, 1);	/* no extended memory to be used */
X
X  for (tp = &tty_struct[0]; tp < &tty_struct[NR_CONS]; tp++) {
X	tp->tty_inhead = tp->tty_inqueue;
X	tp->tty_intail = tp->tty_inqueue;
X	tp->tty_mode = CRMOD | XTABS | ECHO;
X	tp->tty_devstart = console;
X	tp->tty_makebreak = TWO_INTS;
X	tp->tty_attribute = BLANK;
X	tp->tty_erase = ERASE_CHAR;
X	tp->tty_kill  = KILL_CHAR;
X	tp->tty_intr  = INTR_CHAR;
X	tp->tty_quit  = QUIT_CHAR;
X	tp->tty_xon   = XON_CHAR;
X	tp->tty_xoff  = XOFF_CHAR;
X	tp->tty_eof   = EOT_CHAR;
X  }
X
X  if (color) {
X	vid_base = COLOR_BASE;
X	vid_mask = C_VID_MASK;
X	vid_port = C_6845;
X	vid_retrace = C_RETRACE;
X  } else {
X	vid_base = MONO_BASE;
X	vid_mask = M_VID_MASK;
X	vid_port = M_6845;
X	vid_retrace = M_RETRACE;
X  }
X
X  if (ega) {
X	vid_mask = C_VID_MASK;
X	vid_retrace = C_VID_MASK + 1;
X  }
X  tty_buf_max(tty_driver_buf) = MAX_OVERRUN;	/* set up limit on keyboard buffering*/
X  set_6845(CUR_SIZE, 31);		/* set cursor shape */
X  set_6845(VID_ORG, 0);			/* use page 0 of video ram */
X  move_to(&tty_struct[0], 0, SCR_LINES-1); /* move cursor to lower left */
X
X  if (ps) {
X	set_leds();		/* turn off numlock led */
X	softscroll = TRUE;
X  }
X
X  /* Determine which keyboard type is attached.  The bootstrap program asks 
X   * the user to type an '='.  The scan codes for '=' differ depending on the
X   * keyboard in use.
X   */
X  switch(scan_code) {
X	case STANDARD_SCAN:	keyb_type = IBM_PC; break;
X	case OLIVETTI_SCAN: 	keyb_type = OLIVETTI; load_olivetti(); break;
X	case DUTCH_EXT_SCAN:	keyb_type = DUTCH_EXT;
X				load_dutch_table(); break;
X	case US_EXT_SCAN:	keyb_type = US_EXT;
X				load_us_ext(); break;
X  }
X}
X
X/*===========================================================================*
X *			load_dutch_table				     *
X *===========================================================================*/
XPRIVATE load_dutch_table()
X{
X/* Load the scan code to ASCII table for extended dutch keyboard. */
X
X  register int i;
X
X  for (i = 0; i < NR_SCAN_CODES; i++) {
X	sh[i] = dutch_sh[i];
X	unsh[i] = dutch_unsh[i];
X	alt_c[i] = dutch_alt[i];
X  }
X
X  minus_code = MINUS_DU;
X  num_slash = NUM_SLASH_DU;
X}
X
X/*===========================================================================*
X *			load_olivetti					     *
X *===========================================================================*/
XPRIVATE load_olivetti()
X{
X/* Load the scan code to ASCII table for olivetti type keyboard. */
X
X  register int i;
X
X  for (i = 0; i < NR_SCAN_CODES; i++) {
X	sh[i] = m24[i];
X	unsh[i] = unm24[i];
X  }
X}
X
X/*===========================================================================*
X *			load_us_ext					     *
X *===========================================================================*/
XPRIVATE load_us_ext()
X{
X/* Load the scan code to ASCII table for US extended keyboard. */
X
X  register int i;
X
X  for (i = 0; i < NR_SCAN_CODES; i++) {
X	sh[i] = sh_usx[i];
X	unsh[i] = unsh_usx[i];
X  }
X}
X
X/*===========================================================================*
X *				putc					     *
X *===========================================================================*/
XPUBLIC putc(c)
Xchar c;				/* character to print */
X{
X/* This procedure is used by the version of printf() that is linked with
X * the kernel itself.  The one in the library sends a message to FS, which is
X * not what is needed for printing within the kernel.  This version just queues
X * the character and starts the output.
X */
X
X  out_char(&tty_struct[0], c);
X}
X
X/*===========================================================================*
X *				func_key				     *
X *===========================================================================*/
XPUBLIC func_key(ch)
Xchar ch;			/* scan code for a function key */
X{
X/* This procedure traps function keys for debugging purposes.  When MINIX is
X * fully debugged, it should be removed.
X */
X
X  if (ch == F1) p_dmp();	/* print process table */
X  if (ch == F2) map_dmp();	/* print memory map */
X  if (ch == F3) {		/* hardware vs. software scrolling */
X	softscroll = 1 - softscroll;	/* toggle scroll mode */
X	tty_struct[0].tty_org = 0;
X	move_to(&tty_struct[0], 0, SCR_LINES-1); /* cursor to lower left */
X	set_6845(VID_ORG, 0);
X
X	if (softscroll)
X		printf("\033[H\033[JSoftware scrolling enabled.\n");
X	else
X		printf("\033[H\033[JHardware scrolling enabled.\n");
X  }
X
X#ifdef AM_KERNEL
X#ifndef NONET
X  if (ch == F4) net_init();	/* re-initialise the ethernet card */
X#endif NONET
X#endif AM_KERNEL
X  if (ch == F9 && control) sigchar(&tty_struct[0], SIGKILL);	/* SIGKILL */
X}
+ END-OF-FILE console.c
chmod 'u=rw,g=r,o=r' 'console.c'
set `wc -c 'console.c'`
count=$1
case $count in
33549)	:;;
*)	echo 'Bad character count in ''console.c' >&2
		echo 'Count should be 33549' >&2
esac
echo Extracting 'at_makefile.cdif'
sed 's/^X//' > 'at_makefile.cdif' << '+ END-OF-FILE ''at_makefile.cdif'
X*** ../oldkernel/at_makefile	Thu Oct 13 16:23:01 1988
X--- at_makefile	Thu Oct 13 16:17:56 1988
X***************
X*** 123,130 ****
X  tty.s:	proc.h
X  tty.s:	tty.h
X  tty.s:	ttymaps.h
X- tty.s:	tty.h
X- tty.s:	ttymaps.h
X  
X  wini.s:	const.h type.h $h/const.h $h/type.h
X  wini.s:	$h/callnr.h
X--- 123,128 ----
+ END-OF-FILE at_makefile.cdif
chmod 'u=rw,g=r,o=r' 'at_makefile.cdif'
set `wc -c 'at_makefile.cdif'`
count=$1
case $count in
300)	:;;
*)	echo 'Bad character count in ''at_makefile.cdif' >&2
		echo 'Count should be 300' >&2
esac
echo Extracting 'clock.c.cdif'
sed 's/^X//' > 'clock.c.cdif' << '+ END-OF-FILE ''clock.c.cdif'
X*** ../oldkernel/clock.c	Thu Oct 13 16:23:02 1988
X--- clock.c	Thu Oct 13 16:17:53 1988
X***************
X*** 55,61 ****
X  PRIVATE message mc;		/* message buffer for both input and output */
X  PRIVATE int (*watch_dog[NR_TASKS+1])();	/* watch_dog functions to call */
X  extern int flush_flag;		/* tells clock when to flush the tty buf */
X- extern int need_ega_int;	/* tells clock to do ega adjust */
X  
X  /*===========================================================================*
X   *				clock_task				     *
X--- 55,60 ----
X***************
X*** 204,212 ****
X  	if (bill_ptr == prev_ptr) sched();	/* process has run too long */
X  	sched_ticks = SCHED_RATE;		/* reset quantum */
X  	prev_ptr = bill_ptr;			/* new previous process */
X- 
X- 	/* Does ega need adjustment? */
X- 	if (need_ega_int) ega_int();  
X  
X  	/* Check if printer is hung up, and if so, restart it. */
X  	if (pr_busy && pcount > 0 && cum_count == prev_ct) pr_char(); 
X--- 203,208 ----
+ END-OF-FILE clock.c.cdif
chmod 'u=rw,g=r,o=r' 'clock.c.cdif'
set `wc -c 'clock.c.cdif'`
count=$1
case $count in
948)	:;;
*)	echo 'Bad character count in ''clock.c.cdif' >&2
		echo 'Count should be 948' >&2
esac
echo Extracting 'glo.h.cdif'
sed 's/^X//' > 'glo.h.cdif' << '+ END-OF-FILE ''glo.h.cdif'
X*** ../oldkernel/glo.h	Thu Oct 13 16:23:05 1988
X--- glo.h	Thu Oct 13 16:17:55 1988
X***************
X*** 18,22 ****
X  /* Video cards and keyboard types. */
X  EXTERN int color;		/* 1 if console is color, 0 if it is mono */
X  EXTERN int ega;			/* 1 if console is EGA, 0 if not */
X- EXTERN int need_ega_int; 	/* ask clock for ega interrupt */
X  EXTERN int scan_code;		/* scan code of key pressed to start minix */
X--- 18,21 ----
+ END-OF-FILE glo.h.cdif
chmod 'u=rw,g=r,o=r' 'glo.h.cdif'
set `wc -c 'glo.h.cdif'`
count=$1
case $count in
424)	:;;
*)	echo 'Bad character count in ''glo.h.cdif' >&2
		echo 'Count should be 424' >&2
esac
echo Extracting 'klib88.s.cdif'
sed 's/^X//' > 'klib88.s.cdif' << '+ END-OF-FILE ''klib88.s.cdif'
X*** ../oldkernel/klib88.s	Thu Oct 13 16:23:06 1988
X--- klib88.s	Thu Oct 13 16:27:31 1988
X***************
X*** 20,26 ****
X  |   dma_write:	transfer data between memory and HD controller
X  |   em_xfer:	read or write AT extended memory using the BIOS
X  |   wait_retrace: waits for retrace interval, and returns int disabled
X- |   wait_no_retrace: waits for not retrace interval, and returns int disabled
X  |   ack_char:	acknowledge character from keyboard
X  |   save_tty_vec: save tty interrupt vector 0x71 for PS/2
X  
X--- 20,25 ----
X***************
X*** 28,34 ****
X  .globl _phys_copy, _cp_mess, _lock, _restore
X  .globl _build_sig, csv, cret, _get_chrome, _vid_copy, _get_byte, _reboot
X  .globl _wreboot, _dma_read, _dma_write, _em_xfer, _scr_up, _scr_down
X! .globl _ack_char, _save_tty_vec, _get_ega, _wait_retrace, _wait_no_retrace
X  
X  
X  | The following external procedures are called in this file.
X--- 27,33 ----
X  .globl _phys_copy, _cp_mess, _lock, _restore
X  .globl _build_sig, csv, cret, _get_chrome, _vid_copy, _get_byte, _reboot
X  .globl _wreboot, _dma_read, _dma_write, _em_xfer, _scr_up, _scr_down
X! .globl _ack_char, _save_tty_vec, _get_ega, _wait_retrace
X  
X  
X  | The following external procedures are called in this file.
X***************
X*** 467,494 ****
X  	in			| 0x3DA bit 3 is set during retrace.
X  	testb al,*010		| Wait until it is on.
X  	jz wtre.3
X- 
X- 	pop ax	 		| return flags for restoration later
X- 	pop dx
X- 	ret			| return to caller
X- 
X- |*===========================================================================*
X- |*			      wait_no_retrace				     *
X- |*===========================================================================*
X- | Wait until we're not in the retrace interval.  Return locked (ints off).
X- | But enable then during the wait.
X- 
X- _wait_no_ret: push dx
X- 	pushf
X- 	mov dx,_vid_port
X- 	or dx,#0x000A
X- wtnre:	sti
X- 	nop
X- 	nop
X- 	cli	
X- 	in			| 0x3DA bit 3 is set during retrace.
X- 	testb al,*010		| Wait until it is off.
X- 	jnz wtnre
X  
X  	pop ax	 		| return flags for restoration later
X  	pop dx
X--- 466,471 ----
+ END-OF-FILE klib88.s.cdif
chmod 'u=rw,g=r,o=r' 'klib88.s.cdif'
set `wc -c 'klib88.s.cdif'`
count=$1
case $count in
2065)	:;;
*)	echo 'Bad character count in ''klib88.s.cdif' >&2
		echo 'Count should be 2065' >&2
esac
echo Extracting 'pc_makefile.cdif'
sed 's/^X//' > 'pc_makefile.cdif' << '+ END-OF-FILE ''pc_makefile.cdif'
X*** ../oldkernel/pc_makefile	Thu Oct 13 16:23:08 1988
X--- pc_makefile	Thu Oct 13 16:17:56 1988
+ END-OF-FILE pc_makefile.cdif
chmod 'u=rw,g=r,o=r' 'pc_makefile.cdif'
set `wc -c 'pc_makefile.cdif'`
count=$1
case $count in
95)	:;;
*)	echo 'Bad character count in ''pc_makefile.cdif' >&2
		echo 'Count should be 95' >&2
esac
echo Extracting 'rs232.c.cdif'
sed 's/^X//' > 'rs232.c.cdif' << '+ END-OF-FILE ''rs232.c.cdif'
X*** ../oldkernel/rs232.c	Thu Oct 13 16:23:10 1988
X--- rs232.c	Thu Oct 13 16:17:54 1988
X***************
X*** 135,148 ****
X    port_in(base + RS232_RECEIVER_DATA_REG, &val);
X  
X    /* Store the character in memory so the task can get at it later */
X!   if ((k = tty_driver_buf[0]) < tty_driver_buf[1]) {
X  	/* There is room to store this character, do it */
X  	k = k + k;			/* each entry contains two bytes */
X! 	tty_driver_buf[k + 2] = val;	/* store the ascii code */
X! 	tty_driver_buf[k + 3] = line;	/* tell wich line it came from */ 
X! 	tty_driver_buf[0]++;		/* increment counter */
X  
X! 	if (tty_driver_buf[0] < THRESHOLD) {
X  		/* Don't send message.  Just accumulate.  Let clock do it. */
X  		port_out(INT_CTL, ENABLE);
X  		flush_flag++;
X--- 135,148 ----
X    port_in(base + RS232_RECEIVER_DATA_REG, &val);
X  
X    /* Store the character in memory so the task can get at it later */
X!   if ((k = tty_buf_count(tty_driver_buf)) < tty_buf_max(tty_driver_buf)) {
X  	/* There is room to store this character, do it */
X  	k = k + k;			/* each entry contains two bytes */
X! 	tty_driver_buf[k + 4] = val;	/* store the ascii code */
X! 	tty_driver_buf[k + 5] = line;	/* tell wich line it came from */ 
X! 	tty_buf_count(tty_driver_buf)++;		/* increment counter */
X  
X! 	if (tty_buf_count(tty_driver_buf) < THRESHOLD) {
X  		/* Don't send message.  Just accumulate.  Let clock do it. */
X  		port_out(INT_CTL, ENABLE);
X  		flush_flag++;
X***************
X*** 167,173 ****
X  
X    /* Build and send the interrupt message */ 
X    flush_flag = 0;
X!   if (tty_driver_buf[0] == 0) return;	/* nothing to flush */
X    rs232_rd_mess.m_type = TTY_CHAR_INT;
X    rs232_rd_mess.ADDRESS = tty_driver_buf;
X    interrupt(TTY, &rs232_rd_mess);	/* send a message to the tty task */
X--- 167,173 ----
X  
X    /* Build and send the interrupt message */ 
X    flush_flag = 0;
X!   if (tty_buf_count(tty_driver_buf) == 0) return;	/* nothing to flush */
X    rs232_rd_mess.m_type = TTY_CHAR_INT;
X    rs232_rd_mess.ADDRESS = tty_driver_buf;
X    interrupt(TTY, &rs232_rd_mess);	/* send a message to the tty task */
+ END-OF-FILE rs232.c.cdif
chmod 'u=rw,g=r,o=r' 'rs232.c.cdif'
set `wc -c 'rs232.c.cdif'`
count=$1
case $count in
2071)	:;;
*)	echo 'Bad character count in ''rs232.c.cdif' >&2
		echo 'Count should be 2071' >&2
esac
echo Extracting 'tty.c.cdif'
sed 's/^X//' > 'tty.c.cdif' << '+ END-OF-FILE ''tty.c.cdif'
X*** ../oldkernel/tty.c	Thu Oct 13 16:23:12 1988
X--- tty.c	Thu Oct 13 16:17:55 1988
X***************
X*** 160,173 ****
X    old_state = lock();
X    ptr = m_ptr->ADDRESS;		/* pointer to accumulated char array */
X    copy_ptr = tty_copy_buf;	/* ptr to shadow array where chars copied */
X!   n = *ptr;			/* how many chars have been accumulated */
X    count = n;			/* save the character count */
X    n = n + n;			/* each char occupies 2 bytes */
X!   ptr += 2;			/* skip count field at start of array */
X    while (n-- > 0)
X  	*copy_ptr++ = *ptr++;	/* copy the array to safety */
X    ptr = m_ptr->ADDRESS;
X!   *ptr = 0;			/* accumulation count set to 0 */
X    restore(old_state);
X  
X    /* Loop on the accumulated characters, processing each in turn. */
X--- 160,173 ----
X    old_state = lock();
X    ptr = m_ptr->ADDRESS;		/* pointer to accumulated char array */
X    copy_ptr = tty_copy_buf;	/* ptr to shadow array where chars copied */
X!   n = tty_buf_count(ptr);	/* how many chars have been accumulated */
X    count = n;			/* save the character count */
X    n = n + n;			/* each char occupies 2 bytes */
X!   ptr += 4;			/* skip count field at start of array */
X    while (n-- > 0)
X  	*copy_ptr++ = *ptr++;	/* copy the array to safety */
X    ptr = m_ptr->ADDRESS;
X!   tty_buf_count(ptr) = 0;		/* accumulation count set to 0 */
X    restore(old_state);
X  
X    /* Loop on the accumulated characters, processing each in turn. */
+ END-OF-FILE tty.c.cdif
chmod 'u=rw,g=r,o=r' 'tty.c.cdif'
set `wc -c 'tty.c.cdif'`
count=$1
case $count in
1416)	:;;
*)	echo 'Bad character count in ''tty.c.cdif' >&2
		echo 'Count should be 1416' >&2
esac
echo Extracting 'tty.h.cdif'
sed 's/^X//' > 'tty.h.cdif' << '+ END-OF-FILE ''tty.h.cdif'
X*** ../oldkernel/tty.h	Thu Oct 13 16:23:13 1988
X--- tty.h	Thu Oct 13 16:17:56 1988
X***************
X*** 1,13 ****
X  #define NR_CONS            1	/* how many consoles can system handle */
X  #define	NR_RS_LINES	   1	/* how many rs232 terminals can system handle*/
X! #define TTY_IN_BYTES     200	/* input queue size */
X  #define TTY_RAM_WORDS    320	/* ram buffer size */
X  #define TTY_BUF_SIZE     256	/* unit for copying to/from queues */
X  #define TAB_SIZE           8	/* distance between tabs */
X  #define TAB_MASK          07	/* mask for tty_column when tabbing */
X  #define WORD_MASK     0xFFFF	/* mask for 16 bits */
X  #define OFF_MASK      0x000F	/* mask for  4 bits */
X! #define MAX_OVERRUN      100	/* size of overrun input buffer */
X  #define MAX_ESC_PARMS      2	/* number of escape sequence params allowed */
X  
X  #define ERASE_CHAR      '\b'	/* default erase character */
X--- 1,13 ----
X  #define NR_CONS            1	/* how many consoles can system handle */
X  #define	NR_RS_LINES	   1	/* how many rs232 terminals can system handle*/
X! #define TTY_IN_BYTES    1000	/* input queue size */
X  #define TTY_RAM_WORDS    320	/* ram buffer size */
X  #define TTY_BUF_SIZE     256	/* unit for copying to/from queues */
X  #define TAB_SIZE           8	/* distance between tabs */
X  #define TAB_MASK          07	/* mask for tty_column when tabbing */
X  #define WORD_MASK     0xFFFF	/* mask for 16 bits */
X  #define OFF_MASK      0x000F	/* mask for  4 bits */
X! #define MAX_OVERRUN      500	/* size of overrun input buffer */
X  #define MAX_ESC_PARMS      2	/* number of escape sequence params allowed */
X  
X  #define ERASE_CHAR      '\b'	/* default erase character */
X***************
X*** 17,22 ****
X--- 17,23 ----
X  #define XOFF_CHAR (char) 023	/* default x-off character (CTRL-S) */
X  #define XON_CHAR  (char) 021	/* default x-on character (CTRL-Q) */
X  #define EOT_CHAR  (char) 004	/* CTRL-D */
X+ 
X  /*
X   * This MARKER is used as an unambiguous flag for an unescaped end of
X   * file character.  It is meaningful only in cooked mode.  0200 should
X***************
X*** 102,109 ****
X--- 103,112 ----
X  
X    /* Miscellaneous. */
X    int tty_ioport;		/* I/O port number for this terminal */
X+ 
X  } tty_struct[NR_CONS+NR_RS_LINES];
X  
X+ 
X  /* Values for the fields. */
X  #define NOT_ESCAPED        0	/* previous character on this line not '\' */
X  #define ESCAPED            1	/* previous character on this line was '\' */
X***************
X*** 117,123 ****
X  #define WAITING            1	/* an output process is waiting for a reply */
X  #define COMPLETED          2	/* output done; send a completion message */
X  
X! EXTERN char tty_driver_buf[2*MAX_OVERRUN+2]; /* driver collects chars here */
X  EXTERN char tty_copy_buf[2*MAX_OVERRUN];  /* copy buf used to avoid races */
X  EXTERN char tty_buf[TTY_BUF_SIZE];	/* scratch buffer to/from user space */
X  EXTERN int shift1, shift2, capslock, numlock;	/* keep track of shift keys */
X--- 120,128 ----
X  #define WAITING            1	/* an output process is waiting for a reply */
X  #define COMPLETED          2	/* output done; send a completion message */
X  
X! EXTERN char tty_driver_buf[2*MAX_OVERRUN+4]; /* driver collects chars here */
X! #define tty_buf_count(p) (((int *)(p))[0])
X! #define tty_buf_max(p) (((int *)(p))[1])
X  EXTERN char tty_copy_buf[2*MAX_OVERRUN];  /* copy buf used to avoid races */
X  EXTERN char tty_buf[TTY_BUF_SIZE];	/* scratch buffer to/from user space */
X  EXTERN int shift1, shift2, capslock, numlock;	/* keep track of shift keys */
X***************
X*** 125,134 ****
X  EXTERN int caps_off;		/* 1 = normal position, 0 = depressed */
X  EXTERN int num_off;		/* 1 = normal position, 0 = depressed */
X  EXTERN int softscroll;		/* 1 = software scrolling, 0 = hardware */
X! EXTERN int output_done;	/* number of RS232 output messages to be sent*/
X! EXTERN int ega_origin;		/* origin to set at next ega int */
X! EXTERN int ega_line;		/* line to set at next ega int */
X! EXTERN int char_height;	/* number of scan lines for a char */
X  EXTERN int keyb_type;		/* type of keyboard attached */
X  EXTERN int minus_code;		/* numeric minus on dutch extended keyboard */
X  EXTERN int num_slash;		/* scan code of numeric slash */
X--- 130,137 ----
X  EXTERN int caps_off;		/* 1 = normal position, 0 = depressed */
X  EXTERN int num_off;		/* 1 = normal position, 0 = depressed */
X  EXTERN int softscroll;		/* 1 = software scrolling, 0 = hardware */
X! EXTERN int output_done;		/* number of RS232 output messages to be sent*/
X! EXTERN int char_height;		/* number of scan lines for a char */
X  EXTERN int keyb_type;		/* type of keyboard attached */
X  EXTERN int minus_code;		/* numeric minus on dutch extended keyboard */
X  EXTERN int num_slash;		/* scan code of numeric slash */
+ END-OF-FILE tty.h.cdif
chmod 'u=rw,g=r,o=r' 'tty.h.cdif'
set `wc -c 'tty.h.cdif'`
count=$1
case $count in
4719)	:;;
*)	echo 'Bad character count in ''tty.h.cdif' >&2
		echo 'Count should be 4719' >&2
esac
exit 0

hall@nosc.NOSC.MIL (Robert R. Hall) (10/18/88)

Yes I have completed the upgrades using these patches.
Does this put us at version level 1.3D
I find the new console stuff is very fast. How fast is that,
It can print a screen full, scroll it off and the only
screen I get to read is the last one.
I ran all test 1-11 and they run to completion in 1:33 real time.

But then I am the guy with the creditability problem using
Microsoft C and I am sure Andy still want other reports. :-)

rtregn@immd3.informatik.uni-erlangen.de (Robert Regn) (10/25/88)

I have tried to apply Andys fixes of 13. Oct.
When I compile console.c  with the 1.1 compiler on
the current 1.3c system,  cg prints:
Error : bad argument type 244

The generated console.s file is too small (3445 bytes)
and a try to link kernel gives many unresolveds:
I0044
I004D
_esc
_move_h
_tty_ini
_putc
_vid_por
_vid_esc
....
_parse_e

I have checked the crc (on sun and minix): 01201  3354
??????????????????????????????????????????

			Robert Regn							rtregn.faui32.uucp