From: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
Date: Fri, 14 Feb 97 10:26:44 +0100
To: linux-m68k@phil.uni-sb.de
Subject: L68K: Abscon patch update and bug fix
X-Yow: ..  does your DRESSING ROOM have enough ASPARAGUS?
Sender: owner-linux-m68k@phil.uni-sb.de
Reply-To: schwab@issan.informatik.uni-dortmund.de

Hi!

Here is an patch for drivers/char/console.c with the abscon patch that
brings it uptodate with 2.1.26 and fixes a few bugs:

- drawing the video_erase_char with con_putc should use its attributes,
  not the current ones,
- CSI @ is broken (WYSINAWYG: what you see is not always what you get :-) ),
- the bound checks of the repeat count in CSI M, CSI L and CSI P are not
  strong enough.

Additionally i converted a few loop into calls to memsetw.

Andreas.

----------------------------------------------------------------------
--- drivers/char/abscon.c.~1~	Thu Feb 13 12:25:47 1997
+++ drivers/char/abscon.c	Thu Feb 13 12:40:04 1997
@@ -114,6 +114,10 @@
 	return(conswitchp->con_startup(kmem_start, display_desc));
 }
 
+void con_type_init_finish(void)
+{
+}
+
 void set_vesa_blanking(int arg)
 {
 	char *argp = (char *)arg + 1;
--- drivers/char/console.c.geert	Thu Feb 13 12:35:31 1997
+++ drivers/char/console.c	Thu Feb 13 14:09:22 1997
@@ -62,6 +62,8 @@
  * User-defined bell sound, new setterm control sequences and printk
  * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
  *
+ * APM screenblank bug fixed Takashi Manabe <manabe@roy.dsl.tutics.tut.jp>
+ *
  * Merge with the abstract console driver (m68k) by Geert Uytterhoeven
  * <Geert.Uytterhoeven@cs.kuleuven.ac.be>, Jan 1997.
  *
@@ -175,8 +177,10 @@
 extern void reset_palette(int currcons);
 extern void set_palette(void);
 extern unsigned long con_type_init(unsigned long, const char **);
+extern void con_type_init_finish(void);
 extern int set_get_cmap(unsigned char *, int);
 extern int set_get_font(unsigned char *, int, int);
+extern void rs_cons_hook(int chip, int out, int channel);
 
 static int printable = 0;		/* Is console ready for printing? */
 
@@ -248,20 +252,28 @@
 
 static inline void abscon_insert_chars(int currcons, unsigned int nr)
 {
+    unsigned short oldattr;
     if (currcons != fg_console)
 	return;
     sw->con_bmove(vc_cons[currcons].d,y,x,y,x+nr,1,video_num_columns-x-nr);
+    oldattr = attr;
+    attr = video_erase_char >> 8;
     while (nr--)
 	sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,x+nr);
+    attr = oldattr;
 }
 
 static inline void abscon_delete_chars(int currcons, unsigned int nr)
 {
+    unsigned short oldattr;
     if (currcons != fg_console)
 	return;
     sw->con_bmove(vc_cons[currcons].d,y,x+nr,y,x,1,video_num_columns-x-nr);
+    oldattr = attr;
+    attr = video_erase_char >> 8;
     while (nr--)
 	sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,video_num_columns-1-nr);
+    attr = oldattr;
 }
 
 static inline void abscon_putc(int currcons, int tc, int yy, int xx)
@@ -836,7 +848,6 @@
 {
 #ifdef CONFIG_ABSTRACT_CONSOLE
 	unsigned short *p;
-	int i;
 
 	if (b > video_num_lines || t >= b)
 		return;
@@ -844,8 +855,7 @@
 		(unsigned short *)video_mem_start + (t + nr) * video_num_columns,
 		(b - t - nr) * video_num_columns * 2);
 	p = (unsigned short *)video_mem_start + (b - nr) * video_num_columns;
-	for (i = nr * video_num_columns; i > 0; i--)
-	  *p++ = video_erase_char;
+	memsetw(p, video_erase_char, nr * video_size_row);
 	if (currcons != fg_console)
 	  return;
 	sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr);
@@ -896,17 +906,9 @@
 	} else {
 		unsigned short * d = (unsigned short *) (origin+video_size_row*t);
 		unsigned short * s = (unsigned short *) (origin+video_size_row*(t+nr));
-		unsigned int count = (b-t-nr) * video_num_columns;
 
-		while (count) {
-			count--;
-			scr_writew(scr_readw(s++), d++);
-		}
-		count = nr*video_num_columns;
-		while (count) {
-			count--;
-			scr_writew(video_erase_char, d++);
-		}
+		memcpyw(d, s, (b-t-nr) * video_size_row);
+		memsetw(d + (b-t-nr) * video_num_columns, video_erase_char, video_size_row);
 	}
 #endif /* !CONFIG_ABSTRACT_CONSOLE */
 }
