patch-2.1.110 linux/drivers/video/creatorfb.c

Next file: linux/drivers/video/cyberfb.c
Previous file: linux/drivers/video/compatcon.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.109/linux/drivers/video/creatorfb.c linux/drivers/video/creatorfb.c
@@ -1,4 +1,4 @@
-/* $Id: creatorfb.c,v 1.4 1998/07/06 15:51:10 jj Exp $
+/* $Id: creatorfb.c,v 1.5 1998/07/13 12:47:12 jj Exp $
  * creatorfb.c: Creator/Creator3D frame buffer driver
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -177,35 +177,6 @@
 	p->next_plane = 0;
 }
 
-static void ffb_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			   int height, int width)
-{
-	int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
-	u8 *src, *dst;
-
-	if (sx == 0 && dx == 0 && width * 32 == bytes)
-		mymemmove(p->screen_base + dy * linesize,
-				  p->screen_base + sy * linesize,
-				  height * linesize);
-	else if (dy < sy || (dy == sy && dx < sx)) {
-		src = p->screen_base + sy * linesize + sx * 32;
-		dst = p->screen_base + dy * linesize + dx * 32;
-		for (rows = height * p->fontheight ; rows-- ;) {
-			mymemmove(dst, src, width * 32);
-			src += bytes;
-			dst += bytes;
-		}
-	} else {
-		src = p->screen_base + (sy+height) * linesize + sx * 32 - bytes;
-		dst = p->screen_base + (dy+height) * linesize + dx * 32 - bytes;
-		for (rows = height * p->fontheight ; rows-- ;) {
-			mymemmove(dst, src, width * 32);
-			src -= bytes;
-			dst -= bytes;
-		}
-	}
-}
-
 static void ffb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
 		      int height, int width)
 {
@@ -221,12 +192,16 @@
 	fbc->unk2 = 8;
 
 	/* FIXME: Optimize this by allowing 8/16 fontheigh only and introduce p->fontheightlog */
