[BACK]Return to cgsix.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / sun

Annotation of src/sys/dev/sun/cgsix.c, Revision 1.12.2.7

1.12.2.7! skrll       1: /*     $NetBSD: cgsix.c,v 1.12.2.6 2005/04/01 14:30:33 skrll Exp $ */
1.1       pk          2:
                      3: /*-
                      4:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Paul Kranenburg.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *        This product includes software developed by the NetBSD
                     21:  *        Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: /*
                     40:  * Copyright (c) 1993
                     41:  *     The Regents of the University of California.  All rights reserved.
                     42:  *
                     43:  * This software was developed by the Computer Systems Engineering group
                     44:  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
                     45:  * contributed to Berkeley.
                     46:  *
                     47:  * All advertising materials mentioning features or use of this software
                     48:  * must display the following acknowledgement:
                     49:  *     This product includes software developed by the University of
                     50:  *     California, Lawrence Berkeley Laboratory.
                     51:  *
                     52:  * Redistribution and use in source and binary forms, with or without
                     53:  * modification, are permitted provided that the following conditions
                     54:  * are met:
                     55:  * 1. Redistributions of source code must retain the above copyright
                     56:  *    notice, this list of conditions and the following disclaimer.
                     57:  * 2. Redistributions in binary form must reproduce the above copyright
                     58:  *    notice, this list of conditions and the following disclaimer in the
                     59:  *    documentation and/or other materials provided with the distribution.
1.12.2.1  skrll      60:  * 3. Neither the name of the University nor the names of its contributors
1.1       pk         61:  *    may be used to endorse or promote products derived from this software
                     62:  *    without specific prior written permission.
                     63:  *
                     64:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     65:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     66:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     67:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     68:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     69:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     70:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     71:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     72:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     73:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     74:  * SUCH DAMAGE.
                     75:  *
                     76:  *     @(#)cgsix.c     8.4 (Berkeley) 1/21/94
                     77:  */
                     78:
                     79: /*
                     80:  * color display (cgsix) driver.
                     81:  *
                     82:  * Does not handle interrupts, even though they can occur.
                     83:  *
                     84:  * XXX should defer colormap updates to vertical retrace interrupts
                     85:  */
1.7       lukem      86:
                     87: #include <sys/cdefs.h>
1.12.2.7! skrll      88: __KERNEL_RCSID(0, "$NetBSD: cgsix.c,v 1.12.2.6 2005/04/01 14:30:33 skrll Exp $");
1.1       pk         89:
                     90: #include <sys/param.h>
                     91: #include <sys/systm.h>
                     92: #include <sys/buf.h>
                     93: #include <sys/device.h>
                     94: #include <sys/ioctl.h>
                     95: #include <sys/malloc.h>
                     96: #include <sys/mman.h>
                     97: #include <sys/tty.h>
                     98: #include <sys/conf.h>
                     99:
                    100: #ifdef DEBUG
                    101: #include <sys/proc.h>
                    102: #include <sys/syslog.h>
                    103: #endif
                    104:
                    105: #include <uvm/uvm_extern.h>
                    106:
                    107: #include <machine/bus.h>
                    108:
                    109: #include <dev/sun/fbio.h>
                    110: #include <dev/sun/fbvar.h>
                    111:
                    112: #include <dev/sun/btreg.h>
                    113: #include <dev/sun/btvar.h>
                    114: #include <dev/sun/pfourreg.h>
                    115:
                    116: #include <dev/wscons/wsconsio.h>
1.12.2.5  skrll     117: #include <dev/wsfont/wsfont.h>
                    118: #include <dev/rasops/rasops.h>
                    119:
                    120: #include "opt_wsemul.h"
                    121: #include "rasops_glue.h"
1.1       pk        122:
1.12.2.7! skrll     123: #include <dev/sun/cgsixreg.h>
        !           124: #include <dev/sun/cgsixvar.h>
        !           125:
1.1       pk        126: static void    cg6_unblank(struct device *);
                    127:
1.8       gehenna   128: extern struct cfdriver cgsix_cd;
1.1       pk        129:
1.8       gehenna   130: dev_type_open(cgsixopen);
                    131: dev_type_close(cgsixclose);
                    132: dev_type_ioctl(cgsixioctl);
                    133: dev_type_mmap(cgsixmmap);
                    134:
                    135: const struct cdevsw cgsix_cdevsw = {
                    136:        cgsixopen, cgsixclose, noread, nowrite, cgsixioctl,
1.9       jdolecek  137:        nostop, notty, nopoll, cgsixmmap, nokqfilter,
1.8       gehenna   138: };
1.1       pk        139:
                    140: /* frame buffer generic driver */
                    141: static struct fbdriver cg6_fbdriver = {
1.9       jdolecek  142:        cg6_unblank, cgsixopen, cgsixclose, cgsixioctl, nopoll, cgsixmmap,
                    143:        nokqfilter
1.1       pk        144: };
                    145:
                    146: static void cg6_reset (struct cgsix_softc *);
                    147: static void cg6_loadcmap (struct cgsix_softc *, int, int);
                    148: static void cg6_loadomap (struct cgsix_softc *);
                    149: static void cg6_setcursor (struct cgsix_softc *);/* set position */
                    150: static void cg6_loadcursor (struct cgsix_softc *);/* set shape */
                    151:
1.12.2.7! skrll     152: #if NWSDISPLAY > 0
        !           153: static void cg6_setup_palette(struct cgsix_softc *);
        !           154:
1.12.2.5  skrll     155: struct wsscreen_descr cgsix_defaultscreen = {
                    156:        "std",
                    157:        0, 0,   /* will be filled in -- XXX shouldn't, it's global */
1.12.2.7! skrll     158:        NULL,           /* textops */
        !           159:        8, 16,  /* font width/height */
        !           160:        WSSCREEN_WSCOLORS       /* capabilities */
1.12.2.5  skrll     161: };
                    162:
1.12.2.7! skrll     163: static int     cgsix_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !           164: static paddr_t cgsix_mmap(void *, off_t, int);
        !           165: void           cgsix_init_screen(struct cgsix_softc *, struct cg6_screen *,
        !           166:                        int, long *);
        !           167:
        !           168: static int     cgsix_alloc_screen(void *, const struct wsscreen_descr *,
1.12.2.6  skrll     169:                                void **, int *, int *, long *);
1.12.2.7! skrll     170: static void    cgsix_free_screen(void *, void *);
        !           171: static int     cgsix_show_screen(void *, void *, int,
1.12.2.6  skrll     172:                                void (*) (void *, int, int), void *);
1.12.2.7! skrll     173: void   cgsix_switch_screen(struct cgsix_softc *);
        !           174: void   cgsix_restore_screen(struct cg6_screen *, const struct wsscreen_descr *,                u_int16_t *);
        !           175: void   cgsix_clearscreen(struct cgsix_softc *);
        !           176: void   cgsix_setup_mono(struct cgsix_softc *, int, int, int, int, uint32_t,
        !           177:                uint32_t);
        !           178: void   cgsix_feed_line(struct cgsix_softc *, int, uint8_t *);
        !           179: void   cgsix_rectfill(struct cgsix_softc *, int, int, int, int, uint32_t);
        !           180:
        !           181: int    cgsix_putcmap(struct cgsix_softc *, struct wsdisplay_cmap *);
        !           182: int    cgsix_getcmap(struct cgsix_softc *, struct wsdisplay_cmap *);
        !           183: void   cgsix_putchar(void *, int, int, u_int, long);
        !           184: void   cgsix_cursor(void *, int, int, int);
        !           185:
1.12.2.5  skrll     186:
                    187: struct wsdisplay_accessops cgsix_accessops = {
                    188:        cgsix_ioctl,
                    189:        cgsix_mmap,
                    190:        cgsix_alloc_screen,
                    191:        cgsix_free_screen,
                    192:        cgsix_show_screen,
                    193:        NULL,   /* load_font */
                    194:        NULL,   /* pollc */
                    195:        NULL,   /* getwschar */
                    196:        NULL,   /* putwschar */
                    197:        NULL    /* scroll */
                    198: };
                    199:
                    200: const struct wsscreen_descr *_cgsix_scrlist[] = {
                    201:        &cgsix_defaultscreen
                    202: };
                    203:
                    204: struct wsscreen_list cgsix_screenlist = {
                    205:        sizeof(_cgsix_scrlist) / sizeof(struct wsscreen_descr *),
                    206:        _cgsix_scrlist
                    207: };
                    208:
1.12.2.7! skrll     209:
        !           210: extern const u_char rasops_cmap[768];
        !           211:
        !           212: #endif /* NWSDISPLAY > 0 */
        !           213:
        !           214: #if (NWSDISPLAY > 0) || defined(RASTERCONSOLE)
        !           215: void   cg6_invert(struct cgsix_softc *, int, int, int, int);
        !           216:
        !           217: /* need this for both cases because ri_hw points to it */
        !           218: static struct cg6_screen cg6_console_screen;
        !           219: #endif
        !           220:
1.1       pk        221: #ifdef RASTERCONSOLE
                    222: int cgsix_use_rasterconsole = 1;
1.12.2.5  skrll     223: #endif
1.1       pk        224:
                    225: /*
                    226:  * cg6 accelerated console routines.
                    227:  *
                    228:  * Note that buried in this code in several places is the assumption
                    229:  * that pixels are exactly one byte wide.  Since this is cg6-specific
                    230:  * code, this seems safe.  This assumption resides in things like the
                    231:  * use of ri_emuwidth without messing around with ri_pelbytes, or the
                    232:  * assumption that ri_font->fontwidth is the right thing to multiply
                    233:  * character-cell counts by to get byte counts.
                    234:  */
                    235:
                    236: /*
                    237:  * Magic values for blitter
                    238:  */
                    239:
1.5       tsutsui   240: /* Values for the mode register */
                    241: #define CG6_MODE       (                                               \
                    242:          0x00200000 /* GX_BLIT_SRC */                                  \
                    243:        | 0x00020000 /* GX_MODE_COLOR8 */                               \
                    244:        | 0x00008000 /* GX_DRAW_RENDER */                               \
                    245:        | 0x00002000 /* GX_BWRITE0_ENABLE */                            \
                    246:        | 0x00001000 /* GX_BWRITE1_DISABLE */                           \
                    247:        | 0x00000200 /* GX_BREAD_0 */                                   \
                    248:        | 0x00000080 /* GX_BDISP_0 */                                   \
                    249: )
                    250: #define CG6_MODE_MASK  (                                               \
                    251:          0x00300000 /* GX_BLIT_ALL */                                  \
                    252:        | 0x00060000 /* GX_MODE_ALL */                                  \
                    253:        | 0x00018000 /* GX_DRAW_ALL */                                  \
                    254:        | 0x00006000 /* GX_BWRITE0_ALL */                               \
                    255:        | 0x00001800 /* GX_BWRITE1_ALL */                               \
                    256:        | 0x00000600 /* GX_BREAD_ALL */                                 \
                    257:        | 0x00000180 /* GX_BDISP_ALL */                                 \
                    258: )
                    259:
