Initial import of 'rasops', the new raster operations set for wscons/rcons.

This commit is contained in:
ad 1999-04-13 00:17:57 +00:00
parent 246f73e1a0
commit 14d2ed835e
10 changed files with 3457 additions and 0 deletions

7
sys/dev/rasops/Makefile Normal file
View File

@ -0,0 +1,7 @@
# $NetBSD: Makefile,v 1.1 1999/04/13 00:17:57 ad Exp $
INCSDIR= /usr/include/dev/rasops
INCS= rasops.h
.include <bsd.kinc.mk>

21
sys/dev/rasops/README Normal file
View File

@ -0,0 +1,21 @@
$NetBSD: README,v 1.1 1999/04/13 00:17:57 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.
The stamp_mutex used by some of the colordepths is not fully atomic. It's
designed to stop stamp corruption in the event that text is printed at
interrupt time. Even if it fails, >99% of the time text will be white on
black, so it doesn't really matter. Going to splhigh for each character is
a Bad Thing.
Status of the various depths. Feel free to complete/test:
8 tested, complete
15/16 untested, complete (endainness issues exist?)
32 untested, complete (endainness issues exist?)
1 untested, incomplete for non 8,16 pel fonts
24 untested, incomplete, assumes RGB order
- Andy Doran <ad@NetBSD.org>, April 1999

View File

@ -0,0 +1,11 @@
# $NetBSD: files.rasops,v 1.1 1999/04/13 00:17:58 ad Exp $
file dev/rasops/rasops.c rasterconsole
file dev/rasops/rasops1.c rasterconsole
file dev/rasops/rasops8.c rasterconsole
file dev/rasops/rasops15.c rasterconsole
file dev/rasops/rasops24.c rasterconsole
file dev/rasops/rasops32.c rasterconsole
defopt opt_rasops.h RASOPS1 RASOPS8 RASOPS15 RASOPS16 RASOPS24 RASOPS32
RASOPS_CLIPPING

600
sys/dev/rasops/rasops.c Normal file
View File

@ -0,0 +1,600 @@
/* $NetBSD: rasops.c,v 1.1 1999/04/13 00:17:58 ad Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andy Doran <ad@NetBSD.org>.
*
* 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.1 1999/04/13 00:17:58 ad Exp $");
#include "opt_rasops.h"
#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/wsfont/wsfont.h>
#include <dev/rasops/rasops.h>
/* ANSI colormap (R,G,B). Upper 8 are high-intensity */
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 */
};
/* True if color is gray */
u_char rasops_isgray[16] = {
1, 0, 0, 0,
0, 0, 0, 1,
1, 0, 0, 0,
0, 0, 0, 1
};
/* Common functions */
static void rasops_copycols __P((void *, int, int, int, int));
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 *));
/* Per-depth initalization functions */
void rasops1_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 *));
/*
* Initalize a 'rasops_info' descriptor.
*/
int
rasops_init(ri, wantrows, wantcols, clear, center)
struct rasops_info *ri;
int wantrows, wantcols, clear, center;
{
/* 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,
WSFONT_LITTLE, WSFONT_LITTLE) < 0) {
printf("rasops_init: couldn't lock font\n");
return (-1);
}
}
/* This should never happen in reality... */
#ifdef DEBUG
if ((int)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);
}
if (ri->ri_font->fontwidth > 32) {
printf("rasops_init: fontwidth > 32\n");
return (-1);
}
#endif
/* Fix color palette. We need this for the cursor to work. */
rasops_cmap[255*3+0] = 0xff;
rasops_cmap[255*3+1] = 0xff;
rasops_cmap[255*3+2] = 0xff;
/* Don't care if the caller wants a hideously small console */
if (wantrows < 10)
wantrows = 5000;
if (wantcols < 20)
wantcols = 5000;
/* 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*ri->ri_depth & 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 * ri->ri_depth >> 3;
ri->ri_delta = ri->ri_stride - ri->ri_emustride;
ri->ri_ccol = 0;
ri->ri_crow = 0;
ri->ri_pelbytes = ri->ri_depth >> 3;
ri->ri_xscale = (ri->ri_font->fontwidth * ri->ri_depth) >> 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)
panic("rasops_init: delta isn't aligned on 32-bit boundary!");
#endif
/* Clear the entire display */
if (clear)
bzero(ri->ri_bits, ri->ri_stride * ri->ri_height);
/* Now centre our window if needs be */
ri->ri_origbits = ri->ri_bits;
if (center) {
ri->ri_bits += ((ri->ri_stride - ri->ri_emustride) >> 1) & ~3;
ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
ri->ri_stride;
}
/* Fill in defaults for operations set */
ri->ri_ops.mapchar = rasops_mapchar;
ri->ri_ops.copyrows = rasops_copyrows;
ri->ri_ops.copycols = rasops_copycols;
ri->ri_ops.cursor = rasops_cursor;
if (ri->ri_depth == 1 || ri->ri_forcemono)
ri->ri_ops.alloc_attr = rasops_alloc_mattr;
else
ri->ri_ops.alloc_attr = rasops_alloc_cattr;
switch (ri->ri_depth) {
#ifdef RASOPS1
case 1:
rasops1_init(ri);
break;
#endif
#ifdef RASOPS8
case 8:
rasops8_init(ri);
break;
#endif
#if defined(RASOPS15) || defined(RASOPS16)
case 15:
case 16:
rasops15_init(ri);
break;
#endif
#ifdef RASOPS24
case 24:
rasops24_init(ri);
break;
#endif
#ifdef RASOPS24
case 32:
rasops32_init(ri);
break;
#endif
default:
ri->ri_flg = 0;
return (-1);
}
ri->ri_flg = RASOPS_INITTED;
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;
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;
flg &= 255;
#endif
if (flg & WSATTR_BLINK)
return (EINVAL);
if (flg & WSATTR_REVERSE) {
swap = fg;
fg = bg;
bg = swap;
}
if (flg & WSATTR_HILIT)
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;
#ifdef RASOPS_CLIPPING
flg &= 255;
#endif
fg = fg ? 1 : 0;
bg = bg ? 1 : 0;
if (flg & WSATTR_BLINK)
return (EINVAL);
if (!(flg & WSATTR_REVERSE) ^ !(flg & WSATTR_HILIT)) {
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;
{
struct rasops_info *ri;
int32_t *sp, *dp, *srp, *drp;
int n8, n1, cnt;
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) {
sp = (int32_t *)(ri->ri_bits + src * ri->ri_yscale);
dp = (int32_t *)(ri->ri_bits + dst * ri->ri_yscale);
while (num--) {
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++;
DELTA(dp, ri->ri_delta, int32_t *);
DELTA(sp, ri->ri_delta, int32_t *);
}
} 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);
while (num--) {
dp = drp;
sp = srp;
DELTA(srp, -ri->ri_stride, int32_t *);
DELTA(drp, -ri->ri_stride, 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.
*/
static 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;
if (row < 0 || row >= 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 & RASOPS_CURSOR)
#ifdef RASOPS_CLIPPING
if (!(ri->ri_flg & RASOPS_CURSOR_CLIPPED))
#endif
ri->ri_do_cursor(ri);
/* Select new cursor */
#ifdef RASOPS_CLIPPING
ri->ri_flg &= ~RASOPS_CURSOR_CLIPPED;
if (row < 0 || row >= ri->ri_rows)
ri->ri_flg |= RASOPS_CURSOR_CLIPPED;
else if (col < 0 || col >= ri->ri_cols)
ri->ri_flg |= RASOPS_CURSOR_CLIPPED;
#endif
ri->ri_crow = row;
ri->ri_ccol = col;
if (on) {
ri->ri_flg |= RASOPS_CURSOR;
#ifdef RASOPS_CLIPPING
if (!(ri->ri_flg & RASOPS_CURSOR_CLIPPED))
#endif
ri->ri_do_cursor(ri);
} else
ri->ri_flg &= ~RASOPS_CURSOR;
}
#if (RASOPS15 + RASOPS16 + RASOPS32)
/*
* Make the device colormap
*/
void
rasops_init_devcmap(ri)
struct rasops_info *ri;
{
int i, c;
u_char *p;
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;
if (ri->ri_gnum <= 8)
c = (*p++ >> (8 - ri->ri_gnum)) << ri->ri_gpos;
else
c = (*p++ << (ri->ri_gnum - 8)) << ri->ri_gpos;
if (ri->ri_bnum <= 8)
c = (*p++ >> (8 - ri->ri_bnum)) << ri->ri_bpos;
else
c = (*p++ << (ri->ri_bnum - 8)) << ri->ri_bpos;
ri->ri_devcmap[i] = c;
}
}
#endif
/*
* Unpack a rasops attribute
*/
void
rasops_unpack_attr(attr, fg, bg, underline)
long attr;
int *fg, *bg, *underline;
{
*fg = ((u_int)attr >> 24) & 15;
*bg = ((u_int)attr >> 16) & 15;
*underline = (u_int)attr & 1;
}