-	if (p->fontheight == 16) {
-		y = sy << 4; h = height << 4;
+	if (p->fontheightlog) {
+		y = sy << p->fontheightlog; h = height << p->fontheightlog;
 	} else {
 		y = sy * p->fontheight; h = height * p->fontheight;
 	}
-	x = sx << 3; w = width << 3;
+	if (p->fontwidthlog) {
+		x = sx << p->fontwidthlog; w = width << p->fontwidthlog;
+	} else {
+		x = sx * p->fontwidth; w = width * p->fontwidth;
+	}
 	fbc->by = y + fb->y_margin;
 	fbc->bx = x + fb->x_margin;
 	fbc->bh = h;
@@ -260,25 +235,39 @@
 	int i, xy;
 	u8 *fd;
 
-	if (p->fontheight == 16) {
-		xy = (yy << (16 + 4));
-		fd = p->fontdata + ((c & 0xff) << 4);
+	if (p->fontheightlog) {
+		xy = (yy << (16 + p->fontheightlog));
+		i = ((c & 0xff) << p->fontheightlog);
 	} else {
 		xy = ((yy * p->fontheight) << 16);
-		fd = p->fontdata + (c & 0xff) * p->fontheight;
+		i = (c & 0xff) * p->fontheight;
 	}
-	xy += (xx << 3) + fb->s.ffb.xy_margin;
+	if (p->fontwidth <= 8)
+		fd = p->fontdata + i;
+	else
+		fd = p->fontdata + (i << 1);
+	if (p->fontwidthlog)
+		xy += (xx << p->fontwidthlog) + fb->s.ffb.xy_margin;
+	else
+		xy += (xx * p->fontwidth) + fb->s.ffb.xy_margin;
 	fbc->ppc = 0x203;
 	fbc->fg = ffb_cmap[attr_fg_col(c)];
 	fbc->fbc = 0x2000707f;
 	fbc->rop = 0x83;
 	fbc->pmask = 0xffffffff;
 	fbc->bg = ffb_cmap[attr_bg_col(c)];
-	fbc->fontw = 8;
+	fbc->fontw = p->fontwidth;
 	fbc->fontinc = 0x10000;
 	fbc->fontxy = xy;
-	for (i = 0; i < p->fontheight; i++)
-		fbc->font = *fd++ << 24;
+	if (p->fontwidth <= 8) {
+		for (i = 0; i < p->fontheight; i++)
+			fbc->font = *fd++ << 24;
+	} else {
+		for (i = 0; i < p->fontheight; i++) {
+			fbc->font = *(u16 *)fd << 16;
+			fd += 2;
+		}
+	}
 }
 
 static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
@@ -295,75 +284,91 @@
 	fbc->rop = 0x83;
 	fbc->pmask = 0xffffffff;
 	fbc->bg = ffb_cmap[attr_bg_col(*s)];
-	if (p->fontheight == 16) {
-		xy = (yy << (16 + 4)) + (xx << 3) + fb->s.ffb.xy_margin;
+	xy = fb->s.ffb.xy_margin;
+	if (p->fontwidthlog)
+		xy += (xx << p->fontwidthlog);
+	else
+		xy += xx * p->fontwidth;
+	if (p->fontheightlog)
+		xy += (yy << (16 + p->fontheightlog));
+	else
+		xy += ((yy * p->fontheight) << 16);
+	if (p->fontwidth <= 8) {
 		while (count >= 4) {
 			count -= 4;
-			fbc->fontw = 32;
+			fbc->fontw = 4 * p->fontwidth;
 			fbc->fontinc = 0x10000;
 			fbc->fontxy = xy;
-			fd1 = p->fontdata + ((*s++ & 0xff) << 4);
-			fd2 = p->fontdata + ((*s++ & 0xff) << 4);
-			fd3 = p->fontdata + ((*s++ & 0xff) << 4);
-			fd4 = p->fontdata + ((*s++ & 0xff) << 4);
-			for (i = 0; i < 16; i++)
-				fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) << 8)) << 8)) << 8);
-			xy += 32;
-		}
-		while (count) {
-			count--;
-			fbc->fontw = 8;
-			fbc->fontinc = 0x10000;
-			fbc->fontxy = xy;
-			fd1 = p->fontdata + ((*s++ & 0xff) << 4);
-			for (i = 0; i < 16; i++)
-				fbc->font = *fd1++ << 24;
-			xy += 8;
+			if (p->fontheightlog) {
+				fd1 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+				fd2 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+				fd3 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+				fd4 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+			} else {
+				fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+				fd2 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+				fd3 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+				fd4 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+			}
+			if (p->fontwidth == 8) {
+				for (i = 0; i < p->fontheight; i++)
+					fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 
+						<< 8)) << 8)) << 8);
+				xy += 32;
+			} else {
+				for (i = 0; i < p->fontheight; i++)
+					fbc->font = (((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 
+						<< p->fontwidth)) << p->fontwidth)) << p->fontwidth)) << (24 - 3 * p->fontwidth);
+				xy += 4 * p->fontwidth;
+			}
 		}
 	} else {
-		xy = ((yy * p->fontheight) << 16) + (xx << 3) + fb->s.ffb.xy_margin;
-		while (count >= 4) {
-			count -= 4;
-			fbc->fontw = 32;
+		while (count >= 2) {
+			count -= 2;
+			fbc->fontw = 2 * p->fontwidth;
 			fbc->fontinc = 0x10000;
 			fbc->fontxy = xy;
-			fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-			fd2 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-			fd3 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-			fd4 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-			for (i = 0; i < p->fontheight; i++)
-				fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) << 8)) << 8)) << 8);
-			xy += 32;
+			if (p->fontheightlog) {
+				fd1 = p->fontdata + ((*s++ & 0xff) << (p->fontheightlog + 1));
+				fd2 = p->fontdata + ((*s++ & 0xff) << (p->fontheightlog + 1));
+			} else {
+				fd1 = p->fontdata + (((*s++ & 0xff) * p->fontheight) << 1);
+				fd2 = p->fontdata + (((*s++ & 0xff) * p->fontheight) << 1);
+			}
+			for (i = 0; i < p->fontheight; i++) {
+				fbc->font = ((((u32)*(u16 *)fd1) << p->fontwidth) | ((u32)*(u16 *)fd2)) << (16 - p->fontwidth);
+				fd1 += 2; fd2 += 2;
+			}
+			xy += 2 * p->fontwidth;
 		}
