[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

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