123
sys/dev/rasops/rasops.h Normal file
View File

@ -0,0 +1,123 @@
/* $NetBSD: rasops.h,v 1.1 1999/04/13 00:17:59 ad Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andy Doran <ad@NetBSD.org>.
*
* 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
/* Avoid dragging in dev/wscons/wsconsio.h */
struct wsdisplay_font;
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 NULL */
struct wsdisplay_font *ri_font;/* font to use */
void *ri_priv; /* driver private data */
u_char ri_forcemono; /* force monochrome operation */
u_char __pad0;
/*
* 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_flg; /* flags */
int ri_crow; /* cursor row */
int ri_ccol; /* cursor column */
int ri_pelbytes; /* bytes per pel */
int ri_fontscale; /* fontheight * fontstride */
int ri_xscale; /* fontwidth * pelbytes */
int ri_yscale; /* fontheight * stride */
u_char *ri_origbits; /* where screen bits actually start */
/* For 15, 16, 24, 32 bits */
int32_t ri_devcmap[16]; /* device colormap (WSCOL_*) */
/* The emulops you need to use */
struct wsdisplay_emulops ri_ops;
/* Callbacks so we can share some code */
void (*ri_do_cursor)(struct rasops_info *);
};
#define RASOPS_CURSOR (0x01) /* cursor is on */
#define RASOPS_INITTED (0x02) /* struct is initialized */
#define RASOPS_CURSOR_CLIPPED (0x04) /* cursor is clipped */
#define DELTA(p, d, cast) ((p) = (cast)((caddr_t)(p) + (d)))
/*
* rasops_init().
*
* Integer parameters are: number of rows we'd like, number of columns we'd
* like, whether we should clear the display and whether we should center
* the output. Remember that what you'd like is always not what you get.
*
* In terms of optimization, fonts that are a multiple of 8 pixels wide
* work the best: this is important, and will cost you if you don't use 'em.
*/
/* rasops.c */
int rasops_init __P((struct rasops_info *, int, int, int, int));
void rasops_unpack_attr __P((long, int *, int *, int *));
/* This should not be called outside rasops */
void rasops_init_devcmap __P((struct rasops_info *));
extern u_char rasops_isgray[16];
extern u_char rasops_cmap[256*3];
#endif /* _RASOPS_H_ */

642
sys/dev/rasops/rasops1.c Normal file
View File

