Subject: port-i386/580: netbsd 1.0 PL03 i386/pcvt bugs/enhancements; fixes included
To: None <gnats-admin@sun-lamp.cs.berkeley.edu>
From: Lon Willett <lon%softt.uucp@math.utah.edu>
List: netbsd-bugs
Date: 11/18/1994 15:05:05
>Number:         580
>Category:       port-i386
>Synopsis:       netbsd i386/pcvt bugs/enhancements; fixes included
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 18 15:05:03 1994
>Originator:     Lon Willett
>Organization:
none
>Release:        1.0 PL03
>Environment:

Hardware: i586-66Mhz, CL-GD6440 VGA
OS: NetBSD-1.0 PL03
System: NetBSD hilly 1.0 NetBSD 1.0 (HILLY) #37: Fri Nov 18 12:31:45 MST 1994 lon@hilly:/usr/src/sys/arch/i386/compile/HILLY i386

>Description:

	I had several different problems with the pcvt console driver,
	which I managed to fix.  They are:

	1 -- The displayed cursor is not updated during kernel I/O,
	because async_update() doesn't get called.  This is merely ugly
	while the system startup messages are being displayed, but it is
	positively annoying when using the kernel debugger.

	2 -- CONTROL-SHIFT-<KEY> is taken to be the same as SHIFT-<KEY>.
	It should be interpretted as CONTROL-<KEY>, or even have its own
	binding.  One of the lines below fixes it in the former way.
	This is especially bad (i.e. clearly buggy) when I type
	CONTROL-SHIFT-<6/^> to get a "Control-^", and instead get a "^".

	3 -- The "special" region at the bottom of the screen, i.e.  the
	function-key-labels/status-line in HPVT mode, and the blank line
	in FORCE24LINES mode, do not get properly cleared/updated.

	4 -- When switching screen sizes/modes, the FORCE24LINES setting
	is not always handled.

	5 -- The PCVT_VT220KEYB functions are missing some features.
	The control key settings are bug fixes; they apply only if
	system function key labels are on, and match the labels.  The
	shift key definitions are enhancements.

	The new keys (previously undefined) are:

		Control-F1 -- toggle 80/132 columns
		Control-F2 -- soft reset emulator
		Control-F3 -- toggle force 24 lines mode
		Control-F4 -- toggle keyboard debugging

		Shift-F1 -- select screen 4
		Shift-F2 -- select screen 5
		Shift-F3 -- select screen 6
		Shift-F4 -- select screen 7
		Shift-F5 -- select (current screen - 1)

	6 -- [Enhancement] The initial startup screen is cleared, and
	the screen gets cleared when changing modes/sizes.  I don't like
	this.  I want a chance to see bootstrap loader messages, and I
	also want the command "scon -d/dev/ttyv0 -H -s28" in my
	rc.local, but then I lose various messages from daemons, etc
	(which aren't always logged to syslog).  So I have fixed the
	code so that it tries to preserve the contents of the screen
	when starting up, and when changing modes/sizes.

	7 -- [Enhancement?] I added code to preserve the initial cursor
	shape at startup.  This isn't really necessary, since the
	"cursor" command can be used to set it to your preference; but
	it seems like this is the preferable policy to use for the
	default.

>How-To-Repeat:

	1 -- Type <CONTROL-ALT-ESCAPE>, then some debugger commands.

	2 -- Type XXX<CONTROL-SHIFT-U>.

	3 -- For instance (lots of other ways):
		scon -d/dev/ttyv0 -H -s25
		scon -d/dev/ttyv1 -V -s25
		<Fill up /dev/ttyv1 screen with stuff, especially in the
		 last 3 lines>
		<Switch to /dev/ttyv0 screen; garbage will be left
		 between the function key labels>

	4 -- For instance:
		scon -f off
		scon -s25 -H
		scon -f on
		scon -V
		scon -l
		# This indicates that you are operating in pure vt mode
		# on a screen with 25 lines, and force24lines is set, so
		# you should only be using 24 of them.  But:
		i=25; while [ $i -gt 1 ]; do echo $i; i=`expr $i - 1`; done
		# will show you that it is really using all 25 lines.

	5 -- Build kernel with PCVT_VT220KEYB option.  Then
		scon -H
		# Function key label say that F2 does a reset, but
		<CONTROL-F2>
		# won't do anything.

	6 -- Boot your system.  Use scon -H, scon -V, scon -sXXX.  They
	clear the screen.

	7 -- Look at the cursor.

>Fix:

	The included patch has fixes for all of the above.

	It needs to be applied from the directory

		/usr/src/sys/arch/i386/isa/pcvt

	The specific fixes are:

	1 -- The lines in pcvt_drv.c and pcvt_sup.c that concern
	async_update().

	2 -- The line in pcvt_kbd.c that adds "!ctrl_down" to the
	test.

	3,4 -- The changes in pcvt_out.c that are not ifdef'ed HILLY.

	5 -- The other changes in pcvt_kbd.c (besides the one for #2).

	6 -- The stuff that is ifdef'ed HILLY (my kernel config name),
	other than the one for #7.

	7 -- The "#ifdef HILLY" in pcvt_out.c with the comment
	"Preserve initial cursor shape".

---------------------------- START OF PATCH ----------------------------
--- pcvt_drv.c.orig	Thu May  5 05:11:25 1994
+++ pcvt_drv.c	Thu Nov 17 18:02:37 1994
@@ -791,6 +791,7 @@
 	if (c == '\n')
 		sput("\r", 1, 1, 0);
 	sput((char *) &c, 1, 1, 0);
+	async_update ((void *)2);
 	return 0;
 }
 
@@ -814,6 +815,7 @@
 	s = spltty();		/* block pcrint while we poll */
 	cp = sgetc(0);
 	splx(s);
+	async_update ((void *)2);
 
 	if (*cp == '\r')
 		return('\n');
@@ -877,6 +879,7 @@
 	x = splhigh();
 
 	sput(">", 1, 1, 0);
+	async_update ((void *)2);
 	thechar = *(sgetc(0));
 
 	kbd_polling = 0;
@@ -1029,7 +1032,7 @@
 			pcvt_set_scrnsv_tmo(0);	/* turn it off */
 #endif /* PCVT_SCREENSAVER */
 
-		async_update(1);	/* turn off */
+		async_update((void *)1);	/* turn off */
 
 		/* disable text output and save screen contents */
 		/* video board memory -> kernel memory */
--- pcvt_sup.c.orig	Thu May  5 05:37:36 1994
+++ pcvt_sup.c	Fri Nov 18 12:28:35 1994
@@ -735,14 +735,18 @@
 		{
 			set_charset(svsp, i);
 
+#ifndef HILLY
 			fillw(user_attr | ' ',
 				svsp->Crtat,
 				svsp->maxcol * svsp->screen_rowsize);
+#endif
 			clr_parms(svsp); 	/* escape parameter init */
 			svsp->state = STATE_INIT; /* initial state */
+#ifndef HILLY
 			svsp->col = 0;		/* init row */
 			svsp->row = 0;		/* init col */
 			svsp->cur_offset = 0;	/* cursor address offset init*/
+#endif
 			svsp->scrr_beg = 0;	/* start of scrolling region */
 			svsp->sc_flag = 0;	/* invalidate saved cursor
 						 * position */
@@ -756,6 +760,16 @@
 				(svsp->maxcol == 80)? 720: 1056;
 			svsp->vs_tty->t_winsize.ws_ypixel = 400;
 
+#ifdef HILLY
+			/* screen_rows already calculated in set_charset() */
+			if(svsp->vt_pure_mode == M_HPVT && svsp->labels_on)
+			{
+				if(svsp->which_fkl == SYS_FKL)
+					sw_sfkl(svsp);
+				else if(svsp->which_fkl == USR_FKL)
+					sw_ufkl(svsp);
+			}
+#else
 			if(svsp->vt_pure_mode == M_HPVT)
 			{
 				svsp->screen_rows = svsp->screen_rowsize - 3;
@@ -777,7 +791,8 @@
 				
 				if((size == SIZ_25ROWS) && svsp->force24)
 					svsp->screen_rows--;
-			}		
+			}
+#endif
 
 			svsp->vs_tty->t_winsize.ws_row = svsp->screen_rows;
 			
@@ -897,17 +912,20 @@
 
 /*---------------------------------------------------------------------------*
  *	update asynchronous: cursor, cursor pos displ, sys load, keyb scan
+ *	arg is:
+ *		0 -- do update; requeue
+ *		(void *)1 -- suspend updates
+ *		(void *)2 -- do update for kernel printfs
  *---------------------------------------------------------------------------*/
 void
 async_update(void *arg)
 {
-	int a = (int)arg;
 	static int lastpos = 0;
 	static int counter = PCVT_UPDATESLOW;
 
 #ifdef XSERVER
 	/* need a method to suspend the updates */
-	if(a)
+	if (arg == (void *)1)
 	{
 		untimeout(async_update, (void *)0);
 		return;
@@ -953,6 +971,10 @@
 		outb(addr_6845+1, (lastpos));
 	}
 
+	/* Magic arg: for kernel printfs */
+	if (arg == (void *)2)
+	    return;
+
 	if(--counter)			/* below is possible update */
 		goto async_update_exit;	/*  just now and then ..... */
 	counter = PCVT_UPDATESLOW;	/* caution, see screensaver above !! */
@@ -1089,7 +1111,7 @@
 
 async_update_exit:
 
-	if(a == 0)
+	if(arg == (void *)0)
 		timeout(async_update, (void *)0, PCVT_UPDATEFAST);
 }
     
@@ -1100,7 +1122,11 @@
 set_charset(struct video_state *svsp, int curvgacs)
 {
 	static int sizetab[] = { 25, 28, 35, 40, 43, 50 };
-	
+
+#ifdef HILLY
+	int oldsize, oldrows, newsize, newrows;
+#endif
+
 	if((curvgacs < 0) || (curvgacs > (NVGAFONTS-1)))
 		return;
 
@@ -1108,12 +1134,47 @@
 
 	select_vga_charset(curvgacs);
 
+#ifdef HILLY
+	oldsize = svsp->screen_rowsize;
+	oldrows = svsp->screen_rows;
+	newsize = sizetab[(vgacs[curvgacs].screen_size)];
+	newrows = newsize;
+	if (svsp->vt_pure_mode == M_HPVT)
+		newrows -= 3;
+	if (newrows == 25 && svsp->force24)
+		newrows = 24;
+	if (newrows < oldrows) {
+		int nscroll = svsp->row + 1 - newrows;
+		
+		if (svsp->row >= oldrows) /* Sanity check */
+			nscroll = oldrows - newrows;
+		if (nscroll > 0) {
+			/* Scroll up */
+			bcopy (svsp->Crtat + nscroll * svsp->maxcol,
+			       svsp->Crtat,
+			       newrows * svsp->maxcol * CHR);
+			svsp->row -= nscroll;
+			svsp->cur_offset -= nscroll * svsp->maxcol;
+		}
+		if (newrows < newsize)
+			fillw(user_attr | ' ',
+			      svsp->Crtat + newrows * svsp->maxcol,
+			      (newsize - newrows) * svsp->maxcol);
+	} else if (oldrows < newsize)
+		fillw(user_attr | ' ',
+		      svsp->Crtat + oldrows * svsp->maxcol,
+		      (newsize - oldrows) * svsp->maxcol);
+
+	svsp->screen_rowsize = newsize;
+	svsp->screen_rows = newrows;
+#else
 	svsp->screen_rowsize = sizetab[(vgacs[curvgacs].screen_size)];
 
 	if( svsp->labels_on && svsp->vt_pure_mode != M_PUREVT)
 		svsp->screen_rows = svsp->screen_rowsize-3;
 	else
 		svsp->screen_rows = svsp->screen_rowsize;
+#endif
 
 	/* Clip scrolling region */
 	if(svsp->scrr_end > svsp->screen_rows - 1)
--- pcvt_out.c.orig	Tue Mar 29 13:16:14 1994
+++ pcvt_out.c	Fri Nov 18 12:31:01 1994
@@ -1073,11 +1073,23 @@
 		svsp->scrr_len = svsp->screen_rows; /* scrolling region
 						     * end */
 		svsp->scrr_end = svsp->scrr_len - 1;
+#ifdef HILLY /* Preserve initial cursor shape */
+		if (nscr == 0) {
+			outb(addr_6845,CRTC_CURSTART);
+			svsp->cursor_start = inb(addr_6845+1);
+			outb(addr_6845,CRTC_CUREND);
+			svsp->cursor_end = inb(addr_6845+1);
+		} else {
+			svsp->cursor_start = vs[0].cursor_start;
+			svsp->cursor_end = vs[0].cursor_end;
+		}
+#else
 		if(vga_family == VGA_F_TRI)
 			svsp->cursor_start = 1; /* cursor upper scanline */
 		else
 			svsp->cursor_start = 0; /* cursor upper scanline */
 		svsp->cursor_end = 15;		/* cursor lower scanline */
+#endif
 		svsp->cursor_on = 1;		/* cursor is on */
 		svsp->ckm = 1;			/* normal cursor key mode */
 		svsp->irm = 0;			/* replace mode */
@@ -1121,9 +1133,41 @@
 
 		if(nscr == 0)
 		{
+#ifdef HILLY
+			/* Preserve data on the startup screen that precedes
+			   the cursor position.  Leave the cursor where
+			   it was found. */
+			unsigned cursorat;
+			int filllen;
+
+			outb(addr_6845, CRTC_CURSORH);
+			cursorat = inb(addr_6845+1) << 8;
+			outb(addr_6845, CRTC_CURSORL);
+			cursorat |= inb(addr_6845+1);
+			svsp->cur_offset = cursorat;
+			svsp->row = cursorat / svsp->maxcol;
+			svsp->col = cursorat % svsp->maxcol;
+			if (svsp->row >= svsp->screen_rows) {
+				/* Scroll up; this should only happen when
+				   PCVT_24LINESDEF is set */
+				int nscroll =
+					svsp->row + 1 - svsp->screen_rows;
+				bcopy (svsp->Crtat + nscroll*svsp->maxcol,
+				       svsp->Crtat,
+				       svsp->screen_rows * svsp->maxcol * CHR);
+				svsp->row -= nscroll;
+				svsp->cur_offset -= nscroll * svsp->maxcol;
+			}
+			filllen = (svsp->maxcol * svsp->screen_rowsize)
+				- svsp->cur_offset;
+			if (filllen > 0)
+				fillw(user_attr | ' ',
+				      svsp->Crtat+svsp->cur_offset, filllen);
+#else
 			fillw(user_attr | ' ',
 				svsp->Crtat,
 				svsp->maxcol * svsp->screen_rowsize);
+#endif
 		}
 
 #if PCVT_USL_VT_COMPAT
@@ -1412,26 +1456,43 @@
 	if(svsp->vt_pure_mode == mode)
 		return;
 	
+#ifndef HILLY
 	fillw(user_attr | ' ',
 		svsp->Crtat,
 		svsp->maxcol * svsp->screen_rowsize);
+#endif
 
 	clr_parms(svsp);		/* escape parameter init */
 	svsp->state = STATE_INIT;	/* initial state */
 
+#ifndef HILLY
 	svsp->col = 0;			/* init row */
 	svsp->row = 0;			/* init col */
 	svsp->cur_offset = 0;		/* cursor offset init */
+#endif
 	svsp->scrr_beg = 0;		/* start of scrolling region */
 	svsp->sc_flag = 0;		/* invalidate saved cursor position */
 	svsp->transparent = 0;		/* disable control code processing */
 
 	if(mode == M_HPVT)		/* vt-pure -> hp/vt-mode */
 	{
+		svsp->screen_rows = svsp->screen_rowsize - 3;
+		if (svsp->force24 && svsp->screen_rows == 25)
+			svsp->screen_rows = 24;
+#ifdef HILLY
+		if (svsp->row >= svsp->screen_rows) {
+			/* Scroll up */
+			int nscroll = svsp->row + 1 - svsp->screen_rows;
+			bcopy (svsp->Crtat + nscroll * svsp->maxcol,
+			       svsp->Crtat,
+			       svsp->screen_rows * svsp->maxcol * CHR);
+			svsp->row -= nscroll;
+			svsp->cur_offset -= nscroll * svsp->maxcol;
+		}
+#endif
 		svsp->vt_pure_mode = M_HPVT;
 
-		svsp->vs_tty->t_winsize.ws_row
-			= svsp->screen_rows = svsp->screen_rowsize - 3;
+		svsp->vs_tty->t_winsize.ws_row = svsp->screen_rows;
 
 		svsp->scrr_len = svsp->screen_rows;
 		svsp->scrr_end = svsp->scrr_len - 1;
@@ -1440,14 +1501,23 @@
 	}
 	else if(mode == M_PUREVT)	/* hp/vt-mode -> vt-pure */
 	{
+#ifdef HILLY
+		fillw(user_attr | ' ',
+		      svsp->Crtat + svsp->screen_rows * svsp->maxcol,
+		      (svsp->screen_rowsize - svsp->screen_rows)
+		      * svsp->maxcol);
+#endif
 		svsp->vt_pure_mode = M_PUREVT;
 
-		svsp->vs_tty->t_winsize.ws_row
-			= svsp->screen_rows = svsp->screen_rowsize;
+		svsp->screen_rows = svsp->screen_rowsize;
+		if (svsp->force24 && svsp->screen_rows == 25)
+			svsp->screen_rows = 24;
+
+		svsp->vs_tty->t_winsize.ws_row = svsp->screen_rows;
 
 		svsp->scrr_len = svsp->screen_rows;
 		svsp->scrr_end = svsp->scrr_len - 1;
-	}		
+	}
 
 #if PCVT_SIGWINCH
 	pgsignal(svsp->vs_tty->t_pgrp, SIGWINCH, 1);
@@ -1739,7 +1809,14 @@
 void
 update_hp(struct video_state *svsp)
 {
-	if(svsp->vt_pure_mode != M_HPVT || (!svsp->labels_on))
+	if(svsp->vt_pure_mode != M_HPVT)
+		return;
+
+	fillw (user_attr | ' ',
+	       svsp->Crtat + svsp->screen_rows * svsp->maxcol,
+	       (svsp->screen_rowsize - svsp->screen_rows) * svsp->maxcol);
+
+	if (!svsp->labels_on)
 		return;
 
 	/* update fkey labels */
--- pcvt_kbd.c.orig	Mon Sep 19 23:09:45 1994
+++ pcvt_kbd.c	Fri Nov 18 14:43:23 1994
@@ -866,7 +866,7 @@
 			if(altgr_down)
 				more_chars = (u_char *)thisdef.altgr;
 	
-			else if(shift_down || vsp->shift_lock)
+			else if(!ctrl_down && (shift_down || vsp->shift_lock))
 			{
 				if(key2ascii[key].shift.subtype == STR)
 					more_chars = (u_char *)thisdef.shift;
@@ -2108,6 +2108,8 @@
 		else
 			more_chars = (u_char *)"\033[23~"; /* F11 */
 	}
+	else
+		do_vgapage(4);
 }
 
 /*---------------------------------------------------------------------------*
@@ -2124,6 +2126,8 @@
 		else
 			more_chars = (u_char *)"\033[24~"; /* F12 */
 	}
+	else
+		do_vgapage(5);
 }
 
 /*---------------------------------------------------------------------------*
@@ -2140,6 +2144,8 @@
 		else
 			more_chars = (u_char *)"\033[25~"; /* F13 */
 	}
+	else
+		do_vgapage(6);
 }
 
 /*---------------------------------------------------------------------------*
@@ -2156,6 +2162,8 @@
 		else
 			more_chars = (u_char *)"\033[26~"; /* F14 */
 	}
+	else
+		do_vgapage(7);
 }
 
 /*---------------------------------------------------------------------------*
@@ -2172,6 +2180,13 @@
 		else
 			more_chars = (u_char *)"\033[28~"; /* Help */
 	}
+	else
+	{
+		if(current_video_screen <= 0)
+			do_vgapage(totalscreens-1);
+		else
+			do_vgapage(current_video_screen - 1);
+	}
 }
 
 /*---------------------------------------------------------------------------*
@@ -2317,6 +2332,8 @@
 static void
 cfkey1(void)
 {
+	if(vsp->which_fkl == SYS_FKL)
+		toggl_columns(vsp);
 }
 
 /*---------------------------------------------------------------------------*
@@ -2325,6 +2342,8 @@
 static void
 cfkey2(void)
 {
+	if(vsp->which_fkl == SYS_FKL)
+		vt_ris(vsp);
 }
 
 /*---------------------------------------------------------------------------*
@@ -2333,6 +2352,8 @@
 static void
 cfkey3(void)
 {
+	if(vsp->which_fkl == SYS_FKL)
+		toggl_24l(vsp);
 }
 
 /*---------------------------------------------------------------------------*
@@ -2341,6 +2362,10 @@
 static void
 cfkey4(void)
 {
+#if PCVT_SHOWKEYS
+	if(vsp->which_fkl == SYS_FKL)
+		toggl_kbddbg(vsp);
+#endif /* PCVT_SHOWKEYS */
 }
 
 /*---------------------------------------------------------------------------*
----------------------------- END OF PATCH -----------------------------
>Audit-Trail:
>Unformatted: