[BACK]Return to smg.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / vsa

Annotation of sys/arch/vax/vsa/smg.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: smg.c,v 1.19 2006/11/29 19:08:22 miod Exp $   */
        !             2: /*     $NetBSD: smg.c,v 1.21 2000/03/23 06:46:44 thorpej Exp $ */
        !             3: /*
        !             4:  * Copyright (c) 2006, Miodrag Vallat
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  *
        !            15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            18:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            19:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            20:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            21:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            23:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            24:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            25:  * POSSIBILITY OF SUCH DAMAGE.
        !            26:  */
        !            27: /*
        !            28:  * Copyright (c) 1998 Ludd, University of Lule}, Sweden.
        !            29:  * All rights reserved.
        !            30:  *
        !            31:  * Redistribution and use in source and binary forms, with or without
        !            32:  * modification, are permitted provided that the following conditions
        !            33:  * are met:
        !            34:  * 1. Redistributions of source code must retain the above copyright
        !            35:  *    notice, this list of conditions and the following disclaimer.
        !            36:  * 2. Redistributions in binary form must reproduce the above copyright
        !            37:  *    notice, this list of conditions and the following disclaimer in the
        !            38:  *    documentation and/or other materials provided with the distribution.
        !            39:  * 3. All advertising materials mentioning features or use of this software
        !            40:  *    must display the following acknowledgement:
        !            41:  *     This product includes software developed at Ludd, University of
        !            42:  *     Lule}, Sweden and its contributors.
        !            43:  * 4. The name of the author may not be used to endorse or promote products
        !            44:  *    derived from this software without specific prior written permission
        !            45:  *
        !            46:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            47:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            48:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            49:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            50:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            51:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            52:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            53:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            54:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            55:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            56:  */
        !            57: /*
        !            58:  * Copyright (c) 1996 Jason R. Thorpe.  All rights reserved.
        !            59:  * Copyright (c) 1991 University of Utah.
        !            60:  * Copyright (c) 1990, 1993
        !            61:  *     The Regents of the University of California.  All rights reserved.
        !            62:  *
        !            63:  * This code is derived from software contributed to Berkeley by
        !            64:  * the Systems Programming Group of the University of Utah Computer
        !            65:  * Science Department and Mark Davies of the Department of Computer
        !            66:  * Science, Victoria University of Wellington, New Zealand.
        !            67:  *
        !            68:  * Redistribution and use in source and binary forms, with or without
        !            69:  * modification, are permitted provided that the following conditions
        !            70:  * are met:
        !            71:  * 1. Redistributions of source code must retain the above copyright
        !            72:  *    notice, this list of conditions and the following disclaimer.
        !            73:  * 2. Redistributions in binary form must reproduce the above copyright
        !            74:  *    notice, this list of conditions and the following disclaimer in the
        !            75:  *    documentation and/or other materials provided with the distribution.
        !            76:  * 3. Neither the name of the University nor the names of its contributors
        !            77:  *    may be used to endorse or promote products derived from this software
        !            78:  *    without specific prior written permission.
        !            79:  *
        !            80:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            81:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            82:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            83:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            84:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            85:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            86:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            87:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            88:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            89:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            90:  * SUCH DAMAGE.
        !            91:  *
        !            92:  * from: Utah $Hdr: grf_hy.c 1.2 93/08/13$
        !            93:  *
        !            94:  *     @(#)grf_hy.c    8.4 (Berkeley) 1/12/94
        !            95:  */
        !            96:
        !            97: #include <sys/param.h>
        !            98: #include <sys/device.h>
        !            99: #include <sys/systm.h>
        !           100: #include <sys/malloc.h>
        !           101: #include <sys/conf.h>
        !           102: #include <sys/kernel.h>
        !           103:
        !           104: #include <machine/vsbus.h>
        !           105: #include <machine/sid.h>
        !           106: #include <machine/cpu.h>
        !           107: #include <machine/ka420.h>
        !           108: #include <machine/scb.h>
        !           109:
        !           110: #include <uvm/uvm_extern.h>
        !           111:
        !           112: #include <dev/cons.h>
        !           113:
        !           114: #include <dev/ic/dc503reg.h>
        !           115:
        !           116: #include <vax/qbus/dzreg.h>
        !           117: #include <vax/qbus/dzvar.h>
        !           118: #include <vax/dec/dzkbdvar.h>
        !           119:
        !           120: #include <dev/wscons/wsconsio.h>
        !           121: #include <dev/wscons/wsdisplayvar.h>
        !           122: #include <dev/rasops/rasops.h>
        !           123: #include <dev/rasops/rasops_masks.h>
        !           124:
        !           125: /* Screen hardware defs */
        !           126: #define SM_XWIDTH      1024
        !           127: #define SM_YWIDTH      864
        !           128:
        !           129: #define CUR_XBIAS      216     /* Add to cursor position */
        !           130: #define CUR_YBIAS      33
        !           131:
        !           132: int    smg_match(struct device *, void *, void *);
        !           133: void   smg_attach(struct device *, struct device *, void *);
        !           134:
        !           135: struct smg_screen {
        !           136:        struct rasops_info ss_ri;
        !           137:        caddr_t         ss_addr;                /* frame buffer address */
        !           138:        struct dc503reg *ss_cursor;             /* cursor registers */
        !           139:        u_int16_t       ss_curcmd;
        !           140:        struct wsdisplay_curpos ss_curpos, ss_curhot;
        !           141:        u_int16_t       ss_curimg[PCC_CURSOR_SIZE];
        !           142:        u_int16_t       ss_curmask[PCC_CURSOR_SIZE];
        !           143: };
        !           144:
        !           145: /* for console */
        !           146: struct smg_screen smg_consscr;
        !           147:
        !           148: struct smg_softc {
        !           149:        struct device sc_dev;
        !           150:        struct smg_screen *sc_scr;
        !           151:        int     sc_nscreens;
        !           152: };
        !           153:
        !           154: struct cfattach smg_ca = {
        !           155:        sizeof(struct smg_softc), smg_match, smg_attach,
        !           156: };
        !           157:
        !           158: struct cfdriver smg_cd = {
        !           159:        NULL, "smg", DV_DULL
        !           160: };
        !           161:
        !           162: struct wsscreen_descr smg_stdscreen = {
        !           163:        "std",
        !           164: };
        !           165:
        !           166: const struct wsscreen_descr *_smg_scrlist[] = {
        !           167:        &smg_stdscreen,
        !           168: };
        !           169:
        !           170: const struct wsscreen_list smg_screenlist = {
        !           171:        sizeof(_smg_scrlist) / sizeof(struct wsscreen_descr *),
        !           172:        _smg_scrlist,
        !           173: };
        !           174:
        !           175: int    smg_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !           176: paddr_t        smg_mmap(void *, off_t, int);
        !           177: int    smg_alloc_screen(void *, const struct wsscreen_descr *,
        !           178:            void **, int *, int *, long *);
        !           179: void   smg_free_screen(void *, void *);
        !           180: int    smg_show_screen(void *, void *, int,
        !           181:            void (*) (void *, int, int), void *);
        !           182: void   smg_burner(void *, u_int, u_int);
        !           183:
        !           184: const struct wsdisplay_accessops smg_accessops = {
        !           185:        smg_ioctl,
        !           186:        smg_mmap,
        !           187:        smg_alloc_screen,
        !           188:        smg_free_screen,
        !           189:        smg_show_screen,
        !           190:        NULL,   /* load_font */
        !           191:        NULL,   /* scrollback */
        !           192:        NULL,   /* getchar */
        !           193:        smg_burner
        !           194: };
        !           195:
        !           196: void   smg_blockmove(struct rasops_info *, u_int, u_int, u_int, u_int, u_int,
        !           197:            int);
        !           198: void   smg_copycols(void *, int, int, int, int);
        !           199: void   smg_erasecols(void *, int, int, int, long);
        !           200:
        !           201: int    smg_getcursor(struct smg_screen *, struct wsdisplay_cursor *);
        !           202: int    smg_setup_screen(struct smg_screen *);
        !           203: int    smg_setcursor(struct smg_screen *, struct wsdisplay_cursor *);
        !           204: void   smg_updatecursor(struct smg_screen *, u_int);
        !           205:
        !           206: int
        !           207: smg_match(struct device *parent, void *vcf, void *aux)
        !           208: {
        !           209:        struct cfdata *cf = vcf;
        !           210:        struct vsbus_attach_args *va = aux;
        !           211:        volatile short *curcmd;
        !           212:        volatile short *cfgtst;
        !           213:        short tmp, tmp2;
        !           214:        extern struct consdev wsdisplay_cons;
        !           215:
        !           216:        switch (vax_boardtype) {
        !           217:        default:
        !           218:                return (0);
        !           219:
        !           220:        case VAX_BTYP_410:
        !           221:        case VAX_BTYP_420:
        !           222:        case VAX_BTYP_43:
        !           223:                if (va->va_paddr != KA420_CUR_BASE)
        !           224:                        return (0);
        !           225:
        !           226:                /* not present on microvaxes */
        !           227:                if ((vax_confdata & KA420_CFG_MULTU) != 0)
        !           228:                        return (0);
        !           229:
        !           230:                /*
        !           231:                 * If the color option board is present, do not attach
        !           232:                 * unless we are explicitely asked to via device flags.
        !           233:                 */
        !           234:                if ((vax_confdata & KA420_CFG_VIDOPT) != 0 &&
        !           235:                    (cf->cf_flags & 1) == 0)
        !           236:                        return (0);
        !           237:                break;
        !           238:        }
        !           239:
        !           240:        /* when already running as console, always fake things */
        !           241:        if ((vax_confdata & (KA420_CFG_L3CON | KA420_CFG_VIDOPT)) == 0 &&
        !           242:            cn_tab == &wsdisplay_cons) {
        !           243:                struct vsbus_softc *sc = (void *)parent;
        !           244:                extern int oldvsbus;
        !           245:
        !           246:                sc->sc_mask = 0x08;
        !           247:                scb_fake(0x44, oldvsbus ? 0x14 : 0x15);
        !           248:                return (20);
        !           249:        } else {
        !           250:                /*
        !           251:                 * Try to find the cursor chip by testing the flip-flop.
        !           252:                 * If nonexistent, no glass tty.
        !           253:                 */
        !           254:                curcmd = (short *)va->va_addr;
        !           255:                cfgtst = (short *)vax_map_physmem(VS_CFGTST, 1);
        !           256:                curcmd[0] = PCCCMD_HSHI | PCCCMD_FOPB;
        !           257:                DELAY(300000);
        !           258:                tmp = cfgtst[0];
        !           259:                curcmd[0] = PCCCMD_TEST | PCCCMD_HSHI;
        !           260:                DELAY(300000);
        !           261:                tmp2 = cfgtst[0];
        !           262:                vax_unmap_physmem((vaddr_t)cfgtst, 1);
        !           263:
        !           264:                if (tmp2 != tmp)
        !           265:                        return (20); /* Using periodic interrupt */
        !           266:                else
        !           267:                        return (0);
        !           268:        }
        !           269: }
        !           270:
        !           271: void
        !           272: smg_attach(struct device *parent, struct device *self, void *aux)
        !           273: {
        !           274:        struct smg_softc *sc = (struct smg_softc *)self;
        !           275:        struct smg_screen *scr;
        !           276:        struct wsemuldisplaydev_attach_args aa;
        !           277:        int console;
        !           278:        extern struct consdev wsdisplay_cons;
        !           279:
        !           280:        console = (vax_confdata & (KA420_CFG_L3CON | KA420_CFG_VIDOPT)) == 0 &&
        !           281:            cn_tab == &wsdisplay_cons;
        !           282:        if (console) {
        !           283:                scr = &smg_consscr;
        !           284:                sc->sc_nscreens = 1;
        !           285:        } else {
        !           286:                scr = malloc(sizeof(struct smg_screen), M_DEVBUF, M_NOWAIT);
        !           287:                if (scr == NULL) {
        !           288:                        printf(": can not allocate memory\n");
        !           289:                        return;
        !           290:                }
        !           291:                bzero(scr, sizeof(struct smg_screen));
        !           292:
        !           293:                scr->ss_addr =
        !           294:                    (caddr_t)vax_map_physmem(SMADDR, SMSIZE / VAX_NBPG);
        !           295:                if (scr->ss_addr == NULL) {
        !           296:                        printf(": can not map frame buffer\n");
        !           297:                        free(scr, M_DEVBUF);
        !           298:                        return;
        !           299:                }
        !           300:
        !           301:                scr->ss_cursor =
        !           302:                    (struct dc503reg *)vax_map_physmem(KA420_CUR_BASE, 1);
        !           303:                if (scr->ss_cursor == NULL) {
        !           304:                        printf(": can not map cursor chip\n");
        !           305:                        vax_unmap_physmem((vaddr_t)scr->ss_addr,
        !           306:                            SMSIZE / VAX_NBPG);
        !           307:                        free(scr, M_DEVBUF);
        !           308:                        return;
        !           309:                }
        !           310:
        !           311:                if (smg_setup_screen(scr) != 0) {
        !           312:                        printf(": initialization failed\n");
        !           313:                        vax_unmap_physmem((vaddr_t)scr->ss_cursor, 1);
        !           314:                        vax_unmap_physmem((vaddr_t)scr->ss_addr,
        !           315:                            SMSIZE / VAX_NBPG);
        !           316:                        free(scr, M_DEVBUF);
        !           317:                        return;
        !           318:                }
        !           319:        }
        !           320:        sc->sc_scr = scr;
        !           321:
        !           322:        printf("\n%s: %dx%d on-board monochrome framebuffer\n",
        !           323:            self->dv_xname, SM_XWIDTH, SM_YWIDTH);
        !           324:
        !           325:        aa.console = console;
        !           326:        aa.scrdata = &smg_screenlist;
        !           327:        aa.accessops = &smg_accessops;
        !           328:        aa.accesscookie = sc;
        !           329:        aa.defaultscreens = 0;
        !           330:
        !           331:        config_found(self, &aa, wsemuldisplaydevprint);
        !           332: }
        !           333:
        !           334: /*
        !           335:  * Initialize anything necessary for an emulating wsdisplay to work (i.e.
        !           336:  * pick a font, initialize a rasops structure, setup the accessops callbacks.)
        !           337:  */
        !           338: int
        !           339: smg_setup_screen(struct smg_screen *ss)
        !           340: {
        !           341:        struct rasops_info *ri = &ss->ss_ri;
        !           342:
        !           343:        bzero(ri, sizeof(*ri));
        !           344:        ri->ri_depth = 1;
        !           345:        ri->ri_width = SM_XWIDTH;
        !           346:        ri->ri_height = SM_YWIDTH;
        !           347:        ri->ri_stride = SM_XWIDTH >> 3;
        !           348:        ri->ri_flg = RI_CLEAR | RI_CENTER;
        !           349:        ri->ri_bits = (void *)ss->ss_addr;
        !           350:        ri->ri_hw = ss;
        !           351:
        !           352:        /*
        !           353:         * Ask for an unholy big display, rasops will trim this to more
        !           354:         * reasonable values.
        !           355:         */
        !           356:        if (rasops_init(ri, 160, 160) != 0)
        !           357:                return (-1);
        !           358:
        !           359:        ri->ri_ops.copycols = smg_copycols;
        !           360:        ri->ri_ops.erasecols = smg_erasecols;
        !           361:
        !           362:        smg_stdscreen.ncols = ri->ri_cols;
        !           363:        smg_stdscreen.nrows = ri->ri_rows;
        !           364:        smg_stdscreen.textops = &ri->ri_ops;
        !           365:        smg_stdscreen.fontwidth = ri->ri_font->fontwidth;
        !           366:        smg_stdscreen.fontheight = ri->ri_font->fontheight;
        !           367:        smg_stdscreen.capabilities = ri->ri_caps;
        !           368:
        !           369:        ss->ss_curcmd = PCCCMD_HSHI;
        !           370:        ss->ss_cursor->cmdr = ss->ss_curcmd;
        !           371:
        !           372:        return (0);
        !           373: }
        !           374:
        !           375: int
        !           376: smg_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
        !           377: {
        !           378:        struct smg_softc *sc = v;
        !           379:        struct smg_screen *ss = sc->sc_scr;
        !           380:        struct wsdisplay_fbinfo *wdf;
        !           381:        struct wsdisplay_curpos *pos;
        !           382:
        !           383:        switch (cmd) {
        !           384:        case WSDISPLAYIO_GTYPE:
        !           385:                *(u_int *)data = WSDISPLAY_TYPE_VAX_MONO;
        !           386:                break;
        !           387:
        !           388:        case WSDISPLAYIO_GINFO:
        !           389:                wdf = (struct wsdisplay_fbinfo *)data;
        !           390:                wdf->height = ss->ss_ri.ri_height;
        !           391:                wdf->width = ss->ss_ri.ri_width;
        !           392:                wdf->depth = ss->ss_ri.ri_depth;
        !           393:                wdf->cmsize = 0;
        !           394:                break;
        !           395:
        !           396:        case WSDISPLAYIO_LINEBYTES:
        !           397:                *(u_int *)data = ss->ss_ri.ri_stride;
        !           398:                break;
        !           399:
        !           400:        case WSDISPLAYIO_GETCMAP:
        !           401:        case WSDISPLAYIO_PUTCMAP:
        !           402:        case WSDISPLAYIO_GVIDEO:
        !           403:        case WSDISPLAYIO_SVIDEO:
        !           404:                break;
        !           405:
        !           406:        case WSDISPLAYIO_GCURPOS:
        !           407:                pos = (struct wsdisplay_curpos *)data;
        !           408:                pos->x = ss->ss_curpos.x;
        !           409:                pos->y = ss->ss_curpos.y;
        !           410:                break;
        !           411:        case WSDISPLAYIO_SCURPOS:
        !           412:                pos = (struct wsdisplay_curpos *)data;
        !           413:                ss->ss_curpos.x = pos->x;
        !           414:                ss->ss_curpos.y = pos->y;
        !           415:                smg_updatecursor(ss, WSDISPLAY_CURSOR_DOPOS);
        !           416:                break;
        !           417:        case WSDISPLAYIO_GCURMAX:
        !           418:                pos = (struct wsdisplay_curpos *)data;
        !           419:                pos->x = pos->y = PCC_CURSOR_SIZE;
        !           420:        case WSDISPLAYIO_GCURSOR:
        !           421:                return (smg_getcursor(ss, (struct wsdisplay_cursor *)data));
        !           422:        case WSDISPLAYIO_SCURSOR:
        !           423:                return (smg_setcursor(ss, (struct wsdisplay_cursor *)data));
        !           424:                break;
        !           425:
        !           426:        default:
        !           427:                return (-1);
        !           428:        }
        !           429:
        !           430:        return (0);
        !           431: }
        !           432:
        !           433: paddr_t
        !           434: smg_mmap(void *v, off_t offset, int prot)
        !           435: {
        !           436:        if (offset >= SMSIZE || offset < 0)
        !           437:                return (-1);
        !           438:
        !           439:        return (SMADDR + offset) >> PGSHIFT;
        !           440: }
        !           441:
        !           442: int
        !           443: smg_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
        !           444:     int *curxp, int *curyp, long *defattrp)
        !           445: {
        !           446:        struct smg_softc *sc = v;
        !           447:        struct smg_screen *ss = sc->sc_scr;
        !           448:        struct rasops_info *ri = &ss->ss_ri;
        !           449:
        !           450:        if (sc->sc_nscreens > 0)
        !           451:                return (ENOMEM);
        !           452:
        !           453:        *cookiep = ri;
        !           454:        *curxp = *curyp = 0;
        !           455:        ri->ri_ops.alloc_attr(ri, 0, 0, 0, defattrp);
        !           456:        sc->sc_nscreens++;
        !           457:
        !           458:        return (0);
        !           459: }
        !           460:
        !           461: void
        !           462: smg_free_screen(void *v, void *cookie)
        !           463: {
        !           464:        struct smg_softc *sc = v;
        !           465:
        !           466:        sc->sc_nscreens--;
        !           467: }
        !           468:
        !           469: int
        !           470: smg_show_screen(void *v, void *cookie, int waitok,
        !           471:     void (*cb)(void *, int, int), void *cbarg)
        !           472: {
        !           473:        return (0);
        !           474: }
        !           475:
        !           476: void
        !           477: smg_burner(void *v, u_int on, u_int flags)
        !           478: {
        !           479:        struct smg_softc *sc = v;
        !           480:        struct smg_screen *ss = sc->sc_scr;
        !           481:
        !           482:        ss->ss_cursor->cmdr = on ? ss->ss_curcmd :
        !           483:            (ss->ss_curcmd & ~(PCCCMD_FOPA | PCCCMD_ENPA)) | PCCCMD_FOPB;
        !           484: }
        !           485:
        !           486: int
        !           487: smg_getcursor(struct smg_screen *ss, struct wsdisplay_cursor *wdc)
        !           488: {
        !           489:        int error;
        !           490:
        !           491:        if (wdc->which & WSDISPLAY_CURSOR_DOCUR)
        !           492:                wdc->enable = ss->ss_curcmd & PCCCMD_ENPA ? 1 : 0;
        !           493:        if (wdc->which & WSDISPLAY_CURSOR_DOPOS) {
        !           494:                wdc->pos.x = ss->ss_curpos.x;
        !           495:                wdc->pos.y = ss->ss_curpos.y;
        !           496:        }
        !           497:        if (wdc->which & WSDISPLAY_CURSOR_DOHOT) {
        !           498:                wdc->hot.x = ss->ss_curhot.x;
        !           499:                wdc->hot.y = ss->ss_curhot.y;
        !           500:        }
        !           501:        if (wdc->which & WSDISPLAY_CURSOR_DOCMAP) {
        !           502:                wdc->cmap.index = 0;
        !           503:                wdc->cmap.count = 0;
        !           504:        }
        !           505:        if (wdc->which & WSDISPLAY_CURSOR_DOSHAPE) {
        !           506:                wdc->size.x = wdc->size.y = PCC_CURSOR_SIZE;
        !           507:                error = copyout(ss->ss_curimg, wdc->image,
        !           508:                    sizeof(ss->ss_curimg));
        !           509:                if (error != 0)
        !           510:                        return (error);
        !           511:                error = copyout(ss->ss_curmask, wdc->mask,
        !           512:                    sizeof(ss->ss_curmask));
        !           513:                if (error != 0)
        !           514:                        return (error);
        !           515:        }
        !           516:
        !           517:        return (0);
        !           518: }
        !           519:
        !           520: int
        !           521: smg_setcursor(struct smg_screen *ss, struct wsdisplay_cursor *wdc)
        !           522: {
        !           523:        u_int16_t curfg[PCC_CURSOR_SIZE], curmask[PCC_CURSOR_SIZE];
        !           524:        int error;
        !           525:
        !           526:        if (wdc->which & WSDISPLAY_CURSOR_DOCMAP) {
        !           527:                /* No cursor colormap since we are a B&W device. */
        !           528:                if (wdc->cmap.count != 0)
        !           529:                        return (EINVAL);
        !           530:        }
        !           531:
        !           532:        /*
        !           533:         * First, do the userland-kernel data transfers, so that we can fail
        !           534:         * if necessary before altering anything.
        !           535:         */
        !           536:        if (wdc->which & WSDISPLAY_CURSOR_DOSHAPE) {
        !           537:                if (wdc->size.x != PCC_CURSOR_SIZE ||
        !           538:                    wdc->size.y != PCC_CURSOR_SIZE)
        !           539:                        return (EINVAL);
        !           540:                error = copyin(wdc->image, curfg, sizeof(curfg));
        !           541:                if (error != 0)
        !           542:                        return (error);
        !           543:                error = copyin(wdc->mask, curmask, sizeof(curmask));
        !           544:                if (error != 0)
        !           545:                        return (error);
        !           546:        }
        !           547:
        !           548:        /*
        !           549:         * Now update our variables...
        !           550:         */
        !           551:        if (wdc->which & WSDISPLAY_CURSOR_DOCUR) {
        !           552:                if (wdc->enable)
        !           553:                        ss->ss_curcmd |= PCCCMD_ENPB | PCCCMD_ENPA;
        !           554:                else
        !           555:                        ss->ss_curcmd &= ~(PCCCMD_ENPB | PCCCMD_ENPA);
        !           556:        }
        !           557:        if (wdc->which & WSDISPLAY_CURSOR_DOPOS) {
        !           558:                ss->ss_curpos.x = wdc->pos.x;
        !           559:                ss->ss_curpos.y = wdc->pos.y;
        !           560:        }
        !           561:        if (wdc->which & WSDISPLAY_CURSOR_DOHOT) {
        !           562:                ss->ss_curhot.x = wdc->hot.x;
        !           563:                ss->ss_curhot.y = wdc->hot.y;
        !           564:        }
        !           565:        if (wdc->which & WSDISPLAY_CURSOR_DOSHAPE) {
        !           566:                bcopy(curfg, ss->ss_curimg, sizeof ss->ss_curimg);
        !           567:                bcopy(curmask, ss->ss_curmask, sizeof ss->ss_curmask);
        !           568:        }
        !           569:
        !           570:        /*
        !           571:         * ...and update the cursor
        !           572:         */
        !           573:        smg_updatecursor(ss, wdc->which);
        !           574:
        !           575:        return (0);
        !           576: }
        !           577:
        !           578: void
        !           579: smg_updatecursor(struct smg_screen *ss, u_int which)
        !           580: {
        !           581:        u_int i;
        !           582:
        !           583:        if (which & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
        !           584:                ss->ss_cursor->xpos =
        !           585:                    ss->ss_curpos.x - ss->ss_curhot.x + CUR_XBIAS;
        !           586:                ss->ss_cursor->ypos =
        !           587:                    ss->ss_curpos.y - ss->ss_curhot.y + CUR_YBIAS;
        !           588:        }
        !           589:        if (which & WSDISPLAY_CURSOR_DOSHAPE) {
        !           590:                ss->ss_cursor->cmdr = ss->ss_curcmd | PCCCMD_LODSA;
        !           591:                for (i = 0; i < PCC_CURSOR_SIZE; i++)
        !           592:                        ss->ss_cursor->load = ss->ss_curimg[i];
        !           593:                for (i = 0; i < PCC_CURSOR_SIZE; i++)
        !           594:                        ss->ss_cursor->load = ss->ss_curmask[i];
        !           595:                ss->ss_cursor->cmdr = ss->ss_curcmd;
        !           596:        } else
        !           597:        if (which & WSDISPLAY_CURSOR_DOCUR)
        !           598:                ss->ss_cursor->cmdr = ss->ss_curcmd;
        !           599: }
        !           600:
        !           601: /*
        !           602:  * Faster console operations
        !           603:  */
        !           604:
        !           605: #include <vax/vsa/maskbits.h>
        !           606:
        !           607: void
        !           608: smg_blockmove(struct rasops_info *ri, u_int sx, u_int y, u_int dx, u_int cx,
        !           609:     u_int cy, int rop)
        !           610: {
        !           611:        int width;              /* add to get to same position in next line */
        !           612:
        !           613:        unsigned int *psrcLine, *pdstLine;
        !           614:                                /* pointers to line with current src and dst */
        !           615:        unsigned int *psrc;     /* pointer to current src longword */
        !           616:        unsigned int *pdst;     /* pointer to current dst longword */
        !           617:
        !           618:                                /* following used for looping through a line */
        !           619:        unsigned int startmask, endmask;  /* masks for writing ends of dst */
        !           620:        int nlMiddle;           /* whole longwords in dst */
        !           621:        int nl;                 /* temp copy of nlMiddle */
        !           622:        int xoffSrc;            /* offset (>= 0, < 32) from which to
        !           623:                                   fetch whole longwords fetched in src */
        !           624:        int nstart;             /* number of ragged bits at start of dst */
        !           625:        int nend;               /* number of ragged bits at end of dst */
        !           626:        int srcStartOver;       /* pulling nstart bits from src
        !           627:                                   overflows into the next word? */
        !           628:
        !           629:        width = SM_XWIDTH >> 5;
        !           630:
        !           631:        /* start at first scanline */
        !           632:        psrcLine = pdstLine = ((u_int *)ri->ri_bits) + (y * width);
        !           633:
        !           634:        /* x direction doesn't matter for < 1 longword */
        !           635:        if (cx <= 32) {
        !           636:                int srcBit, dstBit;     /* bit offset of src and dst */
        !           637:
        !           638:                pdstLine += (dx >> 5);
        !           639:                psrcLine += (sx >> 5);
        !           640:                psrc = psrcLine;
        !           641:                pdst = pdstLine;
        !           642:
        !           643:                srcBit = sx & 0x1f;
        !           644:                dstBit = dx & 0x1f;
        !           645:
        !           646:                while (cy--) {
        !           647:                        getandputrop(psrc, srcBit, dstBit, cx, pdst, rop);
        !           648:                        pdst += width;
        !           649:                        psrc += width;
        !           650:                }
        !           651:        } else {
        !           652:                maskbits(dx, cx, startmask, endmask, nlMiddle);
        !           653:                if (startmask)
        !           654:                        nstart = 32 - (dx & 0x1f);
        !           655:                else
        !           656:                        nstart = 0;
        !           657:                if (endmask)
        !           658:                        nend = (dx + cx) & 0x1f;
        !           659:                else
        !           660:                        nend = 0;
        !           661:
        !           662:                xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
        !           663:                srcStartOver = ((sx & 0x1f) + nstart) > 31;
        !           664:
        !           665:                if (sx >= dx) { /* move left to right */
        !           666:                        pdstLine += (dx >> 5);
        !           667:                        psrcLine += (sx >> 5);
        !           668:
        !           669:                        while (cy--) {
        !           670:                                psrc = psrcLine;
        !           671:                                pdst = pdstLine;
        !           672:
        !           673:                                if (startmask) {
        !           674:                                        getandputrop(psrc, (sx & 0x1f),
        !           675:                                            (dx & 0x1f), nstart, pdst, rop);
        !           676:                                        pdst++;
        !           677:                                        if (srcStartOver)
        !           678:                                                psrc++;
        !           679:                                }
        !           680:
        !           681:                                /* special case for aligned operations */
        !           682:                                if (xoffSrc == 0) {
        !           683:                                        nl = nlMiddle;
        !           684:                                        while (nl--) {
        !           685:                                                switch (rop) {
        !           686:                                                case RR_CLEAR:
        !           687:                                                        *pdst = 0;
        !           688:                                                        break;
        !           689:                                                case RR_SET:
        !           690:                                                        *pdst = ~0;
        !           691:                                                        break;
        !           692:                                                default:
        !           693:                                                        *pdst = *psrc;
        !           694:                                                        break;
        !           695:                                                }
        !           696:                                                psrc++;
        !           697:                                                pdst++;
        !           698:                                        }
        !           699:                                } else {
        !           700:                                        nl = nlMiddle + 1;
        !           701:                                        while (--nl) {
        !           702:                                                switch (rop) {
        !           703:                                                case RR_CLEAR:
        !           704:                                                        *pdst = 0;
        !           705:                                                        break;
        !           706:                                                case RR_SET:
        !           707:                                                        *pdst = ~0;
        !           708:                                                        break;
        !           709:                                                default:
        !           710:                                                        getunalignedword(psrc,
        !           711:                                                            xoffSrc, *pdst);
        !           712:                                                        break;
        !           713:                                                }
        !           714:                                                pdst++;
        !           715:                                                psrc++;
        !           716:                                        }
        !           717:                                }
        !           718:
        !           719:                                if (endmask) {
        !           720:                                        getandputrop(psrc, xoffSrc, 0, nend,
        !           721:                                            pdst, rop);
        !           722:                                }
        !           723:
        !           724:                                pdstLine += width;
        !           725:                                psrcLine += width;
        !           726:                        }
        !           727:                } else {        /* move right to left */
        !           728:                        pdstLine += ((dx + cx) >> 5);
        !           729:                        psrcLine += ((sx + cx) >> 5);
        !           730:                        /*
        !           731:                         * If fetch of last partial bits from source crosses
        !           732:                         * a longword boundary, start at the previous longword
        !           733:                         */
        !           734:                        if (xoffSrc + nend >= 32)
        !           735:                                --psrcLine;
        !           736:
        !           737:                        while (cy--) {
        !           738:                                psrc = psrcLine;
        !           739:                                pdst = pdstLine;
        !           740:
        !           741:                                if (endmask) {
        !           742:                                        getandputrop(psrc, xoffSrc, 0, nend,
        !           743:                                            pdst, rop);
        !           744:                                }
        !           745:
        !           746:                                nl = nlMiddle + 1;
        !           747:                                while (--nl) {
        !           748:                                        --psrc;
        !           749:                                        --pdst;
        !           750:                                        switch (rop) {
        !           751:                                        case RR_CLEAR:
        !           752:                                                *pdst = 0;
        !           753:                                                break;
        !           754:                                        case RR_SET:
        !           755:                                                *pdst = ~0;
        !           756:                                                break;
        !           757:                                        default:
        !           758:                                                getunalignedword(psrc, xoffSrc,
        !           759:                                                    *pdst);
        !           760:                                                break;
        !           761:                                        }
        !           762:                                }
        !           763:
        !           764:                                if (startmask) {
        !           765:                                        if (srcStartOver)
        !           766:                                                --psrc;
        !           767:                                        --pdst;
        !           768:                                        getandputrop(psrc, (sx & 0x1f),
        !           769:                                            (dx & 0x1f), nstart, pdst, rop);
        !           770:                                }
        !           771:
        !           772:                                pdstLine += width;
        !           773:                                psrcLine += width;
        !           774:                        }
        !           775:                }
        !           776:        }
        !           777: }
        !           778:
        !           779: void
        !           780: smg_copycols(void *cookie, int row, int src, int dst, int n)
        !           781: {
        !           782:        struct rasops_info *ri = cookie;
        !           783:
        !           784:        n *= ri->ri_font->fontwidth;
        !           785:        src *= ri->ri_font->fontwidth;
        !           786:        dst *= ri->ri_font->fontwidth;
        !           787:        row *= ri->ri_font->fontheight;
        !           788:
        !           789:        smg_blockmove(ri, src, row, dst, n, ri->ri_font->fontheight,
        !           790:            RR_COPY);
        !           791: }
        !           792:
        !           793: void
        !           794: smg_erasecols(void *cookie, int row, int col, int num, long attr)
        !           795: {
        !           796:        struct rasops_info *ri = cookie;
        !           797:        int fg, bg;
        !           798:
        !           799:        ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
        !           800:
        !           801:        num *= ri->ri_font->fontwidth;
        !           802:        col *= ri->ri_font->fontwidth;
        !           803:        row *= ri->ri_font->fontheight;
        !           804:
        !           805:        smg_blockmove(ri, col, row, col, num, ri->ri_font->fontheight,
        !           806:            bg == 0 ? RR_CLEAR : RR_SET);
        !           807: }
        !           808:
        !           809: /*
        !           810:  * Console support code
        !           811:  */
        !           812:
        !           813: int    smgcnprobe(void);
        !           814: void   smgcninit(void);
        !           815:
        !           816: int
        !           817: smgcnprobe()
        !           818: {
        !           819:        switch (vax_boardtype) {
        !           820:        case VAX_BTYP_410:
        !           821:        case VAX_BTYP_420:
        !           822:        case VAX_BTYP_43:
        !           823:                if ((vax_confdata & (KA420_CFG_L3CON | KA420_CFG_MULTU)) != 0)
        !           824:                        break; /* doesn't use graphics console */
        !           825:
        !           826:                if ((vax_confdata & KA420_CFG_VIDOPT) != 0)
        !           827:                        break;  /* there is a color option */
        !           828:
        !           829:                return (1);
        !           830:
        !           831:        default:
        !           832:                break;
        !           833:        }
        !           834:
        !           835:        return (0);
        !           836: }
        !           837:
        !           838: /*
        !           839:  * Called very early to setup the glass tty as console.
        !           840:  * Because it's called before the VM system is initialized, virtual memory
        !           841:  * for the framebuffer can be stolen directly without disturbing anything.
        !           842:  */
        !           843: void
        !           844: smgcninit()
        !           845: {
        !           846:        struct smg_screen *ss = &smg_consscr;
        !           847:        extern vaddr_t virtual_avail;
        !           848:        long defattr;
        !           849:        struct rasops_info *ri;
        !           850:
        !           851:        ss->ss_addr = (caddr_t)virtual_avail;
        !           852:        virtual_avail += SMSIZE;
        !           853:        ioaccess((vaddr_t)ss->ss_addr, SMADDR, SMSIZE / VAX_NBPG);
        !           854:
        !           855:        ss->ss_cursor = (struct dc503reg *)virtual_avail;
        !           856:        virtual_avail += VAX_NBPG;
        !           857:        ioaccess((vaddr_t)ss->ss_cursor, KA420_CUR_BASE, 1);
        !           858:
        !           859:        virtual_avail = round_page(virtual_avail);
        !           860:
        !           861:        /* this had better not fail as we can't recover there */
        !           862:        if (smg_setup_screen(ss) != 0)
        !           863:                panic(__func__);
        !           864:
        !           865:        ri = &ss->ss_ri;
        !           866:        ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
        !           867:        wsdisplay_cnattach(&smg_stdscreen, ri, 0, 0, defattr);
        !           868: }

CVSweb