@ -0,0 +1,642 @@
/* $NetBSD: rasops1.c,v 1.1 1999/04/13 00:17:59 ad Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Andy Doran <ad@NetBSD.org>.
*
* 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"
#ifdef RASOPS1
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rasops1.c,v 1.1 1999/04/13 00:17:59 ad 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/rasops/rasops.h>
static void rasops1_putchar __P((void *, int, int col, u_int, long));
static void rasops1_putchar8 __P((void *, int, int col, u_int, long));
static void rasops1_putchar16 __P((void *, int, int col, u_int, long));
static void rasops1_copycols __P((void *, int, int, int, int));
static void rasops1_erasecols __P((void *, int, int, int));
static void rasops1_erasecols8 __P((void *, int, int, int));
static void rasops1_eraserows __P((void *, int, int));
static int32_t rasops1_fg_color __P((long));
static int32_t rasops1_bg_color __P((long));
static void rasops1_do_cursor __P((struct rasops_info *));
static void rasops1_do_cursor8 __P((struct rasops_info *));
void rasops1_init __P((struct rasops_info *ri));
#if BYTE_ORDER == LITTLE_ENDIAN
static u_int32_t rightmask[32] = {
#else
static u_int32_t leftmask[32] = {
#endif
0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe,
};
#if BYTE_ORDER == LITTLE_ENDIAN
static u_int32_t leftmask[32] = {
#else
static u_int32_t rightmask[32] = {
#endif
0x00000000, 0x00000001, 0x00000003, 0x00000007,
0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
};
/*
* Initalize rasops_info struct for this colordepth.
*/
void
rasops1_init(ri)
struct rasops_info *ri;
{
switch (ri->ri_font->fontwidth) {
case 8:
ri->ri_ops.putchar = rasops1_putchar8;
break;
case 16:
ri->ri_ops.putchar = rasops1_putchar16;
break;
default:
/*
* XXX we don't support anything other than 8 and 16 pel
* wide fonts yet. rasops1_copycols needs to be finished, the
* other routines will need to be checked.
*/
panic("rasops1_init: not completed - see this location in src for details");
ri->ri_ops.putchar = rasops1_putchar;
break;
}
if (ri->ri_font->fontwidth & 7) {
ri->ri_ops.erasecols = rasops1_erasecols;
ri->ri_ops.copycols = rasops1_copycols;
ri->ri_do_cursor = rasops1_do_cursor;
} else {
ri->ri_ops.erasecols = rasops1_erasecols8;
/* use default copycols */
ri->ri_do_cursor = rasops1_do_cursor8;
}
ri->ri_ops.eraserows = rasops1_eraserows;
}
/*
* Get foreground color from attribute and copy across all 4 bytes
* in a int32_t.
*/
static __inline__ int32_t
rasops1_fg_color(long attr)
{
return (attr & 0x0f000000) ? 0xffffffff : 0;
}
/*
* Get background color from attribute and copy across all 4 bytes
* in a int32_t.
*/
static __inline__ int32_t
rasops1_bg_color(long attr)
{
return (attr & 0x000f0000) ? 0xffffffff : 0;
}
/*
* Paint a single character. This is the generic version.
*/
static void
rasops1_putchar(cookie, row, col, uc, attr)
void *cookie;
int row, col;
u_int uc;
long attr;
{
/* XXX i need implemention */
}
/*
* 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
if (row < 0 || row >= ri->ri_rows)
return;
if (col < 0 || col >= ri->ri_cols)
return;
#endif
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
height = ri->ri_font->fontheight;
rs = ri->ri_stride;
bg = (attr & 0x000f0000) ? 0xff : 0;
fg = (attr & 0x0f000000) ? 0xff : 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)
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
if (row < 0 || row >= ri->ri_rows)
return;
if (col < 0 || col >= ri->ri_cols)
return;
#endif
rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
height = ri->ri_font->fontheight;
rs = ri->ri_stride;
bg = (attr & 0x000f0000) ? 0xffff : 0;
fg = (attr & 0x0f000000) ? 0xffff : 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)
*(int16_t *)(rp - (ri->ri_stride << 1)) = fg;
}
/*
* Erase columns.
*/
static void
rasops1_erasecols(cookie, row, col, num, attr)
void *cookie;
int row, num;
long attr;
{
int32_t *dp, *rp, lmask, rmask, lclr, rclr, clr;
struct rasops_info *ri;
int nint, height, cnt;
ri = (struct rasops_info *)cookie;
#ifdef RASOPS_CLIPPING
if (row < 0 || row > 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_fontwidth;
num *= ri->ri_fontwidth;
/*
* lmask: mask for leftmost int32
* rmask: mask for rightmost int32
* nint: number of full int32s
*/
lmask = leftmask[col & 31];
rmask = rightmask[(col + num) & 31];
nint = ((col + num) & ~31) - ((col + 31) & ~31) >> 5;
/* Merge both masks if the span is encapsulated within one int32 */
if (col & ~31 == (col + num) & ~31) {
lmask &= rmask;
rmask = 0;
}
clr = rasops1_bg_color(attr);
lclr = clr & lmask;
rclr = clr & rmask;
lmask = ~lmask;
rmask = ~rmask;
height = ri->ri_fontheight;
rp = ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3);
while (height--) {
dp = rp;
DELTA(rp, ri->ri_stride, int32_t *);
if (lmask != 0xffffffffU)
*dp++ = (*dp & lmask) | lclr;
for (cnt = nint; cnt; cnt--)
*dp++ = clr;
if (rmask != 0xffffffffU)
*dp = (*dp & rmask) | rclr;
}
}
/*
* Erase columns for fonts that are a multiple of 8 pels in width.
*/
static void
rasops1_erasecols8(cookie, row, col, num, attr)
void *cookie;
int row, col, num;
long attr;
{
struct rasops_info *ri;
int32_t *dst;
u_char *dstb, *rp;
int clr, height, cnt, slop1, slop2;
ri = (struct rasops_info *)cookie;
#ifdef RASOPS_CLIPPING
if (row < 0 || row >= 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 = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
clr = rasops1_bg_color(attr);
height = ri->ri_font->fontheight;
slop1 = (int)rp & 3;
slop2 = (num - slop1) & 3;
num = (num - slop1 - slop2) >> 2;
while (height--) {
dstb = rp;
rp += ri->ri_stride;
/* Align span to 4 bytes */
for (cnt = slop1; cnt; cnt--)
*dstb++ = (u_char)clr;
dst = (int32_t *)dstb;
/* Write 4 bytes per loop */
for (cnt = num; cnt; cnt--)
*dst++ = clr;
/* Write unaligned trailing slop */
if (slop2 == 0)
continue;
dstb = (u_char *)dst;
for (cnt = slop2; cnt; cnt--)
*dstb++ = (u_char)clr;
}
}
/*
* Actually paint the cursor.
*/
static void
rasops1_do_cursor(ri)
struct rasops_info *ri;
{
int32_t *dp, *rp, lmask, rmask;
int height, row, col;
row = ri->ri_crow;
col = ri->ri_ccol * ri->ri_fontwidth;
/*
* lmask: mask for leftmost int32
* rmask: mask for rightmost int32
*/
lmask = leftmask[col & 31];
rmask = rightmask[(col + ri->ri_fontwidth) & 31];
/* Merge both masks if the span is encapsulated within one int32 */
if (col & ~31 == (col + ri->ri_fontwidth) & ~31) {
lmask &= rmask;
rmask = 0;
}
lmask = ~lmask;
rmask = ~rmask;
height = ri->ri_fontheight;
rp = ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3);
while (height--) {
dp = rp;
DELTA(rp, ri->ri_stride, int32_t *);
*dp++ = ((*dp & lmask) ^ lmask) | (*dp & ~lmask);
if (rmask != 0xffffffffU)
*dp = ((*dp & rmask) ^ rmask) | (*dp & ~rmask);
}
}
/*
* Paint cursors that are a multiple of 8 pels in size.
*/
static void
rasops1_do_cursor8(ri)
struct rasops_info *ri;
{
int width, height, cnt;
u_char *dp, *rp;
height = ri->ri_fontheight;
width = ri->ri_fontwidth >> 3;
rp = ri->ri_bits + ri->ri_crow * ri->ri_yscale +
ri->ri_ccol * ri->ri_xscale;
while (height--) {
dp = rp;
rp += ri->ri_stride;
for (cnt = width; cnt; cnt--)
*dp++ ^= 0xff;
}
}
/*
* Erase rows.
*/
static void
rasops1_eraserows(cookie, row, num, attr)
void *cookie;
int row, num;
long attr;
{
struct rasops_info *ri;
int32_t *dp, clr;
int n8, n1, cnt;
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
num *= ri->ri_font->fontheight;
dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
clr = rasops1_bg_color(attr);
n8 = ri->ri_emustride >> 5;
n1 = (ri->ri_emustride >> 2) & 7;
while (num--) {
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;
}
for (cnt = n1; cnt; cnt--)
*dp++ = clr;
DELTA(dp, ri->ri_delta, int32_t *);
}
}
/*
* Copy columns. This is slow. Ick! You'd better use a font with
* a width that's a multiple of 8 pels, otherwise this is used...
*/
static void
rasops1_copycols(cookie, row, src, src)
void *cookie;
int row, src, dst;
{
#ifdef notyet
struct rasops_info *ri;
int32_t *dp, *drp, *sp, *srp, lmask, rmask;
int nint, height, cnt;
ri = (struct rasops_info *)cookie;
#ifdef RASOPS_CLIPPING
if (row < 0 || row >= 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
src *= ri->ri_fontwidth;
dst *= ri->ri_fontwidth;
num *= ri->ri_fontwidth;
/*
* lmask: mask for leftmost int32
* rmask: mask for rightmost int32
* nint: number of full int32s
*/
lmask = leftmask[col & 31];
rmask = rightmask[(col + num) & 31];
nint = ((col + num) & ~31) - ((col + 31) & ~31) >> 5;
/* Merge both masks if the span is encapsulated within one int32 */
if (col & ~31 == (col + num) & ~31) {
lmask &= rmask;
rmask = 0;
}
lmask = ~lmask;
rmask = ~rmask;
height = ri->ri_fontheight;
drp = ri->ri_bits + row*ri->ri_yscale + ((dst >> 3) & ~3);
srp = ri->ri_bits + row*ri->ri_yscale + ((src >> 3) & ~3);
while (height--) {
dp = rp;
DELTA(rp, ri->ri_stride, int32_t *);
if (lmask != 0xffffffffU)
*dp++ = (*dp & lmask) | lclr;
for (cnt = nint; cnt; cnt--)
*dp++ = clr;
if (rmask != 0xffffffffU)
*dp = (*dp & rmask) | rclr;
}
#endif
}
#endif /* RASOPS1 */

646
sys/dev/rasops/rasops15.c Normal file
View File

@ -0,0 +1,646 @@
/* $NetBSD: rasops15.c,v 1.1 1999/04/13 00:18: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 Andy Doran <ad@NetBSD.org>.
*
* 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"
#ifdef RASOPS15
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rasops15.c,v 1.1 1999/04/13 00:18:00 ad 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));
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_erasecols __P((void *, int, int, int, long));
static void rasops15_eraserows __P((void *, int, int, long));
static void rasops15_makestamp __P((struct rasops_info *, long));
static int32_t rasops15_bg_color __P((struct rasops_info *, long));
static void rasops15_do_cursor __P((struct rasops_info *));
void rasops15_init __P((struct rasops_info *ri));
/*
* (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) {
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;
default:
ri->ri_ops.putchar = rasops15_putchar;
break;
}
/* Select defaults for color masks if none selected */
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);
}
ri->ri_ops.erasecols = rasops15_erasecols;
ri->ri_ops.eraserows = rasops15_eraserows;
ri->ri_do_cursor = rasops15_do_cursor;
rasops_init_devcmap(ri);
}
/*
* Get background color from attribute and copy across all 4 bytes
* in a int32_t.
*/
static __inline__ int32_t
rasops15_bg_color(ri, attr)
struct rasops_info *ri;
long attr;
{
int32_t bg;
bg = ri->ri_devcmap[((u_int)attr >> 16) & 15];
return bg | (bg << 16);
}
/*
* Actually turn the cursor on or off. This does the dirty work for
* rasops_cursor().
*/
static void
rasops15_do_cursor(ri)
struct rasops_info *ri;
{
u_char *rp, *dp;
int full1, height, cnt, slop1, slop2, row, col;
int32_t planemask;
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 = (int)rp & 2;
slop2 = (ri->ri_xscale - slop1) & 2;
full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
planemask = ri->ri_devcmap[15] | (ri->ri_devcmap[15] << 16);
while (height--) {
dp = rp;
rp += ri->ri_stride;
if (slop1) {
*(int16_t *)dp ^= (int16_t)planemask;
dp += 2;
}
for (cnt = full1; cnt; cnt--) {
*(int32_t *)dp ^= planemask;
dp += 4;
}
if (slop2)
*(int16_t *)dp ^= (int16_t)planemask;
}
}
/*
* Erase columns.
*/
static void
rasops15_erasecols(cookie, row, col, num, attr)
void *cookie;
int row, num;
long attr;
{
int n8, clr, height, cnt, slop1, slop2;
struct rasops_info *ri;
int32_t *dp;
u_char *rp;
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 = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
num *= ri->ri_xscale;
clr = rasops15_bg_color(ri, attr);
height = ri->ri_font->fontheight;
slop1 = (int)rp & 2;
slop2 = (num - slop1) & 2;
num = num - slop1 - slop2;
n8 = num >> 5;
num = (num >> 2) & 7;
while (height--) {
dp = (u_int32_t *)rp;
rp += ri->ri_stride;
/* Align span to 4 bytes */
if (slop1) {
*(int16_t *)dp = (int16_t)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)
*(int16_t *)dp = (int16_t)clr;
}
}
/*
* Paint a single character.
*/
static void
rasops15_putchar(cookie, row, col, uc, attr)
void *cookie;
int row, col;
u_int uc;
long attr;
{
struct rasops_info *ri;
int fb, width, height, cnt, clr[2];
u_char *dp, *rp, *fr;
if (uc == (u_int)-1) {
rasops15_erasecols(cookie, row, col, 1, attr);
return;
}
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
uc -= ri->ri_font->firstchar;
rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
height = ri->ri_font->fontheight;
width = ri->ri_font->fontwidth;
clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 15];
clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 15];
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;
}
}
}
/*
* 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) & 15];
bg = ri->ri_devcmap[((u_int)attr >> 16) & 15];
stamp_attr = attr;
for (i = 0; i < 16; i++) {
#if BYTE_ORDER == LITTLE_ENDIAN
stamp[i << 1] = (i & 8 ? fg : bg);
stamp[i << 1] |= ((i & 4 ? fg : bg) << 16);
stamp[(i << 1) + 1] = (i & 2 ? fg : bg);
stamp[(i << 1) + 1] |= ((i & 1 ? fg : bg) << 16);
#else
stamp[i << 1] = (i & 1 ? fg : bg);
stamp[i << 1] |= ((i & 2 ? fg : bg) << 16);
stamp[(i << 1) + 1] = (i & 4 ? fg : bg);
stamp[(i << 1) + 1] |= ((i & 8 ? 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) {
while (height--) {
rp[0] = stamp[0];
rp[1] = stamp[0];
rp[2] = stamp[0];
rp[3] = 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--) {
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 *);
}
}
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) {
while (height--) {
rp[0] = stamp[0];
rp[1] = stamp[0];
rp[2] = stamp[0];
rp[3] = stamp[0];
rp[4] = stamp[0];
rp[5] = 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--) {
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 *);
}
}
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) {
while (height--) {
rp[0] = stamp[0];
rp[1] = stamp[0];
rp[2] = stamp[0];
rp[3] = stamp[0];
rp[4] = stamp[0];
rp[5] = stamp[0];
rp[6] = stamp[0];
rp[7] = 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--) {
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;
}
}
stamp_mutex--;
}
/*
* Erase rows.
*/
static void
rasops15_eraserows(cookie, row, num, attr)
void *cookie;
int row, num;
long attr;
{
struct rasops_info *ri;
int32_t *dp, clr;
int n8, n1, cnt;
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
num *= ri->ri_font->fontheight;
dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
clr = rasops15_bg_color(ri, attr);
n8 = ri->ri_emustride >> 5;
n1 = (ri->ri_emustride >> 2) & 7;
while (num--) {
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;
}
for (cnt = n1; cnt; cnt--)
*dp++ = clr;
DELTA(dp, ri->ri_delta, int32_t *);
}
}
#endif /* RASOPS15 */