1.1       pk        260: /* Value for the alu register for screen-to-screen copies */
                    261: #define CG6_ALU_COPY   (                                               \
                    262:          0x80000000 /* GX_PLANE_ONES (ignore planemask register) */    \
                    263:        | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */    \
                    264:        | 0x00800000 /* GX_ATTR_SUPP (function unknown) */              \
                    265:        | 0x00000000 /* GX_RAST_BOOL (function unknown) */              \
                    266:        | 0x00000000 /* GX_PLOT_PLOT (function unknown) */              \
                    267:        | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */             \
                    268:        | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */  \
                    269:        | 0x0000cccc /* ALU = src */                                    \
                    270: )
                    271:
                    272: /* Value for the alu register for region fills */
                    273: #define CG6_ALU_FILL   (                                               \
                    274:          0x80000000 /* GX_PLANE_ONES (ignore planemask register) */    \
                    275:        | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */    \
                    276:        | 0x00800000 /* GX_ATTR_SUPP (function unknown) */              \
                    277:        | 0x00000000 /* GX_RAST_BOOL (function unknown) */              \
                    278:        | 0x00000000 /* GX_PLOT_PLOT (function unknown) */              \
                    279:        | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */             \
                    280:        | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */  \
                    281:        | 0x0000ff00 /* ALU = fg color */                               \
                    282: )
                    283:
                    284: /* Value for the alu register for toggling an area */
                    285: #define CG6_ALU_FLIP   (                                               \
                    286:          0x80000000 /* GX_PLANE_ONES (ignore planemask register) */    \
                    287:        | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */    \
                    288:        | 0x00800000 /* GX_ATTR_SUPP (function unknown) */              \
                    289:        | 0x00000000 /* GX_RAST_BOOL (function unknown) */              \
                    290:        | 0x00000000 /* GX_PLOT_PLOT (function unknown) */              \
                    291:        | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */             \
                    292:        | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */  \
                    293:        | 0x00005555 /* ALU = ~dst */                                   \
                    294: )
                    295:
                    296: /*
                    297:  * Wait for a blit to finish.
                    298:  * 0x8000000 bit: function unknown; 0x20000000 bit: GX_BLT_INPROGRESS
                    299:  */
                    300: #define CG6_BLIT_WAIT(fbc) do {                                                \
                    301:        while (((fbc)->fbc_blit & 0xa0000000) == 0xa0000000)            \
                    302:                /*EMPTY*/;                                              \
                    303: } while (0)
                    304:
                    305: /*
                    306:  * Wait for a drawing operation to finish, or at least get queued.
                    307:  * 0x8000000 bit: function unknown; 0x20000000 bit: GX_FULL
                    308:  */
                    309: #define CG6_DRAW_WAIT(fbc) do {                                                \
                    310:                while (((fbc)->fbc_draw & 0xa0000000) == 0xa0000000)            \
                    311:                /*EMPTY*/;                                              \
                    312: } while (0)
                    313:
                    314: /*
                    315:  * Wait for the whole engine to go idle.  This may not matter in our case;
                    316:  * I'm not sure whether blits are actually queued or not.  It more likely
                    317:  * is intended for lines and such that do get queued.
                    318:  * 0x10000000 bit: GX_INPROGRESS
                    319:  */
                    320: #define CG6_DRAIN(fbc) do {                                            \
                    321:        while ((fbc)->fbc_s & 0x10000000)                               \
                    322:                /*EMPTY*/;                                              \
                    323: } while (0)
                    324:
1.12.2.7! skrll     325: #if (NWSDISPLAY > 0) || defined(RASTERCONSOLE)
1.5       tsutsui   326: static void cg6_ras_init(struct cgsix_softc *);
                    327: static void cg6_ras_copyrows(void *, int, int, int);
                    328: static void cg6_ras_copycols(void *, int, int, int, int);
                    329: static void cg6_ras_erasecols(void *, int, int, int, long int);
                    330: static void cg6_ras_eraserows(void *, int, int, long int);
1.12.2.7! skrll     331: #if defined(RASTERCONSOLE) && defined(CG6_BLIT_CURSOR)
1.5       tsutsui   332: static void cg6_ras_do_cursor(struct rasops_info *);
1.12.2.7! skrll     333: #endif
1.5       tsutsui   334: static void
                    335: cg6_ras_init(struct cgsix_softc *sc)
                    336: {
                    337:        volatile struct cg6_fbc *fbc = sc->sc_fbc;
                    338:
                    339:        CG6_DRAIN(fbc);
                    340:        fbc->fbc_mode &= ~CG6_MODE_MASK;
                    341:        fbc->fbc_mode |= CG6_MODE;
                    342: }
                    343:
1.1       pk        344: static void
                    345: cg6_ras_copyrows(void *cookie, int src, int dst, int n)
                    346: {
1.12.2.7! skrll     347:        struct rasops_info *ri=cookie;
        !           348:        struct cg6_screen *scr=ri->ri_hw;
        !           349:        struct cgsix_softc *sc=scr->sc;
        !           350:
        !           351: #if NWSDISPLAY > 0
        !           352:        int from, to, len;
        !           353:
        !           354:        from = ri->ri_cols * src;
        !           355:        to = ri->ri_cols * dst;
        !           356:        len = ri->ri_cols * n;
        !           357:
        !           358:        memmove(&scr->attrs[to], &scr->attrs[from], len * sizeof(long));
        !           359:        memmove(&scr->chars[to], &scr->chars[from], len * sizeof(uint16_t));
        !           360:
        !           361:        if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
        !           362: #endif
        !           363:                volatile struct cg6_fbc *fbc = sc->sc_fbc;
1.1       pk        364:
1.12.2.7! skrll     365:                if (dst == src)
        !           366:                        return;
        !           367:                if (src < 0) {
        !           368:                        n += src;
        !           369:                        src = 0;
        !           370:                }
        !           371:                if (src+n > ri->ri_rows)
        !           372:                        n = ri->ri_rows - src;
        !           373:                if (dst < 0) {
        !           374:                        n += dst;
        !           375:                        dst = 0;
        !           376:                }
        !           377:                if (dst+n > ri->ri_rows)
        !           378:                        n = ri->ri_rows - dst;
        !           379:                if (n <= 0)
        !           380:                        return;
        !           381:                n *= ri->ri_font->fontheight;
        !           382:                src *= ri->ri_font->fontheight;
        !           383:                dst *= ri->ri_font->fontheight;
        !           384:                fbc->fbc_clip = 0;
        !           385:                fbc->fbc_s = 0;
        !           386:                fbc->fbc_offx = 0;
        !           387:                fbc->fbc_offy = 0;
        !           388:                fbc->fbc_clipminx = 0;
        !           389:                fbc->fbc_clipminy = 0;
        !           390:                fbc->fbc_clipmaxx = ri->ri_width - 1;
        !           391:                fbc->fbc_clipmaxy = ri->ri_height - 1;
        !           392:                fbc->fbc_alu = CG6_ALU_COPY;
        !           393:                fbc->fbc_x0 = ri->ri_xorigin;
        !           394:                fbc->fbc_y0 = ri->ri_yorigin + src;
        !           395:                fbc->fbc_x1 = ri->ri_xorigin + ri->ri_emuwidth - 1;
        !           396:                fbc->fbc_y1 = ri->ri_yorigin + src + n - 1;
        !           397:                fbc->fbc_x2 = ri->ri_xorigin;
        !           398:                fbc->fbc_y2 = ri->ri_yorigin + dst;
        !           399:                fbc->fbc_x3 = ri->ri_xorigin + ri->ri_emuwidth - 1;
        !           400:                fbc->fbc_y3 = ri->ri_yorigin + dst + n - 1;
        !           401:                CG6_BLIT_WAIT(fbc);
        !           402:                CG6_DRAIN(fbc);
        !           403: #if NWSDISPLAY > 0
        !           404:        }
        !           405: #endif
1.1       pk        406: }
                    407:
                    408: static void
                    409: cg6_ras_copycols(void *cookie, int row, int src, int dst, int n)
                    410: {
1.12.2.7! skrll     411:        struct rasops_info *ri=cookie;
        !           412:        struct cg6_screen *scr=ri->ri_hw;
        !           413:        struct cgsix_softc *sc=scr->sc;
        !           414:
        !           415: #if NWSDISPLAY > 0
        !           416:        int from, to;
        !           417:
        !           418:        from = src + row * ri->ri_cols;
        !           419:        to = dst + row * ri->ri_cols;
        !           420:
        !           421:        memmove(&scr->attrs[to], &scr->attrs[from], n * sizeof(long));
        !           422:        memmove(&scr->chars[to], &scr->chars[from], n * sizeof(uint16_t));
1.1       pk        423:
1.12.2.7! skrll     424:        if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
        !           425: #endif
        !           426:                volatile struct cg6_fbc *fbc = sc->sc_fbc;
        !           427:
        !           428:                if (dst == src)
        !           429:                        return;
        !           430:                if ((row < 0) || (row >= ri->ri_rows))
        !           431:                        return;
        !           432:                if (src < 0) {
        !           433:                        n += src;
        !           434:                        src = 0;
        !           435:                }
        !           436:                if (src+n > ri->ri_cols)
        !           437:                        n = ri->ri_cols - src;
        !           438:                if (dst < 0) {
        !           439:                        n += dst;
        !           440:                        dst = 0;
        !           441:                }
        !           442:                if (dst+n > ri->ri_cols)
        !           443:                        n = ri->ri_cols - dst;
        !           444:                if (n <= 0)
        !           445:                        return;
        !           446:                n *= ri->ri_font->fontwidth;
        !           447:                src *= ri->ri_font->fontwidth;
        !           448:                dst *= ri->ri_font->fontwidth;
        !           449:                row *= ri->ri_font->fontheight;
        !           450:                fbc->fbc_clip = 0;
        !           451:                fbc->fbc_s = 0;
        !           452:                fbc->fbc_offx = 0;
        !           453:                fbc->fbc_offy = 0;
        !           454:                fbc->fbc_clipminx = 0;
        !           455:                fbc->fbc_clipminy = 0;
        !           456:                fbc->fbc_clipmaxx = ri->ri_width - 1;
        !           457:                fbc->fbc_clipmaxy = ri->ri_height - 1;
        !           458:                fbc->fbc_alu = CG6_ALU_COPY;
        !           459:                fbc->fbc_x0 = ri->ri_xorigin + src;
        !           460:                fbc->fbc_y0 = ri->ri_yorigin + row;
        !           461:                fbc->fbc_x1 = ri->ri_xorigin + src + n - 1;
        !           462:                fbc->fbc_y1 = ri->ri_yorigin + row +
        !           463:                    ri->ri_font->fontheight - 1;
        !           464:                fbc->fbc_x2 = ri->ri_xorigin + dst;
        !           465:                fbc->fbc_y2 = ri->ri_yorigin + row;
        !           466:                fbc->fbc_x3 = ri->ri_xorigin + dst + n - 1;
        !           467:                fbc->fbc_y3 = ri->ri_yorigin + row +
        !           468:                    ri->ri_font->fontheight - 1;
        !           469:                CG6_BLIT_WAIT(fbc);
        !           470:                CG6_DRAIN(fbc);
        !           471: #if NWSDISPLAY > 0
        !           472:        }
        !           473: #endif
