diofb.c revision 1.4 1 1.4 christos /* $NetBSD: diofb.c,v 1.4 2014/03/24 19:42:58 christos Exp $ */
2 1.1 tsutsui /* $OpenBSD: diofb.c,v 1.18 2010/12/26 15:40:59 miod Exp $ */
3 1.1 tsutsui
4 1.1 tsutsui /*
5 1.1 tsutsui * Copyright (c) 2005, Miodrag Vallat
6 1.1 tsutsui *
7 1.1 tsutsui * Redistribution and use in source and binary forms, with or without
8 1.1 tsutsui * modification, are permitted provided that the following conditions
9 1.1 tsutsui * are met:
10 1.1 tsutsui * 1. Redistributions of source code must retain the above copyright
11 1.1 tsutsui * notice, this list of conditions and the following disclaimer.
12 1.1 tsutsui * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 tsutsui * notice, this list of conditions and the following disclaimer in the
14 1.1 tsutsui * documentation and/or other materials provided with the distribution.
15 1.1 tsutsui *
16 1.1 tsutsui * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.1 tsutsui * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 1.1 tsutsui * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 1.1 tsutsui * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 1.1 tsutsui * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 1.1 tsutsui * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 1.1 tsutsui * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 1.1 tsutsui * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 1.1 tsutsui * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 1.1 tsutsui * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 tsutsui * POSSIBILITY OF SUCH DAMAGE.
27 1.1 tsutsui */
28 1.1 tsutsui /*
29 1.1 tsutsui * Copyright (c) 1988 University of Utah.
30 1.1 tsutsui * Copyright (c) 1990, 1993
31 1.1 tsutsui * The Regents of the University of California. All rights reserved.
32 1.1 tsutsui *
33 1.1 tsutsui * This code is derived from software contributed to Berkeley by
34 1.1 tsutsui * the Systems Programming Group of the University of Utah Computer
35 1.1 tsutsui * Science Department.
36 1.1 tsutsui *
37 1.1 tsutsui * Redistribution and use in source and binary forms, with or without
38 1.1 tsutsui * modification, are permitted provided that the following conditions
39 1.1 tsutsui * are met:
40 1.1 tsutsui * 1. Redistributions of source code must retain the above copyright
41 1.1 tsutsui * notice, this list of conditions and the following disclaimer.
42 1.1 tsutsui * 2. Redistributions in binary form must reproduce the above copyright
43 1.1 tsutsui * notice, this list of conditions and the following disclaimer in the
44 1.1 tsutsui * documentation and/or other materials provided with the distribution.
45 1.1 tsutsui * 3. Neither the name of the University nor the names of its contributors
46 1.1 tsutsui * may be used to endorse or promote products derived from this software
47 1.1 tsutsui * without specific prior written permission.
48 1.1 tsutsui *
49 1.1 tsutsui * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 1.1 tsutsui * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 1.1 tsutsui * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 1.1 tsutsui * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 1.1 tsutsui * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 1.1 tsutsui * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 1.1 tsutsui * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 1.1 tsutsui * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 1.1 tsutsui * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 1.1 tsutsui * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 1.1 tsutsui * SUCH DAMAGE.
60 1.1 tsutsui */
61 1.1 tsutsui
62 1.1 tsutsui #include <sys/param.h>
63 1.1 tsutsui #include <sys/conf.h>
64 1.1 tsutsui #include <sys/proc.h>
65 1.1 tsutsui #include <sys/ioctl.h>
66 1.1 tsutsui #include <sys/tty.h>
67 1.1 tsutsui #include <sys/systm.h>
68 1.1 tsutsui #include <sys/device.h>
69 1.1 tsutsui #include <sys/bus.h>
70 1.1 tsutsui #include <sys/cpu.h>
71 1.1 tsutsui
72 1.1 tsutsui #include <machine/autoconf.h>
73 1.1 tsutsui
74 1.1 tsutsui #include <dev/wscons/wsconsio.h>
75 1.1 tsutsui #include <dev/wscons/wsdisplayvar.h>
76 1.1 tsutsui #include <dev/rasops/rasops.h>
77 1.1 tsutsui
78 1.1 tsutsui #include <hp300/dev/dioreg.h>
79 1.1 tsutsui #include <hp300/dev/diovar.h>
80 1.1 tsutsui #include <hp300/dev/diofbreg.h>
81 1.1 tsutsui #include <hp300/dev/diofbvar.h>
82 1.1 tsutsui
83 1.2 tsutsui static void diofb_do_cursor(struct rasops_info *);
84 1.2 tsutsui static void diofb_copycols(void *, int, int, int, int);
85 1.2 tsutsui static void diofb_erasecols(void *, int, int, int, long);
86 1.2 tsutsui static void diofb_copyrows(void *, int, int, int);
87 1.2 tsutsui static void diofb_eraserows(void *, int, int, long);
88 1.2 tsutsui static int diofb_allocattr(void *, int, int, int, long *);
89 1.1 tsutsui
90 1.1 tsutsui struct diofb diofb_cn;
91 1.1 tsutsui
92 1.1 tsutsui /*
93 1.1 tsutsui * Frame buffer geometry initialization
94 1.1 tsutsui */
95 1.1 tsutsui
96 1.1 tsutsui int
97 1.1 tsutsui diofb_fbinquire(struct diofb *fb, int scode, struct diofbreg *fbr)
98 1.1 tsutsui {
99 1.1 tsutsui int fboff, regsize;
100 1.1 tsutsui
101 1.1 tsutsui if (ISIIOVA(fbr))
102 1.1 tsutsui fb->regaddr = (uint8_t *)IIOP(fbr);
103 1.1 tsutsui else
104 1.1 tsutsui fb->regaddr = dio_scodetopa(scode);
105 1.1 tsutsui
106 1.1 tsutsui if (fb->fbwidth == 0 || fb->fbheight == 0) {
107 1.1 tsutsui fb->fbwidth = (fbr->fbwmsb << 8) | fbr->fbwlsb;
108 1.1 tsutsui fb->fbheight = (fbr->fbhmsb << 8) | fbr->fbhlsb;
109 1.1 tsutsui }
110 1.1 tsutsui fb->fbsize = fb->fbwidth * fb->fbheight;
111 1.1 tsutsui
112 1.1 tsutsui fb->regkva = (uint8_t *)fbr;
113 1.1 tsutsui fboff = (fbr->fbomsb << 8) | fbr->fbolsb;
114 1.1 tsutsui fb->fbaddr = (uint8_t *) (*((uint8_t *)fbr + fboff) << 16);
115 1.1 tsutsui
116 1.1 tsutsui if (fb->regaddr >= (uint8_t *)DIOII_BASE) {
117 1.1 tsutsui /*
118 1.1 tsutsui * For DIO-II space the fbaddr just computed is
119 1.1 tsutsui * the offset from the select code base (regaddr)
120 1.1 tsutsui * of the framebuffer. Hence it is also implicitly
121 1.1 tsutsui * the size of the set.
122 1.1 tsutsui */
123 1.1 tsutsui regsize = (uintptr_t)fb->fbaddr;
124 1.1 tsutsui fb->fbaddr = fb->regaddr + (uintptr_t)fb->fbaddr;
125 1.1 tsutsui fb->fbkva = (uint8_t *)fbr + regsize;
126 1.1 tsutsui } else {
127 1.1 tsutsui /*
128 1.1 tsutsui * For internal or DIO-I space we need to map the separate
129 1.1 tsutsui * framebuffer.
130 1.1 tsutsui */
131 1.1 tsutsui fb->fbkva = iomap(fb->fbaddr, fb->fbsize);
132 1.1 tsutsui if (fb->fbkva == NULL)
133 1.2 tsutsui return ENOMEM;
134 1.1 tsutsui }
135 1.1 tsutsui if (fb->dwidth == 0 || fb->dheight == 0) {
136 1.1 tsutsui fb->dwidth = (fbr->dwmsb << 8) | fbr->dwlsb;
137 1.1 tsutsui fb->dheight = (fbr->dhmsb << 8) | fbr->dhlsb;
138 1.1 tsutsui }
139 1.1 tsutsui
140 1.1 tsutsui /*
141 1.1 tsutsui * Some displays, such as the DaVinci, appear to return a display
142 1.1 tsutsui * height larger than the frame buffer height.
143 1.1 tsutsui */
144 1.1 tsutsui if (fb->dwidth > fb->fbwidth)
145 1.1 tsutsui fb->dwidth = fb->fbwidth;
146 1.1 tsutsui if (fb->dheight > fb->fbheight)
147 1.1 tsutsui fb->dheight = fb->fbheight;
148 1.1 tsutsui
149 1.1 tsutsui fb->planes = fbr->num_planes;
150 1.1 tsutsui if (fb->planes > 8)
151 1.1 tsutsui fb->planes = 8;
152 1.1 tsutsui fb->planemask = (1 << fb->planes) - 1;
153 1.1 tsutsui
154 1.1 tsutsui fb->mapmode = WSDISPLAYIO_MODE_DUMBFB;
155 1.1 tsutsui
156 1.2 tsutsui return 0;
157 1.1 tsutsui }
158 1.1 tsutsui
159 1.1 tsutsui /*
160 1.1 tsutsui * Frame buffer rasops and colormap setup
161 1.1 tsutsui */
162 1.1 tsutsui
163 1.1 tsutsui void
164 1.1 tsutsui diofb_fbsetup(struct diofb *fb)
165 1.1 tsutsui {
166 1.1 tsutsui struct rasops_info *ri = &fb->ri;
167 1.1 tsutsui
168 1.1 tsutsui /*
169 1.1 tsutsui * Pretend we are an 8bpp frame buffer, unless ri_depth is already
170 1.1 tsutsui * initialized, since this is how it is supposed to be addressed.
171 1.1 tsutsui * (Hyperion forces 1bpp because it is really 1bpp addressed).
172 1.1 tsutsui */
173 1.1 tsutsui if (ri->ri_depth == 0)
174 1.1 tsutsui ri->ri_depth = 8;
175 1.1 tsutsui ri->ri_stride = (fb->fbwidth * ri->ri_depth) / 8;
176 1.1 tsutsui
177 1.1 tsutsui ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
178 1.1 tsutsui /* We don't really support colors on less than 4bpp frame buffers */
179 1.1 tsutsui if (fb->planes < 4)
180 1.1 tsutsui ri->ri_flg |= RI_FORCEMONO;
181 1.1 tsutsui if (fb == &diofb_cn)
182 1.1 tsutsui ri->ri_flg |= RI_NO_AUTO;
183 1.1 tsutsui ri->ri_bits = fb->fbkva;
184 1.1 tsutsui ri->ri_width = fb->dwidth;
185 1.1 tsutsui ri->ri_height = fb->dheight;
186 1.1 tsutsui ri->ri_hw = fb;
187 1.1 tsutsui
188 1.1 tsutsui /*
189 1.1 tsutsui * Ask for an unholy big display, rasops will trim this to more
190 1.1 tsutsui * reasonable values.
191 1.1 tsutsui */
192 1.1 tsutsui rasops_init(ri, 160, 160);
193 1.1 tsutsui
194 1.1 tsutsui diofb_resetcmap(fb);
195 1.1 tsutsui
196 1.1 tsutsui /*
197 1.1 tsutsui * For low depth frame buffers, since we have faked a 8bpp frame buffer
198 1.1 tsutsui * to rasops, we actually have to remove capabilities.
199 1.1 tsutsui */
200 1.1 tsutsui if (fb->planes == 4) {
201 1.1 tsutsui ri->ri_ops.allocattr = diofb_allocattr;
202 1.1 tsutsui ri->ri_caps &= ~WSSCREEN_HILIT;
203 1.1 tsutsui }
204 1.1 tsutsui
205 1.1 tsutsui ri->ri_ops.copycols = diofb_copycols;
206 1.1 tsutsui ri->ri_ops.erasecols = diofb_erasecols;
207 1.1 tsutsui if (ri->ri_depth != 1) {
208 1.1 tsutsui ri->ri_ops.copyrows = diofb_copyrows;
209 1.1 tsutsui ri->ri_ops.eraserows = diofb_eraserows;
210 1.1 tsutsui ri->ri_do_cursor = diofb_do_cursor;
211 1.1 tsutsui }
212 1.1 tsutsui
213 1.1 tsutsui /* Clear entire display, including non visible areas */
214 1.1 tsutsui (*fb->bmv)(fb, 0, 0, 0, 0, fb->fbwidth, fb->fbheight, RR_CLEAR, 0xff);
215 1.1 tsutsui
216 1.1 tsutsui fb->wsd.name = fb->wsdname;
217 1.1 tsutsui fb->wsd.ncols = ri->ri_cols;
218 1.1 tsutsui fb->wsd.nrows = ri->ri_rows;
219 1.1 tsutsui fb->wsd.textops = &ri->ri_ops;
220 1.1 tsutsui fb->wsd.fontwidth = ri->ri_font->fontwidth;
221 1.1 tsutsui fb->wsd.fontheight = ri->ri_font->fontheight;
222 1.1 tsutsui fb->wsd.capabilities = ri->ri_caps;
223 1.1 tsutsui strlcpy(fb->wsdname, "std", sizeof(fb->wsdname));
224 1.1 tsutsui }
225 1.1 tsutsui
226 1.1 tsutsui /*
227 1.1 tsutsui * Setup default emulation mode colormap
228 1.1 tsutsui */
229 1.1 tsutsui void
230 1.1 tsutsui diofb_resetcmap(struct diofb *fb)
231 1.1 tsutsui {
232 1.1 tsutsui const u_char *color;
233 1.1 tsutsui u_int i;
234 1.1 tsutsui
235 1.1 tsutsui /* start with the rasops colormap */
236 1.1 tsutsui color = (const u_char *)rasops_cmap;
237 1.1 tsutsui for (i = 0; i < 256; i++) {
238 1.1 tsutsui fb->cmap.r[i] = *color++;
239 1.1 tsutsui fb->cmap.g[i] = *color++;
240 1.1 tsutsui fb->cmap.b[i] = *color++;
241 1.1 tsutsui }
242 1.1 tsutsui
243 1.1 tsutsui /*
244 1.1 tsutsui * Tweak colormap
245 1.1 tsutsui *
246 1.1 tsutsui * Due to the way rasops cursor work, we need to provide
247 1.1 tsutsui * copies of the 8 or 16 basic colors at extra locations
248 1.1 tsutsui * in 4bpp and 6bpp mode. This is because missing planes
249 1.1 tsutsui * accept writes but read back as zero.
250 1.1 tsutsui *
251 1.1 tsutsui * So, in 6bpp mode:
252 1.1 tsutsui * 00 gets inverted to ff, read back as 3f
253 1.1 tsutsui * 3f gets inverted to c0, read back as 00
254 1.1 tsutsui * and in 4bpp mode:
255 1.1 tsutsui * 00 gets inverted to ff, read back as 0f
256 1.1 tsutsui * 0f gets inverted to f0, read back as 00
257 1.1 tsutsui */
258 1.1 tsutsui
259 1.1 tsutsui switch (fb->planes) {
260 1.1 tsutsui case 6:
261 1.1 tsutsui /*
262 1.1 tsutsui * 00-0f normal colors
263 1.1 tsutsui * 30-3f inverted colors
264 1.1 tsutsui * c0-cf normal colors
265 1.1 tsutsui * f0-ff inverted colors
266 1.1 tsutsui */
267 1.1 tsutsui memcpy(fb->cmap.r + 0xc0, fb->cmap.r + 0x00, 0x10);
268 1.1 tsutsui memcpy(fb->cmap.g + 0xc0, fb->cmap.g + 0x00, 0x10);
269 1.1 tsutsui memcpy(fb->cmap.b + 0xc0, fb->cmap.b + 0x00, 0x10);
270 1.1 tsutsui memcpy(fb->cmap.r + 0x30, fb->cmap.r + 0xf0, 0x10);
271 1.1 tsutsui memcpy(fb->cmap.g + 0x30, fb->cmap.g + 0xf0, 0x10);
272 1.1 tsutsui memcpy(fb->cmap.b + 0x30, fb->cmap.b + 0xf0, 0x10);
273 1.1 tsutsui break;
274 1.1 tsutsui case 4:
275 1.1 tsutsui /*
276 1.1 tsutsui * 00-07 normal colors
277 1.1 tsutsui * 08-0f inverted colors
278 1.1 tsutsui * highlighted colors are not available.
279 1.1 tsutsui */
280 1.1 tsutsui memcpy(fb->cmap.r + 0x08, fb->cmap.r + 0xf8, 0x08);
281 1.1 tsutsui memcpy(fb->cmap.g + 0x08, fb->cmap.g + 0xf8, 0x08);
282 1.1 tsutsui memcpy(fb->cmap.b + 0x08, fb->cmap.b + 0xf8, 0x08);
283 1.1 tsutsui break;
284 1.1 tsutsui }
285 1.1 tsutsui }
286 1.1 tsutsui
287 1.1 tsutsui /*
288 1.1 tsutsui * Attachment helpers
289 1.1 tsutsui */
290 1.1 tsutsui
291 1.1 tsutsui void
292 1.1 tsutsui diofb_cnattach(struct diofb *fb)
293 1.1 tsutsui {
294 1.1 tsutsui long defattr;
295 1.1 tsutsui struct rasops_info *ri;
296 1.1 tsutsui
297 1.1 tsutsui ri = &fb->ri;
298 1.1 tsutsui ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr);
299 1.1 tsutsui wsdisplay_cnattach(&fb->wsd, ri, 0, 0, defattr);
300 1.1 tsutsui }
301 1.1 tsutsui
302 1.1 tsutsui void
303 1.1 tsutsui diofb_end_attach(device_t self, struct wsdisplay_accessops *accessops,
304 1.1 tsutsui struct diofb *fb, int console, const char *descr)
305 1.1 tsutsui {
306 1.1 tsutsui struct wsemuldisplaydev_attach_args waa;
307 1.1 tsutsui
308 1.3 tsutsui aprint_normal(": %dx%d", fb->dwidth, fb->dheight);
309 1.1 tsutsui
310 1.1 tsutsui if (fb->planes == 1)
311 1.3 tsutsui aprint_normal(" monochrome");
312 1.1 tsutsui else
313 1.3 tsutsui aprint_normal("x%d", fb->planes);
314 1.1 tsutsui
315 1.1 tsutsui if (descr != NULL)
316 1.3 tsutsui aprint_normal(" %s", descr);
317 1.3 tsutsui aprint_normal(" frame buffer\n");
318 1.1 tsutsui
319 1.1 tsutsui fb->scrlist[0] = &fb->wsd;
320 1.1 tsutsui fb->wsl.nscreens = 1;
321 1.4 christos fb->wsl.screens = (void *)fb->scrlist;
322 1.1 tsutsui
323 1.1 tsutsui waa.console = console;
324 1.1 tsutsui waa.scrdata = &fb->wsl;
325 1.1 tsutsui waa.accessops = accessops;
326 1.1 tsutsui waa.accesscookie = fb;
327 1.1 tsutsui
328 1.1 tsutsui config_found(self, &waa, wsemuldisplaydevprint);
329 1.1 tsutsui }
330 1.1 tsutsui
331 1.1 tsutsui /*
332 1.1 tsutsui * Common wsdisplay emulops for DIO frame buffers
333 1.1 tsutsui */
334 1.1 tsutsui
335 1.1 tsutsui int
336 1.1 tsutsui diofb_allocattr(void *cookie, int fg, int bg, int flg, long *attr)
337 1.1 tsutsui {
338 1.2 tsutsui
339 1.1 tsutsui if ((flg & (WSATTR_BLINK | WSATTR_HILIT)) != 0)
340 1.2 tsutsui return EINVAL;
341 1.1 tsutsui
342 1.1 tsutsui if ((flg & WSATTR_WSCOLORS) == 0) {
343 1.1 tsutsui fg = WSCOL_WHITE;
344 1.1 tsutsui bg = WSCOL_BLACK;
345 1.1 tsutsui }
346 1.1 tsutsui
347 1.1 tsutsui if ((flg & WSATTR_REVERSE) != 0) {
348 1.1 tsutsui int swap;
349 1.1 tsutsui swap = fg;
350 1.1 tsutsui fg = bg;
351 1.1 tsutsui bg = swap;
352 1.1 tsutsui }
353 1.1 tsutsui
354 1.1 tsutsui flg = ((flg & WSATTR_UNDERLINE) ? 1 : 0);
355 1.1 tsutsui
356 1.1 tsutsui *attr = (bg << 16) | (fg << 24) | flg;
357 1.1 tsutsui
358 1.1 tsutsui return 0;
359 1.1 tsutsui }
360 1.1 tsutsui
361 1.1 tsutsui void
362 1.1 tsutsui diofb_copycols(void *cookie, int row, int src, int dst, int n)
363 1.1 tsutsui {
364 1.1 tsutsui struct rasops_info *ri = cookie;
365 1.1 tsutsui struct diofb *fb = ri->ri_hw;
366 1.1 tsutsui
367 1.1 tsutsui n *= ri->ri_font->fontwidth;
368 1.1 tsutsui src *= ri->ri_font->fontwidth;
369 1.1 tsutsui dst *= ri->ri_font->fontwidth;
370 1.1 tsutsui row *= ri->ri_font->fontheight;
371 1.1 tsutsui
372 1.1 tsutsui (*fb->bmv)(fb, ri->ri_xorigin + src, ri->ri_yorigin + row,
373 1.1 tsutsui ri->ri_xorigin + dst, ri->ri_yorigin + row,
374 1.1 tsutsui n, ri->ri_font->fontheight, RR_COPY, 0xff);
375 1.1 tsutsui }
376 1.1 tsutsui
377 1.1 tsutsui void
378 1.1 tsutsui diofb_copyrows(void *cookie, int src, int dst, int n)
379 1.1 tsutsui {
380 1.1 tsutsui struct rasops_info *ri = cookie;
381 1.1 tsutsui struct diofb *fb = ri->ri_hw;
382 1.1 tsutsui
383 1.1 tsutsui n *= ri->ri_font->fontheight;
384 1.1 tsutsui src *= ri->ri_font->fontheight;
385 1.1 tsutsui dst *= ri->ri_font->fontheight;
386 1.1 tsutsui
387 1.1 tsutsui (*fb->bmv)(fb, ri->ri_xorigin, ri->ri_yorigin + src,
388 1.1 tsutsui ri->ri_xorigin, ri->ri_yorigin + dst,
389 1.1 tsutsui ri->ri_emuwidth, n, RR_COPY, 0xff);
390 1.1 tsutsui }
391 1.1 tsutsui
392 1.1 tsutsui void
393 1.1 tsutsui diofb_erasecols(void *cookie, int row, int col, int num, long attr)
394 1.1 tsutsui {
395 1.1 tsutsui struct rasops_info *ri = cookie;
396 1.1 tsutsui struct diofb *fb = ri->ri_hw;
397 1.1 tsutsui int fg, bg;
398 1.1 tsutsui int snum, scol, srow;
399 1.1 tsutsui
400 1.1 tsutsui rasops_unpack_attr(attr, &fg, &bg, NULL);
401 1.1 tsutsui
402 1.1 tsutsui snum = num * ri->ri_font->fontwidth;
403 1.1 tsutsui scol = col * ri->ri_font->fontwidth + ri->ri_xorigin;
404 1.1 tsutsui srow = row * ri->ri_font->fontheight + ri->ri_yorigin;
405 1.1 tsutsui
406 1.1 tsutsui /*
407 1.1 tsutsui * If this is too tricky for the simple raster ops engine,
408 1.1 tsutsui * pass the fun to rasops.
409 1.1 tsutsui */
410 1.1 tsutsui if ((*fb->bmv)(fb, scol, srow, scol, srow, snum,
411 1.1 tsutsui ri->ri_font->fontheight, RR_CLEAR, 0xff ^ bg) != 0)
412 1.1 tsutsui rasops_erasecols(cookie, row, col, num, attr);
413 1.1 tsutsui }
414 1.1 tsutsui
415 1.1 tsutsui void
416 1.1 tsutsui diofb_eraserows(void *cookie, int row, int num, long attr)
417 1.1 tsutsui {
418 1.1 tsutsui struct rasops_info *ri = cookie;
419 1.1 tsutsui struct diofb *fb = ri->ri_hw;
420 1.1 tsutsui int fg, bg;
421 1.1 tsutsui int srow, snum;
422 1.1 tsutsui int rc;
423 1.1 tsutsui
424 1.1 tsutsui rasops_unpack_attr(attr, &fg, &bg, NULL);
425 1.1 tsutsui bg ^= 0xff;
426 1.1 tsutsui
427 1.1 tsutsui if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR)) {
428 1.1 tsutsui rc = (*fb->bmv)(fb, 0, 0, 0, 0, ri->ri_width, ri->ri_height,
429 1.1 tsutsui RR_CLEAR, bg);
430 1.1 tsutsui } else {
431 1.1 tsutsui srow = row * ri->ri_font->fontheight + ri->ri_yorigin;
432 1.1 tsutsui snum = num * ri->ri_font->fontheight;
433 1.1 tsutsui rc = (*fb->bmv)(fb, ri->ri_xorigin, srow, ri->ri_xorigin,
434 1.1 tsutsui srow, ri->ri_emuwidth, snum, RR_CLEAR, bg);
435 1.1 tsutsui }
436 1.1 tsutsui if (rc != 0)
437 1.1 tsutsui rasops_eraserows(cookie, row, num, attr);
438 1.1 tsutsui }
439 1.1 tsutsui
440 1.1 tsutsui void
441 1.1 tsutsui diofb_do_cursor(struct rasops_info *ri)
442 1.1 tsutsui {
443 1.1 tsutsui struct diofb *fb = ri->ri_hw;
444 1.1 tsutsui int x, y;
445 1.1 tsutsui
446 1.1 tsutsui x = ri->ri_ccol * ri->ri_font->fontwidth + ri->ri_xorigin;
447 1.1 tsutsui y = ri->ri_crow * ri->ri_font->fontheight + ri->ri_yorigin;
448 1.1 tsutsui (*fb->bmv)(fb, x, y, x, y, ri->ri_font->fontwidth,
449 1.1 tsutsui ri->ri_font->fontheight, RR_INVERT, 0xff);
450 1.1 tsutsui }
451 1.1 tsutsui
452 1.1 tsutsui /*
453 1.1 tsutsui * Common wsdisplay accessops for DIO frame buffers
454 1.1 tsutsui */
455 1.1 tsutsui
456 1.1 tsutsui int
457 1.1 tsutsui diofb_alloc_screen(void *v, const struct wsscreen_descr *type,
458 1.1 tsutsui void **cookiep, int *curxp, int *curyp, long *attrp)
459 1.1 tsutsui {
460 1.1 tsutsui struct diofb *fb = v;
461 1.1 tsutsui struct rasops_info *ri = &fb->ri;
462 1.1 tsutsui
463 1.1 tsutsui if (fb->nscreens > 0)
464 1.2 tsutsui return ENOMEM;
465 1.1 tsutsui
466 1.1 tsutsui *cookiep = ri;
467 1.1 tsutsui *curxp = *curyp = 0;
468 1.1 tsutsui ri->ri_ops.allocattr(ri, 0, 0, 0, attrp);
469 1.1 tsutsui fb->nscreens++;
470 1.1 tsutsui
471 1.2 tsutsui return 0;
472 1.1 tsutsui }
473 1.1 tsutsui
474 1.1 tsutsui void
475 1.1 tsutsui diofb_free_screen(void *v, void *cookie)
476 1.1 tsutsui {
477 1.1 tsutsui struct diofb *fb = v;
478 1.1 tsutsui
479 1.1 tsutsui fb->nscreens--;
480 1.1 tsutsui }
481 1.1 tsutsui
482 1.1 tsutsui int
483 1.1 tsutsui diofb_show_screen(void *v, void *cookie, int waitok,
484 1.1 tsutsui void (*cb)(void *, int, int), void *cbarg)
485 1.1 tsutsui {
486 1.2 tsutsui
487 1.2 tsutsui return 0;
488 1.1 tsutsui }
489 1.1 tsutsui
490 1.1 tsutsui paddr_t
491 1.1 tsutsui diofb_mmap(void *v, void *vs, off_t offset, int prot)
492 1.1 tsutsui {
493 1.1 tsutsui struct diofb *fb = v;
494 1.1 tsutsui
495 1.1 tsutsui if ((offset & PAGE_MASK) != 0)
496 1.2 tsutsui return -1;
497 1.1 tsutsui
498 1.1 tsutsui switch (fb->mapmode) {
499 1.1 tsutsui case WSDISPLAYIO_MODE_MAPPED:
500 1.1 tsutsui if (offset >= 0 && offset < DIOFB_REGSPACE)
501 1.1 tsutsui return m68k_btop(fb->regaddr + offset);
502 1.1 tsutsui offset -= DIOFB_REGSPACE;
503 1.1 tsutsui /* FALLTHROUGH */
504 1.1 tsutsui case WSDISPLAYIO_MODE_DUMBFB:
505 1.1 tsutsui if (offset >= 0 && offset < fb->fbsize)
506 1.1 tsutsui return m68k_btop(fb->fbaddr + offset);
507 1.1 tsutsui break;
508 1.1 tsutsui }
509 1.1 tsutsui
510 1.2 tsutsui return -1;
511 1.1 tsutsui }
512 1.1 tsutsui
513 1.1 tsutsui int
514 1.1 tsutsui diofb_getcmap(struct diofb *fb, struct wsdisplay_cmap *cm)
515 1.1 tsutsui {
516 1.1 tsutsui u_int index = cm->index, count = cm->count;
517 1.1 tsutsui u_int colcount = 1 << fb->planes;
518 1.1 tsutsui int error;
519 1.1 tsutsui
520 1.1 tsutsui if (index >= colcount || count > colcount - index)
521 1.2 tsutsui return EINVAL;
522 1.1 tsutsui
523 1.1 tsutsui if ((error = copyout(fb->cmap.r + index, cm->red, count)) != 0)
524 1.2 tsutsui return error;
525 1.1 tsutsui if ((error = copyout(fb->cmap.g + index, cm->green, count)) != 0)
526 1.2 tsutsui return error;
527 1.1 tsutsui if ((error = copyout(fb->cmap.b + index, cm->blue, count)) != 0)
528 1.2 tsutsui return error;
529 1.1 tsutsui
530 1.2 tsutsui return 0;
531 1.1 tsutsui }
532