diff options
author | Nathan Binkert <nate@cvs.openbsd.org> | 2001-03-18 04:32:46 +0000 |
---|---|---|
committer | Nathan Binkert <nate@cvs.openbsd.org> | 2001-03-18 04:32:46 +0000 |
commit | ef2d578c271a786653e241b072dc56250ca1430d (patch) | |
tree | b318f8acf09096eea9445db0dedcafc8eafc26f0 /sys/dev/rasops | |
parent | f4f01277bc5305a12ccc3f2024dfa89e24335a13 (diff) |
Import rasops from NetBSD. This gives improved performance for raster
operations.
Diffstat (limited to 'sys/dev/rasops')
-rw-r--r-- | sys/dev/rasops/Makefile | 8 | ||||
-rw-r--r-- | sys/dev/rasops/README | 21 | ||||
-rw-r--r-- | sys/dev/rasops/files.rasops | 19 | ||||
-rw-r--r-- | sys/dev/rasops/rasops.c | 957 | ||||
-rw-r--r-- | sys/dev/rasops/rasops.h | 149 | ||||
-rw-r--r-- | sys/dev/rasops/rasops1.c | 378 | ||||
-rw-r--r-- | sys/dev/rasops/rasops15.c | 470 | ||||
-rw-r--r-- | sys/dev/rasops/rasops2.c | 481 | ||||
-rw-r--r-- | sys/dev/rasops/rasops24.c | 740 | ||||
-rw-r--r-- | sys/dev/rasops/rasops32.c | 142 | ||||
-rw-r--r-- | sys/dev/rasops/rasops4.c | 499 | ||||
-rw-r--r-- | sys/dev/rasops/rasops8.c | 420 | ||||
-rw-r--r-- | sys/dev/rasops/rasops_bitops.h | 318 | ||||
-rw-r--r-- | sys/dev/rasops/rasops_masks.c | 355 | ||||
-rw-r--r-- | sys/dev/rasops/rasops_masks.h | 103 |
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_ */ |