1.1       pk        474: }
                    475:
                    476: static void
                    477: cg6_ras_erasecols(void *cookie, int row, int col, int n, long int attr)
                    478: {
1.12.2.7! skrll     479:        struct rasops_info *ri=cookie;
        !           480:        struct cg6_screen *scr=ri->ri_hw;
        !           481:        struct cgsix_softc *sc=scr->sc;
        !           482:
        !           483: #if NWSDISPLAY > 0
        !           484:        int start, end, i;
        !           485:
        !           486:        start = col + row * ri->ri_cols;
        !           487:        end = start + n;
        !           488:
        !           489:        for (i = start; i < end; i++) {
        !           490:                scr->attrs[i] = attr;
        !           491:                scr->chars[i] = 0x20;
        !           492:        }
        !           493:        if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
        !           494: #endif
        !           495:                volatile struct cg6_fbc *fbc = sc->sc_fbc;
1.1       pk        496:
1.12.2.7! skrll     497:                if ((row < 0) || (row >= ri->ri_rows))
        !           498:                        return;
        !           499:                if (col < 0) {
        !           500:                        n += col;
        !           501:                        col = 0;
        !           502:                }
        !           503:                if (col+n > ri->ri_cols)
        !           504:                        n = ri->ri_cols - col;
        !           505:                if (n <= 0)
        !           506:                        return;
        !           507:                n *= ri->ri_font->fontwidth;
        !           508:                col *= ri->ri_font->fontwidth;
        !           509:                row *= ri->ri_font->fontheight;
        !           510:                fbc->fbc_clip = 0;
        !           511:                fbc->fbc_s = 0;
        !           512:                fbc->fbc_offx = 0;
        !           513:                fbc->fbc_offy = 0;
        !           514:                fbc->fbc_clipminx = 0;
        !           515:                fbc->fbc_clipminy = 0;
        !           516:                fbc->fbc_clipmaxx = ri->ri_width - 1;
        !           517:                fbc->fbc_clipmaxy = ri->ri_height - 1;
        !           518:                fbc->fbc_alu = CG6_ALU_FILL;
        !           519:                fbc->fbc_fg = ri->ri_devcmap[(attr >> 16) & 0xff];
        !           520:                fbc->fbc_arecty = ri->ri_yorigin + row;
        !           521:                fbc->fbc_arectx = ri->ri_xorigin + col;
        !           522:                fbc->fbc_arecty = ri->ri_yorigin + row +
        !           523:                    ri->ri_font->fontheight - 1;
        !           524:                fbc->fbc_arectx = ri->ri_xorigin + col + n - 1;
        !           525:                CG6_DRAW_WAIT(fbc);
        !           526:                CG6_DRAIN(fbc);
        !           527: #if NWSDISPLAY > 0
        !           528:        }
        !           529: #endif
1.1       pk        530: }
                    531:
                    532: static void
                    533: cg6_ras_eraserows(void *cookie, int row, int n, long int attr)
                    534: {
1.12.2.7! skrll     535:        struct rasops_info *ri=cookie;
        !           536:        struct cg6_screen *scr=ri->ri_hw;
        !           537:        struct cgsix_softc *sc=scr->sc;
        !           538:
        !           539: #if NWSDISPLAY > 0
        !           540:        int start, end, i;
        !           541:
        !           542:        start = ri->ri_cols*row;
        !           543:        end = ri->ri_cols * (row + n);
        !           544:
        !           545:        for (i = start; i < end; i++) {
        !           546:                scr->attrs[i] = attr;
        !           547:                scr->chars[i] = 0x20;
        !           548:        }
1.1       pk        549:
1.12.2.7! skrll     550:        if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
        !           551: #endif
        !           552:                volatile struct cg6_fbc *fbc = sc->sc_fbc;
        !           553:
        !           554:                if (row < 0) {
        !           555:                        n += row;
        !           556:                        row = 0;
        !           557:                }
        !           558:                if (row+n > ri->ri_rows)
        !           559:                        n = ri->ri_rows - row;
        !           560:                if (n <= 0)
        !           561:                        return;
        !           562:                fbc->fbc_clip = 0;
        !           563:                fbc->fbc_s = 0;
        !           564:                fbc->fbc_offx = 0;
        !           565:                fbc->fbc_offy = 0;
        !           566:                fbc->fbc_clipminx = 0;
        !           567:                fbc->fbc_clipminy = 0;
        !           568:                fbc->fbc_clipmaxx = ri->ri_width - 1;
        !           569:                fbc->fbc_clipmaxy = ri->ri_height - 1;
        !           570:                fbc->fbc_alu = CG6_ALU_FILL;
        !           571:                fbc->fbc_fg = ri->ri_devcmap[(attr >> 16) & 0xff];
        !           572:                if ((n == ri->ri_rows) && (ri->ri_flg & RI_FULLCLEAR)) {
        !           573:                        fbc->fbc_arecty = 0;
        !           574:                        fbc->fbc_arectx = 0;
        !           575:                        fbc->fbc_arecty = ri->ri_height - 1;
        !           576:                        fbc->fbc_arectx = ri->ri_width - 1;
        !           577:                } else {
        !           578:                        row *= ri->ri_font->fontheight;
        !           579:                        fbc->fbc_arecty = ri->ri_yorigin + row;
        !           580:                        fbc->fbc_arectx = ri->ri_xorigin;
        !           581:                        fbc->fbc_arecty = ri->ri_yorigin + row +
        !           582:                            (n * ri->ri_font->fontheight) - 1;
        !           583:                        fbc->fbc_arectx = ri->ri_xorigin + ri->ri_emuwidth - 1;
        !           584:                }
        !           585:                CG6_DRAW_WAIT(fbc);
        !           586:                CG6_DRAIN(fbc);
        !           587: #if NWSDISPLAY > 0
1.1       pk        588:        }
1.12.2.7! skrll     589: #endif
1.1       pk        590: }
                    591:
1.12.2.7! skrll     592: #if defined(RASTERCONSOLE) && defined(CG6_BLIT_CURSOR)
1.1       pk        593: /*
                    594:  * Really want something more like fg^bg here, but that would be more
                    595:  * or less impossible to migrate to colors.  So we hope there's
                    596:  * something not too inappropriate in the colormap...besides, it's what
                    597:  * the non-accelerated code did. :-)
                    598:  */
                    599: static void
                    600: cg6_ras_do_cursor(struct rasops_info *ri)
                    601: {
1.12.2.7! skrll     602:        struct cg6_screen *scr = ri->ri_hw;
        !           603:        struct cgsix_softc *sc = scr->sc;
        !           604:        int row, col;
        !           605:
1.1       pk        606:        row = ri->ri_crow * ri->ri_font->fontheight;
                    607:        col = ri->ri_ccol * ri->ri_font->fontwidth;
1.12.2.7! skrll     608:        cg6_invert(sc, ri->ri_xorigin + col,ri->ri_yorigin +
        !           609:            row, ri->ri_font->fontwidth, ri->ri_font->fontheight);
1.1       pk        610: }
1.12.2.7! skrll     611: #endif /* RASTERCONSOLE */
        !           612:
        !           613: #endif /* (NWSDISPLAY > 0) || defined(RASTERCONSOLE) */
1.1       pk        614:
                    615: void
