1 /* $NetBSD: vga_raster.c,v 1.32 2008/10/19 17:20:38 jmcneill Exp $ */
4 * Copyright (c) 2001, 2002 Bang Jun-Young
5 * Copyright (c) 2004 Julio M. Merino Vidal
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
33 * All rights reserved.
35 * Author: Chris G. Demetriou
37 * Permission to use, copy, modify and distribute this software and
38 * its documentation is hereby granted, provided that both the copyright
39 * notice and this permission notice appear in all copies of the
40 * software, derivative works or modified versions, and any portions
41 * thereof, and that both notices appear in supporting documentation.
43 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
44 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
45 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
47 * Carnegie Mellon requests users of this software to return to
49 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
50 * School of Computer Science
51 * Carnegie Mellon University
52 * Pittsburgh PA 15213-3890
54 * any improvements or extensions that they make and grant Carnegie the
55 * rights to redistribute these changes.
58 #include <sys/cdefs.h>
59 __KERNEL_RCSID(0, "$NetBSD: vga_raster.c,v 1.32 2008/10/19 17:20:38 jmcneill Exp $");
61 #include "opt_wsmsgattrs.h" /* for WSDISPLAY_CUSTOM_OUTPUT */
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/callout.h>
66 #include <sys/kernel.h>
67 #include <sys/device.h>
68 #include <sys/malloc.h>
69 #include <sys/queue.h>
72 #include <dev/ic/mc6845reg.h>
73 #include <dev/ic/pcdisplayvar.h>
74 #include <dev/ic/vgareg.h>
75 #include <dev/ic/vgavar.h>
76 #include <dev/ic/videomode.h>
78 #include <dev/wscons/wsdisplayvar.h>
79 #include <dev/wscons/wsconsio.h>
80 #include <dev/wsfont/wsfont.h>
82 #include <dev/ic/pcdisplay.h>
84 int vga_no_builtinfont
= 0;
86 u_int8_t builtinfont_data
[256 * 16];
88 struct wsdisplay_font builtinfont
= {
89 "builtin", /* typeface name */
92 WSDISPLAY_FONTENC_IBM
, /* encoding */
96 WSDISPLAY_FONTORDER_L2R
, /* bit order */
97 WSDISPLAY_FONTORDER_L2R
, /* byte order */
98 builtinfont_data
/* data */
104 u_int8_t second
; /* XXXBJY should be u_int8_t len; */
108 #ifdef VGA_CONSOLE_SCREENTYPE
109 #define VGA_SCRMEM_SIZE (80 * 30)
111 #define VGA_SCRMEM_SIZE (80 * 25)
114 struct vga_scrmem boot_scrmem
[VGA_SCRMEM_SIZE
];
116 struct vga_raster_font
{
117 LIST_ENTRY(vga_raster_font
) next
;
118 struct wsdisplay_font
*font
;
122 LIST_ENTRY(vgascreen
) next
;
123 struct vga_config
*cfg
;
124 struct vga_handle
*hdl
;
125 const struct wsscreen_descr
*type
;
128 struct vga_scrmem
*mem
;
135 int cursoron
; /* Is cursor displayed? */
136 int cursorcol
; /* Current cursor column */
137 int cursorrow
; /* Current cursor row */
138 struct vga_scrmem cursortmp
;
141 LIST_HEAD(, vga_raster_font
) fontset
;
144 struct vga_moderegs
{
145 u_int8_t miscout
; /* Misc. output */
146 u_int8_t crtc
[MC6845_NREGS
]; /* CRTC controller */
147 u_int8_t atc
[VGA_ATC_NREGS
]; /* Attribute controller */
148 u_int8_t ts
[VGA_TS_NREGS
]; /* Time sequencer */
149 u_int8_t gdc
[VGA_GDC_NREGS
]; /* Graphics display controller */
152 static int vgaconsole
, vga_console_type
, vga_console_attached
;
153 static struct vgascreen vga_console_screen
;
154 static struct vga_config vga_console_vc
;
155 static struct vga_raster_font vga_console_fontset_ascii
;
156 static struct videomode vga_console_modes
[2] = {
157 /* 640x400 for 80x25, 80x40 and 80x50 modes */
159 25175, 640, 664, 760, 800, 400, 409, 411, 450, 0, NULL
,
161 /* 640x480 for 80x30 mode */
163 25175, 640, 664, 760, 800, 480, 491, 493, 525, 0, NULL
,
167 static void vga_raster_init(struct vga_config
*, bus_space_tag_t
,
169 static void vga_raster_init_screen(struct vga_config
*, struct vgascreen
*,
170 const struct wsscreen_descr
*, int, long *);
171 static void vga_raster_setup_font(struct vga_config
*, struct vgascreen
*);
172 static void vga_setup_regs(struct videomode
*, struct vga_moderegs
*);
173 static void vga_set_mode(struct vga_handle
*, struct vga_moderegs
*);
174 static void vga_restore_screen(struct vgascreen
*,
175 const struct wsscreen_descr
*, struct vga_scrmem
*);
176 static void vga_raster_cursor_init(struct vgascreen
*, int);
177 static void _vga_raster_putchar(void *, int, int, u_int
, long,
178 struct vga_raster_font
*);
180 static void vga_raster_cursor(void *, int, int, int);
181 static int vga_raster_mapchar(void *, int, u_int
*);
182 static void vga_raster_putchar(void *, int, int, u_int
, long);
183 static void vga_raster_copycols(void *, int, int, int, int);
184 static void vga_raster_erasecols(void *, int, int, int, long);
185 static void vga_raster_copyrows(void *, int, int, int);
186 static void vga_raster_eraserows(void *, int, int, long);
187 static int vga_raster_allocattr(void *, int, int, int, long *);
188 #ifdef WSDISPLAY_CUSTOM_OUTPUT
189 static void vga_raster_replaceattr(void *, long, long);
190 #endif /* WSDISPLAY_CUSTOM_OUTPUT */
192 const struct wsdisplay_emulops vga_raster_emulops
= {
197 vga_raster_erasecols
,
199 vga_raster_eraserows
,
200 vga_raster_allocattr
,
201 #ifdef WSDISPLAY_CUSTOM_OUTPUT
202 vga_raster_replaceattr
,
203 #else /* WSDISPLAY_CUSTOM_OUTPUT */
205 #endif /* WSDISPLAY_CUSTOM_OUTPUT */
209 * translate WS(=ANSI) color codes to standard pc ones
211 static const unsigned char fgansitopc
[] = {
214 * XXX DEC HAS SWITCHED THE CODES FOR BLUE AND RED!!!
215 * XXX We should probably not bother with this
216 * XXX (reinitialize the palette registers).
218 FG_BLACK
, FG_BLUE
, FG_GREEN
, FG_CYAN
, FG_RED
,
219 FG_MAGENTA
, FG_BROWN
, FG_LIGHTGREY
221 FG_BLACK
, FG_RED
, FG_GREEN
, FG_BROWN
, FG_BLUE
,
222 FG_MAGENTA
, FG_CYAN
, FG_LIGHTGREY
226 BG_BLACK
, BG_BLUE
, BG_GREEN
, BG_CYAN
, BG_RED
,
227 BG_MAGENTA
, BG_BROWN
, BG_LIGHTGREY
229 BG_BLACK
, BG_RED
, BG_GREEN
, BG_BROWN
, BG_BLUE
,
230 BG_MAGENTA
, BG_CYAN
, BG_LIGHTGREY
234 const struct wsscreen_descr vga_25lscreen
= {
238 WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
| WSSCREEN_BLINK
,
239 &vga_console_modes
[0]
240 }, vga_25lscreen_mono
= {
244 WSSCREEN_HILIT
| WSSCREEN_UNDERLINE
| WSSCREEN_BLINK
| WSSCREEN_REVERSE
,
245 &vga_console_modes
[0]
250 WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
| WSSCREEN_BLINK
,
251 &vga_console_modes
[1]
252 }, vga_30lscreen_mono
= {
256 WSSCREEN_HILIT
| WSSCREEN_UNDERLINE
| WSSCREEN_BLINK
| WSSCREEN_REVERSE
,
257 &vga_console_modes
[1]
262 WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
| WSSCREEN_BLINK
,
263 &vga_console_modes
[0]
264 }, vga_40lscreen_mono
= {
268 WSSCREEN_HILIT
| WSSCREEN_UNDERLINE
| WSSCREEN_BLINK
| WSSCREEN_REVERSE
,
269 &vga_console_modes
[0]
274 WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
| WSSCREEN_BLINK
,
275 &vga_console_modes
[0]
276 }, vga_50lscreen_mono
= {
280 WSSCREEN_HILIT
| WSSCREEN_UNDERLINE
| WSSCREEN_BLINK
| WSSCREEN_REVERSE
,
281 &vga_console_modes
[0]
284 const struct wsscreen_descr
*_vga_scrlist
[] = {
289 }, *_vga_scrlist_mono
[] = {
296 const struct wsscreen_list vga_screenlist
= {
297 sizeof(_vga_scrlist
) / sizeof(struct wsscreen_descr
*),
299 }, vga_screenlist_mono
= {
300 sizeof(_vga_scrlist_mono
) / sizeof(struct wsscreen_descr
*),
304 static int vga_raster_ioctl(void *, void *, u_long
, void *, int,
306 static paddr_t
vga_raster_mmap(void *, void *, off_t
, int);
307 static int vga_raster_alloc_screen(void *, const struct wsscreen_descr
*,
308 void **, int *, int *, long *);
309 static void vga_raster_free_screen(void *, void *);
310 static int vga_raster_show_screen(void *, void *, int,
311 void (*)(void *, int, int), void *);
312 static int vga_raster_load_font(void *, void *, struct wsdisplay_font
*);
314 static void vga_switch_screen(struct vga_config
*);
315 static void vga_raster_setscreentype(struct vga_config
*,
316 const struct wsscreen_descr
*);
318 const struct wsdisplay_accessops vga_raster_accessops
= {
321 vga_raster_alloc_screen
,
322 vga_raster_free_screen
,
323 vga_raster_show_screen
,
324 vga_raster_load_font
,
330 vga_cnattach(bus_space_tag_t iot
, bus_space_tag_t memt
, int type
, int check
)
333 const struct wsscreen_descr
*scr
;
334 #ifdef VGA_CONSOLE_SCREENTYPE
335 const char *typestr
= NULL
;
338 if (check
&& !vga_common_probe(iot
, memt
))
341 /* set up bus-independent VGA configuration */
342 vga_raster_init(&vga_console_vc
, iot
, memt
);
343 #ifdef VGA_CONSOLE_SCREENTYPE
344 scr
= wsdisplay_screentype_pick(vga_console_vc
.hdl
.vh_mono
?
345 &vga_screenlist_mono
: &vga_screenlist
, VGA_CONSOLE_SCREENTYPE
);
347 /* Invalid screen type, continue with the default mode. */
349 else if (scr
->nrows
> 30)
350 /* Unsupported screen type, try 80x30. */
353 scr
= wsdisplay_screentype_pick(vga_console_vc
.hdl
.vh_mono
?
354 &vga_screenlist_mono
: &vga_screenlist
, typestr
);
355 if (scr
!= vga_console_vc
.currenttype
)
356 vga_console_vc
.currenttype
= scr
;
358 scr
= vga_console_vc
.currenttype
;
360 vga_raster_init_screen(&vga_console_vc
, &vga_console_screen
, scr
, 1,
363 vga_console_screen
.active
= 1;
364 vga_console_vc
.active
= &vga_console_screen
;
366 wsdisplay_cnattach(scr
, &vga_console_screen
,
367 vga_console_screen
.cursorcol
, vga_console_screen
.cursorrow
,
371 vga_console_type
= type
;
376 vga_raster_init(struct vga_config
*vc
, bus_space_tag_t iot
,
377 bus_space_tag_t memt
)
379 struct vga_handle
*vh
= &vc
->hdl
;
381 struct vga_raster_font
*vf
;
386 if (bus_space_map(vh
->vh_iot
, 0x3c0, 0x10, 0, &vh
->vh_ioh_vga
))
387 panic("vga_raster_init: couldn't map vga io");
389 /* read "misc output register" */
390 mor
= bus_space_read_1(vh
->vh_iot
, vh
->vh_ioh_vga
, VGA_MISC_DATAR
);
391 vh
->vh_mono
= !(mor
& 1);
393 if (bus_space_map(vh
->vh_iot
, (vh
->vh_mono
? 0x3b0 : 0x3d0), 0x10, 0,
395 panic("vga_raster_init: couldn't map 6845 io");
397 if (bus_space_map(vh
->vh_memt
, 0xa0000, 0x20000, 0, &vh
->vh_allmemh
))
398 panic("vga_raster_init: couldn't map memory");
400 if (bus_space_subregion(vh
->vh_memt
, vh
->vh_allmemh
, 0, 0x10000,
402 panic("vga_raster_init: mem subrange failed");
404 /* should only reserve the space (no need to map - save KVM) */
405 vc
->vc_biostag
= memt
;
406 if (bus_space_map(vc
->vc_biostag
, 0xc0000, 0x8000, 0, &vc
->vc_bioshdl
))
407 vc
->vc_biosmapped
= 0;
409 vc
->vc_biosmapped
= 1;
412 LIST_INIT(&vc
->screens
);
414 vc
->currenttype
= vh
->vh_mono
? &vga_25lscreen_mono
: &vga_25lscreen
;
415 callout_init(&vc
->vc_switch_callout
, 0);
419 LIST_INIT(&vc
->vc_fontlist
);
420 vf
= &vga_console_fontset_ascii
;
421 if (vga_no_builtinfont
) {
422 struct wsdisplay_font
*wf
;
425 /* prefer 8x16 pixel font */
426 cookie
= wsfont_find(NULL
, 8, 16, 0, WSDISPLAY_FONTORDER_L2R
,
429 cookie
= wsfont_find(NULL
, 0, 0, 0,
430 WSDISPLAY_FONTORDER_L2R
, WSDISPLAY_FONTORDER_L2R
);
431 if (cookie
== -1 || wsfont_lock(cookie
, &wf
))
432 panic("vga_raster_init: can't load console font");
435 vga_load_builtinfont(vh
, builtinfont_data
, 0, 256);
436 vf
->font
= &builtinfont
;
438 LIST_INSERT_HEAD(&vc
->vc_fontlist
, vf
, next
);
442 vga_raster_init_screen(struct vga_config
*vc
, struct vgascreen
*scr
,
443 const struct wsscreen_descr
*type
, int existing
, long *attrp
)
447 struct vga_handle
*vh
;
452 scr
->mindispoffset
= 0;
453 scr
->maxdispoffset
= scr
->dispoffset
+
454 type
->nrows
* type
->ncols
* type
->fontheight
;
457 LIST_INIT(&scr
->fontset
);
458 vga_raster_setup_font(vc
, scr
);
463 cpos
= vga_6845_read(vh
, cursorh
) << 8;
464 cpos
|= vga_6845_read(vh
, cursorl
);
466 /* make sure we have a valid cursor position */
467 if (cpos
< 0 || cpos
>= type
->nrows
* type
->ncols
)
470 scr
->dispoffset
= vga_6845_read(vh
, startadrh
) << 9;
471 scr
->dispoffset
|= vga_6845_read(vh
, startadrl
) << 1;
473 /* make sure we have a valid memory offset */
474 if (scr
->dispoffset
< scr
->mindispoffset
||
475 scr
->dispoffset
> scr
->maxdispoffset
)
476 scr
->dispoffset
= scr
->mindispoffset
;
478 scr
->mem
= boot_scrmem
;
481 /* Save the current screen to memory. XXXBJY assume 80x25 */
482 for (i
= 0; i
< 80 * 25; i
++) {
483 scr
->mem
[i
].ch
= bus_space_read_1(vh
->vh_memt
,
484 vh
->vh_allmemh
, 0x18000 + i
* 2);
485 scr
->mem
[i
].attr
= bus_space_read_1(vh
->vh_memt
,
486 vh
->vh_allmemh
, 0x18000 + i
* 2 + 1);
487 scr
->mem
[i
].enc
= scr
->encoding
;
490 vga_raster_setscreentype(vc
, type
);
492 /* Clear the entire screen. */
493 vga_gdc_write(vh
, mode
, 0x02);
494 bus_space_set_region_4(vh
->vh_memt
, vh
->vh_allmemh
, 0, 0,
497 vga_restore_screen(scr
, type
, scr
->mem
);
500 scr
->dispoffset
= scr
->mindispoffset
;
505 scr
->cursorrow
= cpos
/ type
->ncols
;
506 scr
->cursorcol
= cpos
% type
->ncols
;
507 vga_raster_cursor_init(scr
, existing
);
510 if (!vc
->hdl
.vh_mono
)
512 * DEC firmware uses a blue background.
514 res
= vga_raster_allocattr(scr
, WSCOL_WHITE
, WSCOL_BLUE
,
515 WSATTR_WSCOLORS
, attrp
);
518 res
= vga_raster_allocattr(scr
, 0, 0, 0, attrp
);
521 panic("vga_raster_init_screen: attribute botch");
525 LIST_INSERT_HEAD(&vc
->screens
, scr
, next
);
529 vga_common_attach(struct vga_softc
*sc
, bus_space_tag_t iot
,
530 bus_space_tag_t memt
, int type
, int quirks
,
531 const struct vga_funcs
*vf
)
534 struct vga_config
*vc
;
535 struct wsemuldisplaydev_attach_args aa
;
537 console
= vga_is_console(iot
, type
);
540 vc
= &vga_console_vc
;
541 vga_console_attached
= 1;
543 vc
= malloc(sizeof(struct vga_config
), M_DEVBUF
, M_WAITOK
);
544 vga_raster_init(vc
, iot
, memt
);
553 aa
.console
= console
;
554 aa
.scrdata
= (vc
->hdl
.vh_mono
? &vga_screenlist_mono
: &vga_screenlist
);
555 aa
.accessops
= &vga_raster_accessops
;
556 aa
.accesscookie
= vc
;
558 config_found(sc
->sc_dev
, &aa
, wsemuldisplaydevprint
);
564 struct vga_config
*vc
;
565 struct vga_handle
*vh
;
567 vc
= &vga_console_vc
;
571 bus_space_unmap(vh
->vh_iot
, vh
->vh_ioh_vga
, 0x10);
572 bus_space_unmap(vh
->vh_iot
, vh
->vh_ioh_6845
, 0x10);
581 vga_is_console(bus_space_tag_t iot
, int type
)
584 !vga_console_attached
&&
585 iot
== vga_console_vc
.hdl
.vh_iot
&&
586 (vga_console_type
== -1 || (type
== vga_console_type
)))
592 vga_get_video(struct vga_config
*vc
)
595 return (vga_ts_read(&vc
->hdl
, mode
) & VGA_TS_MODE_BLANK
) == 0;
599 vga_set_video(struct vga_config
*vc
, int state
)
603 vga_ts_write(&vc
->hdl
, syncreset
, 0x01);
604 if (state
) { /* unblank screen */
605 val
= vga_ts_read(&vc
->hdl
, mode
);
606 vga_ts_write(&vc
->hdl
, mode
, val
& ~VGA_TS_MODE_BLANK
);
607 #ifndef VGA_NO_VBLANK
608 val
= vga_6845_read(&vc
->hdl
, mode
);
609 vga_6845_write(&vc
->hdl
, mode
, val
| 0x80);
611 } else { /* blank screen */
612 val
= vga_ts_read(&vc
->hdl
, mode
);
613 vga_ts_write(&vc
->hdl
, mode
, val
| VGA_TS_MODE_BLANK
);
614 #ifndef VGA_NO_VBLANK
615 val
= vga_6845_read(&vc
->hdl
, mode
);
616 vga_6845_write(&vc
->hdl
, mode
, val
& ~0x80);
619 vga_ts_write(&vc
->hdl
, syncreset
, 0x03);
623 vga_raster_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
,
626 struct vga_config
*vc
= v
;
627 const struct vga_funcs
*vf
= vc
->vc_funcs
;
630 case WSDISPLAYIO_GTYPE
:
631 *(int *)data
= vc
->vc_type
;
634 case WSDISPLAYIO_GINFO
:
635 /* XXX should get detailed hardware information here */
638 case WSDISPLAYIO_GVIDEO
:
640 *(int *)data
= (vga_get_video(vc
) ?
641 WSDISPLAYIO_VIDEO_ON
: WSDISPLAYIO_VIDEO_OFF
);
645 case WSDISPLAYIO_SVIDEO
:
647 vga_set_video(vc
, *(int *)data
== WSDISPLAYIO_VIDEO_ON
);
651 case WSDISPLAYIO_GETCMAP
:
652 case WSDISPLAYIO_PUTCMAP
:
653 case WSDISPLAYIO_GCURPOS
:
654 case WSDISPLAYIO_SCURPOS
:
655 case WSDISPLAYIO_GCURMAX
:
656 case WSDISPLAYIO_GCURSOR
:
657 case WSDISPLAYIO_SCURSOR
:
658 /* NONE of these operations are by the generic VGA driver. */
662 if (vc
->vc_funcs
== NULL
)
663 return (EPASSTHROUGH
);
665 if (vf
->vf_ioctl
== NULL
)
666 return (EPASSTHROUGH
);
668 return ((*vf
->vf_ioctl
)(v
, cmd
, data
, flag
, l
));
672 vga_raster_mmap(void *v
, void *vs
, off_t offset
, int prot
)
674 struct vga_config
*vc
= v
;
675 const struct vga_funcs
*vf
= vc
->vc_funcs
;
677 if (vc
->vc_funcs
== NULL
)
680 if (vf
->vf_mmap
== NULL
)
683 return ((*vf
->vf_mmap
)(v
, offset
, prot
));
687 vga_raster_alloc_screen(void *v
, const struct wsscreen_descr
*type
,
688 void **cookiep
, int *curxp
, int *curyp
, long *defattrp
)
690 struct vga_config
*vc
= v
;
691 struct vgascreen
*scr
;
693 if (vc
->nscreens
== 1) {
694 vc
->screens
.lh_first
->mem
= boot_scrmem
;
697 scr
= malloc(sizeof(struct vgascreen
), M_DEVBUF
, M_WAITOK
);
698 vga_raster_init_screen(vc
, scr
, type
, vc
->nscreens
== 0, defattrp
);
700 if (vc
->nscreens
== 1) {
703 vc
->currenttype
= type
;
705 scr
->mem
= malloc(sizeof(struct vga_scrmem
) *
706 type
->ncols
* type
->nrows
, M_DEVBUF
, M_WAITOK
);
707 vga_raster_eraserows(scr
, 0, type
->nrows
, *defattrp
);
711 *curxp
= scr
->cursorcol
;
712 *curyp
= scr
->cursorrow
;
718 vga_raster_free_screen(void *v
, void *cookie
)
720 struct vgascreen
*vs
= cookie
;
721 struct vga_config
*vc
= vs
->cfg
;
723 LIST_REMOVE(vs
, next
);
725 if (vs
!= &vga_console_screen
)
728 panic("vga_raster_free_screen: console");
730 if (vc
->active
== vs
)
735 vga_raster_show_screen(void *v
, void *cookie
, int waitok
,
736 void (*cb
)(void *, int, int), void *cbarg
)
738 struct vgascreen
*scr
= cookie
, *oldscr
;
739 struct vga_config
*vc
= scr
->cfg
;
741 oldscr
= vc
->active
; /* can be NULL! */
746 vc
->wantedscreen
= cookie
;
748 vc
->switchcbarg
= cbarg
;
750 callout_reset(&vc
->vc_switch_callout
, 0,
751 (void(*)(void *))vga_switch_screen
, vc
);
755 vga_switch_screen(vc
);
760 vga_switch_screen(struct vga_config
*vc
)
762 struct vgascreen
*scr
, *oldscr
;
763 struct vga_handle
*vh
= &vc
->hdl
;
764 const struct wsscreen_descr
*type
;
766 scr
= vc
->wantedscreen
;
768 printf("vga_switch_screen: disappeared\n");
769 (*vc
->switchcb
)(vc
->switchcbarg
, EIO
, 0);
773 oldscr
= vc
->active
; /* can be NULL! */
777 panic("vga_raster_show_screen: not active");
778 if (oldscr
->type
!= vc
->currenttype
)
779 panic("vga_raster_show_screen: bad type");
787 panic("vga_raster_show_screen: active");
793 if (vc
->currenttype
!= type
) {
794 vga_raster_setscreentype(vc
, type
);
795 vc
->currenttype
= type
;
798 scr
->dispoffset
= scr
->mindispoffset
;
800 if (!oldscr
|| (scr
->dispoffset
!= oldscr
->dispoffset
)) {
801 vga_6845_write(vh
, startadrh
, scr
->dispoffset
>> 8);
802 vga_6845_write(vh
, startadrl
, scr
->dispoffset
);
805 /* Clear the entire screen. */
806 vga_gdc_write(vh
, mode
, 0x02);
807 bus_space_set_region_4(vh
->vh_memt
, vh
->vh_allmemh
, 0, 0, 0x2000);
810 vga_restore_screen(scr
, type
, scr
->mem
);
814 vga_raster_cursor(scr
, scr
->cursoron
, scr
->cursorrow
, scr
->cursorcol
);
816 vc
->wantedscreen
= 0;
818 (*vc
->switchcb
)(vc
->switchcbarg
, 0, 0);
822 vga_raster_load_font(void *v
, void *id
,
823 struct wsdisplay_font
*data
)
826 printf("vga_raster_load_font: called\n");
832 vga_raster_setup_font(struct vga_config
*vc
, struct vgascreen
*scr
)
834 struct vga_raster_font
*vf
;
835 struct wsdisplay_font
*wf
;
838 LIST_FOREACH(vf
, &vc
->vc_fontlist
, next
) {
839 if (wsfont_matches(vf
->font
, 0, 0, scr
->type
->fontheight
, 0)) {
840 scr
->encoding
= vf
->font
->encoding
;
841 LIST_INSERT_HEAD(&scr
->fontset
, vf
, next
);
846 cookie
= wsfont_find(NULL
, 0, scr
->type
->fontheight
, 0,
847 WSDISPLAY_FONTORDER_L2R
, 0);
851 if (wsfont_lock(cookie
, &wf
))
854 vf
= malloc(sizeof(struct vga_raster_font
), M_DEVBUF
, M_NOWAIT
);
856 wsfont_unlock(cookie
);
861 scr
->encoding
= vf
->font
->encoding
;
862 LIST_INSERT_HEAD(&scr
->fontset
, vf
, next
);
866 vga_setup_regs(struct videomode
*mode
, struct vga_moderegs
*regs
)
869 int depth
= 4; /* XXXBJY hardcoded for now */
870 const u_int8_t palette
[] = {
871 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
872 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
876 * Compute hsync and vsync polarity.
878 if ((mode
->flags
& (VID_PHSYNC
| VID_NHSYNC
))
879 && (mode
->flags
& (VID_PVSYNC
| VID_NVSYNC
))) {
880 regs
->miscout
= 0x23;
881 if (mode
->flags
& VID_NHSYNC
)
882 regs
->miscout
|= 0x40;
883 if (mode
->flags
& VID_NVSYNC
)
884 regs
->miscout
|= 0x80;
886 if (mode
->flags
& VID_DBLSCAN
)
888 if (mode
->vdisplay
< 400)
889 regs
->miscout
= 0xa3;
890 else if (mode
->vdisplay
< 480)
891 regs
->miscout
= 0x63;
892 else if (mode
->vdisplay
< 768)
893 regs
->miscout
= 0xe3;
895 regs
->miscout
= 0x23;
905 if (mode
->flags
& VID_CLKDIV2
)
919 regs
->crtc
[0] = (mode
->htotal
>> 3) - 5;
920 regs
->crtc
[1] = (mode
->hdisplay
>> 3) - 1;
921 regs
->crtc
[2] = (mode
->hsync_start
>> 3) - 1;
922 regs
->crtc
[3] = (((mode
->hsync_end
>> 3) - 1) & 0x1f) | 0x80;
923 regs
->crtc
[4] = mode
->hsync_start
>> 3;
924 regs
->crtc
[5] = ((((mode
->hsync_end
>> 3) - 1) & 0x20) << 2)
925 | (((mode
->hsync_end
>> 3)) & 0x1f);
926 regs
->crtc
[6] = (mode
->vtotal
- 2) & 0xff;
927 regs
->crtc
[7] = (((mode
->vtotal
- 2) & 0x100) >> 8)
928 | (((mode
->vdisplay
- 1) & 0x100) >> 7)
929 | ((mode
->vsync_start
& 0x100) >> 6)
930 | (((mode
->vsync_start
- 1) & 0x100) >> 5)
932 | (((mode
->vtotal
- 2) & 0x200) >> 4)
933 | (((mode
->vdisplay
- 1) & 0x200) >> 3)
934 | ((mode
->vsync_start
& 0x200) >> 2);
935 regs
->crtc
[8] = 0x00;
936 regs
->crtc
[9] = (((mode
->vsync_start
- 1) & 0x200) >> 4) | 0x40;
937 if (mode
->flags
& VID_DBLSCAN
)
938 regs
->crtc
[9] |= 0x80;
939 regs
->crtc
[10] = 0x00;
940 regs
->crtc
[11] = 0x00;
941 regs
->crtc
[12] = 0x00;
942 regs
->crtc
[13] = 0x00;
943 regs
->crtc
[14] = 0x00;
944 regs
->crtc
[15] = 0x00;
945 regs
->crtc
[16] = mode
->vsync_start
& 0xff;
946 regs
->crtc
[17] = (mode
->vsync_end
& 0x0f) | 0x20;
947 regs
->crtc
[18] = (mode
->vdisplay
- 1) & 0xff;
948 regs
->crtc
[19] = mode
->hdisplay
>> 4; /* XXXBJY */
949 regs
->crtc
[20] = 0x00;
950 regs
->crtc
[21] = (mode
->vsync_start
- 1) & 0xff;
951 regs
->crtc
[22] = (mode
->vsync_end
- 1) & 0xff;
953 regs
->crtc
[23] = 0xe3;
955 regs
->crtc
[23] = 0xc3;
956 regs
->crtc
[24] = 0xff;
959 * Graphics display controller
975 * Attribute controller
977 /* Set palette registers. */
978 for (i
= 0; i
< 16; i
++)
979 regs
->atc
[i
] = palette
[i
];
981 regs
->atc
[16] = 0x01; /* XXXBJY was 0x81 in XFree86 */
983 regs
->atc
[16] = 0x41;
984 regs
->atc
[17] = 0x00; /* XXXBJY just a guess */
985 regs
->atc
[18] = 0x0f;
986 regs
->atc
[19] = 0x00;
987 regs
->atc
[20] = 0x00;
991 vga_set_mode(struct vga_handle
*vh
, struct vga_moderegs
*regs
)
995 /* Disable display. */
996 vga_ts_write(vh
, mode
, vga_ts_read(vh
, mode
) | VGA_TS_MODE_BLANK
);
998 /* Write misc output register. */
999 bus_space_write_1(vh
->vh_iot
, vh
->vh_ioh_vga
, VGA_MISC_DATAW
,
1002 /* Set synchronous reset. */
1003 vga_ts_write(vh
, syncreset
, 0x01);
1004 vga_ts_write(vh
, mode
, regs
->ts
[1] | VGA_TS_MODE_BLANK
);
1005 for (i
= 2; i
< VGA_TS_NREGS
; i
++)
1006 _vga_ts_write(vh
, i
, regs
->ts
[i
]);
1007 /* Clear synchronous reset. */
1008 vga_ts_write(vh
, syncreset
, 0x03);
1010 /* Unprotect CRTC registers 0-7. */
1011 vga_6845_write(vh
, vsynce
, vga_6845_read(vh
, vsynce
) & ~0x80);
1012 /* Write CRTC registers. */
1013 for (i
= 0; i
< MC6845_NREGS
; i
++)
1014 _vga_6845_write(vh
, i
, regs
->crtc
[i
]);
1016 /* Write graphics display registers. */
1017 for (i
= 0; i
< VGA_GDC_NREGS
; i
++)
1018 _vga_gdc_write(vh
, i
, regs
->gdc
[i
]);
1020 /* Write attribute controller registers. */
1021 for (i
= 0; i
< VGA_ATC_NREGS
; i
++)
1022 _vga_attr_write(vh
, i
, regs
->atc
[i
]);
1024 /* Enable display. */
1025 vga_ts_write(vh
, mode
, vga_ts_read(vh
, mode
) & ~VGA_TS_MODE_BLANK
);
1029 vga_raster_cursor_init(struct vgascreen
*scr
, int existing
)
1031 struct vga_handle
*vh
= scr
->hdl
;
1032 bus_space_tag_t memt
;
1033 bus_space_handle_t memh
;
1038 * This is the first screen. At this point, scr->active is
1039 * false, so we can't use vga_raster_cursor() to do this.
1043 off
= (scr
->cursorrow
* scr
->type
->ncols
+ scr
->cursorcol
) +
1044 scr
->dispoffset
/ 8;
1046 scr
->cursortmp
= scr
->mem
[off
];
1047 vga_raster_putchar(scr
, scr
->cursorrow
, scr
->cursorcol
,
1048 scr
->cursortmp
.ch
, scr
->cursortmp
.attr
^ 0x77);
1050 scr
->cursortmp
.ch
= 0;
1051 scr
->cursortmp
.attr
= 0;
1052 scr
->cursortmp
.second
= 0;
1053 scr
->cursortmp
.enc
= scr
->encoding
;
1060 vga_raster_cursor(void *id
, int on
, int row
, int col
)
1062 struct vgascreen
*scr
= id
;
1065 /* Remove old cursor image */
1066 if (scr
->cursoron
) {
1067 off
= scr
->cursorrow
* scr
->type
->ncols
+ scr
->cursorcol
;
1069 tmp
= scr
->encoding
;
1070 scr
->encoding
= scr
->cursortmp
.enc
;
1071 if (scr
->cursortmp
.second
)
1072 vga_raster_putchar(id
, scr
->cursorrow
,
1073 scr
->cursorcol
- 1, scr
->cursortmp
.ch
,
1074 scr
->cursortmp
.attr
);
1076 vga_raster_putchar(id
, scr
->cursorrow
,
1077 scr
->cursorcol
, scr
->cursortmp
.ch
,
1078 scr
->cursortmp
.attr
);
1079 scr
->encoding
= tmp
;
1083 scr
->cursorrow
= row
;
1084 scr
->cursorcol
= col
;
1086 if ((scr
->cursoron
= on
) == 0)
1089 off
= scr
->cursorrow
* scr
->type
->ncols
+ scr
->cursorcol
;
1090 scr
->cursortmp
= scr
->mem
[off
];
1092 tmp
= scr
->encoding
;
1093 scr
->encoding
= scr
->cursortmp
.enc
;
1094 if (scr
->cursortmp
.second
)
1095 vga_raster_putchar(id
, scr
->cursorrow
,
1096 scr
->cursorcol
- 1, scr
->cursortmp
.ch
,
1097 scr
->cursortmp
.attr
^ 0x77);
1099 vga_raster_putchar(id
, scr
->cursorrow
,
1100 scr
->cursorcol
, scr
->cursortmp
.ch
,
1101 scr
->cursortmp
.attr
^ 0x77);
1102 scr
->encoding
= tmp
;
1107 vga_raster_mapchar(void *id
, int uni
, u_int
*index
)
1109 struct vgascreen
*scr
= id
;
1111 if (scr
->encoding
== WSDISPLAY_FONTENC_IBM
)
1112 return pcdisplay_mapchar(id
, uni
, index
);
1120 vga_raster_putchar(void *id
, int row
, int col
, u_int c
, long attr
)
1122 struct vgascreen
*scr
= id
;
1124 struct vga_raster_font
*fs
;
1127 off
= row
* scr
->type
->ncols
+ col
;
1129 if (__predict_false(off
>= (scr
->type
->ncols
* scr
->type
->nrows
)))
1132 LIST_FOREACH(fs
, &scr
->fontset
, next
) {
1133 if ((scr
->encoding
== fs
->font
->encoding
) &&
1134 (c
>= fs
->font
->firstchar
) &&
1135 (c
< fs
->font
->firstchar
+ fs
->font
->numchars
) &&
1136 (scr
->type
->fontheight
== fs
->font
->fontheight
)) {
1138 tmp_ch
= c
- fs
->font
->firstchar
;
1139 _vga_raster_putchar(scr
, row
, col
, tmp_ch
,
1143 scr
->mem
[off
].ch
= c
;
1144 scr
->mem
[off
].attr
= attr
;
1145 scr
->mem
[off
].second
= 0;
1146 scr
->mem
[off
].enc
= fs
->font
->encoding
;
1148 if (fs
->font
->stride
== 2) {
1149 scr
->mem
[off
+ 1].ch
= c
;
1150 scr
->mem
[off
+ 1].attr
= attr
;
1151 scr
->mem
[off
+ 1].second
= 1;
1152 scr
->mem
[off
+ 1].enc
= fs
->font
->encoding
;
1164 * Put a single width space character no matter what the
1165 * actual width of the character is.
1167 _vga_raster_putchar(scr
, row
, col
, ' ', attr
,
1168 &vga_console_fontset_ascii
);
1169 scr
->mem
[off
].ch
= c
;
1170 scr
->mem
[off
].attr
= attr
;
1171 scr
->mem
[off
].second
= 0;
1172 scr
->mem
[off
].enc
= scr
->encoding
;
1176 _vga_raster_putchar(void *id
, int row
, int col
, u_int c
, long attr
,
1177 struct vga_raster_font
*fs
)
1179 struct vgascreen
*scr
= id
;
1180 struct vga_handle
*vh
= scr
->hdl
;
1181 bus_space_tag_t memt
= vh
->vh_memt
;
1182 bus_space_handle_t memh
= vh
->vh_memh
;
1184 int rasoff
, rasoff2
;
1185 int fheight
= scr
->type
->fontheight
;
1186 volatile u_int8_t dummy
, pattern
;
1187 u_int8_t fgcolor
, bgcolor
;
1189 rasoff
= scr
->dispoffset
+ row
* scr
->type
->ncols
* fheight
+ col
;
1193 bgcolor
= bgansitopc
[attr
>> 4];
1194 fgcolor
= fgansitopc
[attr
& 0x0f];
1196 bgcolor
= ((attr
>> 4) & 0x0f);
1197 fgcolor
= attr
& 0x0f;
1200 if (fs
->font
->stride
== 1) {
1201 /* Paint background. */
1202 vga_gdc_write(vh
, mode
, 0x02);
1203 for (i
= 0; i
< fheight
; i
++) {
1204 bus_space_write_1(memt
, memh
, rasoff
, bgcolor
);
1205 rasoff
+= scr
->type
->ncols
;
1208 /* Draw a single width character. */
1209 vga_gdc_write(vh
, mode
, 0x03);
1210 vga_gdc_write(vh
, setres
, fgcolor
);
1211 for (i
= 0; i
< fheight
; i
++) {
1212 pattern
= ((u_int8_t
*)fs
->font
->data
)[c
* fheight
+ i
];
1213 /* When pattern is 0, skip output for speed-up. */
1215 dummy
= bus_space_read_1(memt
, memh
, rasoff2
);
1216 bus_space_write_1(memt
, memh
, rasoff2
, pattern
);
1218 rasoff2
+= scr
->type
->ncols
;
1220 } else if (fs
->font
->stride
== 2) {
1221 /* Paint background. */
1222 vga_gdc_write(vh
, mode
, 0x02);
1223 for (i
= 0; i
< fheight
; i
++) {
1224 bus_space_write_1(memt
, memh
, rasoff
, bgcolor
);
1225 bus_space_write_1(memt
, memh
, rasoff
+ 1, bgcolor
);
1226 rasoff
+= scr
->type
->ncols
;
1229 /* Draw a double width character. */
1230 vga_gdc_write(vh
, mode
, 0x03);
1231 vga_gdc_write(vh
, setres
, fgcolor
);
1232 for (i
= 0; i
< fheight
; i
++) {
1233 pattern
= ((u_int8_t
*)fs
->font
->data
)
1234 [(c
* fheight
+ i
) * 2];
1236 dummy
= bus_space_read_1(memt
, memh
, rasoff2
);
1237 bus_space_write_1(memt
, memh
, rasoff2
, pattern
);
1239 pattern
= ((u_int8_t
*)fs
->font
->data
)
1240 [(c
* fheight
+ i
) * 2 + 1];
1243 dummy
= bus_space_read_1(memt
, memh
, rasoff2
);
1244 bus_space_write_1(memt
, memh
, rasoff2
, pattern
);
1247 rasoff2
+= scr
->type
->ncols
;
1253 vga_raster_copycols(void *id
, int row
, int srccol
, int dstcol
, int ncols
)
1255 struct vgascreen
*scr
= id
;
1256 struct vga_handle
*vh
= scr
->hdl
;
1257 bus_space_tag_t memt
= vh
->vh_memt
;
1258 bus_space_handle_t memh
= vh
->vh_memh
;
1259 bus_size_t srcoff
, dstoff
;
1260 bus_size_t rassrcoff
, rasdstoff
;
1262 int fheight
= scr
->type
->fontheight
;
1264 srcoff
= row
* scr
->type
->ncols
+ srccol
;
1265 dstoff
= row
* scr
->type
->ncols
+ dstcol
;
1266 rassrcoff
= scr
->dispoffset
+ row
* scr
->type
->ncols
* fheight
+ srccol
;
1267 rasdstoff
= scr
->dispoffset
+ row
* scr
->type
->ncols
* fheight
+ dstcol
;
1269 memcpy(&scr
->mem
[dstoff
], &scr
->mem
[srcoff
],
1270 ncols
* sizeof(struct vga_scrmem
));
1272 vga_gdc_write(vh
, mode
, 0x01);
1274 for (i
= 0; i
< fheight
; i
++) {
1275 bus_space_copy_region_1(memt
, memh
,
1276 rassrcoff
+ i
* scr
->type
->ncols
, memh
,
1277 rasdstoff
+ i
* scr
->type
->ncols
, ncols
);
1283 vga_raster_erasecols(void *id
, int row
, int startcol
, int ncols
, long fillattr
)
1285 struct vgascreen
*scr
= id
;
1288 if (scr
->active
== 0)
1291 for (i
= startcol
; i
< startcol
+ ncols
; i
++)
1292 vga_raster_putchar(id
, row
, i
, ' ', fillattr
);
1296 vga_raster_copyrows(void *id
, int srcrow
, int dstrow
, int nrows
)
1298 struct vgascreen
*scr
= id
;
1299 struct vga_handle
*vh
= scr
->hdl
;
1300 bus_space_tag_t memt
= vh
->vh_memt
;
1301 bus_space_handle_t memh
= vh
->vh_memh
;
1303 bus_size_t srcoff
, dstoff
;
1304 bus_size_t rassrcoff
, rasdstoff
;
1307 ncols
= scr
->type
->ncols
;
1308 fheight
= scr
->type
->fontheight
;
1310 srcoff
= srcrow
* ncols
;
1311 dstoff
= dstrow
* ncols
;
1312 rassrcoff
= srcoff
* fheight
;
1313 rasdstoff
= dstoff
* fheight
;
1316 vga_gdc_write(vh
, mode
, 0x01);
1317 if (dstrow
== 0 && (srcrow
+ nrows
== scr
->type
->nrows
)) {
1318 int cursoron
= scr
->cursoron
;
1321 /* Disable cursor. */
1322 vga_raster_cursor(scr
, 0,
1323 scr
->cursorrow
, scr
->cursorcol
);
1325 /* scroll up whole screen */
1326 if ((scr
->dispoffset
+ srcrow
* ncols
* fheight
)
1327 <= scr
->maxdispoffset
)
1328 scr
->dispoffset
+= srcrow
* ncols
* fheight
;
1330 bus_space_copy_region_1(memt
, memh
,
1331 scr
->dispoffset
+ rassrcoff
,
1332 memh
, scr
->mindispoffset
,
1333 nrows
* ncols
* fheight
);
1334 scr
->dispoffset
= scr
->mindispoffset
;
1336 vga_6845_write(vh
, startadrh
, scr
->dispoffset
>> 8);
1337 vga_6845_write(vh
, startadrl
, scr
->dispoffset
);
1340 /* Enable cursor. */
1341 vga_raster_cursor(scr
, 1, scr
->cursorrow
,
1344 bus_space_copy_region_1(memt
, memh
,
1345 scr
->dispoffset
+ rassrcoff
, memh
,
1346 scr
->dispoffset
+ rasdstoff
,
1347 nrows
* ncols
* fheight
);
1349 memcpy(&scr
->mem
[dstoff
], &scr
->mem
[srcoff
],
1350 nrows
* ncols
* sizeof(struct vga_scrmem
));
1354 vga_raster_eraserows(void *id
, int startrow
, int nrows
, long fillattr
)
1356 struct vgascreen
*scr
= id
;
1357 struct vga_handle
*vh
= scr
->hdl
;
1358 bus_space_tag_t memt
= vh
->vh_memt
;
1359 bus_space_handle_t memh
= vh
->vh_memh
;
1360 bus_size_t off
, count
;
1361 bus_size_t rasoff
, rascount
;
1364 off
= startrow
* scr
->type
->ncols
;
1365 count
= nrows
* scr
->type
->ncols
;
1366 rasoff
= off
* scr
->type
->fontheight
;
1367 rascount
= count
* scr
->type
->fontheight
;
1370 u_int8_t bgcolor
= (fillattr
>> 4) & 0x0F;
1372 /* Paint background. */
1373 vga_gdc_write(vh
, mode
, 0x02);
1374 if (scr
->type
->ncols
% 4 == 0) {
1375 u_int32_t fill
= bgcolor
| (bgcolor
<< 8) |
1376 (bgcolor
<< 16) | (bgcolor
<< 24);
1377 /* We can speed up I/O */
1378 for (i
= rasoff
; i
< rasoff
+ rascount
; i
+= 4)
1379 bus_space_write_4(memt
, memh
,
1380 scr
->dispoffset
+ i
, fill
);
1382 u_int16_t fill
= bgcolor
| (bgcolor
<< 8);
1383 for (i
= rasoff
; i
< rasoff
+ rascount
; i
+= 2)
1384 bus_space_write_2(memt
, memh
,
1385 scr
->dispoffset
+ i
, fill
);
1388 for (i
= 0; i
< count
; i
++) {
1389 scr
->mem
[off
+ i
].ch
= ' ';
1390 scr
->mem
[off
+ i
].attr
= fillattr
;
1391 scr
->mem
[off
+ i
].second
= 0;
1392 scr
->mem
[off
+ i
].enc
= scr
->encoding
;
1397 vga_raster_allocattr(void *id
, int fg
, int bg
, int flags
, long *attrp
)
1399 struct vgascreen
*scr
= id
;
1400 struct vga_config
*vc
= scr
->cfg
;
1402 if (__predict_false((unsigned int)fg
>= sizeof(fgansitopc
) ||
1403 (unsigned int)bg
>= sizeof(bgansitopc
)))
1406 if (vc
->hdl
.vh_mono
) {
1407 if (flags
& WSATTR_WSCOLORS
)
1409 if (flags
& WSATTR_REVERSE
)
1413 if (flags
& WSATTR_UNDERLINE
)
1414 *attrp
|= FG_UNDERLINE
;
1415 if (flags
& WSATTR_HILIT
)
1416 *attrp
|= FG_INTENSE
;
1418 if (flags
& (WSATTR_UNDERLINE
| WSATTR_REVERSE
))
1420 if (flags
& WSATTR_WSCOLORS
)
1421 *attrp
= fgansitopc
[fg
] | bgansitopc
[bg
];
1424 if (flags
& WSATTR_HILIT
)
1427 if (flags
& WSATTR_BLINK
)
1433 vga_restore_screen(struct vgascreen
*scr
,
1434 const struct wsscreen_descr
*type
, struct vga_scrmem
*mem
)
1438 tmp
= scr
->encoding
;
1439 for (i
= 0; i
< type
->nrows
; i
++) {
1440 for (j
= 0; j
< type
->ncols
; j
++) {
1441 off
= i
* type
->ncols
+ j
;
1442 if (mem
[off
].second
!= 1) {
1443 scr
->encoding
= mem
[off
].enc
;
1444 vga_raster_putchar(scr
, i
, j
, mem
[off
].ch
,
1449 scr
->encoding
= tmp
;
1453 vga_raster_setscreentype(struct vga_config
*vc
,
1454 const struct wsscreen_descr
*type
)
1456 struct vga_handle
*vh
= &vc
->hdl
;
1457 struct vga_moderegs moderegs
;
1459 vga_setup_regs((struct videomode
*)type
->modecookie
, &moderegs
);
1460 vga_set_mode(vh
, &moderegs
);
1463 #ifdef WSDISPLAY_CUSTOM_OUTPUT
1465 vga_raster_replaceattr(void *id
, long oldattr
, long newattr
)
1467 struct vgascreen
*scr
= id
;
1468 const struct wsscreen_descr
*type
= scr
->type
;
1471 for (off
= 0; off
< type
->nrows
* type
->ncols
; off
++) {
1472 if (scr
->mem
[off
].attr
== oldattr
)
1473 scr
->mem
[off
].attr
= newattr
;
1476 /* Repaint the whole screen, if needed */
1478 vga_restore_screen(scr
, type
, scr
->mem
);
1480 #endif /* WSDISPLAY_CUSTOM_OUTPUT */
1483 vga_resume(struct vga_softc
*sc
)
1485 #ifdef VGA_RESET_ON_RESUME
1486 vga_initregs(&sc
->sc_vc
->hdl
);