Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 May 2005 21:52:13 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 76946 for review
Message-ID:  <200505132152.j4DLqDx9019001@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=76946

Change 76946 by marcel@marcel_nfs on 2005/05/13 21:51:51

	Implement BitBlt operations CTOFB, FBTOFB and H1TOFB. Both CTOFB
	and FBTOFB use write mode 0. H1TOFB uses write mode 3.
	
	The implementation is not feature complete. It is assumed for now
	that the width is always a multiple of 8 bits and that the
	bit offset is also a multiple of 8. Some VGA magic with masks and
	rotate registers is needed to handle all possible cases. As long
	as we're using fonts of width 8, this is not an issue so we're
	good for now.

Affected files ...

.. //depot/projects/tty/sys/dev/vga/vga.c#11 edit

Differences ...

==== //depot/projects/tty/sys/dev/vga/vga.c#11 (text+ko) ====

@@ -33,6 +33,7 @@
 #include <machine/resource.h>
 #include <sys/bus.h>
 #include <sys/rman.h>
+#include <sys/vtc.h>
 
 #include <dev/ic/vga.h>
 #include <dev/vga/vga.h>
@@ -186,7 +187,7 @@
 	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_SET_RESET);
 	REG_WRITE(sc, VGA_GC_DATA, 0);
 	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_ENABLE_SET_RESET);
-	REG_WRITE(sc, VGA_GC_DATA, 0);
+	REG_WRITE(sc, VGA_GC_DATA, 0x0f);
 	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_COLOR_COMPARE);
 	REG_WRITE(sc, VGA_GC_DATA, 0);
 	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_DATA_ROTATE);
@@ -267,12 +268,133 @@
 	return (0);
 }
 
+static __inline int
+vga_bitblt_ctofb(struct vga_softc *sc, u_long c, u_long dst, int width,
+    int height)
+{
+	int w;
+
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_MODE);
+	REG_WRITE(sc, VGA_GC_DATA, 0);
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_ENABLE_SET_RESET);
+	REG_WRITE(sc, VGA_GC_DATA, 0x0f);
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_SET_RESET);
+	REG_WRITE(sc, VGA_GC_DATA, c & 0x0f);
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_DATA_ROTATE);
+	REG_WRITE(sc, VGA_GC_DATA, 0);
+	dst >>= 3;
+	while (height > 0) {
+		for (w = 0; w < width; w += 8) {
+			MEM_READ(sc, dst);
+			MEM_WRITE(sc, dst++, 0);
+		}
+		dst += (640 - w) >> 3;
+		height--;
+	}
+	return (0);
+}
+
+static __inline int
+vga_bitblt_fbtofb(struct vga_softc *sc, u_long src, u_long dst, int width,
+    int height)
+{
+	int w;
+
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_MODE);
+	REG_WRITE(sc, VGA_GC_DATA, 0);
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_ENABLE_SET_RESET);
+	REG_WRITE(sc, VGA_GC_DATA, 0x0f);
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_SET_RESET);
+	REG_WRITE(sc, VGA_GC_DATA, 0);
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_DATA_ROTATE);
+	REG_WRITE(sc, VGA_GC_DATA, VGA_GC_DR_FS_OR);
+	dst >>= 3;
+	src >>= 3;
+	while (height > 0) {
+		for (w = 0; w < width; w += 8) {
+			MEM_READ(sc, src++);
+			MEM_WRITE(sc, dst++, 0);
+		}
+		src += (640 - w) >> 3;
+		dst += (640 - w) >> 3;
+		height--;
+	}
+	return (0);
+}
+
+static __inline int
+vga_bitblt_h1tofb(struct vga_softc *sc, uint8_t *src, u_long dst, int width,
+    int height, int bgclr, int fgclr)
+{
+	int c, w;
+	uint8_t b;
+
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_MODE);
+	REG_WRITE(sc, VGA_GC_DATA, 3);
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_ENABLE_SET_RESET);
+	REG_WRITE(sc, VGA_GC_DATA, 0x0f);
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_SET_RESET);
+	REG_WRITE(sc, VGA_GC_DATA, fgclr);
+	REG_WRITE(sc, VGA_GC_ADDRESS, VGA_GC_DATA_ROTATE);
+	REG_WRITE(sc, VGA_GC_DATA, 0);
+	c = fgclr;
+	dst >>= 3;
+	while (height > 0) {
+		for (w = 0; w < width; w += 8) {
+			b = *src++;
+			if (b != 0) {
+				if (c != fgclr) {
+					REG_WRITE(sc, VGA_GC_ADDRESS,
+					    VGA_GC_SET_RESET);
+					REG_WRITE(sc, VGA_GC_DATA, fgclr);
+					c = fgclr;
+				}
+				MEM_READ(sc, dst);
+				MEM_WRITE(sc, dst, b);
+			}
+			if (b != 0xff) {
+				if (c != bgclr) {
+					REG_WRITE(sc, VGA_GC_ADDRESS,
+					    VGA_GC_SET_RESET);
+					REG_WRITE(sc, VGA_GC_DATA, bgclr);
+					c = bgclr;
+				}
+				MEM_READ(sc, dst);
+				MEM_WRITE(sc, dst, ~b);
+			}
+			dst++;
+		}
+		dst += (640 - w) >> 3;
+		height--;
+	}
+	return (0);
+}
+
 int
-vga_vbitblt(struct vga_softc *sc, int op, uintptr_t dst, uintptr_t src,
+vga_vbitblt(struct vga_softc *sc, int op, uintptr_t src, uintptr_t dst,
     int width, int height, va_list ap)
 {
+	int bgclr, fgclr;
+	int error;
 
-	return (0);
+	switch (op) {
+	case BITBLT_FBTOFB:
+		error = vga_bitblt_fbtofb(sc, src, dst, width, height);
+		break;
+	case BITBLT_H1TOFB:
+		bgclr = va_arg(ap, int);
+		fgclr = va_arg(ap, int);
+		error = vga_bitblt_h1tofb(sc, (uint8_t *)src, dst, width,
+		    height, bgclr, fgclr);
+		break;
+	case BITBLT_CTOFB:
+		error = vga_bitblt_ctofb(sc, src, dst, width, height);
+		break;
+	default:
+		error = EINVAL;
+		break;
+	}
+	return (error);
 }
 
 int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200505132152.j4DLqDx9019001>