1.12.2.7! skrll     616: cg6attach(struct cgsix_softc *sc, const char *name, int isconsole)
1.1       pk        617: {
                    618:        struct fbdevice *fb = &sc->sc_fb;
1.12.2.7! skrll     619: #if NWSDISPLAY > 0
1.12.2.5  skrll     620:        struct wsemuldisplaydev_attach_args aa;
1.12.2.7! skrll     621:        struct rasops_info *ri = &cg6_console_screen.ri;
1.12.2.5  skrll     622:        unsigned long defattr;
                    623: #endif
1.1       pk        624:
                    625:        fb->fb_driver = &cg6_fbdriver;
                    626:
                    627:        /* Don't have to map the pfour register on the cgsix. */
                    628:        fb->fb_pfour = NULL;
                    629:
                    630:        fb->fb_type.fb_cmsize = 256;
1.12.2.7! skrll     631:        fb->fb_type.fb_size = sc->sc_ramsize;
        !           632:        /*fb->fb_type.fb_height * fb->fb_linebytes;*/
1.1       pk        633:        printf(": %s, %d x %d", name,
                    634:               fb->fb_type.fb_width, fb->fb_type.fb_height);
1.12.2.5  skrll     635:        if(sc->sc_fhc) {
1.12.2.7! skrll     636:                sc->sc_fhcrev = (*sc->sc_fhc >> FHC_REV_SHIFT) &
1.1       pk        637:                        (FHC_REV_MASK >> FHC_REV_SHIFT);
1.12.2.5  skrll     638:        } else
                    639:                sc->sc_fhcrev=-1;
1.1       pk        640:        printf(", rev %d", sc->sc_fhcrev);
                    641:
                    642:        /* reset cursor & frame buffer controls */
                    643:        cg6_reset(sc);
                    644:
                    645:        /* enable video */
                    646:        sc->sc_thc->thc_misc |= THC_MISC_VIDEN;
                    647:
                    648:        if (isconsole) {
                    649:                printf(" (console)");
1.12.2.5  skrll     650:
1.12.2.7! skrll     651: /* this is the old console attachment stuff - sparc still needs it */
1.1       pk        652: #ifdef RASTERCONSOLE
                    653:                if (cgsix_use_rasterconsole) {
                    654:                        fbrcons_init(&sc->sc_fb);
1.12.2.7! skrll     655:                        /*
        !           656:                         * we don't use the screen struct but keep it here to
        !           657:                         * avoid ugliness in the cg6_ras_* functions
        !           658:                         */
        !           659:                        cg6_console_screen.sc = sc;
        !           660:                        sc->sc_fb.fb_rinfo.ri_hw = &cg6_console_screen;
1.1       pk        661:                        sc->sc_fb.fb_rinfo.ri_ops.copyrows = cg6_ras_copyrows;
                    662:                        sc->sc_fb.fb_rinfo.ri_ops.copycols = cg6_ras_copycols;
                    663:                        sc->sc_fb.fb_rinfo.ri_ops.erasecols = cg6_ras_erasecols;
                    664:                        sc->sc_fb.fb_rinfo.ri_ops.eraserows = cg6_ras_eraserows;
1.12.2.7! skrll     665: #ifdef CG6_BLIT_CURSOR
1.1       pk        666:                        sc->sc_fb.fb_rinfo.ri_do_cursor = cg6_ras_do_cursor;
1.12.2.7! skrll     667: #endif
1.5       tsutsui   668:                        cg6_ras_init(sc);
1.1       pk        669:                }
                    670: #endif
                    671:        }
1.12.2.7! skrll     672:        printf("\n");
1.1       pk        673:
                    674:        fb_attach(&sc->sc_fb, isconsole);
1.12.2.7! skrll     675:        sc->sc_width = fb->fb_type.fb_width;
        !           676:        sc->sc_stride = fb->fb_type.fb_width;
        !           677:        sc->sc_height = fb->fb_type.fb_height;
        !           678:
        !           679:        printf("%s: framebuffer size: %d MB\n", sc->sc_dev.dv_xname,
        !           680:            sc->sc_ramsize >> 20);
1.12.2.5  skrll     681:
                    682: #if NWSDISPLAY
                    683:        /* setup rasops and so on for wsdisplay */
                    684:        wsfont_init();
                    685:        cg6_ras_init(sc);
1.12.2.7! skrll     686:        sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
        !           687:        sc->sc_bg = WS_DEFAULT_BG;
        !           688:
        !           689:        LIST_INIT(&sc->screens);
        !           690:        sc->active = NULL;
        !           691:        sc->currenttype = &cgsix_defaultscreen;
        !           692:        callout_init(&sc->switch_callout);
        !           693:
1.12.2.5  skrll     694:        if(isconsole) {
1.12.2.7! skrll     695:                /* we mess with cg6_console_screen only once */
        !           696:                cgsix_init_screen(sc, &cg6_console_screen, 1, &defattr);
        !           697:                cgsix_defaultscreen.textops = &ri->ri_ops;
        !           698:                cgsix_defaultscreen.capabilities = ri->ri_caps;
        !           699:                cgsix_defaultscreen.nrows = ri->ri_rows;
        !           700:                cgsix_defaultscreen.ncols = ri->ri_cols;
        !           701:                cg6_console_screen.active = 1;
        !           702:                sc->active = &cg6_console_screen;
        !           703:                wsdisplay_cnattach(&cgsix_defaultscreen, ri, 0, 0, defattr);
        !           704:        } else {
        !           705:                /*
        !           706:                 * we're not the console so we just clear the screen and don't
        !           707:                 * set up any sort of text display
        !           708:                 */
        !           709:                if (cgsix_defaultscreen.textops == NULL) {
        !           710:                        /*
        !           711:                         * ugly, but...
        !           712:                         * we want the console settings to win, so we only
        !           713:                         * touch anything when we find an untouched screen
        !           714:                         * definition. In this case we fill it from fb to
        !           715:                         * avoid problems in case no cgsix is the console
        !           716:                         */
        !           717:                        ri = &sc->sc_fb.fb_rinfo;
        !           718:                        cgsix_defaultscreen.textops = &ri->ri_ops;
        !           719:                        cgsix_defaultscreen.capabilities = ri->ri_caps;
        !           720:                        cgsix_defaultscreen.nrows = ri->ri_rows;
        !           721:                        cgsix_defaultscreen.ncols = ri->ri_cols;
        !           722:                }
        !           723:                sc->active = NULL;
        !           724:                cgsix_clearscreen(sc);
1.12.2.5  skrll     725:        }
                    726:
1.12.2.7! skrll     727:        cg6_setup_palette(sc);
        !           728:
1.12.2.5  skrll     729:        aa.scrdata = &cgsix_screenlist;
1.12.2.7! skrll     730:        aa.console = isconsole;
1.12.2.5  skrll     731:        aa.accessops = &cgsix_accessops;
                    732:        aa.accesscookie = sc;
                    733:        config_found(&sc->sc_dev, &aa, wsemuldisplaydevprint);
1.12.2.7! skrll     734: #else
        !           735:        bt_initcmap(&sc->sc_cmap, 256);
        !           736:        cg6_loadcmap(sc, 0, 256);
        !           737:
1.12.2.5  skrll     738: #endif
                    739:
1.1       pk        740: }
                    741:
                    742:
                    743: int
1.12.2.6  skrll     744: cgsixopen(dev_t dev, int flags, int mode, struct lwp *l)
1.1       pk        745: {
                    746:        int unit = minor(dev);
                    747:
                    748:        if (unit >= cgsix_cd.cd_ndevs || cgsix_cd.cd_devs[unit] == NULL)
1.12.2.6  skrll     749:                return ENXIO;
                    750:        return 0;
1.1       pk        751: }
                    752:
                    753: int
1.12.2.6  skrll     754: cgsixclose(dev_t dev, int flags, int mode, struct lwp *l)
1.1       pk        755: {
                    756:        struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
                    757:
                    758:        cg6_reset(sc);
                    759:
1.12.2.7! skrll     760: #if NWSDISPLAY > 0
        !           761:        cg6_setup_palette(sc);
        !           762: #else
1.1       pk        763:        /* (re-)initialize the default color map */
                    764:        bt_initcmap(&sc->sc_cmap, 256);
1.12.2.7! skrll     765:
1.1       pk        766:        cg6_loadcmap(sc, 0, 256);
1.12.2.7! skrll     767: #endif
1.1       pk        768:
1.12.2.6  skrll     769:        return 0;
1.1       pk        770: }
                    771:
                    772: int