449
sys/dev/rasops/rasops24.c Normal file
View File

@ -0,0 +1,449 @@
/* $NetBSD: rasops24.c,v 1.1 1999/04/13 00:18: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 Andy Doran <ad@NetBSD.org>.
*
* 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: rasops24.c,v 1.1 1999/04/13 00:18:00 ad Exp $");
#include "opt_rasops.h"
#ifdef RASOPS24
#error This is dangerously incomplete.
#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 rasops24_putchar __P((void *, int, int, u_int, long attr));
static void rasops24_erasecols __P((void *, int, int, int, long));
static void rasops24_eraserows __P((void *, int, int, long));
static int rasops24_alloc_attr __P((void *, int, int, int, long *));
static void rasops24_make_bgstamp __P((int, u_char *));
static int32_t rasops24_fg_color __P((struct rasops_info *, long));
static int32_t rasops24_bg_color __P((struct rasops_info *, long));
static void rasops24_do_cursor __P((struct rasops_info *));
void rasops24_init __P((struct rasops_info *ri));
/*
* Initalize rasops_info struct for this colordepth.
*/
void
rasops24_init(ri)
struct rasops_info *ri;
{
switch (ri->ri_font->fontwidth) {
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;
default:
ri->ri_ops.putchar = rasops15_putchar;
break;
}
/* Select defaults for color positions if none selected */
if (ri->ri_rnum == 0) {
ri->ri_rnum = 8;
ri->ri_gnum = 8;
ri->ri_bnum = 8;
ri->ri_rpos = 0;
ri->ri_gpos = 8;
ri->ri_bpos = 16;
}
ri->ri_ops.erasecols = rasops25_erasecols;
ri->ri_ops.eraserows = rasops25_eraserows;
ri->ri_do_cursor = rasops25_do_cursor;
rasops_init_devcmap(ri);
}
/*
* Get foreground color from attribute and copy across all 4 bytes
* in a int32_t.
*/
static __inline__ int32_t
rasops24_fg_color(ri, attr)
struct rasops_info *ri;
long attr;
{
int32_t fg;
fg = ri->ri_devcmap[((u_int)attr >> 24) & 15];
/* Copy across all 4 bytes if the color is gray */
if (attr & 2)
fg |= fg << 8;
return fg;
}
/*
* Get background color from attribute and copy across all 4 bytes
* in a int32_t.
*/
static __inline__ int32_t
rasops24_bg_color(ri, attr)
struct rasops_info *ri;
long attr;
{
int32_t bg;
bg = ri->ri_devcmap[((u_int)attr >> 16) & 15];
/* Copy across all 4 bytes if the color is gray */
if (attr & 4)
bg |= bg << 8;
return bg;
}
/*
* Actually turn the cursor on or off. This does the dirty work for
* rasops_cursor().
*/
static void
rasops24_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 = (int)rp & 3;
slop2 = (ri->ri_xscale - slop1) & 3;
full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
while (height--) {
dp = rp;
rp += ri->ri_stride;
for (cnt = slop1; cnt; cnt--)
*dp++ ^= 0xff;
for (cnt = full1; cnt; cnt--) {
*(int32_t *)dp ^= 0xffffffff;
dp += 4;
}
for (cnt = slop2; cnt; cnt--)
*dp++ ^= 0xff;
}
}
/*
* Erase columns.
*/
static void
rasops24_erasecols(cookie, row, col, num, attr)
void *cookie;
int row, col, num;
long attr;
{
struct rasops_info *ri;
int32_t *dp;
u_char *rp;
int n8, n1, clr, height, cnt, slop1, slop2;
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 = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
num *= ri->ri_xscale;
clr = rasops24_bg_color(ri, attr);
height = ri->ri_font->fontheight;
slop1 = (int)rp & 2;
slop2 = (num - slop1) & 2;
n8 = num >> 5;
n1 = (num >> 2) & 7;
while (height--) {
cnt = num;
dp = (u_int32_t *)rp;
rp += ri->ri_stride;
/* Align span to 4 bytes */
if (slop1) {
*(int16_t *)dp = (int16_t)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 = n1; cnt; cnt--)
*dp++ = clr;
/* Write unaligned trailing slop */
if (slop2)
*(int16_t *)dp = (int16_t)clr;
}
}
/*
* Paint a single character.
*/
static void
rasops24_putchar(cookie, row, col, uc, attr)
void *cookie;
int row, col;
u_int uc;
long attr;
{
struct rasops_info *ri;
u_char *dp, *rp;
int32_t *fr, clr[16], fb;
int width, height, cnt;
if (uc == (u_int)-1) {
rasops24_erasecols(cookie, row, col, 1, attr);
return;
}
ri = (struct rasops_info *)cookie;
#ifdef RASOPS_CLIPPING
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;
fr = (int32_t *)ri->ri_font->data + uc * ri->ri_font->fontheight;
height = ri->ri_font->fontheight;
width = ri->ri_font->fontwidth;
clr[1] = ri->ri_devcmap[((u_int)attr >> 24)];
clr[0] = ri->ri_devcmap[((u_int)attr >> 16)];
while (height--) {
dp = rp;
fb = *fr++;
rp += ri->ri_stride;
for (cnt = width; cnt; cnt--) {
*(int16_t *)dp = (int16_t)clr[fb & 1];
fb >>= 1;
dp += 2;
}
}
}
/*
* Construct a 12 byte by 1 byte blitting stamp. This uses the background
* color only (for erasecols()/eraserows()).
*/
static void
rasops24_make_bgstamp(i, bp)
int i;
u_char *bp;
{
u_char r, g, b;
i = (i >> 8) & 0xff;
i = (i << 1) + i;
r = rasops_cmap[i+0];
g = rasops_cmap[i+1];
b = rasops_cmap[i+2];
#if BYTE_ORDER == LITTLE_ENDIAN
bp[0] = r; bp[1] = g; bp[2] = b; bp[3] = r;
bp[4] = g; bp[5] = b; bp[6] = r; bp[7] = g;
bp[8] = b; bp[9] = r; bp[10] = g; bp[11] = b;
#else
bp[3] = r; bp[2] = g; bp[1] = b; bp[0] = r;
bp[7] = g; bp[6] = b; bp[5] = r; bp[4] = g;
bp[11] = b; bp[10] = r; bp[9] = g; bp[8] = b;
#endif
}
/*
* Erase rows.
*/
static void
rasops24_eraserows(cookie, row, num, attr)
void *cookie;
int row, num;
long attr;
{
struct rasops_info *ri;
int32_t *dp, clr, stamp[3];
int n9, n3, n1, cnt;
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
num *= ri->ri_font->fontheight;
dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
n9 = ri->ri_emustride / 36;
cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
n3 = (ri->ri_emustride - cnt) / 12;
cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
n1 = (ri->ri_emustride - cnt) >> 2;
/* If the color is gray, we can cheat... */
if (attr & ATTR_GRAY_BG) {
clr = rasops24_bg_color(ri, attr);
while (num--) {
for (cnt = n9; 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] = clr;
dp += 9;
}
for (cnt = n3; cnt; cnt--) {
dp[0] = clr;
dp[1] = clr;
dp[2] = clr;
dp += 3;
}
for (cnt = n1; cnt; cnt--)
*dp++ = clr;
DELTA(dp, ri->ri_delta, int32_t *);
}
} else {
rasops24_make_bgstamp((int)attr, (u_char *)stamp);
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, ri->ri_delta, int32_t *);
}
}
}
#endif /* RASOPS24 */

