1 1.10 tsutsui /* $NetBSD: diofb.c,v 1.10 2024/05/01 19:28:33 tsutsui 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.7 thorpej config_found(self, &waa, wsemuldisplaydevprint, CFARGS_NONE); 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.9 tsutsui *attr = (bg << 16) | (fg << 24) | (flg & WSATTR_UNDERLINE); 355 1.1 tsutsui 356 1.1 tsutsui return 0; 357 1.1 tsutsui } 358 1.1 tsutsui 359 1.1 tsutsui void 360 1.1 tsutsui diofb_copycols(void *cookie, int row, int src, int dst, int n) 361 1.1 tsutsui { 362 1.1 tsutsui struct rasops_info *ri = cookie; 363 1.1 tsutsui struct diofb *fb = ri->ri_hw; 364 1.10 tsutsui int fontwidth = fb->wsd.fontwidth; 365 1.1 tsutsui 366 1.10 tsutsui n *= fontwidth; 367 1.10 tsutsui src *= fontwidth; 368 1.10 tsutsui dst *= fontwidth; 369 1.1 tsutsui row *= ri->ri_font->fontheight; 370 1.1 tsutsui 371 1.1 tsutsui (*fb->bmv)(fb, ri->ri_xorigin + src, ri->ri_yorigin + row, 372 1.1 tsutsui ri->ri_xorigin + dst, ri->ri_yorigin + row, 373 1.1 tsutsui n, ri->ri_font->fontheight, RR_COPY, 0xff); 374 1.1 tsutsui } 375 1.1 tsutsui 376 1.1 tsutsui void 377 1.1 tsutsui diofb_copyrows(void *cookie, int src, int dst, int n) 378 1.1 tsutsui { 379 1.1 tsutsui struct rasops_info *ri = cookie; 380 1.1 tsutsui struct diofb *fb = ri->ri_hw; 381 1.1 tsutsui 382 1.1 tsutsui n *= ri->ri_font->fontheight; 383 1.1 tsutsui src *= ri->ri_font->fontheight; 384 1.1 tsutsui dst *= ri->ri_font->fontheight; 385 1.1 tsutsui 386 1.1 tsutsui (*fb->bmv)(fb, ri->ri_xorigin, ri->ri_yorigin + src, 387 1.1 tsutsui ri->ri_xorigin, ri->ri_yorigin + dst, 388 1.1 tsutsui ri->ri_emuwidth, n, RR_COPY, 0xff); 389 1.1 tsutsui } 390 1.1 tsutsui 391 1.1 tsutsui void 392 1.1 tsutsui diofb_erasecols(void *cookie, int row, int col, int num, long attr) 393 1.1 tsutsui { 394 1.1 tsutsui struct rasops_info *ri = cookie; 395 1.1 tsutsui struct diofb *fb = ri->ri_hw; 396 1.1 tsutsui int fg, bg; 397 1.1 tsutsui int snum, scol, srow; 398 1.10 tsutsui int fontwidth = fb->wsd.fontwidth; 399 1.1 tsutsui 400 1.1 tsutsui rasops_unpack_attr(attr, &fg, &bg, NULL); 401 1.1 tsutsui 402 1.10 tsutsui snum = num * fontwidth; 403 1.10 tsutsui scol = col * 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.10 tsutsui rc = (*fb->bmv)(fb, 0, 0, 0, 0, fb->fbwidth, 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.10 tsutsui int fontwidth = fb->wsd.fontwidth; 446 1.1 tsutsui 447 1.10 tsutsui x = ri->ri_ccol * fontwidth + ri->ri_xorigin; 448 1.1 tsutsui y = ri->ri_crow * ri->ri_font->fontheight + ri->ri_yorigin; 449 1.10 tsutsui (*fb->bmv)(fb, x, y, x, y, fontwidth, 450 1.1 tsutsui ri->ri_font->fontheight, RR_INVERT, 0xff); 451 1.1 tsutsui } 452 1.1 tsutsui 453 1.1 tsutsui /* 454 1.1 tsutsui * Common wsdisplay accessops for DIO frame buffers 455 1.1 tsutsui */ 456 1.1 tsutsui 457 1.1 tsutsui int 458 1.1 tsutsui diofb_alloc_screen(void *v, const struct wsscreen_descr *type, 459 1.1 tsutsui void **cookiep, int *curxp, int *curyp, long *attrp) 460 1.1 tsutsui { 461 1.1 tsutsui struct diofb *fb = v; 462 1.1 tsutsui struct rasops_info *ri = &fb->ri; 463 1.1 tsutsui 464 1.1 tsutsui if (fb->nscreens > 0) 465 1.2 tsutsui return ENOMEM; 466 1.1 tsutsui 467 1.1 tsutsui *cookiep = ri; 468 1.1 tsutsui *curxp = *curyp = 0; 469 1.1 tsutsui ri->ri_ops.allocattr(ri, 0, 0, 0, attrp); 470 1.1 tsutsui fb->nscreens++; 471 1.1 tsutsui 472 1.2 tsutsui return 0; 473 1.1 tsutsui } 474 1.1 tsutsui 475 1.1 tsutsui void 476 1.1 tsutsui diofb_free_screen(void *v, void *cookie) 477 1.1 tsutsui { 478 1.1 tsutsui struct diofb *fb = v; 479 1.1 tsutsui 480 1.1 tsutsui fb->nscreens--; 481 1.1 tsutsui } 482 1.1 tsutsui 483 1.1 tsutsui int 484 1.1 tsutsui diofb_show_screen(void *v, void *cookie, int waitok, 485 1.1 tsutsui void (*cb)(void *, int, int), void *cbarg) 486 1.1 tsutsui { 487 1.2 tsutsui 488 1.2 tsutsui return 0; 489 1.1 tsutsui } 490 1.1 tsutsui 491 1.1 tsutsui paddr_t 492 1.1 tsutsui diofb_mmap(void *v, void *vs, off_t offset, int prot) 493 1.1 tsutsui { 494 1.1 tsutsui struct diofb *fb = v; 495 1.1 tsutsui 496 1.1 tsutsui if ((offset & PAGE_MASK) != 0) 497 1.2 tsutsui return -1; 498 1.1 tsutsui 499 1.1 tsutsui switch (fb->mapmode) { 500 1.1 tsutsui case WSDISPLAYIO_MODE_MAPPED: 501 1.1 tsutsui if (offset >= 0 && offset < DIOFB_REGSPACE) 502 1.1 tsutsui return m68k_btop(fb->regaddr + offset); 503 1.1 tsutsui offset -= DIOFB_REGSPACE; 504 1.1 tsutsui /* FALLTHROUGH */ 505 1.1 tsutsui case WSDISPLAYIO_MODE_DUMBFB: 506 1.1 tsutsui if (offset >= 0 && offset < fb->fbsize) 507 1.1 tsutsui return m68k_btop(fb->fbaddr + offset); 508 1.1 tsutsui break; 509 1.1 tsutsui } 510 1.1 tsutsui 511 1.2 tsutsui return -1; 512 1.1 tsutsui } 513 1.1 tsutsui 514 1.1 tsutsui int 515 1.1 tsutsui diofb_getcmap(struct diofb *fb, struct wsdisplay_cmap *cm) 516 1.1 tsutsui { 517 1.1 tsutsui u_int index = cm->index, count = cm->count; 518 1.1 tsutsui u_int colcount = 1 << fb->planes; 519 1.1 tsutsui int error; 520 1.1 tsutsui 521 1.1 tsutsui if (index >= colcount || count > colcount - index) 522 1.2 tsutsui return EINVAL; 523 1.1 tsutsui 524 1.1 tsutsui if ((error = copyout(fb->cmap.r + index, cm->red, count)) != 0) 525 1.2 tsutsui return error; 526 1.1 tsutsui if ((error = copyout(fb->cmap.g + index, cm->green, count)) != 0) 527 1.2 tsutsui return error; 528 1.1 tsutsui if ((error = copyout(fb->cmap.b + index, cm->blue, count)) != 0) 529 1.2 tsutsui return error; 530 1.1 tsutsui 531 1.2 tsutsui return 0; 532 1.1 tsutsui } 533