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>