[BACK]Return to cgsix.c CVS log [TXT][DIR] Up to [local] / sys / dev / sbus

Annotation of sys/dev/sbus/cgsix.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: cgsix.c,v 1.56 2006/12/17 22:18:16 miod Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2001 Jason L. Wright (jason@thought.net)
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  *
        !            16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            18:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            19:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            20:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            21:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            22:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            24:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            25:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            26:  * POSSIBILITY OF SUCH DAMAGE.
        !            27:  *
        !            28:  * Effort sponsored in part by the Defense Advanced Research Projects
        !            29:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
        !            30:  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
        !            31:  *
        !            32:  */
        !            33:
        !            34: #include <sys/param.h>
        !            35: #include <sys/systm.h>
        !            36: #include <sys/kernel.h>
        !            37: #include <sys/errno.h>
        !            38: #include <sys/device.h>
        !            39: #include <sys/ioctl.h>
        !            40: #include <sys/malloc.h>
        !            41:
        !            42: #include <machine/bus.h>
        !            43: #include <machine/intr.h>
        !            44: #include <machine/autoconf.h>
        !            45: #include <machine/openfirm.h>
        !            46:
        !            47: #include <dev/sbus/sbusvar.h>
        !            48: #include <dev/wscons/wsconsio.h>
        !            49: #include <dev/wscons/wsdisplayvar.h>
        !            50: #include <dev/rasops/rasops.h>
        !            51: #include <machine/fbvar.h>
        !            52: #include <dev/sbus/cgsixreg.h>
        !            53: #include <dev/ic/bt458reg.h>
        !            54:
        !            55: int cgsix_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !            56: int cgsix_alloc_screen(void *, const struct wsscreen_descr *, void **,
        !            57:     int *, int *, long *);
        !            58: void cgsix_free_screen(void *, void *);
        !            59: int cgsix_show_screen(void *, void *, int, void (*cb)(void *, int, int),
        !            60:     void *);
        !            61: paddr_t cgsix_mmap(void *, off_t, int);
        !            62: int cgsix_is_console(int);
        !            63: int cg6_bt_getcmap(union bt_cmap *, struct wsdisplay_cmap *);
        !            64: int cg6_bt_putcmap(union bt_cmap *, struct wsdisplay_cmap *);
        !            65: void cgsix_loadcmap_immediate(struct cgsix_softc *, u_int, u_int);
        !            66: void cgsix_loadcmap_deferred(struct cgsix_softc *, u_int, u_int);
        !            67: void cgsix_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
        !            68: void cgsix_reset(struct cgsix_softc *, u_int32_t);
        !            69: void cgsix_hardreset(struct cgsix_softc *);
        !            70: void cgsix_burner(void *, u_int, u_int);
        !            71: int cgsix_intr(void *);
        !            72: void cgsix_ras_init(struct cgsix_softc *);
        !            73: void cgsix_ras_copyrows(void *, int, int, int);
        !            74: void cgsix_ras_copycols(void *, int, int, int, int);
        !            75: void cgsix_ras_erasecols(void *, int, int, int, long int);
        !            76: void cgsix_ras_eraserows(void *, int, int, long int);
        !            77: void cgsix_ras_do_cursor(struct rasops_info *);
        !            78: int cgsix_setcursor(struct cgsix_softc *, struct wsdisplay_cursor *);
        !            79: int cgsix_updatecursor(struct cgsix_softc *, u_int);
        !            80:
        !            81: struct wsdisplay_accessops cgsix_accessops = {
        !            82:        cgsix_ioctl,
        !            83:        cgsix_mmap,
        !            84:        cgsix_alloc_screen,
        !            85:        cgsix_free_screen,
        !            86:        cgsix_show_screen,
        !            87:        NULL,   /* load_font */
        !            88:        NULL,   /* scrollback */
        !            89:        NULL,   /* getchar */
        !            90:        cgsix_burner,
        !            91: };
        !            92:
        !            93: int    cgsixmatch(struct device *, void *, void *);
        !            94: void   cgsixattach(struct device *, struct device *, void *);
        !            95:
        !            96: struct cfattach cgsix_ca = {
        !            97:        sizeof (struct cgsix_softc), cgsixmatch, cgsixattach
        !            98: };
        !            99:
        !           100: struct cfdriver cgsix_cd = {
        !           101:        NULL, "cgsix", DV_DULL
        !           102: };
        !           103:
        !           104: int
        !           105: cgsixmatch(struct device *parent, void *vcf, void *aux)
        !           106: {
        !           107:        struct cfdata *cf = vcf;
        !           108:        struct sbus_attach_args *sa = aux;
        !           109:
        !           110:        return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0);
        !           111: }
        !           112:
        !           113: void
        !           114: cgsixattach(struct device *parent, struct device *self, void *aux)
        !           115: {
        !           116:        struct cgsix_softc *sc = (struct cgsix_softc *)self;
        !           117:        struct sbus_attach_args *sa = aux;
        !           118:        int node, console;
        !           119:        u_int32_t fhc, rev;
        !           120:        const char *nam;
        !           121:
        !           122:        node = sa->sa_node;
        !           123:        sc->sc_bustag = sa->sa_bustag;
        !           124:        sc->sc_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_slot, sa->sa_offset);
        !           125:
        !           126:        if (sa->sa_nreg != 1) {
        !           127:                printf(": expected %d registers, got %d\n", 1, sa->sa_nreg);
        !           128:                goto fail;
        !           129:        }
        !           130:
        !           131:        fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);
        !           132:
        !           133:        /*
        !           134:         * Map just BT, FHC, FBC, THC, and video RAM.
        !           135:         */
        !           136:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           137:            sa->sa_reg[0].sbr_offset + CGSIX_BT_OFFSET,
        !           138:            CGSIX_BT_SIZE, 0, 0, &sc->sc_bt_regs) != 0) {
        !           139:                printf(": cannot map bt registers\n");
        !           140:                goto fail_bt;
        !           141:        }
        !           142:
        !           143:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           144:            sa->sa_reg[0].sbr_offset + CGSIX_FHC_OFFSET,
        !           145:            CGSIX_FHC_SIZE, 0, 0, &sc->sc_fhc_regs) != 0) {
        !           146:                printf(": cannot map fhc registers\n");
        !           147:                goto fail_fhc;
        !           148:        }
        !           149:
        !           150:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           151:            sa->sa_reg[0].sbr_offset + CGSIX_THC_OFFSET,
        !           152:            CGSIX_THC_SIZE, 0, 0, &sc->sc_thc_regs) != 0) {
        !           153:                printf(": cannot map thc registers\n");
        !           154:                goto fail_thc;
        !           155:        }
        !           156:
        !           157:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           158:            sa->sa_reg[0].sbr_offset + CGSIX_VID_OFFSET,
        !           159:            sc->sc_sunfb.sf_fbsize, BUS_SPACE_MAP_LINEAR,
        !           160:            0, &sc->sc_vid_regs) != 0) {
        !           161:                printf(": cannot map vid registers\n");
        !           162:                goto fail_vid;
        !           163:        }
        !           164:
        !           165:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           166:            sa->sa_reg[0].sbr_offset + CGSIX_TEC_OFFSET,
        !           167:            CGSIX_TEC_SIZE, 0, 0, &sc->sc_tec_regs) != 0) {
        !           168:                printf(": cannot map tec registers\n");
        !           169:                goto fail_tec;
        !           170:        }
        !           171:
        !           172:        if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
        !           173:            sa->sa_reg[0].sbr_offset + CGSIX_FBC_OFFSET,
        !           174:            CGSIX_FBC_SIZE, 0, 0, &sc->sc_fbc_regs) != 0) {
        !           175:                printf(": cannot map fbc registers\n");
        !           176:                goto fail_fbc;
        !           177:        }
        !           178:
        !           179:        if ((sc->sc_ih = bus_intr_establish(sa->sa_bustag, sa->sa_pri,
        !           180:            IPL_TTY, 0, cgsix_intr, sc, self->dv_xname)) == NULL) {
        !           181:                printf(": couldn't establish interrupt, pri %d\n%s",
        !           182:                    INTLEV(sa->sa_pri), self->dv_xname);
        !           183:        }
        !           184:
        !           185:        /* if prom didn't initialize us, do it the hard way */
        !           186:        if (OF_getproplen(node, "width") != sizeof(u_int32_t))
        !           187:                cgsix_hardreset(sc);
        !           188:
        !           189:        nam = getpropstring(node, "model");
        !           190:        if (*nam == '\0')
        !           191:                nam = sa->sa_name;
        !           192:        printf(": %s", nam);
        !           193:
        !           194:        console = cgsix_is_console(node);
        !           195:
        !           196:        fhc = FHC_READ(sc);
        !           197:        rev = (fhc & FHC_REV_MASK) >> FHC_REV_SHIFT;
        !           198:        cgsix_reset(sc, rev);
        !           199:
        !           200:        cgsix_burner(sc, 1, 0);
        !           201:
        !           202:        sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bustag,
        !           203:            sc->sc_vid_regs);
        !           204:        sc->sc_sunfb.sf_ro.ri_hw = sc;
        !           205:        fbwscons_init(&sc->sc_sunfb, console ? 0 : RI_CLEAR);
        !           206:
        !           207:        /*
        !           208:         * Old rev. cg6 cards do not like the current acceleration code.
        !           209:         *
        !           210:         * Some hints from Sun point out at timing and cache problems, which
        !           211:         * will be investigated later.
        !           212:         */
        !           213:        if (rev < 5)
        !           214:                sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags |= CG6_CFFLAG_NOACCEL;
        !           215:
        !           216:        if ((sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags & CG6_CFFLAG_NOACCEL)
        !           217:            == 0) {
        !           218:                sc->sc_sunfb.sf_ro.ri_ops.copyrows = cgsix_ras_copyrows;
        !           219:                sc->sc_sunfb.sf_ro.ri_ops.copycols = cgsix_ras_copycols;
        !           220:                sc->sc_sunfb.sf_ro.ri_ops.eraserows = cgsix_ras_eraserows;
        !           221:                sc->sc_sunfb.sf_ro.ri_ops.erasecols = cgsix_ras_erasecols;
        !           222:                sc->sc_sunfb.sf_ro.ri_do_cursor = cgsix_ras_do_cursor;
        !           223:                cgsix_ras_init(sc);
        !           224:        }
        !           225:
        !           226:        printf(", %dx%d, rev %d\n", sc->sc_sunfb.sf_width,
        !           227:            sc->sc_sunfb.sf_height, rev);
        !           228:
        !           229:        fbwscons_setcolormap(&sc->sc_sunfb, cgsix_setcolor);
        !           230:
        !           231:        if (console) {
        !           232:                fbwscons_console_init(&sc->sc_sunfb, -1);
        !           233:        }
        !           234:
        !           235:        fbwscons_attach(&sc->sc_sunfb, &cgsix_accessops, console);
        !           236:
        !           237:        return;
        !           238:
        !           239: fail_fbc:
        !           240:        bus_space_unmap(sa->sa_bustag, sc->sc_tec_regs, CGSIX_TEC_SIZE);
        !           241: fail_tec:
        !           242:        bus_space_unmap(sa->sa_bustag, sc->sc_vid_regs, sc->sc_sunfb.sf_fbsize);
        !           243: fail_vid:
        !           244:        bus_space_unmap(sa->sa_bustag, sc->sc_thc_regs, CGSIX_THC_SIZE);
        !           245: fail_thc:
        !           246:        bus_space_unmap(sa->sa_bustag, sc->sc_fhc_regs, CGSIX_FHC_SIZE);
        !           247: fail_fhc:
        !           248:        bus_space_unmap(sa->sa_bustag, sc->sc_bt_regs, CGSIX_BT_SIZE);
        !           249: fail_bt:
        !           250: fail:
        !           251:        return;
        !           252: }
        !           253:
        !           254: int
        !           255: cgsix_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
        !           256: {
        !           257:        struct cgsix_softc *sc = v;
        !           258:        struct wsdisplay_cmap *cm;
        !           259:        struct wsdisplay_fbinfo *wdf;
        !           260:        struct wsdisplay_cursor *curs;
        !           261:        struct wsdisplay_curpos *pos;
        !           262:        u_char r[2], g[2], b[2];
        !           263:        int error, s;
        !           264:        u_int mode;
        !           265:
        !           266:        switch (cmd) {
        !           267:        case WSDISPLAYIO_GTYPE:
        !           268:                *(u_int *)data = WSDISPLAY_TYPE_SUNCG6;
        !           269:                break;
        !           270:        case WSDISPLAYIO_SMODE:
        !           271:                mode = *(u_int *)data;
        !           272:                if ((sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags &
        !           273:                    CG6_CFFLAG_NOACCEL) == 0) {
        !           274:                        if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL &&
        !           275:                            mode == WSDISPLAYIO_MODE_EMUL)
        !           276:                                cgsix_ras_init(sc);
        !           277:                }
        !           278:                sc->sc_mode = mode;
        !           279:                break;
        !           280:        case WSDISPLAYIO_GINFO:
        !           281:                wdf = (void *)data;
        !           282:                wdf->height = sc->sc_sunfb.sf_height;
        !           283:                wdf->width  = sc->sc_sunfb.sf_width;
        !           284:                wdf->depth  = sc->sc_sunfb.sf_depth;
        !           285:                wdf->cmsize = 256;
        !           286:                break;
        !           287:        case WSDISPLAYIO_LINEBYTES:
        !           288:                *(u_int *)data = sc->sc_sunfb.sf_linebytes;
        !           289:                break;
        !           290:        case WSDISPLAYIO_GETCMAP:
        !           291:                cm = (struct wsdisplay_cmap *)data;
        !           292:                error = cg6_bt_getcmap(&sc->sc_cmap, cm);
        !           293:                if (error)
        !           294:                        return (error);
        !           295:                break;
        !           296:        case WSDISPLAYIO_PUTCMAP:
        !           297:                cm = (struct wsdisplay_cmap *)data;
        !           298:                error = cg6_bt_putcmap(&sc->sc_cmap, cm);
        !           299:                if (error)
        !           300:                        return (error);
        !           301:                /* if we can handle interrupts, defer the update */
        !           302:                if (sc->sc_ih != NULL)
        !           303:                        cgsix_loadcmap_deferred(sc, cm->index, cm->count);
        !           304:                else
        !           305:                        cgsix_loadcmap_immediate(sc, cm->index, cm->count);
        !           306:                break;
        !           307:        case WSDISPLAYIO_SCURSOR:
        !           308:                curs = (struct wsdisplay_cursor *)data;
        !           309:                return (cgsix_setcursor(sc, curs));
        !           310:        case WSDISPLAYIO_GCURSOR:
        !           311:                curs = (struct wsdisplay_cursor *)data;
        !           312:                if (curs->which & WSDISPLAY_CURSOR_DOCUR)
        !           313:                        curs->enable = sc->sc_curs_enabled;
        !           314:                if (curs->which & WSDISPLAY_CURSOR_DOPOS) {
        !           315:                        curs->pos.x = sc->sc_curs_pos.x;
        !           316:                        curs->pos.y = sc->sc_curs_pos.y;
        !           317:                }
        !           318:                if (curs->which & WSDISPLAY_CURSOR_DOHOT) {
        !           319:                        curs->hot.x = sc->sc_curs_hot.x;
        !           320:                        curs->hot.y = sc->sc_curs_hot.y;
        !           321:                }
        !           322:                if (curs->which & WSDISPLAY_CURSOR_DOCMAP) {
        !           323:                        curs->cmap.index = 0;
        !           324:                        curs->cmap.count = 2;
        !           325:                        r[0] = sc->sc_curs_fg >> 16;
        !           326:                        g[0] = sc->sc_curs_fg >> 8;
        !           327:                        b[0] = sc->sc_curs_fg >> 0;
        !           328:                        r[1] = sc->sc_curs_bg >> 16;
        !           329:                        g[1] = sc->sc_curs_bg >> 8;
        !           330:                        b[1] = sc->sc_curs_bg >> 0;
        !           331:                        error = copyout(r, curs->cmap.red, sizeof(r));
        !           332:                        if (error)
        !           333:                                return (error);
        !           334:                        error = copyout(g, curs->cmap.green, sizeof(g));
        !           335:                        if (error)
        !           336:                                return (error);
        !           337:                        error = copyout(b, curs->cmap.blue, sizeof(b));
        !           338:                        if (error)
        !           339:                                return (error);
        !           340:                }
        !           341:                if (curs->which & WSDISPLAY_CURSOR_DOSHAPE) {
        !           342:                        size_t l;
        !           343:
        !           344:                        curs->size.x = sc->sc_curs_size.x;
        !           345:                        curs->size.y = sc->sc_curs_size.y;
        !           346:                        l = (sc->sc_curs_size.x * sc->sc_curs_size.y) / NBBY;
        !           347:                        error = copyout(sc->sc_curs_image, curs->image, l);
        !           348:                        if (error)
        !           349:                                return (error);
        !           350:                        error = copyout(sc->sc_curs_mask, curs->mask, l);
        !           351:                        if (error)
        !           352:                                return (error);
        !           353:                }
        !           354:                break;
        !           355:        case WSDISPLAYIO_GCURPOS:
        !           356:                pos = (struct wsdisplay_curpos *)data;
        !           357:                pos->x = sc->sc_curs_pos.x;
        !           358:                pos->y = sc->sc_curs_pos.y;
        !           359:                break;
        !           360:        case WSDISPLAYIO_SCURPOS:
        !           361:                pos = (struct wsdisplay_curpos *)data;
        !           362:                s = spltty();
        !           363:                sc->sc_curs_pos.x = pos->x;
        !           364:                sc->sc_curs_pos.y = pos->y;
        !           365:                cgsix_updatecursor(sc, WSDISPLAY_CURSOR_DOPOS);
        !           366:                splx(s);
        !           367:                break;
        !           368:        case WSDISPLAYIO_GCURMAX:
        !           369:                pos = (struct wsdisplay_curpos *)data;
        !           370:                pos->x = pos->y = 32;
        !           371:                break;
        !           372:        case WSDISPLAYIO_SVIDEO:
        !           373:        case WSDISPLAYIO_GVIDEO:
        !           374:                break;
        !           375:        default:
        !           376:                return -1; /* not supported */
        !           377:         }
        !           378:
        !           379:        return (0);
        !           380: }
        !           381:
        !           382: int
        !           383: cgsix_setcursor(struct cgsix_softc *sc, struct wsdisplay_cursor *curs)
        !           384: {
        !           385:        u_int8_t r[2], g[2], b[2], image[128], mask[128];
        !           386:        int s, error;
        !           387:        size_t imcount;
        !           388:
        !           389:        /*
        !           390:         * Do stuff that can generate errors first, then we'll blast it
        !           391:         * all at once.
        !           392:         */
        !           393:        if (curs->which & WSDISPLAY_CURSOR_DOCMAP) {
        !           394:                if (curs->cmap.count < 2)
        !           395:                        return (EINVAL);
        !           396:                error = copyin(curs->cmap.red, r, sizeof(r));
        !           397:                if (error)
        !           398:                        return (error);
        !           399:                error = copyin(curs->cmap.green, g, sizeof(g));
        !           400:                if (error)
        !           401:                        return (error);
        !           402:                error = copyin(curs->cmap.blue, b, sizeof(b));
        !           403:                if (error)
        !           404:                        return (error);
        !           405:        }
        !           406:
        !           407:        if (curs->which & WSDISPLAY_CURSOR_DOSHAPE) {
        !           408:                if (curs->size.x > CG6_MAX_CURSOR ||
        !           409:                    curs->size.y > CG6_MAX_CURSOR)
        !           410:                        return (EINVAL);
        !           411:                imcount = (curs->size.x * curs->size.y) / NBBY;
        !           412:                error = copyin(curs->image, image, imcount);
        !           413:                if (error)
        !           414:                        return (error);
        !           415:                error = copyin(curs->mask, mask, imcount);
        !           416:                if (error)
        !           417:                        return (error);
        !           418:        }
        !           419:
        !           420:        /*
        !           421:         * Ok, everything is in kernel space and sane, update state.
        !           422:         */
        !           423:        s = spltty();
        !           424:
        !           425:        if (curs->which & WSDISPLAY_CURSOR_DOCUR)
        !           426:                sc->sc_curs_enabled = curs->enable;
        !           427:        if (curs->which & WSDISPLAY_CURSOR_DOPOS) {
        !           428:                sc->sc_curs_pos.x = curs->pos.x;
        !           429:                sc->sc_curs_pos.y = curs->pos.y;
        !           430:        }
        !           431:        if (curs->which & WSDISPLAY_CURSOR_DOHOT) {
        !           432:                sc->sc_curs_hot.x = curs->hot.x;
        !           433:                sc->sc_curs_hot.y = curs->hot.y;
        !           434:        }
        !           435:        if (curs->which & WSDISPLAY_CURSOR_DOCMAP) {
        !           436:                sc->sc_curs_fg = ((r[0] << 16) | (g[0] << 8) | (b[0] << 0));
        !           437:                sc->sc_curs_bg = ((r[1] << 16) | (g[1] << 8) | (b[1] << 0));
        !           438:        }
        !           439:        if (curs->which & WSDISPLAY_CURSOR_DOSHAPE) {
        !           440:                sc->sc_curs_size.x = curs->size.x;
        !           441:                sc->sc_curs_size.y = curs->size.y;
        !           442:                bcopy(image, sc->sc_curs_image, imcount);
        !           443:                bcopy(mask, sc->sc_curs_mask, imcount);
        !           444:        }
        !           445:
        !           446:        cgsix_updatecursor(sc, curs->which);
        !           447:        splx(s);
        !           448:
        !           449:        return (0);
        !           450: }
        !           451:
        !           452: int
        !           453: cgsix_updatecursor(struct cgsix_softc *sc, u_int which)
        !           454: {
        !           455:        if (which & WSDISPLAY_CURSOR_DOCMAP) {
        !           456:                BT_WRITE(sc, BT_ADDR, BT_OV1 << 24);
        !           457:                BT_WRITE(sc, BT_OMAP,
        !           458:                    ((sc->sc_curs_fg & 0x00ff0000) >> 16) << 24);
        !           459:                BT_WRITE(sc, BT_OMAP,
        !           460:                    ((sc->sc_curs_fg & 0x0000ff00) >> 8) << 24);
        !           461:                BT_WRITE(sc, BT_OMAP,
        !           462:                    ((sc->sc_curs_fg & 0x000000ff) >> 0) << 24);
        !           463:
        !           464:                BT_WRITE(sc, BT_ADDR, BT_OV3 << 24);
        !           465:                BT_WRITE(sc, BT_OMAP,
        !           466:                    ((sc->sc_curs_bg & 0x00ff0000) >> 16) << 24);
        !           467:                BT_WRITE(sc, BT_OMAP,
        !           468:                    ((sc->sc_curs_bg & 0x0000ff00) >> 8) << 24);
        !           469:                BT_WRITE(sc, BT_OMAP,
        !           470:                    ((sc->sc_curs_bg & 0x000000ff) >> 0) << 24);
        !           471:        }
        !           472:
        !           473:        if (which & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
        !           474:                u_int32_t x, y;
        !           475:
        !           476:                x = sc->sc_curs_pos.x + CG6_MAX_CURSOR - sc->sc_curs_hot.x;
        !           477:                y = sc->sc_curs_pos.y + CG6_MAX_CURSOR - sc->sc_curs_hot.y;
        !           478:                THC_WRITE(sc, CG6_THC_CURSXY,
        !           479:                    ((x & 0xffff) << 16) | (y & 0xffff));
        !           480:        }
        !           481:
        !           482:        if (which & WSDISPLAY_CURSOR_DOCUR) {
        !           483:                u_int32_t c;
        !           484:
        !           485:                /* Enable or disable the cursor overlay planes */
        !           486:                if (sc->sc_curs_enabled) {
        !           487:                        BT_WRITE(sc, BT_ADDR, BT_CR << 24);
        !           488:                        c = BT_READ(sc, BT_CTRL);
        !           489:                        c |= (BTCR_DISPENA_OV0 | BTCR_DISPENA_OV1) << 24;
        !           490:                        BT_WRITE(sc, BT_CTRL, c);
        !           491:                } else {
        !           492:                        BT_WRITE(sc, BT_ADDR, BT_CR << 24);
        !           493:                        c = BT_READ(sc, BT_CTRL);
        !           494:                        c &= ~((BTCR_DISPENA_OV0 | BTCR_DISPENA_OV1) << 24);
        !           495:                        BT_WRITE(sc, BT_CTRL, c);
        !           496:                        THC_WRITE(sc, CG6_THC_CURSXY, THC_CURSOFF);
        !           497:                }
        !           498:        }
        !           499:
        !           500:        return (0);
        !           501: }
        !           502:
        !           503: int
        !           504: cgsix_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
        !           505:     int *curxp, int *curyp, long *attrp)
        !           506: {
        !           507:        struct cgsix_softc *sc = v;
        !           508:
        !           509:        if (sc->sc_nscreens > 0)
        !           510:                return (ENOMEM);
        !           511:
        !           512:        *cookiep = &sc->sc_sunfb.sf_ro;
        !           513:        *curyp = 0;
        !           514:        *curxp = 0;
        !           515:        sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
        !           516:            WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp);
        !           517:        sc->sc_nscreens++;
        !           518:        return (0);
        !           519: }
        !           520:
        !           521: void
        !           522: cgsix_free_screen(void *v, void *cookie)
        !           523: {
        !           524:        struct cgsix_softc *sc = v;
        !           525:
        !           526:        sc->sc_nscreens--;
        !           527: }
        !           528:
        !           529: int
        !           530: cgsix_show_screen(void *v, void *cookie, int waitok,
        !           531:     void (*cb)(void *, int, int), void *cbarg)
        !           532: {
        !           533:        return (0);
        !           534: }
        !           535:
        !           536: struct mmo {
        !           537:        off_t mo_uaddr;
        !           538:        bus_size_t mo_size;
        !           539:        bus_size_t mo_physoff;
        !           540: };
        !           541:
        !           542: paddr_t
        !           543: cgsix_mmap(void *v, off_t off, int prot)
        !           544: {
        !           545:        struct cgsix_softc *sc = v;
        !           546:        struct mmo *mo;
        !           547:        bus_addr_t u;
        !           548:        bus_size_t sz;
        !           549:
        !           550:        static struct mmo mmo[] = {
        !           551:                { CG6_USER_RAM, 0, CGSIX_VID_OFFSET },
        !           552:
        !           553:                /* do not actually know how big most of these are! */
        !           554:                { CG6_USER_FBC, 1, CGSIX_FBC_OFFSET },
        !           555:                { CG6_USER_TEC, 1, CGSIX_TEC_OFFSET },
        !           556:                { CG6_USER_BTREGS, 8192 /* XXX */, CGSIX_BT_OFFSET },
        !           557:                { CG6_USER_FHC, 1, CGSIX_FHC_OFFSET },
        !           558:                { CG6_USER_THC, CGSIX_THC_SIZE, CGSIX_THC_OFFSET },
        !           559:                { CG6_USER_ROM, 65536, CGSIX_ROM_OFFSET },
        !           560:                { CG6_USER_DHC, 1, CGSIX_DHC_OFFSET },
        !           561:        };
        !           562: #define        NMMO (sizeof mmo / sizeof *mmo)
        !           563:
        !           564:        if (off & PGOFSET || off < 0)
        !           565:                return (-1);
        !           566:
        !           567:        switch (sc->sc_mode) {
        !           568:        case WSDISPLAYIO_MODE_MAPPED:
        !           569:                for (mo = mmo; mo < &mmo[NMMO]; mo++) {
        !           570:                        if (off < mo->mo_uaddr)
        !           571:                                continue;
        !           572:                        u = off - mo->mo_uaddr;
        !           573:                        sz = mo->mo_size ? mo->mo_size : sc->sc_sunfb.sf_fbsize;
        !           574:                        if (u < sz) {
        !           575:                                return (bus_space_mmap(sc->sc_bustag,
        !           576:                                    sc->sc_paddr, u + mo->mo_physoff,
        !           577:                                    prot, BUS_SPACE_MAP_LINEAR));
        !           578:                        }
        !           579:                }
        !           580:                break;
        !           581:
        !           582:        case WSDISPLAYIO_MODE_DUMBFB:
        !           583:                /* Allow mapping as a dumb framebuffer from offset 0 */
        !           584:                if (off >= 0 && off < sc->sc_sunfb.sf_fbsize)
        !           585:                        return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
        !           586:                            off + CGSIX_VID_OFFSET, prot,
        !           587:                            BUS_SPACE_MAP_LINEAR));
        !           588:                break;
        !           589:        }
        !           590:
        !           591:        return (-1);
        !           592: }
        !           593:
        !           594: int
        !           595: cgsix_is_console(int node)
        !           596: {
        !           597:        extern int fbnode;
        !           598:
        !           599:        return (fbnode == node);
        !           600: }
        !           601:
        !           602: int
        !           603: cg6_bt_getcmap(union bt_cmap *bcm, struct wsdisplay_cmap *rcm)
        !           604: {
        !           605:        u_int index = rcm->index, count = rcm->count, i;
        !           606:        int error;
        !           607:
        !           608:        if (index >= 256 || count > 256 - index)
        !           609:                return (EINVAL);
        !           610:        for (i = 0; i < count; i++) {
        !           611:                if ((error = copyout(&bcm->cm_map[index + i][0],
        !           612:                    &rcm->red[i], 1)) != 0)
        !           613:                        return (error);
        !           614:                if ((error = copyout(&bcm->cm_map[index + i][1],
        !           615:                    &rcm->green[i], 1)) != 0)
        !           616:                        return (error);
        !           617:                if ((error = copyout(&bcm->cm_map[index + i][2],
        !           618:                    &rcm->blue[i], 1)) != 0)
        !           619:                        return (error);
        !           620:        }
        !           621:        return (0);
        !           622: }
        !           623:
        !           624: int
        !           625: cg6_bt_putcmap(union bt_cmap *bcm, struct wsdisplay_cmap *rcm)
        !           626: {
        !           627:        u_int index = rcm->index, count = rcm->count, i;
        !           628:        int error;
        !           629:
        !           630:        if (index >= 256 || count > 256 - index)
        !           631:                return (EINVAL);
        !           632:        for (i = 0; i < count; i++) {
        !           633:                if ((error = copyin(&rcm->red[i],
        !           634:                    &bcm->cm_map[index + i][0], 1)) != 0)
        !           635:                        return (error);
        !           636:                if ((error = copyin(&rcm->green[i],
        !           637:                    &bcm->cm_map[index + i][1], 1)) != 0)
        !           638:                        return (error);
        !           639:                if ((error = copyin(&rcm->blue[i],
        !           640:                    &bcm->cm_map[index + i][2], 1)) != 0)
        !           641:                        return (error);
        !           642:        }
        !           643:        return (0);
        !           644: }
        !           645:
        !           646: void
        !           647: cgsix_loadcmap_deferred(struct cgsix_softc *sc, u_int start, u_int ncolors)
        !           648: {
        !           649:        u_int32_t thcm;
        !           650:
        !           651:        thcm = THC_READ(sc, CG6_THC_MISC);
        !           652:        thcm &= ~THC_MISC_RESET;
        !           653:        thcm |= THC_MISC_INTEN;
        !           654:        THC_WRITE(sc, CG6_THC_MISC, thcm);
        !           655: }
        !           656:
        !           657: void
        !           658: cgsix_loadcmap_immediate(struct cgsix_softc *sc, u_int start, u_int ncolors)
        !           659: {
        !           660:        u_int cstart;
        !           661:        u_int32_t v;
        !           662:        int count;
        !           663:
        !           664:        cstart = BT_D4M3(start);
        !           665:        count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
        !           666:        BT_WRITE(sc, BT_ADDR, BT_D4M4(start) << 24);
        !           667:        while (--count >= 0) {
        !           668:                v = sc->sc_cmap.cm_chip[cstart];
        !           669:                BT_WRITE(sc, BT_CMAP, v << 0);
        !           670:                BT_WRITE(sc, BT_CMAP, v << 8);
        !           671:                BT_WRITE(sc, BT_CMAP, v << 16);
        !           672:                BT_WRITE(sc, BT_CMAP, v << 24);
        !           673:                cstart++;
        !           674:        }
        !           675: }
        !           676:
        !           677: void
        !           678: cgsix_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
        !           679: {
        !           680:        struct cgsix_softc *sc = v;
        !           681:        union bt_cmap *bcm = &sc->sc_cmap;
        !           682:
        !           683:        bcm->cm_map[index][0] = r;
        !           684:        bcm->cm_map[index][1] = g;
        !           685:        bcm->cm_map[index][2] = b;
        !           686:        cgsix_loadcmap_immediate(sc, index, 1);
        !           687: }
        !           688:
        !           689: void
        !           690: cgsix_reset(struct cgsix_softc *sc, u_int32_t fhcrev)
        !           691: {
        !           692:        u_int32_t fhc;
        !           693:
        !           694:        /* hide the cursor, just in case */
        !           695:        THC_WRITE(sc, CG6_THC_CURSXY, THC_CURSOFF);
        !           696:
        !           697:        TEC_WRITE(sc, CG6_TEC_MV, 0);
        !           698:        TEC_WRITE(sc, CG6_TEC_CLIP, 0);
        !           699:        TEC_WRITE(sc, CG6_TEC_VDC, 0);
        !           700:
        !           701:        /* take core of hardware bugs in old revisions */
        !           702:        if (fhcrev < 5) {
        !           703:                /*
        !           704:                 * Keep current resolution; set cpu to 68020, set test
        !           705:                 * window (size 1Kx1K), and for rev 1, disable dest cache.
        !           706:                 */
        !           707:                fhc = FHC_READ(sc);
        !           708:                fhc &= FHC_RES_MASK;
        !           709:                fhc |= FHC_CPU_68020 | FHC_TEST |
        !           710:                    (11 << FHC_TESTX_SHIFT) | (11 << FHC_TESTY_SHIFT);
        !           711:                if (fhcrev < 2)
        !           712:                        fhc |= FHC_DST_DISABLE;
        !           713:                FHC_WRITE(sc, fhc);
        !           714:        }
        !           715:
        !           716:        /* enable cursor overlays in brooktree DAC */
        !           717:        BT_WRITE(sc, BT_ADDR, BT_CR << 24);
        !           718:        BT_WRITE(sc, BT_CTRL, BT_READ(sc, BT_CTRL) |
        !           719:            ((BTCR_DISPENA_OV1 | BTCR_DISPENA_OV0) << 24));
        !           720: }
        !           721:
        !           722: void
        !           723: cgsix_hardreset(struct cgsix_softc *sc)
        !           724: {
        !           725:        u_int32_t fhc, rev;
        !           726:
        !           727:        /* enable all of the bit planes */
        !           728:        BT_WRITE(sc, BT_ADDR, BT_RMR << 24);
        !           729:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
        !           730:        BT_WRITE(sc, BT_CTRL, 0xff << 24);
        !           731:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
        !           732:
        !           733:        /* no bit planes should blink */
        !           734:        BT_WRITE(sc, BT_ADDR, BT_BMR << 24);
        !           735:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
        !           736:        BT_WRITE(sc, BT_CTRL, 0x00 << 24);
        !           737:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
        !           738:
        !           739:        /*
        !           740:         * enable the RAMDAC, disable blink, disable overlay 0 and 1,
        !           741:         * use 4:1 multiplexor.
        !           742:         */
        !           743:        BT_WRITE(sc, BT_ADDR, BT_CR << 24);
        !           744:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
        !           745:        BT_WRITE(sc, BT_CTRL,
        !           746:            (BTCR_MPLX_4 | BTCR_RAMENA | BTCR_BLINK_6464) << 24);
        !           747:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
        !           748:
        !           749:        /* disable the D/A read pins */
        !           750:        BT_WRITE(sc, BT_ADDR, BT_CTR << 24);
        !           751:        BT_BARRIER(sc, BT_ADDR, BUS_SPACE_BARRIER_WRITE);
        !           752:        BT_WRITE(sc, BT_CTRL, 0x00 << 24);
        !           753:        BT_BARRIER(sc, BT_CTRL, BUS_SPACE_BARRIER_WRITE);
        !           754:
        !           755:        /* configure thc */
        !           756:        THC_WRITE(sc, CG6_THC_MISC, THC_MISC_RESET | THC_MISC_INTR |
        !           757:            THC_MISC_CYCLS);
        !           758:        THC_WRITE(sc, CG6_THC_MISC, THC_MISC_INTR | THC_MISC_CYCLS);
        !           759:
        !           760:        THC_WRITE(sc, CG6_THC_HSYNC1, 0x10009);
        !           761:        THC_WRITE(sc, CG6_THC_HSYNC2, 0x570000);
        !           762:        THC_WRITE(sc, CG6_THC_HSYNC3, 0x15005d);
        !           763:        THC_WRITE(sc, CG6_THC_VSYNC1, 0x10005);
        !           764:        THC_WRITE(sc, CG6_THC_VSYNC2, 0x2403a8);
        !           765:        THC_WRITE(sc, CG6_THC_REFRESH, 0x16b);
        !           766:
        !           767:        THC_WRITE(sc, CG6_THC_MISC, THC_MISC_RESET | THC_MISC_INTR |
        !           768:            THC_MISC_CYCLS);
        !           769:        THC_WRITE(sc, CG6_THC_MISC, THC_MISC_INTR | THC_MISC_CYCLS);
        !           770:
        !           771:        /* configure fhc (1152x900) */
        !           772:        fhc = FHC_READ(sc);
        !           773:        rev = (fhc & FHC_REV_MASK) >> FHC_REV_SHIFT;
        !           774:
        !           775:        fhc = FHC_RES_1152 | FHC_CPU_68020 | FHC_TEST;
        !           776:        if (rev < 1)
        !           777:                fhc |= FHC_FROP_DISABLE;
        !           778:        if (rev < 2)
        !           779:                fhc |= FHC_DST_DISABLE;
        !           780:        FHC_WRITE(sc, fhc);
        !           781: }
        !           782:
        !           783: void
        !           784: cgsix_burner(void *vsc, u_int on, u_int flags)
        !           785: {
        !           786:        struct cgsix_softc *sc = vsc;
        !           787:        int s;
        !           788:        u_int32_t thcm;
        !           789:
        !           790:        s = splhigh();
        !           791:        thcm = THC_READ(sc, CG6_THC_MISC);
        !           792:        if (on)
        !           793:                thcm |= THC_MISC_VIDEN | THC_MISC_SYNCEN;
        !           794:        else {
        !           795:                thcm &= ~THC_MISC_VIDEN;
        !           796:                if (flags & WSDISPLAY_BURN_VBLANK)
        !           797:                        thcm &= ~THC_MISC_SYNCEN;
        !           798:        }
        !           799:        THC_WRITE(sc, CG6_THC_MISC, thcm);
        !           800:        splx(s);
        !           801: }
        !           802:
        !           803: int
        !           804: cgsix_intr(void *vsc)
        !           805: {
        !           806:        struct cgsix_softc *sc = vsc;
        !           807:        u_int32_t thcm;
        !           808:
        !           809:        thcm = THC_READ(sc, CG6_THC_MISC);
        !           810:        if ((thcm & (THC_MISC_INTEN | THC_MISC_INTR)) !=
        !           811:            (THC_MISC_INTEN | THC_MISC_INTR)) {
        !           812:                /* Not expecting an interrupt, it's not for us. */
        !           813:                return (0);
        !           814:        }
        !           815:
        !           816:        /* Acknowledge the interrupt and disable it. */
        !           817:        thcm &= ~(THC_MISC_RESET | THC_MISC_INTEN);
        !           818:        thcm |= THC_MISC_INTR;
        !           819:        THC_WRITE(sc, CG6_THC_MISC, thcm);
        !           820:        cgsix_loadcmap_immediate(sc, 0, 256);
        !           821:        return (1);
        !           822: }
        !           823:
        !           824: void
        !           825: cgsix_ras_init(struct cgsix_softc *sc)
        !           826: {
        !           827:        u_int32_t m;
        !           828:
        !           829:        CG6_DRAIN(sc);
        !           830:        m = FBC_READ(sc, CG6_FBC_MODE);
        !           831:        m &= ~FBC_MODE_MASK;
        !           832:        m |= FBC_MODE_VAL;
        !           833:        FBC_WRITE(sc, CG6_FBC_MODE, m);
        !           834: }
        !           835:
        !           836: void
        !           837: cgsix_ras_copyrows(void *cookie, int src, int dst, int n)
        !           838: {
        !           839:        struct rasops_info *ri = cookie;
        !           840:        struct cgsix_softc *sc = ri->ri_hw;
        !           841:
        !           842:        if (dst == src)
        !           843:                return;
        !           844:        if (src < 0) {
        !           845:                n += src;
        !           846:                src = 0;
        !           847:        }
        !           848:        if (src + n > ri->ri_rows)
        !           849:                n = ri->ri_rows - src;
        !           850:        if (dst < 0) {
        !           851:                n += dst;
        !           852:                dst = 0;
        !           853:        }
        !           854:        if (dst + n > ri->ri_rows)
        !           855:                n = ri->ri_rows - dst;
        !           856:        if (n <= 0)
        !           857:                return;
        !           858:        n *= ri->ri_font->fontheight;
        !           859:        src *= ri->ri_font->fontheight;
        !           860:        dst *= ri->ri_font->fontheight;
        !           861:
        !           862:        FBC_WRITE(sc, CG6_FBC_CLIP, 0);
        !           863:        FBC_WRITE(sc, CG6_FBC_S, 0);
        !           864:        FBC_WRITE(sc, CG6_FBC_OFFX, 0);
        !           865:        FBC_WRITE(sc, CG6_FBC_OFFY, 0);
        !           866:        FBC_WRITE(sc, CG6_FBC_CLIPMINX, 0);
        !           867:        FBC_WRITE(sc, CG6_FBC_CLIPMINY, 0);
        !           868:        FBC_WRITE(sc, CG6_FBC_CLIPMAXX, ri->ri_width - 1);
        !           869:        FBC_WRITE(sc, CG6_FBC_CLIPMAXY, ri->ri_height - 1);
        !           870:        FBC_WRITE(sc, CG6_FBC_ALU, FBC_ALU_COPY);
        !           871:        FBC_WRITE(sc, CG6_FBC_X0, ri->ri_xorigin);
        !           872:        FBC_WRITE(sc, CG6_FBC_Y0, ri->ri_yorigin + src);
        !           873:        FBC_WRITE(sc, CG6_FBC_X1, ri->ri_xorigin + ri->ri_emuwidth - 1);
        !           874:        FBC_WRITE(sc, CG6_FBC_Y1, ri->ri_yorigin + src + n - 1);
        !           875:        FBC_WRITE(sc, CG6_FBC_X2, ri->ri_xorigin);
        !           876:        FBC_WRITE(sc, CG6_FBC_Y2, ri->ri_yorigin + dst);
        !           877:        FBC_WRITE(sc, CG6_FBC_X3, ri->ri_xorigin + ri->ri_emuwidth - 1);
        !           878:        FBC_WRITE(sc, CG6_FBC_Y3, ri->ri_yorigin + dst + n - 1);
        !           879:        CG6_BLIT_WAIT(sc);
        !           880:        CG6_DRAIN(sc);
        !           881: }
        !           882:
        !           883: void
        !           884: cgsix_ras_copycols(void *cookie, int row, int src, int dst, int n)
        !           885: {
        !           886:        struct rasops_info *ri = cookie;
        !           887:        struct cgsix_softc *sc = ri->ri_hw;
        !           888:
        !           889:        if (dst == src)
        !           890:                return;
        !           891:        if ((row < 0) || (row >= ri->ri_rows))
        !           892:                return;
        !           893:        if (src < 0) {
        !           894:                n += src;
        !           895:                src = 0;
        !           896:        }
        !           897:        if (src + n > ri->ri_cols)
        !           898:                n = ri->ri_cols - src;
        !           899:        if (dst < 0) {
        !           900:                n += dst;
        !           901:                dst = 0;
        !           902:        }
        !           903:        if (dst + n > ri->ri_cols)
        !           904:                n = ri->ri_cols - dst;
        !           905:        if (n <= 0)
        !           906:                return;
        !           907:        n *= ri->ri_font->fontwidth;
        !           908:        src *= ri->ri_font->fontwidth;
        !           909:        dst *= ri->ri_font->fontwidth;
        !           910:        row *= ri->ri_font->fontheight;
        !           911:
        !           912:        FBC_WRITE(sc, CG6_FBC_CLIP, 0);
        !           913:        FBC_WRITE(sc, CG6_FBC_S, 0);
        !           914:        FBC_WRITE(sc, CG6_FBC_OFFX, 0);
        !           915:        FBC_WRITE(sc, CG6_FBC_OFFY, 0);
        !           916:        FBC_WRITE(sc, CG6_FBC_CLIPMINX, 0);
        !           917:        FBC_WRITE(sc, CG6_FBC_CLIPMINY, 0);
        !           918:        FBC_WRITE(sc, CG6_FBC_CLIPMAXX, ri->ri_width - 1);
        !           919:        FBC_WRITE(sc, CG6_FBC_CLIPMAXY, ri->ri_height - 1);
        !           920:        FBC_WRITE(sc, CG6_FBC_ALU, FBC_ALU_COPY);
        !           921:        FBC_WRITE(sc, CG6_FBC_X0, ri->ri_xorigin + src);
        !           922:        FBC_WRITE(sc, CG6_FBC_Y0, ri->ri_yorigin + row);
        !           923:        FBC_WRITE(sc, CG6_FBC_X1, ri->ri_xorigin + src + n - 1);
        !           924:        FBC_WRITE(sc, CG6_FBC_Y1,
        !           925:            ri->ri_yorigin + row + ri->ri_font->fontheight - 1);
        !           926:        FBC_WRITE(sc, CG6_FBC_X2, ri->ri_xorigin + dst);
        !           927:        FBC_WRITE(sc, CG6_FBC_Y2, ri->ri_yorigin + row);
        !           928:        FBC_WRITE(sc, CG6_FBC_X3, ri->ri_xorigin + dst + n - 1);
        !           929:        FBC_WRITE(sc, CG6_FBC_Y3,
        !           930:            ri->ri_yorigin + row + ri->ri_font->fontheight - 1);
        !           931:        CG6_BLIT_WAIT(sc);
        !           932:        CG6_DRAIN(sc);
        !           933: }
        !           934:
        !           935: void
        !           936: cgsix_ras_erasecols(void *cookie, int row, int col, int n, long int attr)
        !           937: {
        !           938:        struct rasops_info *ri = cookie;
        !           939:        struct cgsix_softc *sc = ri->ri_hw;
        !           940:        int fg, bg;
        !           941:
        !           942:        if ((row < 0) || (row >= ri->ri_rows))
        !           943:                return;
        !           944:        if (col < 0) {
        !           945:                n += col;
        !           946:                col = 0;
        !           947:        }
        !           948:        if (col + n > ri->ri_cols)
        !           949:                n = ri->ri_cols - col;
        !           950:        if (n <= 0)
        !           951:                return;
        !           952:        n *= ri->ri_font->fontwidth;
        !           953:        col *= ri->ri_font->fontwidth;
        !           954:        row *= ri->ri_font->fontheight;
        !           955:
        !           956:        ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
        !           957:
        !           958:        FBC_WRITE(sc, CG6_FBC_CLIP, 0);
        !           959:        FBC_WRITE(sc, CG6_FBC_S, 0);
        !           960:        FBC_WRITE(sc, CG6_FBC_OFFX, 0);
        !           961:        FBC_WRITE(sc, CG6_FBC_OFFY, 0);
        !           962:        FBC_WRITE(sc, CG6_FBC_CLIPMINX, 0);
        !           963:        FBC_WRITE(sc, CG6_FBC_CLIPMINY, 0);
        !           964:        FBC_WRITE(sc, CG6_FBC_CLIPMAXX, ri->ri_width - 1);
        !           965:        FBC_WRITE(sc, CG6_FBC_CLIPMAXY, ri->ri_height - 1);
        !           966:        FBC_WRITE(sc, CG6_FBC_ALU, FBC_ALU_FILL);
        !           967:        FBC_WRITE(sc, CG6_FBC_FG, ri->ri_devcmap[bg]);
        !           968:        FBC_WRITE(sc, CG6_FBC_ARECTY, ri->ri_yorigin + row);
        !           969:        FBC_WRITE(sc, CG6_FBC_ARECTX, ri->ri_xorigin + col);
        !           970:        FBC_WRITE(sc, CG6_FBC_ARECTY,
        !           971:            ri->ri_yorigin + row + ri->ri_font->fontheight - 1);
        !           972:        FBC_WRITE(sc, CG6_FBC_ARECTX, ri->ri_xorigin + col + n - 1);
        !           973:        CG6_DRAW_WAIT(sc);
        !           974:        CG6_DRAIN(sc);
        !           975: }
        !           976:
        !           977: void
        !           978: cgsix_ras_eraserows(void *cookie, int row, int n, long int attr)
        !           979: {
        !           980:        struct rasops_info *ri = cookie;
        !           981:        struct cgsix_softc *sc = ri->ri_hw;
        !           982:        int fg, bg;
        !           983:
        !           984:        if (row < 0) {
        !           985:                n += row;
        !           986:                row = 0;
        !           987:        }
        !           988:        if (row + n > ri->ri_rows)
        !           989:                n = ri->ri_rows - row;
        !           990:        if (n <= 0)
        !           991:                return;
        !           992:
        !           993:        ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
        !           994:
        !           995:        FBC_WRITE(sc, CG6_FBC_CLIP, 0);
        !           996:        FBC_WRITE(sc, CG6_FBC_S, 0);
        !           997:        FBC_WRITE(sc, CG6_FBC_OFFX, 0);
        !           998:        FBC_WRITE(sc, CG6_FBC_OFFY, 0);
        !           999:        FBC_WRITE(sc, CG6_FBC_CLIPMINX, 0);
        !          1000:        FBC_WRITE(sc, CG6_FBC_CLIPMINY, 0);
        !          1001:        FBC_WRITE(sc, CG6_FBC_CLIPMAXX, ri->ri_width - 1);
        !          1002:        FBC_WRITE(sc, CG6_FBC_CLIPMAXY, ri->ri_height - 1);
        !          1003:        FBC_WRITE(sc, CG6_FBC_ALU, FBC_ALU_FILL);
        !          1004:        FBC_WRITE(sc, CG6_FBC_FG, ri->ri_devcmap[bg]);
        !          1005:        if ((n == ri->ri_rows) && (ri->ri_flg & RI_FULLCLEAR)) {
        !          1006:                FBC_WRITE(sc, CG6_FBC_ARECTY, 0);
        !          1007:                FBC_WRITE(sc, CG6_FBC_ARECTX, 0);
        !          1008:                FBC_WRITE(sc, CG6_FBC_ARECTY, ri->ri_height - 1);
        !          1009:                FBC_WRITE(sc, CG6_FBC_ARECTX, ri->ri_width - 1);
        !          1010:        } else {
        !          1011:                row *= ri->ri_font->fontheight;
        !          1012:                FBC_WRITE(sc, CG6_FBC_ARECTY, ri->ri_yorigin + row);
        !          1013:                FBC_WRITE(sc, CG6_FBC_ARECTX, ri->ri_xorigin);
        !          1014:                FBC_WRITE(sc, CG6_FBC_ARECTY,
        !          1015:                    ri->ri_yorigin + row + (n * ri->ri_font->fontheight) - 1);
        !          1016:                FBC_WRITE(sc, CG6_FBC_ARECTX,
        !          1017:                    ri->ri_xorigin + ri->ri_emuwidth - 1);
        !          1018:        }
        !          1019:        CG6_DRAW_WAIT(sc);
        !          1020:        CG6_DRAIN(sc);
        !          1021: }
        !          1022:
        !          1023: void
        !          1024: cgsix_ras_do_cursor(struct rasops_info *ri)
        !          1025: {
        !          1026:        struct cgsix_softc *sc = ri->ri_hw;
        !          1027:        int row, col;
        !          1028:
        !          1029:        row = ri->ri_crow * ri->ri_font->fontheight;
        !          1030:        col = ri->ri_ccol * ri->ri_font->fontwidth;
        !          1031:        FBC_WRITE(sc, CG6_FBC_CLIP, 0);
        !          1032:        FBC_WRITE(sc, CG6_FBC_S, 0);
        !          1033:        FBC_WRITE(sc, CG6_FBC_OFFX, 0);
        !          1034:        FBC_WRITE(sc, CG6_FBC_OFFY, 0);
        !          1035:        FBC_WRITE(sc, CG6_FBC_CLIPMINX, 0);
        !          1036:        FBC_WRITE(sc, CG6_FBC_CLIPMINY, 0);
        !          1037:        FBC_WRITE(sc, CG6_FBC_CLIPMAXX, ri->ri_width - 1);
        !          1038:        FBC_WRITE(sc, CG6_FBC_CLIPMAXY, ri->ri_height - 1);
        !          1039:        FBC_WRITE(sc, CG6_FBC_ALU, FBC_ALU_FLIP);
        !          1040:        FBC_WRITE(sc, CG6_FBC_ARECTY, ri->ri_yorigin + row);
        !          1041:        FBC_WRITE(sc, CG6_FBC_ARECTX, ri->ri_xorigin + col);
        !          1042:        FBC_WRITE(sc, CG6_FBC_ARECTY,
        !          1043:            ri->ri_yorigin + row + ri->ri_font->fontheight - 1);
        !          1044:        FBC_WRITE(sc, CG6_FBC_ARECTX,
        !          1045:            ri->ri_xorigin + col + ri->ri_font->fontwidth - 1);
        !          1046:        CG6_DRAW_WAIT(sc);
        !          1047:        CG6_DRAIN(sc);
        !          1048: }

CVSweb