-		while (count) {
-			count--;
-			fbc->fontw = 8;
-			fbc->fontinc = 0x10000;
-			fbc->fontxy = xy;
-			fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
-			for (i = 0; i < 16; i++)
+	}
+	while (count) {
+		count--;
+		fbc->fontw = p->fontwidth;
+		fbc->fontinc = 0x10000;
+		fbc->fontxy = xy;
+		if (p->fontheightlog)
+			i = ((*s++ & 0xff) << p->fontheightlog);
+		else
+			i = ((*s++ & 0xff) * p->fontheight);
+		if (p->fontwidth <= 8) {
+			fd1 = p->fontdata + i;
+			for (i = 0; i < p->fontheight; i++)
 				fbc->font = *fd1++ << 24;
-			xy += 8;
+		} else {
+			fd1 = p->fontdata + (i << 1);
+			for (i = 0; i < p->fontheight; i++) {
+				fbc->font = *(u16 *)fd1 << 16;
+				fd1 += 2;
+			}
 		}
+		xy += p->fontwidth;
 	}
 }
 
 static void ffb_revc(struct display *p, int xx, int yy)
 {
-	u8 *dest;
-	int bytes = p->next_line, rows;
-
-	dest = p->screen_base + yy * p->fontheight * bytes + xx * 32;
-	for (rows = p->fontheight ; rows-- ; dest += bytes) {
-		((u32 *)dest)[0] ^= 0xffffffff;
-		((u32 *)dest)[1] ^= 0xffffffff;
-		((u32 *)dest)[2] ^= 0xffffffff;
-		((u32 *)dest)[3] ^= 0xffffffff;
-		((u32 *)dest)[4] ^= 0xffffffff;
-		((u32 *)dest)[5] ^= 0xffffffff;
-		((u32 *)dest)[6] ^= 0xffffffff;
-		((u32 *)dest)[7] ^= 0xffffffff;
-	}
+	/* Not used if hw cursor */
 }
 
 static void ffb_loadcmap (struct fb_info_sbusfb *fb, int index, int count)
@@ -384,9 +389,16 @@
 }
 
 static struct display_switch ffb_dispsw __initdata = {
-	ffb_setup, ffb_bmove, ffb_clear, ffb_putc, ffb_putcs, ffb_revc, NULL
+	ffb_setup, fbcon_redraw_bmove, ffb_clear, ffb_putc, ffb_putcs, ffb_revc, 
+	NULL, NULL, FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */
 };
 
+static void ffb_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
+{
+	fb->s.ffb.xy_margin = (y_margin << 16) + x_margin;
+	p->screen_base += 8192 * (y_margin - fb->y_margin) + 4 * (x_margin - fb->x_margin);
+}
+
 static inline void ffb_curs_enable (struct fb_info_sbusfb *fb, int enable)
 {
 	struct ffb_dac *dac = fb->s.ffb.dac;
@@ -478,6 +490,7 @@
 	fb->s.ffb.dac = (struct ffb_dac *)((char *)__va(regs[0].phys_addr) + FFB_DAC_POFF);
 	fb->dispsw = ffb_dispsw;
 
+	fb->margins = ffb_margins;
 	fb->loadcmap = ffb_loadcmap;
 	fb->setcursor = ffb_setcursor;
 	fb->setcursormap = ffb_setcursormap;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov