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