Home | History | Annotate | Line # | Download | only in rasops
rasops24.c revision 1.1
      1 /* $NetBSD: rasops24.c,v 1.1 1999/04/13 00:18:00 ad Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Andy Doran <ad (at) NetBSD.org>.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *        This product includes software developed by the NetBSD
     21  *        Foundation, Inc. and its contributors.
     22  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  *    contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  * POSSIBILITY OF SUCH DAMAGE.
     37  */
     38 #include <sys/cdefs.h>
     39 __KERNEL_RCSID(0, "$NetBSD: rasops24.c,v 1.1 1999/04/13 00:18:00 ad Exp $");
     40 
     41 #include "opt_rasops.h"
     42 #ifdef RASOPS24
     43 #error This is dangerously incomplete.
     44 
     45 #include <sys/types.h>
     46 #include <sys/param.h>
     47 #include <sys/systm.h>
     48 #include <sys/time.h>
     49 
     50 #include <dev/wscons/wsdisplayvar.h>
     51 #include <dev/wscons/wsconsio.h>
     52 #include <dev/rasops/rasops.h>
     53 
     54 static void 	rasops24_putchar __P((void *, int, int, u_int, long attr));
     55 static void 	rasops24_erasecols __P((void *, int, int, int, long));
     56 static void 	rasops24_eraserows __P((void *, int, int, long));
     57 static int	rasops24_alloc_attr __P((void *, int, int, int, long *));
     58 static void	rasops24_make_bgstamp __P((int, u_char *));
     59 static int32_t	rasops24_fg_color __P((struct rasops_info *, long));
     60 static int32_t	rasops24_bg_color __P((struct rasops_info *, long));
     61 static void	rasops24_do_cursor __P((struct rasops_info *));
     62 
     63 void	rasops24_init __P((struct rasops_info *ri));
     64 
     65 /*
     66  * Initalize rasops_info struct for this colordepth.
     67  */
     68 void
     69 rasops24_init(ri)
     70 	struct rasops_info *ri;
     71 {
     72 
     73 	switch (ri->ri_font->fontwidth) {
     74 	case 8:
     75 		ri->ri_ops.putchar = rasops15_putchar8;
     76 		break;
     77 
     78 	case 12:
     79 		ri->ri_ops.putchar = rasops15_putchar12;
     80 		break;
     81 
     82 	case 16:
     83 		ri->ri_ops.putchar = rasops15_putchar16;
     84 		break;
     85 
     86 	default:
     87 		ri->ri_ops.putchar = rasops15_putchar;
     88 		break;
     89 	}
     90 
     91 	/* Select defaults for color positions if none selected */
     92 	if (ri->ri_rnum == 0) {
     93 		ri->ri_rnum = 8;
     94 		ri->ri_gnum = 8;
     95 		ri->ri_bnum = 8;
     96 		ri->ri_rpos = 0;
     97 		ri->ri_gpos = 8;
     98 		ri->ri_bpos = 16;
     99 	}
    100 
    101 	ri->ri_ops.erasecols = rasops25_erasecols;
    102 	ri->ri_ops.eraserows = rasops25_eraserows;
    103 	ri->ri_do_cursor = rasops25_do_cursor;
    104 	rasops_init_devcmap(ri);
    105 }
    106 
    107 /*
    108  * Get foreground color from attribute and copy across all 4 bytes
    109  * in a int32_t.
    110  */
    111 static __inline__ int32_t
    112 rasops24_fg_color(ri, attr)
    113 	struct rasops_info *ri;
    114 	long attr;
    115 {
    116 	int32_t fg;
    117 
    118 	fg = ri->ri_devcmap[((u_int)attr >> 24) & 15];
    119 
    120 	/* Copy across all 4 bytes if the color is gray */
    121 	if (attr & 2)
    122 		fg |= fg << 8;
    123 
    124 	return fg;
    125 }
    126 
    127 
    128 /*
    129  * Get background color from attribute and copy across all 4 bytes
    130  * in a int32_t.
    131  */
    132 static __inline__ int32_t
    133 rasops24_bg_color(ri, attr)
    134 	struct rasops_info *ri;
    135 	long attr;
    136 {
    137 	int32_t bg;
    138 
    139 	bg = ri->ri_devcmap[((u_int)attr >> 16) & 15];
    140 
    141 	/* Copy across all 4 bytes if the color is gray */
    142 	if (attr & 4)
    143 		bg |= bg << 8;
    144 
    145 	return bg;
    146 }
    147 
    148 
    149 /*
    150  * Actually turn the cursor on or off. This does the dirty work for
    151  * rasops_cursor().
    152  */
    153 static void
    154 rasops24_do_cursor(ri)
    155 	struct rasops_info *ri;
    156 {
    157 	int full1, height, cnt, slop1, slop2, row, col;
    158 	u_char *dp, *rp;
    159 
    160 	row = ri->ri_crow;
    161 	col = ri->ri_ccol;
    162 
    163 	rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
    164 	height = ri->ri_font->fontheight;
    165 
    166 	slop1 = (int)rp & 3;
    167 	slop2 = (ri->ri_xscale - slop1) & 3;
    168 	full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
    169 
    170 	while (height--) {
    171 		dp = rp;
    172 		rp += ri->ri_stride;
    173 
    174 		for (cnt = slop1; cnt; cnt--)
    175 			*dp++ ^= 0xff;
    176 
    177 		for (cnt = full1; cnt; cnt--) {
    178 			*(int32_t *)dp ^= 0xffffffff;
    179 			dp += 4;
    180 		}
    181 
    182 		for (cnt = slop2; cnt; cnt--)
    183 			*dp++ ^= 0xff;
    184 	}
    185 }
    186 
    187 
    188 /*
    189  * Erase columns.
    190  */
    191 static void
    192 rasops24_erasecols(cookie, row, col, num, attr)
    193 	void *cookie;
    194 	int row, col, num;
    195 	long attr;
    196 {
    197 	struct rasops_info *ri;
    198 	int32_t *dp;
    199 	u_char *rp;
    200 	int n8, n1, clr, height, cnt, slop1, slop2;
    201 
    202 	ri = (struct rasops_info *)cookie;
    203 
    204 #ifdef RASOPS_CLIPPING
    205 	/* Catches 'row < 0' case too */
    206 	if ((unsigned)row >= (unsigned)ri->ri_rows)
    207 		return;
    208 
    209 	if (col < 0) {
    210 		num += col;
    211 		col = 0;
    212 	}
    213 
    214 	if ((col + num) > ri->ri_cols)
    215 		num = ri->ri_cols - col;
    216 
    217 	if (num <= 0)
    218 		return;
    219 #endif
    220 
    221 	rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
    222 	num *= ri->ri_xscale;
    223 	clr = rasops24_bg_color(ri, attr);
    224 	height = ri->ri_font->fontheight;
    225 
    226 	slop1 = (int)rp & 2;
    227 	slop2 = (num - slop1) & 2;
    228 	n8 = num >> 5;
    229 	n1 = (num >> 2) & 7;
    230 
    231 	while (height--) {
    232 		cnt = num;
    233 		dp = (u_int32_t *)rp;
    234 		rp += ri->ri_stride;
    235 
    236 		/* Align span to 4 bytes */
    237 		if (slop1) {
    238 			*(int16_t *)dp = (int16_t)clr;
    239 			DELTA(dp, 2, int32_t *);
    240 		}
    241 
    242 		/* Write 32 bytes per loop */
    243 		for (cnt = n8; cnt; cnt--) {
    244 			dp[0] = clr;
    245 			dp[1] = clr;
    246 			dp[2] = clr;
    247 			dp[3] = clr;
    248 			dp[4] = clr;
    249 			dp[5] = clr;
    250 			dp[6] = clr;
    251 			dp[7] = clr;
    252 			dp += 8;
    253 		}
    254 
    255 		/* Write 4 bytes per loop */
    256 		for (cnt = n1; cnt; cnt--)
    257 			*dp++ = clr;
    258 
    259 		/* Write unaligned trailing slop */
    260 		if (slop2)
    261 			*(int16_t *)dp = (int16_t)clr;
    262 	}
    263 }
    264 
    265 
    266 /*
    267  * Paint a single character.
    268  */
    269 static void
    270 rasops24_putchar(cookie, row, col, uc, attr)
    271 	void *cookie;
    272 	int row, col;
    273 	u_int uc;
    274 	long attr;
    275 {
    276 	struct rasops_info *ri;
    277 	u_char *dp, *rp;
    278 	int32_t *fr, clr[16], fb;
    279 	int width, height, cnt;
    280 
    281 	if (uc == (u_int)-1) {
    282 		rasops24_erasecols(cookie, row, col, 1, attr);
    283 		return;
    284 	}
    285 
    286 	ri = (struct rasops_info *)cookie;
    287 
    288 #ifdef RASOPS_CLIPPING
    289 	if ((unsigned)row >= (unsigned)ri->ri_rows)
    290 		return;
    291 
    292 	if ((unsigned)col >= (unsigned)ri->ri_cols)
    293 		return;
    294 #endif
    295 
    296 	rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
    297 	fr = (int32_t *)ri->ri_font->data + uc * ri->ri_font->fontheight;
    298 
    299 	height = ri->ri_font->fontheight;
    300 	width = ri->ri_font->fontwidth;
    301 
    302 	clr[1] = ri->ri_devcmap[((u_int)attr >> 24)];
    303 	clr[0] = ri->ri_devcmap[((u_int)attr >> 16)];
    304 
    305 	while (height--) {
    306 		dp = rp;
    307 		fb = *fr++;
    308 		rp += ri->ri_stride;
    309 
    310 		for (cnt = width; cnt; cnt--) {
    311 			*(int16_t *)dp = (int16_t)clr[fb & 1];
    312 			fb >>= 1;
    313 			dp += 2;
    314 		}
    315 	}
    316 }
    317 
    318 
    319 /*
    320  * Construct a 12 byte by 1 byte blitting stamp. This uses the background
    321  * color only (for erasecols()/eraserows()).
    322  */
    323 static void
    324 rasops24_make_bgstamp(i, bp)
    325 	int i;
    326 	u_char *bp;
    327 {
    328 	u_char r, g, b;
    329 
    330 	i = (i >> 8) & 0xff;
    331 	i = (i << 1) + i;
    332 	r = rasops_cmap[i+0];
    333 	g = rasops_cmap[i+1];
    334 	b = rasops_cmap[i+2];
    335 
    336 #if BYTE_ORDER == LITTLE_ENDIAN
    337 	bp[0] = r; bp[1] = g; bp[2] = b;  bp[3] = r;
    338 	bp[4] = g; bp[5] = b; bp[6] = r;  bp[7] = g;
    339 	bp[8] = b; bp[9] = r; bp[10] = g; bp[11] = b;
    340 #else
    341 	bp[3] = r;  bp[2] = g;  bp[1] = b; bp[0] = r;
    342 	bp[7] = g;  bp[6] = b;  bp[5] = r; bp[4] = g;
    343 	bp[11] = b; bp[10] = r; bp[9] = g; bp[8] = b;
    344 #endif
    345 }
    346 
    347 
    348 /*
    349  * Erase rows.
    350  */
    351 static void
    352 rasops24_eraserows(cookie, row, num, attr)
    353 	void *cookie;
    354 	int row, num;
    355 	long attr;
    356 {
    357 	struct rasops_info *ri;
    358 	int32_t *dp, clr, stamp[3];
    359 	int n9, n3, n1, cnt;
    360 
    361 	ri = (struct rasops_info *)cookie;
    362 
    363 #ifdef RASOPS_CLIPPING
    364 	if (row < 0) {
    365 		num += row;
    366 		row = 0;
    367 	}
    368 
    369 	if ((row + num) > ri->ri_rows)
    370 		num = ri->ri_rows - row;
    371 
    372 	if (num <= 0)
    373 		return;
    374 #endif
    375 
    376 	num *= ri->ri_font->fontheight;
    377 	dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
    378 
    379 	n9 = ri->ri_emustride / 36;
    380 	cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
    381 
    382 	n3 = (ri->ri_emustride - cnt) / 12;
    383 	cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
    384 
    385 	n1 = (ri->ri_emustride - cnt) >> 2;
    386 
    387 	/* If the color is gray, we can cheat... */
    388 	if (attr & ATTR_GRAY_BG) {
    389 		clr = rasops24_bg_color(ri, attr);
    390 
    391 		while (num--) {
    392 			for (cnt = n9; cnt; cnt--) {
    393 				dp[0] = clr;
    394 				dp[1] = clr;
    395 				dp[2] = clr;
    396 				dp[3] = clr;
    397 				dp[4] = clr;
    398 				dp[5] = clr;
    399 				dp[6] = clr;
    400 				dp[7] = clr;
    401 				dp[8] = clr;
    402 				dp += 9;
    403 			}
    404 
    405 			for (cnt = n3; cnt; cnt--) {
    406 				dp[0] = clr;
    407 				dp[1] = clr;
    408 				dp[2] = clr;
    409 				dp += 3;
    410 			}
    411 
    412 			for (cnt = n1; cnt; cnt--)
    413 				*dp++ = clr;
    414 
    415 			DELTA(dp, ri->ri_delta, int32_t *);
    416 		}
    417 	} else {
    418 		rasops24_make_bgstamp((int)attr, (u_char *)stamp);
    419 
    420 		while (num--) {
    421 			for (cnt = n9; cnt; cnt--) {
    422 				dp[0] = stamp[0];
    423 				dp[1] = stamp[1];
    424 				dp[2] = stamp[2];
    425 				dp[3] = stamp[0];
    426 				dp[4] = stamp[1];
    427 				dp[5] = stamp[2];
    428 				dp[6] = stamp[0];
    429 				dp[7] = stamp[1];
    430 				dp[8] = stamp[2];
    431 				dp += 9;
    432 			}
    433 
    434 			for (cnt = n3; cnt; cnt--) {
    435 				dp[0] = stamp[0];
    436 				dp[1] = stamp[1];
    437 				dp[2] = stamp[2];
    438 				dp += 3;
    439 			}
    440 
    441 			for (cnt = 0; cnt < n1; cnt++)
    442 				*dp++ = stamp[cnt];
    443 
    444 			DELTA(dp, ri->ri_delta, int32_t *);
    445 		}
    446 	}
    447 }
    448 
    449 #endif /* RASOPS24 */
    450