1 /* $NetBSD: rasops4.c,v 1.8 2009/03/14 15:36:20 dsl Exp $ */
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: rasops4.c,v 1.8 2009/03/14 15:36:20 dsl Exp $");
35 #include "opt_rasops.h"
37 #include <sys/param.h>
38 #include <sys/systm.h>
40 #include <machine/endian.h>
42 #include <dev/wscons/wsdisplayvar.h>
43 #include <dev/wscons/wsconsio.h>
44 #include <dev/rasops/rasops.h>
45 #include <dev/rasops/rasops_masks.h>
47 static void rasops4_copycols(void *, int, int, int, int);
48 static void rasops4_erasecols(void *, int, int, int, long);
49 static void rasops4_do_cursor(struct rasops_info
*);
50 static void rasops4_putchar(void *, int, int col
, u_int
, long);
52 static void rasops4_putchar8(void *, int, int col
, u_int
, long);
53 static void rasops4_putchar12(void *, int, int col
, u_int
, long);
54 static void rasops4_putchar16(void *, int, int col
, u_int
, long);
55 static void rasops4_makestamp(struct rasops_info
*, long);
58 * 4x1 stamp for optimized character blitting
60 static u_int16_t stamp
[16];
61 static long stamp_attr
;
62 static int stamp_mutex
; /* XXX see note in README */
66 * Initialize rasops_info struct for this colordepth.
69 rasops4_init(struct rasops_info
*ri
)
72 switch (ri
->ri_font
->fontwidth
) {
75 ri
->ri_ops
.putchar
= rasops4_putchar8
;
78 ri
->ri_ops
.putchar
= rasops4_putchar12
;
81 ri
->ri_ops
.putchar
= rasops4_putchar16
;
83 #endif /* !RASOPS_SMALL */
85 panic("fontwidth not 8/12/16 or RASOPS_SMALL - fixme!");
86 ri
->ri_ops
.putchar
= rasops4_putchar
;
90 if ((ri
->ri_font
->fontwidth
& 1) != 0) {
91 ri
->ri_ops
.erasecols
= rasops4_erasecols
;
92 ri
->ri_ops
.copycols
= rasops4_copycols
;
93 ri
->ri_do_cursor
= rasops4_do_cursor
;
99 * Paint a single character. This is the generic version, this is ugly.
102 rasops4_putchar(void *cookie
, int row
, int col
, u_int uc
, long attr
)
104 int height
, width
, fs
, rs
, fb
, bg
, fg
, lmask
, rmask
;
105 struct rasops_info
*ri
;
109 ri
= (struct rasops_info
*)cookie
;
111 #ifdef RASOPS_CLIPPING
112 /* Catches 'row < 0' case too */
113 if ((unsigned)row
>= (unsigned)ri
->ri_rows
)
116 if ((unsigned)col
>= (unsigned)ri
->ri_cols
)
120 width
= ri
->ri_font
->fontwidth
<< 1;
121 height
= ri
->ri_font
->fontheight
;
123 rp
= (int32_t *)(ri
->ri_bits
+ row
* ri
->ri_yscale
+ ((col
>> 3) & ~3));
127 bg
= ri
->ri_devcmap
[(attr
>> 16) & 0xf];
128 fg
= ri
->ri_devcmap
[(attr
>> 24) & 0xf];
130 /* If fg and bg match this becomes a space character */
131 if (fg
== bg
|| uc
== ' ') {
133 fr
= 0; /* shutup gcc */
134 fs
= 0; /* shutup gcc */
136 uc
-= ri
->ri_font
->firstchar
;
137 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
138 fs
= ri
->ri_font
->stride
;
141 /* Single word, one mask */
142 if ((col
+ width
) <= 32) {
143 rmask
= rasops_pmask
[col
][width
];
146 if (uc
== (u_int
)-1) {
150 *rp
= (*rp
& lmask
) | bg
;
151 DELTA(rp
, rs
, int32_t *);
164 DELTA(rp
, -(ri
->ri_stride
<< 1), int32_t *);
165 *rp
= (*rp
& lmask
) | (fg
& rmask
);
168 lmask
= ~rasops_lmask
[col
];
169 rmask
= ~rasops_rmask
[(col
+ width
) & 31];
171 if (uc
== (u_int
)-1) {
176 rp
[0] = (rp
[0] & lmask
) | bg
;
177 rp
[1] = (rp
[1] & rmask
) | width
;
178 DELTA(rp
, rs
, int32_t *);
183 /* NOT fontbits if bg is white */
185 fb
= ~(fr
[3] | (fr
[2] << 8) |
186 (fr
[1] << 16) | (fr
[0] << 24));
188 rp
[0] = (rp
[0] & lmask
)
189 | MBE((u_int
)fb
>> col
);
191 rp
[1] = (rp
[1] & rmask
)
192 | (MBE((u_int
)fb
<< width
) & ~rmask
);
195 DELTA(rp
, rs
, int32_t *);
201 DELTA(rp
, -(ri
->ri_stride
<< 1), int32_t *);
202 rp
[0] = (rp
[0] & lmask
) | (fg
& ~lmask
);
203 rp
[1] = (rp
[1] & rmask
) | (fg
& ~rmask
);
210 * Put a single character. This is the generic version.
213 rasops4_putchar(void *cookie
, int row
, int col
, u_int uc
, long attr
)
221 * Recompute the blitting stamp.
224 rasops4_makestamp(struct rasops_info
*ri
, long attr
)
228 fg
= ri
->ri_devcmap
[(attr
>> 24) & 0xf] & 0xf;
229 bg
= ri
->ri_devcmap
[(attr
>> 16) & 0xf] & 0xf;
232 for (i
= 0; i
< 16; i
++) {
233 stamp
[i
] = (i
& 1 ? fg
: bg
) << 8;
234 stamp
[i
] |= (i
& 2 ? fg
: bg
) << 12;
235 stamp
[i
] |= (i
& 4 ? fg
: bg
) << 0;
236 stamp
[i
] |= (i
& 8 ? fg
: bg
) << 4;
241 * Put a single character. This is for 8-pixel wide fonts.
244 rasops4_putchar8(void *cookie
, int row
, int col
, u_int uc
, long attr
)
246 struct rasops_info
*ri
;
251 /* Can't risk remaking the stamp if it's already in use */
254 rasops4_putchar(cookie
, row
, col
, uc
, attr
);
258 ri
= (struct rasops_info
*)cookie
;
260 #ifdef RASOPS_CLIPPING
261 /* Catches 'row < 0' case too */
262 if ((unsigned)row
>= (unsigned)ri
->ri_rows
) {
267 if ((unsigned)col
>= (unsigned)ri
->ri_cols
) {
273 rp
= (u_int16_t
*)(ri
->ri_bits
+ row
* ri
->ri_yscale
+ col
* ri
->ri_xscale
);
274 height
= ri
->ri_font
->fontheight
;
275 rs
= ri
->ri_stride
/ sizeof(*rp
);
277 /* Recompute stamp? */
278 if (attr
!= stamp_attr
)
279 rasops4_makestamp(ri
, attr
);
282 u_int16_t c
= stamp
[0];
289 uc
-= ri
->ri_font
->firstchar
;
290 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
291 fs
= ri
->ri_font
->stride
;
294 rp
[0] = stamp
[(*fr
>> 4) & 0xf];
295 rp
[1] = stamp
[*fr
& 0xf];
302 if ((attr
& 1) != 0) {
312 * Put a single character. This is for 12-pixel wide fonts.
315 rasops4_putchar12(void *cookie
, int row
, int col
, u_int uc
, long attr
)
317 struct rasops_info
*ri
;
322 /* Can't risk remaking the stamp if it's already in use */
325 rasops4_putchar(cookie
, row
, col
, uc
, attr
);
329 ri
= (struct rasops_info
*)cookie
;
331 #ifdef RASOPS_CLIPPING
332 /* Catches 'row < 0' case too */
333 if ((unsigned)row
>= (unsigned)ri
->ri_rows
) {
338 if ((unsigned)col
>= (unsigned)ri
->ri_cols
) {
344 rp
= (u_int16_t
*)(ri
->ri_bits
+ row
* ri
->ri_yscale
+ col
* ri
->ri_xscale
);
345 height
= ri
->ri_font
->fontheight
;
346 rs
= ri
->ri_stride
/ sizeof(*rp
);
348 /* Recompute stamp? */
349 if (attr
!= stamp_attr
)
350 rasops4_makestamp(ri
, attr
);
353 u_int16_t c
= stamp
[0];
361 uc
-= ri
->ri_font
->firstchar
;
362 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
363 fs
= ri
->ri_font
->stride
;
366 rp
[0] = stamp
[(fr
[0] >> 4) & 0xf];
367 rp
[1] = stamp
[fr
[0] & 0xf];
368 rp
[2] = stamp
[(fr
[1] >> 4) & 0xf];
375 if ((attr
& 1) != 0) {
386 * Put a single character. This is for 16-pixel wide fonts.
389 rasops4_putchar16(void *cookie
, int row
, int col
, u_int uc
, long attr
)
391 struct rasops_info
*ri
;
396 /* Can't risk remaking the stamp if it's already in use */
399 rasops4_putchar(cookie
, row
, col
, uc
, attr
);
403 ri
= (struct rasops_info
*)cookie
;
405 #ifdef RASOPS_CLIPPING
406 /* Catches 'row < 0' case too */
407 if ((unsigned)row
>= (unsigned)ri
->ri_rows
) {
412 if ((unsigned)col
>= (unsigned)ri
->ri_cols
) {
418 rp
= (u_int16_t
*)(ri
->ri_bits
+ row
* ri
->ri_yscale
+ col
* ri
->ri_xscale
);
419 height
= ri
->ri_font
->fontheight
;
420 rs
= ri
->ri_stride
/ sizeof(*rp
);
422 /* Recompute stamp? */
423 if (attr
!= stamp_attr
)
424 rasops4_makestamp(ri
, attr
);
427 u_int16_t c
= stamp
[0];
436 uc
-= ri
->ri_font
->firstchar
;
437 fr
= (u_char
*)ri
->ri_font
->data
+ uc
* ri
->ri_fontscale
;
438 fs
= ri
->ri_font
->stride
;
441 rp
[0] = stamp
[(fr
[0] >> 4) & 0xf];
442 rp
[1] = stamp
[fr
[0] & 0xf];
443 rp
[2] = stamp
[(fr
[1] >> 4) & 0xf];
444 rp
[3] = stamp
[fr
[1] & 0xf];
451 if ((attr
& 1) != 0) {
461 #endif /* !RASOPS_SMALL */
464 * Grab routines common to depths where (bpp < 8)
466 #define NAME(ident) rasops4_##ident
467 #define PIXEL_SHIFT 3
469 #include <dev/rasops/rasops_bitops.h>