[BACK]Return to zx.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc / dev

Annotation of sys/arch/sparc/dev/zx.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: zx.c,v 1.19 2007/03/13 19:40:48 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/cpu.h>
                     87: #include <machine/conf.h>
                     88:
                     89: #include <dev/wscons/wsconsio.h>
                     90: #include <dev/wscons/wsdisplayvar.h>
                     91: #include <dev/rasops/rasops.h>
                     92: #include <machine/fbvar.h>
                     93:
                     94: #include <dev/sbus/zxreg.h>
                     95: #include <sparc/dev/sbusvar.h>
                     96:
                     97: #include <dev/cons.h>  /* for prom console hook */
                     98:
                     99: #define        ZX_WID_SHARED_8         0
                    100: #define        ZX_WID_SHARED_24        1
                    101: #define        ZX_WID_DBL_8            2
                    102: #define        ZX_WID_DBL_24           3
                    103:
                    104: /*
                    105:  * Per-instance data.
                    106:  */
                    107:
                    108: struct zx_cmap {
                    109:        u_int8_t        cm_red[256];
                    110:        u_int8_t        cm_green[256];
                    111:        u_int8_t        cm_blue[256];
                    112: };
                    113:
                    114: struct zx_softc {
                    115:        struct  sunfb   sc_sunfb;
                    116:        struct  rom_reg sc_phys;
                    117:
                    118:        struct  zx_cmap sc_cmap;        /* shadow color map for overlay plane */
                    119:
                    120:        volatile struct zx_command *sc_zc;
                    121:        volatile struct zx_cross *sc_zx;
                    122:        volatile struct zx_draw *sc_zd_ss0;
                    123:        volatile struct zx_draw_ss1 *sc_zd_ss1;
                    124:        volatile struct zx_cursor *sc_zcu;
                    125:
                    126:        int     sc_mode;
                    127: };
                    128:
                    129: void   zx_burner(void *, u_int, u_int);
                    130: int    zx_ioctl(void *, u_long, caddr_t, int, struct proc *);
                    131: paddr_t        zx_mmap(void *v, off_t offset, int prot);
                    132: void   zx_prom(void *);
                    133: void   zx_reset(struct zx_softc *, u_int);
                    134: void   zx_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
                    135:
                    136: struct wsdisplay_accessops zx_accessops = {
                    137:        zx_ioctl,
                    138:        zx_mmap,
                    139:        NULL,   /* alloc_screen */
                    140:        NULL,   /* free_screen */
                    141:        NULL,   /* show_screen */
                    142:        NULL,   /* load_font */
                    143:        NULL,   /* scrollback */
                    144:        NULL,   /* getchar */
                    145:        zx_burner,
                    146:        NULL    /* pollc */
                    147: };
                    148:
                    149: /* Force 32-bit writes. */
                    150: #define        SETREG(r, v)    (*((volatile u_int32_t *)&r) = (v))
                    151:
                    152: #define        ZX_STD_ROP      (ZX_ROP_NEW | ZX_ATTR_WE_ENABLE | \
                    153:     ZX_ATTR_OE_ENABLE | ZX_ATTR_FORCE_WID)
                    154:
                    155: #define        ZX_BWIDTH       13
                    156: #define        ZX_WWIDTH       11      /* word width */
                    157:
                    158: #define        ZX_COORDS(x, y) ((x) | ((y) << ZX_WWIDTH))
                    159:
                    160: void   zx_attach(struct device *, struct device *, void *);
                    161: int    zx_match(struct device *, void *, void *);
                    162:
                    163: void   zx_copyrect(struct rasops_info *, int, int, int, int, int, int);
                    164: int    zx_cross_loadwid(struct zx_softc *, u_int, u_int, u_int);
                    165: int    zx_cross_wait(struct zx_softc *);
                    166: void   zx_fillrect(struct rasops_info *, int, int, int, int, long, int);
                    167: int    zx_intr(void *);
                    168: int    zx_putcmap(struct zx_softc *);
                    169:
                    170: void   zx_copycols(void *, int, int, int, int);
                    171: void   zx_copyrows(void *, int, int, int);
                    172: void   zx_do_cursor(struct rasops_info *);
                    173: void   zx_erasecols(void *, int, int, int, long);
                    174: void   zx_eraserows(void *, int, int, long);
                    175: void   zx_putchar(void *, int, int, u_int, long);
                    176:
                    177: struct cfattach zx_ca = {
                    178:        sizeof(struct zx_softc), zx_match, zx_attach
                    179: };
                    180:
                    181: struct cfdriver zx_cd = {
                    182:        NULL, "zx", DV_DULL
                    183: };
                    184:
                    185: int
                    186: zx_match(struct device *parent, void *vcf, void *aux)
                    187: {
                    188:        struct confargs *ca = aux;
                    189:        struct romaux *ra = &ca->ca_ra;
                    190:
                    191:        if (strcmp(ra->ra_name, "SUNW,leo") == 0)
                    192:                return (1);
                    193:
                    194:        return (0);
                    195: }
                    196:
                    197: void
                    198: zx_attach(struct device *parent, struct device *self, void *args)
                    199: {
                    200:        struct zx_softc *sc = (struct zx_softc *)self;
                    201:        struct confargs *ca = args;
                    202:        struct rasops_info *ri;
                    203:        int node, isconsole = 0;
                    204:        const char *nam;
                    205:
                    206:        ri = &sc->sc_sunfb.sf_ro;
                    207:        node = ca->ca_ra.ra_node;
                    208:
                    209:        /*
                    210:         * Map the various parts of the card.
                    211:         */
                    212:        sc->sc_phys = ca->ca_ra.ra_reg[0];
                    213:
                    214:        sc->sc_zc = (struct zx_command *)
                    215:            mapiodev(ca->ca_ra.ra_reg, ZX_OFF_LC_SS0_USR,
                    216:                sizeof(struct zx_command));
                    217:        sc->sc_zd_ss0 = (struct zx_draw *)
                    218:            mapiodev(ca->ca_ra.ra_reg, ZX_OFF_LD_SS0,
                    219:                sizeof(struct zx_draw));
                    220:        sc->sc_zd_ss1 = (struct zx_draw_ss1 *)
                    221:            mapiodev(ca->ca_ra.ra_reg, ZX_OFF_LD_SS1,
                    222:                sizeof(struct zx_draw_ss1));
                    223:        sc->sc_zx = (struct zx_cross *)
                    224:            mapiodev(ca->ca_ra.ra_reg, ZX_OFF_LX_CROSS,
                    225:                sizeof(struct zx_cross));
                    226:        sc->sc_zcu = (struct zx_cursor *)
                    227:            mapiodev(ca->ca_ra.ra_reg, ZX_OFF_LX_CURSOR,
                    228:                sizeof(struct zx_cursor));
                    229:
                    230:        nam = getpropstring(node, "model");
                    231:        if (*nam == '\0')
                    232:                nam = ca->ca_ra.ra_name;
                    233:        printf(": %s", nam);
                    234:
                    235:        isconsole = node == fbnode;
                    236:
                    237:        /*
                    238:         * The console is using the 8-bit overlay plane, while the prom
                    239:         * will correctly report 32 bit depth.
                    240:         * The following is an equivalent for
                    241:         *    fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
                    242:         * forcing the depth value not to be overwritten.
                    243:         * Furthermore, the linebytes value is in fact 8192 bytes.
                    244:         */
                    245:        sc->sc_sunfb.sf_depth = 8;
                    246:        sc->sc_sunfb.sf_width = getpropint(node, "width", 1152);
                    247:        sc->sc_sunfb.sf_height = getpropint(node, "height", 900);
                    248:        sc->sc_sunfb.sf_linebytes = 1 << ZX_BWIDTH;
                    249:        sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height << ZX_BWIDTH;
                    250:
                    251:        printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
                    252:
                    253:        ri->ri_bits = mapiodev(ca->ca_ra.ra_reg,
                    254:            ZX_OFF_SS0, round_page(sc->sc_sunfb.sf_fbsize));
                    255:        ri->ri_hw = sc;
                    256:
                    257:        fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);
                    258:
                    259:        /*
                    260:         * Watch out! rasops_init() invoked via fbwscons_init() did not
                    261:         * compute ri_bits correctly when centering the display, because
                    262:         * it has been tricked with the low depth value.
                    263:         * Recompute now.
                    264:         */
                    265:        ri->ri_emustride = ri->ri_emuwidth * 4;
                    266:        ri->ri_delta = ri->ri_stride - ri->ri_emustride;
                    267:        ri->ri_pelbytes = 4;
                    268:        ri->ri_xscale = ri->ri_font->fontwidth * 4;
                    269:        ri->ri_bits = ri->ri_origbits;
                    270:        ri->ri_bits += (((ri->ri_width * 4) - ri->ri_emustride) >> 1) & ~3;
                    271:        ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
                    272:            ri->ri_stride;
                    273:        ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits)
                    274:            / ri->ri_stride;
                    275:        ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits)
                    276:            % ri->ri_stride) / 4);
                    277:
                    278:        ri->ri_ops.copyrows = zx_copyrows;
                    279:        ri->ri_ops.copycols = zx_copycols;
                    280:        ri->ri_ops.eraserows = zx_eraserows;
                    281:        ri->ri_ops.erasecols = zx_erasecols;
                    282:        ri->ri_ops.putchar = zx_putchar;
                    283:        ri->ri_do_cursor = zx_do_cursor;
                    284:
                    285:        if (isconsole) {
                    286:                /* zx_reset() below will clear screen, so restart at 1st row */
                    287:                fbwscons_console_init(&sc->sc_sunfb, 0);
                    288:                shutdownhook_establish(zx_prom, sc);
                    289:        }
                    290:
                    291:        /* reset cursor & frame buffer controls */
                    292:        sc->sc_mode = ~WSDISPLAYIO_MODE_EMUL;   /* force action */
                    293:        zx_reset(sc, WSDISPLAYIO_MODE_EMUL);
                    294:
                    295:        /* enable video */
                    296:        zx_burner(sc, 1, 0);
                    297:
                    298:        fbwscons_attach(&sc->sc_sunfb, &zx_accessops, isconsole);
                    299: }
                    300:
                    301: int
                    302: zx_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p)
                    303: {
                    304:        struct zx_softc *sc = dev;
                    305:        struct wsdisplay_fbinfo *wdf;
                    306:
                    307:        /*
                    308:         * Note that, although the emulation (text) mode is running in
                    309:         * a 8-bit plane, we advertize the frame buffer as the full-blown
                    310:         * 32-bit beast it is.
                    311:         */
                    312:        switch (cmd) {
                    313:        case WSDISPLAYIO_GTYPE:
                    314:                *(u_int *)data = WSDISPLAY_TYPE_SUN24;
                    315:                break;
                    316:        case WSDISPLAYIO_GINFO:
                    317:                wdf = (struct wsdisplay_fbinfo *)data;
                    318:                wdf->height = sc->sc_sunfb.sf_height;
                    319:                wdf->width = sc->sc_sunfb.sf_width;
                    320:                wdf->depth = 32;
                    321:                wdf->cmsize = 0;
                    322:                break;
                    323:        case WSDISPLAYIO_GETSUPPORTEDDEPTH:
                    324:                *(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
                    325:                break;
                    326:        case WSDISPLAYIO_LINEBYTES:
                    327:                *(u_int *)data = sc->sc_sunfb.sf_linebytes;
                    328:                break;
                    329:
                    330:        case WSDISPLAYIO_GETCMAP:
                    331:        case WSDISPLAYIO_PUTCMAP:
                    332:                break;
                    333:
                    334:        case WSDISPLAYIO_SMODE:
                    335:                zx_reset(sc, *(u_int *)data);
                    336:                break;
                    337:
                    338:        case WSDISPLAYIO_SVIDEO:
                    339:        case WSDISPLAYIO_GVIDEO:
                    340:                break;
                    341:
                    342:        default:
                    343:                return (-1);
                    344:        }
                    345:
                    346:        return (0);
                    347: }
                    348:
                    349: /*
                    350:  * Return the address that would map the given device at the given
                    351:  * offset, allowing for the given protection, or return -1 for error.
                    352:  */
                    353: paddr_t
                    354: zx_mmap(void *v, off_t offset, int prot)
                    355: {
                    356:        struct zx_softc *sc = v;
                    357:
                    358:        if (offset & PGOFSET)
                    359:                return (-1);
                    360:
                    361:        /* Allow mapping as a dumb framebuffer from offset 0 */
                    362:        if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
                    363:                return (REG2PHYS(&sc->sc_phys, ZX_OFF_SS0 + offset) | PMAP_NC);
                    364:        }
                    365:
                    366:        return (-1);
                    367: }
                    368:
                    369: void
                    370: zx_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
                    371: {
                    372:        struct zx_softc *sc = v;
                    373:
                    374:        sc->sc_cmap.cm_red[index] = r;
                    375:        sc->sc_cmap.cm_green[index] = g;
                    376:        sc->sc_cmap.cm_blue[index] = b;
                    377: }
                    378:
                    379: void
                    380: zx_reset(struct zx_softc *sc, u_int mode)
                    381: {
                    382:        volatile struct zx_draw *zd;
                    383:        volatile struct zx_command *zc;
                    384:        u_int32_t i;
                    385:        const u_char *color;
                    386:        u_int8_t *r, *g, *b;
                    387:
                    388:        if (mode == sc->sc_mode)
                    389:                return;
                    390:
                    391:        zd = sc->sc_zd_ss0;
                    392:        zc = sc->sc_zc;
                    393:
                    394:        if (mode == WSDISPLAYIO_MODE_EMUL) {
                    395:                /* Back from X11 to emulation mode, or first reset */
                    396:                zx_cross_loadwid(sc, ZX_WID_DBL_8, 0, 0x2c0);
                    397:                zx_cross_loadwid(sc, ZX_WID_DBL_8, 1, 0x30);
                    398:                zx_cross_loadwid(sc, ZX_WID_DBL_8, 2, 0x20);
                    399:                zx_cross_loadwid(sc, ZX_WID_DBL_24, 1, 0x30);
                    400:
                    401:                i = sc->sc_zd_ss1->zd_misc;
                    402:                i |= ZX_SS1_MISC_ENABLE;
                    403:                SETREG(sc->sc_zd_ss1->zd_misc, i);
                    404:
                    405:                /*
                    406:                 * XXX
                    407:                 * If zc_fill is not set to that value, there will be black
                    408:                 * bars left in the margins. But then with this value, the
                    409:                 * screen gets cleared. Go figure.
                    410:                 */
                    411:                SETREG(zd->zd_wid, 0xffffffff);
                    412:                SETREG(zd->zd_wmask, 0xffff);
                    413:                SETREG(zd->zd_vclipmin, 0);
                    414:                SETREG(zd->zd_vclipmax, (sc->sc_sunfb.sf_width - 1) |
                    415:                    ((sc->sc_sunfb.sf_height - 1) << 16));
                    416:                SETREG(zd->zd_fg, 0);
                    417:                SETREG(zd->zd_planemask, 0xff000000);
                    418:                SETREG(zd->zd_rop, ZX_STD_ROP);
                    419:                SETREG(zd->zd_widclip, 0);
                    420:
                    421:                SETREG(zc->zc_extent, ZX_COORDS(sc->sc_sunfb.sf_width - 1,
                    422:                    sc->sc_sunfb.sf_height - 1));
                    423:                SETREG(zc->zc_addrspace, ZX_ADDRSPC_FONT_OBGR);
                    424:                SETREG(zc->zc_fill, ZX_COORDS(0, 0) | ZX_EXTENT_DIR_BACKWARDS);
                    425:                SETREG(zc->zc_fontt, 0);
                    426:
                    427:                while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    428:                        ;
                    429:
                    430:                /*
                    431:                 * Initialize the 8-bit colormap
                    432:                 */
                    433:                r = sc->sc_cmap.cm_red;
                    434:                g = sc->sc_cmap.cm_green;
                    435:                b = sc->sc_cmap.cm_blue;
                    436:                color = rasops_cmap;
                    437:                for (i = 0; i < 256; i++) {
                    438:                        *r++ = *color++;
                    439:                        *g++ = *color++;
                    440:                        *b++ = *color++;
                    441:                }
                    442:                fbwscons_setcolormap(&sc->sc_sunfb, zx_setcolor);
                    443:                zx_putcmap(sc);
                    444:        } else {
                    445:                /* Starting X11 - switch to 24bit WID */
                    446:                SETREG(zd->zd_wid, 1);
                    447:                SETREG(zd->zd_widclip, 0);
                    448:                SETREG(zd->zd_wmask, 0xffff);
                    449:                SETREG(zd->zd_planemask, 0x00ffffff);
                    450:                SETREG(zc->zc_extent, ZX_COORDS(sc->sc_sunfb.sf_width - 1,
                    451:                    sc->sc_sunfb.sf_height - 1));
                    452:                SETREG(zc->zc_fill, 0);
                    453:                while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    454:                        ;
                    455:
                    456:                SETREG(zc->zc_addrspace, ZX_ADDRSPC_OBGR);
                    457:                SETREG(zd->zd_rop, ZX_ATTR_RGBE_ENABLE |
                    458:                    ZX_ROP_NEW /* | ZX_ATTR_FORCE_WID */);
                    459:        }
                    460:
                    461:        sc->sc_mode = mode;
                    462: }
                    463:
                    464: int
                    465: zx_cross_wait(struct zx_softc *sc)
                    466: {
                    467:        volatile struct zx_cross *zx;
                    468:        int i;
                    469:
                    470:        zx = sc->sc_zx;
                    471:
                    472:        for (i = 300000; i != 0; i--) {
                    473:                if ((zx->zx_csr & ZX_CROSS_CSR_PROGRESS) == 0)
                    474:                        break;
                    475:                DELAY(1);
                    476:        }
                    477:
                    478:        if (i == 0)
                    479:                printf("%s: zx_cross_wait: timed out\n",
                    480:                    sc->sc_sunfb.sf_dev.dv_xname);
                    481:
                    482:        return (i);
                    483: }
                    484:
                    485: int
                    486: zx_cross_loadwid(struct zx_softc *sc, u_int type, u_int index, u_int value)
                    487: {
                    488:        volatile struct zx_cross *zx;
                    489:        u_int tmp;
                    490:
                    491:        zx = sc->sc_zx;
                    492:        SETREG(zx->zx_type, ZX_CROSS_TYPE_WID);
                    493:
                    494:        if (!zx_cross_wait(sc))
                    495:                return (1);
                    496:
                    497:        if (type == ZX_WID_DBL_8)
                    498:                tmp = (index & 0x0f) + 0x40;
                    499:        else if (type == ZX_WID_DBL_24)
                    500:                tmp = index & 0x3f;
                    501:
                    502:        SETREG(zx->zx_type, 0x5800 + tmp);
                    503:        SETREG(zx->zx_value, value);
                    504:        SETREG(zx->zx_type, ZX_CROSS_TYPE_WID);
                    505:        SETREG(zx->zx_csr, ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2);
                    506:
                    507:        return (0);
                    508: }
                    509:
                    510: int
                    511: zx_putcmap(struct zx_softc *sc)
                    512: {
                    513:        volatile struct zx_cross *zx;
                    514:        u_int32_t i;
                    515:        u_int8_t *r, *g, *b;
                    516:
                    517:        zx = sc->sc_zx;
                    518:
                    519:        SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUT0);
                    520:        if (!zx_cross_wait(sc))
                    521:                return (1);
                    522:
                    523:        SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUTDATA);
                    524:
                    525:        r = sc->sc_cmap.cm_red;
                    526:        g = sc->sc_cmap.cm_green;
                    527:        b = sc->sc_cmap.cm_blue;
                    528:        for (i = 0; i < 256; i++) {
                    529:                SETREG(zx->zx_value, *r++ | (*g++ << 8) | (*b++ << 16));
                    530:        }
                    531:
                    532:        SETREG(zx->zx_type, ZX_CROSS_TYPE_CLUT0);
                    533:        i = zx->zx_csr;
                    534:        i = i | ZX_CROSS_CSR_UNK | ZX_CROSS_CSR_UNK2;
                    535:        SETREG(zx->zx_csr, i);
                    536:        return (0);
                    537: }
                    538:
                    539: void
                    540: zx_burner(void *v, u_int on, u_int flags)
                    541: {
                    542:        struct zx_softc *sc = v;
                    543:        volatile struct zx_cross *zx;
                    544:        u_int32_t i;
                    545:
                    546:        zx = sc->sc_zx;
                    547:
                    548:        SETREG(zx->zx_type, ZX_CROSS_TYPE_VIDEO);
                    549:        i = zx->zx_csr;
                    550:        if (on) {
                    551:                i |= ZX_CROSS_CSR_ENABLE;
                    552:        } else {
                    553:                i &= ~ZX_CROSS_CSR_ENABLE;
                    554:        }
                    555:        SETREG(zx->zx_csr, i);
                    556: }
                    557:
                    558: void
                    559: zx_fillrect(struct rasops_info *ri, int x, int y, int w, int h, long attr,
                    560:     int rop)
                    561: {
                    562:        struct zx_softc *sc;
                    563:        volatile struct zx_command *zc;
                    564:        volatile struct zx_draw *zd;
                    565:        int fg, bg;
                    566:
                    567:        sc = ri->ri_hw;
                    568:        zc = sc->sc_zc;
                    569:        zd = sc->sc_zd_ss0;
                    570:
                    571:        ri->ri_ops.unpack_attr(ri, attr, &fg, &bg, NULL);
                    572:        x = x * ri->ri_font->fontwidth + ri->ri_xorigin;
                    573:        y = y * ri->ri_font->fontheight + ri->ri_yorigin;
                    574:        w = ri->ri_font->fontwidth * w - 1;
                    575:        h = ri->ri_font->fontheight * h - 1;
                    576:
                    577:        while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    578:                ;
                    579:
                    580:        SETREG(zd->zd_rop, rop);
                    581:        SETREG(zd->zd_fg, ri->ri_devcmap[bg] << 24);
                    582:        SETREG(zc->zc_extent, ZX_COORDS(w, h));
                    583:        SETREG(zc->zc_fill, ZX_COORDS(x, y) | ZX_EXTENT_DIR_BACKWARDS);
                    584: }
                    585:
                    586: void
                    587: zx_copyrect(struct rasops_info *ri, int sx, int sy, int dx, int dy, int w,
                    588:     int h)
                    589: {
                    590:        struct zx_softc *sc;
                    591:        volatile struct zx_command *zc;
                    592:        volatile struct zx_draw *zd;
                    593:        int dir;
                    594:
                    595:        sc = ri->ri_hw;
                    596:        zc = sc->sc_zc;
                    597:        zd = sc->sc_zd_ss0;
                    598:
                    599:        sx = sx * ri->ri_font->fontwidth + ri->ri_xorigin;
                    600:        sy = sy * ri->ri_font->fontheight + ri->ri_yorigin;
                    601:        dx = dx * ri->ri_font->fontwidth + ri->ri_xorigin;
                    602:        dy = dy * ri->ri_font->fontheight + ri->ri_yorigin;
                    603:        w = w * ri->ri_font->fontwidth - 1;
                    604:        h = h * ri->ri_font->fontheight - 1;
                    605:
                    606:        if (sy < dy || sx < dx) {
                    607:                dir = ZX_EXTENT_DIR_BACKWARDS;
                    608:                sx += w;
                    609:                sy += h;
                    610:                dx += w;
                    611:                dy += h;
                    612:        } else
                    613:                dir = ZX_EXTENT_DIR_FORWARDS;
                    614:
                    615:        while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    616:                ;
                    617:
                    618:        SETREG(zd->zd_rop, ZX_STD_ROP);
                    619:        SETREG(zc->zc_extent, ZX_COORDS(w, h) | dir);
                    620:        SETREG(zc->zc_src, ZX_COORDS(sx, sy));
                    621:        SETREG(zc->zc_copy, ZX_COORDS(dx, dy));
                    622: }
                    623:
                    624: void
                    625: zx_do_cursor(struct rasops_info *ri)
                    626: {
                    627:
                    628:        zx_fillrect(ri, ri->ri_ccol, ri->ri_crow, 1, 1, WSCOL_BLACK << 16,
                    629:            ZX_ROP_NEW_XOR_OLD | ZX_ATTR_WE_ENABLE | ZX_ATTR_OE_ENABLE |
                    630:            ZX_ATTR_FORCE_WID);
                    631: }
                    632:
                    633: void
                    634: zx_erasecols(void *cookie, int row, int col, int num, long attr)
                    635: {
                    636:        struct rasops_info *ri;
                    637:
                    638:        ri = (struct rasops_info *)cookie;
                    639:
                    640:        zx_fillrect(ri, col, row, num, 1, attr, ZX_STD_ROP);
                    641: }
                    642:
                    643: void
                    644: zx_eraserows(void *cookie, int row, int num, long attr)
                    645: {
                    646:        struct rasops_info *ri;
                    647:        struct zx_softc *sc;
                    648:        volatile struct zx_command *zc;
                    649:        volatile struct zx_draw *zd;
                    650:        int fg, bg;
                    651:
                    652:        ri = (struct rasops_info *)cookie;
                    653:
                    654:        if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR)) {
                    655:                sc = ri->ri_hw;
                    656:                zc = sc->sc_zc;
                    657:                zd = sc->sc_zd_ss0;
                    658:
                    659:                ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
                    660:
                    661:                while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    662:                        ;
                    663:
                    664:                SETREG(zd->zd_rop, ZX_STD_ROP);
                    665:                SETREG(zd->zd_fg, ri->ri_devcmap[bg] << 24);
                    666:                SETREG(zc->zc_extent,
                    667:                    ZX_COORDS(ri->ri_width - 1, ri->ri_height - 1));
                    668:                SETREG(zc->zc_fill, ZX_COORDS(0, 0) | ZX_EXTENT_DIR_BACKWARDS);
                    669:        } else
                    670:                zx_fillrect(ri, 0, row, ri->ri_cols, num, attr, ZX_STD_ROP);
                    671: }
                    672:
                    673: void
                    674: zx_copyrows(void *cookie, int src, int dst, int num)
                    675: {
                    676:        struct rasops_info *ri;
                    677:
                    678:        ri = (struct rasops_info *)cookie;
                    679:
                    680:        zx_copyrect(ri, 0, src, 0, dst, ri->ri_cols, num);
                    681: }
                    682:
                    683: void
                    684: zx_copycols(void *cookie, int row, int src, int dst, int num)
                    685: {
                    686:        struct rasops_info *ri;
                    687:
                    688:        ri = (struct rasops_info *)cookie;
                    689:
                    690:        zx_copyrect(ri, src, row, dst, row, num, 1);
                    691: }
                    692:
                    693: void
                    694: zx_putchar(void *cookie, int row, int col, u_int uc, long attr)
                    695: {
                    696:        struct rasops_info *ri;
                    697:        struct zx_softc *sc;
                    698:        struct wsdisplay_font *font;
                    699:        volatile struct zx_command *zc;
                    700:        volatile struct zx_draw *zd;
                    701:        volatile u_int32_t *dp;
                    702:        u_int8_t *fb;
                    703:        int fs, i, fg, bg, ul;
                    704:
                    705:        ri = (struct rasops_info *)cookie;
                    706:        font = ri->ri_font;
                    707:        ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, &ul);
                    708:        fg = ri->ri_devcmap[fg];
                    709:        bg = ri->ri_devcmap[bg];
                    710:
                    711:        dp = (volatile u_int32_t *)ri->ri_bits +
                    712:            ZX_COORDS(col * font->fontwidth, row * font->fontheight);
                    713:
                    714:        if (uc == ' ') {
                    715:                zx_fillrect(ri, col, row, 1, 1, attr, ZX_STD_ROP);
                    716:                if (ul == 0)
                    717:                        return;
                    718:
                    719:                dp += font->fontheight << ZX_WWIDTH;
                    720:
                    721:                while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    722:                        ;
                    723:
                    724:                SETREG(zd->zd_rop, ZX_STD_ROP);
                    725:                SETREG(zd->zd_fg, fg << 24);
                    726:                SETREG(zd->zd_bg, bg << 24);
                    727:                SETREG(zc->zc_fontmsk, 0xffffffff << (32 - font->fontwidth));
                    728:        } else {
                    729:                sc = ri->ri_hw;
                    730:                zc = sc->sc_zc;
                    731:                zd = sc->sc_zd_ss0;
                    732:
                    733:                fb = (u_int8_t *)font->data + (uc - font->firstchar) *
                    734:                    ri->ri_fontscale;
                    735:                fs = font->stride;
                    736:
                    737:                while ((zc->zc_csr & ZX_CSR_BLT_BUSY) != 0)
                    738:                        ;
                    739:
                    740:                SETREG(zd->zd_rop, ZX_STD_ROP);
                    741:                SETREG(zd->zd_fg, fg << 24);
                    742:                SETREG(zd->zd_bg, bg << 24);
                    743:                SETREG(zc->zc_fontmsk, 0xffffffff << (32 - font->fontwidth));
                    744:
                    745:                if (font->fontwidth <= 8) {
                    746:                        for (i = font->fontheight; i != 0;
                    747:                            i--, dp += 1 << ZX_WWIDTH) {
                    748:                                *dp = *fb << 24;
                    749:                                fb += fs;
                    750:                        }
                    751:                } else {
                    752:                        for (i = font->fontheight; i != 0;
                    753:                            i--, dp += 1 << ZX_WWIDTH) {
                    754:                                *dp = *((u_int16_t *)fb) << 16;
                    755:                                fb += fs;
                    756:                        }
                    757:                }
                    758:        }
                    759:
                    760:        /* underline */
                    761:        if (ul) {
                    762:                dp -= 2 << ZX_WWIDTH;
                    763:                *dp = 0xffffffff;
                    764:        }
                    765: }
                    766:
                    767: void
                    768: zx_prom(void *v)
                    769: {
                    770:        struct zx_softc *sc = v;
                    771:        extern struct consdev consdev_prom;
                    772:
                    773:        if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) {
                    774:                /*
                    775:                 * Select 8-bit mode.
                    776:                 */
                    777:                zx_reset(sc, WSDISPLAYIO_MODE_EMUL);
                    778:
                    779:                /*
                    780:                 * Go back to prom output for the last few messages, so they
                    781:                 * will be displayed correctly.
                    782:                 */
                    783:                cn_tab = &consdev_prom;
                    784:        }
                    785: }

CVSweb