1 /* $NetBSD: ega.c,v 1.28 2009/05/12 08:44:19 cegger Exp $ */
5 * Matthias Drochner. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: ega.c,v 1.28 2009/05/12 08:44:19 cegger Exp $");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/callout.h>
35 #include <sys/kernel.h>
36 #include <sys/device.h>
37 #include <sys/malloc.h>
40 #include <dev/isa/isavar.h>
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 #include <dev/isa/egavar.h>
48 #include <dev/ic/pcdisplay.h>
50 #include <dev/wscons/wsconsio.h>
51 #include <dev/wscons/wsdisplayvar.h>
53 static struct egafont
{
61 WSDISPLAY_FONTENC_IBM
,
66 struct pcdisplayscreen pcs
;
67 LIST_ENTRY(egascreen
) next
;
68 struct ega_config
*cfg
;
69 struct egafont
*fontset1
, *fontset2
;
71 int mindispoffset
, maxdispoffset
;
75 struct vga_handle hdl
;
78 LIST_HEAD(, egascreen
) screens
;
79 struct egascreen
*active
; /* current display */
80 const struct wsscreen_descr
*currenttype
;
81 int currentfontset1
, currentfontset2
;
83 struct egafont
*vc_fonts
[4];
85 struct egascreen
*wantedscreen
;
86 void (*switchcb
)(void *, int, int);
89 callout_t switch_callout
;
94 struct ega_config
*sc_dc
;
98 static int egaconsole
, ega_console_attached
;
99 static struct egascreen ega_console_screen
;
100 static struct ega_config ega_console_dc
;
102 int ega_match(device_t
, cfdata_t
, void *);
103 void ega_attach(device_t
, device_t
, void *);
105 static int ega_is_console(bus_space_tag_t
);
106 static int ega_probe_col(bus_space_tag_t
, bus_space_tag_t
);
107 static int ega_probe_mono(bus_space_tag_t
, bus_space_tag_t
);
108 int ega_selectfont(struct ega_config
*, struct egascreen
*, char *, char *);
109 void ega_init_screen(struct ega_config
*, struct egascreen
*,
110 const struct wsscreen_descr
*, int, long *);
111 static void ega_init(struct ega_config
*, bus_space_tag_t
, bus_space_tag_t
,
113 static void ega_setfont(struct ega_config
*, struct egascreen
*);
114 static int ega_allocattr(void *, int, int, int, long *);
115 void ega_copyrows(void *, int, int, int);
117 CFATTACH_DECL(ega
, sizeof(struct ega_softc
),
118 ega_match
, ega_attach
, NULL
, NULL
);
120 const struct wsdisplay_emulops ega_emulops
= {
132 * translate WS(=ANSI) color codes to standard pc ones
134 static unsigned char fgansitopc
[] = {
135 FG_BLACK
, FG_RED
, FG_GREEN
, FG_BROWN
, FG_BLUE
,
136 FG_MAGENTA
, FG_CYAN
, FG_LIGHTGREY
138 BG_BLACK
, BG_RED
, BG_GREEN
, BG_BROWN
, BG_BLUE
,
139 BG_MAGENTA
, BG_CYAN
, BG_LIGHTGREY
142 const struct wsscreen_descr ega_stdscreen
= {
146 WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
| WSSCREEN_BLINK
147 }, ega_stdscreen_mono
= {
151 WSSCREEN_HILIT
| WSSCREEN_UNDERLINE
| WSSCREEN_BLINK
| WSSCREEN_REVERSE
152 }, ega_stdscreen_bf
= {
156 WSSCREEN_WSCOLORS
| WSSCREEN_BLINK
161 WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
| WSSCREEN_BLINK
162 }, ega_35lscreen_mono
= {
166 WSSCREEN_HILIT
| WSSCREEN_UNDERLINE
| WSSCREEN_BLINK
| WSSCREEN_REVERSE
167 }, ega_35lscreen_bf
= {
171 WSSCREEN_WSCOLORS
| WSSCREEN_BLINK
176 WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
| WSSCREEN_BLINK
177 }, ega_43lscreen_mono
= {
181 WSSCREEN_HILIT
| WSSCREEN_UNDERLINE
| WSSCREEN_BLINK
| WSSCREEN_REVERSE
182 }, ega_43lscreen_bf
= {
186 WSSCREEN_WSCOLORS
| WSSCREEN_BLINK
189 #define VGA_SCREEN_CANTWOFONTS(type) (!((type)->capabilities & WSSCREEN_HILIT))
191 const struct wsscreen_descr
*_ega_scrlist
[] = {
198 }, *_ega_scrlist_mono
[] = {
205 const struct wsscreen_list ega_screenlist
= {
206 sizeof(_ega_scrlist
) / sizeof(struct wsscreen_descr
*),
208 }, ega_screenlist_mono
= {
209 sizeof(_ega_scrlist_mono
) / sizeof(struct wsscreen_descr
*),
213 static int ega_ioctl(void *, void *, u_long
, void *, int, struct proc
*);
214 static paddr_t
ega_mmap(void *, void *, off_t
, int);
215 static int ega_alloc_screen(void *, const struct wsscreen_descr
*,
216 void **, int *, int *, long *);
217 static void ega_free_screen(void *, void *);
218 static int ega_show_screen(void *, void *, int,
219 void (*) (void *, int, int), void *);
220 static int ega_load_font(void *, void *, struct wsdisplay_font
*);
222 void ega_doswitch(struct ega_config
*);
224 const struct wsdisplay_accessops ega_accessops
= {
234 ega_probe_col(bus_space_tag_t iot
, bus_space_tag_t memt
)
236 bus_space_handle_t memh
, ioh_6845
;
237 u_int16_t oldval
, val
;
239 if (bus_space_map(memt
, 0xb8000, 0x8000, 0, &memh
))
241 oldval
= bus_space_read_2(memt
, memh
, 0);
242 bus_space_write_2(memt
, memh
, 0, 0xa55a);
243 val
= bus_space_read_2(memt
, memh
, 0);
244 bus_space_write_2(memt
, memh
, 0, oldval
);
245 bus_space_unmap(memt
, memh
, 0x8000);
249 if (bus_space_map(iot
, 0x3d0, 0x10, 0, &ioh_6845
))
251 bus_space_unmap(iot
, ioh_6845
, 0x10);
257 ega_probe_mono(bus_space_tag_t iot
, bus_space_tag_t memt
)
259 bus_space_handle_t memh
, ioh_6845
;
260 u_int16_t oldval
, val
;
262 if (bus_space_map(memt
, 0xb0000, 0x8000, 0, &memh
))
264 oldval
= bus_space_read_2(memt
, memh
, 0);
265 bus_space_write_2(memt
, memh
, 0, 0xa55a);
266 val
= bus_space_read_2(memt
, memh
, 0);
267 bus_space_write_2(memt
, memh
, 0, oldval
);
268 bus_space_unmap(memt
, memh
, 0x8000);
272 if (bus_space_map(iot
, 0x3b0, 0x10, 0, &ioh_6845
))
274 bus_space_unmap(iot
, ioh_6845
, 0x10);
279 * We want at least ASCII 32..127 be present in the
282 #define vga_valid_primary_font(f) \
283 (f->encoding == WSDISPLAY_FONTENC_IBM || \
284 f->encoding == WSDISPLAY_FONTENC_ISO)
287 ega_selectfont(struct ega_config
*vc
, struct egascreen
*scr
, char *name1
, char *name2
)
288 /* name1, *name2: NULL: take first found */
290 const struct wsscreen_descr
*type
= scr
->pcs
.type
;
291 struct egafont
*f1
, *f2
;
296 for (i
= 0; i
< 4; i
++) {
297 struct egafont
*f
= vc
->vc_fonts
[i
];
298 if (!f
|| f
->height
!= type
->fontheight
)
301 vga_valid_primary_font(f
) &&
302 (!name1
|| !strcmp(name1
, f
->name
))) {
307 VGA_SCREEN_CANTWOFONTS(type
) &&
308 (!name2
|| !strcmp(name2
, f
->name
))) {
315 * The request fails if no primary font was found,
316 * or if a second font was requested but not found.
318 if (f1
&& (!name2
|| f2
)) {
320 if (scr
!= &ega_console_screen
|| ega_console_attached
) {
321 printf("ega (%s): font1=%s (slot %d)", type
->name
,
324 printf(", font2=%s (slot %d)",
337 ega_init_screen(struct ega_config
*vc
, struct egascreen
*scr
, const struct wsscreen_descr
*type
, int existing
, long *attrp
)
343 scr
->pcs
.hdl
= (struct pcdisplay_handle
*)&vc
->hdl
;
344 scr
->pcs
.type
= type
;
346 scr
->mindispoffset
= 0;
347 scr
->maxdispoffset
= 0x8000 - type
->nrows
* type
->ncols
* 2;
350 cpos
= vga_6845_read(&vc
->hdl
, cursorh
) << 8;
351 cpos
|= vga_6845_read(&vc
->hdl
, cursorl
);
353 /* make sure we have a valid cursor position */
354 if (cpos
< 0 || cpos
>= type
->nrows
* type
->ncols
)
357 scr
->pcs
.dispoffset
= vga_6845_read(&vc
->hdl
, startadrh
) << 9;
358 scr
->pcs
.dispoffset
|= vga_6845_read(&vc
->hdl
, startadrl
) << 1;
360 /* make sure we have a valid memory offset */
361 if (scr
->pcs
.dispoffset
< scr
->mindispoffset
||
362 scr
->pcs
.dispoffset
> scr
->maxdispoffset
)
363 scr
->pcs
.dispoffset
= scr
->mindispoffset
;
366 scr
->pcs
.dispoffset
= scr
->mindispoffset
;
369 scr
->pcs
.cursorrow
= cpos
/ type
->ncols
;
370 scr
->pcs
.cursorcol
= cpos
% type
->ncols
;
371 pcdisplay_cursor_init(&scr
->pcs
, existing
);
373 res
= ega_allocattr(scr
, 0, 0, 0, attrp
);
376 panic("ega_init_screen: attribute botch");
381 scr
->fontset1
= scr
->fontset2
= 0;
382 if (ega_selectfont(vc
, scr
, 0, 0)) {
383 if (scr
== &ega_console_screen
)
384 panic("ega_init_screen: no font");
386 printf("ega_init_screen: no font\n");
390 LIST_INSERT_HEAD(&vc
->screens
, scr
, next
);
394 ega_init(struct ega_config
*vc
, bus_space_tag_t iot
, bus_space_tag_t memt
, int mono
)
396 struct vga_handle
*vh
= &vc
->hdl
;
403 if (bus_space_map(vh
->vh_iot
, 0x3c0, 0x10, 0, &vh
->vh_ioh_vga
))
404 panic("ega_common_setup: couldn't map ega io");
406 if (bus_space_map(vh
->vh_iot
, (vh
->vh_mono
? 0x3b0 : 0x3d0), 0x10, 0,
408 panic("ega_common_setup: couldn't map 6845 io");
410 if (bus_space_map(vh
->vh_memt
, 0xa0000, 0x20000, 0, &vh
->vh_allmemh
))
411 panic("ega_common_setup: couldn't map memory");
413 if (bus_space_subregion(vh
->vh_memt
, vh
->vh_allmemh
,
414 (vh
->vh_mono
? 0x10000 : 0x18000), 0x8000,
416 panic("ega_common_setup: mem subrange failed");
419 LIST_INIT(&vc
->screens
);
421 vc
->currenttype
= vh
->vh_mono
? &ega_stdscreen_mono
: &ega_stdscreen
;
422 callout_init(&vc
->switch_callout
, 0);
424 vc
->vc_fonts
[0] = &ega_builtinfont
;
425 for (i
= 1; i
< 4; i
++)
428 vc
->currentfontset1
= vc
->currentfontset2
= 0;
432 ega_match(device_t parent
, cfdata_t match
, void *aux
)
434 struct isa_attach_args
*ia
= aux
;
440 if (ia
->ia_iomem
< 1)
449 if (ISA_DIRECT_CONFIG(ia
))
452 /* If values are hardwired to something that they can't be, punt. */
453 if ((ia
->ia_io
[0].ir_addr
!= ISA_UNKNOWN_PORT
&&
454 ia
->ia_io
[0].ir_addr
!= 0x3d0 &&
455 ia
->ia_io
[0].ir_addr
!= 0x3b0) ||
456 /* ia->ia_io[0].ir_size != 0 || XXX isa.c */
457 (ia
->ia_iomem
[0].ir_addr
!= ISA_UNKNOWN_IOMEM
&&
458 ia
->ia_iomem
[0].ir_addr
!= 0xb8000 &&
459 ia
->ia_iomem
[0].ir_addr
!= 0xb0000) ||
460 (ia
->ia_iomem
[0].ir_size
!= 0 &&
461 ia
->ia_iomem
[0].ir_size
!= 0x8000) ||
462 ia
->ia_irq
[0].ir_irq
!= ISA_UNKNOWN_IRQ
||
463 ia
->ia_drq
[0].ir_drq
!= ISA_UNKNOWN_DRQ
)
466 if (ega_is_console(ia
->ia_iot
))
467 mono
= ega_console_dc
.hdl
.vh_mono
;
468 else if (ia
->ia_io
[0].ir_addr
!= 0x3b0 &&
469 ia
->ia_iomem
[0].ir_addr
!= 0xb0000 &&
470 ega_probe_col(ia
->ia_iot
, ia
->ia_memt
))
472 else if (ia
->ia_io
[0].ir_addr
!= 0x3d0 &&
473 ia
->ia_iomem
[0].ir_addr
!= 0xb8000 &&
474 ega_probe_mono(ia
->ia_iot
, ia
->ia_memt
))
479 ia
->ia_io
[0].ir_addr
= mono
? 0x3b0 : 0x3d0;
480 ia
->ia_io
[0].ir_size
= 0x10;
481 ia
->ia_iomem
[0].ir_addr
= mono
? 0xb0000 : 0xb8000;
482 ia
->ia_iomem
[0].ir_size
= 0x8000;
483 return (2); /* beat pcdisplay */
487 ega_attach(device_t parent
, device_t self
, void *aux
)
489 struct isa_attach_args
*ia
= aux
;
490 struct ega_softc
*sc
= (struct ega_softc
*)self
;
492 struct ega_config
*dc
;
493 struct wsemuldisplaydev_attach_args aa
;
497 console
= ega_is_console(ia
->ia_iot
);
500 dc
= &ega_console_dc
;
502 ega_console_attached
= 1;
504 dc
= malloc(sizeof(struct ega_config
),
506 if (ia
->ia_io
[0].ir_addr
!= 0x3b0 &&
507 ia
->ia_iomem
[0].ir_addr
!= 0xb0000 &&
508 ega_probe_col(ia
->ia_iot
, ia
->ia_memt
))
509 ega_init(dc
, ia
->ia_iot
, ia
->ia_memt
, 0);
510 else if (ia
->ia_io
[0].ir_addr
!= 0x3d0 &&
511 ia
->ia_iomem
[0].ir_addr
!= 0xb8000 &&
512 ega_probe_mono(ia
->ia_iot
, ia
->ia_memt
))
513 ega_init(dc
, ia
->ia_iot
, ia
->ia_memt
, 1);
515 panic("ega_attach: display disappeared");
519 aa
.console
= console
;
520 aa
.scrdata
= &ega_screenlist
;
521 aa
.accessops
= &ega_accessops
;
522 aa
.accesscookie
= dc
;
524 config_found(self
, &aa
, wsemuldisplaydevprint
);
529 ega_cnattach(bus_space_tag_t iot
, bus_space_tag_t memt
)
533 const struct wsscreen_descr
*scr
;
535 if (ega_probe_col(iot
, memt
))
537 else if (ega_probe_mono(iot
, memt
))
542 ega_init(&ega_console_dc
, iot
, memt
, mono
);
543 scr
= ega_console_dc
.currenttype
;
544 ega_init_screen(&ega_console_dc
, &ega_console_screen
, scr
, 1, &defattr
);
546 ega_console_screen
.pcs
.active
= 1;
547 ega_console_dc
.active
= &ega_console_screen
;
549 wsdisplay_cnattach(scr
, &ega_console_screen
,
550 ega_console_screen
.pcs
.cursorcol
,
551 ega_console_screen
.pcs
.cursorrow
,
559 ega_is_console(bus_space_tag_t iot
)
562 !ega_console_attached
&&
563 iot
== ega_console_dc
.hdl
.vh_iot
)
569 ega_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
, struct proc
*p
)
572 * XXX "do something!"
574 return (EPASSTHROUGH
);
578 ega_mmap(void *v
, void *vs
, off_t offset
, int prot
)
584 ega_alloc_screen(void *v
, const struct wsscreen_descr
*type
, void **cookiep
, int *curxp
, int *curyp
, long *defattrp
)
586 struct ega_config
*vc
= v
;
587 struct egascreen
*scr
;
589 if (vc
->nscreens
== 1) {
591 * When allocating the second screen, get backing store
592 * for the first one too.
593 * XXX We could be more clever and use video RAM.
595 vc
->screens
.lh_first
->pcs
.mem
=
596 malloc(type
->ncols
* type
->nrows
* 2, M_DEVBUF
, M_WAITOK
);
599 scr
= malloc(sizeof(struct egascreen
), M_DEVBUF
, M_WAITOK
);
600 ega_init_screen(vc
, scr
, type
, vc
->nscreens
== 0, defattrp
);
602 if (vc
->nscreens
== 1) {
605 vc
->currenttype
= type
;
607 scr
->pcs
.mem
= malloc(type
->ncols
* type
->nrows
* 2,
609 pcdisplay_eraserows(&scr
->pcs
, 0, type
->nrows
, *defattrp
);
613 *curxp
= scr
->pcs
.cursorcol
;
614 *curyp
= scr
->pcs
.cursorrow
;
619 ega_free_screen(void *v
, void *cookie
)
621 struct egascreen
*vs
= cookie
;
622 struct ega_config
*vc
= vs
->cfg
;
624 LIST_REMOVE(vs
, next
);
625 if (vs
!= &ega_console_screen
)
628 panic("ega_free_screen: console");
630 if (vc
->active
== vs
)
635 ega_setfont(struct ega_config
*vc
, struct egascreen
*scr
)
637 int fontslot1
, fontslot2
;
639 fontslot1
= (scr
->fontset1
? scr
->fontset1
->slot
: 0);
640 fontslot2
= (scr
->fontset2
? scr
->fontset2
->slot
: fontslot1
);
641 if (vc
->currentfontset1
!= fontslot1
||
642 vc
->currentfontset2
!= fontslot2
) {
643 vga_setfontset(&vc
->hdl
, 2 * fontslot1
, 2 * fontslot2
);
644 vc
->currentfontset1
= fontslot1
;
645 vc
->currentfontset2
= fontslot2
;
650 ega_show_screen(void *v
, void *cookie
, int waitok
, void (*cb
)(void *, int, int), void *cbarg
)
652 struct egascreen
*scr
= cookie
, *oldscr
;
653 struct ega_config
*vc
= scr
->cfg
;
655 oldscr
= vc
->active
; /* can be NULL! */
660 vc
->wantedscreen
= cookie
;
662 vc
->switchcbarg
= cbarg
;
664 callout_reset(&vc
->switch_callout
, 0,
665 (void(*)(void *))ega_doswitch
);
674 ega_doswitch(struct ega_config
*vc
)
676 struct egascreen
*scr
, *oldscr
;
677 struct vga_handle
*vh
= &vc
->hdl
;
678 const struct wsscreen_descr
*type
;
680 scr
= vc
->wantedscreen
;
682 printf("ega_doswitch: disappeared\n");
683 (*vc
->switchcb
)(vc
->switchcbarg
, EIO
, 0);
686 type
= scr
->pcs
.type
;
687 oldscr
= vc
->active
; /* can be NULL! */
690 if (!oldscr
->pcs
.active
)
691 panic("ega_show_screen: not active");
692 if (oldscr
->pcs
.type
!= vc
->currenttype
)
693 panic("ega_show_screen: bad type");
701 panic("ega_show_screen: active");
705 const struct wsscreen_descr
*oldtype
= oldscr
->pcs
.type
;
707 oldscr
->pcs
.active
= 0;
708 bus_space_read_region_2(vh
->vh_memt
, vh
->vh_memh
,
709 oldscr
->pcs
.dispoffset
, oldscr
->pcs
.mem
,
710 oldtype
->ncols
* oldtype
->nrows
);
713 if (vc
->currenttype
!= type
) {
714 vga_setscreentype(vh
, type
);
715 vc
->currenttype
= type
;
718 ega_setfont(vc
, scr
);
719 /* XXX swich colours! */
721 scr
->pcs
.dispoffset
= scr
->mindispoffset
;
722 if (!oldscr
|| (scr
->pcs
.dispoffset
!= oldscr
->pcs
.dispoffset
)) {
723 vga_6845_write(vh
, startadrh
, scr
->pcs
.dispoffset
>> 9);
724 vga_6845_write(vh
, startadrl
, scr
->pcs
.dispoffset
>> 1);
727 bus_space_write_region_2(vh
->vh_memt
, vh
->vh_memh
,
728 scr
->pcs
.dispoffset
, scr
->pcs
.mem
,
729 type
->ncols
* type
->nrows
);
734 pcdisplay_cursor(&scr
->pcs
, scr
->pcs
.cursoron
,
735 scr
->pcs
.cursorrow
, scr
->pcs
.cursorcol
);
737 vc
->wantedscreen
= 0;
739 (*vc
->switchcb
)(vc
->switchcbarg
, 0, 0);
743 ega_load_font(void *v
, void *cookie
, struct wsdisplay_font
*data
)
745 struct ega_config
*vc
= v
;
746 struct egascreen
*scr
= cookie
;
752 name2
= strchr(data
->name
, ',');
755 res
= ega_selectfont(vc
, scr
, data
->name
, name2
);
757 ega_setfont(vc
, scr
);
761 if (data
->fontwidth
!= 8 || data
->stride
!= 1)
762 return (EINVAL
); /* XXX 1 byte per line */
763 if (data
->firstchar
!= 0 || data
->numchars
!= 256)
765 #ifndef WSCONS_SUPPORT_PCVTFONTS
766 if (data
->encoding
== WSDISPLAY_FONTENC_PCVT
) {
767 printf("vga: pcvt font support not built in, see vga(4)\n");
772 for (slot
= 0; slot
< 4; slot
++)
773 if (!vc
->vc_fonts
[slot
])
778 f
= malloc(sizeof(struct egafont
), M_DEVBUF
, M_WAITOK
);
779 strncpy(f
->name
, data
->name
, sizeof(f
->name
));
780 f
->height
= data
->fontheight
;
781 f
->encoding
= data
->encoding
;
783 f
->firstchar
= data
->firstchar
;
784 f
->numchars
= data
->numchars
;
787 printf("ega: load %s (8x%d, enc %d) font to slot %d\n", f
->name
,
788 f
->height
, f
->encoding
, slot
);
790 vga_loadchars(&vc
->hdl
, 2 * slot
, 0, 256, f
->height
, data
->data
);
792 vc
->vc_fonts
[slot
] = f
;
798 ega_allocattr(void *id
, int fg
, int bg
, int flags
, long *attrp
)
800 struct egascreen
*scr
= id
;
801 struct ega_config
*vc
= scr
->cfg
;
803 if (__predict_false((unsigned int)fg
>= sizeof(fgansitopc
) ||
804 (unsigned int)bg
>= sizeof(bgansitopc
)))
807 if (vc
->hdl
.vh_mono
) {
808 if (flags
& WSATTR_WSCOLORS
)
810 if (flags
& WSATTR_REVERSE
)
814 if (flags
& WSATTR_UNDERLINE
)
815 *attrp
|= FG_UNDERLINE
;
816 if (flags
& WSATTR_HILIT
)
817 *attrp
|= FG_INTENSE
;
819 if (flags
& (WSATTR_UNDERLINE
| WSATTR_REVERSE
))
821 if (flags
& WSATTR_WSCOLORS
)
822 *attrp
= fgansitopc
[fg
] | bgansitopc
[bg
];
825 if (flags
& WSATTR_HILIT
)
828 if (flags
& WSATTR_BLINK
)
834 ega_copyrows(void *id
, int srcrow
, int dstrow
, int nrows
)
836 struct egascreen
*scr
= id
;
837 bus_space_tag_t memt
= scr
->pcs
.hdl
->ph_memt
;
838 bus_space_handle_t memh
= scr
->pcs
.hdl
->ph_memh
;
839 int ncols
= scr
->pcs
.type
->ncols
;
840 bus_size_t srcoff
, dstoff
;
842 srcoff
= srcrow
* ncols
+ 0;
843 dstoff
= dstrow
* ncols
+ 0;
845 if (scr
->pcs
.active
) {
846 if (dstrow
== 0 && (srcrow
+ nrows
== scr
->pcs
.type
->nrows
)) {
847 #ifdef PCDISPLAY_SOFTCURSOR
848 int cursoron
= scr
->pcs
.cursoron
;
851 pcdisplay_cursor(&scr
->pcs
, 0,
852 scr
->pcs
.cursorrow
, scr
->pcs
.cursorcol
);
854 /* scroll up whole screen */
855 if ((scr
->pcs
.dispoffset
+ srcrow
* ncols
* 2)
856 <= scr
->maxdispoffset
) {
857 scr
->pcs
.dispoffset
+= srcrow
* ncols
* 2;
859 bus_space_copy_region_2(memt
, memh
,
860 scr
->pcs
.dispoffset
+ srcoff
* 2,
861 memh
, scr
->mindispoffset
,
863 scr
->pcs
.dispoffset
= scr
->mindispoffset
;
865 vga_6845_write(&scr
->cfg
->hdl
, startadrh
,
866 scr
->pcs
.dispoffset
>> 9);
867 vga_6845_write(&scr
->cfg
->hdl
, startadrl
,
868 scr
->pcs
.dispoffset
>> 1);
869 #ifdef PCDISPLAY_SOFTCURSOR
871 pcdisplay_cursor(&scr
->pcs
, 1,
872 scr
->pcs
.cursorrow
, scr
->pcs
.cursorcol
);
875 bus_space_copy_region_2(memt
, memh
,
876 scr
->pcs
.dispoffset
+ srcoff
* 2,
877 memh
, scr
->pcs
.dispoffset
+ dstoff
* 2,
881 memcpy(&scr
->pcs
.mem
[dstoff
], &scr
->pcs
.mem
[srcoff
],