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