324
sys/dev/rasops/rasops32.c Normal file
View File

@ -0,0 +1,324 @@
/* $NetBSD: rasops32.c,v 1.1 1999/04/13 00:18: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 Andy Doran <ad@NetBSD.org>.
*
* 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"
#ifdef RASOPS32
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rasops32.c,v 1.1 1999/04/13 00:18:01 ad 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));
static void rasops32_erasecols __P((void *, int, int, int, long));
static void rasops32_eraserows __P((void *, int, int, long));
static int32_t rasops32_fg_color __P((struct rasops_info *, long));
static int32_t rasops32_bg_color __P((struct rasops_info *, long));
static void rasops32_do_cursor __P((struct rasops_info *));
void rasops32_init __P((struct rasops_info *ri));
/*
* Initalize a 'rasops_info' descriptor for this depth.
*/
void
rasops32_init(ri)
struct rasops_info *ri;
{
/*
* This sucks. There is little optimization you can do with this
* colordepth on 32-bit machines.
*
* XXX c'mon sparc, alpha ppl?
*/
ri->ri_ops.putchar = rasops32_putchar;
ri->ri_ops.erasecols = rasops32_erasecols;
ri->ri_ops.eraserows = rasops32_eraserows;
ri->ri_do_cursor = rasops32_do_cursor;
rasops_init_devcmap(ri);
}
/*
* Get background color from attribute.
*/
static __inline__ int32_t
rasops32_bg_color(ri, attr)
struct rasops_info *ri;
long attr;
{
return ri->ri_devcmap[((int32_t)attr >> 24) & 15];
}
/*
* Get foreground color from attribute.
*/
static __inline__ int32_t
rasops32_fg_color(ri, attr)
struct rasops_info *ri;
long attr;
{
return ri->ri_devcmap[((int32_t)attr >> 16) & 15];
}
/*
* Actually turn the cursor on or off. This does the dirty work for
* rasops_cursor().
*/
static void
rasops32_do_cursor(ri)
struct rasops_info *ri;
{
u_char *rp;
int32_t *dp, planemask;
int num, height, cnt, row, col;
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;
num = ri->ri_xscale >> 2;
planemask = ri->ri_devcmap[15];
while (height--) {
dp = (int32_t *)rp;
rp += ri->ri_stride;
for (cnt = num; cnt; cnt--)
*dp++ ^= planemask;
}
}
/*
* Paint a single character.
*/
static void
rasops32_putchar(cookie, row, col, uc, attr)
void *cookie;
int row, col;
u_int uc;
long attr;
{
struct rasops_info *ri;
int32_t *dp, *rp, clr[2];
u_char *fr;
int width, height, cnt, fs, fb;
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] = rasops32_bg_color(ri, attr);
clr[1] = rasops32_fg_color(ri, attr);
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) {
DELTA(rp, -(ri->ri_stride << 1), int32_t *);
while (width--)
*rp++ = clr[1];
}
}
/*
* Erase rows.
*/
static void
rasops32_eraserows(cookie, row, num, attr)
void *cookie;
int row, num;
long attr;
{
struct rasops_info *ri;
int32_t *dp, clr;
int n8, n1, cnt;
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
num *= ri->ri_font->fontheight;
dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
clr = rasops32_bg_color(ri, attr);
n8 = ri->ri_emustride >> 5;
n1 = (ri->ri_emustride >> 2) & 7;
while (num--) {
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;
}
for (cnt = n1; cnt; cnt--)
*dp++ = clr;
DELTA(dp, ri->ri_delta, int32_t *);
}
}
/*
* Erase columns.
*/
static void
rasops32_erasecols(cookie, row, col, num, attr)
void *cookie;
int row, col, num;
long attr;
{
int n8, clr, height, cnt;
struct rasops_info *ri;
int32_t *dst;
u_char *rp;
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 = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
clr = rasops32_bg_color(ri, attr);
height = ri->ri_font->fontheight;
n8 = num >> 5;
num = (num >> 2) & 7;
while (height--) {
dst = (int32_t *)rp;
rp += ri->ri_stride;
for (cnt = n8; cnt; cnt--) {
dst[0] = clr;
dst[1] = clr;
dst[2] = clr;
dst[3] = clr;
dst[4] = clr;
dst[5] = clr;
dst[6] = clr;
dst[7] = clr;
dst += 8;
}
for (cnt = num; cnt; cnt--)
*dst++ = clr;
}
}
#endif /* RASOPS32 */

