Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / luna68k / dev / omrasops.c
blobbf7997cec0ad0f1a65a4e9603806d0e0deff447c
1 /* $NetBSD: omrasops.c,v 1.8 2009/03/14 15:36:08 dsl Exp $ */
3 /*-
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tohru Nishimura.
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.
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> /* RCS ID & Copyright macro defns */
34 __KERNEL_RCSID(0, "$NetBSD: omrasops.c,v 1.8 2009/03/14 15:36:08 dsl Exp $");
37 * Designed speficically for 'm68k bitorder';
38 * - most significant byte is stored at lower address,
39 * - most significant bit is displayed at left most on screen.
40 * Implementation relys on;
41 * - every memory references is done in aligned 32bit chunk,
42 * - font glyphs are stored in 32bit padded.
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/device.h>
49 #include <dev/rcons/raster.h>
50 #include <dev/wscons/wscons_raster.h>
51 #include <dev/wscons/wscons_rfont.h>
52 #include <dev/wscons/wsdisplayvar.h>
54 void rcons_init(struct rcons *, int, int);
56 /* wscons emulator operations */
57 static void om_cursor(void *, int, int, int);
58 static int om_mapchar(void *, int, unsigned int *);
59 static void om_putchar(void *, int, int, u_int, long);
60 static void om_copycols(void *, int, int, int, int);
61 static void om_copyrows(void *, int, int, int num);
62 static void om_erasecols(void *, int, int, int, long);
63 static void om_eraserows(void *, int, int, long);
64 static int om_allocattr(void *, int, int, int, long *);
66 struct wsdisplay_emulops omfb_emulops = {
67 om_cursor,
68 om_mapchar,
69 om_putchar,
70 om_copycols,
71 om_erasecols,
72 om_copyrows,
73 om_eraserows,
74 om_allocattr
77 #define ALL1BITS (~0U)
78 #define ALL0BITS (0U)
79 #define BLITWIDTH (32)
80 #define ALIGNMASK (0x1f)
81 #define BYTESDONE (4)
83 #define W(p) (*(u_int32_t *)(p))
84 #define R(p) (*(u_int32_t *)((uint8_t *)(p) + 0x40000))
87 * Blit a character at the specified co-ordinates.
89 static void
90 om_putchar(void *cookie, int row, int startcol, u_int uc, long attr)
92 struct rcons *rc = cookie;
93 struct raster *rap = rc->rc_sp;
94 uint8_t *p;
95 int scanspan, startx, height, width, align, y;
96 u_int32_t lmask, rmask, glyph, inverse;
97 u_int32_t *g;
99 scanspan = rap->linelongs * 4;
100 y = rc->rc_yorigin + rc->rc_font->height * row;
101 startx = rc->rc_xorigin + rc->rc_font->width * startcol;
102 height = rc->rc_font->height;
103 g = rc->rc_font->chars[uc].r->pixels;
104 inverse = (attr != 0) ? ALL1BITS : ALL0BITS;
106 p = (uint8_t *)rap->pixels + y * scanspan + ((startx / 32) * 4);
107 align = startx & ALIGNMASK;
108 width = rc->rc_font->width + align;
109 lmask = ALL1BITS >> align;
110 rmask = ALL1BITS << (-width & ALIGNMASK);
111 if (width <= BLITWIDTH) {
112 lmask &= rmask;
113 while (height > 0) {
114 glyph = *g;
115 glyph = (glyph >> align) ^ inverse;
116 W(p) = (R(p) & ~lmask) | (glyph & lmask);
117 p += scanspan;
118 g += 1;
119 height--;
122 else {
123 uint8_t *q = p;
124 u_int32_t lhalf, rhalf;
126 while (height > 0) {
127 glyph = *g;
128 lhalf = (glyph >> align) ^ inverse;
129 W(p) = (R(p) & ~lmask) | (lhalf & lmask);
130 p += BYTESDONE;
131 rhalf = (glyph << (BLITWIDTH - align)) ^ inverse;
132 W(p) = (rhalf & rmask) | (R(p) & ~rmask);
134 p = (q += scanspan);
135 g += 1;
136 height--;
141 static void
142 om_erasecols(void *cookie, int row, int startcol, int ncols, long attr)
144 struct rcons *rc = cookie;
145 struct raster *rap = rc->rc_sp;
146 uint8_t *p;
147 int scanspan, startx, height, width, align, w, y;
148 u_int32_t lmask, rmask, fill;
150 scanspan = rap->linelongs * 4;
151 y = rc->rc_yorigin + rc->rc_font->height * row;
152 startx = rc->rc_xorigin + rc->rc_font->width * startcol;
153 height = rc->rc_font->height;
154 w = rc->rc_font->width * ncols;
155 fill = (attr != 0) ? ALL1BITS : ALL0BITS;
157 p = (uint8_t *)rap->pixels + y * scanspan + ((startx / 32) * 4);
158 align = startx & ALIGNMASK;
159 width = w + align;
160 lmask = ALL1BITS >> align;
161 rmask = ALL1BITS << (-width & ALIGNMASK);
162 if (width <= BLITWIDTH) {
163 lmask &= rmask;
164 fill &= lmask;
165 while (height > 0) {
166 W(p) = (R(p) & ~lmask) | fill;
167 p += scanspan;
168 height--;
171 else {
172 uint8_t *q = p;
173 while (height > 0) {
174 W(p) = (R(p) & ~lmask) | (fill & lmask);
175 width -= 2 * BLITWIDTH;
176 while (width > 0) {
177 p += BYTESDONE;
178 W(p) = fill;
179 width -= BLITWIDTH;
181 p += BYTESDONE;
182 W(p) = (fill & rmask) | (R(p) & ~rmask);
184 p = (q += scanspan);
185 width = w + align;
186 height--;
191 static void
192 om_eraserows(void *cookie, int startrow, int nrows, long attr)
194 struct rcons *rc = cookie;
195 struct raster *rap = rc->rc_sp;
196 uint8_t *p, *q;
197 int scanspan, starty, height, width, w;
198 u_int32_t rmask, fill;
200 scanspan = rap->linelongs * 4;
201 starty = rc->rc_yorigin + rc->rc_font->height * startrow;
202 height = rc->rc_font->height * nrows;
203 w = rc->rc_font->width * rc->rc_maxcol;
204 fill = (attr == 1) ? ALL1BITS : ALL0BITS;
206 p = (uint8_t *)rap->pixels + starty * scanspan;
207 p += (rc->rc_xorigin / 32) * 4;
208 width = w;
209 rmask = ALL1BITS << (-width & ALIGNMASK);
210 q = p;
211 while (height > 0) {
212 W(p) = fill; /* always aligned */
213 width -= 2 * BLITWIDTH;
214 while (width > 0) {
215 p += BYTESDONE;
216 W(p) = fill;
217 width -= BLITWIDTH;
219 p += BYTESDONE;
220 W(p) = (fill & rmask) | (R(p) & ~rmask);
221 p = (q += scanspan);
222 width = w;
223 height--;
227 static void
228 om_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
230 struct rcons *rc = cookie;
231 struct raster *rap = rc->rc_sp;
232 uint8_t *p, *q;
233 int scanspan, offset, srcy, height, width, w;
234 u_int32_t rmask;
236 scanspan = rap->linelongs * 4;
237 height = rc->rc_font->height * nrows;
238 offset = (dstrow - srcrow) * scanspan * rc->rc_font->height;
239 srcy = rc->rc_yorigin + rc->rc_font->height * srcrow;
240 if (srcrow < dstrow && srcrow + nrows > dstrow) {
241 scanspan = -scanspan;
242 srcy += height;
245 p = (uint8_t *)rap->pixels + srcy * (rap->linelongs * 4);
246 p += (rc->rc_xorigin / 32) * 4;
247 w = rc->rc_font->width * rc->rc_maxcol;
248 width = w;
249 rmask = ALL1BITS << (-width & ALIGNMASK);
250 q = p;
251 while (height > 0) {
252 W(p + offset) = R(p); /* always aligned */
253 width -= 2 * BLITWIDTH;
254 while (width > 0) {
255 p += BYTESDONE;
256 W(p + offset) = R(p);
257 width -= BLITWIDTH;
259 p += BYTESDONE;
260 W(p + offset) = (R(p) & rmask) | (R(p + offset) & ~rmask);
262 p = (q += scanspan);
263 width = w;
264 height--;
268 static void
269 om_copycols(void *cookie, int startrow, int srccol, int dstcol, int ncols)
271 struct rcons *rc = cookie;
272 struct raster *rap = rc->rc_sp;
273 uint8_t *sp, *dp, *basep;
274 int scanspan, height, width, align, shift, w, y, srcx, dstx;
275 u_int32_t lmask, rmask;
277 scanspan = rap->linelongs * 4;
278 y = rc->rc_yorigin + rc->rc_font->height * startrow;
279 srcx = rc->rc_xorigin + rc->rc_font->width * srccol;
280 dstx = rc->rc_xorigin + rc->rc_font->width * dstcol;
281 height = rc->rc_font->height;
282 w = rc->rc_font->width * ncols;
283 basep = (uint8_t *)rap->pixels + y * scanspan;
285 align = shift = srcx & ALIGNMASK;
286 width = w + align;
287 align = dstx & ALIGNMASK;
288 lmask = ALL1BITS >> align;
289 rmask = ALL1BITS << (-(w + align) & ALIGNMASK);
290 shift = align - shift;
291 sp = basep + (srcx / 32) * 4;
292 dp = basep + (dstx / 32) * 4;
294 if (shift != 0)
295 goto hardluckalignment;
297 /* alignments comfortably match */
298 if (width <= BLITWIDTH) {
299 lmask &= rmask;
300 while (height > 0) {
301 W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
302 dp += scanspan;
303 sp += scanspan;
304 height--;
307 /* copy forward (left-to-right) */
308 else if (dstcol < srccol || srccol + ncols < dstcol) {
309 uint8_t *sq = sp, *dq = dp;
311 w = width;
312 while (height > 0) {
313 W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
314 width -= 2 * BLITWIDTH;
315 while (width > 0) {
316 sp += BYTESDONE;
317 dp += BYTESDONE;
318 W(dp) = R(sp);
319 width -= BLITWIDTH;
321 sp += BYTESDONE;
322 dp += BYTESDONE;
323 W(dp) = (R(sp) & rmask) | (R(dp) & ~rmask);
324 sp = (sq += scanspan);
325 dp = (dq += scanspan);
326 width = w;
327 height--;
330 /* copy backward (right-to-left) */
331 else {
332 uint8_t *sq, *dq;
334 sq = (sp += width / 32 * 4);
335 dq = (dp += width / 32 * 4);
336 w = width;
337 while (height > 0) {
338 W(dp) = (R(sp) & rmask) | (R(dp) & ~rmask);
339 width -= 2 * BLITWIDTH;
340 while (width > 0) {
341 sp -= BYTESDONE;
342 dp -= BYTESDONE;
343 W(dp) = R(sp);
344 width -= BLITWIDTH;
346 sp -= BYTESDONE;
347 dp -= BYTESDONE;
348 W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
350 sp = (sq += scanspan);
351 dp = (dq += scanspan);
352 width = w;
353 height--;
356 return;
358 hardluckalignment:
359 /* alignments painfully disagree */
360 return;
364 * Map a character.
366 static int
367 om_mapchar(void *cookie, int c, u_int *cp)
369 if (c < 128) {
370 *cp = c;
371 return (5);
373 *cp = ' ';
374 return (0);
378 * Position|{enable|disable} the cursor at the specified location.
380 static void
381 om_cursor(void *cookie, int on, int row, int col)
383 struct rcons *rc = cookie;
384 struct raster *rap = rc->rc_sp;
385 uint8_t *p;
386 int scanspan, startx, height, width, align, y;
387 u_int32_t lmask, rmask, image;
389 if (!on) {
390 /* make sure it's on */
391 if ((rc->rc_bits & RC_CURSOR) == 0)
392 return;
394 row = *rc->rc_crowp;
395 col = *rc->rc_ccolp;
396 } else {
397 /* unpaint the old copy. */
398 *rc->rc_crowp = row;
399 *rc->rc_ccolp = col;
402 scanspan = rap->linelongs * 4;
403 y = rc->rc_yorigin + rc->rc_font->height * row;
404 startx = rc->rc_xorigin + rc->rc_font->width * col;
405 height = rc->rc_font->height;
407 p = (uint8_t *)rap->pixels + y * scanspan + ((startx / 32) * 4);
408 align = startx & ALIGNMASK;
409 width = rc->rc_font->width + align;
410 lmask = ALL1BITS >> align;
411 rmask = ALL1BITS << (-width & ALIGNMASK);
412 if (width <= BLITWIDTH) {
413 lmask &= rmask;
414 while (height > 0) {
415 image = R(p);
416 W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask);
417 p += scanspan;
418 height--;
421 else {
422 uint8_t *q = p;
424 while (height > 0) {
425 image = R(p);
426 W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask);
427 p += BYTESDONE;
428 image = R(p);
429 W(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask);
431 p = (q += scanspan);
432 height--;
435 rc->rc_bits ^= RC_CURSOR;
439 * Allocate attribute. We just pack these into an integer.
441 static int
442 om_allocattr(void *id, int fg, int bg, int flags, long *attrp)
444 if (flags & (WSATTR_HILIT | WSATTR_BLINK |
445 WSATTR_UNDERLINE | WSATTR_WSCOLORS))
446 return (EINVAL);
447 if (flags & WSATTR_REVERSE)
448 *attrp = 1;
449 else
450 *attrp = 0;
451 return (0);
454 void
455 rcons_init(struct rcons *rc, int mrow, int mcol)
457 struct raster *rp = rc->rc_sp;
458 int i;
460 rc->rc_font = &gallant19; /* 12x22 monospacing font */
462 /* Get distance to top and bottom of font from font origin */
463 rc->rc_font_ascent = -(rc->rc_font->chars)['a'].homey;
465 i = rp->height / rc->rc_font->height;
466 rc->rc_maxrow = min(i, mrow);
468 i = rp->width / rc->rc_font->width;
469 rc->rc_maxcol = min(i, mcol);
471 /* Center emulator screen (but align x origin to 32 bits) */
472 rc->rc_xorigin =
473 ((rp->width - rc->rc_maxcol * rc->rc_font->width) / 2) & ~ALIGNMASK;
474 rc->rc_yorigin =
475 (rp->height - rc->rc_maxrow * rc->rc_font->height) / 2;
476 #if 0
477 /* Raster width used for row copies */
478 rc->rc_raswidth = rc->rc_maxcol * rc->rc_font->width;
479 if (rc->rc_raswidth & ALIGNMASK) {
480 /* Pad to 32 bits */
481 i = (rc->rc_raswidth + ALIGNMASK) & ~ALIGNMASK;
482 /* Make sure width isn't too wide */
483 if (rc->rc_xorigin + i <= rp->width)
484 rc->rc_raswidth = i;
486 #endif
487 rc->rc_bits = 0;