@@ -916,7 +918,6 @@
 {
 #ifdef CONFIG_ABSTRACT_CONSOLE
 	unsigned short *p;
-	int i;
 
 	if (b > video_num_lines || t >= b)
 		return;
@@ -924,29 +925,26 @@
 		(unsigned short *)video_mem_start + t * video_num_columns,
 		(b - t - nr) * video_num_columns * 2);
 	p = (unsigned short *)video_mem_start + t * video_num_columns;
-	for (i = nr * video_num_columns; i > 0; i--)
-	  *p++ = video_erase_char;
+	memsetw(p, video_erase_char, nr * video_size_row);
 	if (currcons != fg_console)
 	  return;
 	sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr);
 #else /* !CONFIG_ABSTRACT_CONSOLE */
-	unsigned short *d, *s;
+	unsigned short *s;
 	unsigned int count;
 
 	if (b > video_num_lines || t >= b)
 		return;
-	d = (unsigned short *) (origin+video_size_row*b);
-	s = (unsigned short *) (origin+video_size_row*(b-nr));
-	count = (b-t-nr)*video_num_columns;
-	while (count) {
-		count--;
-		scr_writew(scr_readw(--s), --d);
-	}
-	count = nr*video_num_columns;
-	while (count) {
-		count--;
-		scr_writew(video_erase_char, --d);
+	s = (unsigned short *) (origin+video_size_row*(b-1-nr));
+	if (b >= t + nr) {
+		count = b - t - nr;
+		while (count) {
+			count--;
+			memcpyw(s + video_num_columns, s, video_size_row);
+			s -= video_num_columns;
+		}
 	}
+	memsetw(s + nr*video_num_columns, video_erase_char, video_size_row);
 	has_scrolled = 1;
 #endif /* !CONFIG_ABSTRACT_CONSOLE */
 }
@@ -1023,10 +1021,7 @@
 		default:
 			return;
 	}
-	while (count) {
-		count--;
-		scr_writew(video_erase_char, start++);
-	}
+	memsetw(start, video_erase_char, 2*count);
 	need_wrap = 0;
 }
 
@@ -1054,29 +1049,20 @@
 		default:
 			return;
 	}
-	while (count) {
-		count--;
-		scr_writew(video_erase_char, start++);
-	}
+	memsetw(start, video_erase_char, 2 * count);
 	need_wrap = 0;
 }
 
 static void csi_X(int currcons, int vpar) /* erase the following vpar positions */
 {					  /* not vt100? */
-	unsigned long count;
-	unsigned short * start;
+	int count;
 
 	if (!vpar)
 		vpar++;
-
-	start = (unsigned short *) pos;
 	count = (vpar > video_num_columns-x) ? (video_num_columns-x) : vpar;
 
 	ABSCON(erase_next_chars(currcons, count));
-	while (count) {
-		count--;
-		scr_writew(video_erase_char, start++);
-	}
+	memsetw((unsigned short *) pos, video_erase_char, 2 * count);
 	need_wrap = 0;
 }
 
@@ -1529,7 +1515,7 @@
 #if 0 /* no longer used */
 static void insert_line(int currcons)
 {
-	scrdown(currcons,y,bottom);
+	scrdown(currcons,y,bottom,1);
 	need_wrap = 0;
 }
 
@@ -1549,7 +1535,7 @@
 
 static void delete_line(int currcons)
 {
-	scrup(currcons,y,bottom);
+	scrup(currcons,y,bottom,1);
 	need_wrap = 0;
 }
 #endif /* no longer used */
@@ -1563,23 +1549,21 @@
 		nr = video_num_columns - x;
 	else if (!nr)
 		nr = 1;
-	i = video_num_columns-2-x;
-	p = (unsigned short *)pos;
+	i = video_num_columns-nr-x;
+	p = (unsigned short *)pos + i;
 	while (i--) {
-		scr_writew(scr_readw(p), p+i);
 		p--;
+		scr_writew(scr_readw(p), p+nr);
 	}
