Annotation of sys/dev/sbus/zx.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: zx.c,v 1.13 2007/03/13 19:40:49 miod Exp $ */
! 2: /* $NetBSD: zx.c,v 1.5 2002/10/02 16:52:46 thorpej Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 2003, Miodrag Vallat.
! 6: * All rights reserved.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: *
! 17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 18: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 19: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
! 20: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
! 21: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 22: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 23: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 25: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
! 26: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 27: * POSSIBILITY OF SUCH DAMAGE.
! 28: *
! 29: * Derived from NetBSD syssrc/sys/dev/sbus/zx.c under the following licence
! 30: * terms:
! 31: *
! 32: * Copyright (c) 2002 The NetBSD Foundation, Inc.
! 33: * All rights reserved.
! 34: *
! 35: * This code is derived from software contributed to The NetBSD Foundation
! 36: * by Andrew Doran.
! 37: *
! 38: * Redistribution and use in source and binary forms, with or without
! 39: * modification, are permitted provided that the following conditions
! 40: * are met:
! 41: * 1. Redistributions of source code must retain the above copyright
! 42: * notice, this list of conditions and the following disclaimer.
! 43: * 2. Redistributions in binary form must reproduce the above copyright
! 44: * notice, this list of conditions and the following disclaimer in the
! 45: * documentation and/or other materials provided with the distribution.
! 46: * 3. All advertising materials mentioning features or use of this software
! 47: * must display the following acknowledgement:
! 48: * This product includes software developed by the NetBSD
! 49: * Foundation, Inc. and its contributors.
! 50: * 4. Neither the name of The NetBSD Foundation nor the names of its
! 51: * contributors may be used to endorse or promote products derived
! 52: * from this software without specific prior written permission.
! 53: *
! 54: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 55: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 56: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 57: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 58: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 59: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 60: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 61: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 62: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 63: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 64: * POSSIBILITY OF SUCH DAMAGE.
! 65: */
! 66:
! 67: /*
! 68: * Driver for the Sun ZX display adapter. This would be called 'leo', but
! 69: * NetBSD/amiga already has a driver by that name. The XFree86 and Linux
! 70: * drivers were used as "living documentation" when writing this; thanks
! 71: * to the authors.
! 72: */
! 73:
! 74: #include <sys/param.h>
! 75: #include <sys/systm.h>
! 76: #include <sys/device.h>
! 77: #include <sys/ioctl.h>
! 78: #include <sys/malloc.h>
! 79: #include <sys/mman.h>
! 80: #include <sys/tty.h>
! 81: #include <sys/conf.h>
! 82:
! 83: #include <uvm/uvm_extern.h>
! 84:
! 85: #include <machine/autoconf.h>
! 86: #include <machine/bus.h>
! 87: #include <machine/cpu.h>
! 88: #include <machine/conf.h>
! 89:
! 90: #include <dev/wscons/wsconsio.h>
! 91: #include <dev/wscons/wsdisplayvar.h>
! 92: #include <dev/rasops/rasops.h>
! 93: #include <machine/fbvar.h>
! 94:
! 95: #include <dev/sbus/zxreg.h>
! 96: #include <dev/sbus/sbusvar.h>
! 97:
! 98: #define ZX_WID_SHARED_8 0
! 99: #define ZX_WID_SHARED_24 1
! 100: #define ZX_WID_DBL_8 2
! 101: #define ZX_WID_DBL_24 3
! 102:
! 103: /*
! 104: * Per-instance data.
! 105: */
! 106:
! 107: struct zx_cmap {
! 108: u_int8_t cm_red[256];
! 109: u_int8_t cm_green[256];
! 110: u_int8_t cm_blue[256];
! 111: };
! 112:
! 113: struct zx_softc {
! 114: struct sunfb sc_sunfb;
! 115:
! 116: bus_space_tag_t sc_bustag;
! 117: bus_addr_t sc_paddr;
! 118:
! 119: struct zx_cmap sc_cmap; /* shadow color map for overlay plane */
! 120:
! 121: volatile struct zx_command *sc_zc;
! 122: volatile struct zx_cross *sc_zx;
! 123: volatile struct zx_draw *sc_zd_ss0;
! 124: volatile struct zx_draw_ss1 *sc_zd_ss1;
! 125: volatile struct zx_cursor *sc_zcu;
! 126:
! 127: int sc_nscreens;
! 128: };
! 129:
! 130: int zx_ioctl(void *, u_long, caddr_t, int, struct proc *);
! 131: int zx_alloc_screen(void *, const struct wsscreen_descr *, void **,
! 132: int *, int *, long *);
! 133: void zx_free_screen(void *, void *);
! 134: int zx_show_screen(void *, void *, int, void (*)(void *, int, int), void *);
! 135: paddr_t zx_mmap(void *, off_t, int);
! 136: void zx_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
! 137: void zx_reset(struct zx_softc *, u_int);
! 138: void zx_burner(void *, u_int, u_int);
! 139:
! 140: struct wsdisplay_accessops zx_accessops = {
! 141: zx_ioctl,
! 142: zx_mmap,
! 143: zx_alloc_screen,
! 144: zx_free_screen,
! 145: zx_show_screen,
! 146: NULL, /* load_font */
! 147: NULL, /* scrollback */
! 148: NULL, /* getchar */
! 149: zx_burner
! 150: };
! 151:
! 152: /* Force 32-bit writes. */
! 153: #define SETREG(r, v) (*((volatile u_int32_t *)&r) = (v))
! 154:
! 155: #define ZX_STD_ROP (ZX_ROP_NEW | ZX_ATTR_WE_ENABLE | \
! 156: ZX_ATTR_OE_ENABLE | ZX_ATTR_FORCE_WID)
! 157:
! 158: #define ZX_BWIDTH 13
! 159: #define ZX_WWIDTH 11 /* word width */
! 160:
! 161: #define ZX_COORDS(x, y) ((x) | ((y) << ZX_WWIDTH))
! 162:
! 163: void zx_attach(struct device *, struct device *, void *);
! 164: int zx_match(struct device *, void *, void *);
! 165:
! 166: int zx_putcmap(struct zx_softc *);
! 167: void zx_copyrect(struct rasops_info *, int, int, int, int, int, int);
! 168: int zx_cross_loadwid(struct zx_softc *, u_int, u_int, u_int);
! 169: int zx_cross_wait(struct zx_softc *);
! 170: void zx_fillrect(struct rasops_info *, int, int, int, int, long, int);
! 171: int zx_intr(void *);
! 172: void zx_prom(void *);
! 173:
! 174: void zx_putchar(void *, int, int, u_int, long);
! 175: void zx_copycols(void *, int, int, int, int);
! 176: void zx_erasecols(void *, int, int, int, long);
! 177: void zx_copyrows(void *, int, int, int);
! 178: void zx_eraserows(void *, int, int, long);
! 179: void zx_do_cursor(struct rasops_info *);
! 180:
! 181: struct cfattach zx_ca = {
! 182: sizeof(struct zx_softc), zx_match, zx_attach
! 183: };
! 184:
! 185: struct cfdriver zx_cd = {
! 186: NULL, "zx", DV_DULL
! 187: };
! 188:
! 189: int
! 190: zx_match(struct device *parent, void *vcf, void *aux)
! 191: {
! 192: struct sbus_attach_args *sa = aux;
! 193:
! 194: if (strcmp(sa->sa_name, "SUNW,leo") == 0)
! 195: return (1);
! 196:
! 197: return (0);
! 198: }
! 199:
! 200: void
! 201: zx_attach(struct device *parent, struct device *self, void *args)
! 202: {
! 203: struct zx_softc *sc = (struct zx_softc *)self;
! 204: struct sbus_attach_args *sa = args;
! 205: struct rasops_info *ri;
! 206: bus_space_tag_t bt;
! 207: bus_space_handle_t bh;
! 208: int node, isconsole = 0;
! 209: const char *nam;
! 210:
! 211: bt = sa->sa_bustag;
! 212: ri = &sc->sc_sunfb.sf_ro;
! 213: node = sa->sa_node;
! 214:
! 215: /*
! 216: * Map the various parts of the card.
! 217: */
! 218: sc->sc_bustag = bt;
! 219: sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset);
! 220:
! 221: if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LC_SS0_USR,
! 222: sizeof(struct zx_command), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
! 223: printf(": couldn't map command registers\n");
! 224: return;
! 225: }
! 226: sc->sc_zc = (struct zx_command *)bus_space_vaddr(bt, bh);
! 227:
! 228: if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS0,
! 229: sizeof(struct zx_draw), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
! 230: printf(": couldn't map ss0 drawing registers\n");
! 231: return;
! 232: }
! 233: sc->sc_zd_ss0 = (struct zx_draw *)bus_space_vaddr(bt, bh);
! 234:
! 235: if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS1,
! 236: sizeof(struct zx_draw_ss1), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
! 237: printf(": couldn't map ss1 drawing registers\n");
! 238: return;
! 239: }
! 240: sc->sc_zd_ss1 = (struct zx_draw_ss1 *)bus_space_vaddr(bt, bh);
! 241:
! 242: if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CROSS,
! 243: sizeof(struct zx_cross), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
! 244: printf(": couldn't map cross registers\n");
! 245: return;
! 246: }
! 247: sc->sc_zx = (struct zx_cross *)bus_space_vaddr(bt, bh);
! 248:
! 249: if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CURSOR,
! 250: sizeof(struct zx_cursor), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
! 251: printf(": couldn't map cursor registers\n");
! 252: return;
! 253: }
! 254: sc->sc_zcu = (struct zx_cursor *)bus_space_vaddr(bt, bh);
! 255:
! 256: nam = getpropstring(node, "model");
! 257: if (*nam == '\0')
! 258: nam = sa->sa_name;
! 259: printf(": %s", nam);
! 260:
! 261: isconsole = node == fbnode;
! 262:
! 263: /*
! 264: * The console is using the 8-bit overlay plane, while the prom
! 265: * will correctly report 32 bit depth.
! 266: * The following is an equivalent for
! 267: * fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
! 268: * forcing the depth value not to be overwritten.
! 269: * Furthermore, the linebytes value is in fact 8192 bytes.
! 270: */
! 271: sc->sc_sunfb.sf_depth = 8;
! 272: sc->sc_sunfb.sf_width = getpropint(node, "width", 1152);
! 273: sc->sc_sunfb.sf_height = getpropint(node, "height", 900);
! 274: sc->sc_sunfb.sf_linebytes = 1 << ZX_BWIDTH;
! 275: sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height << ZX_BWIDTH;
! 276:
! 277: printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
! 278:
! 279: if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_SS0,
! 280: round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR,
! 281: 0, &bh) != 0) {
! 282: printf("%s: couldn't map video memory\n", self->dv_xname);
! 283: return;
! 284: }
! 285: ri->ri_bits = bus_space_vaddr(bt, bh);
! 286: ri->ri_hw = sc;
! 287:
! 288: fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);
! 289:
! 290: /*
! 291: * Watch out! rasops_init() invoked via fbwscons_init() did not
! 292: * compute ri_bits correctly when centering the display, because
! 293: * it has been tricked with the low depth value.
! 294: * Recompute now.
! 295: */
! 296: ri->ri_emustride = ri->ri_emuwidth * 4;
! 297: ri->ri_delta = ri->ri_stride - ri->ri_emustride;
! 298: ri->ri_pelbytes = 4;
! 299: ri->ri_xscale = ri->ri_font->fontwidth * 4;
! 300: ri->ri_bits = ri->ri_origbits;
! 301: ri->ri_bits += (((ri->ri_width * 4) - ri->ri_emustride) >> 1) & ~3;
! 302: ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
! 303: ri->ri_stride;
! 304: ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits)
! 305: / ri->ri_stride;
! 306: ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits)
! 307: % ri->ri_stride) / 4);
! 308:
! 309: ri->ri_ops.copyrows = zx_copyrows;
! 310: ri->ri_ops.copycols = zx_copycols;
! 311: ri->ri_ops.eraserows = zx_eraserows;
! 312: ri->ri_ops.erasecols = zx_erasecols;
! 313: ri->ri_ops.putchar = zx_putchar;
! 314: ri->ri_do_cursor = zx_do_cursor;
! 315:
! 316: if (isconsole) {
! 317: /* zx_reset() below will clear screen, so restart at 1st row */
! 318: fbwscons_console_init(&sc->sc_sunfb, 0);
! 319: }
! 320:
! 321: /* reset cursor & frame buffer controls */
! 322: zx_reset(sc, WSDISPLAYIO_MODE_EMUL);
! 323:
! 324: /* enable video */
! 325: zx_burner(sc, 1, 0);
! 326:
! 327: fbwscons_attach(&sc->sc_sunfb, &zx_accessops, isconsole);
! 328: }
! 329:
! 330: int
! 331: zx_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p)
! 332: {
! 333: struct zx_softc *sc = dev;
! 334: struct wsdisplay_fbinfo *wdf;
! 335:
! 336: /*
! 337: * Note that, although the emulation (text) mode is running in
! 338: * a 8-bit plane, we advertize the frame buffer as the full-blown
! 339: * 32-bit beast it is.
! 340: */
! 341: switch (cmd) {
! 342: case WSDISPLAYIO_GTYPE:
! 343: *(u_int *)data = WSDISPLAY_TYPE_SUN24;
! 344: break;
! 345: case WSDISPLAYIO_GINFO:
! 346: wdf = (struct wsdisplay_fbinfo *)data;
! 347: wdf->height = sc->sc_sunfb.sf_height;
! 348: wdf->width = sc->sc_sunfb.sf_width;
! 349: wdf->depth = 32;
! 350: wdf->cmsize = 0;
! 351: break;
! 352: case WSDISPLAYIO_GETSUPPORTEDDEPTH:
! 353: *(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
! 354: break;
! 355: case WSDISPLAYIO_LINEBYTES:
! 356: *(u_int *)data = sc->sc_sunfb.sf_linebytes;
! 357: break;
! 358:
! 359: case WSDISPLAYIO_GETCMAP:
! 360: case WSDISPLAYIO_PUTCMAP:
! 361: break;
! 362:
! 363: case WSDISPLAYIO_SMODE:
! 364: zx_reset(sc, *(u_int *)data);
! 365: break;
! 366:
! 367: case WSDISPLAYIO_SVIDEO:
! 368: case WSDISPLAYIO_GVIDEO:
! 369: break;
! 370:
! 371: default:
! 372: return (-1);
! 373: }
! 374:
! 375: return (0);
! 376: }
! 377:
! 378: int
! 379: zx_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
! 380: int *curxp, int *curyp, long *attrp)
! 381: {
! 382: struct zx_softc *sc = v;
! 383:
! 384: if (sc->sc_nscreens > 0)
! 385: return (ENOMEM);
! 386:
! 387: *cookiep = &sc->sc_sunfb.sf_ro;
! 388: *curyp = 0;
! 389: *curxp = 0;
! 390: sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
! 391: WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp);
! 392: sc->sc_nscreens++;
! 393: return (0);
! 394: }
! 395:
! 396: void
! 397: zx_free_screen(void *v, void *cookie)
! 398: {
! 399: struct zx_softc *sc = v;
! 400:
! 401: sc->sc_nscreens--;
! 402: }
! 403:
! 404: int
! 405: zx_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int),
! 406: void *cbarg)
! 407: {
! 408: return (0);
! 409: }
! 410:
! 411: /*
! 412: * Return the address that would map the given device at the given
! 413: * offset, allowing for the given protection, or return -1 for error.
! 414: */
! 415: paddr_t
! 416: zx_mmap(void *v, off_t offset, int prot)
! 417: {
! 418: struct zx_softc *sc = v;
! 419:
! 420: if (offset & PGOFSET)
! 421: return (-1);
! 422:
! 423: /* Allow mapping as a dumb framebuffer from offset 0 */
! 424: if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
! 425: return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
! 426: ZX_OFF_SS0 + offset, prot, BUS_SPACE_MAP_LINEAR));
! 427: }
! 428:
! 429: return (-1);
! 430: }
! 431:
! 432: void
! 433: zx_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
! 434: {
! 435: struct zx_softc *sc = v;
! 436:
! 437: sc->sc_cmap.cm_red[index] = r;
! 438: sc->sc_cmap.cm_green[index] = g;
! 439: sc->sc_cmap.cm_blue[index] = b;
! 440: }
! 441:
! 442: void
! 443: zx_reset(struct zx_softc *sc, u_int mode)
! 444: {
! 445: volatile struct zx_draw *zd;
! 446: volatile struct zx_command *zc;
! 447: u_int32_t i;
! 448: const u_char *color;
! 449: u_int8_t *r, *g, *b;
! 450:
! 451: zd = sc->sc_zd_ss0;
! 452: zc = sc->sc_zc;
! 453:
! 454: if (mode == WSDISPLAYIO_MODE_EMUL) {
! 455: /* Back from X11 to emulation mode, or first reset */
! 456: zx_cross_loadwid(sc, ZX_WID_DBL_8, 0, 0x2c0);
! 457: zx_cross_loadwid(sc, ZX_WID_DBL_8, 1, 0x30);
! 458: zx_cross_loadwid(sc, ZX_WID_DBL_8, 2, 0x20);
! 459: zx_cross_loadwid(sc, ZX_WID_DBL_24, 1, 0x30);
! 460:
! 461: i = sc->sc_zd_ss1->zd_misc;
! 462: i |= ZX_SS1_MISC_ENABLE;
! 463: SETREG(sc->sc_zd_ss1->zd_misc, i);
! 464:
! 465: /*
! 466: * XXX
! 467: * If zc_fill is not set to that value, there will be black
! 468: * bars left in the margins. But then with this value, the
! 469: * screen gets cleared. Go figure.
! 470: */
! 471: SETREG(zd->zd_wid, 0xffffffff);
! 472: SETREG(zd->zd_wmask, 0xffff);
! 473: SETREG(zd->zd_vclipmin, 0);
! 474: SETREG(zd->zd_vclipmax, (sc->sc_sunfb.sf_width - 1) |
! 475: ((sc->sc_sunfb.sf_height - 1) << 16));
! 476: SETREG(zd->zd_fg, 0);
! 477: SETREG(zd->zd_planemask, 0xff000000);
! 478: SETREG(zd->zd_rop, ZX_STD_ROP);
! 479: SETREG(zd->zd_widclip, 0);
! 480:
! 481: SETREG(zc->zc_extent, ZX_COORDS(sc->sc_sunfb.sf_width - 1,
! 482: sc->sc_sunfb.sf_height - 1));
! 483: SETREG(zc->zc_addrspace, ZX_ADDRSPC_FONT_OBGR);
! 484: SETREG(zc->zc_fill, ZX_COORDS(0, 0) | ZX_EXTENT_DIR_BACKWARDS);
! 485: SETREG(zc->zc_fontt, 0);
! 486:
! 487: while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
! 488: ;
! 489:
! 490: /*
! 491: * Initialize the 8-bit colormap
! 492: */
! 493: r = sc->sc_cmap.cm_red;
! 494: g = sc->sc_cmap.cm_green;
! 495: b = sc->sc_cmap.cm_blue;
! 496: color = rasops_cmap;
! 497: for (i = 0; i < 256; i++) {
! 498: *r++ = *color++;
! 499: *g++ = *color++;
! 500: *b++ = *color++;
! 501: }
! 502: fbwscons_setcolormap(&sc->sc_sunfb, zx_setcolor);
! 503: zx_putcmap(sc);
! 504: } else {
! 505: /* Starting X11 - switch to 24bit WID */
! 506: SETREG(zd->zd_wid, 1);
! 507: SETREG(zd->zd_widclip, 0);
! 508: SETREG(zd->zd_wmask, 0xffff);
! 509: SETREG(zd->zd_planemask, 0x00ffffff);
! 510: SETREG(zc->zc_extent, ZX_COORDS(sc->sc_sunfb.sf_width - 1,
! 511: sc->sc_sunfb.sf_height - 1));
! 512: SETREG(zc->zc_fill, 0);
! 513: while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
! 514: ;
! 515:
! 516: SETREG(zc->zc_addrspace, ZX_ADDRSPC_OBGR);
! 517: SETREG(zd->zd_rop, ZX_ATTR_RGBE_ENABLE |
! 518: ZX_ROP_NEW /* | ZX_ATTR_FORCE_WID */);
! 519: }
! 520: }
! 521:
! 522: int
! 523: zx_cross_wait(struct zx_softc *sc)
! 524: {
! 525: volatile struct zx_cross *zx;
! 526: int i;
! 527:
! 528: zx = sc->sc_zx;
! 529:
! 530: for (i = 300000; i != 0; i--) {
! 531: if ((zx->zx_csr & ZX_CROSS_CSR_PROGRESS) == 0)
! 532: break;
! 533: DELAY(1);
! 534: }
! 535:
! 536: if (i == 0)
! 537: printf("%s: zx_cross_wait: timed out\n",
! 538: sc->sc_sunfb.sf_dev.dv_xname);
! 539:
! 540: return (i);
! 541: }
! 542:
! 543: int
! 544: zx_cross_loadwid(struct zx_softc *sc, u_int type, u_int index, u_int value)
! 545: {
! 546: volatile struct zx_cross *zx;
! 547: u_int tmp;
! 548:
! 549: zx = sc->sc_zx;
! 550: SETREG(zx->zx_type, ZX_CROSS_TYPE_WID);
! 551:
! 552: if (!zx_cross_wait(sc))
! 553: return (1);
! 554:
! 555: if (type == ZX_WID_DBL_8)
! 556: tmp = (index & 0x0f) + 0x40;
! 557: else if (type == ZX_WID_DBL_24)
! 558: tmp = index & 0x3f;
! 559:
! 560: SETREG(zx->zx_type, 0x5800 + tmp);
! 561: SETREG(zx->zx_value, value);
! 562: SETREG(zx->zx_type, ZX_CROSS_TYPE_WID);
! 563: SETREG(zx->zx_csr, ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2);
! 564:
! 565: return (0);
! 566: }
! 567:
! 568: int
! 569: zx_putcmap(struct zx_softc *sc)
! 570: {
! 571: volatile struct zx_cross *zx;
! 572: u_int32_t i;
! 573: u_int8_t *r, *g, *b;
! 574:
! 575: zx = sc->sc_zx;
! 576:
! 577: SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUT0);
! 578: if (!zx_cross_wait(sc))
! 579: return (1);
! 580:
! 581: SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUTDATA);
! 582:
! 583: r = sc->sc_cmap.cm_red;
! 584: g = sc->sc_cmap.cm_green;
! 585: b = sc->sc_cmap.cm_blue;
! 586: for (i = 0; i < 256; i++) {
! 587: SETREG(zx->zx_value, *r++ | (*g++ << 8) | (*b++ << 16));
! 588: }
! 589:
! 590: SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUT0);
! 591: i = zx->zx_csr;
! 592: i = i | ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2;
! 593: SETREG(zx->zx_csr, i);
! 594: return (0);
! 595: }
! 596:
! 597: void
! 598: zx_burner(void *v, u_int on, u_int flags)
! 599: {
! 600: struct zx_softc *sc = v;
! 601: volatile struct zx_cross *zx;
! 602: u_int32_t i;
! 603:
! 604: zx = sc->sc_zx;
! 605:
! 606: SETREG(zx->zx_type, ZX_CROSS_TYPE_VIDEO);
! 607: i = zx->zx_csr;
! 608: if (on) {
! 609: i |= ZX_CROSS_CSR_ENABLE;
! 610: } else {
! 611: i &= ~ZX_CROSS_CSR_ENABLE;
! 612: }
! 613: SETREG(zx->zx_csr, i);
! 614: }
! 615:
! 616: void
! 617: zx_fillrect(struct rasops_info *ri, int x, int y, int w, int h, long attr,
! 618: int rop)
! 619: {
! 620: struct zx_softc *sc;
! 621: volatile struct zx_command *zc;
! 622: volatile struct zx_draw *zd;
! 623: int fg, bg;
! 624:
! 625: sc = ri->ri_hw;
! 626: zc = sc->sc_zc;
! 627: zd = sc->sc_zd_ss0;
! 628:
! 629: ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, NULL);
! 630: x = x * ri->ri_font->fontwidth + ri->ri_xorigin;
! 631: y = y * ri->ri_font->fontheight + ri->ri_yorigin;
! 632: w = ri->ri_font->fontwidth * w - 1;
! 633: h = ri->ri_font->fontheight * h - 1;
! 634:
! 635: while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
! 636: ;
! 637:
! 638: SETREG(zd->zd_rop, rop);
! 639: SETREG(zd->zd_fg, ri->ri_devcmap[bg] << 24);
! 640: SETREG(zc->zc_extent, ZX_COORDS(w, h));
! 641: SETREG(zc->zc_fill, ZX_COORDS(x, y) | ZX_EXTENT_DIR_BACKWARDS);
! 642: }
! 643:
! 644: void
! 645: zx_copyrect(struct rasops_info *ri, int sx, int sy, int dx, int dy, int w,
! 646: int h)
! 647: {
! 648: struct zx_softc *sc;
! 649: volatile struct zx_command *zc;
! 650: volatile struct zx_draw *zd;
! 651: int dir;
! 652:
! 653: sc = ri->ri_hw;
! 654: zc = sc->sc_zc;
! 655: zd = sc->sc_zd_ss0;
! 656:
! 657: sx = sx * ri->ri_font->fontwidth + ri->ri_xorigin;
! 658: sy = sy * ri->ri_font->fontheight + ri->ri_yorigin;
! 659: dx = dx * ri->ri_font->fontwidth + ri->ri_xorigin;
! 660: dy = dy * ri->ri_font->fontheight + ri->ri_yorigin;
! 661: w = w * ri->ri_font->fontwidth - 1;
! 662: h = h * ri->ri_font->fontheight - 1;
! 663:
! 664: if (sy < dy || sx < dx) {
! 665: dir = ZX_EXTENT_DIR_BACKWARDS;
! 666: sx += w;
! 667: sy += h;
! 668: dx += w;
! 669: dy += h;
! 670: } else
! 671: dir = ZX_EXTENT_DIR_FORWARDS;
! 672:
! 673: while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
! 674: ;
! 675:
! 676: SETREG(zd->zd_rop, ZX_STD_ROP);
! 677: SETREG(zc->zc_extent, ZX_COORDS(w, h) | dir);
! 678: SETREG(zc->zc_src, ZX_COORDS(sx, sy));
! 679: SETREG(zc->zc_copy, ZX_COORDS(dx, dy));
! 680: }
! 681:
! 682: void
! 683: zx_do_cursor(struct rasops_info *ri)
! 684: {
! 685:
! 686: zx_fillrect(ri, ri->ri_ccol, ri->ri_crow, 1, 1, WSCOL_BLACK << 16,
! 687: ZX_ROP_NEW_XOR_OLD | ZX_ATTR_WE_ENABLE | ZX_ATTR_OE_ENABLE |
! 688: ZX_ATTR_FORCE_WID);
! 689: }
! 690:
! 691: void
! 692: zx_erasecols(void *cookie, int row, int col, int num, long attr)
! 693: {
! 694: struct rasops_info *ri;
! 695:
! 696: ri = (struct rasops_info *)cookie;
! 697:
! 698: zx_fillrect(ri, col, row, num, 1, attr, ZX_STD_ROP);
! 699: }
! 700:
! 701: void
! 702: zx_eraserows(void *cookie, int row, int num, long attr)
! 703: {
! 704: struct rasops_info *ri;
! 705: struct zx_softc *sc;
! 706: volatile struct zx_command *zc;
! 707: volatile struct zx_draw *zd;
! 708: int fg, bg;
! 709:
! 710: ri = (struct rasops_info *)cookie;
! 711:
! 712: if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR)) {
! 713: sc = ri->ri_hw;
! 714: zc = sc->sc_zc;
! 715: zd = sc->sc_zd_ss0;
! 716:
! 717: ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
! 718:
! 719: while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
! 720: ;
! 721:
! 722: SETREG(zd->zd_rop, ZX_STD_ROP);
! 723: SETREG(zd->zd_fg, ri->ri_devcmap[bg] << 24);
! 724: SETREG(zc->zc_extent,
! 725: ZX_COORDS(ri->ri_width - 1, ri->ri_height - 1));
! 726: SETREG(zc->zc_fill, ZX_COORDS(0, 0) | ZX_EXTENT_DIR_BACKWARDS);
! 727: } else
! 728: zx_fillrect(ri, 0, row, ri->ri_cols, num, attr, ZX_STD_ROP);
! 729: }
! 730:
! 731: void
! 732: zx_copyrows(void *cookie, int src, int dst, int num)
! 733: {
! 734: struct rasops_info *ri;
! 735:
! 736: ri = (struct rasops_info *)cookie;
! 737:
! 738: zx_copyrect(ri, 0, src, 0, dst, ri->ri_cols, num);
! 739: }
! 740:
! 741: void
! 742: zx_copycols(void *cookie, int row, int src, int dst, int num)
! 743: {
! 744: struct rasops_info *ri;
! 745:
! 746: ri = (struct rasops_info *)cookie;
! 747:
! 748: zx_copyrect(ri, src, row, dst, row, num, 1);
! 749: }
! 750:
! 751: void
! 752: zx_putchar(void *cookie, int row, int col, u_int uc, long attr)
! 753: {
! 754: struct rasops_info *ri;
! 755: struct zx_softc *sc;
! 756: struct wsdisplay_font *font;
! 757: volatile struct zx_command *zc;
! 758: volatile struct zx_draw *zd;
! 759: volatile u_int32_t *dp;
! 760: u_int8_t *fb;
! 761: int fs, i, fg, bg, ul;
! 762:
! 763: ri = (struct rasops_info *)cookie;
! 764: font = ri->ri_font;
! 765: ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, &ul);
! 766: fg = ri->ri_devcmap[fg];
! 767: bg = ri->ri_devcmap[bg];
! 768:
! 769: dp = (volatile u_int32_t *)ri->ri_bits +
! 770: ZX_COORDS(col * font->fontwidth, row * font->fontheight);
! 771:
! 772: if (uc == ' ') {
! 773: zx_fillrect(ri, col, row, 1, 1, attr, ZX_STD_ROP);
! 774: if (ul == 0)
! 775: return;
! 776:
! 777: dp += font->fontheight << ZX_WWIDTH;
! 778:
! 779: while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
! 780: ;
! 781:
! 782: SETREG(zd->zd_rop, ZX_STD_ROP);
! 783: SETREG(zd->zd_fg, fg << 24);
! 784: SETREG(zd->zd_bg, bg << 24);
! 785: SETREG(zc->zc_fontmsk, 0xffffffff << (32 - font->fontwidth));
! 786: } else {
! 787: sc = ri->ri_hw;
! 788: zc = sc->sc_zc;
! 789: zd = sc->sc_zd_ss0;
! 790:
! 791: fb = (u_int8_t *)font->data + (uc - font->firstchar) *
! 792: ri->ri_fontscale;
! 793: fs = font->stride;
! 794:
! 795: while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
! 796: ;
! 797:
! 798: SETREG(zd->zd_rop, ZX_STD_ROP);
! 799: SETREG(zd->zd_fg, fg << 24);
! 800: SETREG(zd->zd_bg, bg << 24);
! 801: SETREG(zc->zc_fontmsk, 0xffffffff << (32 - font->fontwidth));
! 802:
! 803: if (font->fontwidth <= 8) {
! 804: for (i = font->fontheight; i != 0;
! 805: i--, dp += 1 << ZX_WWIDTH) {
! 806: *dp = *fb << 24;
! 807: fb += fs;
! 808: }
! 809: } else {
! 810: for (i = font->fontheight; i != 0;
! 811: i--, dp += 1 << ZX_WWIDTH) {
! 812: *dp = *((u_int16_t *)fb) << 16;
! 813: fb += fs;
! 814: }
! 815: }
! 816: }
! 817:
! 818: /* underline */
! 819: if (ul) {
! 820: dp -= 2 << ZX_WWIDTH;
! 821: *dp = 0xffffffff;
! 822: }
! 823: }
CVSweb