Annotation of sys/dev/ic/vga.c, Revision 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