1.12.2.6  skrll     773: cgsixioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct lwp *l)
1.1       pk        774: {
                    775:        struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
1.12.2.1  skrll     776:        union cursor_cmap tcm;
                    777:        uint32_t image[32], mask[32];
1.1       pk        778:        u_int count;
                    779:        int v, error;
                    780:
1.12.2.5  skrll     781: #ifdef CGSIX_DEBUG
                    782:        printf("cgsixioctl(%ld)\n",cmd);
                    783: #endif
                    784:
1.1       pk        785:        switch (cmd) {
                    786:
                    787:        case FBIOGTYPE:
                    788:                *(struct fbtype *)data = sc->sc_fb.fb_type;
                    789:                break;
                    790:
                    791:        case FBIOGATTR:
                    792: #define fba ((struct fbgattr *)data)
                    793:                fba->real_type = sc->sc_fb.fb_type.fb_type;
                    794:                fba->owner = 0;         /* XXX ??? */
                    795:                fba->fbtype = sc->sc_fb.fb_type;
                    796:                fba->sattr.flags = 0;
                    797:                fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
                    798:                fba->sattr.dev_specific[0] = -1;
                    799:                fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
                    800:                fba->emu_types[1] = -1;
                    801: #undef fba
                    802:                break;
                    803:
                    804:        case FBIOGETCMAP:
                    805: #define        p ((struct fbcmap *)data)
                    806:                return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
                    807:
                    808:        case FBIOPUTCMAP:
                    809:                /* copy to software map */
                    810:                error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
                    811:                if (error)
1.12.2.6  skrll     812:                        return error;
1.1       pk        813:                /* now blast them into the chip */
                    814:                /* XXX should use retrace interrupt */
                    815:                cg6_loadcmap(sc, p->index, p->count);
                    816: #undef p
                    817:                break;
                    818:
                    819:        case FBIOGVIDEO:
                    820:                *(int *)data = sc->sc_blanked;
                    821:                break;
                    822:
                    823:        case FBIOSVIDEO:
                    824:                if (*(int *)data)
                    825:                        cg6_unblank(&sc->sc_dev);
                    826:                else if (!sc->sc_blanked) {
                    827:                        sc->sc_blanked = 1;
                    828:                        sc->sc_thc->thc_misc &= ~THC_MISC_VIDEN;
                    829:                }
                    830:                break;
                    831:
                    832: /* these are for both FBIOSCURSOR and FBIOGCURSOR */
                    833: #define p ((struct fbcursor *)data)
                    834: #define cc (&sc->sc_cursor)
                    835:
                    836:        case FBIOGCURSOR:
                    837:                /* do not quite want everything here... */
                    838:                p->set = FB_CUR_SETALL; /* close enough, anyway */
                    839:                p->enable = cc->cc_enable;
                    840:                p->pos = cc->cc_pos;
                    841:                p->hot = cc->cc_hot;
                    842:                p->size = cc->cc_size;
                    843:
                    844:                /* begin ugh ... can we lose some of this crap?? */
                    845:                if (p->image != NULL) {
                    846:                        count = cc->cc_size.y * 32 / NBBY;
1.12.2.1  skrll     847:                        error = copyout(cc->cc_bits[1], p->image, count);
1.1       pk        848:                        if (error)
1.12.2.6  skrll     849:                                return error;
1.12.2.1  skrll     850:                        error = copyout(cc->cc_bits[0], p->mask, count);
1.1       pk        851:                        if (error)
1.12.2.6  skrll     852:                                return error;
1.1       pk        853:                }
                    854:                if (p->cmap.red != NULL) {
                    855:                        error = bt_getcmap(&p->cmap,
                    856:                            (union bt_cmap *)&cc->cc_color, 2, 1);
                    857:                        if (error)
1.12.2.6  skrll     858:                                return error;
1.1       pk        859:                } else {
                    860:                        p->cmap.index = 0;
                    861:                        p->cmap.count = 2;
                    862:                }
                    863:                /* end ugh */
                    864:                break;
                    865:
                    866:        case FBIOSCURSOR:
                    867:                /*
                    868:                 * For setcmap and setshape, verify parameters, so that
                    869:                 * we do not get halfway through an update and then crap
                    870:                 * out with the software state screwed up.
                    871:                 */
                    872:                v = p->set;
                    873:                if (v & FB_CUR_SETCMAP) {
                    874:                        /*
                    875:                         * This use of a temporary copy of the cursor
                    876:                         * colormap is not terribly efficient, but these
                    877:                         * copies are small (8 bytes)...
                    878:                         */
                    879:                        tcm = cc->cc_color;
1.12.2.7! skrll     880:                        error = bt_putcmap(&p->cmap, (union bt_cmap *)&tcm, 2,
        !           881:                            1);
1.1       pk        882:                        if (error)
1.12.2.6  skrll     883:                                return error;
1.1       pk        884:                }
                    885:                if (v & FB_CUR_SETSHAPE) {
                    886:                        if ((u_int)p->size.x > 32 || (u_int)p->size.y > 32)
1.12.2.6  skrll     887:                                return EINVAL;
1.1       pk        888:                        count = p->size.y * 32 / NBBY;
1.12.2.1  skrll     889:                        error = copyin(p->image, image, count);
                    890:                        if (error)
                    891:                                return error;
                    892:                        error = copyin(p->mask, mask, count);
                    893:                        if (error)
                    894:                                return error;
1.1       pk        895:                }
                    896:
                    897:                /* parameters are OK; do it */
                    898:                if (v & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)) {
                    899:                        if (v & FB_CUR_SETCUR)
                    900:                                cc->cc_enable = p->enable;
                    901:                        if (v & FB_CUR_SETPOS)
                    902:                                cc->cc_pos = p->pos;
                    903:                        if (v & FB_CUR_SETHOT)
                    904:                                cc->cc_hot = p->hot;
                    905:                        cg6_setcursor(sc);
                    906:                }
                    907:                if (v & FB_CUR_SETCMAP) {
                    908:                        cc->cc_color = tcm;
                    909:                        cg6_loadomap(sc); /* XXX defer to vertical retrace */
                    910:                }
                    911:                if (v & FB_CUR_SETSHAPE) {
                    912:                        cc->cc_size = p->size;
                    913:                        count = p->size.y * 32 / NBBY;
1.12.2.1  skrll     914:                        memset(cc->cc_bits, 0, sizeof cc->cc_bits);
                    915:                        memcpy(cc->cc_bits[1], image, count);
                    916:                        memcpy(cc->cc_bits[0], mask, count);
1.1       pk        917:                        cg6_loadcursor(sc);
                    918:                }
                    919:                break;
                    920:
                    921: #undef p
                    922: #undef cc
                    923:
                    924:        case FBIOGCURPOS:
                    925:                *(struct fbcurpos *)data = sc->sc_cursor.cc_pos;
                    926:                break;
                    927:
                    928:        case FBIOSCURPOS:
                    929:                sc->sc_cursor.cc_pos = *(struct fbcurpos *)data;
                    930:                cg6_setcursor(sc);
                    931:                break;
                    932:
                    933:        case FBIOGCURMAX:
                    934:                /* max cursor size is 32x32 */
                    935:                ((struct fbcurpos *)data)->x = 32;
                    936:                ((struct fbcurpos *)data)->y = 32;
                    937:                break;
                    938:
                    939:        default:
                    940: #ifdef DEBUG
                    941:                log(LOG_NOTICE, "cgsixioctl(0x%lx) (%s[%d])\n", cmd,
                    942:                    p->p_comm, p->p_pid);
                    943: #endif
1.12.2.6  skrll     944:                return ENOTTY;
1.1       pk        945:        }
1.12.2.6  skrll     946:        return 0;
1.1       pk        947: }
                    948:
                    949: /*
                    950:  * Clean up hardware state (e.g., after bootup or after X crashes).
                    951:  */
                    952: static void
1.12.2.6  skrll     953: cg6_reset(struct cgsix_softc *sc)
1.1       pk        954: {
                    955:        volatile struct cg6_tec_xxx *tec;
                    956:        int fhc;
                    957:        volatile struct bt_regs *bt;
                    958:
                    959:        /* hide the cursor, just in case */
                    960:        sc->sc_thc->thc_cursxy = (THC_CURSOFF << 16) | THC_CURSOFF;
                    961:
                    962:        /* turn off frobs in transform engine (makes X11 work) */
                    963:        tec = sc->sc_tec;
                    964:        tec->tec_mv = 0;
                    965:        tec->tec_clip = 0;
                    966:        tec->tec_vdc = 0;
                    967:
                    968:        /* take care of hardware bugs in old revisions */
                    969:        if (sc->sc_fhcrev < 5) {
                    970:                /*
1.12.2.1  skrll     971:                 * Keep current resolution; set CPU to 68020, set test
1.1       pk        972:                 * window (size 1Kx1K), and for rev 1, disable dest cache.
                    973:                 */
                    974:                fhc = (*sc->sc_fhc & FHC_RES_MASK) | FHC_CPU_68020 |
                    975:                    FHC_TEST |
                    976:                    (11 << FHC_TESTX_SHIFT) | (11 << FHC_TESTY_SHIFT);
                    977:                if (sc->sc_fhcrev < 2)
                    978:                        fhc |= FHC_DST_DISABLE;
                    979:                *sc->sc_fhc = fhc;
                    980:        }
                    981:
                    982:        /* Enable cursor in Brooktree DAC. */
                    983:        bt = sc->sc_bt;
                    984:        bt->bt_addr = 0x06 << 24;
                    985:        bt->bt_ctrl |= 0x03 << 24;
                    986: }
                    987:
                    988: static void
1.12.2.6  skrll     989: cg6_setcursor(struct cgsix_softc *sc)
1.1       pk        990: {
                    991:
                    992:        /* we need to subtract the hot-spot value here */
                    993: #define COORD(f) (sc->sc_cursor.cc_pos.f - sc->sc_cursor.cc_hot.f)
                    994:        sc->sc_thc->thc_cursxy = sc->sc_cursor.cc_enable ?
                    995:            ((COORD(x) << 16) | (COORD(y) & 0xffff)) :
                    996:            (THC_CURSOFF << 16) | THC_CURSOFF;
                    997: #undef COORD
                    998: }
                    999:
                   1000: static void
1.12.2.6  skrll    1001: cg6_loadcursor(struct cgsix_softc *sc)
1.1       pk       1002: {
                   1003:        volatile struct cg6_thc *thc;
                   1004:        u_int edgemask, m;
                   1005:        int i;
                   1006:
                   1007:        /*
                   1008:         * Keep the top size.x bits.  Here we *throw out* the top
                   1009:         * size.x bits from an all-one-bits word, introducing zeros in
                   1010:         * the top size.x bits, then invert all the bits to get what
                   1011:         * we really wanted as our mask.  But this fails if size.x is
                   1012:         * 32---a sparc uses only the low 5 bits of the shift count---
                   1013:         * so we have to special case that.
                   1014:         */
                   1015:        edgemask = ~0;
                   1016:        if (sc->sc_cursor.cc_size.x < 32)
                   1017:                edgemask = ~(edgemask >> sc->sc_cursor.cc_size.x);
                   1018:        thc = sc->sc_thc;
                   1019:        for (i = 0; i < 32; i++) {
                   1020:                m = sc->sc_cursor.cc_bits[0][i] & edgemask;
                   1021:                thc->thc_cursmask[i] = m;
                   1022:                thc->thc_cursbits[i] = m & sc->sc_cursor.cc_bits[1][i];
                   1023:        }
                   1024: }
                   1025:
                   1026: /*
                   1027:  * Load a subset of the current (new) colormap into the color DAC.
                   1028:  */
                   1029: static void
1.12.2.6  skrll    1030: cg6_loadcmap(struct cgsix_softc *sc, int start, int ncolors)
1.1       pk       1031: {
                   1032:        volatile struct bt_regs *bt;
                   1033:        u_int *ip, i;
                   1034:        int count;
                   1035:
                   1036:        ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)];      /* start/4 * 3 */
                   1037:        count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
                   1038:        bt = sc->sc_bt;
                   1039:        bt->bt_addr = BT_D4M4(start) << 24;
                   1040:        while (--count >= 0) {
                   1041:                i = *ip++;
                   1042:                /* hardware that makes one want to pound boards with hammers */
                   1043:                bt->bt_cmap = i;
                   1044:                bt->bt_cmap = i << 8;
                   1045:                bt->bt_cmap = i << 16;
                   1046:                bt->bt_cmap = i << 24;
                   1047:        }
                   1048: }
                   1049:
                   1050: /*
                   1051:  * Load the cursor (overlay `foreground' and `background') colors.
                   1052:  */
                   1053: static void
1.12.2.6  skrll    1054: cg6_loadomap(struct cgsix_softc *sc)
1.1       pk       1055: {
                   1056:        volatile struct bt_regs *bt;
                   1057:        u_int i;
                   1058:
                   1059:        bt = sc->sc_bt;
                   1060:        bt->bt_addr = 0x01 << 24;       /* set background color */
                   1061:        i = sc->sc_cursor.cc_color.cm_chip[0];
                   1062:        bt->bt_omap = i;                /* R */
                   1063:        bt->bt_omap = i << 8;           /* G */
                   1064:        bt->bt_omap = i << 16;          /* B */
                   1065:
                   1066:        bt->bt_addr = 0x03 << 24;       /* set foreground color */
                   1067:        bt->bt_omap = i << 24;          /* R */
                   1068:        i = sc->sc_cursor.cc_color.cm_chip[1];
                   1069:        bt->bt_omap = i;                /* G */
                   1070:        bt->bt_omap = i << 8;           /* B */
                   1071: }
                   1072:
                   1073: static void
