root/dev/ic/vga.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vga_common_probe
  2. vga_selectfont
  3. vga_init_screen
  4. vga_init
  5. vga_common_attach
  6. vga_extended_attach
  7. vga_cnattach
  8. vga_is_console
  9. vga_ioctl
  10. vga_mmap
  11. vga_alloc_screen
  12. vga_free_screen
  13. vga_setfont
  14. vga_show_screen
  15. vga_doswitch
  16. vga_load_font
  17. vga_scrollback
  18. vga_alloc_attr
  19. vga_unpack_attr
  20. vga_copyrows
  21. vga_pcvt_mapchar
  22. _vga_mapchar
  23. vga_mapchar
  24. vga_putchar
  25. vga_burner
  26. vga_getchar

    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 };

/* [<][>][^][v][top][bottom][index][help] */