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