omrasops.c revision 1.15 1 1.15 tsutsui /* $NetBSD: omrasops.c,v 1.15 2013/12/14 19:27:41 tsutsui Exp $ */
2 1.1 nisimura
3 1.1 nisimura /*-
4 1.1 nisimura * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 1.1 nisimura * All rights reserved.
6 1.1 nisimura *
7 1.1 nisimura * This code is derived from software contributed to The NetBSD Foundation
8 1.1 nisimura * by Tohru Nishimura.
9 1.1 nisimura *
10 1.1 nisimura * Redistribution and use in source and binary forms, with or without
11 1.1 nisimura * modification, are permitted provided that the following conditions
12 1.1 nisimura * are met:
13 1.1 nisimura * 1. Redistributions of source code must retain the above copyright
14 1.1 nisimura * notice, this list of conditions and the following disclaimer.
15 1.1 nisimura * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 nisimura * notice, this list of conditions and the following disclaimer in the
17 1.1 nisimura * documentation and/or other materials provided with the distribution.
18 1.1 nisimura *
19 1.1 nisimura * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 nisimura * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 nisimura * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 nisimura * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 nisimura * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 nisimura * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 nisimura * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 nisimura * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 nisimura * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 nisimura * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 nisimura * POSSIBILITY OF SUCH DAMAGE.
30 1.1 nisimura */
31 1.1 nisimura
32 1.1 nisimura #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
33 1.1 nisimura
34 1.15 tsutsui __KERNEL_RCSID(0, "$NetBSD: omrasops.c,v 1.15 2013/12/14 19:27:41 tsutsui Exp $");
35 1.1 nisimura
36 1.1 nisimura /*
37 1.1 nisimura * Designed speficically for 'm68k bitorder';
38 1.1 nisimura * - most significant byte is stored at lower address,
39 1.1 nisimura * - most significant bit is displayed at left most on screen.
40 1.12 tsutsui * Implementation relies on;
41 1.15 tsutsui * - first column is at 32bit aligned address,
42 1.1 nisimura * - font glyphs are stored in 32bit padded.
43 1.1 nisimura */
44 1.1 nisimura
45 1.1 nisimura #include <sys/param.h>
46 1.1 nisimura #include <sys/systm.h>
47 1.1 nisimura #include <sys/device.h>
48 1.1 nisimura
49 1.13 tsutsui #include <dev/wscons/wsconsio.h>
50 1.1 nisimura #include <dev/wscons/wsdisplayvar.h>
51 1.13 tsutsui #include <dev/rasops/rasops.h>
52 1.1 nisimura
53 1.13 tsutsui #include <arch/luna68k/dev/omrasopsvar.h>
54 1.1 nisimura
55 1.1 nisimura /* wscons emulator operations */
56 1.7 dsl static void om_cursor(void *, int, int, int);
57 1.7 dsl static int om_mapchar(void *, int, unsigned int *);
58 1.7 dsl static void om_putchar(void *, int, int, u_int, long);
59 1.7 dsl static void om_copycols(void *, int, int, int, int);
60 1.7 dsl static void om_copyrows(void *, int, int, int num);
61 1.7 dsl static void om_erasecols(void *, int, int, int, long);
62 1.7 dsl static void om_eraserows(void *, int, int, long);
63 1.7 dsl static int om_allocattr(void *, int, int, int, long *);
64 1.1 nisimura
65 1.1 nisimura #define ALL1BITS (~0U)
66 1.1 nisimura #define ALL0BITS (0U)
67 1.1 nisimura #define BLITWIDTH (32)
68 1.1 nisimura #define ALIGNMASK (0x1f)
69 1.1 nisimura #define BYTESDONE (4)
70 1.1 nisimura
71 1.11 tsutsui #define W(p) (*(uint32_t *)(p))
72 1.11 tsutsui #define R(p) (*(uint32_t *)((uint8_t *)(p) + 0x40000))
73 1.1 nisimura
74 1.1 nisimura /*
75 1.15 tsutsui * macros to handle unaligned bit copy ops.
76 1.15 tsutsui * See src/sys/dev/rasops/rasops_mask.h for MI version.
77 1.15 tsutsui * Also refer src/sys/arch/hp300/dev/maskbits.h.
78 1.15 tsutsui * (which was implemented for ancient src/sys/arch/hp300/dev/grf_hy.c)
79 1.15 tsutsui */
80 1.15 tsutsui
81 1.15 tsutsui /* luna68k version GETBITS() that gets w bits from bit x at psrc memory */
82 1.15 tsutsui #define FASTGETBITS(psrc, x, w, dst) \
83 1.15 tsutsui asm("bfextu %3{%1:%2},%0" \
84 1.15 tsutsui : "=d" (dst) \
85 1.15 tsutsui : "di" (x), "di" (w), "o" R(psrc))
86 1.15 tsutsui
87 1.15 tsutsui /* luna68k version PUTBITS() that puts w bits from bit x at pdst memory */
88 1.15 tsutsui /* XXX this macro assumes (x + w) <= 32 to handle unaligned residual bits */
89 1.15 tsutsui #define FASTPUTBITS(src, x, w, pdst) \
90 1.15 tsutsui do { \
91 1.15 tsutsui uint32_t __tmp; \
92 1.15 tsutsui __tmp = R(pdst); \
93 1.15 tsutsui asm("bfins %3,%0{%1:%2}" \
94 1.15 tsutsui : "+d" (__tmp) \
95 1.15 tsutsui : "di" (x), "di" (w), "d" (src)); \
96 1.15 tsutsui W(pdst) = __tmp; \
97 1.15 tsutsui } while (/* CONSTCOND */0)
98 1.15 tsutsui
99 1.15 tsutsui #define GETBITS(psrc, x, w, dst) FASTGETBITS(psrc, x, w, dst)
100 1.15 tsutsui #define PUTBITS(src, x, w, pdst) FASTPUTBITS(src, x, w, pdst)
101 1.15 tsutsui
102 1.15 tsutsui /*
103 1.1 nisimura * Blit a character at the specified co-ordinates.
104 1.1 nisimura */
105 1.1 nisimura static void
106 1.9 dsl om_putchar(void *cookie, int row, int startcol, u_int uc, long attr)
107 1.1 nisimura {
108 1.13 tsutsui struct rasops_info *ri = cookie;
109 1.5 tsutsui uint8_t *p;
110 1.1 nisimura int scanspan, startx, height, width, align, y;
111 1.11 tsutsui uint32_t lmask, rmask, glyph, inverse;
112 1.13 tsutsui int i;
113 1.13 tsutsui uint8_t *fb;
114 1.1 nisimura
115 1.13 tsutsui scanspan = ri->ri_stride;
116 1.13 tsutsui y = ri->ri_font->fontheight * row;
117 1.13 tsutsui startx = ri->ri_font->fontwidth * startcol;
118 1.13 tsutsui height = ri->ri_font->fontheight;
119 1.13 tsutsui fb = (uint8_t *)ri->ri_font->data +
120 1.13 tsutsui (uc - ri->ri_font->firstchar) * ri->ri_fontscale;
121 1.1 nisimura inverse = (attr != 0) ? ALL1BITS : ALL0BITS;
122 1.1 nisimura
123 1.13 tsutsui p = (uint8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
124 1.1 nisimura align = startx & ALIGNMASK;
125 1.13 tsutsui width = ri->ri_font->fontwidth + align;
126 1.1 nisimura lmask = ALL1BITS >> align;
127 1.1 nisimura rmask = ALL1BITS << (-width & ALIGNMASK);
128 1.1 nisimura if (width <= BLITWIDTH) {
129 1.1 nisimura lmask &= rmask;
130 1.1 nisimura while (height > 0) {
131 1.13 tsutsui glyph = 0;
132 1.13 tsutsui for (i = ri->ri_font->stride; i != 0; i--)
133 1.13 tsutsui glyph = (glyph << 8) | *fb++;
134 1.13 tsutsui glyph <<= (4 - ri->ri_font->stride) * NBBY;
135 1.1 nisimura glyph = (glyph >> align) ^ inverse;
136 1.1 nisimura W(p) = (R(p) & ~lmask) | (glyph & lmask);
137 1.1 nisimura p += scanspan;
138 1.1 nisimura height--;
139 1.1 nisimura }
140 1.11 tsutsui } else {
141 1.5 tsutsui uint8_t *q = p;
142 1.11 tsutsui uint32_t lhalf, rhalf;
143 1.1 nisimura
144 1.1 nisimura while (height > 0) {
145 1.13 tsutsui glyph = 0;
146 1.13 tsutsui for (i = ri->ri_font->stride; i != 0; i--)
147 1.13 tsutsui glyph = (glyph << 8) | *fb++;
148 1.13 tsutsui glyph <<= (4 - ri->ri_font->stride) * NBBY;
149 1.1 nisimura lhalf = (glyph >> align) ^ inverse;
150 1.1 nisimura W(p) = (R(p) & ~lmask) | (lhalf & lmask);
151 1.1 nisimura p += BYTESDONE;
152 1.1 nisimura rhalf = (glyph << (BLITWIDTH - align)) ^ inverse;
153 1.1 nisimura W(p) = (rhalf & rmask) | (R(p) & ~rmask);
154 1.1 nisimura
155 1.1 nisimura p = (q += scanspan);
156 1.1 nisimura height--;
157 1.1 nisimura }
158 1.1 nisimura }
159 1.1 nisimura }
160 1.1 nisimura
161 1.1 nisimura static void
162 1.9 dsl om_erasecols(void *cookie, int row, int startcol, int ncols, long attr)
163 1.1 nisimura {
164 1.13 tsutsui struct rasops_info *ri = cookie;
165 1.13 tsutsui uint8_t *p;
166 1.13 tsutsui int scanspan, startx, height, width, align, w, y;
167 1.13 tsutsui uint32_t lmask, rmask, fill;
168 1.13 tsutsui
169 1.13 tsutsui scanspan = ri->ri_stride;;
170 1.13 tsutsui fill = (attr != 0) ? ALL1BITS : ALL0BITS;
171 1.13 tsutsui y = ri->ri_font->fontheight * row;
172 1.13 tsutsui startx = ri->ri_font->fontwidth * startcol;
173 1.13 tsutsui height = ri->ri_font->fontheight;
174 1.13 tsutsui w = ri->ri_font->fontwidth * ncols;
175 1.1 nisimura fill = (attr != 0) ? ALL1BITS : ALL0BITS;
176 1.1 nisimura
177 1.13 tsutsui p = (uint8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
178 1.1 nisimura align = startx & ALIGNMASK;
179 1.1 nisimura width = w + align;
180 1.1 nisimura lmask = ALL1BITS >> align;
181 1.1 nisimura rmask = ALL1BITS << (-width & ALIGNMASK);
182 1.1 nisimura if (width <= BLITWIDTH) {
183 1.1 nisimura lmask &= rmask;
184 1.1 nisimura fill &= lmask;
185 1.1 nisimura while (height > 0) {
186 1.1 nisimura W(p) = (R(p) & ~lmask) | fill;
187 1.1 nisimura p += scanspan;
188 1.1 nisimura height--;
189 1.1 nisimura }
190 1.11 tsutsui } else {
191 1.5 tsutsui uint8_t *q = p;
192 1.1 nisimura while (height > 0) {
193 1.1 nisimura W(p) = (R(p) & ~lmask) | (fill & lmask);
194 1.1 nisimura width -= 2 * BLITWIDTH;
195 1.1 nisimura while (width > 0) {
196 1.1 nisimura p += BYTESDONE;
197 1.1 nisimura W(p) = fill;
198 1.1 nisimura width -= BLITWIDTH;
199 1.1 nisimura }
200 1.1 nisimura p += BYTESDONE;
201 1.1 nisimura W(p) = (fill & rmask) | (R(p) & ~rmask);
202 1.1 nisimura
203 1.1 nisimura p = (q += scanspan);
204 1.1 nisimura width = w + align;
205 1.1 nisimura height--;
206 1.1 nisimura }
207 1.1 nisimura }
208 1.1 nisimura }
209 1.1 nisimura
210 1.1 nisimura static void
211 1.9 dsl om_eraserows(void *cookie, int startrow, int nrows, long attr)
212 1.1 nisimura {
213 1.13 tsutsui struct rasops_info *ri = cookie;
214 1.5 tsutsui uint8_t *p, *q;
215 1.1 nisimura int scanspan, starty, height, width, w;
216 1.11 tsutsui uint32_t rmask, fill;
217 1.1 nisimura
218 1.13 tsutsui scanspan = ri->ri_stride;
219 1.13 tsutsui starty = ri->ri_font->fontheight * startrow;
220 1.13 tsutsui height = ri->ri_font->fontheight * nrows;
221 1.13 tsutsui w = ri->ri_emuwidth;
222 1.13 tsutsui fill = (attr != 0) ? ALL1BITS : ALL0BITS;
223 1.1 nisimura
224 1.13 tsutsui p = (uint8_t *)ri->ri_bits + starty * scanspan;
225 1.1 nisimura width = w;
226 1.13 tsutsui rmask = ALL1BITS << (-width & ALIGNMASK);
227 1.1 nisimura q = p;
228 1.1 nisimura while (height > 0) {
229 1.1 nisimura W(p) = fill; /* always aligned */
230 1.1 nisimura width -= 2 * BLITWIDTH;
231 1.1 nisimura while (width > 0) {
232 1.1 nisimura p += BYTESDONE;
233 1.1 nisimura W(p) = fill;
234 1.1 nisimura width -= BLITWIDTH;
235 1.1 nisimura }
236 1.1 nisimura p += BYTESDONE;
237 1.1 nisimura W(p) = (fill & rmask) | (R(p) & ~rmask);
238 1.1 nisimura p = (q += scanspan);
239 1.1 nisimura width = w;
240 1.1 nisimura height--;
241 1.1 nisimura }
242 1.1 nisimura }
243 1.1 nisimura
244 1.1 nisimura static void
245 1.9 dsl om_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
246 1.1 nisimura {
247 1.13 tsutsui struct rasops_info *ri = cookie;
248 1.13 tsutsui uint8_t *p, *q;
249 1.1 nisimura int scanspan, offset, srcy, height, width, w;
250 1.13 tsutsui uint32_t rmask;
251 1.13 tsutsui
252 1.13 tsutsui scanspan = ri->ri_stride;
253 1.13 tsutsui height = ri->ri_font->fontheight * nrows;
254 1.13 tsutsui offset = (dstrow - srcrow) * scanspan * ri->ri_font->fontheight;
255 1.13 tsutsui srcy = ri->ri_font->fontheight * srcrow;
256 1.1 nisimura if (srcrow < dstrow && srcrow + nrows > dstrow) {
257 1.1 nisimura scanspan = -scanspan;
258 1.14 tsutsui srcy = srcy + height - 1;
259 1.1 nisimura }
260 1.1 nisimura
261 1.13 tsutsui p = (uint8_t *)ri->ri_bits + srcy * ri->ri_stride;
262 1.13 tsutsui w = ri->ri_emuwidth;
263 1.1 nisimura width = w;
264 1.1 nisimura rmask = ALL1BITS << (-width & ALIGNMASK);
265 1.1 nisimura q = p;
266 1.1 nisimura while (height > 0) {
267 1.1 nisimura W(p + offset) = R(p); /* always aligned */
268 1.1 nisimura width -= 2 * BLITWIDTH;
269 1.1 nisimura while (width > 0) {
270 1.1 nisimura p += BYTESDONE;
271 1.1 nisimura W(p + offset) = R(p);
272 1.1 nisimura width -= BLITWIDTH;
273 1.1 nisimura }
274 1.1 nisimura p += BYTESDONE;
275 1.1 nisimura W(p + offset) = (R(p) & rmask) | (R(p + offset) & ~rmask);
276 1.1 nisimura
277 1.1 nisimura p = (q += scanspan);
278 1.1 nisimura width = w;
279 1.1 nisimura height--;
280 1.1 nisimura }
281 1.1 nisimura }
282 1.1 nisimura
283 1.1 nisimura static void
284 1.9 dsl om_copycols(void *cookie, int startrow, int srccol, int dstcol, int ncols)
285 1.1 nisimura {
286 1.13 tsutsui struct rasops_info *ri = cookie;
287 1.15 tsutsui uint8_t *sp, *dp, *sq, *dq, *basep;
288 1.15 tsutsui int scanspan, height, w, y, srcx, dstx;
289 1.15 tsutsui int sb, eb, db, sboff, full, cnt, lnum, rnum;
290 1.15 tsutsui uint32_t lmask, rmask, tmp;
291 1.15 tsutsui bool sbover;
292 1.1 nisimura
293 1.13 tsutsui scanspan = ri->ri_stride;
294 1.13 tsutsui y = ri->ri_font->fontheight * startrow;
295 1.13 tsutsui srcx = ri->ri_font->fontwidth * srccol;
296 1.13 tsutsui dstx = ri->ri_font->fontwidth * dstcol;
297 1.13 tsutsui height = ri->ri_font->fontheight;
298 1.13 tsutsui w = ri->ri_font->fontwidth * ncols;
299 1.13 tsutsui basep = (uint8_t *)ri->ri_bits + y * scanspan;
300 1.1 nisimura
301 1.15 tsutsui sb = srcx & ALIGNMASK;
302 1.15 tsutsui db = dstx & ALIGNMASK;
303 1.1 nisimura
304 1.15 tsutsui if (db + w <= BLITWIDTH) {
305 1.15 tsutsui /* Destination is contained within a single word */
306 1.15 tsutsui sp = basep + (srcx / 32) * 4;
307 1.15 tsutsui dp = basep + (dstx / 32) * 4;
308 1.1 nisimura
309 1.1 nisimura while (height > 0) {
310 1.15 tsutsui GETBITS(sp, sb, w, tmp);
311 1.15 tsutsui PUTBITS(tmp, db, w, dp);
312 1.1 nisimura dp += scanspan;
313 1.1 nisimura sp += scanspan;
314 1.1 nisimura height--;
315 1.1 nisimura }
316 1.15 tsutsui return;
317 1.1 nisimura }
318 1.1 nisimura
319 1.15 tsutsui lmask = (db == 0) ? 0 : ALL1BITS >> db;
320 1.15 tsutsui eb = (db + w) & ALIGNMASK;
321 1.15 tsutsui rmask = (eb == 0) ? 0 : ALL1BITS << (32 - eb);
322 1.15 tsutsui lnum = (32 - db) & ALIGNMASK;
323 1.15 tsutsui rnum = (dstx + w) & ALIGNMASK;
324 1.15 tsutsui
325 1.15 tsutsui if (lmask != 0)
326 1.15 tsutsui full = (w - (32 - db)) / 32;
327 1.15 tsutsui else
328 1.15 tsutsui full = w / 32;
329 1.15 tsutsui
330 1.15 tsutsui sbover = (sb + lnum) >= 32;
331 1.15 tsutsui
332 1.15 tsutsui if (dstcol < srccol || srccol + ncols < dstcol) {
333 1.15 tsutsui /* copy forward (left-to-right) */
334 1.15 tsutsui sp = basep + (srcx / 32) * 4;
335 1.15 tsutsui dp = basep + (dstx / 32) * 4;
336 1.15 tsutsui
337 1.15 tsutsui if (lmask != 0) {
338 1.15 tsutsui sboff = sb + lnum;
339 1.15 tsutsui if (sboff >= 32)
340 1.15 tsutsui sboff -= 32;
341 1.15 tsutsui } else
342 1.15 tsutsui sboff = sb;
343 1.15 tsutsui
344 1.15 tsutsui sq = sp;
345 1.15 tsutsui dq = dp;
346 1.1 nisimura while (height > 0) {
347 1.15 tsutsui if (lmask != 0) {
348 1.15 tsutsui GETBITS(sp, sb, lnum, tmp);
349 1.15 tsutsui PUTBITS(tmp, db, lnum, dp);
350 1.15 tsutsui dp += BYTESDONE;
351 1.15 tsutsui if (sbover)
352 1.15 tsutsui sp += BYTESDONE;
353 1.15 tsutsui }
354 1.15 tsutsui
355 1.15 tsutsui for (cnt = full; cnt; cnt--) {
356 1.15 tsutsui GETBITS(sp, sboff, 32, tmp);
357 1.15 tsutsui W(dp) = tmp;
358 1.1 nisimura sp += BYTESDONE;
359 1.1 nisimura dp += BYTESDONE;
360 1.1 nisimura }
361 1.15 tsutsui
362 1.15 tsutsui if (rmask != 0) {
363 1.15 tsutsui GETBITS(sp, sboff, rnum, tmp);
364 1.15 tsutsui PUTBITS(tmp, 0, rnum, dp);
365 1.15 tsutsui }
366 1.15 tsutsui
367 1.1 nisimura sp = (sq += scanspan);
368 1.1 nisimura dp = (dq += scanspan);
369 1.1 nisimura height--;
370 1.1 nisimura }
371 1.15 tsutsui } else {
372 1.15 tsutsui /* copy backward (right-to-left) */
373 1.15 tsutsui sp = basep + ((srcx + w) / 32) * 4;
374 1.15 tsutsui dp = basep + ((dstx + w) / 32) * 4;
375 1.15 tsutsui
376 1.15 tsutsui sboff = (srcx + w) & ALIGNMASK;
377 1.15 tsutsui sboff -= rnum;
378 1.15 tsutsui if (sboff < 0) {
379 1.15 tsutsui sp -= BYTESDONE;
380 1.15 tsutsui sboff += 32;
381 1.15 tsutsui }
382 1.15 tsutsui
383 1.15 tsutsui sq = sp;
384 1.15 tsutsui dq = dp;
385 1.1 nisimura while (height > 0) {
386 1.15 tsutsui if (rnum != 0) {
387 1.15 tsutsui GETBITS(sp, sboff, rnum, tmp);
388 1.15 tsutsui PUTBITS(tmp, 0, rnum, dp);
389 1.15 tsutsui }
390 1.15 tsutsui
391 1.15 tsutsui for (cnt = full; cnt; cnt--) {
392 1.1 nisimura sp -= BYTESDONE;
393 1.1 nisimura dp -= BYTESDONE;
394 1.15 tsutsui GETBITS(sp, sboff, 32, tmp);
395 1.15 tsutsui W(dp) = tmp;
396 1.15 tsutsui }
397 1.15 tsutsui
398 1.15 tsutsui if (lmask != 0) {
399 1.15 tsutsui if (sbover)
400 1.15 tsutsui sp -= BYTESDONE;
401 1.15 tsutsui dp -= BYTESDONE;
402 1.15 tsutsui GETBITS(sp, sb, lnum, tmp);
403 1.15 tsutsui PUTBITS(tmp, db, lnum, dp);
404 1.1 nisimura }
405 1.1 nisimura
406 1.1 nisimura sp = (sq += scanspan);
407 1.1 nisimura dp = (dq += scanspan);
408 1.1 nisimura height--;
409 1.1 nisimura }
410 1.1 nisimura }
411 1.1 nisimura }
412 1.1 nisimura
413 1.1 nisimura /*
414 1.1 nisimura * Map a character.
415 1.1 nisimura */
416 1.1 nisimura static int
417 1.8 dsl om_mapchar(void *cookie, int c, u_int *cp)
418 1.1 nisimura {
419 1.13 tsutsui struct rasops_info *ri = cookie;
420 1.13 tsutsui struct wsdisplay_font *wf = ri->ri_font;
421 1.11 tsutsui
422 1.13 tsutsui if (wf->encoding != WSDISPLAY_FONTENC_ISO) {
423 1.13 tsutsui c = wsfont_map_unichar(wf, c);
424 1.13 tsutsui
425 1.13 tsutsui if (c < 0)
426 1.13 tsutsui goto fail;
427 1.1 nisimura }
428 1.13 tsutsui if (c < wf->firstchar || c >= (wf->firstchar + wf->numchars))
429 1.13 tsutsui goto fail;
430 1.13 tsutsui
431 1.13 tsutsui *cp = c;
432 1.13 tsutsui return 5;
433 1.13 tsutsui
434 1.13 tsutsui fail:
435 1.1 nisimura *cp = ' ';
436 1.11 tsutsui return 0;
437 1.1 nisimura }
438 1.1 nisimura
439 1.1 nisimura /*
440 1.1 nisimura * Position|{enable|disable} the cursor at the specified location.
441 1.1 nisimura */
442 1.1 nisimura static void
443 1.9 dsl om_cursor(void *cookie, int on, int row, int col)
444 1.1 nisimura {
445 1.13 tsutsui struct rasops_info *ri = cookie;
446 1.5 tsutsui uint8_t *p;
447 1.1 nisimura int scanspan, startx, height, width, align, y;
448 1.11 tsutsui uint32_t lmask, rmask, image;
449 1.1 nisimura
450 1.1 nisimura if (!on) {
451 1.1 nisimura /* make sure it's on */
452 1.13 tsutsui if ((ri->ri_flg & RI_CURSOR) == 0)
453 1.1 nisimura return;
454 1.1 nisimura
455 1.13 tsutsui row = ri->ri_crow;
456 1.13 tsutsui col = ri->ri_ccol;
457 1.1 nisimura } else {
458 1.1 nisimura /* unpaint the old copy. */
459 1.13 tsutsui ri->ri_crow = row;
460 1.13 tsutsui ri->ri_ccol = col;
461 1.1 nisimura }
462 1.1 nisimura
463 1.13 tsutsui scanspan = ri->ri_stride;
464 1.13 tsutsui y = ri->ri_font->fontheight * row;
465 1.13 tsutsui startx = ri->ri_font->fontwidth * col;
466 1.13 tsutsui height = ri->ri_font->fontheight;
467 1.1 nisimura
468 1.13 tsutsui p = (uint8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
469 1.1 nisimura align = startx & ALIGNMASK;
470 1.13 tsutsui width = ri->ri_font->fontwidth + align;
471 1.1 nisimura lmask = ALL1BITS >> align;
472 1.1 nisimura rmask = ALL1BITS << (-width & ALIGNMASK);
473 1.1 nisimura if (width <= BLITWIDTH) {
474 1.1 nisimura lmask &= rmask;
475 1.1 nisimura while (height > 0) {
476 1.1 nisimura image = R(p);
477 1.1 nisimura W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask);
478 1.1 nisimura p += scanspan;
479 1.1 nisimura height--;
480 1.1 nisimura }
481 1.11 tsutsui } else {
482 1.5 tsutsui uint8_t *q = p;
483 1.1 nisimura
484 1.1 nisimura while (height > 0) {
485 1.1 nisimura image = R(p);
486 1.1 nisimura W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask);
487 1.1 nisimura p += BYTESDONE;
488 1.1 nisimura image = R(p);
489 1.1 nisimura W(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask);
490 1.1 nisimura
491 1.1 nisimura p = (q += scanspan);
492 1.1 nisimura height--;
493 1.1 nisimura }
494 1.1 nisimura }
495 1.13 tsutsui ri->ri_flg ^= RI_CURSOR;
496 1.1 nisimura }
497 1.1 nisimura
498 1.1 nisimura /*
499 1.1 nisimura * Allocate attribute. We just pack these into an integer.
500 1.1 nisimura */
501 1.1 nisimura static int
502 1.9 dsl om_allocattr(void *id, int fg, int bg, int flags, long *attrp)
503 1.1 nisimura {
504 1.11 tsutsui
505 1.1 nisimura if (flags & (WSATTR_HILIT | WSATTR_BLINK |
506 1.13 tsutsui WSATTR_UNDERLINE | WSATTR_WSCOLORS))
507 1.11 tsutsui return EINVAL;
508 1.1 nisimura if (flags & WSATTR_REVERSE)
509 1.1 nisimura *attrp = 1;
510 1.1 nisimura else
511 1.1 nisimura *attrp = 0;
512 1.11 tsutsui return 0;
513 1.1 nisimura }
514 1.1 nisimura
515 1.13 tsutsui /*
516 1.13 tsutsui * Init subset of rasops(9) for omrasops.
517 1.13 tsutsui */
518 1.13 tsutsui int
519 1.13 tsutsui omrasops_init(struct rasops_info *ri, int wantrows, int wantcols)
520 1.1 nisimura {
521 1.13 tsutsui int wsfcookie, bpp;
522 1.13 tsutsui
523 1.13 tsutsui if (wantrows == 0)
524 1.13 tsutsui wantrows = 34;
525 1.13 tsutsui if (wantrows < 10)
526 1.13 tsutsui wantrows = 10;
527 1.13 tsutsui if (wantcols == 0)
528 1.13 tsutsui wantcols = 80;
529 1.13 tsutsui if (wantcols < 20)
530 1.13 tsutsui wantcols = 20;
531 1.13 tsutsui
532 1.13 tsutsui /* Use default font */
533 1.13 tsutsui wsfont_init();
534 1.13 tsutsui wsfcookie = wsfont_find(NULL, 0, 0, 0, WSDISPLAY_FONTORDER_L2R,
535 1.13 tsutsui WSDISPLAY_FONTORDER_L2R, WSFONT_FIND_BITMAP);
536 1.13 tsutsui if (wsfcookie < 0)
537 1.13 tsutsui panic("%s: no font available", __func__);
538 1.13 tsutsui if (wsfont_lock(wsfcookie, &ri->ri_font))
539 1.13 tsutsui panic("%s: unable to lock font", __func__);
540 1.13 tsutsui ri->ri_wsfcookie = wsfcookie;
541 1.13 tsutsui
542 1.13 tsutsui KASSERT(ri->ri_font->fontwidth > 4 && ri->ri_font->fontwidth <= 32);
543 1.13 tsutsui
544 1.13 tsutsui bpp = ri->ri_depth;
545 1.13 tsutsui
546 1.13 tsutsui /* Now constrain what they get */
547 1.13 tsutsui ri->ri_emuwidth = ri->ri_font->fontwidth * wantcols;
548 1.13 tsutsui ri->ri_emuheight = ri->ri_font->fontheight * wantrows;
549 1.13 tsutsui if (ri->ri_emuwidth > ri->ri_width)
550 1.13 tsutsui ri->ri_emuwidth = ri->ri_width;
551 1.13 tsutsui if (ri->ri_emuheight > ri->ri_height)
552 1.13 tsutsui ri->ri_emuheight = ri->ri_height;
553 1.13 tsutsui
554 1.13 tsutsui /* Reduce width until aligned on a 32-bit boundary */
555 1.13 tsutsui while ((ri->ri_emuwidth * bpp & 31) != 0)
556 1.13 tsutsui ri->ri_emuwidth--;
557 1.13 tsutsui
558 1.13 tsutsui ri->ri_cols = ri->ri_emuwidth / ri->ri_font->fontwidth;
559 1.13 tsutsui ri->ri_rows = ri->ri_emuheight / ri->ri_font->fontheight;
560 1.13 tsutsui ri->ri_emustride = ri->ri_emuwidth * bpp >> 3;
561 1.13 tsutsui ri->ri_delta = ri->ri_stride - ri->ri_emustride;
562 1.13 tsutsui ri->ri_ccol = 0;
563 1.13 tsutsui ri->ri_crow = 0;
564 1.13 tsutsui ri->ri_pelbytes = bpp >> 3;
565 1.13 tsutsui
566 1.13 tsutsui ri->ri_xscale = (ri->ri_font->fontwidth * bpp) >> 3;
567 1.13 tsutsui ri->ri_yscale = ri->ri_font->fontheight * ri->ri_stride;
568 1.13 tsutsui ri->ri_fontscale = ri->ri_font->fontheight * ri->ri_font->stride;
569 1.13 tsutsui
570 1.13 tsutsui /* Clear the entire display */
571 1.13 tsutsui if ((ri->ri_flg & RI_CLEAR) != 0)
572 1.13 tsutsui memset(ri->ri_bits, 0, ri->ri_stride * ri->ri_height);
573 1.13 tsutsui
574 1.13 tsutsui /* Now centre our window if needs be */
575 1.13 tsutsui ri->ri_origbits = ri->ri_bits;
576 1.13 tsutsui
577 1.13 tsutsui if ((ri->ri_flg & RI_CENTER) != 0) {
578 1.13 tsutsui ri->ri_bits += (((ri->ri_width * bpp >> 3) -
579 1.13 tsutsui ri->ri_emustride) >> 1) & ~3;
580 1.13 tsutsui ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
581 1.13 tsutsui ri->ri_stride;
582 1.13 tsutsui ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits)
583 1.13 tsutsui / ri->ri_stride;
584 1.13 tsutsui ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits)
585 1.13 tsutsui % ri->ri_stride) * 8 / bpp);
586 1.13 tsutsui } else
587 1.13 tsutsui ri->ri_xorigin = ri->ri_yorigin = 0;
588 1.13 tsutsui
589 1.13 tsutsui /* fill our own emulops */
590 1.13 tsutsui ri->ri_ops.cursor = om_cursor;
591 1.13 tsutsui ri->ri_ops.mapchar = om_mapchar;
592 1.13 tsutsui ri->ri_ops.putchar = om_putchar;
593 1.13 tsutsui ri->ri_ops.copycols = om_copycols;
594 1.13 tsutsui ri->ri_ops.erasecols = om_erasecols;
595 1.13 tsutsui ri->ri_ops.copyrows = om_copyrows;
596 1.13 tsutsui ri->ri_ops.eraserows = om_eraserows;
597 1.13 tsutsui ri->ri_ops.allocattr = om_allocattr;
598 1.13 tsutsui ri->ri_caps = WSSCREEN_REVERSE;
599 1.13 tsutsui
600 1.13 tsutsui ri->ri_flg |= RI_CFGDONE;
601 1.1 nisimura
602 1.13 tsutsui return 0;
603 1.1 nisimura }
604