1 /* $NetBSD: omrasops.c,v 1.8 2009/03/14 15:36:08 dsl Exp $ */
4 * Copyright (c) 2000 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> /* 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
= {
77 #define ALL1BITS (~0U)
79 #define BLITWIDTH (32)
80 #define ALIGNMASK (0x1f)
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.
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
;
95 int scanspan
, startx
, height
, width
, align
, y
;
96 u_int32_t lmask
, rmask
, glyph
, inverse
;
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
) {
115 glyph
= (glyph
>> align
) ^ inverse
;
116 W(p
) = (R(p
) & ~lmask
) | (glyph
& lmask
);
124 u_int32_t lhalf
, rhalf
;
128 lhalf
= (glyph
>> align
) ^ inverse
;
129 W(p
) = (R(p
) & ~lmask
) | (lhalf
& lmask
);
131 rhalf
= (glyph
<< (BLITWIDTH
- align
)) ^ inverse
;
132 W(p
) = (rhalf
& rmask
) | (R(p
) & ~rmask
);
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
;
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
;
160 lmask
= ALL1BITS
>> align
;
161 rmask
= ALL1BITS
<< (-width
& ALIGNMASK
);
162 if (width
<= BLITWIDTH
) {
166 W(p
) = (R(p
) & ~lmask
) | fill
;
174 W(p
) = (R(p
) & ~lmask
) | (fill
& lmask
);
175 width
-= 2 * BLITWIDTH
;
182 W(p
) = (fill
& rmask
) | (R(p
) & ~rmask
);
192 om_eraserows(void *cookie
, int startrow
, int nrows
, long attr
)
194 struct rcons
*rc
= cookie
;
195 struct raster
*rap
= rc
->rc_sp
;
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;
209 rmask
= ALL1BITS
<< (-width
& ALIGNMASK
);
212 W(p
) = fill
; /* always aligned */
213 width
-= 2 * BLITWIDTH
;
220 W(p
) = (fill
& rmask
) | (R(p
) & ~rmask
);
228 om_copyrows(void *cookie
, int srcrow
, int dstrow
, int nrows
)
230 struct rcons
*rc
= cookie
;
231 struct raster
*rap
= rc
->rc_sp
;
233 int scanspan
, offset
, srcy
, height
, width
, w
;
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
;
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
;
249 rmask
= ALL1BITS
<< (-width
& ALIGNMASK
);
252 W(p
+ offset
) = R(p
); /* always aligned */
253 width
-= 2 * BLITWIDTH
;
256 W(p
+ offset
) = R(p
);
260 W(p
+ offset
) = (R(p
) & rmask
) | (R(p
+ offset
) & ~rmask
);
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
;
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;
295 goto hardluckalignment
;
297 /* alignments comfortably match */
298 if (width
<= BLITWIDTH
) {
301 W(dp
) = (R(dp
) & ~lmask
) | (R(sp
) & lmask
);
307 /* copy forward (left-to-right) */
308 else if (dstcol
< srccol
|| srccol
+ ncols
< dstcol
) {
309 uint8_t *sq
= sp
, *dq
= dp
;
313 W(dp
) = (R(dp
) & ~lmask
) | (R(sp
) & lmask
);
314 width
-= 2 * BLITWIDTH
;
323 W(dp
) = (R(sp
) & rmask
) | (R(dp
) & ~rmask
);
324 sp
= (sq
+= scanspan
);
325 dp
= (dq
+= scanspan
);
330 /* copy backward (right-to-left) */
334 sq
= (sp
+= width
/ 32 * 4);
335 dq
= (dp
+= width
/ 32 * 4);
338 W(dp
) = (R(sp
) & rmask
) | (R(dp
) & ~rmask
);
339 width
-= 2 * BLITWIDTH
;
348 W(dp
) = (R(dp
) & ~lmask
) | (R(sp
) & lmask
);
350 sp
= (sq
+= scanspan
);
351 dp
= (dq
+= scanspan
);
359 /* alignments painfully disagree */
367 om_mapchar(void *cookie
, int c
, u_int
*cp
)
378 * Position|{enable|disable} the cursor at the specified location.
381 om_cursor(void *cookie
, int on
, int row
, int col
)
383 struct rcons
*rc
= cookie
;
384 struct raster
*rap
= rc
->rc_sp
;
386 int scanspan
, startx
, height
, width
, align
, y
;
387 u_int32_t lmask
, rmask
, image
;
390 /* make sure it's on */
391 if ((rc
->rc_bits
& RC_CURSOR
) == 0)
397 /* unpaint the old copy. */
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
) {
416 W(p
) = (image
& ~lmask
) | ((image
^ ALL1BITS
) & lmask
);
426 W(p
) = (image
& ~lmask
) | ((image
^ ALL1BITS
) & lmask
);
429 W(p
) = ((image
^ ALL1BITS
) & rmask
) | (image
& ~rmask
);
435 rc
->rc_bits
^= RC_CURSOR
;
439 * Allocate attribute. We just pack these into an integer.
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
))
447 if (flags
& WSATTR_REVERSE
)
455 rcons_init(struct rcons
*rc
, int mrow
, int mcol
)
457 struct raster
*rp
= rc
->rc_sp
;
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) */
473 ((rp
->width
- rc
->rc_maxcol
* rc
->rc_font
->width
) / 2) & ~ALIGNMASK
;
475 (rp
->height
- rc
->rc_maxrow
* rc
->rc_font
->height
) / 2;
477 /* Raster width used for row copies */
478 rc
->rc_raswidth
= rc
->rc_maxcol
* rc
->rc_font
->width
;
479 if (rc
->rc_raswidth
& ALIGNMASK
) {
481 i
= (rc
->rc_raswidth
+ ALIGNMASK
) & ~ALIGNMASK
;
482 /* Make sure width isn't too wide */
483 if (rc
->rc_xorigin
+ i
<= rp
->width
)