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