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

Annotation of sys/dev/ic/vga.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: vga.c,v 1.45 2007/02/11 20:29:22 miod Exp $ */
                      2: /* $NetBSD: vga.c,v 1.28.2.1 2000/06/30 16:27:47 simonb Exp $ */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Author: Chris G. Demetriou
                      9:  *
                     10:  * Permission to use, copy, modify and distribute this software and
                     11:  * its documentation is hereby granted, provided that both the copyright
                     12:  * notice and this permission notice appear in all copies of the
                     13:  * software, derivative works or modified versions, and any portions
                     14:  * thereof, and that both notices appear in supporting documentation.
                     15:  *
                     16:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     17:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
                     18:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     19:  *
                     20:  * Carnegie Mellon requests users of this software to return to
                     21:  *
                     22:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     23:  *  School of Computer Science
                     24:  *  Carnegie Mellon University
                     25:  *  Pittsburgh PA 15213-3890
                     26:  *
                     27:  * any improvements or extensions that they make and grant Carnegie the
                     28:  * rights to redistribute these changes.
                     29:  */
                     30:
                     31: #include "vga.h"
                     32:
                     33: #include <sys/param.h>
                     34: #include <sys/systm.h>
                     35: #include <sys/kernel.h>
                     36: #include <sys/device.h>
                     37: #include <sys/malloc.h>
                     38: #include <sys/queue.h>
                     39: #include <machine/bus.h>
                     40:
                     41: #include <dev/ic/mc6845reg.h>
                     42: #include <dev/ic/pcdisplayvar.h>
                     43: #include <dev/ic/vgareg.h>
                     44: #include <dev/ic/vgavar.h>
                     45:
                     46: #include <dev/wscons/wsdisplayvar.h>
                     47: #include <dev/wscons/wsconsio.h>
                     48: #include <dev/wscons/unicode.h>
                     49:
                     50: #include <dev/ic/pcdisplay.h>
                     51:
                     52: static struct vgafont {
                     53:        char name[WSFONT_NAME_SIZE];
                     54:        int height;
                     55:        int encoding;
                     56: #ifdef notyet
                     57:        int firstchar, numchars;
                     58: #endif
                     59:        int slot;
                     60: } vga_builtinfont = {
                     61:        "builtin",
                     62:        16,
                     63:        WSDISPLAY_FONTENC_IBM,
                     64: #ifdef notyet
                     65:        0, 256,
                     66: #endif
                     67:        0
                     68: };
                     69:
                     70: struct vgascreen {
                     71:        struct pcdisplayscreen pcs;
                     72:
                     73:        LIST_ENTRY(vgascreen) next;
                     74:
                     75:        struct vga_config *cfg;
                     76:
                     77:        /* videostate */
                     78:        struct vgafont *fontset1, *fontset2;
                     79:        /* font data */
                     80:        /* palette */
                     81:
                     82:        int mindispoffset, maxdispoffset;
                     83:        int vga_rollover;
                     84: };
                     85:
                     86: int vgaconsole, vga_console_type, vga_console_attached;
                     87: struct vgascreen vga_console_screen;
                     88: struct vga_config vga_console_vc;
                     89:
                     90: int    vga_selectfont(struct vga_config *, struct vgascreen *,
                     91:     const char *, const char *);
                     92: void   vga_init_screen(struct vga_config *, struct vgascreen *,
                     93:     const struct wsscreen_descr *, int, long *);
                     94: void   vga_init(struct vga_config *, bus_space_tag_t, bus_space_tag_t);
                     95: void   vga_setfont(struct vga_config *, struct vgascreen *);
                     96:
                     97: int    vga_mapchar(void *, int, unsigned int *);
                     98: void   vga_putchar(void *, int, int, u_int, long);
                     99: int    vga_alloc_attr(void *, int, int, int, long *);
                    100: void   vga_copyrows(void *, int, int, int);
                    101: void   vga_unpack_attr(void *, long, int *, int *, int *);
                    102:
                    103: static const struct wsdisplay_emulops vga_emulops = {
                    104:        pcdisplay_cursor,
                    105:        vga_mapchar,
                    106:        vga_putchar,
                    107:        pcdisplay_copycols,
                    108:        pcdisplay_erasecols,
                    109:        vga_copyrows,
                    110:        pcdisplay_eraserows,
                    111:        vga_alloc_attr,
                    112:        vga_unpack_attr
                    113: };
                    114:
                    115: /*
                    116:  * translate WS(=ANSI) color codes to standard pc ones
                    117:  */
                    118: static const unsigned char fgansitopc[] = {
                    119: #ifdef __alpha__
                    120:        /*
                    121:         * XXX DEC HAS SWITCHED THE CODES FOR BLUE AND RED!!!
                    122:         * XXX We should probably not bother with this
                    123:         * XXX (reinitialize the palette registers).
                    124:         */
                    125:        FG_BLACK, FG_BLUE, FG_GREEN, FG_CYAN, FG_RED,
                    126:        FG_MAGENTA, FG_BROWN, FG_LIGHTGREY
                    127: #else
                    128:        FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
                    129:        FG_MAGENTA, FG_CYAN, FG_LIGHTGREY
                    130: #endif
                    131: }, bgansitopc[] = {
                    132: #ifdef __alpha__
                    133:        BG_BLACK, BG_BLUE, BG_GREEN, BG_CYAN, BG_RED,
                    134:        BG_MAGENTA, BG_BROWN, BG_LIGHTGREY
                    135: #else
                    136:        BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
                    137:        BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
                    138: #endif
                    139: };
                    140:
                    141: /*
                    142:  * translate standard pc color codes to WS(=ANSI) ones
                    143:  */
                    144: static const u_int8_t pctoansi[] = {
                    145: #ifdef __alpha__
                    146:        WSCOL_BLACK, WSCOL_RED, WSCOL_GREEN, WSCOL_BROWN,
                    147:        WSCOL_BLUE, WSCOL_MAGENTA, WSCOL_CYAN, WSCOL_WHITE
                    148: #else
                    149:        WSCOL_BLACK, WSCOL_BLUE, WSCOL_GREEN, WSCOL_CYAN,
                    150:        WSCOL_RED, WSCOL_MAGENTA, WSCOL_BROWN, WSCOL_WHITE
                    151: #endif
                    152: };
                    153:
                    154:
                    155: const struct wsscreen_descr vga_stdscreen = {
                    156:        "80x25", 80, 25,
                    157:        &vga_emulops,
                    158:        8, 16,
                    159:        WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK
                    160: }, vga_stdscreen_mono = {
                    161:        "80x25", 80, 25,
                    162:        &vga_emulops,
                    163:        8, 16,
                    164:        WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE
                    165: }, vga_stdscreen_bf = {
                    166:        "80x25bf", 80, 25,
                    167:        &vga_emulops,
                    168:        8, 16,
                    169:        WSSCREEN_WSCOLORS | WSSCREEN_BLINK
                    170: }, vga_40lscreen = {
                    171:        "80x40", 80, 40,
                    172:        &vga_emulops,
                    173:        8, 10,
                    174:        WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK
                    175: }, vga_40lscreen_mono = {
                    176:        "80x40", 80, 40,
                    177:        &vga_emulops,
                    178:        8, 10,
                    179:        WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE
                    180: }, vga_40lscreen_bf = {
                    181:        "80x40bf", 80, 40,
                    182:        &vga_emulops,
                    183:        8, 10,
                    184:        WSSCREEN_WSCOLORS | WSSCREEN_BLINK
                    185: }, vga_50lscreen = {
                    186:        "80x50", 80, 50,
                    187:        &vga_emulops,
                    188:        8, 8,
                    189:        WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK
                    190: }, vga_50lscreen_mono = {
                    191:        "80x50", 80, 50,
                    192:        &vga_emulops,
                    193:        8, 8,
                    194:        WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE
                    195: }, vga_50lscreen_bf = {
                    196:        "80x50bf", 80, 50,
                    197:        &vga_emulops,
                    198:        8, 8,
                    199:        WSSCREEN_WSCOLORS | WSSCREEN_BLINK
                    200: };
                    201:
                    202: #define VGA_SCREEN_CANTWOFONTS(type) (!((type)->capabilities & WSSCREEN_HILIT))
                    203:
                    204: const struct wsscreen_descr *_vga_scrlist[] = {
                    205:        &vga_stdscreen,
                    206:        &vga_stdscreen_bf,
                    207:        &vga_40lscreen,
                    208:        &vga_40lscreen_bf,
                    209:        &vga_50lscreen,
                    210:        &vga_50lscreen_bf,
                    211:        /* XXX other formats, graphics screen? */
                    212: }, *_vga_scrlist_mono[] = {
                    213:        &vga_stdscreen_mono,
                    214:        &vga_40lscreen_mono,
                    215:        &vga_50lscreen_mono,
                    216:        /* XXX other formats, graphics screen? */
                    217: };
                    218:
                    219: const struct wsscreen_list vga_screenlist = {
                    220:        sizeof(_vga_scrlist) / sizeof(struct wsscreen_descr *),
                    221:        _vga_scrlist
                    222: }, vga_screenlist_mono = {
                    223:        sizeof(_vga_scrlist_mono) / sizeof(struct wsscreen_descr *),
                    224:        _vga_scrlist_mono
                    225: };
                    226:
                    227: int    vga_ioctl(void *, u_long, caddr_t, int, struct proc *);
                    228: paddr_t        vga_mmap(void *, off_t, int);
                    229: int    vga_alloc_screen(void *, const struct wsscreen_descr *,
                    230:                         void **, int *, int *, long *);
                    231: void   vga_free_screen(void *, void *);
                    232: int    vga_show_screen(void *, void *, int,
                    233:                        void (*) (void *, int, int), void *);
                    234: int    vga_load_font(void *, void *, struct wsdisplay_font *);
                    235: void   vga_scrollback(void *, void *, int);
                    236: void   vga_burner(void *v, u_int on, u_int flags);
                    237: int    vga_getchar(void *, int, int, struct wsdisplay_charcell *);
                    238:
                    239: void vga_doswitch(struct vga_config *);
                    240:
                    241: const struct wsdisplay_accessops vga_accessops = {
                    242:        vga_ioctl,
                    243:        vga_mmap,
                    244:        vga_alloc_screen,
                    245:        vga_free_screen,
                    246:        vga_show_screen,
                    247:        vga_load_font,
                    248:        vga_scrollback,
                    249:        vga_getchar,
                    250:        vga_burner
                    251: };
                    252:
                    253: /*
                    254:  * The following functions implement back-end configuration grabbing
                    255:  * and attachment.
                    256:  */
                    257: int
                    258: vga_common_probe(iot, memt)
                    259:        bus_space_tag_t iot, memt;
                    260: {
                    261:        bus_space_handle_t ioh_vga, ioh_6845, memh;
                    262:        u_int8_t regval;
                    263:        u_int16_t vgadata;
                    264:        int gotio_vga, gotio_6845, gotmem, mono, rv;
                    265:        int dispoffset;
                    266:
                    267:        gotio_vga = gotio_6845 = gotmem = rv = 0;
                    268:
                    269:        if (bus_space_map(iot, 0x3c0, 0x10, 0, &ioh_vga))
                    270:                goto bad;
                    271:        gotio_vga = 1;
                    272:
                    273:        /* read "misc output register" */
                    274:        regval = bus_space_read_1(iot, ioh_vga, 0xc);
                    275:        mono = !(regval & 1);
                    276:
                    277:        if (bus_space_map(iot, (mono ? 0x3b0 : 0x3d0), 0x10, 0, &ioh_6845))
                    278:                goto bad;
                    279:        gotio_6845 = 1;
                    280:
                    281:        if (bus_space_map(memt, 0xa0000, 0x20000, 0, &memh))
                    282:                goto bad;
                    283:        gotmem = 1;
                    284:
                    285:        dispoffset = (mono ? 0x10000 : 0x18000);
                    286:
                    287:        vgadata = bus_space_read_2(memt, memh, dispoffset);
                    288:        bus_space_write_2(memt, memh, dispoffset, 0xa55a);
                    289:        if (bus_space_read_2(memt, memh, dispoffset) != 0xa55a)
                    290:                goto bad;
                    291:        bus_space_write_2(memt, memh, dispoffset, vgadata);
                    292:
                    293:        /*
                    294:         * check if this is really a VGA
                    295:         * (try to write "Color Select" register as XFree86 does)
                    296:         * XXX check before if at least EGA?
                    297:         */
                    298:        /* reset state */
                    299:        (void) bus_space_read_1(iot, ioh_6845, 10);
                    300:        bus_space_write_1(iot, ioh_vga, VGA_ATC_INDEX,
                    301:                          20 | 0x20); /* colselect | enable */
                    302:        regval = bus_space_read_1(iot, ioh_vga, VGA_ATC_DATAR);
                    303:        /* toggle the implemented bits */
                    304:        bus_space_write_1(iot, ioh_vga, VGA_ATC_DATAW, regval ^ 0x0f);
                    305:        bus_space_write_1(iot, ioh_vga, VGA_ATC_INDEX,
                    306:                          20 | 0x20);
                    307:        /* read back */
                    308:        if (bus_space_read_1(iot, ioh_vga, VGA_ATC_DATAR) != (regval ^ 0x0f))
                    309:                goto bad;
                    310:        /* restore contents */
                    311:        bus_space_write_1(iot, ioh_vga, VGA_ATC_DATAW, regval);
                    312:
                    313:        rv = 1;
                    314: bad:
                    315:        if (gotio_vga)
                    316:                bus_space_unmap(iot, ioh_vga, 0x10);
                    317:        if (gotio_6845)
                    318:                bus_space_unmap(iot, ioh_6845, 0x10);
                    319:        if (gotmem)
                    320:                bus_space_unmap(memt, memh, 0x20000);
                    321:
                    322:        return (rv);
                    323: }
                    324:
                    325: /*
                    326:  * We want at least ASCII 32..127 be present in the
                    327:  * first font slot.
                    328:  */
                    329: #define vga_valid_primary_font(f) \
                    330:        (f->encoding == WSDISPLAY_FONTENC_IBM || \
                    331:        f->encoding == WSDISPLAY_FONTENC_ISO)
                    332:
                    333: int
                    334: vga_selectfont(vc, scr, name1, name2)
                    335:        struct vga_config *vc;
                    336:        struct vgascreen *scr;
                    337:        const char *name1, *name2; /* NULL: take first found */
                    338: {
                    339:        const struct wsscreen_descr *type = scr->pcs.type;
                    340:        struct vgafont *f1, *f2;
                    341:        int i;
                    342:
                    343:        f1 = f2 = 0;
                    344:
                    345:        for (i = 0; i < 8; i++) {
                    346:                struct vgafont *f = vc->vc_fonts[i];
                    347:                if (!f || f->height != type->fontheight)
                    348:                        continue;
                    349:                if (!f1 &&
                    350:                    vga_valid_primary_font(f) &&
                    351:                    (!name1 || !*name1 ||
                    352:                     !strncmp(name1, f->name, WSFONT_NAME_SIZE))) {
                    353:                        f1 = f;
                    354:                        continue;
                    355:                }
                    356:                if (!f2 &&
                    357:                    VGA_SCREEN_CANTWOFONTS(type) &&
                    358:                    (!name2 || !*name2 ||
                    359:                     !strncmp(name2, f->name, WSFONT_NAME_SIZE))) {
                    360:                        f2 = f;
                    361:                        continue;
                    362:                }
                    363:        }
                    364:
                    365:        /*
                    366:         * The request fails if no primary font was found,
                    367:         * or if a second font was requested but not found.
                    368:         */
                    369:        if (f1 && (!name2 || !*name2 || f2)) {
                    370: #ifdef VGAFONTDEBUG
                    371:                if (scr != &vga_console_screen || vga_console_attached) {
                    372:                        printf("vga (%s): font1=%s (slot %d)", type->name,
                    373:                               f1->name, f1->slot);
                    374:                        if (f2)
                    375:                                printf(", font2=%s (slot %d)",
                    376:                                       f2->name, f2->slot);
                    377:                        printf("\n");
                    378:                }
                    379: #endif
                    380:                scr->fontset1 = f1;
                    381:                scr->fontset2 = f2;
                    382:                return (0);
                    383:        }
                    384:        return (ENXIO);
                    385: }
                    386:
                    387: void
                    388: vga_init_screen(vc, scr, type, existing, attrp)
                    389:        struct vga_config *vc;
                    390:        struct vgascreen *scr;
                    391:        const struct wsscreen_descr *type;
                    392:        int existing;
                    393:        long *attrp;
                    394: {
                    395:        int cpos;
                    396:        int res;
                    397:
                    398:        scr->cfg = vc;
                    399:        scr->pcs.hdl = (struct pcdisplay_handle *)&vc->hdl;
                    400:        scr->pcs.type = type;
                    401:        scr->pcs.active = 0;
                    402:        scr->mindispoffset = 0;
                    403:        scr->maxdispoffset = 0x8000 - type->nrows * type->ncols * 2;
                    404:
                    405:        if (existing) {
                    406:                cpos = vga_6845_read(&vc->hdl, cursorh) << 8;
                    407:                cpos |= vga_6845_read(&vc->hdl, cursorl);
                    408:
                    409:                /* make sure we have a valid cursor position */
                    410:                if (cpos < 0 || cpos >= type->nrows * type->ncols)
                    411:                        cpos = 0;
                    412:
                    413:                scr->pcs.dispoffset = vga_6845_read(&vc->hdl, startadrh) << 9;
                    414:                scr->pcs.dispoffset |= vga_6845_read(&vc->hdl, startadrl) << 1;
                    415:
                    416:                /* make sure we have a valid memory offset */
                    417:                if (scr->pcs.dispoffset < scr->mindispoffset ||
                    418:                    scr->pcs.dispoffset > scr->maxdispoffset)
                    419:                        scr->pcs.dispoffset = scr->mindispoffset;
                    420:        } else {
                    421:                cpos = 0;
                    422:                scr->pcs.dispoffset = scr->mindispoffset;
                    423:        }
                    424:        scr->pcs.visibleoffset = scr->pcs.dispoffset;
                    425:        scr->vga_rollover = 0;
                    426:
                    427:        scr->pcs.vc_crow = cpos / type->ncols;
                    428:        scr->pcs.vc_ccol = cpos % type->ncols;
                    429:        pcdisplay_cursor_init(&scr->pcs, existing);
                    430:
                    431: #ifdef __alpha__
                    432:        if (!vc->hdl.vh_mono)
                    433:                /*
                    434:                 * DEC firmware uses a blue background.
                    435:                 */
                    436:                res = vga_alloc_attr(scr, WSCOL_WHITE, WSCOL_BLUE,
                    437:                                     WSATTR_WSCOLORS, attrp);
                    438:        else
                    439: #endif
                    440:        res = vga_alloc_attr(scr, 0, 0, 0, attrp);
                    441: #ifdef DIAGNOSTIC
                    442:        if (res)
                    443:                panic("vga_init_screen: attribute botch");
                    444: #endif
                    445:
                    446:        scr->pcs.mem = NULL;
                    447:
                    448:        scr->fontset1 = scr->fontset2 = 0;
                    449:        if (vga_selectfont(vc, scr, 0, 0)) {
                    450:                if (scr == &vga_console_screen)
                    451:                        panic("vga_init_screen: no font");
                    452:                else
                    453:                        printf("vga_init_screen: no font\n");
                    454:        }
                    455:
                    456:        vc->nscreens++;
                    457:        LIST_INSERT_HEAD(&vc->screens, scr, next);
                    458: }
                    459:
                    460: void
                    461: vga_init(vc, iot, memt)
                    462:        struct vga_config *vc;
                    463:        bus_space_tag_t iot, memt;
                    464: {
                    465:        struct vga_handle *vh = &vc->hdl;
                    466:        u_int8_t mor;
                    467:        int i;
                    468:
                    469:         vh->vh_iot = iot;
                    470:         vh->vh_memt = memt;
                    471:
                    472:         if (bus_space_map(vh->vh_iot, 0x3c0, 0x10, 0, &vh->vh_ioh_vga))
                    473:                 panic("vga_common_setup: couldn't map vga io");
                    474:
                    475:        /* read "misc output register" */
                    476:        mor = bus_space_read_1(vh->vh_iot, vh->vh_ioh_vga, 0xc);
                    477:        vh->vh_mono = !(mor & 1);
                    478:
                    479:        if (bus_space_map(vh->vh_iot, (vh->vh_mono ? 0x3b0 : 0x3d0), 0x10, 0,
                    480:                          &vh->vh_ioh_6845))
                    481:                 panic("vga_common_setup: couldn't map 6845 io");
                    482:
                    483:         if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000, 0, &vh->vh_allmemh))
                    484:                 panic("vga_common_setup: couldn't map memory");
                    485:
                    486:         if (bus_space_subregion(vh->vh_memt, vh->vh_allmemh,
                    487:                                (vh->vh_mono ? 0x10000 : 0x18000), 0x8000,
                    488:                                &vh->vh_memh))
                    489:                 panic("vga_common_setup: mem subrange failed");
                    490:
                    491:        vc->nscreens = 0;
                    492:        LIST_INIT(&vc->screens);
                    493:        vc->active = NULL;
                    494:        vc->currenttype = vh->vh_mono ? &vga_stdscreen_mono : &vga_stdscreen;
                    495: #if 0
                    496:        callout_init(&vc->vc_switch_callout);
                    497: #endif
                    498:
                    499:        vc->vc_fonts[0] = &vga_builtinfont;
                    500:        for (i = 1; i < 8; i++)
                    501:                vc->vc_fonts[i] = 0;
                    502:
                    503:        vc->currentfontset1 = vc->currentfontset2 = 0;
                    504: }
                    505:
                    506: void
                    507: vga_common_attach(self, iot, memt, type)
                    508:        struct device *self;
                    509:        bus_space_tag_t iot, memt;
                    510:        int type;
                    511: {
                    512:        vga_extended_attach(self, iot, memt, type, NULL);
                    513: }
                    514:
                    515: void
                    516: vga_extended_attach(self, iot, memt, type, map)
                    517:        struct device *self;
                    518:        bus_space_tag_t iot, memt;
                    519:        int type;
                    520:        paddr_t (*map)(void *, off_t, int);
                    521: {
                    522:        int console;
                    523:        struct vga_config *vc;
                    524:        struct wsemuldisplaydev_attach_args aa;
                    525:
                    526:        console = vga_is_console(iot, type);
                    527:
                    528:        if (console) {
                    529:                vc = &vga_console_vc;
                    530:                vga_console_attached = 1;
                    531:        } else {
                    532:                vc = malloc(sizeof(struct vga_config), M_DEVBUF, M_NOWAIT);
                    533:                if (vc == NULL)
                    534:                        return;
                    535:                bzero(vc, sizeof(struct vga_config));
                    536:                vga_init(vc, iot, memt);
                    537:        }
                    538:
                    539:        vc->vc_softc = self;
                    540:        vc->vc_type = type;
                    541:        vc->vc_mmap = map;
                    542:
                    543:        aa.console = console;
                    544:        aa.scrdata = (vc->hdl.vh_mono ? &vga_screenlist_mono : &vga_screenlist);
                    545:        aa.accessops = &vga_accessops;
                    546:        aa.accesscookie = vc;
                    547:        aa.defaultscreens = 0;
                    548:
                    549:         config_found(self, &aa, wsemuldisplaydevprint);
                    550: }
                    551:
                    552: int
                    553: vga_cnattach(iot, memt, type, check)
                    554:        bus_space_tag_t iot, memt;
                    555:        int type, check;
                    556: {
                    557:        long defattr;
                    558:        const struct wsscreen_descr *scr;
                    559:
                    560:        if (check && !vga_common_probe(iot, memt))
                    561:                return (ENXIO);
                    562:
                    563:        /* set up bus-independent VGA configuration */
                    564:        vga_init(&vga_console_vc, iot, memt);
                    565:        scr = vga_console_vc.currenttype;
                    566:        vga_init_screen(&vga_console_vc, &vga_console_screen, scr, 1, &defattr);
                    567:
                    568:        vga_console_screen.pcs.active = 1;
                    569:        vga_console_vc.active = &vga_console_screen;
                    570:
                    571:        wsdisplay_cnattach(scr, &vga_console_screen,
                    572:                           vga_console_screen.pcs.vc_ccol,
                    573:                           vga_console_screen.pcs.vc_crow,
                    574:                           defattr);
                    575:
                    576:        vgaconsole = 1;
                    577:        vga_console_type = type;
                    578:        return (0);
                    579: }
                    580:
                    581: int
                    582: vga_is_console(iot, type)
                    583:        bus_space_tag_t iot;
                    584:        int type;
                    585: {
                    586:        if (vgaconsole &&
                    587:            !vga_console_attached &&
                    588:            iot == vga_console_vc.hdl.vh_iot &&
                    589:            (vga_console_type == -1 || (type == vga_console_type)))
                    590:                return (1);
                    591:        return (0);
                    592: }
                    593:
                    594: int
                    595: vga_ioctl(v, cmd, data, flag, p)
                    596:        void *v;
                    597:        u_long cmd;
                    598:        caddr_t data;
                    599:        int flag;
                    600:        struct proc *p;
                    601: {
                    602:        struct vga_config *vc = v;
                    603: #if NVGA_PCI > 0
                    604:        int error;
                    605:
                    606:        if (vc->vc_type == WSDISPLAY_TYPE_PCIVGA &&
                    607:            (error = vga_pci_ioctl(v, cmd, data, flag, p)) != ENOTTY)
                    608:                return (error);
                    609: #endif
                    610:
                    611:        switch (cmd) {
                    612:        case WSDISPLAYIO_GTYPE:
                    613:                *(int *)data = vc->vc_type;
                    614:                /* XXX should get detailed hardware information here */
                    615:                break;
                    616:
                    617:        case WSDISPLAYIO_GVIDEO:
                    618:        case WSDISPLAYIO_SVIDEO:
                    619:                break;
                    620:
                    621:        case WSDISPLAYIO_GINFO:
                    622:        case WSDISPLAYIO_GETCMAP:
                    623:        case WSDISPLAYIO_PUTCMAP:
                    624:        case WSDISPLAYIO_GCURPOS:
                    625:        case WSDISPLAYIO_SCURPOS:
                    626:        case WSDISPLAYIO_GCURMAX:
                    627:        case WSDISPLAYIO_GCURSOR:
                    628:        case WSDISPLAYIO_SCURSOR:
                    629:        default:
                    630:                /* NONE of these operations are by the generic VGA driver. */
                    631:                return ENOTTY;
                    632:        }
                    633:
                    634:        return (0);
                    635: }
                    636:
                    637: paddr_t
                    638: vga_mmap(v, offset, prot)
                    639:        void *v;
                    640:        off_t offset;
                    641:        int prot;
                    642: {
                    643:        struct vga_config *vc = v;
                    644:
                    645:        if (vc->vc_mmap != NULL)
                    646:                return (*vc->vc_mmap)(v, offset, prot);
                    647:
                    648:        return -1;
                    649: }
                    650:
                    651: int
                    652: vga_alloc_screen(v, type, cookiep, curxp, curyp, defattrp)
                    653:        void *v;
                    654:        const struct wsscreen_descr *type;
                    655:        void **cookiep;
                    656:        int *curxp, *curyp;
                    657:        long *defattrp;
                    658: {
                    659:        struct vga_config *vc = v;
                    660:        struct vgascreen *scr;
                    661:
                    662:        if (vc->nscreens == 1) {
                    663:                /*
                    664:                 * When allocating the second screen, get backing store
                    665:                 * for the first one too.
                    666:                 * XXX We could be more clever and use video RAM.
                    667:                 */
                    668:                LIST_FIRST(&vc->screens)->pcs.mem =
                    669:                  malloc(type->ncols * type->nrows * 2, M_DEVBUF, M_WAITOK);
                    670:        }
                    671:
                    672:        scr = malloc(sizeof(struct vgascreen), M_DEVBUF, M_WAITOK);
                    673:        vga_init_screen(vc, scr, type, vc->nscreens == 0, defattrp);
                    674:
                    675:        if (vc->nscreens == 1) {
                    676:                scr->pcs.active = 1;
                    677:                vc->active = scr;
                    678:                vc->currenttype = type;
                    679:        } else {
                    680:                scr->pcs.mem = malloc(type->ncols * type->nrows * 2,
                    681:                                      M_DEVBUF, M_WAITOK);
                    682:                pcdisplay_eraserows(&scr->pcs, 0, type->nrows, *defattrp);
                    683:        }
                    684:
                    685:        *cookiep = scr;
                    686:        *curxp = scr->pcs.vc_ccol;
                    687:        *curyp = scr->pcs.vc_crow;
                    688:
                    689:        return (0);
                    690: }
                    691:
                    692: void
                    693: vga_free_screen(v, cookie)
                    694:        void *v;
                    695:        void *cookie;
                    696: {
                    697:        struct vgascreen *vs = cookie;
                    698:        struct vga_config *vc = vs->cfg;
                    699:
                    700:        LIST_REMOVE(vs, next);
                    701:        vc->nscreens--;
                    702:        if (vs != &vga_console_screen) {
                    703:                /*
                    704:                 * deallocating the one but last screen
                    705:                 * removes backing store for the last one
                    706:                 */
                    707:                if (vc->nscreens == 1)
                    708:                        free(LIST_FIRST(&vc->screens)->pcs.mem, M_DEVBUF);
                    709:
                    710:                /* Last screen has no backing store */
                    711:                if (vc->nscreens != 0)
                    712:                        free(vs->pcs.mem, M_DEVBUF);
                    713:
                    714:                free(vs, M_DEVBUF);
                    715:        } else
                    716:                panic("vga_free_screen: console");
                    717:
                    718:        if (vc->active == vs)
                    719:                vc->active = NULL;
                    720: }
                    721:
                    722: void
                    723: vga_setfont(vc, scr)
                    724:        struct vga_config *vc;
                    725:        struct vgascreen *scr;
                    726: {
                    727:        int fontslot1, fontslot2;
                    728:
                    729:        fontslot1 = (scr->fontset1 ? scr->fontset1->slot : 0);
                    730:        fontslot2 = (scr->fontset2 ? scr->fontset2->slot : fontslot1);
                    731:        if (vc->currentfontset1 != fontslot1 ||
                    732:            vc->currentfontset2 != fontslot2) {
                    733:                vga_setfontset(&vc->hdl, fontslot1, fontslot2);
                    734:                vc->currentfontset1 = fontslot1;
                    735:                vc->currentfontset2 = fontslot2;
                    736:        }
                    737: }
                    738:
                    739: int
                    740: vga_show_screen(v, cookie, waitok, cb, cbarg)
                    741:        void *v;
                    742:        void *cookie;
                    743:        int waitok;
                    744:        void (*cb)(void *, int, int);
                    745:        void *cbarg;
                    746: {
                    747:        struct vgascreen *scr = cookie, *oldscr;
                    748:        struct vga_config *vc = scr->cfg;
                    749:
                    750:        oldscr = vc->active; /* can be NULL! */
                    751:        if (scr == oldscr) {
                    752:                return (0);
                    753:        }
                    754:
                    755:        vc->wantedscreen = cookie;
                    756:        vc->switchcb = cb;
                    757:        vc->switchcbarg = cbarg;
                    758:        if (cb) {
                    759:                timeout_set(&vc->vc_switch_timeout,
                    760:                    (void(*)(void *))vga_doswitch, vc);
                    761:                timeout_add(&vc->vc_switch_timeout, 0);
                    762:                return (EAGAIN);
                    763:        }
                    764:
                    765:        vga_doswitch(vc);
                    766:        return (0);
                    767: }
                    768:
                    769: void
                    770: vga_doswitch(vc)
                    771:        struct vga_config *vc;
                    772: {
                    773:        struct vgascreen *scr, *oldscr;
                    774:        struct vga_handle *vh = &vc->hdl;
                    775:        const struct wsscreen_descr *type;
                    776:
                    777:        scr = vc->wantedscreen;
                    778:        if (!scr) {
                    779:                printf("vga_doswitch: disappeared\n");
                    780:                (*vc->switchcb)(vc->switchcbarg, EIO, 0);
                    781:                return;
                    782:        }
                    783:        type = scr->pcs.type;
                    784:        oldscr = vc->active; /* can be NULL! */
                    785: #ifdef DIAGNOSTIC
                    786:        if (oldscr) {
                    787:                if (!oldscr->pcs.active)
                    788:                        panic("vga_show_screen: not active");
                    789:                if (oldscr->pcs.type != vc->currenttype)
                    790:                        panic("vga_show_screen: bad type");
                    791:        }
                    792: #endif
                    793:        if (scr == oldscr) {
                    794:                return;
                    795:        }
                    796: #ifdef DIAGNOSTIC
                    797:        if (scr->pcs.active)
                    798:                panic("vga_show_screen: active");
                    799: #endif
                    800:
                    801:        scr->vga_rollover = 0;
                    802:
                    803:        if (oldscr) {
                    804:                const struct wsscreen_descr *oldtype = oldscr->pcs.type;
                    805:
                    806:                oldscr->pcs.active = 0;
                    807:                bus_space_read_region_2(vh->vh_memt, vh->vh_memh,
                    808:                                        oldscr->pcs.dispoffset, oldscr->pcs.mem,
                    809:                                        oldtype->ncols * oldtype->nrows);
                    810:        }
                    811:
                    812:        if (vc->currenttype != type) {
                    813:                vga_setscreentype(vh, type);
                    814:                vc->currenttype = type;
                    815:        }
                    816:
                    817:        vga_setfont(vc, scr);
                    818:        /* XXX switch colours! */
                    819:
                    820:        scr->pcs.visibleoffset = scr->pcs.dispoffset = scr->mindispoffset;
                    821:        if (!oldscr || (scr->pcs.dispoffset != oldscr->pcs.dispoffset)) {
                    822:                vga_6845_write(vh, startadrh, scr->pcs.dispoffset >> 9);
                    823:                vga_6845_write(vh, startadrl, scr->pcs.dispoffset >> 1);
                    824:        }
                    825:
                    826:        bus_space_write_region_2(vh->vh_memt, vh->vh_memh,
                    827:                                scr->pcs.dispoffset, scr->pcs.mem,
                    828:                                type->ncols * type->nrows);
                    829:        scr->pcs.active = 1;
                    830:
                    831:        vc->active = scr;
                    832:
                    833:        pcdisplay_cursor_reset(&scr->pcs);
                    834:        pcdisplay_cursor(&scr->pcs, scr->pcs.cursoron,
                    835:                         scr->pcs.vc_crow, scr->pcs.vc_ccol);
                    836:
                    837:        vc->wantedscreen = 0;
                    838:        if (vc->switchcb)
                    839:                (*vc->switchcb)(vc->switchcbarg, 0, 0);
                    840: }
                    841:
                    842: int
                    843: vga_load_font(v, cookie, data)
                    844:        void *v;
                    845:        void *cookie;
                    846:        struct wsdisplay_font *data;
                    847: {
                    848:        struct vga_config *vc = v;
                    849:        struct vgascreen *scr = cookie;
                    850:        char *name2;
                    851:        int res, slot;
                    852:        struct vgafont *f;
                    853:
                    854:        if (scr) {
                    855:                if ((name2 = data->name) != NULL) {
                    856:                        while (*name2 && *name2 != ',')
                    857:                                name2++;
                    858:                        if (*name2)
                    859:                                *name2++ = '\0';
                    860:                }
                    861:                res = vga_selectfont(vc, scr, data->name, name2);
                    862:                if (!res)
                    863:                        vga_setfont(vc, scr);
                    864:                return (res);
                    865:        }
                    866:
                    867:        if (data->fontwidth != 8 || data->stride != 1)
                    868:                return (EINVAL); /* XXX 1 byte per line */
                    869:        if (data->firstchar != 0 || data->numchars != 256)
                    870:                return (EINVAL);
                    871: #ifndef WSCONS_SUPPORT_PCVTFONTS
                    872:        if (data->encoding == WSDISPLAY_FONTENC_PCVT) {
                    873:                printf("vga: pcvt font support not built in, see vga(4)\n");
                    874:                return (EINVAL);
                    875:        }
                    876: #endif
                    877:
                    878:        if (data->index < 0) {
                    879:                for (slot = 0; slot < 8; slot++)
                    880:                        if (!vc->vc_fonts[slot])
                    881:                                break;
                    882:        } else
                    883:                slot = data->index;
                    884:
                    885:        if (slot >= 8)
                    886:                return (ENOSPC);
                    887:
                    888:        if (vc->vc_fonts[slot] != NULL)
                    889:                return (EEXIST);
                    890:        f = malloc(sizeof(struct vgafont), M_DEVBUF, M_WAITOK);
                    891:        if (f == NULL)
                    892:                return (ENOMEM);
                    893:        strlcpy(f->name, data->name, sizeof(f->name));
                    894:        f->height = data->fontheight;
                    895:        f->encoding = data->encoding;
                    896: #ifdef notyet
                    897:        f->firstchar = data->firstchar;
                    898:        f->numchars = data->numchars;
                    899: #endif
                    900: #ifdef VGAFONTDEBUG
                    901:        printf("vga: load %s (8x%d, enc %d) font to slot %d\n", f->name,
                    902:               f->height, f->encoding, slot);
                    903: #endif
                    904:        vga_loadchars(&vc->hdl, slot, 0, 256, f->height, data->data);
                    905:        f->slot = slot;
                    906:        vc->vc_fonts[slot] = f;
                    907:        data->cookie = f;
                    908:        data->index = slot;
                    909:
                    910:        return (0);
                    911: }
                    912:
                    913: void
                    914: vga_scrollback(v, cookie, lines)
                    915:        void *v;
                    916:        void *cookie;
                    917:        int lines;
                    918: {
                    919:        struct vga_config *vc = v;
                    920:        struct vgascreen *scr = cookie;
                    921:        struct vga_handle *vh = &vc->hdl;
                    922:
                    923:        if (lines == 0) {
                    924:                if (scr->pcs.visibleoffset == scr->pcs.dispoffset)
                    925:                        return;
                    926:
                    927:                scr->pcs.visibleoffset = scr->pcs.dispoffset;   /* reset */
                    928:        }
                    929:        else {
                    930:                int vga_scr_end;
                    931:                int margin = scr->pcs.type->ncols * 2;
                    932:                int ul, we, p, st;
                    933:
                    934:                vga_scr_end = (scr->pcs.dispoffset + scr->pcs.type->ncols *
                    935:                    scr->pcs.type->nrows * 2);
                    936:                if (scr->vga_rollover > vga_scr_end + margin) {
                    937:                        ul = vga_scr_end;
                    938:                        we = scr->vga_rollover + scr->pcs.type->ncols * 2;
                    939:                } else {
                    940:                        ul = 0;
                    941:                        we = 0x8000;
                    942:                }
                    943:                p = (scr->pcs.visibleoffset - ul + we) % we + lines *
                    944:                    (scr->pcs.type->ncols * 2);
                    945:                st = (scr->pcs.dispoffset - ul + we) % we;
                    946:                if (p < margin)
                    947:                        p = 0;
                    948:                if (p > st - margin)
                    949:                        p = st;
                    950:                scr->pcs.visibleoffset = (p + ul) % we;
                    951:        }
                    952:
                    953:        /* update visible position */
                    954:        vga_6845_write(vh, startadrh, scr->pcs.visibleoffset >> 9);
                    955:        vga_6845_write(vh, startadrl, scr->pcs.visibleoffset >> 1);
                    956: }
                    957:
                    958: int
                    959: vga_alloc_attr(id, fg, bg, flags, attrp)
                    960:        void *id;
                    961:        int fg, bg;
                    962:        int flags;
                    963:        long *attrp;
                    964: {
                    965:        struct vgascreen *scr = id;
                    966:        struct vga_config *vc = scr->cfg;
                    967:
                    968:        if (vc->hdl.vh_mono) {
                    969:                if (flags & WSATTR_WSCOLORS)
                    970:                        return (EINVAL);
                    971:                if (flags & WSATTR_REVERSE)
                    972:                        *attrp = 0x70;
                    973:                else
                    974:                        *attrp = 0x07;
                    975:                if (flags & WSATTR_UNDERLINE)
                    976:                        *attrp |= FG_UNDERLINE;
                    977:                if (flags & WSATTR_HILIT)
                    978:                        *attrp |= FG_INTENSE;
                    979:        } else {
                    980:                if (flags & (WSATTR_UNDERLINE | WSATTR_REVERSE))
                    981:                        return (EINVAL);
                    982:                if (flags & WSATTR_WSCOLORS)
                    983:                        *attrp = fgansitopc[fg & 7] | bgansitopc[bg & 7];
                    984:                else
                    985:                        *attrp = 7;
                    986:                if ((flags & WSATTR_HILIT) || (fg & 8) || (bg & 8))
                    987:                        *attrp += 8;
                    988:        }
                    989:        if (flags & WSATTR_BLINK)
                    990:                *attrp |= FG_BLINK;
                    991:        return (0);
                    992: }
                    993:
                    994: void
                    995: vga_unpack_attr(id, attr, fg, bg, ul)
                    996:        void *id;
                    997:        long attr;
                    998:        int *fg, *bg, *ul;
                    999: {
                   1000:        struct vgascreen *scr = id;
                   1001:        struct vga_config *vc = scr->cfg;
                   1002:
                   1003:        if (vc->hdl.vh_mono) {
                   1004:                *fg = (attr & 0x07) == 0x07 ? WSCOL_WHITE : WSCOL_BLACK;
                   1005:                *bg = attr & 0x70 ? WSCOL_WHITE : WSCOL_BLACK;
                   1006:                if (ul != NULL)
                   1007:                        *ul = *fg != WSCOL_WHITE && (attr & 0x01) ? 1 : 0;
                   1008:        } else {
                   1009:                *fg = pctoansi[attr & 0x07];
                   1010:                *bg = pctoansi[(attr & 0x70) >> 4];
                   1011:                if (ul != NULL)
                   1012:                        *ul = 0;
                   1013:        }
                   1014:        if (attr & FG_INTENSE)
                   1015:                *fg += 8;
                   1016: }
                   1017:
                   1018: void
                   1019: vga_copyrows(id, srcrow, dstrow, nrows)
                   1020:        void *id;
                   1021:        int srcrow, dstrow, nrows;
                   1022: {
                   1023:        struct vgascreen *scr = id;
                   1024:        bus_space_tag_t memt = scr->pcs.hdl->ph_memt;
                   1025:        bus_space_handle_t memh = scr->pcs.hdl->ph_memh;
                   1026:        int ncols = scr->pcs.type->ncols;
                   1027:        bus_size_t srcoff, dstoff;
                   1028:
                   1029:        srcoff = srcrow * ncols + 0;
                   1030:        dstoff = dstrow * ncols + 0;
                   1031:
                   1032:        if (scr->pcs.active) {
                   1033:                if (dstrow == 0 && (srcrow + nrows == scr->pcs.type->nrows)) {
                   1034: #ifdef PCDISPLAY_SOFTCURSOR
                   1035:                        int cursoron = scr->pcs.cursoron;
                   1036:
                   1037:                        if (cursoron)
                   1038:                                pcdisplay_cursor(&scr->pcs, 0,
                   1039:                                    scr->pcs.vc_crow, scr->pcs.vc_ccol);
                   1040: #endif
                   1041:                        /* scroll up whole screen */
                   1042:                        if ((scr->pcs.dispoffset + srcrow * ncols * 2)
                   1043:                            <= scr->maxdispoffset) {
                   1044:                                scr->pcs.dispoffset += srcrow * ncols * 2;
                   1045:                        } else {
                   1046:                                bus_space_copy_2(memt, memh,
                   1047:                                        scr->pcs.dispoffset + srcoff * 2,
                   1048:                                        memh, scr->mindispoffset,
                   1049:                                        nrows * ncols);
                   1050:                                scr->vga_rollover = scr->pcs.dispoffset;
                   1051:                                scr->pcs.dispoffset = scr->mindispoffset;
                   1052:                        }
                   1053:                        scr->pcs.visibleoffset = scr->pcs.dispoffset;
                   1054:                        vga_6845_write(&scr->cfg->hdl, startadrh,
                   1055:                                       scr->pcs.dispoffset >> 9);
                   1056:                        vga_6845_write(&scr->cfg->hdl, startadrl,
                   1057:                                       scr->pcs.dispoffset >> 1);
                   1058: #ifdef PCDISPLAY_SOFTCURSOR
                   1059:                        if (cursoron)
                   1060:                                pcdisplay_cursor(&scr->pcs, 1,
                   1061:                                    scr->pcs.vc_crow, scr->pcs.vc_ccol);
                   1062: #endif
                   1063:                } else {
                   1064:                        bus_space_copy_2(memt, memh,
                   1065:                                        scr->pcs.dispoffset + srcoff * 2,
                   1066:                                        memh, scr->pcs.dispoffset + dstoff * 2,
                   1067:                                        nrows * ncols);
                   1068:                }
                   1069:        } else
                   1070:                bcopy(&scr->pcs.mem[srcoff], &scr->pcs.mem[dstoff],
                   1071:                      nrows * ncols * 2);
                   1072: }
                   1073:
                   1074: #ifdef WSCONS_SUPPORT_PCVTFONTS
                   1075:
                   1076: #define NOTYET 0xffff
                   1077: static u_int16_t pcvt_unichars[0xa0] = {
                   1078: /* 0 */        _e006U,
                   1079:        NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
                   1080:        NOTYET,
                   1081:        0x2409, /* SYMBOL FOR HORIZONTAL TABULATION */
                   1082:        0x240a, /* SYMBOL FOR LINE FEED */
                   1083:        0x240b, /* SYMBOL FOR VERTICAL TABULATION */
                   1084:        0x240c, /* SYMBOL FOR FORM FEED */
                   1085:        0x240d, /* SYMBOL FOR CARRIAGE RETURN */
                   1086:        NOTYET, NOTYET,
                   1087: /* 1 */        NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
                   1088:        NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
                   1089: /* 2 */        NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
                   1090:        NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
                   1091: /* 3 */        NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
                   1092:        NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
                   1093: /* 4 */        0x03c1, /* GREEK SMALL LETTER RHO */
                   1094:        0x03c8, /* GREEK SMALL LETTER PSI */
                   1095:        0x2202, /* PARTIAL DIFFERENTIAL */
                   1096:        0x03bb, /* GREEK SMALL LETTER LAMDA */
                   1097:        0x03b9, /* GREEK SMALL LETTER IOTA */
                   1098:        0x03b7, /* GREEK SMALL LETTER ETA */
                   1099:        0x03b5, /* GREEK SMALL LETTER EPSILON */
                   1100:        0x03c7, /* GREEK SMALL LETTER CHI */
                   1101:        0x2228, /* LOGICAL OR */
                   1102:        0x2227, /* LOGICAL AND */
                   1103:        0x222a, /* UNION */
                   1104:        0x2283, /* SUPERSET OF */
                   1105:        0x2282, /* SUBSET OF */
                   1106:        0x03a5, /* GREEK CAPITAL LETTER UPSILON */
                   1107:        0x039e, /* GREEK CAPITAL LETTER XI */
                   1108:        0x03a8, /* GREEK CAPITAL LETTER PSI */
                   1109: /* 5 */        0x03a0, /* GREEK CAPITAL LETTER PI */
                   1110:        0x21d2, /* RIGHTWARDS DOUBLE ARROW */
                   1111:        0x21d4, /* LEFT RIGHT DOUBLE ARROW */
                   1112:        0x039b, /* GREEK CAPITAL LETTER LAMDA */
                   1113:        0x0398, /* GREEK CAPITAL LETTER THETA */
                   1114:        0x2243, /* ASYMPTOTICALLY EQUAL TO */
                   1115:        0x2207, /* NABLA */
                   1116:        0x2206, /* INCREMENT */
                   1117:        0x221d, /* PROPORTIONAL TO */
                   1118:        0x2234, /* THEREFORE */
                   1119:        0x222b, /* INTEGRAL */
                   1120:        0x2215, /* DIVISION SLASH */
                   1121:        0x2216, /* SET MINUS */
                   1122:        _e00eU,
                   1123:        _e00dU,
                   1124:        _e00bU,
                   1125: /* 6 */        _e00cU,
                   1126:        _e007U,
                   1127:        _e008U,
                   1128:        _e009U,
                   1129:        _e00aU,
                   1130:        0x221a, /* SQUARE ROOT */
                   1131:        0x03c9, /* GREEK SMALL LETTER OMEGA */
                   1132:        0x00a5, /* YEN SIGN */
                   1133:        0x03be, /* GREEK SMALL LETTER XI */
                   1134:        0x00fd, /* LATIN SMALL LETTER Y WITH ACUTE */
                   1135:        0x00fe, /* LATIN SMALL LETTER THORN */
                   1136:        0x00f0, /* LATIN SMALL LETTER ETH */
                   1137:        0x00de, /* LATIN CAPITAL LETTER THORN */
                   1138:        0x00dd, /* LATIN CAPITAL LETTER Y WITH ACUTE */
                   1139:        0x00d7, /* MULTIPLICATION SIGN */
                   1140:        0x00d0, /* LATIN CAPITAL LETTER ETH */
                   1141: /* 7 */        0x00be, /* VULGAR FRACTION THREE QUARTERS */
                   1142:        0x00b8, /* CEDILLA */
                   1143:        0x00b4, /* ACUTE ACCENT */
                   1144:        0x00af, /* MACRON */
                   1145:        0x00ae, /* REGISTERED SIGN */
                   1146:        0x00ad, /* SOFT HYPHEN */
                   1147:        0x00ac, /* NOT SIGN */
                   1148:        0x00a8, /* DIAERESIS */
                   1149:        0x2260, /* NOT EQUAL TO */
                   1150:        _e005U,
                   1151:        _e004U,
                   1152:        _e003U,
                   1153:        _e002U,
                   1154:        _e001U,
                   1155:        0x03c5, /* GREEK SMALL LETTER UPSILON */
                   1156:        0x00f8, /* LATIN SMALL LETTER O WITH STROKE */
                   1157: /* 8 */        0x0153, /* LATIN SMALL LIGATURE OE */
                   1158:        0x00f5, /* LATIN SMALL LETTER O WITH TILDE !!!doc bug */
                   1159:        0x00e3, /* LATIN SMALL LETTER A WITH TILDE */
                   1160:        0x0178, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
                   1161:        0x00db, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
                   1162:        0x00da, /* LATIN CAPITAL LETTER U WITH ACUTE */
                   1163:        0x00d9, /* LATIN CAPITAL LETTER U WITH GRAVE */
                   1164:        0x00d8, /* LATIN CAPITAL LETTER O WITH STROKE */
                   1165:        0x0152, /* LATIN CAPITAL LIGATURE OE */
                   1166:        0x00d5, /* LATIN CAPITAL LETTER O WITH TILDE */
                   1167:        0x00d4, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
                   1168:        0x00d3, /* LATIN CAPITAL LETTER O WITH ACUTE */
                   1169:        0x00d2, /* LATIN CAPITAL LETTER O WITH GRAVE */
                   1170:        0x00cf, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
                   1171:        0x00ce, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
                   1172:        0x00cd, /* LATIN CAPITAL LETTER I WITH ACUTE */
                   1173: /* 9 */        0x00cc, /* LATIN CAPITAL LETTER I WITH GRAVE */
                   1174:        0x00cb, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
                   1175:        0x00ca, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
                   1176:        0x00c8, /* LATIN CAPITAL LETTER E WITH GRAVE */
                   1177:        0x00c3, /* LATIN CAPITAL LETTER A WITH TILDE */
                   1178:        0x00c2, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
                   1179:        0x00c1, /* LATIN CAPITAL LETTER A WITH ACUTE */
                   1180:        0x00c0, /* LATIN CAPITAL LETTER A WITH GRAVE */
                   1181:        0x00b9, /* SUPERSCRIPT ONE */
                   1182:        0x00b7, /* MIDDLE DOT */
                   1183:        0x03b6, /* GREEK SMALL LETTER ZETA */
                   1184:        0x00b3, /* SUPERSCRIPT THREE */
                   1185:        0x00a9, /* COPYRIGHT SIGN */
                   1186:        0x00a4, /* CURRENCY SIGN */
                   1187:        0x03ba, /* GREEK SMALL LETTER KAPPA */
                   1188:        _e000U
                   1189: };
                   1190:
                   1191: int vga_pcvt_mapchar(int, unsigned int *);
                   1192:
                   1193: int
                   1194: vga_pcvt_mapchar(uni, index)
                   1195:        int uni;
                   1196:        unsigned int *index;
                   1197: {
                   1198:        int i;
                   1199:
                   1200:        for (i = 0; i < 0xa0; i++) /* 0xa0..0xff are reserved */
                   1201:                if (uni == pcvt_unichars[i]) {
                   1202:                        *index = i;
                   1203:                        return (5);
                   1204:                }
                   1205:        *index = 0x99; /* middle dot */
                   1206:        return (0);
                   1207: }
                   1208:
                   1209: #endif /* WSCONS_SUPPORT_PCVTFONTS */
                   1210:
                   1211: int _vga_mapchar(void *, struct vgafont *, int, unsigned int *);
                   1212:
                   1213: int
                   1214: _vga_mapchar(id, font, uni, index)
                   1215:        void *id;
                   1216:        struct vgafont *font;
                   1217:        int uni;
                   1218:        unsigned int *index;
                   1219: {
                   1220:
                   1221:        switch (font->encoding) {
                   1222:        case WSDISPLAY_FONTENC_ISO:
                   1223:                if (uni < 256) {
                   1224:                        *index = uni;
                   1225:                        return (5);
                   1226:                } else {
                   1227:                        *index = ' ';
                   1228:                        return (0);
                   1229:                }
                   1230:                break;
                   1231:        case WSDISPLAY_FONTENC_IBM:
                   1232:                return (pcdisplay_mapchar(id, uni, index));
                   1233: #ifdef WSCONS_SUPPORT_PCVTFONTS
                   1234:        case WSDISPLAY_FONTENC_PCVT:
                   1235:                return (vga_pcvt_mapchar(uni, index));
                   1236: #endif
                   1237:        default:
                   1238: #ifdef VGAFONTDEBUG
                   1239:                printf("_vga_mapchar: encoding=%d\n", font->encoding);
                   1240: #endif
                   1241:                *index = ' ';
                   1242:                return (0);
                   1243:        }
                   1244: }
                   1245:
                   1246: int
                   1247: vga_mapchar(id, uni, index)
                   1248:        void *id;
                   1249:        int uni;
                   1250:        unsigned int *index;
                   1251: {
                   1252:        struct vgascreen *scr = id;
                   1253:        unsigned int idx1, idx2;
                   1254:        int res1, res2;
                   1255:
                   1256:        res1 = 0;
                   1257:        idx1 = ' '; /* space */
                   1258:        if (scr->fontset1)
                   1259:                res1 = _vga_mapchar(id, scr->fontset1, uni, &idx1);
                   1260:        res2 = -1;
                   1261:        if (scr->fontset2) {
                   1262:                KASSERT(VGA_SCREEN_CANTWOFONTS(scr->pcs.type));
                   1263:                res2 = _vga_mapchar(id, scr->fontset2, uni, &idx2);
                   1264:        }
                   1265:        if (res2 >= res1) {
                   1266:                *index = idx2 | 0x0800; /* attribute bit 3 */
                   1267:                return (res2);
                   1268:        }
                   1269:        *index = idx1;
                   1270:        return (res1);
                   1271: }
                   1272:
                   1273: void
                   1274: vga_putchar(c, row, col, uc, attr)
                   1275:        void *c;
                   1276:        int row;
                   1277:        int col;
                   1278:        u_int uc;
                   1279:        long attr;
                   1280: {
                   1281:        struct vgascreen *scr = c;
                   1282:
                   1283:        if (scr->pcs.visibleoffset != scr->pcs.dispoffset)
                   1284:                vga_scrollback(scr->cfg, scr, 0);
                   1285:
                   1286:        pcdisplay_putchar(c, row, col, uc, attr);
                   1287: }
                   1288:
                   1289: void
                   1290: vga_burner(v, on, flags)
                   1291:        void *v;
                   1292:        u_int on, flags;
                   1293: {
                   1294:        struct vga_config *vc = v;
                   1295:        struct vga_handle *vh = &vc->hdl;
                   1296:        u_int8_t r;
                   1297:        int s;
                   1298:
                   1299:        s = splhigh();
                   1300:        vga_ts_write(vh, syncreset, 0x01);
                   1301:        if (on) {
                   1302:                vga_ts_write(vh, mode, (vga_ts_read(vh, mode) & ~0x20));
                   1303:                r = vga_6845_read(vh, mode) | 0x80;
                   1304:                DELAY(10000);
                   1305:                vga_6845_write(vh, mode, r);
                   1306:        } else {
                   1307:                vga_ts_write(vh, mode, (vga_ts_read(vh, mode) | 0x20));
                   1308:                if (flags & WSDISPLAY_BURN_VBLANK) {
                   1309:                        r = vga_6845_read(vh, mode) & ~0x80;
                   1310:                        DELAY(10000);
                   1311:                        vga_6845_write(vh, mode, r);
                   1312:                }
                   1313:        }
                   1314:        vga_ts_write(vh, syncreset, 0x03);
                   1315:        splx(s);
                   1316: }
                   1317:
                   1318: int
                   1319: vga_getchar(c, row, col, cell)
                   1320:        void *c;
                   1321:        int row, col;
                   1322:        struct wsdisplay_charcell *cell;
                   1323: {
                   1324:        struct vga_config *vc = c;
                   1325:
                   1326:        return (pcdisplay_getchar(vc->active, row, col, cell));
                   1327: }
                   1328:
                   1329: struct cfdriver vga_cd = {
                   1330:        NULL, "vga", DV_DULL
                   1331: };

CVSweb