Subject: port-alpha/13796: display problems on TGA console
To: None <gnats-bugs@gnats.netbsd.org>
From: Christian Groessler <cpg@aladdin.de>
List: netbsd-bugs
Date: 08/27/2001 22:52:27
>Number:         13796
>Category:       port-alpha
>Synopsis:       display problems on TGA console
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-alpha-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Aug 27 13:49:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Christian Groessler
>Release:        NetBSD-current 24-aug-01
>Organization:
	
>Environment:
	
System: NetBSD alpha 1.5X NetBSD 1.5X (SIXTYFOUR) #0: Sun Aug 26 02:38:56 CEST 2001 chris@alpha:/net/swamp/zeug/netbsd-chkout/sys/arch/alpha/compile/SIXTYFOUR alpha
Architecture: alpha
Machine: alpha
>Description:
	Sometimes when scrolling a line to the right (e.g. with bash)
the display gets garbled. This depends on the lenght of the line and
where the scrolling starts.
>How-To-Repeat:
	- use e.g. bash
	- type very long command line (almost whole x size)
	- put the cursor somewhere in the right third of the line and
	  type characters, causing the right part of the line to be
	  scrolled to the right
	- watch garbage displayed at start of the line
>Fix:
	The problem was, the after the for loops for scrolling right
in tga_rop_vtov (sys/dev/pci/tga.c) there was no check whether x
really has been decremented by the loop (it wouldn't if the loop
condition initially was not met) and always "fixed" that
decrementing.

	Here's a patch:

	Index: tga.c
===================================================================
RCS file: /net/swamp/zeug/netbsd-rsync/main/syssrc/sys/dev/pci/tga.c,v
retrieving revision 1.35
diff -u -p -r1.35 tga.c
--- tga.c	2001/08/05 18:07:54	1.35
+++ tga.c	2001/08/18 00:32:44
@@ -1057,6 +1058,7 @@ tga_rop_vtov(dst, dx, dy, w, h, rop, src
 	int xstart, xend, xdir;
 	int ystart, yend, ydir, yinc;
 	int xleft, lastx, lastleft;
+	int adjust, adjust2 = 0;
 	int offset = 1 * dc->dc_tgaconf->tgac_vvbr_units;
 
 	/*
@@ -1118,8 +1120,10 @@ tga_rop_vtov(dst, dx, dy, w, h, rop, src
 
 		for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
 
+			xleft = wb;
+
 			/* 4*64 byte chunks */
-			for (xleft = wb, x = xstart;
+			for (x = xstart;
 			     x <= xend && xleft >= 4*64;
 			     x += XINC256, xleft -= XINC256) {
 
@@ -1165,8 +1169,10 @@ tga_rop_vtov(dst, dx, dy, w, h, rop, src
 
 		for (y = ystart; (ydir * y) <= (ydir * yend); y += yinc) {
 
+			xleft = wb;
+
 			/* 4*64 byte chunks */
-			for (xleft = wb, x = xstart;
+			for (x = xstart, adjust = 0;
 			     x >= xend && xleft >= 4*64;
 			     x -= XINC256, xleft -= XINC256) {
 
@@ -1184,17 +1190,24 @@ tga_rop_vtov(dst, dx, dy, w, h, rop, src
 				TGAWALREG(dc, TGA_REG_GCDR, 2, tga_dstb + y + x + 1 * 64);
 				TGAWALREG(dc, TGA_REG_GCSR, 3, tga_srcb + y + x + 0 * 64);
 				TGAWALREG(dc, TGA_REG_GCDR, 3, tga_dstb + y + x + 0 * 64);
+				adjust = 1;
 			}
 
-			if (xleft) x += XINC256 - XINC64;
+			if (adjust) {
+				if (xleft) x += XINC256;
+				if (xleft >= XINC64) x -= XINC64;
+				adjust2 = 1;
+			}
 
 			/* 64 byte chunks */
-			for ( ; x >= xend && xleft >= 64;
-			      x -= XINC64, xleft -= XINC64) {
+			for (adjust = 0; x >= xend && xleft >= 64;
+			     x -= XINC64, xleft -= XINC64) {
 				TGAWALREG(dc, TGA_REG_GCSR, 0, tga_srcb + y + x + 0 * 64);
 				TGAWALREG(dc, TGA_REG_GCDR, 0, tga_dstb + y + x + 0 * 64);
+				adjust = 1;
 			}
-			if (xleft) x += XINC64 - XINC4;
+			if (xleft && adjust) x += XINC64;
+			if (xleft >= XINC4 && (adjust || adjust2))  x -= XINC4;
 			lastx = x; lastleft = xleft;  /* remember for CPU loop */
 		}
 		TGAWALREG(dc, TGA_REG_GOPR, 0, 0x0003); /* op -> dst = src */

>Release-Note:
>Audit-Trail:
>Unformatted: