To: Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>
Cc: Linux/m68k <linux-m68k@lists.linux-m68k.org>
Subject: Re: L68K: Video patches for 2.1.115
References: <Pine.LNX.4.02A.9808122032190.5829-100000@mercator.cs.kuleuven.ac.be>
X-Yow: Go on, EMOTE!  I was RAISED on thought balloons!!
From: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
Date: 19 Aug 1998 10:18:58 +0200
Sender: owner-linux-m68k@phil.uni-sb.de

Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be> writes:

|>   - Colormap changes, as promised. From now on, {set,get}colreg use 16 bit RGB
|>     values instead of values rounded to the hardware's capabilities. This fixes
|>     the DIRECTCOLOR problem. Note that I DID NOT UPDATE ATAFB, due to my lack
|>     of knowledge about the Atari hardware. Can someone please (please) look at
|>     this?

Here is a patch that (partially) fixes atafb.  Falcon and external is not
yet fixed.  I have also optimized fbcon-iplan2p?.c to use fontheightlog
where possible.

Andreas.

----------------------------------------------------------------------
--- linux/drivers/video/atafb.c.~3~	Tue Aug 18 23:44:35 1998
+++ linux/drivers/video/atafb.c	Wed Aug 19 01:14:19 1998
@@ -682,33 +682,44 @@
 }
 
 
-#error Fix getcolreg/setcolreg
-static int tt_getcolreg( unsigned regno, unsigned *red,
-						 unsigned *green, unsigned *blue,
-						 unsigned *transp, struct fb_info *info )
+static int tt_getcolreg(unsigned regno, unsigned *red,
+			unsigned *green, unsigned *blue,
+			unsigned *transp, struct fb_info *info)
 {
+	int t, col;
+
 	if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH)
 		regno += 254;
 	if (regno > 255)
 		return 1;
-	*blue = tt_palette[regno];
-	*green = (*blue >> 4) & 0xf;
-	*red = (*blue >> 8) & 0xf;
-	*blue &= 0xf;
+	t = tt_palette[regno];
+	col = t & 15;
+	col |= col << 4;
+	col |= col << 8;
+	*blue = col;
+	col = (t >> 4) & 15;
+	col |= col << 4;
+	col |= col << 8;
+	*green = col;
+	col = (t >> 8) & 15;
+	col |= col << 4;
+	col |= col << 8;
+	*red = col;
 	*transp = 0;
 	return 0;
 }
 
 
-static int tt_setcolreg( unsigned regno, unsigned red,
-						 unsigned green, unsigned blue,
-						 unsigned transp, struct fb_info *info )
+static int tt_setcolreg(unsigned regno, unsigned red,
+			unsigned green, unsigned blue,
+			unsigned transp, struct fb_info *info)
 {
 	if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) == TT_SHIFTER_STHIGH)
 		regno += 254;
 	if (regno > 255)
 		return 1;
-	tt_palette[regno] = (red << 8) | (green << 4) | blue;
+	tt_palette[regno] = (((red >> 12) << 8) | ((green >> 12) << 4) |
+			     (blue >> 12));
 	if ((shifter_tt.tt_shiftmode & TT_SHIFTER_MODEMASK) ==
 		TT_SHIFTER_STHIGH && regno == 254)
 		tt_palette[0] = 0;
@@ -1924,35 +1935,51 @@
 }
 
 
-static int stste_getcolreg( unsigned regno, unsigned *red,
-							unsigned *green, unsigned *blue,
-							unsigned *transp, struct fb_info *info )
-{	unsigned col;
+static int stste_getcolreg(unsigned regno, unsigned *red,
+			   unsigned *green, unsigned *blue,
+			   unsigned *transp, struct fb_info *info)
+{
+	unsigned col, t;
 	
 	if (regno > 15)
 		return 1;
 	col = shifter_tt.color_reg[regno];
 	if (ATARIHW_PRESENT(EXTD_SHIFTER)) {
-		*red = ((col >> 7) & 0xe) | ((col >> 11) & 1);
-		*green = ((col >> 3) & 0xe) | ((col >> 7) & 1);
-		*blue = ((col << 1) & 0xe) | ((col >> 3) & 1);
+		t = ((col >> 7) & 0xe) | ((col >> 11) & 1);
+		t |= t << 4;
+		*red = t | (t << 8);
+		t = ((col >> 3) & 0xe) | ((col >> 7) & 1);
+		t |= t << 4;
+		*green = t | (t << 8);
+		t = ((col << 1) & 0xe) | ((col >> 3) & 1);
+		t |= t << 4;
+		*blue = t | (t << 8);
 	}
 	else {
-		*red = (col >> 8) & 0x7;
-		*green = (col >> 4) & 0x7;
-		*blue = col & 0x7;
+		t = (col >> 7) & 0xe;
+		t |= t << 4;
+		*red = t | (t << 8);
+		t = (col >> 3) & 0xe;
+		t |= t << 4;
+		*green = t | (t << 8);
+		t = (col << 1) & 0xe;
+		t |= t << 4;
+		*blue = t | (t << 8);
 	}
 	*transp = 0;
 	return 0;
 }
 
 
-static int stste_setcolreg( unsigned regno, unsigned red,
-						 unsigned green, unsigned blue,
-						 unsigned transp, struct fb_info *info )
+static int stste_setcolreg(unsigned regno, unsigned red,
+			   unsigned green, unsigned blue,
+			   unsigned transp, struct fb_info *info)
 {
 	if (regno > 15)
 		return 1;
+	red >>= 12;
+	blue >>= 12;
+	green >>= 12;
 	if (ATARIHW_PRESENT(EXTD_SHIFTER))
 		shifter_tt.color_reg[regno] =
 			(((red & 0xe) >> 1) | ((red & 1) << 3) << 8) |
@@ -1960,9 +1987,9 @@
 			((blue & 0xe) >> 1) | ((blue & 1) << 3);
 	else
 		shifter_tt.color_reg[regno] =
-			((red & 0x7) << 8) |
-			((green & 0x7) << 4) |
-			(blue & 0x7);
+			((red & 0xe) << 7) |
+			((green & 0xe) << 3) |
+			((blue & 0xe) >> 1);
 	return 0;
 }
 
--- linux/drivers/video/fbcon-iplan2p2.c.~2~	Wed Aug 19 00:10:02 1998
+++ linux/drivers/video/fbcon-iplan2p2.c	Wed Aug 19 00:52:18 1998
@@ -169,16 +169,16 @@
 	/*  Special (but often used) case: Moving whole lines can be
 	 *  done with memmove()
 	 */
-	mymemmove(p->screen_base + dy * p->next_line * fontheight(p),
-		  p->screen_base + sy * p->next_line * fontheight(p),
-		  p->next_line * height * fontheight(p));
+	mymemmove(p->screen_base + ((dy * p->next_line) << fontheightlog(p)),
+		  p->screen_base + ((sy * p->next_line) << fontheightlog(p)),
+		  (p->next_line * height) << fontheightlog(p));
     } else {
 	int rows, cols;
 	u8 *src;
 	u8 *dst;
 	int bytes = p->next_line;
-	int linesize = bytes * fontheight(p);
-	u_int colsize  = height * fontheight(p);
+	int linesize = bytes << fontheightlog(p);
+	u_int colsize  = height << fontheightlog(p);
 	u_int upwards  = (dy < sy) || (dy == sy && dx < sx);
 
 	if ((sx & 1) == (dx & 1)) {
@@ -258,7 +258,7 @@
     u8 *start;
     int rows;
     int bytes = p->next_line;
-    int lines = height * fontheight(p);
+    int lines = height << fontheightlog(p);
     u32 size;
     u32 cval;
     u16 pcval;
@@ -266,11 +266,11 @@
     cval = expand2l (COLOR_2P (attr_bgcol_ec(p,conp)));
 
     if (sx == 0 && width * 2 == bytes) {
-	offset = sy * bytes * fontheight(p);
+	offset = (sy * bytes) << fontheightlog(p);
 	size = lines * bytes;
 	memset_even_2p(p->screen_base+offset, size, cval);
     } else {
-	offset = (sy * bytes * fontheight(p)) + (sx>>1)*4 + (sx & 1);
+	offset = ((sy * bytes) << fontheightlog(p)) + (sx>>1)*4 + (sx & 1);
 	start = p->screen_base + offset;
 	pcval = expand2w(COLOR_2P(attr_bgcol_ec(p,conp)));
 
@@ -306,8 +306,8 @@
     int bytes = p->next_line;
     u16 eorx, fgx, bgx, fdx;
 
-    dest = p->screen_base + yy * fontheight(p) * bytes + (xx>>1)*4 + (xx & 1);
-    cdat = p->fontdata + (c & p->charmask) * fontheight(p);
+    dest = p->screen_base + ((yy * bytes) << fontheightlog(p)) + (xx>>1)*4 + (xx & 1);
+    cdat = p->fontdata + ((c & p->charmask) << fontheightlog(p));
 
     fgx = expand2w(COLOR_2P(attr_fgcol(p,c)));
     bgx = expand2w(COLOR_2P(attr_bgcol(p,c)));
@@ -330,14 +330,14 @@
     u16 eorx, fgx, bgx, fdx;
 
     bytes = p->next_line;
-    dest0 = p->screen_base + yy * fontheight(p) * bytes + (xx>>1)*4 + (xx & 1);
+    dest0 = p->screen_base + ((yy * bytes) << fontheightlog(p)) + (xx>>1)*4 + (xx & 1);
     fgx = expand2w(COLOR_2P(attr_fgcol(p,*s)));
     bgx = expand2w(COLOR_2P(attr_bgcol(p,*s)));
     eorx = fgx ^ bgx;
 
     while (count--) {
 	c = *s++ & p->charmask;
-	cdat  = p->fontdata + (c * fontheight(p));
+	cdat  = p->fontdata + (c << fontheightlog(p));
 
 	for (rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
 	    fdx = dup2w(*cdat++);
@@ -353,8 +353,8 @@
     int j;
     int bytes;
 
-    dest = p->screen_base + yy * fontheight(p) * p->next_line + (xx>>1)*4 +
-	   (xx & 1);
+    dest = (p->screen_base + ((yy * p->next_line) << fontheightlog(p)) +
+	    (xx>>1)*4 + (xx & 1));
     j = fontheight(p);
     bytes = p->next_line;
     while (j--) {
--- linux/drivers/video/fbcon-iplan2p4.c.~2~	Wed Aug 19 00:17:28 1998
+++ linux/drivers/video/fbcon-iplan2p4.c	Wed Aug 19 00:47:07 1998
@@ -177,16 +177,16 @@
 	/*  Special (but often used) case: Moving whole lines can be
 	 *done with memmove()
 	 */
-	mymemmove(p->screen_base + dy * p->next_line * fontheight(p),
-		  p->screen_base + sy * p->next_line * fontheight(p),
-		  p->next_line * height * fontheight(p));
+	mymemmove(p->screen_base + ((dy * p->next_line) << fontheightlog(p)),
+		  p->screen_base + ((sy * p->next_line) << fontheightlog(p)),
+		  (p->next_line * height) << fontheightlog(p));
     } else {
 	int rows, cols;
 	u8 *src;
 	u8 *dst;
 	int bytes = p->next_line;
-	int linesize = bytes * fontheight(p);
-	u_int colsize  = height * fontheight(p);
+	int linesize = bytes << fontheightlog(p);
+	u_int colsize  = height << fontheightlog(p);
 	u_int upwards  = (dy < sy) || (dy == sy && dx < sx);
 
 	if ((sx & 1) == (dx & 1)) {
@@ -269,18 +269,18 @@
     u8 *start;
     int rows;
     int bytes = p->next_line;
-    int lines = height * fontheight(p);
+    int lines = height << fontheightlog(p);
     u32 size;
     u32 cval1, cval2, pcval;
 
     expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2);
 
     if (sx == 0 && width * 4 == bytes) {
-	offset = sy * bytes * fontheight(p);
+	offset = (sy * bytes) << fontheightlog(p);
 	size = lines * bytes;
 	memset_even_4p(p->screen_base+offset, size, cval1, cval2);
     } else {
-	offset = (sy * bytes * fontheight(p)) + (sx>>1)*8 + (sx & 1);
+	offset = ((sy * bytes) << fontheightlog(p)) + (sx>>1)*8 + (sx & 1);
 	start = p->screen_base + offset;
 	pcval = expand4l(attr_bgcol_ec(p,conp));
 
@@ -316,8 +316,8 @@
     int bytes = p->next_line;
     u32 eorx, fgx, bgx, fdx;
 
-    dest = p->screen_base + yy * fontheight(p) * bytes + (xx>>1)*8 + (xx & 1);
-    cdat = p->fontdata + (c & p->charmask) * fontheight(p);
+    dest = p->screen_base + ((yy * bytes) << fontheightlog(p)) + (xx>>1)*8 + (xx & 1);
+    cdat = p->fontdata + ((c & p->charmask) << fontheightlog(p));
 
     fgx = expand4l(attr_fgcol(p,c));
     bgx = expand4l(attr_bgcol(p,c));
@@ -340,7 +340,7 @@
     u32 eorx, fgx, bgx, fdx;
 
     bytes = p->next_line;
-    dest0 = p->screen_base + yy * fontheight(p) * bytes + (xx>>1)*8 + (xx & 1);
+    dest0 = p->screen_base + ((yy * bytes) << fontheightlog(p)) + (xx>>1)*8 + (xx & 1);
     fgx = expand4l(attr_fgcol(p,*s));
     bgx = expand4l(attr_bgcol(p,*s));
     eorx = fgx ^ bgx;
@@ -354,7 +354,7 @@
 	*/
 
 	c = *s++ & p->charmask;
-	cdat  = p->fontdata + (c * fontheight(p));
+	cdat  = p->fontdata + (c << fontheightlog(p));
 
 	for(rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
 	    fdx = dup4l(*cdat++);
@@ -370,8 +370,8 @@
     int j;
     int bytes;
 
-    dest = p->screen_base + yy * fontheight(p) * p->next_line + (xx>>1)*8 +
-	   (xx & 1);
+    dest = (p->screen_base + ((yy * p->next_line) << fontheightlog(p)) +
+	    (xx>>1)*8 + (xx & 1));
     j = fontheight(p);
     bytes = p->next_line;
 
--- linux/drivers/video/fbcon-iplan2p8.c.~2~	Wed Aug 19 00:19:01 1998
+++ linux/drivers/video/fbcon-iplan2p8.c	Wed Aug 19 00:49:54 1998
@@ -209,16 +209,16 @@
 	/*  Special (but often used) case: Moving whole lines can be
 	 *  done with memmove()
 	 */
-	fast_memmove(p->screen_base + dy * p->next_line * fontheight(p),
-		     p->screen_base + sy * p->next_line * fontheight(p),
-		     p->next_line * height * fontheight(p));
+	fast_memmove(p->screen_base + ((dy * p->next_line) << fontheightlog(p)),
+		     p->screen_base + ((sy * p->next_line) << fontheightlog(p)),
+		     (p->next_line * height) << fontheightlog(p));
      } else {
 	int rows, cols;
 	u8 *src;
 	u8 *dst;
 	int bytes = p->next_line;
-	int linesize = bytes * fontheight(p);
-	u_int colsize = height * fontheight(p);
+	int linesize = bytes << fontheightlog(p);
+	u_int colsize = height << fontheightlog(p);
 	u_int upwards = (dy < sy) || (dy == sy && dx < sx);
 
 	if ((sx & 1) == (dx & 1)) {
@@ -301,18 +301,18 @@
     u8 *start;
     int rows;
     int bytes = p->next_line;
-    int lines = height * fontheight(p);
+    int lines = height << fontheightlog(p);
     u32 size;
     u32 cval1, cval2, cval3, cval4, pcval1, pcval2;
 
     expand8ql(attr_bgcol_ec(p,conp), &cval1, &cval2, &cval3, &cval4);
 
     if (sx == 0 && width * 8 == bytes) {
-	offset = sy * bytes * fontheight(p);
+	offset = (sy * bytes) << fontheightlog(p);
 	size    = lines * bytes;
 	memset_even_8p(p->screen_base+offset, size, cval1, cval2, cval3, cval4);
     } else {
-	offset = (sy * bytes * fontheight(p)) + (sx>>1)*16 + (sx & 1);
+	offset = ((sy * bytes) << fontheightlog(p)) + (sx>>1)*16 + (sx & 1);
 	start = p->screen_base + offset;
 	expand8dl(attr_bgcol_ec(p,conp), &pcval1, &pcval2);
 
@@ -348,8 +348,8 @@
     int bytes = p->next_line;
     u32 eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
 
-    dest = p->screen_base + yy * fontheight(p) * bytes + (xx>>1)*16 + (xx & 1);
-    cdat = p->fontdata + (c & p->charmask) * fontheight(p);
+    dest = p->screen_base + ((yy * bytes) << fontheightlog(p)) + (xx>>1)*16 + (xx & 1);
+    cdat = p->fontdata + ((c & p->charmask) << fontheightlog(p));
 
     expand8dl(attr_fgcol(p,c), &fgx1, &fgx2);
     expand8dl(attr_bgcol(p,c), &bgx1, &bgx2);
@@ -372,7 +372,7 @@
     u32 eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
 
     bytes = p->next_line;
-    dest0 = p->screen_base + yy * fontheight(p) * bytes + (xx>>1)*16 +
+    dest0 = p->screen_base + ((yy * bytes) << fontheightlog(p)) + (xx>>1)*16 +
 	    (xx & 1);
 
     expand8dl(attr_fgcol(p,*s), &fgx1, &fgx2);
@@ -389,7 +389,7 @@
 	*/
 
 	c = *s++ & p->charmask;
-	cdat  = p->fontdata + (c * fontheight(p));
+	cdat  = p->fontdata + (c << fontheightlog(p));
 
 	for(rows = fontheight(p), dest = dest0; rows-- ; dest += bytes) {
 	    fdx = dup4l(*cdat++);
@@ -405,8 +405,8 @@
     int j;
     int bytes;
 
-    dest = p->screen_base + yy * fontheight(p) * p->next_line + (xx>>1)*16 +
-	   (xx & 1);
+    dest = (p->screen_base + ((yy * p->next_line) << fontheightlog(p)) +
+	    (xx>>1)*16 + (xx & 1));
     j = fontheight(p);
     bytes = p->next_line;
 

-- 
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
schwab@gnu.org