1.12.2.6  skrll    1074: cg6_unblank(struct device *dev)
1.1       pk       1075: {
                   1076:        struct cgsix_softc *sc = (struct cgsix_softc *)dev;
                   1077:
                   1078:        if (sc->sc_blanked) {
                   1079:                sc->sc_blanked = 0;
                   1080:                sc->sc_thc->thc_misc |= THC_MISC_VIDEN;
                   1081:        }
                   1082: }
                   1083:
                   1084: /* XXX the following should be moved to a "user interface" header */
                   1085: /*
                   1086:  * Base addresses at which users can mmap() the various pieces of a cg6.
                   1087:  * Note that although the Brooktree color registers do not occupy 8K,
                   1088:  * the X server dies if we do not allow it to map 8K there (it just maps
                   1089:  * from 0x70000000 forwards, as a contiguous chunk).
                   1090:  */
                   1091: #define        CG6_USER_FBC    0x70000000
                   1092: #define        CG6_USER_TEC    0x70001000
                   1093: #define        CG6_USER_BTREGS 0x70002000
                   1094: #define        CG6_USER_FHC    0x70004000
                   1095: #define        CG6_USER_THC    0x70005000
                   1096: #define        CG6_USER_ROM    0x70006000
                   1097: #define        CG6_USER_RAM    0x70016000
                   1098: #define        CG6_USER_DHC    0x80000000
                   1099:
                   1100: struct mmo {
1.2       eeh      1101:        u_long  mo_uaddr;       /* user (virtual) address */
                   1102:        u_long  mo_size;        /* size, or 0 for video ram size */
                   1103:        u_long  mo_physoff;     /* offset from sc_physadr */
1.1       pk       1104: };
                   1105:
                   1106: /*
                   1107:  * Return the address that would map the given device at the given
                   1108:  * offset, allowing for the given protection, or return -1 for error.
                   1109:  *
                   1110:  * XXX needs testing against `demanding' applications (e.g., aviator)
                   1111:  */
                   1112: paddr_t
1.12.2.6  skrll    1113: cgsixmmap(dev_t dev, off_t off, int prot)
1.1       pk       1114: {
                   1115:        struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
                   1116:        struct mmo *mo;
                   1117:        u_int u, sz;
                   1118:        static struct mmo mmo[] = {
                   1119:                { CG6_USER_RAM, 0, CGSIX_RAM_OFFSET },
                   1120:
                   1121:                /* do not actually know how big most of these are! */
                   1122:                { CG6_USER_FBC, 1, CGSIX_FBC_OFFSET },
                   1123:                { CG6_USER_TEC, 1, CGSIX_TEC_OFFSET },
                   1124:                { CG6_USER_BTREGS, 8192 /* XXX */, CGSIX_BT_OFFSET },
                   1125:                { CG6_USER_FHC, 1, CGSIX_FHC_OFFSET },
                   1126:                { CG6_USER_THC, sizeof(struct cg6_thc), CGSIX_THC_OFFSET },
                   1127:                { CG6_USER_ROM, 65536, CGSIX_ROM_OFFSET },
                   1128:                { CG6_USER_DHC, 1, CGSIX_DHC_OFFSET },
                   1129:        };
                   1130: #define NMMO (sizeof mmo / sizeof *mmo)
                   1131:
                   1132:        if (off & PGOFSET)
                   1133:                panic("cgsixmmap");
                   1134:
                   1135:        /*
                   1136:         * Entries with size 0 map video RAM (i.e., the size in fb data).
                   1137:         *
                   1138:         * Since we work in pages, the fact that the map offset table's
                   1139:         * sizes are sometimes bizarre (e.g., 1) is effectively ignored:
                   1140:         * one byte is as good as one page.
                   1141:         */
                   1142:        for (mo = mmo; mo < &mmo[NMMO]; mo++) {
1.2       eeh      1143:                if ((u_long)off < mo->mo_uaddr)
1.1       pk       1144:                        continue;
                   1145:                u = off - mo->mo_uaddr;
1.12.2.7! skrll    1146:                sz = mo->mo_size ? mo->mo_size :
        !          1147:                    sc->sc_ramsize/*sc_fb.fb_type.fb_size*/;
1.1       pk       1148:                if (u < sz) {
1.6       eeh      1149:                        return (bus_space_mmap(sc->sc_bustag,
                   1150:                                sc->sc_paddr, u+mo->mo_physoff,
                   1151:                                prot, BUS_SPACE_MAP_LINEAR));
1.1       pk       1152:                }
                   1153:        }
                   1154:
                   1155: #ifdef DEBUG
                   1156:        {
1.10      thorpej  1157:          struct proc *p = curlwp->l_proc;      /* XXX */
1.4       chs      1158:          log(LOG_NOTICE, "cgsixmmap(0x%llx) (%s[%d])\n",
                   1159:                (long long)off, p->p_comm, p->p_pid);
1.1       pk       1160:        }
                   1161: #endif
1.12.2.6  skrll    1162:        return -1;      /* not a user-map offset */
1.1       pk       1163: }
1.12.2.5  skrll    1164:
1.12.2.7! skrll    1165: #if NWSDISPLAY > 0
1.12.2.5  skrll    1166:
1.12.2.7! skrll    1167: static void
        !          1168: cg6_setup_palette(struct cgsix_softc *sc)
1.12.2.5  skrll    1169: {
1.12.2.7! skrll    1170:        int i, j;
        !          1171:
        !          1172:        j = 0;
        !          1173:        for (i = 0; i < 256; i++) {
        !          1174:                sc->sc_cmap.cm_map[i][0] = rasops_cmap[j];
        !          1175:                j++;
        !          1176:                sc->sc_cmap.cm_map[i][1] = rasops_cmap[j];
        !          1177:                j++;
        !          1178:                sc->sc_cmap.cm_map[i][2] = rasops_cmap[j];
        !          1179:                j++;
        !          1180:        }
        !          1181:        cg6_loadcmap(sc, 0, 256);
1.12.2.5  skrll    1182: }
                   1183:
                   1184: int
                   1185: cgsix_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
                   1186: {
                   1187:        /* we'll probably need to add more stuff here */
                   1188:        struct cgsix_softc *sc = v;
                   1189:        struct wsdisplay_fbinfo *wdf;
                   1190:        struct rasops_info *ri = &sc->sc_fb.fb_rinfo;
1.12.2.7! skrll    1191:        struct cg6_screen *ms = sc->active;
1.12.2.5  skrll    1192: #ifdef CGSIX_DEBUG
                   1193:        printf("cgsix_ioctl(%ld)\n",cmd);
                   1194: #endif
                   1195:        switch (cmd) {
                   1196:                case WSDISPLAYIO_GTYPE:
                   1197:                        *(u_int *)data = WSDISPLAY_TYPE_SUNTCX;
                   1198:                        return 0;
                   1199:                case WSDISPLAYIO_GINFO:
                   1200:                        wdf = (void *)data;
                   1201:                        wdf->height = ri->ri_height;
                   1202:                        wdf->width = ri->ri_width;
                   1203:                        wdf->depth = ri->ri_depth;
                   1204:                        wdf->cmsize = 256;
                   1205:                        return 0;
                   1206:
                   1207:                case WSDISPLAYIO_GETCMAP:
1.12.2.6  skrll    1208:                        return cgsix_getcmap(sc,
                   1209:                            (struct wsdisplay_cmap *)data);
1.12.2.5  skrll    1210:                case WSDISPLAYIO_PUTCMAP:
1.12.2.6  skrll    1211:                        return cgsix_putcmap(sc,
                   1212:                            (struct wsdisplay_cmap *)data);
1.12.2.5  skrll    1213:
                   1214:                case WSDISPLAYIO_SMODE:
                   1215:                        {
1.12.2.7! skrll    1216:                                int new_mode = *(int*)data;
        !          1217:                                if (new_mode != sc->sc_mode)
1.12.2.5  skrll    1218:                                {
1.12.2.7! skrll    1219:                                        sc->sc_mode = new_mode;
        !          1220:                                        if(new_mode == WSDISPLAYIO_MODE_EMUL)
1.12.2.5  skrll    1221:                                        {
1.12.2.7! skrll    1222:                                                cg6_reset(sc);
        !          1223:                                                cg6_ras_init(sc);
        !          1224:                                                /* restore the screen content */
        !          1225:                                                cgsix_restore_screen(ms,
        !          1226:                                                    ms->type, ms->chars);
        !          1227:                                                /*
        !          1228:                                                 * because X likes to bork up
        !          1229:                                                 * our colour map
1.12.2.6  skrll    1230:                                                 */
1.12.2.7! skrll    1231:                                                cg6_setup_palette(sc);                                                                  /* and draw the cursor */
        !          1232:                                                cgsix_cursor(ms, ms->cursoron,
        !          1233:                                                    ms->cursorrow,
        !          1234:                                                    ms->cursorcol);
1.12.2.5  skrll    1235:                                        }
                   1236:                                }
                   1237:                        }
                   1238:        }
                   1239:        return EPASSTHROUGH;
                   1240: }
                   1241:
                   1242: paddr_t
                   1243: cgsix_mmap(void *v, off_t offset, int prot)
                   1244: {
                   1245:        struct cgsix_softc *sc = v;
1.12.2.7! skrll    1246:        if(offset<sc->sc_ramsize) {
        !          1247:                return bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
        !          1248:                    CGSIX_RAM_OFFSET+offset, prot, BUS_SPACE_MAP_LINEAR);
1.12.2.5  skrll    1249:        }
                   1250:        /* I'm not at all sure this is the right thing to do */
1.12.2.7! skrll    1251:        return cgsixmmap(0, offset, prot); /* assume minor dev 0 for now */
1.12.2.5  skrll    1252: }
                   1253:
                   1254: int
                   1255: cgsix_putcmap(struct cgsix_softc *sc, struct wsdisplay_cmap *cm)
                   1256: {
                   1257:        u_int index = cm->index;
                   1258:        u_int count = cm->count;
                   1259:        int error,i;
                   1260:        if (index >= 256 || count > 256 || index + count > 256)
                   1261:                return EINVAL;
                   1262:
1.12.2.7! skrll    1263:        for (i = 0; i < count; i++)
1.12.2.5  skrll    1264:        {
1.12.2.6  skrll    1265:                error = copyin(&cm->red[i],
1.12.2.7! skrll    1266:                    &sc->sc_cmap.cm_map[index + i][0], 1);
1.12.2.5  skrll    1267:                if (error)
                   1268:                        return error;
1.12.2.6  skrll    1269:                error = copyin(&cm->green[i],
1.12.2.7! skrll    1270:                    &sc->sc_cmap.cm_map[index + i][1],
1.12.2.6  skrll    1271:                    1);
1.12.2.5  skrll    1272:                if (error)
                   1273:                        return error;
1.12.2.6  skrll    1274:                error = copyin(&cm->blue[i],
1.12.2.7! skrll    1275:                    &sc->sc_cmap.cm_map[index + i][2], 1);
1.12.2.5  skrll    1276:                if (error)
                   1277:                        return error;
                   1278:        }
1.12.2.7! skrll    1279:        cg6_loadcmap(sc, index, count);
1.12.2.5  skrll    1280:
                   1281:        return 0;
                   1282: }
                   1283:
1.12.2.6  skrll    1284: int
                   1285: cgsix_getcmap(struct cgsix_softc *sc, struct wsdisplay_cmap *cm)
1.12.2.5  skrll    1286: {
                   1287:        u_int index = cm->index;
                   1288:        u_int count = cm->count;
                   1289:        int error,i;
                   1290:
                   1291:        if (index >= 256 || count > 256 || index + count > 256)
                   1292:                return EINVAL;
                   1293:
1.12.2.7! skrll    1294:        for (i = 0; i < count; i++)
1.12.2.5  skrll    1295:        {
1.12.2.7! skrll    1296:                error = copyout(&sc->sc_cmap.cm_map[index + i][0],
        !          1297:                    &cm->red[i], 1);
1.12.2.5  skrll    1298:                if (error)
                   1299:                        return error;
1.12.2.7! skrll    1300:                error = copyout(&sc->sc_cmap.cm_map[index + i][1],
        !          1301:                    &cm->green[i], 1);
1.12.2.5  skrll    1302:                if (error)
                   1303:                        return error;
1.12.2.7! skrll    1304:                error = copyout(&sc->sc_cmap.cm_map[index + i][2],
        !          1305:                    &cm->blue[i], 1);
1.12.2.5  skrll    1306:                if (error)
                   1307:                        return error;
                   1308:        }
                   1309:
                   1310:        return 0;
                   1311: }