-	i = nr;
-	while (i--)
-		scr_writew(video_erase_char, p--);
+	memsetw(p, video_erase_char, 2 * nr);
 	need_wrap = 0;
 	ABSCON(insert_chars(currcons, nr));
 }
 
 static void csi_L(int currcons, unsigned int nr)
 {
-	if (nr > video_num_lines)
-		nr = video_num_lines;
+	if (nr > video_num_lines - y)
+		nr = video_num_lines - y;
 	else if (!nr)
 		nr = 1;
 	scrdown(currcons,y,bottom,nr);
@@ -1591,27 +1575,25 @@
 	unsigned int i;
 	unsigned short *p;
 
-	if (nr > video_num_columns)
-		nr = video_num_columns;
+	if (nr > video_num_columns - x)
+		nr = video_num_columns - x;
 	else if (!nr)
 		nr = 1;
-	i = x;
+	i = video_num_columns-nr-x;
 	p = (unsigned short *)pos;
-	while (++i < video_num_columns-nr+1) {
+	while (i--) {
 		scr_writew(scr_readw(p+nr), p);
 		p++;
 	}
-	i = nr;
-	while (i--)
-		scr_writew(video_erase_char, p++);
+	memsetw(p, video_erase_char, 2 * nr);
 	need_wrap = 0;
 	ABSCON(delete_chars(currcons, nr));
 }
 
 static void csi_M(int currcons, unsigned int nr)
 {
-	if (nr > video_num_lines)
-		nr = video_num_lines;
+	if (nr > video_num_lines - y)
+		nr = video_num_lines - y;
 	else if (!nr)
 		nr=1;
 	scrup(currcons,y,bottom,nr);
@@ -1715,8 +1697,10 @@
 	console_num = MINOR(tty->device) - (tty->driver.minor_start);
 	if (!vc_cons_allocated(console_num))
 		return;
+#if !CONFIG_AP1000
 	set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
 	set_leds();
+#endif
 }
 
 /*
@@ -1730,8 +1714,10 @@
 	console_num = MINOR(tty->device) - (tty->driver.minor_start);
 	if (!vc_cons_allocated(console_num))
 		return;
+#if !CONFIG_AP1000
 	clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
 	set_leds();
+#endif
 }
 
 static void con_flush_chars(struct tty_struct *tty)
@@ -1751,6 +1737,11 @@
 	unsigned int currcons;
 	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
 
+#if CONFIG_AP1000
+        ap_write(1,buf,count);
+        return(count);
+#endif
+
 	currcons = vt->vc_num;
 	if (!vc_cons_allocated(currcons)) {
 	    /* could this happen? */
@@ -2357,6 +2348,10 @@
 	ushort myx        = x;
 #endif /* CONFIG_ABSTRACT_CONSOLE */
 
+#if CONFIG_AP1000
+        prom_printf(b);
+        return;
+#endif
 	if (!printable || printing)
 		return;	 /* console not yet initialized */
 	printing = 1;
@@ -2531,6 +2526,19 @@
 	const char *display_desc = "????";
 	unsigned int currcons = 0;
 
+#ifdef __sparc__
+	if (serial_console) {
+		fg_console = 0;
+
+#if CONFIG_SUN_SERIAL
+		rs_cons_hook(0, 0, serial_console);
+		rs_cons_hook(0, 1, serial_console);
+#endif
+
+		return kmem_start;
+	}
+#endif
+
 	memset(&console_driver, 0, sizeof(struct tty_driver));
 	console_driver.magic = TTY_DRIVER_MAGIC;
 	console_driver.name = "tty";
@@ -2561,6 +2569,9 @@
 	if (tty_register_driver(&console_driver))
 		panic("Couldn't register console driver\n");
 
+#if CONFIG_AP1000
+        return(kmem_start);
+#endif
 #ifndef CONFIG_ABSTRACT_CONSOLE
 	video_num_lines = ORIG_VIDEO_LINES;
 	video_num_columns = ORIG_VIDEO_COLS;
@@ -2631,7 +2642,8 @@
 	   a different font */
 
 	if ( video_type == VIDEO_TYPE_VGAC || video_type == VIDEO_TYPE_EGAC
-	    || video_type == VIDEO_TYPE_EGAM || video_type == VIDEO_TYPE_TGAC )
+	    || video_type == VIDEO_TYPE_EGAM || video_type == VIDEO_TYPE_TGAC 
+	     || video_type == VIDEO_TYPE_SUN )
 	{
 		default_font_height = video_font_height = ORIG_VIDEO_POINTS;
 		/* This may be suboptimal but is a safe bet - go with it */
@@ -2652,6 +2664,8 @@
 		MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s",
 	        MAX_NR_CONSOLES);
 
+	con_type_init_finish();
+
 	if (1
 #ifdef CONFIG_SERIAL_CONSOLE
 	    && !serial_console
@@ -2668,7 +2682,7 @@
 	 */
 	    && video_type != VIDEO_TYPE_TGAC
 #endif /* !CONFIG_ABSTRACT_CONSOLE */
-	    && 1)
+	    )
 	    register_console(console_print);
 
 	init_bh(CONSOLE_BH, console_bh);
@@ -2724,12 +2738,15 @@
 	hide_cursor(fg_console);
 #endif /* !CONFIG_ABSTRACT_CONSOLE */
 	console_blanked = fg_console + 1;
+
+	if(!nopowersave)
+	{
 #ifdef CONFIG_APM
-	if (apm_display_blank())
-		return;
+		if (apm_display_blank())
+			return;
 #endif
-	if(!nopowersave)
-	    vesa_blank();
+		vesa_blank();
+	}
 }
 
 void do_unblank_screen(void)
