summaryrefslogtreecommitdiff
path: root/sys/dev/rasops
diff options
context:
space:
mode:
authorNathan Binkert <nate@cvs.openbsd.org>2001-03-18 04:32:46 +0000
committerNathan Binkert <nate@cvs.openbsd.org>2001-03-18 04:32:46 +0000
commitef2d578c271a786653e241b072dc56250ca1430d (patch)
treeb318f8acf09096eea9445db0dedcafc8eafc26f0 /sys/dev/rasops
parentf4f01277bc5305a12ccc3f2024dfa89e24335a13 (diff)
Import rasops from NetBSD. This gives improved performance for raster
operations.
Diffstat (limited to 'sys/dev/rasops')
-rw-r--r--sys/dev/rasops/Makefile8
-rw-r--r--sys/dev/rasops/README21
-rw-r--r--sys/dev/rasops/files.rasops19
-rw-r--r--sys/dev/rasops/rasops.c957
-rw-r--r--sys/dev/rasops/rasops.h149
-rw-r--r--sys/dev/rasops/rasops1.c378
-rw-r--r--sys/dev/rasops/rasops15.c470
-rw-r--r--sys/dev/rasops/rasops2.c481
-rw-r--r--sys/dev/rasops/rasops24.c740
-rw-r--r--sys/dev/rasops/rasops32.c142
-rw-r--r--sys/dev/rasops/rasops4.c499
-rw-r--r--sys/dev/rasops/rasops8.c420
-rw-r--r--sys/dev/rasops/rasops_bitops.h318
-rw-r--r--sys/dev/rasops/rasops_masks.c355
-rw-r--r--sys/dev/rasops/rasops_masks.h103
15 files changed, 5060 insertions, 0 deletions
diff --git a/sys/dev/rasops/Makefile b/sys/dev/rasops/Makefile
new file mode 100644
index 00000000000..bb842672637
--- /dev/null
+++ b/sys/dev/rasops/Makefile
@@ -0,0 +1,8 @@
+# $OpenBSD: Makefile,v 1.1 2001/03/18 04:32:44 nate Exp $
+# $NetBSD: Makefile,v 1.1 1998/06/12 23:22:55 cgd Exp $
+
+INCSDIR= /usr/include/dev/rasops
+
+INCS= rasops.h
+
+.include <bsd.kinc.mk>
diff --git a/sys/dev/rasops/README b/sys/dev/rasops/README
new file mode 100644
index 00000000000..19994147daf
--- /dev/null
+++ b/sys/dev/rasops/README
@@ -0,0 +1,21 @@
+$OpenBSD: README,v 1.1 2001/03/18 04:32:44 nate Exp $
+$NetBSD: README,v 1.3 1999/08/24 11:07:31 ad Exp $
+
+This directory contains `rasops', a set of raster operations intended to
+replace the dev/rcons/raster stuff for both wscons and rcons. It yields
+significantly improved performance, supports multiple depths and color.
+
+Issues/TODO:
+
+- There is no generic `putchar' function for 2bpp
+- Color handling for 2bpp is broken
+- copycols() from rasops_bitops.h is broken in right->left case
+- The stamp mutex is not particularly safe
+- 64-bit types are not used on machines that are 64-bit
+- We should never be doing reads/writes of less than 32-bits
+- Flags in attribute values are hardcoded
+- Need a manpage
+- Should handle multiple fonts simulatneously
+- Generate an `empty' box character when we have no match?
+- Use 'int' in lieu of 'int32' where we can
+- Compress some cases in rasops1.c
diff --git a/sys/dev/rasops/files.rasops b/sys/dev/rasops/files.rasops
new file mode 100644
index 00000000000..e877ccf6eb5
--- /dev/null
+++ b/sys/dev/rasops/files.rasops
@@ -0,0 +1,19 @@
+# $OpenBSD: files.rasops,v 1.1 2001/03/18 04:32:44 nate Exp $
+# $NetBSD: files.rasops,v 1.7 2001/01/21 13:50:59 takemura Exp $
+
+# Note: `rasops_glue' is only here to force the header file's name
+# hence it must be mentioned first (shudder...)
+file dev/rasops/rasops.c ( (rasops_glue |
+ rasops1 | rasops2 | rasops4 | rasops8 | rasops15 | rasops16 | rasops24 |
+ rasops32) &
+ (rasterconsole | wsdisplay)) needs-flag
+
+file dev/rasops/rasops_masks.c ((rasterconsole | wsdisplay) &
+ (rasops1 | rasops2 | rasops4))
+file dev/rasops/rasops1.c ((rasterconsole | wsdisplay) & rasops1)
+file dev/rasops/rasops2.c ((rasterconsole | wsdisplay) & rasops2)
+file dev/rasops/rasops4.c ((rasterconsole | wsdisplay) & rasops4)
+file dev/rasops/rasops8.c ((rasterconsole | wsdisplay) & rasops8)
+file dev/rasops/rasops15.c ((rasterconsole | wsdisplay) & (rasops15 | rasops16))
+file dev/rasops/rasops24.c ((rasterconsole | wsdisplay) & rasops24)
+file dev/rasops/rasops32.c ((rasterconsole | wsdisplay) & rasops32)
diff --git a/sys/dev/rasops/rasops.c b/sys/dev/rasops/rasops.c
new file mode 100644
index 00000000000..0a843483e02
--- /dev/null
+++ b/sys/dev/rasops/rasops.c
@@ -0,0 +1,957 @@
+/* $OpenBSD: rasops.c,v 1.1 2001/03/18 04:32:44 nate Exp $ */
+/* $NetBSD: rasops.c,v 1.35 2001/02/02 06:01:01 marcus Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+//__KERNEL_RCSID(0, "$NetBSD: rasops.c,v 1.35 2001/02/02 06:01:01 marcus Exp $");
+
+#include "rasops_glue.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+
+/* #include <machine/bswap.h> */
+#include <machine/endian.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/wsfont/wsfont.h>
+#include <dev/rasops/rasops.h>
+
+#ifndef _KERNEL
+#include <errno.h>
+#endif
+
+/* ANSI colormap (R,G,B). Upper 8 are high-intensity */
+const u_char rasops_cmap[256*3] = {
+ 0x00, 0x00, 0x00, /* black */
+ 0x7f, 0x00, 0x00, /* red */
+ 0x00, 0x7f, 0x00, /* green */
+ 0x7f, 0x7f, 0x00, /* brown */
+ 0x00, 0x00, 0x7f, /* blue */
+ 0x7f, 0x00, 0x7f, /* magenta */
+ 0x00, 0x7f, 0x7f, /* cyan */
+ 0xc7, 0xc7, 0xc7, /* white - XXX too dim? */
+
+ 0x7f, 0x7f, 0x7f, /* black */
+ 0xff, 0x00, 0x00, /* red */
+ 0x00, 0xff, 0x00, /* green */
+ 0xff, 0xff, 0x00, /* brown */
+ 0x00, 0x00, 0xff, /* blue */
+ 0xff, 0x00, 0xff, /* magenta */
+ 0x00, 0xff, 0xff, /* cyan */
+ 0xff, 0xff, 0xff, /* white */
+
+ /*
+ * For the cursor, we need at least the last (255th)
+ * color to be white. Fill up white completely for
+ * simplicity.
+ */
+#define _CMWHITE 0xff, 0xff, 0xff,
+#define _CMWHITE16 _CMWHITE _CMWHITE _CMWHITE _CMWHITE \
+ _CMWHITE _CMWHITE _CMWHITE _CMWHITE \
+ _CMWHITE _CMWHITE _CMWHITE _CMWHITE \
+ _CMWHITE _CMWHITE _CMWHITE _CMWHITE
+ _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16
+ _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16
+ _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16 _CMWHITE16
+#undef _CMWHITE16
+#undef _CMWHITE
+};
+
+/* True if color is gray */
+const u_char rasops_isgray[16] = {
+ 1, 0, 0, 0,
+ 0, 0, 0, 1,
+ 1, 0, 0, 0,
+ 0, 0, 0, 1
+};
+
+/* Generic functions */
+static void rasops_copyrows __P((void *, int, int, int));
+static int rasops_mapchar __P((void *, int, u_int *));
+static void rasops_cursor __P((void *, int, int, int));
+static int rasops_alloc_cattr __P((void *, int, int, int, long *));
+static int rasops_alloc_mattr __P((void *, int, int, int, long *));
+static void rasops_do_cursor __P((struct rasops_info *));
+static void rasops_init_devcmap __P((struct rasops_info *));
+
+/*
+ * Initalize a 'rasops_info' descriptor.
+ */
+int
+rasops_init(ri, wantrows, wantcols)
+ struct rasops_info *ri;
+ int wantrows, wantcols;
+{
+
+#ifdef _KERNEL
+ /* Select a font if the caller doesn't care */
+ if (ri->ri_font == NULL) {
+ int cookie;
+
+ wsfont_init();
+
+ /* Want 8 pixel wide, don't care about aestethics */
+ if ((cookie = wsfont_find(NULL, 8, 0, 0)) <= 0)
+ cookie = wsfont_find(NULL, 0, 0, 0);
+
+ if (cookie <= 0) {
+ printf("rasops_init: font table is empty\n");
+ return (-1);
+ }
+
+ if (wsfont_lock(cookie, &ri->ri_font,
+ WSDISPLAY_FONTORDER_L2R, WSDISPLAY_FONTORDER_L2R) <= 0) {
+ printf("rasops_init: couldn't lock font\n");
+ return (-1);
+ }
+
+ ri->ri_wsfcookie = cookie;
+ }
+#endif
+
+ /* This should never happen in reality... */
+#ifdef DEBUG
+ if ((long)ri->ri_bits & 3) {
+ printf("rasops_init: bits not aligned on 32-bit boundary\n");
+ return (-1);
+ }
+
+ if ((int)ri->ri_stride & 3) {
+ printf("rasops_init: stride not aligned on 32-bit boundary\n");
+ return (-1);
+ }
+#endif
+
+ if (rasops_reconfig(ri, wantrows, wantcols))
+ return (-1);
+
+ rasops_init_devcmap(ri);
+ return (0);
+}
+
+/*
+ * Reconfigure (because parameters have changed in some way).
+ */
+int
+rasops_reconfig(ri, wantrows, wantcols)
+ struct rasops_info *ri;
+ int wantrows, wantcols;
+{
+ int bpp, s;
+
+ s = splhigh();
+
+ if (ri->ri_font->fontwidth > 32 || ri->ri_font->fontwidth < 4)
+ panic("rasops_init: fontwidth assumptions botched!\n");
+
+ /* Need this to frob the setup below */
+ bpp = (ri->ri_depth == 15 ? 16 : ri->ri_depth);
+
+ if ((ri->ri_flg & RI_CFGDONE) != 0)
+ ri->ri_bits = ri->ri_origbits;
+
+ /* Don't care if the caller wants a hideously small console */
+ if (wantrows < 10)
+ wantrows = 10;
+
+ if (wantcols < 20)
+ wantcols = 20;
+
+ /* Now constrain what they get */
+ ri->ri_emuwidth = ri->ri_font->fontwidth * wantcols;
+ ri->ri_emuheight = ri->ri_font->fontheight * wantrows;
+
+ if (ri->ri_emuwidth > ri->ri_width)
+ ri->ri_emuwidth = ri->ri_width;
+
+ if (ri->ri_emuheight > ri->ri_height)
+ ri->ri_emuheight = ri->ri_height;
+
+ /* Reduce width until aligned on a 32-bit boundary */
+ while ((ri->ri_emuwidth * bpp & 31) != 0)
+ ri->ri_emuwidth--;
+
+ ri->ri_cols = ri->ri_emuwidth / ri->ri_font->fontwidth;
+ ri->ri_rows = ri->ri_emuheight / ri->ri_font->fontheight;
+ ri->ri_emustride = ri->ri_emuwidth * bpp >> 3;
+ ri->ri_delta = ri->ri_stride - ri->ri_emustride;
+ ri->ri_ccol = 0;
+ ri->ri_crow = 0;
+ ri->ri_pelbytes = bpp >> 3;
+
+ ri->ri_xscale = (ri->ri_font->fontwidth * bpp) >> 3;
+ ri->ri_yscale = ri->ri_font->fontheight * ri->ri_stride;
+ ri->ri_fontscale = ri->ri_font->fontheight * ri->ri_font->stride;
+
+#ifdef DEBUG
+ if ((ri->ri_delta & 3) != 0)
+ panic("rasops_init: ri_delta not aligned on 32-bit boundary");
+#endif
+ /* Clear the entire display */
+ if ((ri->ri_flg & RI_CLEAR) != 0)
+ memset(ri->ri_bits, 0, ri->ri_stride * ri->ri_height);
+
+ /* Now centre our window if needs be */
+ ri->ri_origbits = ri->ri_bits;
+
+ if ((ri->ri_flg & RI_CENTER) != 0) {
+ ri->ri_bits += (((ri->ri_width * bpp >> 3) -
+ ri->ri_emustride) >> 1) & ~3;
+ ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
+ ri->ri_stride;
+
+ ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits)
+ / ri->ri_stride;
+ ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits)
+ % ri->ri_stride) * 8 / bpp);
+ } else
+ ri->ri_xorigin = ri->ri_yorigin = 0;
+
+ /*
+ * Fill in defaults for operations set. XXX this nukes private
+ * routines used by accelerated fb drivers.
+ */
+ ri->ri_ops.mapchar = rasops_mapchar;
+ ri->ri_ops.copyrows = rasops_copyrows;
+ ri->ri_ops.copycols = rasops_copycols;
+ ri->ri_ops.erasecols = rasops_erasecols;
+ ri->ri_ops.eraserows = rasops_eraserows;
+ ri->ri_ops.cursor = rasops_cursor;
+ ri->ri_do_cursor = rasops_do_cursor;
+
+ if (ri->ri_depth < 8 || (ri->ri_flg & RI_FORCEMONO) != 0) {
+ ri->ri_ops.alloc_attr = rasops_alloc_mattr;
+ ri->ri_caps = WSSCREEN_UNDERLINE | WSSCREEN_REVERSE;
+ } else {
+ ri->ri_ops.alloc_attr = rasops_alloc_cattr;
+ ri->ri_caps = WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
+ WSSCREEN_WSCOLORS | WSSCREEN_REVERSE;
+ }
+
+ switch (ri->ri_depth) {
+#if NRASOPS1 > 0
+ case 1:
+ rasops1_init(ri);
+ break;
+#endif
+#if NRASOPS2 > 0
+ case 2:
+ rasops2_init(ri);
+ break;
+#endif
+#if NRASOPS4 > 0
+ case 4:
+ rasops4_init(ri);
+ break;
+#endif
+#if NRASOPS8 > 0
+ case 8:
+ rasops8_init(ri);
+ break;
+#endif
+#if NRASOPS15 > 0 || NRASOPS16 > 0
+ case 15:
+ case 16:
+ rasops15_init(ri);
+ break;
+#endif
+#if NRASOPS24 > 0
+ case 24:
+ rasops24_init(ri);
+ break;
+#endif
+#if NRASOPS32 > 0
+ case 32:
+ rasops32_init(ri);
+ break;
+#endif
+ default:
+ ri->ri_flg &= ~RI_CFGDONE;
+ splx(s);
+ return (-1);
+ }
+
+ ri->ri_flg |= RI_CFGDONE;
+ splx(s);
+ return (0);
+}
+
+/*
+ * Map a character.
+ */
+static int
+rasops_mapchar(cookie, c, cp)
+ void *cookie;
+ int c;
+ u_int *cp;
+{
+ struct rasops_info *ri;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef DIAGNOSTIC
+ if (ri->ri_font == NULL)
+ panic("rasops_mapchar: no font selected\n");
+#endif
+ if (ri->ri_font->encoding != WSDISPLAY_FONTENC_ISO) {
+
+ if ( (c = wsfont_map_unichar(ri->ri_font, c)) < 0) {
+
+ *cp = ' ';
+ return (0);
+
+ }
+ }
+
+
+ if (c < ri->ri_font->firstchar) {
+ *cp = ' ';
+ return (0);
+ }
+
+ if (c - ri->ri_font->firstchar >= ri->ri_font->numchars) {
+ *cp = ' ';
+ return (0);
+ }
+
+ *cp = c;
+ return (5);
+}
+
+/*
+ * Allocate a color attribute.
+ */
+static int
+rasops_alloc_cattr(cookie, fg, bg, flg, attr)
+ void *cookie;
+ int fg, bg, flg;
+ long *attr;
+{
+ int swap;
+
+#ifdef RASOPS_CLIPPING
+ fg &= 7;
+ bg &= 7;
+#endif
+ if ((flg & WSATTR_BLINK) != 0)
+ return (EINVAL);
+
+ if ((flg & WSATTR_WSCOLORS) == 0) {
+ fg = WSCOL_WHITE;
+ bg = WSCOL_BLACK;
+ }
+
+ if ((flg & WSATTR_REVERSE) != 0) {
+ swap = fg;
+ fg = bg;
+ bg = swap;
+ }
+
+ if ((flg & WSATTR_HILIT) != 0)
+ fg += 8;
+
+ flg = ((flg & WSATTR_UNDERLINE) ? 1 : 0);
+
+ if (rasops_isgray[fg])
+ flg |= 2;
+
+ if (rasops_isgray[bg])
+ flg |= 4;
+
+ *attr = (bg << 16) | (fg << 24) | flg;
+ return (0);
+}
+
+/*
+ * Allocate a mono attribute.
+ */
+static int
+rasops_alloc_mattr(cookie, fg, bg, flg, attr)
+ void *cookie;
+ int fg, bg, flg;
+ long *attr;
+{
+ int swap;
+
+ if ((flg & (WSATTR_BLINK | WSATTR_HILIT | WSATTR_WSCOLORS)) != 0)
+ return (EINVAL);
+
+ fg = 1;
+ bg = 0;
+
+ if ((flg & WSATTR_REVERSE) != 0) {
+ swap = fg;
+ fg = bg;
+ bg = swap;
+ }
+
+ *attr = (bg << 16) | (fg << 24) | ((flg & WSATTR_UNDERLINE) ? 7 : 6);
+ return (0);
+}
+
+/*
+ * Copy rows.
+ */
+static void
+rasops_copyrows(cookie, src, dst, num)
+ void *cookie;
+ int src, dst, num;
+{
+ int32_t *sp, *dp, *srp, *drp;
+ struct rasops_info *ri;
+ int n8, n1, cnt, delta;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if (dst == src)
+ return;
+
+ if (src < 0) {
+ num += src;
+ src = 0;
+ }
+
+ if ((src + num) > ri->ri_rows)
+ num = ri->ri_rows - src;
+
+ if (dst < 0) {
+ num += dst;
+ dst = 0;
+ }
+
+ if ((dst + num) > ri->ri_rows)
+ num = ri->ri_rows - dst;
+
+ if (num <= 0)
+ return;
+#endif
+
+ num *= ri->ri_font->fontheight;
+ n8 = ri->ri_emustride >> 5;
+ n1 = (ri->ri_emustride >> 2) & 7;
+
+ if (dst < src) {
+ srp = (int32_t *)(ri->ri_bits + src * ri->ri_yscale);
+ drp = (int32_t *)(ri->ri_bits + dst * ri->ri_yscale);
+ delta = ri->ri_stride;
+ } else {
+ src = ri->ri_font->fontheight * src + num - 1;
+ dst = ri->ri_font->fontheight * dst + num - 1;
+ srp = (int32_t *)(ri->ri_bits + src * ri->ri_stride);
+ drp = (int32_t *)(ri->ri_bits + dst * ri->ri_stride);
+ delta = -ri->ri_stride;
+ }
+
+ while (num--) {
+ dp = drp;
+ sp = srp;
+ DELTA(drp, delta, int32_t *);
+ DELTA(srp, delta, int32_t *);
+
+ for (cnt = n8; cnt; cnt--) {
+ dp[0] = sp[0];
+ dp[1] = sp[1];
+ dp[2] = sp[2];
+ dp[3] = sp[3];
+ dp[4] = sp[4];
+ dp[5] = sp[5];
+ dp[6] = sp[6];
+ dp[7] = sp[7];
+ dp += 8;
+ sp += 8;
+ }
+
+ for (cnt = n1; cnt; cnt--)
+ *dp++ = *sp++;
+ }
+}
+
+/*
+ * Copy columns. This is slow, and hard to optimize due to alignment,
+ * and the fact that we have to copy both left->right and right->left.
+ * We simply cop-out here and use bcopy(), since it handles all of
+ * these cases anyway.
+ */
+void
+rasops_copycols(cookie, row, src, dst, num)
+ void *cookie;
+ int row, src, dst, num;
+{
+ struct rasops_info *ri;
+ u_char *sp, *dp;
+ int height;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if (dst == src)
+ return;
+
+ /* Catches < 0 case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if (src < 0) {
+ num += src;
+ src = 0;
+ }
+
+ if ((src + num) > ri->ri_cols)
+ num = ri->ri_cols - src;
+
+ if (dst < 0) {
+ num += dst;
+ dst = 0;
+ }
+
+ if ((dst + num) > ri->ri_cols)
+ num = ri->ri_cols - dst;
+
+ if (num <= 0)
+ return;
+#endif
+
+ num *= ri->ri_xscale;
+ row *= ri->ri_yscale;
+ height = ri->ri_font->fontheight;
+
+ sp = ri->ri_bits + row + src * ri->ri_xscale;
+ dp = ri->ri_bits + row + dst * ri->ri_xscale;
+
+ while (height--) {
+ bcopy(sp, dp, num);
+ dp += ri->ri_stride;
+ sp += ri->ri_stride;
+ }
+}
+
+/*
+ * Turn cursor off/on.
+ */
+static void
+rasops_cursor(cookie, on, row, col)
+ void *cookie;
+ int on, row, col;
+{
+ struct rasops_info *ri;
+
+ ri = (struct rasops_info *)cookie;
+
+ /* Turn old cursor off */
+ if ((ri->ri_flg & RI_CURSOR) != 0)
+#ifdef RASOPS_CLIPPING
+ if ((ri->ri_flg & RI_CURSORCLIP) == 0)
+#endif
+ ri->ri_do_cursor(ri);
+
+ /* Select new cursor */
+#ifdef RASOPS_CLIPPING
+ ri->ri_flg &= ~RI_CURSORCLIP;
+
+ if (row < 0 || row >= ri->ri_rows)
+ ri->ri_flg |= RI_CURSORCLIP;
+ else if (col < 0 || col >= ri->ri_cols)
+ ri->ri_flg |= RI_CURSORCLIP;
+#endif
+ ri->ri_crow = row;
+ ri->ri_ccol = col;
+
+ if (on) {
+ ri->ri_flg |= RI_CURSOR;
+#ifdef RASOPS_CLIPPING
+ if ((ri->ri_flg & RI_CURSORCLIP) == 0)
+#endif
+ ri->ri_do_cursor(ri);
+ } else
+ ri->ri_flg &= ~RI_CURSOR;
+}
+
+/*
+ * Make the device colormap
+ */
+static void
+rasops_init_devcmap(ri)
+ struct rasops_info *ri;
+{
+ const u_char *p;
+ int i, c;
+
+ switch (ri->ri_depth) {
+ case 1:
+ ri->ri_devcmap[0] = 0;
+ for (i = 1; i < 16; i++)
+ ri->ri_devcmap[i] = -1;
+ return;
+
+ case 2:
+ for (i = 1; i < 15; i++)
+ ri->ri_devcmap[i] = 0xaaaaaaaa;
+
+ ri->ri_devcmap[0] = 0;
+ ri->ri_devcmap[8] = 0x55555555;
+ ri->ri_devcmap[15] = -1;
+ return;
+
+ case 8:
+ for (i = 0; i < 16; i++)
+ ri->ri_devcmap[i] = i | (i<<8) | (i<<16) | (i<<24);
+ return;
+ }
+
+ p = rasops_cmap;
+
+ for (i = 0; i < 16; i++) {
+ if (ri->ri_rnum <= 8)
+ c = (*p >> (8 - ri->ri_rnum)) << ri->ri_rpos;
+ else
+ c = (*p << (ri->ri_rnum - 8)) << ri->ri_rpos;
+ p++;
+
+ if (ri->ri_gnum <= 8)
+ c |= (*p >> (8 - ri->ri_gnum)) << ri->ri_gpos;
+ else
+ c |= (*p << (ri->ri_gnum - 8)) << ri->ri_gpos;
+ p++;
+
+ if (ri->ri_bnum <= 8)
+ c |= (*p >> (8 - ri->ri_bnum)) << ri->ri_bpos;
+ else
+ c |= (*p << (ri->ri_bnum - 8)) << ri->ri_bpos;
+ p++;
+
+ /* Fill the word for generic routines, which want this */
+ if (ri->ri_depth == 24)
+ c = c | ((c & 0xff) << 24);
+ else if (ri->ri_depth <= 16)
+ c = c | (c << 16);
+
+ /* 24bpp does bswap on the fly. {32,16,15}bpp do it here. */
+ if ((ri->ri_flg & RI_BSWAP) == 0)
+ ri->ri_devcmap[i] = c;
+ else if (ri->ri_depth == 32)
+ ri->ri_devcmap[i] = swap32(c);
+ else if (ri->ri_depth == 16 || ri->ri_depth == 15)
+ ri->ri_devcmap[i] = swap16(c);
+ else
+ ri->ri_devcmap[i] = c;
+ }
+}
+
+/*
+ * Unpack a rasops attribute
+ */
+void
+rasops_unpack_attr(attr, fg, bg, underline)
+ long attr;
+ int *fg, *bg, *underline;
+{
+
+ *fg = ((u_int)attr >> 24) & 0xf;
+ *bg = ((u_int)attr >> 16) & 0xf;
+ if (underline != NULL)
+ *underline = (u_int)attr & 1;
+}
+
+/*
+ * Erase rows. This isn't static, since 24-bpp uses it in special cases.
+ */
+void
+rasops_eraserows(cookie, row, num, attr)
+ void *cookie;
+ int row, num;
+ long attr;
+{
+ struct rasops_info *ri;
+ int np, nw, cnt, delta;
+ int32_t *dp, clr;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if (row < 0) {
+ num += row;
+ row = 0;
+ }
+
+ if ((row + num) > ri->ri_rows)
+ num = ri->ri_rows - row;
+
+ if (num <= 0)
+ return;
+#endif
+
+ clr = ri->ri_devcmap[(attr >> 16) & 0xf];
+
+ /*
+ * XXX The wsdisplay_emulops interface seems a little deficient in
+ * that there is no way to clear the *entire* screen. We provide a
+ * workaround here: if the entire console area is being cleared, and
+ * the RI_FULLCLEAR flag is set, clear the entire display.
+ */
+ if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
+ np = ri->ri_stride >> 5;
+ nw = (ri->ri_stride >> 2) & 7;
+ num = ri->ri_height;
+ dp = (int32_t *)ri->ri_origbits;
+ delta = 0;
+ } else {
+ np = ri->ri_emustride >> 5;
+ nw = (ri->ri_emustride >> 2) & 7;
+ num *= ri->ri_font->fontheight;
+ dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
+ delta = ri->ri_delta;
+ }
+
+ while (num--) {
+ for (cnt = np; cnt; cnt--) {
+ dp[0] = clr;
+ dp[1] = clr;
+ dp[2] = clr;
+ dp[3] = clr;
+ dp[4] = clr;
+ dp[5] = clr;
+ dp[6] = clr;
+ dp[7] = clr;
+ dp += 8;
+ }
+
+ for (cnt = nw; cnt; cnt--) {
+ *(int32_t *)dp = clr;
+ DELTA(dp, 4, int32_t *);
+ }
+
+ DELTA(dp, delta, int32_t *);
+ }
+}
+
+/*
+ * Actually turn the cursor on or off. This does the dirty work for
+ * rasops_cursor().
+ */
+static void
+rasops_do_cursor(ri)
+ struct rasops_info *ri;
+{
+ int full1, height, cnt, slop1, slop2, row, col;
+ u_char *dp, *rp;
+
+ row = ri->ri_crow;
+ col = ri->ri_ccol;
+
+ rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
+ height = ri->ri_font->fontheight;
+ slop1 = (4 - ((long)rp & 3)) & 3;
+
+ if (slop1 > ri->ri_xscale)
+ slop1 = ri->ri_xscale;
+
+ slop2 = (ri->ri_xscale - slop1) & 3;
+ full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
+
+ if ((slop1 | slop2) == 0) {
+ /* A common case */
+ while (height--) {
+ dp = rp;
+ rp += ri->ri_stride;
+
+ for (cnt = full1; cnt; cnt--) {
+ *(int32_t *)dp ^= ~0;
+ dp += 4;
+ }
+ }
+ } else {
+ /* XXX this is stupid.. use masks instead */
+ while (height--) {
+ dp = rp;
+ rp += ri->ri_stride;
+
+ if (slop1 & 1)
+ *dp++ ^= ~0;
+
+ if (slop1 & 2) {
+ *(int16_t *)dp ^= ~0;
+ dp += 2;
+ }
+
+ for (cnt = full1; cnt; cnt--) {
+ *(int32_t *)dp ^= ~0;
+ dp += 4;
+ }
+
+ if (slop2 & 1)
+ *dp++ ^= ~0;
+
+ if (slop2 & 2)
+ *(int16_t *)dp ^= ~0;
+ }
+ }
+}
+
+/*
+ * Erase columns.
+ */
+void
+rasops_erasecols(cookie, row, col, num, attr)
+ void *cookie;
+ int row, col, num;
+ long attr;
+{
+ int n8, height, cnt, slop1, slop2, clr;
+ struct rasops_info *ri;
+ int32_t *rp, *dp;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if (col < 0) {
+ num += col;
+ col = 0;
+ }
+
+ if ((col + num) > ri->ri_cols)
+ num = ri->ri_cols - col;
+
+ if (num <= 0)
+ return;
+#endif
+
+ num = num * ri->ri_xscale;
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+ clr = ri->ri_devcmap[(attr >> 16) & 0xf];
+
+ /* Don't bother using the full loop for <= 32 pels */
+ if (num <= 32) {
+ if (((num | ri->ri_xscale) & 3) == 0) {
+ /* Word aligned blt */
+ num >>= 2;
+
+ while (height--) {
+ dp = rp;
+ DELTA(rp, ri->ri_stride, int32_t *);
+
+ for (cnt = num; cnt; cnt--)
+ *dp++ = clr;
+ }
+ } else if (((num | ri->ri_xscale) & 1) == 0) {
+ /*
+ * Halfword aligned blt. This is needed so the
+ * 15/16 bit ops can use this function.
+ */
+ num >>= 1;
+
+ while (height--) {
+ dp = rp;
+ DELTA(rp, ri->ri_stride, int32_t *);
+
+ for (cnt = num; cnt; cnt--) {
+ *(int16_t *)dp = clr;
+ DELTA(dp, 2, int32_t *);
+ }
+ }
+ } else {
+ while (height--) {
+ dp = rp;
+ DELTA(rp, ri->ri_stride, int32_t *);
+
+ for (cnt = num; cnt; cnt--) {
+ *(u_char *)dp = clr;
+ DELTA(dp, 1, int32_t *);
+ }
+ }
+ }
+
+ return;
+ }
+
+ slop1 = (4 - ((long)rp & 3)) & 3;
+ slop2 = (num - slop1) & 3;
+ num -= slop1 + slop2;
+ n8 = num >> 5;
+ num = (num >> 2) & 7;
+
+ while (height--) {
+ dp = rp;
+ DELTA(rp, ri->ri_stride, int32_t *);
+
+ /* Align span to 4 bytes */
+ if (slop1 & 1) {
+ *(u_char *)dp = clr;
+ DELTA(dp, 1, int32_t *);
+ }
+
+ if (slop1 & 2) {
+ *(int16_t *)dp = clr;
+ DELTA(dp, 2, int32_t *);
+ }
+
+ /* Write 32 bytes per loop */
+ for (cnt = n8; cnt; cnt--) {
+ dp[0] = clr;
+ dp[1] = clr;
+ dp[2] = clr;
+ dp[3] = clr;
+ dp[4] = clr;
+ dp[5] = clr;
+ dp[6] = clr;
+ dp[7] = clr;
+ dp += 8;
+ }
+
+ /* Write 4 bytes per loop */
+ for (cnt = num; cnt; cnt--)
+ *dp++ = clr;
+
+ /* Write unaligned trailing slop */
+ if (slop2 & 1) {
+ *(u_char *)dp = clr;
+ DELTA(dp, 1, int32_t *);
+ }
+
+ if (slop2 & 2)
+ *(int16_t *)dp = clr;
+ }
+}
diff --git a/sys/dev/rasops/rasops.h b/sys/dev/rasops/rasops.h
new file mode 100644
index 00000000000..9932f303f6b
--- /dev/null
+++ b/sys/dev/rasops/rasops.h
@@ -0,0 +1,149 @@
+/* $OpenBSD: rasops.h,v 1.1 2001/03/18 04:32:44 nate Exp $ */
+/* $NetBSD: rasops.h,v 1.13 2000/06/13 13:36:54 ad Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RASOPS_H_
+#define _RASOPS_H_ 1
+
+struct wsdisplay_font;
+
+/* For rasops_info::ri_flg */
+#define RI_FULLCLEAR 0x01 /* eraserows() hack to clear full screen */
+#define RI_FORCEMONO 0x02 /* monochrome output even if we can do color */
+#define RI_BSWAP 0x04 /* framebuffer endianness doesn't match CPU */
+#define RI_CURSOR 0x08 /* cursor is switched on */
+#define RI_CLEAR 0x10 /* clear display on startup */
+#define RI_CENTER 0x20 /* center onscreen output */
+#define RI_CURSORCLIP 0x40 /* cursor is currently clipped */
+#define RI_CFGDONE 0x80 /* rasops_reconfig() completed successfully */
+
+struct rasops_info {
+ /* These must be filled in by the caller */
+ int ri_depth; /* depth in bits */
+ u_char *ri_bits; /* ptr to bits */
+ int ri_width; /* width (pels) */
+ int ri_height; /* height (pels) */
+ int ri_stride; /* stride in bytes */
+
+ /*
+ * These can optionally be left zeroed out. If you fill ri_font,
+ * but aren't using wsfont, set ri_wsfcookie to -1.
+ */
+ struct wsdisplay_font *ri_font;
+ int ri_wsfcookie; /* wsfont cookie */
+ void *ri_hw; /* driver private data; ignored by rasops */
+ int ri_crow; /* cursor row */
+ int ri_ccol; /* cursor column */
+ int ri_flg; /* various operational flags */
+
+ /*
+ * These are optional and will default if zero. Meaningless
+ * on depths other than 15, 16, 24 and 32 bits per pel. On
+ * 24 bit displays, ri_{r,g,b}num must be 8.
+ */
+ u_char ri_rnum; /* number of bits for red */
+ u_char ri_gnum; /* number of bits for green */
+ u_char ri_bnum; /* number of bits for blue */
+ u_char ri_rpos; /* which bit red starts at */
+ u_char ri_gpos; /* which bit green starts at */
+ u_char ri_bpos; /* which bit blue starts at */
+
+ /* These are filled in by rasops_init() */
+ int ri_emuwidth; /* width we actually care about */
+ int ri_emuheight; /* height we actually care about */
+ int ri_emustride; /* bytes per row we actually care about */
+ int ri_rows; /* number of rows (characters, not pels) */
+ int ri_cols; /* number of columns (characters, not pels) */
+ int ri_delta; /* row delta in bytes */
+ int ri_pelbytes; /* bytes per pel (may be zero) */
+ int ri_fontscale; /* fontheight * fontstride */
+ int ri_xscale; /* fontwidth * pelbytes */
+ int ri_yscale; /* fontheight * stride */
+ u_char *ri_origbits; /* where screen bits actually start */
+ int ri_xorigin; /* where ri_bits begins (x) */
+ int ri_yorigin; /* where ri_bits begins (y) */
+ int32_t ri_devcmap[16]; /* color -> framebuffer data */
+
+ /* The emulops you need to use, and the screen caps for wscons */
+ struct wsdisplay_emulops ri_ops;
+ int ri_caps;
+
+ /* Callbacks so we can share some code */
+ void (*ri_do_cursor) __P((struct rasops_info *));
+};
+
+#define DELTA(p, d, cast) ((p) = (cast)((caddr_t)(p) + (d)))
+
+/*
+ * rasops_init().
+ *
+ * Integer parameters are the number of rows and columns we'd *like*.
+ *
+ * In terms of optimization, fonts that are a multiple of 8 pixels wide
+ * work the best.
+ *
+ * rasops_init() takes care of rasops_reconfig(). The parameters to both
+ * are the same. If calling rasops_reconfig() to change the font and
+ * ri_wsfcookie >= 0, you must call wsfont_unlock() on it, and reset it
+ * to -1 (or a new, valid cookie).
+ */
+
+/*
+ * Per-depth initalization functions. These should not be called outside
+ * the rasops code.
+ */
+void rasops1_init __P((struct rasops_info *));
+void rasops2_init __P((struct rasops_info *));
+void rasops4_init __P((struct rasops_info *));
+void rasops8_init __P((struct rasops_info *));
+void rasops15_init __P((struct rasops_info *));
+void rasops24_init __P((struct rasops_info *));
+void rasops32_init __P((struct rasops_info *));
+
+/* rasops.c */
+int rasops_init __P((struct rasops_info *, int, int));
+int rasops_reconfig __P((struct rasops_info *, int, int));
+void rasops_unpack_attr __P((long, int *, int *, int *));
+void rasops_eraserows __P((void *, int, int, long));
+void rasops_erasecols __P((void *, int, int, int, long));
+void rasops_copycols __P((void *, int, int, int, int));
+
+extern const u_char rasops_isgray[16];
+extern const u_char rasops_cmap[256*3];
+
+#endif /* _RASOPS_H_ */
diff --git a/sys/dev/rasops/rasops1.c b/sys/dev/rasops/rasops1.c
new file mode 100644
index 00000000000..fb345d73d11
--- /dev/null
+++ b/sys/dev/rasops/rasops1.c
@@ -0,0 +1,378 @@
+/* $OpenBSD: rasops1.c,v 1.1 2001/03/18 04:32:44 nate Exp $ */
+/* $NetBSD: rasops1.c,v 1.11 2000/04/12 14:22:29 pk Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+//__KERNEL_RCSID(0, "$NetBSD: rasops1.c,v 1.11 2000/04/12 14:22:29 pk Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <machine/endian.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/rasops/rasops.h>
+#include <dev/rasops/rasops_masks.h>
+
+static void rasops1_copycols __P((void *, int, int, int, int));
+static void rasops1_erasecols __P((void *, int, int, int, long));
+static void rasops1_do_cursor __P((struct rasops_info *));
+static void rasops1_putchar __P((void *, int, int col, u_int, long));
+#ifndef RASOPS_SMALL
+static void rasops1_putchar8 __P((void *, int, int col, u_int, long));
+static void rasops1_putchar16 __P((void *, int, int col, u_int, long));
+#endif
+
+/*
+ * Initalize rasops_info struct for this colordepth.
+ */
+void
+rasops1_init(ri)
+ struct rasops_info *ri;
+{
+
+ switch (ri->ri_font->fontwidth) {
+#ifndef RASOPS_SMALL
+ case 8:
+ ri->ri_ops.putchar = rasops1_putchar8;
+ break;
+ case 16:
+ ri->ri_ops.putchar = rasops1_putchar16;
+ break;
+#endif
+ default:
+ ri->ri_ops.putchar = rasops1_putchar;
+ break;
+ }
+
+ if ((ri->ri_font->fontwidth & 7) != 0) {
+ ri->ri_ops.erasecols = rasops1_erasecols;
+ ri->ri_ops.copycols = rasops1_copycols;
+ ri->ri_do_cursor = rasops1_do_cursor;
+ }
+}
+
+/*
+ * Paint a single character. This is the generic version, this is ugly.
+ */
+static void
+rasops1_putchar(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ u_int fs, rs, fb, bg, fg, lmask, rmask;
+ u_int32_t height, width;
+ struct rasops_info *ri;
+ int32_t *rp;
+ u_char *fr;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols)
+ return;
+#endif
+
+ col *= ri->ri_font->fontwidth;
+ rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
+ height = ri->ri_font->fontheight;
+ width = ri->ri_font->fontwidth;
+ col = col & 31;
+ rs = ri->ri_stride;
+
+ bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
+ fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
+
+ /* If fg and bg match this becomes a space character */
+ if (fg == bg || uc == ' ') {
+ uc = (u_int)-1;
+ fr = 0; /* shutup gcc */
+ fs = 0; /* shutup gcc */
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+ }
+
+ /* Single word, one mask */
+ if ((col + width) <= 32) {
+ rmask = rasops_pmask[col][width];
+ lmask = ~rmask;
+
+ if (uc == (u_int)-1) {
+ bg &= rmask;
+
+ while (height--) {
+ *rp = (*rp & lmask) | bg;
+ DELTA(rp, rs, int32_t *);
+ }
+ } else {
+ /* NOT fontbits if bg is white */
+ if (bg) {
+ while (height--) {
+ fb = ~(fr[3] | (fr[2] << 8) |
+ (fr[1] << 16) | (fr[0] << 24));
+ *rp = (*rp & lmask)
+ | (MBE(fb >> col) & rmask);
+
+ fr += fs;
+ DELTA(rp, rs, int32_t *);
+ }
+ } else {
+ while (height--) {
+ fb = (fr[3] | (fr[2] << 8) |
+ (fr[1] << 16) | (fr[0] << 24));
+ *rp = (*rp & lmask)
+ | (MBE(fb >> col) & rmask);
+
+ fr += fs;
+ DELTA(rp, rs, int32_t *);
+ }
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ *rp = (*rp & lmask) | (fg & rmask);
+ }
+ } else {
+ lmask = ~rasops_lmask[col];
+ rmask = ~rasops_rmask[(col + width) & 31];
+
+ if (uc == (u_int)-1) {
+ width = bg & ~rmask;
+ bg = bg & ~lmask;
+
+ while (height--) {
+ rp[0] = (rp[0] & lmask) | bg;
+ rp[1] = (rp[1] & rmask) | width;
+ DELTA(rp, rs, int32_t *);
+ }
+ } else {
+ width = 32 - col;
+
+ /* NOT fontbits if bg is white */
+ if (bg) {
+ while (height--) {
+ fb = ~(fr[3] | (fr[2] << 8) |
+ (fr[1] << 16) | (fr[0] << 24));
+
+ rp[0] = (rp[0] & lmask)
+ | MBE((u_int)fb >> col);
+
+ rp[1] = (rp[1] & rmask)
+ | (MBE((u_int)fb << width) & ~rmask);
+
+ fr += fs;
+ DELTA(rp, rs, int32_t *);
+ }
+ } else {
+ while (height--) {
+ fb = (fr[3] | (fr[2] << 8) |
+ (fr[1] << 16) | (fr[0] << 24));
+
+ rp[0] = (rp[0] & lmask)
+ | MBE(fb >> col);
+
+ rp[1] = (rp[1] & rmask)
+ | (MBE(fb << width) & ~rmask);
+
+ fr += fs;
+ DELTA(rp, rs, int32_t *);
+ }
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = (rp[0] & lmask) | (fg & ~lmask);
+ rp[1] = (rp[1] & rmask) | (fg & ~rmask);
+ }
+ }
+}
+
+#ifndef RASOPS_SMALL
+/*
+ * Paint a single character. This is for 8-pixel wide fonts.
+ */
+static void
+rasops1_putchar8(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ int height, fs, rs, bg, fg;
+ struct rasops_info *ri;
+ u_char *fr, *rp;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols)
+ return;
+#endif
+
+ rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
+ height = ri->ri_font->fontheight;
+ rs = ri->ri_stride;
+
+ bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
+ fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
+
+ /* If fg and bg match this becomes a space character */
+ if (fg == bg || uc == ' ') {
+ while (height--) {
+ *rp = bg;
+ rp += rs;
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ /* NOT fontbits if bg is white */
+ if (bg) {
+ while (height--) {
+ *rp = ~*fr;
+ fr += fs;
+ rp += rs;
+ }
+ } else {
+ while (height--) {
+ *rp = *fr;
+ fr += fs;
+ rp += rs;
+ }
+ }
+
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0)
+ rp[-(ri->ri_stride << 1)] = fg;
+}
+
+/*
+ * Paint a single character. This is for 16-pixel wide fonts.
+ */
+static void
+rasops1_putchar16(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ int height, fs, rs, bg, fg;
+ struct rasops_info *ri;
+ u_char *fr, *rp;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols)
+ return;
+#endif
+
+ rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
+ height = ri->ri_font->fontheight;
+ rs = ri->ri_stride;
+
+ bg = (attr & 0x000f0000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
+ fg = (attr & 0x0f000000) ? ri->ri_devcmap[1] : ri->ri_devcmap[0];
+
+ /* If fg and bg match this becomes a space character */
+ if (fg == bg || uc == ' ') {
+ while (height--) {
+ *(int16_t *)rp = bg;
+ rp += rs;
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ /* NOT fontbits if bg is white */
+ if (bg) {
+ while (height--) {
+ rp[0] = ~fr[0];
+ rp[1] = ~fr[1];
+ fr += fs;
+ rp += rs;
+ }
+ } else {
+ while (height--) {
+ rp[0] = fr[0];
+ rp[1] = fr[1];
+ fr += fs;
+ rp += rs;
+ }
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0)
+ *(int16_t *)(rp - (ri->ri_stride << 1)) = fg;
+}
+#endif /* !RASOPS_SMALL */
+
+/*
+ * Grab routines common to depths where (bpp < 8)
+ */
+#define NAME(ident) rasops1_##ident
+#define PIXEL_SHIFT 0
+
+#include <dev/rasops/rasops_bitops.h>
diff --git a/sys/dev/rasops/rasops15.c b/sys/dev/rasops/rasops15.c
new file mode 100644
index 00000000000..3a3ed88d7c2
--- /dev/null
+++ b/sys/dev/rasops/rasops15.c
@@ -0,0 +1,470 @@
+/* $OpenBSD: rasops15.c,v 1.1 2001/03/18 04:32:44 nate Exp $ */
+/* $NetBSD: rasops15.c,v 1.7 2000/04/12 14:22:29 pk Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+//__KERNEL_RCSID(0, "$NetBSD: rasops15.c,v 1.7 2000/04/12 14:22:29 pk Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/rasops/rasops.h>
+
+static void rasops15_putchar __P((void *, int, int, u_int, long attr));
+#ifndef RASOPS_SMALL
+static void rasops15_putchar8 __P((void *, int, int, u_int, long attr));
+static void rasops15_putchar12 __P((void *, int, int, u_int, long attr));
+static void rasops15_putchar16 __P((void *, int, int, u_int, long attr));
+static void rasops15_makestamp __P((struct rasops_info *, long));
+#endif
+
+/*
+ * (2x2)x1 stamp for optimized character blitting
+ */
+static int32_t stamp[32];
+static long stamp_attr;
+static int stamp_mutex; /* XXX see note in readme */
+
+/*
+ * XXX this confuses the hell out of gcc2 (not egcs) which always insists
+ * that the shift count is negative.
+ *
+ * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
+ * destination int32_t[0] = STAMP_READ(offset)
+ * destination int32_t[1] = STAMP_READ(offset + 4)
+ */
+#define STAMP_SHIFT(fb,n) ((n*4-3) >= 0 ? (fb)>>(n*4-3):(fb)<<-(n*4-3))
+#define STAMP_MASK (15 << 3)
+#define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o)))
+
+/*
+ * Initalize rasops_info struct for this colordepth.
+ */
+void
+rasops15_init(ri)
+ struct rasops_info *ri;
+{
+
+ switch (ri->ri_font->fontwidth) {
+#ifndef RASOPS_SMALL
+ case 8:
+ ri->ri_ops.putchar = rasops15_putchar8;
+ break;
+
+ case 12:
+ ri->ri_ops.putchar = rasops15_putchar12;
+ break;
+
+ case 16:
+ ri->ri_ops.putchar = rasops15_putchar16;
+ break;
+#endif /* !RASOPS_SMALL */
+ default:
+ ri->ri_ops.putchar = rasops15_putchar;
+ break;
+ }
+
+ if (ri->ri_rnum == 0) {
+ ri->ri_rnum = 5;
+ ri->ri_rpos = 0;
+ ri->ri_gnum = 5 + (ri->ri_depth == 16);
+ ri->ri_gpos = 5;
+ ri->ri_bnum = 5;
+ ri->ri_bpos = 10 + (ri->ri_depth == 16);
+ }
+}
+
+/*
+ * Paint a single character.
+ */
+static void
+rasops15_putchar(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ int fb, width, height, cnt, clr[2];
+ struct rasops_info *ri;
+ u_char *dp, *rp, *fr;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols)
+ return;
+#endif
+
+ rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
+ height = ri->ri_font->fontheight;
+ width = ri->ri_font->fontwidth;
+
+ clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
+ clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
+
+ if (uc == ' ') {
+ int16_t c = (int16_t)clr[0];
+ while (height--) {
+ dp = rp;
+ rp += ri->ri_stride;
+
+ for (cnt = width; cnt; cnt--) {
+ *(int16_t *)dp = c;
+ dp += 2;
+ }
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+
+ while (height--) {
+ dp = rp;
+ fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
+ fr += ri->ri_font->stride;
+ rp += ri->ri_stride;
+
+ for (cnt = width; cnt; cnt--) {
+ *(int16_t *)dp = (int16_t)clr[(fb >> 31) & 1];
+ fb <<= 1;
+ dp += 2;
+ }
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ int16_t c = (int16_t)clr[1];
+ rp -= ri->ri_stride << 1;
+
+ while (width--) {
+ *(int16_t *)rp = c;
+ rp += 2;
+ }
+ }
+}
+
+#ifndef RASOPS_SMALL
+/*
+ * Recompute the (2x2)x1 blitting stamp.
+ */
+static void
+rasops15_makestamp(ri, attr)
+ struct rasops_info *ri;
+ long attr;
+{
+ int32_t fg, bg;
+ int i;
+
+ fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffff;
+ bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffff;
+ stamp_attr = attr;
+
+ for (i = 0; i < 32; i += 2) {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ stamp[i] = (i & 16 ? fg : bg);
+ stamp[i] |= ((i & 8 ? fg : bg) << 16);
+ stamp[i + 1] = (i & 4 ? fg : bg);
+ stamp[i + 1] |= ((i & 2 ? fg : bg) << 16);
+#else
+ stamp[i] = (i & 2 ? fg : bg);
+ stamp[i] |= ((i & 4 ? fg : bg) << 16);
+ stamp[i + 1] = (i & 8 ? fg : bg);
+ stamp[i + 1] |= ((i & 16 ? fg : bg) << 16);
+#endif
+ }
+}
+
+/*
+ * Paint a single character. This is for 8-pixel wide fonts.
+ */
+static void
+rasops15_putchar8(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, so, fs;
+ int32_t *rp;
+ u_char *fr;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops15_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops15_makestamp(ri, attr);
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+
+ if (uc == (u_int)-1) {
+ int32_t c = stamp[0];
+ while (height--) {
+ rp[0] = rp[1] = rp[2] = rp[3] = c;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
+ rp[0] = STAMP_READ(so);
+ rp[1] = STAMP_READ(so + 4);
+
+ so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
+ rp[2] = STAMP_READ(so);
+ rp[3] = STAMP_READ(so + 4);
+
+ fr += fs;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ int32_t c = STAMP_READ(28);
+
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = rp[1] = rp[2] = rp[3] = c;
+ }
+
+ stamp_mutex--;
+}
+
+/*
+ * Paint a single character. This is for 12-pixel wide fonts.
+ */
+static void
+rasops15_putchar12(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, so, fs;
+ int32_t *rp;
+ u_char *fr;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops15_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops15_makestamp(ri, attr);
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+
+ if (uc == (u_int)-1) {
+ int32_t c = stamp[0];
+ while (height--) {
+ rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
+ rp[0] = STAMP_READ(so);
+ rp[1] = STAMP_READ(so + 4);
+
+ so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
+ rp[2] = STAMP_READ(so);
+ rp[3] = STAMP_READ(so + 4);
+
+ so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
+ rp[4] = STAMP_READ(so);
+ rp[5] = STAMP_READ(so + 4);
+
+ fr += fs;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ }
+
+ /* Do underline */
+ if (attr & 1) {
+ int32_t c = STAMP_READ(28);
+
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
+ }
+
+ stamp_mutex--;
+}
+
+/*
+ * Paint a single character. This is for 16-pixel wide fonts.
+ */
+static void
+rasops15_putchar16(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, so, fs;
+ int32_t *rp;
+ u_char *fr;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops15_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops15_makestamp(ri, attr);
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+
+ if (uc == (u_int)-1) {
+ int32_t c = stamp[0];
+ while (height--) {
+ rp[0] = rp[1] = rp[2] = rp[3] =
+ rp[4] = rp[5] = rp[6] = rp[7] = c;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
+ rp[0] = STAMP_READ(so);
+ rp[1] = STAMP_READ(so + 4);
+
+ so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
+ rp[2] = STAMP_READ(so);
+ rp[3] = STAMP_READ(so + 4);
+
+ so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
+ rp[4] = STAMP_READ(so);
+ rp[5] = STAMP_READ(so + 4);
+
+ so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
+ rp[6] = STAMP_READ(so);
+ rp[7] = STAMP_READ(so + 4);
+
+ DELTA(rp, ri->ri_stride, int32_t *);
+ fr += fs;
+ }
+ }
+
+ /* Do underline */
+ if (attr & 1) {
+ int32_t c = STAMP_READ(28);
+
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = rp[1] = rp[2] = rp[3] =
+ rp[4] = rp[5] = rp[6] = rp[7] = c;
+ }
+
+ stamp_mutex--;
+}
+#endif /* !RASOPS_SMALL */
diff --git a/sys/dev/rasops/rasops2.c b/sys/dev/rasops/rasops2.c
new file mode 100644
index 00000000000..0bcc8120a33
--- /dev/null
+++ b/sys/dev/rasops/rasops2.c
@@ -0,0 +1,481 @@
+/* $OpenBSD: rasops2.c,v 1.1 2001/03/18 04:32:44 nate Exp $ */
+/* $NetBSD: rasops2.c,v 1.5 2000/04/12 14:22:29 pk Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opt_rasops.h"
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: rasops2.c,v 1.5 2000/04/12 14:22:29 pk Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <machine/endian.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/rasops/rasops.h>
+#include <dev/rasops/rasops_masks.h>
+
+static void rasops2_copycols __P((void *, int, int, int, int));
+static void rasops2_erasecols __P((void *, int, int, int, long));
+static void rasops2_do_cursor __P((struct rasops_info *));
+static void rasops2_putchar __P((void *, int, int col, u_int, long));
+#ifndef RASOPS_SMALL
+static void rasops2_putchar8 __P((void *, int, int col, u_int, long));
+static void rasops2_putchar12 __P((void *, int, int col, u_int, long));
+static void rasops2_putchar16 __P((void *, int, int col, u_int, long));
+static void rasops2_makestamp __P((struct rasops_info *, long));
+#endif
+
+/*
+ * 4x1 stamp for optimized character blitting
+ */
+static int8_t stamp[16];
+static long stamp_attr;
+static int stamp_mutex; /* XXX see note in README */
+
+/*
+ * Initialize rasops_info struct for this colordepth.
+ */
+void
+rasops2_init(ri)
+ struct rasops_info *ri;
+{
+
+ switch (ri->ri_font->fontwidth) {
+#ifndef RASOPS_SMALL
+ case 8:
+ ri->ri_ops.putchar = rasops2_putchar8;
+ break;
+ case 12:
+ ri->ri_ops.putchar = rasops2_putchar12;
+ break;
+ case 16:
+ ri->ri_ops.putchar = rasops2_putchar16;
+ break;
+#endif /* !RASOPS_SMALL */
+ default:
+ panic("fontwidth not 8/12/16 or RASOPS_SMALL - fixme!");
+ ri->ri_ops.putchar = rasops2_putchar;
+ break;
+ }
+
+ if ((ri->ri_font->fontwidth & 3) != 0) {
+ ri->ri_ops.erasecols = rasops2_erasecols;
+ ri->ri_ops.copycols = rasops2_copycols;
+ ri->ri_do_cursor = rasops2_do_cursor;
+ }
+}
+
+#ifdef notyet
+/*
+ * Paint a single character. This is the generic version, this is ugly.
+ */
+static void
+rasops2_putchar(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ int height, width, fs, rs, fb, bg, fg, lmask, rmask;
+ struct rasops_info *ri;
+ int32_t *rp;
+ u_char *fr;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols)
+ return;
+#endif
+
+ width = ri->ri_font->fontwidth << 1;
+ height = ri->ri_font->fontheight;
+ col *= width;
+ rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
+ col = col & 31;
+ rs = ri->ri_stride;
+
+ bg = ri->ri_devcmap[(attr >> 16) & 0xf];
+ fg = ri->ri_devcmap[(attr >> 24) & 0xf];
+
+ /* If fg and bg match this becomes a space character */
+ if (fg == bg || uc == ' ') {
+ uc = (u_int)-1;
+ fr = 0; /* shutup gcc */
+ fs = 0; /* shutup gcc */
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+ }
+
+ /* Single word, one mask */
+ if ((col + width) <= 32) {
+ rmask = rasops_pmask[col][width];
+ lmask = ~rmask;
+
+ if (uc == (u_int)-1) {
+ bg &= rmask;
+
+ while (height--) {
+ *rp = (*rp & lmask) | bg;
+ DELTA(rp, rs, int32_t *);
+ }
+ } else {
+ while (height--) {
+ /* get bits, mask */
+ /* compose sl */
+ /* mask sl */
+ /* put word */
+ }
+ }
+
+ /* Do underline */
+ if (attr & 1) {
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ *rp = (*rp & lmask) | (fg & rmask);
+ }
+ } else {
+ lmask = ~rasops_lmask[col];
+ rmask = ~rasops_rmask[(col + width) & 31];
+
+ if (uc == (u_int)-1) {
+ bg = bg & ~lmask;
+ width = bg & ~rmask;
+
+ while (height--) {
+ rp[0] = (rp[0] & lmask) | bg;
+ rp[1] = (rp[1] & rmask) | width;
+ DELTA(rp, rs, int32_t *);
+ }
+ } else {
+ width = 32 - col;
+
+ /* NOT fontbits if bg is white */
+ while (height--) {
+ fb = ~(fr[3] | (fr[2] << 8) |
+ (fr[1] << 16) | (fr[0] << 24));
+
+ rp[0] = (rp[0] & lmask)
+ | MBE((u_int)fb >> col);
+
+ rp[1] = (rp[1] & rmask)
+ | (MBE((u_int)fb << width) & ~rmask);
+
+ fr += fs;
+ DELTA(rp, rs, int32_t *);
+ }
+ }
+
+ /* Do underline */
+ if (attr & 1) {
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = (rp[0] & lmask) | (fg & ~lmask);
+ rp[1] = (rp[1] & rmask) | (fg & ~rmask);
+ }
+ }
+}
+#endif
+
+/*
+ * Put a single character. This is the generic version.
+ */
+static void
+rasops2_putchar(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+
+ /* XXX punt */
+}
+
+#ifndef RASOPS_SMALL
+/*
+ * Recompute the blitting stamp.
+ */
+static void
+rasops2_makestamp(ri, attr)
+ struct rasops_info *ri;
+ long attr;
+{
+ int i, fg, bg;
+
+ fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 3;
+ bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 3;
+ stamp_attr = attr;
+
+ for (i = 0; i < 16; i++) {
+ stamp[i] = (i & 1 ? fg : bg);
+ stamp[i] |= (i & 2 ? fg : bg) << 2;
+ stamp[i] |= (i & 4 ? fg : bg) << 4;
+ stamp[i] |= (i & 8 ? fg : bg) << 6;
+ }
+}
+
+/*
+ * Put a single character. This is for 8-pixel wide fonts.
+ */
+static void
+rasops2_putchar8(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, fs, rs;
+ u_char *fr, *rp;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops2_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
+ height = ri->ri_font->fontheight;
+ rs = ri->ri_stride;
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops2_makestamp(ri, attr);
+
+ if (uc == ' ') {
+ int8_t c = stamp[0];
+ while (height--) {
+ *(int16_t *)rp = c;
+ rp += rs;
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ rp[0] = stamp[(*fr >> 4) & 0xf];
+ rp[1] = stamp[*fr & 0xf];
+ fr += fs;
+ rp += rs;
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0)
+ *(int16_t *)(rp - (ri->ri_stride << 1)) = stamp[15];
+
+ stamp_mutex--;
+}
+
+/*
+ * Put a single character. This is for 12-pixel wide fonts.
+ */
+static void
+rasops2_putchar12(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, fs, rs;
+ u_char *fr, *rp;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops2_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
+ height = ri->ri_font->fontheight;
+ rs = ri->ri_stride;
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops2_makestamp(ri, attr);
+
+ if (uc == ' ') {
+ int8_t c = stamp[0];
+ while (height--) {
+ rp[0] = rp[1] = rp[2] = c;
+ rp += rs;
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ rp[0] = stamp[(fr[0] >> 4) & 0xf];
+ rp[1] = stamp[fr[0] & 0xf];
+ rp[2] = stamp[(fr[1] >> 4) & 0xf];
+ fr += fs;
+ rp += rs;
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ rp -= ri->ri_stride << 1;
+ rp[0] = rp[1] = rp[2] = stamp[15];
+ }
+
+ stamp_mutex--;
+}
+
+/*
+ * Put a single character. This is for 16-pixel wide fonts.
+ */
+static void
+rasops2_putchar16(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, fs, rs;
+ u_char *fr, *rp;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops2_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
+ height = ri->ri_font->fontheight;
+ rs = ri->ri_stride;
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops2_makestamp(ri, attr);
+
+ if (uc == ' ') {
+ int8_t c = stamp[0];
+ while (height--) {
+ *(int32_t *)rp = c;
+ rp += rs;
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ rp[0] = stamp[(fr[0] >> 4) & 0xf];
+ rp[1] = stamp[fr[0] & 0xf];
+ rp[2] = stamp[(fr[1] >> 4) & 0xf];
+ rp[3] = stamp[fr[1] & 0xf];
+ fr += fs;
+ rp += rs;
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0)
+ *(int32_t *)(rp - (ri->ri_stride << 1)) = stamp[15];
+
+ stamp_mutex--;
+}
+#endif /* !RASOPS_SMALL */
+
+/*
+ * Grab routines common to depths where (bpp < 8)
+ */
+#define NAME(ident) rasops2_##ident
+#define PIXEL_SHIFT 1
+
+#include <dev/rasops/rasops_bitops.h>
diff --git a/sys/dev/rasops/rasops24.c b/sys/dev/rasops/rasops24.c
new file mode 100644
index 00000000000..59324eddb58
--- /dev/null
+++ b/sys/dev/rasops/rasops24.c
@@ -0,0 +1,740 @@
+/* $OpenBSD: rasops24.c,v 1.1 2001/03/18 04:32:45 nate Exp $ */
+/* $NetBSD: rasops24.c,v 1.12 2000/04/12 14:22:29 pk Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opt_rasops.h"
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: rasops24.c,v 1.12 2000/04/12 14:22:29 pk Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+
+#include <machine/endian.h>
+#include <machine/bswap.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/rasops/rasops.h>
+
+static void rasops24_erasecols __P((void *, int, int, int, long));
+static void rasops24_eraserows __P((void *, int, int, long));
+static void rasops24_putchar __P((void *, int, int, u_int, long attr));
+#ifndef RASOPS_SMALL
+static void rasops24_putchar8 __P((void *, int, int, u_int, long attr));
+static void rasops24_putchar12 __P((void *, int, int, u_int, long attr));
+static void rasops24_putchar16 __P((void *, int, int, u_int, long attr));
+static void rasops24_makestamp __P((struct rasops_info *, long));
+#endif
+
+/*
+ * 4x1 stamp for optimized character blitting
+ */
+static int32_t stamp[64];
+static long stamp_attr;
+static int stamp_mutex; /* XXX see note in readme */
+
+/*
+ * XXX this confuses the hell out of gcc2 (not egcs) which always insists
+ * that the shift count is negative.
+ *
+ * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
+ * destination int32_t[0] = STAMP_READ(offset)
+ * destination int32_t[1] = STAMP_READ(offset + 4)
+ * destination int32_t[2] = STAMP_READ(offset + 8)
+ */
+#define STAMP_SHIFT(fb,n) ((n*4-4) >= 0 ? (fb)>>(n*4-4):(fb)<<-(n*4-4))
+#define STAMP_MASK (0xf << 4)
+#define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o)))
+
+/*
+ * Initalize rasops_info struct for this colordepth.
+ */
+void
+rasops24_init(ri)
+ struct rasops_info *ri;
+{
+
+ switch (ri->ri_font->fontwidth) {
+#ifndef RASOPS_SMALL
+ case 8:
+ ri->ri_ops.putchar = rasops24_putchar8;
+ break;
+ case 12:
+ ri->ri_ops.putchar = rasops24_putchar12;
+ break;
+ case 16:
+ ri->ri_ops.putchar = rasops24_putchar16;
+ break;
+#endif
+ default:
+ ri->ri_ops.putchar = rasops24_putchar;
+ break;
+ }
+
+ if (ri->ri_rnum == 0) {
+ ri->ri_rnum = 8;
+ ri->ri_rpos = 0;
+ ri->ri_gnum = 8;
+ ri->ri_gpos = 8;
+ ri->ri_bnum = 8;
+ ri->ri_bpos = 16;
+ }
+
+ ri->ri_ops.erasecols = rasops24_erasecols;
+ ri->ri_ops.eraserows = rasops24_eraserows;
+}
+
+/*
+ * Put a single character. This is the generic version.
+ * XXX this bites - we should use masks.
+ */
+static void
+rasops24_putchar(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ int fb, width, height, cnt, clr[2];
+ struct rasops_info *ri;
+ u_char *dp, *rp, *fr;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols)
+ return;
+#endif
+
+ rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
+ height = ri->ri_font->fontheight;
+ width = ri->ri_font->fontwidth;
+
+ clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
+ clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
+
+ if (uc == ' ') {
+ u_char c = clr[0];
+ while (height--) {
+ dp = rp;
+ rp += ri->ri_stride;
+
+ for (cnt = width; cnt; cnt--) {
+ *dp++ = c >> 16;
+ *dp++ = c >> 8;
+ *dp++ = c;
+ }
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+
+ while (height--) {
+ dp = rp;
+ fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
+ (fr[0] << 24);
+ fr += ri->ri_font->stride;
+ rp += ri->ri_stride;
+
+ for (cnt = width; cnt; cnt--, fb <<= 1) {
+ if ((fb >> 31) & 1) {
+ *dp++ = clr[1] >> 16;
+ *dp++ = clr[1] >> 8;
+ *dp++ = clr[1];
+ } else {
+ *dp++ = clr[0] >> 16;
+ *dp++ = clr[0] >> 8;
+ *dp++ = clr[0];
+ }
+ }
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ u_char c = clr[1];
+
+ rp -= ri->ri_stride << 1;
+
+ while (width--) {
+ *rp++ = c >> 16;
+ *rp++ = c >> 8;
+ *rp++ = c;
+ }
+ }
+}
+
+#ifndef RASOPS_SMALL
+/*
+ * Recompute the blitting stamp.
+ */
+static void
+rasops24_makestamp(ri, attr)
+ struct rasops_info *ri;
+ long attr;
+{
+ u_int fg, bg, c1, c2, c3, c4;
+ int i;
+
+ fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffffff;
+ bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffffff;
+ stamp_attr = attr;
+
+ for (i = 0; i < 64; i += 4) {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ c1 = (i & 32 ? fg : bg);
+ c2 = (i & 16 ? fg : bg);
+ c3 = (i & 8 ? fg : bg);
+ c4 = (i & 4 ? fg : bg);
+#else
+ c1 = (i & 8 ? fg : bg);
+ c2 = (i & 4 ? fg : bg);
+ c3 = (i & 16 ? fg : bg);
+ c4 = (i & 32 ? fg : bg);
+#endif
+ stamp[i+0] = (c1 << 8) | (c2 >> 16);
+ stamp[i+1] = (c2 << 16) | (c3 >> 8);
+ stamp[i+2] = (c3 << 24) | c4;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ if ((ri->ri_flg & RI_BSWAP) == 0) {
+#else
+ if ((ri->ri_flg & RI_BSWAP) != 0) {
+#endif
+ stamp[i+0] = bswap32(stamp[i+0]);
+ stamp[i+1] = bswap32(stamp[i+1]);
+ stamp[i+2] = bswap32(stamp[i+2]);
+ }
+ }
+}
+
+/*
+ * Put a single character. This is for 8-pixel wide fonts.
+ */
+static void
+rasops24_putchar8(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, so, fs;
+ int32_t *rp;
+ u_char *fr;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops24_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops24_makestamp(ri, attr);
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+
+ if (uc == (u_int)-1) {
+ int32_t c = stamp[0];
+ while (height--) {
+ rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
+ rp[0] = STAMP_READ(so);
+ rp[1] = STAMP_READ(so + 4);
+ rp[2] = STAMP_READ(so + 8);
+
+ so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
+ rp[3] = STAMP_READ(so);
+ rp[4] = STAMP_READ(so + 4);
+ rp[5] = STAMP_READ(so + 8);
+
+ fr += fs;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ int32_t c = STAMP_READ(52);
+
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
+ }
+
+ stamp_mutex--;
+}
+
+/*
+ * Put a single character. This is for 12-pixel wide fonts.
+ */
+static void
+rasops24_putchar12(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, so, fs;
+ int32_t *rp;
+ u_char *fr;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops24_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops24_makestamp(ri, attr);
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+
+ if (uc == (u_int)-1) {
+ int32_t c = stamp[0];
+ while (height--) {
+ rp[0] = rp[1] = rp[2] = rp[3] =
+ rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
+ rp[0] = STAMP_READ(so);
+ rp[1] = STAMP_READ(so + 4);
+ rp[2] = STAMP_READ(so + 8);
+
+ so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
+ rp[3] = STAMP_READ(so);
+ rp[4] = STAMP_READ(so + 4);
+ rp[5] = STAMP_READ(so + 8);
+
+ so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
+ rp[6] = STAMP_READ(so);
+ rp[7] = STAMP_READ(so + 4);
+ rp[8] = STAMP_READ(so + 8);
+
+ fr += fs;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ int32_t c = STAMP_READ(52);
+
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = rp[1] = rp[2] = rp[3] =
+ rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
+ }
+
+ stamp_mutex--;
+}
+
+/*
+ * Put a single character. This is for 16-pixel wide fonts.
+ */
+static void
+rasops24_putchar16(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, so, fs;
+ int32_t *rp;
+ u_char *fr;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops24_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops24_makestamp(ri, attr);
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+
+ if (uc == (u_int)-1) {
+ int32_t c = stamp[0];
+ while (height--) {
+ rp[0] = rp[1] = rp[2] = rp[3] =
+ rp[4] = rp[5] = rp[6] = rp[7] =
+ rp[8] = rp[9] = rp[10] = rp[11] = c;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
+ rp[0] = STAMP_READ(so);
+ rp[1] = STAMP_READ(so + 4);
+ rp[2] = STAMP_READ(so + 8);
+
+ so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
+ rp[3] = STAMP_READ(so);
+ rp[4] = STAMP_READ(so + 4);
+ rp[5] = STAMP_READ(so + 8);
+
+ so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
+ rp[6] = STAMP_READ(so);
+ rp[7] = STAMP_READ(so + 4);
+ rp[8] = STAMP_READ(so + 8);
+
+ so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
+ rp[9] = STAMP_READ(so);
+ rp[10] = STAMP_READ(so + 4);
+ rp[11] = STAMP_READ(so + 8);
+
+ DELTA(rp, ri->ri_stride, int32_t *);
+ fr += fs;
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ int32_t c = STAMP_READ(52);
+
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = rp[1] = rp[2] = rp[3] =
+ rp[4] = rp[5] = rp[6] = rp[7] =
+ rp[8] = rp[9] = rp[10] = rp[11] = c;
+ }
+
+ stamp_mutex--;
+}
+#endif /* !RASOPS_SMALL */
+
+/*
+ * Erase rows. This is nice and easy due to alignment.
+ */
+static void
+rasops24_eraserows(cookie, row, num, attr)
+ void *cookie;
+ int row, num;
+ long attr;
+{
+ int n9, n3, n1, cnt, stride, delta;
+ u_int32_t *dp, clr, stamp[3];
+ struct rasops_info *ri;
+
+ /*
+ * If the color is gray, we can cheat and use the generic routines
+ * (which are faster, hopefully) since the r,g,b values are the same.
+ */
+ if ((attr & 4) != 0) {
+ rasops_eraserows(cookie, row, num, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if (row < 0) {
+ num += row;
+ row = 0;
+ }
+
+ if ((row + num) > ri->ri_rows)
+ num = ri->ri_rows - row;
+
+ if (num <= 0)
+ return;
+#endif
+
+ clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
+ stamp[0] = (clr << 8) | (clr >> 16);
+ stamp[1] = (clr << 16) | (clr >> 8);
+ stamp[2] = (clr << 24) | clr;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ if ((ri->ri_flg & RI_BSWAP) == 0) {
+#else
+ if ((ri->ri_flg & RI_BSWAP) != 0) {
+#endif
+ stamp[0] = bswap32(stamp[0]);
+ stamp[1] = bswap32(stamp[1]);
+ stamp[2] = bswap32(stamp[2]);
+ }
+
+ /*
+ * XXX the wsdisplay_emulops interface seems a little deficient in
+ * that there is no way to clear the *entire* screen. We provide a
+ * workaround here: if the entire console area is being cleared, and
+ * the RI_FULLCLEAR flag is set, clear the entire display.
+ */
+ if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
+ stride = ri->ri_stride;
+ num = ri->ri_height;
+ dp = (int32_t *)ri->ri_origbits;
+ delta = 0;
+ } else {
+ stride = ri->ri_emustride;
+ num *= ri->ri_font->fontheight;
+ dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
+ delta = ri->ri_delta;
+ }
+
+ n9 = stride / 36;
+ cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
+ n3 = (stride - cnt) / 12;
+ cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
+ n1 = (stride - cnt) >> 2;
+
+ while (num--) {
+ for (cnt = n9; cnt; cnt--) {
+ dp[0] = stamp[0];
+ dp[1] = stamp[1];
+ dp[2] = stamp[2];
+ dp[3] = stamp[0];
+ dp[4] = stamp[1];
+ dp[5] = stamp[2];
+ dp[6] = stamp[0];
+ dp[7] = stamp[1];
+ dp[8] = stamp[2];
+ dp += 9;
+ }
+
+ for (cnt = n3; cnt; cnt--) {
+ dp[0] = stamp[0];
+ dp[1] = stamp[1];
+ dp[2] = stamp[2];
+ dp += 3;
+ }
+
+ for (cnt = 0; cnt < n1; cnt++)
+ *dp++ = stamp[cnt];
+
+ DELTA(dp, delta, int32_t *);
+ }
+}
+
+/*
+ * Erase columns.
+ */
+static void
+rasops24_erasecols(cookie, row, col, num, attr)
+ void *cookie;
+ int row, col, num;
+ long attr;
+{
+ int n12, n4, height, cnt, slop, clr, stamp[3];
+ struct rasops_info *ri;
+ int32_t *dp, *rp;
+ u_char *dbp;
+
+ /*
+ * If the color is gray, we can cheat and use the generic routines
+ * (which are faster, hopefully) since the r,g,b values are the same.
+ */
+ if ((attr & 4) != 0) {
+ rasops_erasecols(cookie, row, col, num, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if (col < 0) {
+ num += col;
+ col = 0;
+ }
+
+ if ((col + num) > ri->ri_cols)
+ num = ri->ri_cols - col;
+
+ if (num <= 0)
+ return;
+#endif
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ num *= ri->ri_font->fontwidth;
+ height = ri->ri_font->fontheight;
+
+ clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
+ stamp[0] = (clr << 8) | (clr >> 16);
+ stamp[1] = (clr << 16) | (clr >> 8);
+ stamp[2] = (clr << 24) | clr;
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ if ((ri->ri_flg & RI_BSWAP) == 0) {
+#else
+ if ((ri->ri_flg & RI_BSWAP) != 0) {
+#endif
+ stamp[0] = bswap32(stamp[0]);
+ stamp[1] = bswap32(stamp[1]);
+ stamp[2] = bswap32(stamp[2]);
+ }
+
+ /*
+ * The current byte offset mod 4 tells us the number of 24-bit pels
+ * we need to write for alignment to 32-bits. Once we're aligned on
+ * a 32-bit boundary, we're also aligned on a 4 pixel boundary, so
+ * the stamp does not need to be rotated. The following shows the
+ * layout of 4 pels in a 3 word region and illustrates this:
+ *
+ * aaab bbcc cddd
+ */
+ slop = (int)rp & 3; num -= slop;
+ n12 = num / 12; num -= (n12 << 3) + (n12 << 2);
+ n4 = num >> 2; num &= 3;
+
+ while (height--) {
+ dbp = (u_char *)rp;
+ DELTA(rp, ri->ri_stride, int32_t *);
+
+ /* Align to 4 bytes */
+ /* XXX handle with masks, bring under control of RI_BSWAP */
+ for (cnt = slop; cnt; cnt--) {
+ *dbp++ = (clr >> 16);
+ *dbp++ = (clr >> 8);
+ *dbp++ = clr;
+ }
+
+ dp = (int32_t *)dbp;
+
+ /* 12 pels per loop */
+ for (cnt = n12; cnt; cnt--) {
+ dp[0] = stamp[0];
+ dp[1] = stamp[1];
+ dp[2] = stamp[2];
+ dp[3] = stamp[0];
+ dp[4] = stamp[1];
+ dp[5] = stamp[2];
+ dp[6] = stamp[0];
+ dp[7] = stamp[1];
+ dp[8] = stamp[2];
+ dp += 9;
+ }
+
+ /* 4 pels per loop */
+ for (cnt = n4; cnt; cnt--) {
+ dp[0] = stamp[0];
+ dp[1] = stamp[1];
+ dp[2] = stamp[2];
+ dp += 3;
+ }
+
+ /* Trailing slop */
+ /* XXX handle with masks, bring under control of RI_BSWAP */
+ dbp = (u_char *)dp;
+ for (cnt = num; cnt; cnt--) {
+ *dbp++ = (clr >> 16);
+ *dbp++ = (clr >> 8);
+ *dbp++ = clr;
+ }
+ }
+}
diff --git a/sys/dev/rasops/rasops32.c b/sys/dev/rasops/rasops32.c
new file mode 100644
index 00000000000..2df3db2b385
--- /dev/null
+++ b/sys/dev/rasops/rasops32.c
@@ -0,0 +1,142 @@
+/* $OpenBSD: rasops32.c,v 1.1 2001/03/18 04:32:45 nate Exp $ */
+/* $NetBSD: rasops32.c,v 1.7 2000/04/12 14:22:29 pk Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+//__KERNEL_RCSID(0, "$NetBSD: rasops32.c,v 1.7 2000/04/12 14:22:29 pk Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/rasops/rasops.h>
+
+static void rasops32_putchar __P((void *, int, int, u_int, long attr));
+
+/*
+ * Initalize a 'rasops_info' descriptor for this depth.
+ */
+void
+rasops32_init(ri)
+ struct rasops_info *ri;
+{
+
+ if (ri->ri_rnum == 0) {
+ ri->ri_rnum = 8;
+ ri->ri_rpos = 0;
+ ri->ri_gnum = 8;
+ ri->ri_gpos = 8;
+ ri->ri_bnum = 8;
+ ri->ri_bpos = 16;
+ }
+
+ ri->ri_ops.putchar = rasops32_putchar;
+}
+
+/*
+ * Paint a single character.
+ */
+static void
+rasops32_putchar(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ int width, height, cnt, fs, fb, clr[2];
+ struct rasops_info *ri;
+ int32_t *dp, *rp;
+ u_char *fr;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols)
+ return;
+#endif
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+
+ height = ri->ri_font->fontheight;
+ width = ri->ri_font->fontwidth;
+
+ clr[0] = ri->ri_devcmap[(attr >> 16) & 0xf];
+ clr[1] = ri->ri_devcmap[(attr >> 24) & 0xf];
+
+ if (uc == ' ') {
+ while (height--) {
+ dp = rp;
+ DELTA(rp, ri->ri_stride, int32_t *);
+
+ for (cnt = width; cnt; cnt--)
+ *dp++ = clr[0];
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ dp = rp;
+ fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
+ (fr[0] << 24);
+ fr += fs;
+ DELTA(rp, ri->ri_stride, int32_t *);
+
+ for (cnt = width; cnt; cnt--) {
+ *dp++ = clr[(fb >> 31) & 1];
+ fb <<= 1;
+ }
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+
+ while (width--)
+ *rp++ = clr[1];
+ }
+}
diff --git a/sys/dev/rasops/rasops4.c b/sys/dev/rasops/rasops4.c
new file mode 100644
index 00000000000..6ec6c1c0a18
--- /dev/null
+++ b/sys/dev/rasops/rasops4.c
@@ -0,0 +1,499 @@
+/* $OpenBSD: rasops4.c,v 1.1 2001/03/18 04:32:45 nate Exp $ */
+/* $NetBSD: $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+//__KERNEL_RCSID(0, "$NetBSD: $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <machine/endian.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/rasops/rasops.h>
+#include <dev/rasops/rasops_masks.h>
+
+static void rasops4_copycols __P((void *, int, int, int, int));
+static void rasops4_erasecols __P((void *, int, int, int, long));
+static void rasops4_do_cursor __P((struct rasops_info *));
+static void rasops4_putchar __P((void *, int, int col, u_int, long));
+#ifndef RASOPS_SMALL
+static void rasops4_putchar8 __P((void *, int, int col, u_int, long));
+static void rasops4_putchar12 __P((void *, int, int col, u_int, long));
+static void rasops4_putchar16 __P((void *, int, int col, u_int, long));
+static void rasops4_makestamp __P((struct rasops_info *, long));
+#endif
+
+/*
+ * 4x1 stamp for optimized character blitting
+ */
+static u_int16_t stamp[16];
+static long stamp_attr;
+static int stamp_mutex; /* XXX see note in README */
+
+/*
+ * Initialize rasops_info struct for this colordepth.
+ */
+void
+rasops4_init(ri)
+ struct rasops_info *ri;
+{
+
+ switch (ri->ri_font->fontwidth) {
+#ifndef RASOPS_SMALL
+ case 8:
+ ri->ri_ops.putchar = rasops4_putchar8;
+ break;
+ case 12:
+ ri->ri_ops.putchar = rasops4_putchar12;
+ break;
+ case 16:
+ ri->ri_ops.putchar = rasops4_putchar16;
+ break;
+#endif /* !RASOPS_SMALL */
+ default:
+ panic("fontwidth not 8/12/16 or RASOPS_SMALL - fixme!");
+ ri->ri_ops.putchar = rasops4_putchar;
+ break;
+ }
+
+ if ((ri->ri_font->fontwidth & 1) != 0) {
+ ri->ri_ops.erasecols = rasops4_erasecols;
+ ri->ri_ops.copycols = rasops4_copycols;
+ ri->ri_do_cursor = rasops4_do_cursor;
+ }
+}
+
+#ifdef notyet
+/*
+ * Paint a single character. This is the generic version, this is ugly.
+ */
+static void
+rasops4_putchar(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ int height, width, fs, rs, fb, bg, fg, lmask, rmask;
+ struct rasops_info *ri;
+ int32_t *rp;
+ u_char *fr;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols)
+ return;
+#endif
+
+ width = ri->ri_font->fontwidth << 1;
+ height = ri->ri_font->fontheight;
+ col *= width;
+ rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
+ col = col & 31;
+ rs = ri->ri_stride;
+
+ bg = ri->ri_devcmap[(attr >> 16) & 0xf];
+ fg = ri->ri_devcmap[(attr >> 24) & 0xf];
+
+ /* If fg and bg match this becomes a space character */
+ if (fg == bg || uc == ' ') {
+ uc = (u_int)-1;
+ fr = 0; /* shutup gcc */
+ fs = 0; /* shutup gcc */
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+ }
+
+ /* Single word, one mask */
+ if ((col + width) <= 32) {
+ rmask = rasops_pmask[col][width];
+ lmask = ~rmask;
+
+ if (uc == (u_int)-1) {
+ bg &= rmask;
+
+ while (height--) {
+ *rp = (*rp & lmask) | bg;
+ DELTA(rp, rs, int32_t *);
+ }
+ } else {
+ while (height--) {
+ /* get bits, mask */
+ /* compose sl */
+ /* mask sl */
+ /* put word */
+ }
+ }
+
+ /* Do underline */
+ if (attr & 1) {
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ *rp = (*rp & lmask) | (fg & rmask);
+ }
+ } else {
+ lmask = ~rasops_lmask[col];
+ rmask = ~rasops_rmask[(col + width) & 31];
+
+ if (uc == (u_int)-1) {
+ bg = bg & ~lmask;
+ width = bg & ~rmask;
+
+ while (height--) {
+ rp[0] = (rp[0] & lmask) | bg;
+ rp[1] = (rp[1] & rmask) | width;
+ DELTA(rp, rs, int32_t *);
+ }
+ } else {
+ width = 32 - col;
+
+ /* NOT fontbits if bg is white */
+ while (height--) {
+ fb = ~(fr[3] | (fr[2] << 8) |
+ (fr[1] << 16) | (fr[0] << 24));
+
+ rp[0] = (rp[0] & lmask)
+ | MBE((u_int)fb >> col);
+
+ rp[1] = (rp[1] & rmask)
+ | (MBE((u_int)fb << width) & ~rmask);
+
+ fr += fs;
+ DELTA(rp, rs, int32_t *);
+ }
+ }
+
+ /* Do underline */
+ if (attr & 1) {
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = (rp[0] & lmask) | (fg & ~lmask);
+ rp[1] = (rp[1] & rmask) | (fg & ~rmask);
+ }
+ }
+}
+#endif
+
+/*
+ * Put a single character. This is the generic version.
+ */
+static void
+rasops4_putchar(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+
+ /* XXX punt */
+}
+
+#ifndef RASOPS_SMALL
+/*
+ * Recompute the blitting stamp.
+ */
+static void
+rasops4_makestamp(ri, attr)
+ struct rasops_info *ri;
+ long attr;
+{
+ int i, fg, bg;
+
+ fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 0xf;
+ bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xf;
+ stamp_attr = attr;
+
+ for (i = 0; i < 16; i++) {
+ stamp[i] = (i & 1 ? fg : bg) << 8;
+ stamp[i] |= (i & 2 ? fg : bg) << 12;
+ stamp[i] |= (i & 4 ? fg : bg) << 0;
+ stamp[i] |= (i & 8 ? fg : bg) << 4;
+ }
+}
+
+/*
+ * Put a single character. This is for 8-pixel wide fonts.
+ */
+static void
+rasops4_putchar8(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, fs, rs;
+ u_char *fr;
+ u_int16_t *rp;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops4_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ rp = (u_int16_t *)(ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+ rs = ri->ri_stride / sizeof(*rp);
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops4_makestamp(ri, attr);
+
+ if (uc == ' ') {
+ u_int16_t c = stamp[0];
+ while (height--) {
+ rp[0] = c;
+ rp[1] = c;
+ rp += rs;
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ rp[0] = stamp[(*fr >> 4) & 0xf];
+ rp[1] = stamp[*fr & 0xf];
+ fr += fs;
+ rp += rs;
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ rp -= (rs << 1);
+ rp[0] = stamp[15];
+ rp[1] = stamp[15];
+ }
+
+ stamp_mutex--;
+}
+
+/*
+ * Put a single character. This is for 12-pixel wide fonts.
+ */
+static void
+rasops4_putchar12(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, fs, rs;
+ u_char *fr;
+ u_int16_t *rp;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops4_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ rp = (u_int16_t *)(ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+ rs = ri->ri_stride / sizeof(*rp);
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops4_makestamp(ri, attr);
+
+ if (uc == ' ') {
+ u_int16_t c = stamp[0];
+ while (height--) {
+ rp[0] = c;
+ rp[1] = c;
+ rp[2] = c;
+ rp += rs;
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ rp[0] = stamp[(fr[0] >> 4) & 0xf];
+ rp[1] = stamp[fr[0] & 0xf];
+ rp[2] = stamp[(fr[1] >> 4) & 0xf];
+ fr += fs;
+ rp += rs;
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ rp -= (rs << 1);
+ rp[0] = stamp[15];
+ rp[1] = stamp[15];
+ rp[2] = stamp[15];
+ }
+
+ stamp_mutex--;
+}
+
+/*
+ * Put a single character. This is for 16-pixel wide fonts.
+ */
+static void
+rasops4_putchar16(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, fs, rs;
+ u_char *fr;
+ u_int16_t *rp;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops4_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ rp = (u_int16_t *)(ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+ rs = ri->ri_stride / sizeof(*rp);
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops4_makestamp(ri, attr);
+
+ if (uc == ' ') {
+ u_int16_t c = stamp[0];
+ while (height--) {
+ rp[0] = c;
+ rp[1] = c;
+ rp[2] = c;
+ rp[3] = c;
+ rp += rs;
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ rp[0] = stamp[(fr[0] >> 4) & 0xf];
+ rp[1] = stamp[fr[0] & 0xf];
+ rp[2] = stamp[(fr[1] >> 4) & 0xf];
+ rp[3] = stamp[fr[1] & 0xf];
+ fr += fs;
+ rp += rs;
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ rp -= (rs << 1);
+ rp[0] = stamp[15];
+ rp[1] = stamp[15];
+ rp[2] = stamp[15];
+ rp[3] = stamp[15];
+ }
+
+ stamp_mutex--;
+}
+#endif /* !RASOPS_SMALL */
+
+/*
+ * Grab routines common to depths where (bpp < 8)
+ */
+#define NAME(ident) rasops4_##ident
+#define PIXEL_SHIFT 3
+
+#include <dev/rasops/rasops_bitops.h>
diff --git a/sys/dev/rasops/rasops8.c b/sys/dev/rasops/rasops8.c
new file mode 100644
index 00000000000..881aa503421
--- /dev/null
+++ b/sys/dev/rasops/rasops8.c
@@ -0,0 +1,420 @@
+/* $OpenBSD: rasops8.c,v 1.1 2001/03/18 04:32:45 nate Exp $ */
+/* $NetBSD: rasops8.c,v 1.8 2000/04/12 14:22:29 pk Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+//__KERNEL_RCSID(0, "$NetBSD: rasops8.c,v 1.8 2000/04/12 14:22:29 pk Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/wscons/wsconsio.h>
+#include <dev/rasops/rasops.h>
+
+static void rasops8_putchar __P((void *, int, int, u_int, long attr));
+#ifndef RASOPS_SMALL
+static void rasops8_putchar8 __P((void *, int, int, u_int, long attr));
+static void rasops8_putchar12 __P((void *, int, int, u_int, long attr));
+static void rasops8_putchar16 __P((void *, int, int, u_int, long attr));
+static void rasops8_makestamp __P((struct rasops_info *ri, long));
+#endif
+
+/*
+ * 4x1 stamp for optimized character blitting
+ */
+static int32_t stamp[16];
+static long stamp_attr;
+static int stamp_mutex; /* XXX see note in README */
+
+/*
+ * XXX this confuses the hell out of gcc2 (not egcs) which always insists
+ * that the shift count is negative.
+ *
+ * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
+ * destination = STAMP_READ(offset)
+ */
+#define STAMP_SHIFT(fb,n) ((n*4-2) >= 0 ? (fb)>>(n*4-2):(fb)<<-(n*4-2))
+#define STAMP_MASK (0xf << 2)
+#define STAMP_READ(o) (*(int32_t *)((caddr_t)stamp + (o)))
+
+/*
+ * Initalize a 'rasops_info' descriptor for this depth.
+ */
+void
+rasops8_init(ri)
+ struct rasops_info *ri;
+{
+
+ switch (ri->ri_font->fontwidth) {
+#ifndef RASOPS_SMALL
+ case 8:
+ ri->ri_ops.putchar = rasops8_putchar8;
+ break;
+ case 12:
+ ri->ri_ops.putchar = rasops8_putchar12;
+ break;
+ case 16:
+ ri->ri_ops.putchar = rasops8_putchar16;
+ break;
+#endif /* !RASOPS_SMALL */
+ default:
+ ri->ri_ops.putchar = rasops8_putchar;
+ break;
+ }
+}
+
+/*
+ * Put a single character.
+ */
+static void
+rasops8_putchar(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ int width, height, cnt, fs, fb;
+ u_char *dp, *rp, *fr, clr[2];
+ struct rasops_info *ri;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ /* Catches 'row < 0' case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols)
+ return;
+#endif
+ rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
+
+ height = ri->ri_font->fontheight;
+ width = ri->ri_font->fontwidth;
+ clr[0] = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
+ clr[1] = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
+
+ if (uc == ' ') {
+ u_char c = clr[0];
+
+ while (height--) {
+ dp = rp;
+ rp += ri->ri_stride;
+
+ for (cnt = width; cnt; cnt--)
+ *dp++ = c;
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ dp = rp;
+ fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
+ fr += fs;
+ rp += ri->ri_stride;
+
+ for (cnt = width; cnt; cnt--) {
+ *dp++ = clr[(fb >> 31) & 1];
+ fb <<= 1;
+ }
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ u_char c = clr[1];
+
+ rp -= (ri->ri_stride << 1);
+
+ while (width--)
+ *rp++ = c;
+ }
+}
+
+#ifndef RASOPS_SMALL
+/*
+ * Recompute the 4x1 blitting stamp.
+ */
+static void
+rasops8_makestamp(ri, attr)
+ struct rasops_info *ri;
+ long attr;
+{
+ int32_t fg, bg;
+ int i;
+
+ fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 0xff;
+ bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xff;
+ stamp_attr = attr;
+
+ for (i = 0; i < 16; i++) {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ stamp[i] = (i & 8 ? fg : bg);
+ stamp[i] |= ((i & 4 ? fg : bg) << 8);
+ stamp[i] |= ((i & 2 ? fg : bg) << 16);
+ stamp[i] |= ((i & 1 ? fg : bg) << 24);
+#else
+ stamp[i] = (i & 1 ? fg : bg);
+ stamp[i] |= ((i & 2 ? fg : bg) << 8);
+ stamp[i] |= ((i & 4 ? fg : bg) << 16);
+ stamp[i] |= ((i & 8 ? fg : bg) << 24);
+#endif
+ }
+}
+
+/*
+ * Put a single character. This is for 8-pixel wide fonts.
+ */
+static void
+rasops8_putchar8(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, fs;
+ int32_t *rp;
+ u_char *fr;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops8_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops8_makestamp(ri, attr);
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+
+ if (uc == ' ') {
+ while (height--) {
+ rp[0] = rp[1] = stamp[0];
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
+ rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
+
+ fr += fs;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = rp[1] = stamp[15];
+ }
+
+ stamp_mutex--;
+}
+
+/*
+ * Put a single character. This is for 12-pixel wide fonts.
+ */
+static void
+rasops8_putchar12(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, fs;
+ int32_t *rp;
+ u_char *fr;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops8_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops8_makestamp(ri, attr);
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+
+ if (uc == ' ') {
+ while (height--) {
+ int32_t c = stamp[0];
+
+ rp[0] = rp[1] = rp[2] = c;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
+ rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
+ rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
+
+ fr += fs;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = rp[1] = rp[2] = stamp[15];
+ }
+
+ stamp_mutex--;
+}
+
+/*
+ * Put a single character. This is for 16-pixel wide fonts.
+ */
+static void
+rasops8_putchar16(cookie, row, col, uc, attr)
+ void *cookie;
+ int row, col;
+ u_int uc;
+ long attr;
+{
+ struct rasops_info *ri;
+ int height, fs;
+ int32_t *rp;
+ u_char *fr;
+
+ /* Can't risk remaking the stamp if it's already in use */
+ if (stamp_mutex++) {
+ stamp_mutex--;
+ rasops8_putchar(cookie, row, col, uc, attr);
+ return;
+ }
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows) {
+ stamp_mutex--;
+ return;
+ }
+
+ if ((unsigned)col >= (unsigned)ri->ri_cols) {
+ stamp_mutex--;
+ return;
+ }
+#endif
+
+ /* Recompute stamp? */
+ if (attr != stamp_attr)
+ rasops8_makestamp(ri, attr);
+
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
+ height = ri->ri_font->fontheight;
+
+ if (uc == ' ') {
+ while (height--)
+ rp[0] = rp[1] = rp[2] = rp[3] = stamp[0];
+ } else {
+ uc -= ri->ri_font->firstchar;
+ fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
+ fs = ri->ri_font->stride;
+
+ while (height--) {
+ rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
+ rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
+ rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
+ rp[3] = STAMP_READ(STAMP_SHIFT(fr[1], 0) & STAMP_MASK);
+
+ fr += fs;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ }
+ }
+
+ /* Do underline */
+ if ((attr & 1) != 0) {
+ DELTA(rp, -(ri->ri_stride << 1), int32_t *);
+ rp[0] = rp[1] = rp[2] = rp[3] = stamp[15];
+ }
+
+ stamp_mutex--;
+}
+#endif /* !RASOPS_SMALL */
diff --git a/sys/dev/rasops/rasops_bitops.h b/sys/dev/rasops/rasops_bitops.h
new file mode 100644
index 00000000000..4008ad7f48b
--- /dev/null
+++ b/sys/dev/rasops/rasops_bitops.h
@@ -0,0 +1,318 @@
+/* $OpenBSD: rasops_bitops.h,v 1.1 2001/03/18 04:32:45 nate Exp $ */
+/* $NetBSD: rasops_bitops.h,v 1.6 2000/04/12 14:22:30 pk Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RASOPS_BITOPS_H_
+#define _RASOPS_BITOPS_H_ 1
+
+/*
+ * Erase columns.
+ */
+static void
+NAME(erasecols)(cookie, row, col, num, attr)
+ void *cookie;
+ int row, col, num;
+ long attr;
+{
+ int lmask, rmask, lclr, rclr, clr;
+ struct rasops_info *ri;
+ int32_t *dp, *rp;
+ int height, cnt;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if (col < 0) {
+ num += col;
+ col = 0;
+ }
+
+ if ((col + num) > ri->ri_cols)
+ num = ri->ri_cols - col;
+
+ if (num <= 0)
+ return;
+#endif
+ col *= ri->ri_font->fontwidth << PIXEL_SHIFT;
+ num *= ri->ri_font->fontwidth << PIXEL_SHIFT;
+ height = ri->ri_font->fontheight;
+ clr = ri->ri_devcmap[(attr >> 16) & 0xf];
+ rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3));
+
+ if ((col & 31) + num <= 32) {
+ lmask = ~rasops_pmask[col & 31][num];
+ lclr = clr & ~lmask;
+
+ while (height--) {
+ dp = rp;
+ DELTA(rp, ri->ri_stride, int32_t *);
+
+ *dp = (*dp & lmask) | lclr;
+ }
+ } else {
+ lmask = rasops_rmask[col & 31];
+ rmask = rasops_lmask[(col + num) & 31];
+
+ if (lmask)
+ num = (num - (32 - (col & 31))) >> 5;
+ else
+ num = num >> 5;
+
+ lclr = clr & ~lmask;
+ rclr = clr & ~rmask;
+
+ while (height--) {
+ dp = rp;
+ DELTA(rp, ri->ri_stride, int32_t *);
+
+ if (lmask)
+ *dp++ = (*dp & lmask) | lclr;
+
+ for (cnt = num; cnt > 0; cnt--)
+ *dp++ = clr;
+
+ if (rmask)
+ *dp = (*dp & rmask) | rclr;
+ }
+ }
+}
+
+/*
+ * Actually paint the cursor.
+ */
+static void
+NAME(do_cursor)(ri)
+ struct rasops_info *ri;
+{
+ int lmask, rmask, height, row, col, num;
+ int32_t *dp, *rp;
+
+ row = ri->ri_crow;
+ col = ri->ri_ccol * ri->ri_font->fontwidth << PIXEL_SHIFT;
+ height = ri->ri_font->fontheight;
+ num = ri->ri_font->fontwidth << PIXEL_SHIFT;
+ rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
+
+ if ((col & 31) + num <= 32) {
+ lmask = rasops_pmask[col & 31][num];
+
+ while (height--) {
+ dp = rp;
+ DELTA(rp, ri->ri_stride, int32_t *);
+ *dp ^= lmask;
+ }
+ } else {
+ lmask = ~rasops_rmask[col & 31];
+ rmask = ~rasops_lmask[(col + num) & 31];
+
+ while (height--) {
+ dp = rp;
+ DELTA(rp, ri->ri_stride, int32_t *);
+
+ if (lmask != -1)
+ *dp++ ^= lmask;
+
+ if (rmask != -1)
+ *dp ^= rmask;
+ }
+ }
+}
+
+/*
+ * Copy columns. Ick!
+ */
+static void
+NAME(copycols)(cookie, row, src, dst, num)
+ void *cookie;
+ int row, src, dst, num;
+{
+ int tmp, lmask, rmask, height, lnum, rnum, sb, db, cnt, full;
+ int32_t *sp, *dp, *srp, *drp;
+ struct rasops_info *ri;
+
+ ri = (struct rasops_info *)cookie;
+
+#ifdef RASOPS_CLIPPING
+ if (dst == src)
+ return;
+
+ /* Catches < 0 case too */
+ if ((unsigned)row >= (unsigned)ri->ri_rows)
+ return;
+
+ if (src < 0) {
+ num += src;
+ src = 0;
+ }
+
+ if ((src + num) > ri->ri_cols)
+ num = ri->ri_cols - src;
+
+ if (dst < 0) {
+ num += dst;
+ dst = 0;
+ }
+
+ if ((dst + num) > ri->ri_cols)
+ num = ri->ri_cols - dst;
+
+ if (num <= 0)
+ return;
+#endif
+
+ cnt = ri->ri_font->fontwidth << PIXEL_SHIFT;
+ src *= cnt;
+ dst *= cnt;
+ num *= cnt;
+ row *= ri->ri_yscale;
+ height = ri->ri_font->fontheight;
+ db = dst & 31;
+
+ if (db + num <= 32) {
+ /* Destination is contained within a single word */
+ srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
+ drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
+ sb = src & 31;
+
+ while (height--) {
+ GETBITS(srp, sb, num, tmp);
+ PUTBITS(tmp, db, num, drp);
+ DELTA(srp, ri->ri_stride, int32_t *);
+ DELTA(drp, ri->ri_stride, int32_t *);
+ }
+
+ return;
+ }
+
+ lmask = rasops_rmask[db];
+ rmask = rasops_lmask[(dst + num) & 31];
+ lnum = (32 - db) & 31;
+ rnum = (dst + num) & 31;
+
+ if (lmask)
+ full = (num - (32 - (dst & 31))) >> 5;
+ else
+ full = num >> 5;
+
+ if (src < dst && src + num > dst) {
+ /* Copy right-to-left */
+ sb = src & 31;
+ src = src + num;
+ dst = dst + num;
+ srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
+ drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
+
+ src = src & 31;
+ rnum = 32 - lnum;
+ db = dst & 31;
+
+ if ((src -= db) < 0) {
+ sp--;
+ src += 32;
+ }
+
+ while (height--) {
+ sp = srp;
+ dp = drp;
+ DELTA(srp, ri->ri_stride, int32_t *);
+ DELTA(drp, ri->ri_stride, int32_t *);
+
+ if (db) {
+ GETBITS(sp, src, db, tmp);
+ PUTBITS(tmp, 0, db, dp);
+ dp--;
+ sp--;
+ }
+
+ /* Now aligned to 32-bits wrt dp */
+ for (cnt = full; cnt; cnt--, sp--) {
+ GETBITS(sp, src, 32, tmp);
+ *dp-- = tmp;
+ }
+
+ if (lmask) {
+#if 0
+ if (src > sb)
+ sp++;
+#endif
+ GETBITS(sp, sb, lnum, tmp);
+ PUTBITS(tmp, rnum, lnum, dp);
+ }
+ }
+ } else {
+ /* Copy left-to-right */
+ srp = (int32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
+ drp = (int32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
+ db = dst & 31;
+
+ while (height--) {
+ sb = src & 31;
+ sp = srp;
+ dp = drp;
+ DELTA(srp, ri->ri_stride, int32_t *);
+ DELTA(drp, ri->ri_stride, int32_t *);
+
+ if (lmask) {
+ GETBITS(sp, sb, lnum, tmp);
+ PUTBITS(tmp, db, lnum, dp);
+ dp++;
+
+ if ((sb += lnum) > 31) {
+ sp++;
+ sb -= 32;
+ }
+ }
+
+ /* Now aligned to 32-bits wrt dp */
+ for (cnt = full; cnt; cnt--, sp++) {
+ GETBITS(sp, sb, 32, tmp);
+ *dp++ = tmp;
+ }
+
+ if (rmask) {
+ GETBITS(sp, sb, rnum, tmp);
+ PUTBITS(tmp, 0, rnum, dp);
+ }
+ }
+ }
+}
+
+#endif /* _RASOPS_BITOPS_H_ */
diff --git a/sys/dev/rasops/rasops_masks.c b/sys/dev/rasops/rasops_masks.c
new file mode 100644
index 00000000000..aec4eac218b
--- /dev/null
+++ b/sys/dev/rasops/rasops_masks.c
@@ -0,0 +1,355 @@
+/* $OpenBSD: rasops_masks.c,v 1.1 2001/03/18 04:32:45 nate Exp $ */
+/* $NetBSD: rasops_masks.c,v 1.5 2000/06/13 13:37:00 ad Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "rasops_masks.h"
+
+/* `ragged edge' bitmasks */
+const int32_t rasops_lmask[32+1] = {
+ MBE(0x00000000), MBE(0x7fffffff), MBE(0x3fffffff), MBE(0x1fffffff),
+ MBE(0x0fffffff), MBE(0x07ffffff), MBE(0x03ffffff), MBE(0x01ffffff),
+ MBE(0x00ffffff), MBE(0x007fffff), MBE(0x003fffff), MBE(0x001fffff),
+ MBE(0x000fffff), MBE(0x0007ffff), MBE(0x0003ffff), MBE(0x0001ffff),
+ MBE(0x0000ffff), MBE(0x00007fff), MBE(0x00003fff), MBE(0x00001fff),
+ MBE(0x00000fff), MBE(0x000007ff), MBE(0x000003ff), MBE(0x000001ff),
+ MBE(0x000000ff), MBE(0x0000007f), MBE(0x0000003f), MBE(0x0000001f),
+ MBE(0x0000000f), MBE(0x00000007), MBE(0x00000003), MBE(0x00000001),
+ MBE(0x00000000)
+};
+
+const int32_t rasops_rmask[32+1] = {
+ MBE(0x00000000), MBE(0x80000000), MBE(0xc0000000), MBE(0xe0000000),
+ MBE(0xf0000000), MBE(0xf8000000), MBE(0xfc000000), MBE(0xfe000000),
+ MBE(0xff000000), MBE(0xff800000), MBE(0xffc00000), MBE(0xffe00000),
+ MBE(0xfff00000), MBE(0xfff80000), MBE(0xfffc0000), MBE(0xfffe0000),
+ MBE(0xffff0000), MBE(0xffff8000), MBE(0xffffc000), MBE(0xffffe000),
+ MBE(0xfffff000), MBE(0xfffff800), MBE(0xfffffc00), MBE(0xfffffe00),
+ MBE(0xffffff00), MBE(0xffffff80), MBE(0xffffffc0), MBE(0xffffffe0),
+ MBE(0xfffffff0), MBE(0xfffffff8), MBE(0xfffffffc), MBE(0xfffffffe),
+ MBE(0xffffffff)
+};
+
+/* Part bitmasks */
+const int32_t rasops_pmask[32][32] = {
+ { MBE(0xffffffff), MBE(0x80000000), MBE(0xc0000000), MBE(0xe0000000),
+ MBE(0xf0000000), MBE(0xf8000000), MBE(0xfc000000), MBE(0xfe000000),
+ MBE(0xff000000), MBE(0xff800000), MBE(0xffc00000), MBE(0xffe00000),
+ MBE(0xfff00000), MBE(0xfff80000), MBE(0xfffc0000), MBE(0xfffe0000),
+ MBE(0xffff0000), MBE(0xffff8000), MBE(0xffffc000), MBE(0xffffe000),
+ MBE(0xfffff000), MBE(0xfffff800), MBE(0xfffffc00), MBE(0xfffffe00),
+ MBE(0xffffff00), MBE(0xffffff80), MBE(0xffffffc0), MBE(0xffffffe0),
+ MBE(0xfffffff0), MBE(0xfffffff8), MBE(0xfffffffc), MBE(0xfffffffe), },
+
+ { MBE(0x00000000), MBE(0x40000000), MBE(0x60000000), MBE(0x70000000),
+ MBE(0x78000000), MBE(0x7c000000), MBE(0x7e000000), MBE(0x7f000000),
+ MBE(0x7f800000), MBE(0x7fc00000), MBE(0x7fe00000), MBE(0x7ff00000),
+ MBE(0x7ff80000), MBE(0x7ffc0000), MBE(0x7ffe0000), MBE(0x7fff0000),
+ MBE(0x7fff8000), MBE(0x7fffc000), MBE(0x7fffe000), MBE(0x7ffff000),
+ MBE(0x7ffff800), MBE(0x7ffffc00), MBE(0x7ffffe00), MBE(0x7fffff00),
+ MBE(0x7fffff80), MBE(0x7fffffc0), MBE(0x7fffffe0), MBE(0x7ffffff0),
+ MBE(0x7ffffff8), MBE(0x7ffffffc), MBE(0x7ffffffe), MBE(0x7fffffff), },
+
+ { MBE(0x00000000), MBE(0x20000000), MBE(0x30000000), MBE(0x38000000),
+ MBE(0x3c000000), MBE(0x3e000000), MBE(0x3f000000), MBE(0x3f800000),
+ MBE(0x3fc00000), MBE(0x3fe00000), MBE(0x3ff00000), MBE(0x3ff80000),
+ MBE(0x3ffc0000), MBE(0x3ffe0000), MBE(0x3fff0000), MBE(0x3fff8000),
+ MBE(0x3fffc000), MBE(0x3fffe000), MBE(0x3ffff000), MBE(0x3ffff800),
+ MBE(0x3ffffc00), MBE(0x3ffffe00), MBE(0x3fffff00), MBE(0x3fffff80),
+ MBE(0x3fffffc0), MBE(0x3fffffe0), MBE(0x3ffffff0), MBE(0x3ffffff8),
+ MBE(0x3ffffffc), MBE(0x3ffffffe), MBE(0x3fffffff), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x10000000), MBE(0x18000000), MBE(0x1c000000),
+ MBE(0x1e000000), MBE(0x1f000000), MBE(0x1f800000), MBE(0x1fc00000),
+ MBE(0x1fe00000), MBE(0x1ff00000), MBE(0x1ff80000), MBE(0x1ffc0000),
+ MBE(0x1ffe0000), MBE(0x1fff0000), MBE(0x1fff8000), MBE(0x1fffc000),
+ MBE(0x1fffe000), MBE(0x1ffff000), MBE(0x1ffff800), MBE(0x1ffffc00),
+ MBE(0x1ffffe00), MBE(0x1fffff00), MBE(0x1fffff80), MBE(0x1fffffc0),
+ MBE(0x1fffffe0), MBE(0x1ffffff0), MBE(0x1ffffff8), MBE(0x1ffffffc),
+ MBE(0x1ffffffe), MBE(0x1fffffff), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x08000000), MBE(0x0c000000), MBE(0x0e000000),
+ MBE(0x0f000000), MBE(0x0f800000), MBE(0x0fc00000), MBE(0x0fe00000),
+ MBE(0x0ff00000), MBE(0x0ff80000), MBE(0x0ffc0000), MBE(0x0ffe0000),
+ MBE(0x0fff0000), MBE(0x0fff8000), MBE(0x0fffc000), MBE(0x0fffe000),
+ MBE(0x0ffff000), MBE(0x0ffff800), MBE(0x0ffffc00), MBE(0x0ffffe00),
+ MBE(0x0fffff00), MBE(0x0fffff80), MBE(0x0fffffc0), MBE(0x0fffffe0),
+ MBE(0x0ffffff0), MBE(0x0ffffff8), MBE(0x0ffffffc), MBE(0x0ffffffe),
+ MBE(0x0fffffff), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x04000000), MBE(0x06000000), MBE(0x07000000),
+ MBE(0x07800000), MBE(0x07c00000), MBE(0x07e00000), MBE(0x07f00000),
+ MBE(0x07f80000), MBE(0x07fc0000), MBE(0x07fe0000), MBE(0x07ff0000),
+ MBE(0x07ff8000), MBE(0x07ffc000), MBE(0x07ffe000), MBE(0x07fff000),
+ MBE(0x07fff800), MBE(0x07fffc00), MBE(0x07fffe00), MBE(0x07ffff00),
+ MBE(0x07ffff80), MBE(0x07ffffc0), MBE(0x07ffffe0), MBE(0x07fffff0),
+ MBE(0x07fffff8), MBE(0x07fffffc), MBE(0x07fffffe), MBE(0x07ffffff),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x02000000), MBE(0x03000000), MBE(0x03800000),
+ MBE(0x03c00000), MBE(0x03e00000), MBE(0x03f00000), MBE(0x03f80000),
+ MBE(0x03fc0000), MBE(0x03fe0000), MBE(0x03ff0000), MBE(0x03ff8000),
+ MBE(0x03ffc000), MBE(0x03ffe000), MBE(0x03fff000), MBE(0x03fff800),
+ MBE(0x03fffc00), MBE(0x03fffe00), MBE(0x03ffff00), MBE(0x03ffff80),
+ MBE(0x03ffffc0), MBE(0x03ffffe0), MBE(0x03fffff0), MBE(0x03fffff8),
+ MBE(0x03fffffc), MBE(0x03fffffe), MBE(0x03ffffff), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x01000000), MBE(0x01800000), MBE(0x01c00000),
+ MBE(0x01e00000), MBE(0x01f00000), MBE(0x01f80000), MBE(0x01fc0000),
+ MBE(0x01fe0000), MBE(0x01ff0000), MBE(0x01ff8000), MBE(0x01ffc000),
+ MBE(0x01ffe000), MBE(0x01fff000), MBE(0x01fff800), MBE(0x01fffc00),
+ MBE(0x01fffe00), MBE(0x01ffff00), MBE(0x01ffff80), MBE(0x01ffffc0),
+ MBE(0x01ffffe0), MBE(0x01fffff0), MBE(0x01fffff8), MBE(0x01fffffc),
+ MBE(0x01fffffe), MBE(0x01ffffff), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00800000), MBE(0x00c00000), MBE(0x00e00000),
+ MBE(0x00f00000), MBE(0x00f80000), MBE(0x00fc0000), MBE(0x00fe0000),
+ MBE(0x00ff0000), MBE(0x00ff8000), MBE(0x00ffc000), MBE(0x00ffe000),
+ MBE(0x00fff000), MBE(0x00fff800), MBE(0x00fffc00), MBE(0x00fffe00),
+ MBE(0x00ffff00), MBE(0x00ffff80), MBE(0x00ffffc0), MBE(0x00ffffe0),
+ MBE(0x00fffff0), MBE(0x00fffff8), MBE(0x00fffffc), MBE(0x00fffffe),
+ MBE(0x00ffffff), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00400000), MBE(0x00600000), MBE(0x00700000),
+ MBE(0x00780000), MBE(0x007c0000), MBE(0x007e0000), MBE(0x007f0000),
+ MBE(0x007f8000), MBE(0x007fc000), MBE(0x007fe000), MBE(0x007ff000),
+ MBE(0x007ff800), MBE(0x007ffc00), MBE(0x007ffe00), MBE(0x007fff00),
+ MBE(0x007fff80), MBE(0x007fffc0), MBE(0x007fffe0), MBE(0x007ffff0),
+ MBE(0x007ffff8), MBE(0x007ffffc), MBE(0x007ffffe), MBE(0x007fffff),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00200000), MBE(0x00300000), MBE(0x00380000),
+ MBE(0x003c0000), MBE(0x003e0000), MBE(0x003f0000), MBE(0x003f8000),
+ MBE(0x003fc000), MBE(0x003fe000), MBE(0x003ff000), MBE(0x003ff800),
+ MBE(0x003ffc00), MBE(0x003ffe00), MBE(0x003fff00), MBE(0x003fff80),
+ MBE(0x003fffc0), MBE(0x003fffe0), MBE(0x003ffff0), MBE(0x003ffff8),
+ MBE(0x003ffffc), MBE(0x003ffffe), MBE(0x003fffff), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00100000), MBE(0x00180000), MBE(0x001c0000),
+ MBE(0x001e0000), MBE(0x001f0000), MBE(0x001f8000), MBE(0x001fc000),
+ MBE(0x001fe000), MBE(0x001ff000), MBE(0x001ff800), MBE(0x001ffc00),
+ MBE(0x001ffe00), MBE(0x001fff00), MBE(0x001fff80), MBE(0x001fffc0),
+ MBE(0x001fffe0), MBE(0x001ffff0), MBE(0x001ffff8), MBE(0x001ffffc),
+ MBE(0x001ffffe), MBE(0x001fffff), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00080000), MBE(0x000c0000), MBE(0x000e0000),
+ MBE(0x000f0000), MBE(0x000f8000), MBE(0x000fc000), MBE(0x000fe000),
+ MBE(0x000ff000), MBE(0x000ff800), MBE(0x000ffc00), MBE(0x000ffe00),
+ MBE(0x000fff00), MBE(0x000fff80), MBE(0x000fffc0), MBE(0x000fffe0),
+ MBE(0x000ffff0), MBE(0x000ffff8), MBE(0x000ffffc), MBE(0x000ffffe),
+ MBE(0x000fffff), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00040000), MBE(0x00060000), MBE(0x00070000),
+ MBE(0x00078000), MBE(0x0007c000), MBE(0x0007e000), MBE(0x0007f000),
+ MBE(0x0007f800), MBE(0x0007fc00), MBE(0x0007fe00), MBE(0x0007ff00),
+ MBE(0x0007ff80), MBE(0x0007ffc0), MBE(0x0007ffe0), MBE(0x0007fff0),
+ MBE(0x0007fff8), MBE(0x0007fffc), MBE(0x0007fffe), MBE(0x0007ffff),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00020000), MBE(0x00030000), MBE(0x00038000),
+ MBE(0x0003c000), MBE(0x0003e000), MBE(0x0003f000), MBE(0x0003f800),
+ MBE(0x0003fc00), MBE(0x0003fe00), MBE(0x0003ff00), MBE(0x0003ff80),
+ MBE(0x0003ffc0), MBE(0x0003ffe0), MBE(0x0003fff0), MBE(0x0003fff8),
+ MBE(0x0003fffc), MBE(0x0003fffe), MBE(0x0003ffff), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00010000), MBE(0x00018000), MBE(0x0001c000),
+ MBE(0x0001e000), MBE(0x0001f000), MBE(0x0001f800), MBE(0x0001fc00),
+ MBE(0x0001fe00), MBE(0x0001ff00), MBE(0x0001ff80), MBE(0x0001ffc0),
+ MBE(0x0001ffe0), MBE(0x0001fff0), MBE(0x0001fff8), MBE(0x0001fffc),
+ MBE(0x0001fffe), MBE(0x0001ffff), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00008000), MBE(0x0000c000), MBE(0x0000e000),
+ MBE(0x0000f000), MBE(0x0000f800), MBE(0x0000fc00), MBE(0x0000fe00),
+ MBE(0x0000ff00), MBE(0x0000ff80), MBE(0x0000ffc0), MBE(0x0000ffe0),
+ MBE(0x0000fff0), MBE(0x0000fff8), MBE(0x0000fffc), MBE(0x0000fffe),
+ MBE(0x0000ffff), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00004000), MBE(0x00006000), MBE(0x00007000),
+ MBE(0x00007800), MBE(0x00007c00), MBE(0x00007e00), MBE(0x00007f00),
+ MBE(0x00007f80), MBE(0x00007fc0), MBE(0x00007fe0), MBE(0x00007ff0),
+ MBE(0x00007ff8), MBE(0x00007ffc), MBE(0x00007ffe), MBE(0x00007fff),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00002000), MBE(0x00003000), MBE(0x00003800),
+ MBE(0x00003c00), MBE(0x00003e00), MBE(0x00003f00), MBE(0x00003f80),
+ MBE(0x00003fc0), MBE(0x00003fe0), MBE(0x00003ff0), MBE(0x00003ff8),
+ MBE(0x00003ffc), MBE(0x00003ffe), MBE(0x00003fff), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00001000), MBE(0x00001800), MBE(0x00001c00),
+ MBE(0x00001e00), MBE(0x00001f00), MBE(0x00001f80), MBE(0x00001fc0),
+ MBE(0x00001fe0), MBE(0x00001ff0), MBE(0x00001ff8), MBE(0x00001ffc),
+ MBE(0x00001ffe), MBE(0x00001fff), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000800), MBE(0x00000c00), MBE(0x00000e00),
+ MBE(0x00000f00), MBE(0x00000f80), MBE(0x00000fc0), MBE(0x00000fe0),
+ MBE(0x00000ff0), MBE(0x00000ff8), MBE(0x00000ffc), MBE(0x00000ffe),
+ MBE(0x00000fff), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000400), MBE(0x00000600), MBE(0x00000700),
+ MBE(0x00000780), MBE(0x000007c0), MBE(0x000007e0), MBE(0x000007f0),
+ MBE(0x000007f8), MBE(0x000007fc), MBE(0x000007fe), MBE(0x000007ff),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000200), MBE(0x00000300), MBE(0x00000380),
+ MBE(0x000003c0), MBE(0x000003e0), MBE(0x000003f0), MBE(0x000003f8),
+ MBE(0x000003fc), MBE(0x000003fe), MBE(0x000003ff), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000100), MBE(0x00000180), MBE(0x000001c0),
+ MBE(0x000001e0), MBE(0x000001f0), MBE(0x000001f8), MBE(0x000001fc),
+ MBE(0x000001fe), MBE(0x000001ff), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000080), MBE(0x000000c0), MBE(0x000000e0),
+ MBE(0x000000f0), MBE(0x000000f8), MBE(0x000000fc), MBE(0x000000fe),
+ MBE(0x000000ff), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+ { MBE(0x00000000), MBE(0x00000040), MBE(0x00000060), MBE(0x00000070),
+ MBE(0x00000078), MBE(0x0000007c), MBE(0x0000007e), MBE(0x0000007f),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000020), MBE(0x00000030), MBE(0x00000038),
+ MBE(0x0000003c), MBE(0x0000003e), MBE(0x0000003f), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000010), MBE(0x00000018), MBE(0x0000001c),
+ MBE(0x0000001e), MBE(0x0000001f), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000008), MBE(0x0000000c), MBE(0x0000000e),
+ MBE(0x0000000f), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000004), MBE(0x00000006), MBE(0x00000007),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000002), MBE(0x00000003), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+
+ { MBE(0x00000000), MBE(0x00000001), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000),
+ MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), MBE(0x00000000), },
+};
diff --git a/sys/dev/rasops/rasops_masks.h b/sys/dev/rasops/rasops_masks.h
new file mode 100644
index 00000000000..6e9b3afc89b
--- /dev/null
+++ b/sys/dev/rasops/rasops_masks.h
@@ -0,0 +1,103 @@
+/* $OpenBSD: rasops_masks.h,v 1.1 2001/03/18 04:32:45 nate Exp $ */
+/* $NetBSD: rasops_masks.h,v 1.5 2000/06/13 13:37:01 ad Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RASOPS_MASKS_H_
+#define _RASOPS_MASKS_H_ 1
+
+#include <sys/types.h>
+#include <machine/endian.h>
+
+/*
+ * Convenience macros. To get around the problem of dealing with properly
+ * ordered bits on little-endian machines, we just convert everything to
+ * big-endian and back again when we're done.
+ *
+ * MBL: move bits left
+ * MBR: move bits right
+ * MBE: make big-endian
+ */
+#if BYTE_ORDER == BIG_ENDIAN
+
+#define MBL(x,y) ((y) > 31 ? 0 : (x) >> (y))
+#define MBR(x,y) ((y) > 31 ? 0 : (x) << (y))
+#define MBE(x) (x)
+
+#else
+
+#define MBL(x,y) ((y) > 31 ? 0 : MBE(MBE(x) << (y)))
+#define MBR(x,y) ((y) > 31 ? 0 : MBE(MBE(x) >> (y)))
+#define MBE(x) ( (((x) & 0x000000FFU) << 24) \
+ | (((x) & 0x0000FF00U) << 8) \
+ | (((x) & 0x00FF0000U) >> 8) \
+ | (((x) & 0xFF000000U) >> 24) )
+#endif
+
+/*
+ * Using GETBITS() and PUTBITS() inside a loop mightn't be such a good idea.
+ * There's probably some CSE and strength-reduction that the compiler won't
+ * even think about - really should have a few assumptions/separate cases.
+ */
+
+/* Get a number of bits ( <= 32 ) from *sp and store in dw */
+#define GETBITS(sp, x, w, dw) do { \
+ dw = MBL(*(sp), (x)); \
+ if (((x) + (w)) > 32) \
+ dw |= (MBR((sp)[1], 32 - (x))); \
+} while(0);
+
+/* Put a number of bits ( <= 32 ) from sw to *dp */
+#define PUTBITS(sw, x, w, dp) do { \
+ int n = (x) + (w) - 32; \
+ \
+ if (n <= 0) { \
+ n = rasops_pmask[x & 31][w & 31]; \
+ *(dp) = (*(dp) & ~n) | (MBR(sw, x) & n); \
+ } else { \
+ *(dp) = (*(dp) & rasops_rmask[x]) | (MBR((sw), x)); \
+ (dp)[1] = ((dp)[1] & rasops_rmask[n]) | \
+ (MBL(sw, 32-(x)) & rasops_lmask[n]); \
+ } \
+} while(0);
+
+/* rasops_masks.c */
+extern const int32_t rasops_lmask[32+1];
+extern const int32_t rasops_rmask[32+1];
+extern const int32_t rasops_pmask[32][32];
+
+#endif /* _RASOPS_MASKS_H_ */