634
sys/dev/rasops/rasops8.c Normal file
View File

@ -0,0 +1,634 @@
/* $NetBSD: rasops8.c,v 1.1 1999/04/13 00:18: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 Andy Doran <ad@NetBSD.org>.
*
* 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"
#ifdef RASOPS8
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rasops8.c,v 1.1 1999/04/13 00:18:01 ad 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));
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_erasecols __P((void *, int, int, int, long));
static void rasops8_eraserows __P((void *, int, int, long));
static void rasops8_makestamp __P((long));
static int32_t rasops8_bg_color __P((long));
static void rasops8_do_cursor __P((struct rasops_info *));
void rasops8_init __P((struct rasops_info *ri));
/*
* 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 (15 << 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) {
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;
default:
ri->ri_ops.putchar = rasops8_putchar;
break;
}
ri->ri_ops.erasecols = rasops8_erasecols;
ri->ri_ops.eraserows = rasops8_eraserows;
ri->ri_do_cursor = rasops8_do_cursor;
}
/*
* Get background color from attribute and copy across all 4 bytes
* of an int32_t.
*/
static __inline__ int32_t
rasops8_bg_color(attr)
long attr;
{
int32_t bg;
bg = ((int32_t)attr >> 16) & 15;
return bg | (bg << 8) | (bg << 16) | (bg << 24);
}
/*
* Actually turn the cursor on or off. This does the dirty work for
* rasops_cursor().
*/
static void
rasops8_do_cursor(ri)
struct rasops_info *ri;
{
u_char *dp, *rp;
int full1, height, cnt, slop1, slop2, row, col;
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 = (int)rp & 3;
slop2 = (ri->ri_xscale - slop1) & 3;
full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
while (height--) {
dp = rp;
rp += ri->ri_stride;
for (cnt = slop1; cnt; cnt--)
*dp++ ^= 0xff;
for (cnt = full1; cnt; cnt--) {
*(int32_t *)dp ^= 0xffffffff;
dp += 4;
}
for (cnt = slop2; cnt; cnt--)
*dp++ ^= 0xff;
}
}
/*
* Paint a single character.
*/
static void
rasops8_putchar(cookie, row, col, uc, attr)
void *cookie;
int row, col;
u_int uc;
long attr;
{
struct rasops_info *ri;
u_char *dp, *rp, *fr, clr[2];
int width, height, cnt, fs, fb;
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)(attr >> 16);
clr[1] = (u_char)(attr >> 24);
if (uc == ' ') {
while (height--) {
dp = rp;
rp += ri->ri_stride;
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;
rp += ri->ri_stride;
for (cnt = width; cnt; cnt--) {
*dp++ = clr[(fb >> 31) & 1];
fb <<= 1;
}
}
}
/* Do underline */
if (attr & 1) {
rp -= (ri->ri_stride << 1);
while (width--)
*rp++ = clr[1];
}
}
/*
* Recompute the 4x1 blitting stamp.
*/
static void
rasops8_makestamp(long attr)
{
int i;
int32_t fg, bg;
fg = (attr >> 24) & 15;
bg = (attr >> 16) & 15;
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
}
}
/*
* Paint 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(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] = stamp[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) {
DELTA(rp, -(ri->ri_stride << 1), int32_t *);
rp[0] = stamp[15];
rp[1] = stamp[15];
}
stamp_mutex--;
}
/*
* Paint 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(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] = stamp[0];
rp[1] = stamp[0];
rp[2] = 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);
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) {
DELTA(rp, -(ri->ri_stride << 1), int32_t *);
rp[0] = stamp[15];
rp[1] = stamp[15];
rp[2] = stamp[15];
}
stamp_mutex--;
}
/*
* Paint 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(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] = stamp[0];
rp[1] = stamp[0];
rp[2] = stamp[0];
rp[3] = 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);
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) {
DELTA(rp, -(ri->ri_stride << 1), int32_t *);
rp[0] = stamp[15];
rp[1] = stamp[15];
rp[2] = stamp[15];
rp[3] = stamp[15];
}
stamp_mutex--;
}
/*
* Erase rows.
*/
static void
rasops8_eraserows(cookie, row, num, attr)
void *cookie;
int row, num;
long attr;
{
struct rasops_info *ri;
int32_t *dp, clr;
int n8, n1, cnt;
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
num *= ri->ri_font->fontheight;
dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
clr = rasops8_bg_color(attr);
n8 = ri->ri_emustride >> 5;
n1 = (ri->ri_emustride >> 2) & 7;
while (num--) {
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;
}
for (cnt = n1; cnt; cnt--)
*dp++ = clr;
DELTA(dp, ri->ri_delta, int32_t *);
}
}
/*
* Erase columns.
*/
static void
rasops8_erasecols(cookie, row, col, num, attr)
void *cookie;
int row, col, num;
long attr;
{
int n8, clr, height, cnt, slop1, slop2;
struct rasops_info *ri;
int32_t *dst;
u_char *dstb, *rp;
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 = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
clr = rasops8_bg_color(attr);
height = ri->ri_font->fontheight;
slop1 = (int)rp & 3;
slop2 = (num - slop1) & 3;
num -= slop1 + slop2;
n8 = num >> 5;
num = (num >> 2) & 7;
while (height--) {
dstb = rp;
rp += ri->ri_stride;
/* Align span to 4 bytes */
for (cnt = slop1; cnt; cnt--)
*dstb++ = (u_char)clr;
dst = (int32_t *)dstb;
/* Write 32 bytes per loop */
for (cnt = n8; cnt; cnt--) {
dst[0] = clr;
dst[1] = clr;
dst[2] = clr;
dst[3] = clr;
dst[4] = clr;
dst[5] = clr;
dst[6] = clr;
dst[7] = clr;
dst += 8;
}
/* Write 4 bytes per loop */
for (cnt = num; cnt; cnt--)
*dst++ = clr;
/* Write unaligned trailing slop */
if (slop2 == 0)
continue;
dstb = (u_char *)dst;
for (cnt = slop2; cnt; cnt--)
*dstb++ = (u_char)clr;
}
}
#endif /* RASOPS8 */