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

Annotation of sys/arch/mac68k/dev/macfb.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: macfb.c,v 1.18 2006/11/29 12:13:54 miod Exp $ */
        !             2: /* $NetBSD: macfb.c,v 1.11 2005/01/15 16:00:59 chs Exp $ */
        !             3: /*
        !             4:  * Copyright (c) 1998 Matt DeBergalis
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *    must display the following acknowledgement:
        !            17:  *      This product includes software developed by Matt DeBergalis
        !            18:  * 4. The name of the author may not be used to endorse or promote products
        !            19:  *    derived from this software without specific prior written permission
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            23:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            24:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            25:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            26:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            30:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            31:  */
        !            32:
        !            33: #include <sys/param.h>
        !            34: #include <sys/systm.h>
        !            35: #include <sys/kernel.h>
        !            36: #include <sys/device.h>
        !            37: #include <sys/malloc.h>
        !            38:
        !            39: #include <machine/cpu.h>
        !            40: #include <machine/bus.h>
        !            41:
        !            42: #include <mac68k/dev/nubus.h>
        !            43:
        !            44: #include <uvm/uvm_extern.h>
        !            45:
        !            46: #include <dev/wscons/wsconsio.h>
        !            47: #include <dev/wscons/wsdisplayvar.h>
        !            48: #include <dev/rasops/rasops.h>
        !            49:
        !            50: #include <mac68k/dev/macfbvar.h>
        !            51:
        !            52: struct cfdriver macfb_cd = {
        !            53:        NULL, "macfb", DV_DULL
        !            54: };
        !            55:
        !            56: int    macfb_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !            57: paddr_t        macfb_mmap(void *, off_t, int);
        !            58: int    macfb_alloc_screen(void *, const struct wsscreen_descr *,
        !            59:                    void **, int *, int *, long *);
        !            60: void   macfb_free_screen(void *, void *);
        !            61: int    macfb_show_screen(void *, void *, int,
        !            62:                    void (*)(void *, int, int), void *);
        !            63:
        !            64: const struct wsdisplay_accessops macfb_accessops = {
        !            65:        macfb_ioctl,
        !            66:        macfb_mmap,
        !            67:        macfb_alloc_screen,
        !            68:        macfb_free_screen,
        !            69:        macfb_show_screen,
        !            70:        NULL,   /* load_font */
        !            71:        NULL,   /* scrollback */
        !            72:        NULL,   /* getchar */
        !            73:        NULL    /* burner */
        !            74: };
        !            75:
        !            76: int    macfb_alloc_cattr(void *, int, int, int, long *);
        !            77: int    macfb_alloc_hattr(void *, int, int, int, long *);
        !            78: int    macfb_alloc_mattr(void *, int, int, int, long *);
        !            79: int    macfb_color_setup(struct macfb_devconfig *);
        !            80: int    macfb_getcmap(struct macfb_devconfig *, struct wsdisplay_cmap *);
        !            81: int    macfb_init(struct macfb_devconfig *);
        !            82: int    macfb_is_console(paddr_t);
        !            83: void   macfb_palette_setup(struct macfb_devconfig *);
        !            84: int    macfb_putcmap(struct macfb_devconfig *, struct wsdisplay_cmap *);
        !            85:
        !            86: paddr_t macfb_consaddr;
        !            87:
        !            88: static struct macfb_devconfig macfb_console_dc;
        !            89:
        !            90: /* From Booter via locore */
        !            91: extern long            videoaddr;
        !            92: extern long            videorowbytes;
        !            93: extern long            videobitdepth;
        !            94: extern u_long          videosize;
        !            95: extern u_int32_t       mac68k_vidphys;
        !            96: extern u_int32_t       mac68k_vidlen;
        !            97:
        !            98: extern int rasops_alloc_cattr(void *, int, int, int, long *);
        !            99:
        !           100: int
        !           101: macfb_is_console(paddr_t addr)
        !           102: {
        !           103:        if (addr != macfb_consaddr && (addr >= NBBASE && addr < NBTOP)) {
        !           104:                /*
        !           105:                 * This is in the NuBus standard slot space range, so we
        !           106:                 * may well have to look at 0xFssxxxxx, too.  Mask off the
        !           107:                 * slot number and duplicate it in bits 20-23, per IM:V
        !           108:                 * pp 459, 463, and IM:VI ch 30 p 17.
        !           109:                 * Note:  this is an ugly hack and I wish I knew what
        !           110:                 * to do about it.  -- sr
        !           111:                 */
        !           112:                addr = (paddr_t)(((u_long)addr & 0xff0fffff) |
        !           113:                    (((u_long)addr & 0x0f000000) >> 4));
        !           114:        }
        !           115:        return ((mac68k_machine.serial_console & 0x03) == 0
        !           116:            && (addr == macfb_consaddr));
        !           117: }
        !           118:
        !           119: int
        !           120: macfb_init(struct macfb_devconfig *dc)
        !           121: {
        !           122:        struct rasops_info *ri = &dc->dc_ri;
        !           123:        int bgcolor;
        !           124:
        !           125:        bzero(ri, sizeof(*ri));
        !           126:        ri->ri_depth = dc->dc_depth;
        !           127:        ri->ri_stride = dc->dc_rowbytes;
        !           128:        ri->ri_flg = RI_CENTER;
        !           129:        ri->ri_bits = (void *)(dc->dc_vaddr + dc->dc_offset);
        !           130:        ri->ri_width = dc->dc_wid;
        !           131:        ri->ri_height = dc->dc_ht;
        !           132:        ri->ri_hw = dc;
        !           133:
        !           134:        /* swap B and R if necessary */
        !           135:        switch (ri->ri_depth) {
        !           136:        case 16:
        !           137:                ri->ri_rnum = 5;
        !           138:                ri->ri_rpos = 11;
        !           139:                ri->ri_gnum = 6;
        !           140:                ri->ri_gpos = 5;
        !           141:                ri->ri_bnum = 5;
        !           142:                ri->ri_bpos = 0;
        !           143:                break;
        !           144:        case 24:
        !           145:        case 32:
        !           146:                ri->ri_rnum = 8;
        !           147:                ri->ri_rpos = 16;
        !           148:                ri->ri_gnum = 8;
        !           149:                ri->ri_gpos = 8;
        !           150:                ri->ri_bnum = 8;
        !           151:                ri->ri_bpos = 0;
        !           152:                break;
        !           153:        }
        !           154:
        !           155:        /*
        !           156:         * Ask for an unholy big display, rasops will trim this to more
        !           157:         * reasonable values.
        !           158:         */
        !           159:        if (rasops_init(ri, 160, 160) != 0)
        !           160:                return (-1);
        !           161:
        !           162:        bgcolor = macfb_color_setup(dc);
        !           163:
        !           164:        /*
        !           165:         * Clear display. We can't pass RI_CLEAR in ri_flg and have rasops
        !           166:         * do it for us until we know how to setup the colormap first.
        !           167:         */
        !           168:        memset((char *)dc->dc_vaddr + dc->dc_offset, bgcolor,
        !           169:             dc->dc_rowbytes * dc->dc_ht);
        !           170:
        !           171:        strlcpy(dc->dc_wsd.name, "std", sizeof(dc->dc_wsd.name));
        !           172:        dc->dc_wsd.ncols = ri->ri_cols;
        !           173:        dc->dc_wsd.nrows = ri->ri_rows;
        !           174:        dc->dc_wsd.textops = &ri->ri_ops;
        !           175:        dc->dc_wsd.fontwidth = ri->ri_font->fontwidth;
        !           176:        dc->dc_wsd.fontheight = ri->ri_font->fontheight;
        !           177:        dc->dc_wsd.capabilities = ri->ri_caps;
        !           178:
        !           179:        return (0);
        !           180: }
        !           181:
        !           182: int
        !           183: macfb_color_setup(struct macfb_devconfig *dc)
        !           184: {
        !           185:        extern int rasops_alloc_cattr(void *, int, int, int, long *);
        !           186:        struct rasops_info *ri = &dc->dc_ri;
        !           187:
        !           188:        /* nothing to do for non-indexed modes... */
        !           189:        if (ri->ri_depth > 8)
        !           190:                return (0);     /* fill in black */
        !           191:
        !           192:        if (dc->dc_setcolor == NULL || ISSET(dc->dc_flags, FB_MACOS_PALETTE) ||
        !           193:            ri->ri_depth < 2) {
        !           194:                /*
        !           195:                 * Until we know how to setup the colormap, or if we are
        !           196:                 * already initialized (i.e. glass console), constrain ourselves
        !           197:                 * to mono mode. Note that we need to use our own alloc_attr
        !           198:                 * routine to compensate for inverted black and white colors.
        !           199:                 */
        !           200:                ri->ri_ops.alloc_attr = macfb_alloc_mattr;
        !           201:                ri->ri_caps &= ~(WSSCREEN_WSCOLORS | WSSCREEN_HILIT);
        !           202:                if (ri->ri_depth == 8)
        !           203:                        ri->ri_devcmap[15] = 0xffffffff;
        !           204:
        !           205:                macfb_palette_setup(dc);
        !           206:
        !           207:                return (0xff);  /* fill in black inherited from MacOS */
        !           208:        }
        !           209:
        !           210:        /* start from the rasops colormap */
        !           211:        bcopy(rasops_cmap, dc->dc_cmap, 256 * 3);
        !           212:
        !           213:        switch (ri->ri_depth) {
        !           214:        case 2:
        !           215:                /*
        !           216:                 * 2bpp mode does not really have colors, only two gray
        !           217:                 * shades in addition to black and white, to allow
        !           218:                 * hilighting.
        !           219:                 *
        !           220:                 * Our palette needs to be:
        !           221:                 *   00 black
        !           222:                 *   01 dark gray (highlighted black, sort of)
        !           223:                 *   02 light gray (normal white)
        !           224:                 *   03 white (highlighted white)
        !           225:                 */
        !           226:                bcopy(dc->dc_cmap + (255 - WSCOL_WHITE) * 3,
        !           227:                    dc->dc_cmap + 1 * 3, 3);
        !           228:                bcopy(dc->dc_cmap + WSCOL_WHITE * 3, dc->dc_cmap + 2 * 3, 3);
        !           229:                bcopy(dc->dc_cmap + (8 + WSCOL_WHITE) * 3,
        !           230:                    dc->dc_cmap + 3 * 3, 3);
        !           231:                ri->ri_caps |= WSSCREEN_HILIT;
        !           232:                ri->ri_ops.alloc_attr = macfb_alloc_hattr;
        !           233:                break;
        !           234:        case 4:
        !           235:                /*
        !           236:                 * Tweak colormap
        !           237:                 *
        !           238:                 * Due to the way rasops cursor work, we need to provide
        !           239:                 * inverted copies of the 8 basic colors as the other 8
        !           240:                 * in 4bpp mode.
        !           241:                 */
        !           242:                bcopy(dc->dc_cmap + (256 - 8) * 3, dc->dc_cmap + 8 * 3, 8 * 3);
        !           243:                ri->ri_caps |= WSSCREEN_WSCOLORS;
        !           244:                ri->ri_ops.alloc_attr = macfb_alloc_cattr;
        !           245:                break;
        !           246:        default:
        !           247:        case 8:
        !           248:                break;
        !           249:        }
        !           250:
        !           251:        (*dc->dc_setcolor)(dc, 0, 1 << ri->ri_depth);
        !           252:
        !           253:        return (WSCOL_BLACK);   /* fill in our own black */
        !           254: }
        !           255:
        !           256: /*
        !           257:  * Initialize a black and white, MacOS compatible, shadow colormap.
        !           258:  * This is necessary if we still want to be able to run X11 with colors.
        !           259:  */
        !           260: void
        !           261: macfb_palette_setup(struct macfb_devconfig *dc)
        !           262: {
        !           263:        memset(dc->dc_cmap, 0xff, 3);           /* white */
        !           264:        bzero(dc->dc_cmap + 3, 255 * 3);        /* black */
        !           265: }
        !           266:
        !           267: /*
        !           268:  * Attribute allocator for monochrome displays (either 1bpp or no colormap
        !           269:  * control). Note that the colors we return are indexes into ri_devcmap which
        !           270:  * will select the actual bits.
        !           271:  */
        !           272: int
        !           273: macfb_alloc_mattr(void *cookie, int fg, int bg, int flg, long *attr)
        !           274: {
        !           275:        if ((flg & (WSATTR_BLINK | WSATTR_HILIT | WSATTR_WSCOLORS)) != 0)
        !           276:                return (EINVAL);
        !           277:
        !           278:        /*
        !           279:         * Default values are white on black. However, on indexed displays,
        !           280:         * 0 is white and all bits set is black.
        !           281:         */
        !           282:        if ((flg & WSATTR_REVERSE) != 0) {
        !           283:                fg = 15;
        !           284:                bg = 0;
        !           285:        } else {
        !           286:                fg = 0;
        !           287:                bg = 15;
        !           288:        }
        !           289:
        !           290:        *attr = (bg << 16) | (fg << 24) | ((flg & WSATTR_UNDERLINE) ? 7 : 6);
        !           291:        return (0);
        !           292: }
        !           293:
        !           294: /*
        !           295:  * Attribute allocator for 2bpp displays.
        !           296:  * Note that the colors we return are indexes into ri_devcmap which will
        !           297:  * select the actual bits.
        !           298:  */
        !           299: int
        !           300: macfb_alloc_hattr(void *cookie, int fg, int bg, int flg, long *attr)
        !           301: {
        !           302:        if ((flg & (WSATTR_BLINK | WSATTR_WSCOLORS)) != 0)
        !           303:                return (EINVAL);
        !           304:
        !           305:        if ((flg & WSATTR_REVERSE) != 0) {
        !           306:                fg = WSCOL_BLACK;
        !           307:                bg = WSCOL_WHITE;
        !           308:        } else {
        !           309:                fg = WSCOL_WHITE;
        !           310:                bg = WSCOL_BLACK;
        !           311:        }
        !           312:
        !           313:        if ((flg & WSATTR_HILIT) != 0)
        !           314:                fg += 8;
        !           315:
        !           316:        *attr = (bg << 16) | (fg << 24) | ((flg & WSATTR_UNDERLINE) ? 7 : 6);
        !           317:        return (0);
        !           318: }
        !           319:
        !           320: /*
        !           321:  * Attribute allocator for 4bpp displays.
        !           322:  */
        !           323: int
        !           324: macfb_alloc_cattr(void *cookie, int fg, int bg, int flg, long *attr)
        !           325: {
        !           326:        if ((flg & (WSATTR_BLINK | WSATTR_HILIT)) != 0)
        !           327:                return (EINVAL);
        !           328:
        !           329:        return (rasops_alloc_cattr(cookie, fg, bg, flg, attr));
        !           330: }
        !           331:
        !           332: void
        !           333: macfb_attach_common(struct macfb_softc *sc, struct macfb_devconfig *dc)
        !           334: {
        !           335:        struct wsemuldisplaydev_attach_args waa;
        !           336:        int isconsole;
        !           337:
        !           338:        /* Print hardware characteristics. */
        !           339:        printf("%s: %dx%d, ", sc->sc_dev.dv_xname, dc->dc_wid, dc->dc_ht);
        !           340:        if (dc->dc_depth == 1)
        !           341:                printf("monochrome");
        !           342:        else
        !           343:                printf("%dbit color", dc->dc_depth);
        !           344:        printf(" display\n");
        !           345:
        !           346:        isconsole = macfb_is_console(sc->sc_basepa + dc->dc_offset);
        !           347:
        !           348:        if (isconsole) {
        !           349:                macfb_console_dc.dc_setcolor = dc->dc_setcolor;
        !           350:                macfb_console_dc.dc_cmapregs = dc->dc_cmapregs;
        !           351:                free(dc, M_DEVBUF);
        !           352:                dc = sc->sc_dc = &macfb_console_dc;
        !           353:                dc->dc_nscreens = 1;
        !           354:                macfb_color_setup(dc);
        !           355:                /* XXX at this point we should reset the emulation to have
        !           356:                 * it pick better attributes for kernel messages. Oh well. */
        !           357:        } else {
        !           358:                sc->sc_dc = dc;
        !           359:                if (macfb_init(dc) != 0)
        !           360:                        return;
        !           361:        }
        !           362:
        !           363:        dc->dc_scrlist[0] = &dc->dc_wsd;
        !           364:        dc->dc_screenlist.nscreens = 1;
        !           365:        dc->dc_screenlist.screens =
        !           366:            (const struct wsscreen_descr **)dc->dc_scrlist;
        !           367:
        !           368:        waa.console = isconsole;
        !           369:        waa.scrdata = &dc->dc_screenlist;
        !           370:        waa.accessops = &macfb_accessops;
        !           371:        waa.accesscookie = sc;
        !           372:        waa.defaultscreens = 0;
        !           373:
        !           374:        config_found((struct device *)sc, &waa, wsemuldisplaydevprint);
        !           375: }
        !           376:
        !           377: int
        !           378: macfb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
        !           379: {
        !           380:        struct macfb_softc *sc = v;
        !           381:        struct macfb_devconfig *dc = sc->sc_dc;
        !           382:        struct wsdisplay_fbinfo *wdf;
        !           383:
        !           384:        switch (cmd) {
        !           385:        case WSDISPLAYIO_GTYPE:
        !           386:                *(int *)data = WSDISPLAY_TYPE_MAC68K;
        !           387:                break;
        !           388:        case WSDISPLAYIO_GINFO:
        !           389:                wdf = (struct wsdisplay_fbinfo *)data;
        !           390:                wdf->height = dc->dc_ri.ri_height;
        !           391:                wdf->width = dc->dc_ri.ri_width;
        !           392:                wdf->depth = dc->dc_ri.ri_depth;
        !           393:                if (dc->dc_ri.ri_depth > 8 || dc->dc_setcolor == NULL)
        !           394:                        wdf->cmsize = 0;
        !           395:                else
        !           396:                        wdf->cmsize = 1 << dc->dc_ri.ri_depth;
        !           397:                break;
        !           398:        case WSDISPLAYIO_LINEBYTES:
        !           399:                *(u_int *)data = dc->dc_ri.ri_stride;
        !           400:                break;
        !           401:        case WSDISPLAYIO_GETCMAP:
        !           402:                if (dc->dc_ri.ri_depth > 8 || dc->dc_setcolor == NULL)
        !           403:                        return (0);
        !           404:                return (macfb_getcmap(dc, (struct wsdisplay_cmap *)data));
        !           405:        case WSDISPLAYIO_PUTCMAP:
        !           406:                if (dc->dc_ri.ri_depth > 8 || dc->dc_setcolor == NULL)
        !           407:                        return (0);
        !           408:                return (macfb_putcmap(dc, (struct wsdisplay_cmap *)data));
        !           409:        case WSDISPLAYIO_SMODE:
        !           410:                if (dc->dc_ri.ri_depth > 8 || dc->dc_setcolor == NULL)
        !           411:                        return (0);
        !           412:                if (*(u_int *)data == WSDISPLAYIO_MODE_EMUL &&
        !           413:                    ISSET(dc->dc_flags, FB_MACOS_PALETTE)) {
        !           414:                        macfb_palette_setup(dc);
        !           415:                        (*dc->dc_setcolor)(dc, 0, 1 << dc->dc_ri.ri_depth);
        !           416:                        /* clear display */
        !           417:                        memset((char *)dc->dc_vaddr + dc->dc_offset, 0xff,
        !           418:                             dc->dc_rowbytes * dc->dc_ht);
        !           419:                }
        !           420:                break;
        !           421:        case WSDISPLAYIO_GVIDEO:
        !           422:        case WSDISPLAYIO_SVIDEO:
        !           423:                break;
        !           424:        default:
        !           425:                return (-1);
        !           426:        }
        !           427:
        !           428:        return (0);
        !           429: }
        !           430:
        !           431: paddr_t
        !           432: macfb_mmap(void *v, off_t offset, int prot)
        !           433: {
        !           434:        struct macfb_softc *sc = v;
        !           435:        struct macfb_devconfig *dc = sc->sc_dc;
        !           436:        paddr_t addr;
        !           437:
        !           438:        if (offset >= 0 &&
        !           439:            offset < round_page(dc->dc_size))
        !           440:                addr = atop(dc->dc_paddr + dc->dc_offset + offset);
        !           441:        else
        !           442:                addr = (-1);
        !           443:
        !           444:        return addr;
        !           445: }
        !           446:
        !           447: int
        !           448: macfb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
        !           449:     int *curxp, int *curyp, long *defattrp)
        !           450: {
        !           451:        struct macfb_softc *sc = v;
        !           452:        struct rasops_info *ri = &sc->sc_dc->dc_ri;
        !           453:
        !           454:        if (sc->sc_dc->dc_nscreens > 0)
        !           455:                return (ENOMEM);
        !           456:
        !           457:        *cookiep = ri;
        !           458:        *curxp = *curyp = 0;
        !           459:        ri->ri_ops.alloc_attr(ri, 0, 0, 0, defattrp);
        !           460:        sc->sc_dc->dc_nscreens++;
        !           461:
        !           462:        return (0);
        !           463: }
        !           464:
        !           465: void
        !           466: macfb_free_screen(void *v, void *cookie)
        !           467: {
        !           468:        struct macfb_softc *sc = v;
        !           469:
        !           470:        sc->sc_dc->dc_nscreens--;
        !           471: }
        !           472:
        !           473: int
        !           474: macfb_show_screen(void *v, void *cookie, int waitok,
        !           475:     void (*cb)(void *, int, int), void *cbarg)
        !           476: {
        !           477:        return (0);
        !           478: }
        !           479:
        !           480: int
        !           481: macfb_getcmap(struct macfb_devconfig *dc, struct wsdisplay_cmap *cm)
        !           482: {
        !           483:        u_int index = cm->index, count = cm->count;
        !           484:        u_int colcount = 1 << dc->dc_ri.ri_depth;
        !           485:        int i, error;
        !           486:        u_int8_t ramp[256], *c, *r;
        !           487:
        !           488:        if (index >= colcount || count > colcount - index)
        !           489:                return (EINVAL);
        !           490:
        !           491:        /* extract reds */
        !           492:        c = dc->dc_cmap + 0 + index * 3;
        !           493:        for (i = count, r = ramp; i != 0; i--)
        !           494:                *r++ = *c, c += 3;
        !           495:        if ((error = copyout(ramp, cm->red, count)) != 0)
        !           496:                return (error);
        !           497:
        !           498:        /* extract greens */
        !           499:        c = dc->dc_cmap + 1 + index * 3;
        !           500:        for (i = count, r = ramp; i != 0; i--)
        !           501:                *r++ = *c, c += 3;
        !           502:        if ((error = copyout(ramp, cm->green, count)) != 0)
        !           503:                return (error);
        !           504:
        !           505:        /* extract blues */
        !           506:        c = dc->dc_cmap + 2 + index * 3;
        !           507:        for (i = count, r = ramp; i != 0; i--)
        !           508:                *r++ = *c, c += 3;
        !           509:        if ((error = copyout(ramp, cm->blue, count)) != 0)
        !           510:                return (error);
        !           511:
        !           512:        return (0);
        !           513: }
        !           514:
        !           515: int
        !           516: macfb_putcmap(struct macfb_devconfig *dc, struct wsdisplay_cmap *cm)
        !           517: {
        !           518:        u_int index = cm->index, count = cm->count;
        !           519:        u_int colcount = 1 << dc->dc_ri.ri_depth;
        !           520:        int i, error;
        !           521:        u_int8_t r[256], g[256], b[256], *nr, *ng, *nb, *c;
        !           522:
        !           523:        if (index >= colcount || count > colcount - index)
        !           524:                return (EINVAL);
        !           525:
        !           526:        if ((error = copyin(cm->red, r, count)) != 0)
        !           527:                return (error);
        !           528:        if ((error = copyin(cm->green, g, count)) != 0)
        !           529:                return (error);
        !           530:        if ((error = copyin(cm->blue, b, count)) != 0)
        !           531:                return (error);
        !           532:
        !           533:        nr = r, ng = g, nb = b;
        !           534:        c = dc->dc_cmap + index * 3;
        !           535:        for (i = count; i != 0; i--) {
        !           536:                *c++ = *nr++;
        !           537:                *c++ = *ng++;
        !           538:                *c++ = *nb++;
        !           539:        }
        !           540:
        !           541:        (*dc->dc_setcolor)(dc, index, index + count);
        !           542:
        !           543:        return (0);
        !           544: }
        !           545:
        !           546: int
        !           547: macfb_cnattach()
        !           548: {
        !           549:        struct macfb_devconfig *dc = &macfb_console_dc;
        !           550:        long defattr;
        !           551:        struct rasops_info *ri;
        !           552:
        !           553:        dc->dc_vaddr = trunc_page(videoaddr);
        !           554:        dc->dc_paddr = trunc_page(mac68k_vidphys);
        !           555:        dc->dc_offset = m68k_page_offset(mac68k_vidphys);
        !           556:        dc->dc_wid = videosize & 0xffff;
        !           557:        dc->dc_ht = (videosize >> 16) & 0xffff;
        !           558:        dc->dc_depth = videobitdepth;
        !           559:        dc->dc_rowbytes = videorowbytes;
        !           560:        dc->dc_size = (mac68k_vidlen > 0) ?
        !           561:            mac68k_vidlen : dc->dc_ht * dc->dc_rowbytes;
        !           562:
        !           563:        /* set up the display */
        !           564:        dc->dc_flags |= FB_MACOS_PALETTE;
        !           565:        if (macfb_init(dc) != 0)
        !           566:                return (-1);
        !           567:
        !           568:        ri = &dc->dc_ri;
        !           569:        ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr);
        !           570:        wsdisplay_cnattach(&dc->dc_wsd, ri, 0, 0, defattr);
        !           571:
        !           572:        macfb_consaddr = mac68k_vidphys;
        !           573:        return (0);
        !           574: }

CVSweb