1.12.2.7! skrll    1312:
        !          1313: void
        !          1314: cgsix_init_screen(struct cgsix_softc *sc, struct cg6_screen *scr,
        !          1315:     int existing, long *defattr)
        !          1316: {
        !          1317:        struct rasops_info *ri = &scr->ri;
        !          1318:        int cnt;
        !          1319:        scr->sc = sc;
        !          1320:        /*scr->type = type;*/
        !          1321:        scr->cursorcol = 0;
        !          1322:        scr->cursorrow = 0;
        !          1323:        scr->cursordrawn = 0;
        !          1324:
        !          1325:        ri->ri_depth = 8;
        !          1326:        ri->ri_width = sc->sc_width;
        !          1327:        ri->ri_height = sc->sc_height;
        !          1328:        ri->ri_stride = sc->sc_stride;
        !          1329:        ri->ri_flg = RI_CENTER;
        !          1330:
        !          1331:        ri->ri_bits = sc->sc_fb.fb_pixels;
        !          1332:
        !          1333:        rasops_init(ri, sc->sc_height/8, sc->sc_width/8);
        !          1334:        ri->ri_caps=WSSCREEN_WSCOLORS;
        !          1335:        rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
        !          1336:                    sc->sc_width / ri->ri_font->fontwidth);
        !          1337:        ri->ri_ops.allocattr(ri, 0, 0, 0, defattr);
        !          1338:
        !          1339:        cnt = ri->ri_rows * ri->ri_cols;
        !          1340:        /*
        !          1341:         * we allocate both chars and attributes in one chunk, attributes first
        !          1342:         * because they have the (potentially) bigger alignment
        !          1343:         */
        !          1344:        scr->attrs = (long *)malloc(cnt * (sizeof(long) + sizeof(uint16_t)),
        !          1345:            M_DEVBUF, M_WAITOK);
        !          1346:        scr->chars = (uint16_t *)&scr->attrs[cnt];
        !          1347:
        !          1348:        /* enable acceleration */
        !          1349:        ri->ri_hw = scr;
        !          1350:        ri->ri_ops.copyrows = cg6_ras_copyrows;
        !          1351:        ri->ri_ops.copycols = cg6_ras_copycols;
        !          1352:        ri->ri_ops.eraserows = cg6_ras_eraserows;
        !          1353:        ri->ri_ops.erasecols = cg6_ras_erasecols;
        !          1354:        ri->ri_ops.cursor = cgsix_cursor;
        !          1355:        ri->ri_ops.putchar = cgsix_putchar;
        !          1356:        if (existing) {
        !          1357:                scr->active = 1;
        !          1358:        } else {
        !          1359:                scr->active = 0;
        !          1360:        }
        !          1361:
        !          1362:        cg6_ras_eraserows(&scr->ri, 0, ri->ri_rows, *defattr);
        !          1363:
        !          1364:        LIST_INSERT_HEAD(&sc->screens, scr, next);
        !          1365: }
        !          1366:
        !          1367: int
        !          1368: cgsix_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
        !          1369:     int *curxp, int *curyp, long *defattrp)
        !          1370: {
        !          1371:        struct cgsix_softc *sc = v;
        !          1372:        struct cg6_screen *scr;
        !          1373:
        !          1374:        scr = malloc(sizeof(struct cg6_screen), M_DEVBUF, M_WAITOK|M_ZERO);
        !          1375:        cgsix_init_screen(sc, scr, 0, defattrp);
        !          1376:
        !          1377:        if (sc->active == NULL) {
        !          1378:                scr->active = 1;
        !          1379:                sc->active = scr;
        !          1380:                sc->currenttype = type;
        !          1381:        }
        !          1382:
        !          1383:        *cookiep = scr;
        !          1384:        *curxp = scr->cursorcol;
        !          1385:        *curyp = scr->cursorrow;
        !          1386:        return 0;
        !          1387: }
        !          1388:
        !          1389: void
        !          1390: cgsix_free_screen(void *v, void *cookie)
        !          1391: {
        !          1392:        struct cgsix_softc *sc = v;
        !          1393:        struct cg6_screen *scr = cookie;
        !          1394:
        !          1395:        LIST_REMOVE(scr, next);
        !          1396:        if (scr != &cg6_console_screen) {
        !          1397:                free(scr->attrs, M_DEVBUF);
        !          1398:                free(scr, M_DEVBUF);
        !          1399:        } else
        !          1400:                panic("cgsix_free_screen: console");
        !          1401:
        !          1402:        if (sc->active == scr)
        !          1403:                sc->active = 0;
        !          1404: }
        !          1405:
        !          1406: int
        !          1407: cgsix_show_screen(void *v, void *cookie, int waitok,
        !          1408:     void (*cb)(void *, int, int), void *cbarg)
        !          1409: {
        !          1410:        struct cgsix_softc *sc = v;
        !          1411:        struct cg6_screen *scr, *oldscr;
        !          1412:
        !          1413:        scr = cookie;
        !          1414:        oldscr = sc->active;
        !          1415:        if (scr == oldscr)
        !          1416:                return 0;
        !          1417:
        !          1418:        sc->wanted = scr;
        !          1419:        sc->switchcb = cb;
        !          1420:        sc->switchcbarg = cbarg;
        !          1421:        if (cb) {
        !          1422:                callout_reset(&sc->switch_callout, 0,
        !          1423:                    (void(*)(void *))cgsix_switch_screen, sc);
        !          1424:                return EAGAIN;
        !          1425:        }
        !          1426:
        !          1427:        cgsix_switch_screen(sc);
        !          1428:        return 0;
        !          1429: }
        !          1430:
        !          1431: void
        !          1432: cgsix_switch_screen(struct cgsix_softc *sc)
        !          1433: {
        !          1434:        struct cg6_screen *scr, *oldscr;
        !          1435:
        !          1436:        scr = sc->wanted;
        !          1437:        if (!scr) {
        !          1438:                printf("cgsix_switch_screen: disappeared\n");
        !          1439:                (*sc->switchcb)(sc->switchcbarg, EIO, 0);
        !          1440:                return;
        !          1441:        }
        !          1442:        oldscr = sc->active; /* can be NULL! */
        !          1443: #ifdef DIAGNOSTIC
        !          1444:        if (oldscr) {
        !          1445:                if (!oldscr->active)
        !          1446:                        panic("cgsix_switch_screen: not active");
        !          1447:        }
        !          1448: #endif
        !          1449:        if (scr == oldscr)
        !          1450:                return;
        !          1451:
        !          1452: #ifdef DIAGNOSTIC
        !          1453:        if (scr->active)
        !          1454:                panic("cgsix_switch_screen: active");
        !          1455: #endif
        !          1456:
        !          1457:        if (oldscr)
        !          1458:                oldscr->active = 0;
        !          1459: #ifdef notyet
        !          1460:        if (sc->currenttype != type) {
        !          1461:                cgsix_set_screentype(sc, type);
        !          1462:                sc->currenttype = type;
        !          1463:        }
        !          1464: #endif
        !          1465:
        !          1466:        /* Clear the entire screen. */
        !          1467:
        !          1468:        scr->active = 1;
        !          1469:        cgsix_restore_screen(scr, &cgsix_defaultscreen, scr->chars);
        !          1470:
        !          1471:        sc->active = scr;
        !          1472:
        !          1473:        scr->ri.ri_ops.cursor(scr, scr->cursoron, scr->cursorrow,
        !          1474:            scr->cursorcol);
        !          1475:
        !          1476:        sc->wanted = 0;
        !          1477:        if (sc->switchcb)
        !          1478:                (*sc->switchcb)(sc->switchcbarg, 0, 0);
        !          1479: }
        !          1480:
        !          1481: void
        !          1482: cgsix_restore_screen(struct cg6_screen *scr,
        !          1483:     const struct wsscreen_descr *type, u_int16_t *mem)
        !          1484: {
        !          1485:        int i, j, offset = 0;
        !          1486:        uint16_t *charptr = scr->chars;
        !          1487:        long *attrptr = scr->attrs;
        !          1488:
        !          1489:        cgsix_clearscreen(scr->sc);
        !          1490:        for (i = 0; i < scr->ri.ri_rows; i++) {
        !          1491:                for (j = 0; j < scr->ri.ri_cols; j++) {
        !          1492:                        cgsix_putchar(scr, i, j, charptr[offset],
        !          1493:                            attrptr[offset]);
        !          1494:                        offset++;
        !          1495:                }
        !          1496:        }
        !          1497:        scr->cursordrawn = 0;
        !          1498: }
        !          1499:
        !          1500: void
        !          1501: cgsix_rectfill(struct cgsix_softc *sc, int xs, int ys, int wi, int he,
        !          1502:     uint32_t col)
        !          1503: {
        !          1504:        volatile struct cg6_fbc *fbc = sc->sc_fbc;
        !          1505:
        !          1506:        CG6_DRAIN(fbc);
        !          1507:        fbc->fbc_clip = 0;
        !          1508:        fbc->fbc_s = 0;
        !          1509:        fbc->fbc_offx = 0;
        !          1510:        fbc->fbc_offy = 0;
        !          1511:        fbc->fbc_clipminx = 0;
        !          1512:        fbc->fbc_clipminy = 0;
        !          1513:        fbc->fbc_clipmaxx = sc->sc_width - 1;
        !          1514:        fbc->fbc_clipmaxy = sc->sc_height - 1;
        !          1515:        fbc->fbc_alu = CG6_ALU_FILL;
        !          1516:        fbc->fbc_fg = col;
        !          1517:        fbc->fbc_arecty = ys;
        !          1518:        fbc->fbc_arectx = xs;
        !          1519:        fbc->fbc_arecty = ys + he - 1;
        !          1520:        fbc->fbc_arectx = xs + wi - 1;
        !          1521:        CG6_DRAW_WAIT(fbc);
        !          1522: }
        !          1523:
        !          1524: void
        !          1525: cgsix_setup_mono(struct cgsix_softc *sc, int x, int y, int wi, int he,
        !          1526:     uint32_t fg, uint32_t bg)
        !          1527: {
        !          1528:        volatile struct cg6_fbc *fbc=sc->sc_fbc;
        !          1529:        CG6_DRAIN(fbc);
        !          1530:        fbc->fbc_x0 = x;
        !          1531:        fbc->fbc_x1  =x + wi - 1;
        !          1532:        fbc->fbc_y0 = y;
        !          1533:        fbc->fbc_incx = 0;
        !          1534:        fbc->fbc_incy = 1;
        !          1535:        fbc->fbc_fg = fg;
        !          1536:        fbc->fbc_bg = bg;
        !          1537:        fbc->fbc_mode = 0x00140000;     /* nosrc, color1 */
        !          1538:        fbc->fbc_alu = 0x0800fc30;      /* colour expansion, solid bg */
        !          1539:        sc->sc_mono_width = wi;
        !          1540:        /* now feed the data into the chip */
        !          1541: }
        !          1542:
        !          1543: void
        !          1544: cgsix_feed_line(struct cgsix_softc *sc, int count, uint8_t *data)
        !          1545: {
        !          1546:        int i;
        !          1547:        uint32_t latch, res = 0, shift;
        !          1548:        volatile struct cg6_fbc *fbc = sc->sc_fbc;
        !          1549:
        !          1550:        if (sc->sc_mono_width > 32) {
        !          1551:                /* ARGH! */
        !          1552:        } else
        !          1553:        {
        !          1554:                shift = 24;
        !          1555:                for (i = 0; i < count; i++) {
        !          1556:                        latch = data[i];
        !          1557:                        res |= latch << shift;
        !          1558:                        shift -= 8;
        !          1559:                }
        !          1560:                fbc->fbc_font = res;
        !          1561:        }
        !          1562: }
        !          1563:
        !          1564: void
        !          1565: cgsix_putchar(void *cookie, int row, int col, u_int c, long attr)
        !          1566: {
        !          1567:        struct rasops_info *ri=cookie;
        !          1568:        struct cg6_screen *scr=ri->ri_hw;
        !          1569:        struct cgsix_softc *sc=scr->sc;
        !          1570:        int pos;
        !          1571:
        !          1572:        if ((row >= 0) && (row < ri->ri_rows) && (col >= 0) &&
        !          1573:            (col < ri->ri_cols)) {
        !          1574:                pos = col + row * ri->ri_cols;
        !          1575:                scr->attrs[pos] = attr;
        !          1576:                scr->chars[pos] = c;
        !          1577:
        !          1578:                if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
        !          1579:                        /*cgsix_sync(sc);*/
        !          1580:                        int fg, bg, uc, i;
        !          1581:                        uint8_t *data;
        !          1582:                        int x, y, wi, he;
        !          1583:                        volatile struct cg6_fbc *fbc = sc->sc_fbc;
        !          1584:
        !          1585:                        wi = ri->ri_font->fontwidth;
        !          1586:                        he = ri->ri_font->fontheight;
        !          1587:
        !          1588:                        if (!CHAR_IN_FONT(c, ri->ri_font))
        !          1589:                                return;
        !          1590:                        bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xff];
        !          1591:                        fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xff];
        !          1592:                        x = ri->ri_xorigin + col * wi;
        !          1593:                        y = ri->ri_yorigin + row * he;
        !          1594:                        if (c == 0x20) {
        !          1595:                                cgsix_rectfill(sc, x, y, wi, he, bg);
        !          1596:                        } else {
        !          1597:                                uc = c-ri->ri_font->firstchar;
        !          1598:                                data = (uint8_t *)ri->ri_font->data + uc *
        !          1599:                                    ri->ri_fontscale;
        !          1600:
        !          1601:                                cgsix_setup_mono(sc, x, y, wi, 1, fg, bg);
        !          1602:                                for (i = 0; i < he; i++) {
        !          1603:                                        cgsix_feed_line(sc, ri->ri_font->stride,
        !          1604:                                            data);
        !          1605:                                        data += ri->ri_font->stride;
        !          1606:                                }
        !          1607:                                /* put the chip back to normal */
        !          1608:                                fbc->fbc_incy = 0;
        !          1609:                                /* nosrc, color8 */
        !          1610:                                fbc->fbc_mode = 0x00120000;
        !          1611:                                fbc->fbc_mode &= ~CG6_MODE_MASK;
        !          1612:                                fbc->fbc_mode |= CG6_MODE;
        !          1613:                        }
        !          1614:                }
        !          1615:        }
        !          1616: }
        !          1617:
        !          1618: void
        !          1619: cgsix_cursor(void *cookie, int on, int row, int col)
        !          1620: {
        !          1621:        struct rasops_info *ri=cookie;
        !          1622:        struct cg6_screen *scr=ri->ri_hw;
        !          1623:        struct cgsix_softc *sc=scr->sc;
        !          1624:        int x, y, wi, he;
        !          1625:
        !          1626:        wi = ri->ri_font->fontwidth;
        !          1627:        he = ri->ri_font->fontheight;
        !          1628:
        !          1629:        if((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
        !          1630:                x = scr->cursorcol * wi + ri->ri_xorigin;
        !          1631:                y = scr->cursorrow * he + ri->ri_yorigin;
        !          1632:                if(scr->cursordrawn) {
        !          1633:                        cg6_invert(sc, x, y, wi, he);
        !          1634:                        scr->cursordrawn = 0;
        !          1635:                }
        !          1636:                scr->cursorrow = row;
        !          1637:                scr->cursorcol = col;
        !          1638:                if((scr->cursoron = on) != 0)
        !          1639:                {
        !          1640:                        x = scr->cursorcol * wi + ri->ri_xorigin;
        !          1641:                        y = scr->cursorrow * he + ri->ri_yorigin;
        !          1642:                        cg6_invert(sc, x, y, wi, he);
        !          1643:                        scr->cursordrawn = 1;
        !          1644:                }
        !          1645:        } else {
        !          1646:                scr->cursoron = on;
        !          1647:                scr->cursorrow = row;
        !          1648:                scr->cursorcol = col;
        !          1649:                scr->cursordrawn = 0;
        !          1650:        }
        !          1651: }
        !          1652:
        !          1653: void
        !          1654: cgsix_clearscreen(struct cgsix_softc *sc)
        !          1655: {
        !          1656:        struct rasops_info *ri=&cg6_console_screen.ri;
        !          1657:
        !          1658:        if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
        !          1659:                volatile struct cg6_fbc *fbc = sc->sc_fbc;
        !          1660:
        !          1661:                CG6_DRAIN(fbc);
        !          1662:                fbc->fbc_clip = 0;
        !          1663:                fbc->fbc_s = 0;
        !          1664:                fbc->fbc_offx = 0;
        !          1665:                fbc->fbc_offy = 0;
        !          1666:                fbc->fbc_clipminx = 0;
        !          1667:                fbc->fbc_clipminy = 0;
        !          1668:                fbc->fbc_clipmaxx = ri->ri_width - 1;
        !          1669:                fbc->fbc_clipmaxy = ri->ri_height - 1;
        !          1670:                fbc->fbc_alu = CG6_ALU_FILL;
        !          1671:                fbc->fbc_fg = ri->ri_devcmap[sc->sc_bg];
        !          1672:                fbc->fbc_arectx = 0;
        !          1673:                fbc->fbc_arecty = 0;
        !          1674:                fbc->fbc_arectx = ri->ri_width - 1;
        !          1675:                fbc->fbc_arecty = ri->ri_height - 1;
        !          1676:                CG6_DRAW_WAIT(fbc);
        !          1677:        }
        !          1678: }
        !          1679:
        !          1680: #endif /* NWSDISPLAY > 0 */
        !          1681:
        !          1682: #if (NWSDISPLAY > 0) || defined(RASTERCONSOLE)
        !          1683: void
        !          1684: cg6_invert(struct cgsix_softc *sc, int x, int y, int wi, int he)
        !          1685: {
        !          1686:        volatile struct cg6_fbc *fbc = sc->sc_fbc;
        !          1687:        struct rasops_info *ri = &cg6_console_screen.ri;
        !          1688:
        !          1689:        CG6_DRAIN(fbc);
        !          1690:        fbc->fbc_clip = 0;
        !          1691:        fbc->fbc_s = 0;
        !          1692:        fbc->fbc_offx = 0;
        !          1693:        fbc->fbc_offy = 0;
        !          1694:        fbc->fbc_clipminx = 0;
        !          1695:        fbc->fbc_clipminy = 0;
        !          1696:        fbc->fbc_clipmaxx = ri->ri_width - 1;
        !          1697:        fbc->fbc_clipmaxy = ri->ri_height - 1;
        !          1698:        fbc->fbc_alu = CG6_ALU_FLIP;
        !          1699:        fbc->fbc_arecty = y;
        !          1700:        fbc->fbc_arectx = x;
        !          1701:        fbc->fbc_arecty = y + he - 1;
        !          1702:        fbc->fbc_arectx = x + wi - 1;
        !          1703:        CG6_DRAW_WAIT(fbc);
        !          1704: }
        !          1705:
        !          1706: #endif

CVSweb <webmaster@jp.NetBSD.org>