Home | History | Annotate | Line # | Download | only in ic
vga.c revision 1.120
      1  1.120   thorpej /* $NetBSD: vga.c,v 1.120 2021/08/07 16:19:12 thorpej Exp $ */
      2    1.1  drochner 
      3    1.1  drochner /*
      4    1.1  drochner  * Copyright (c) 1995, 1996 Carnegie-Mellon University.
      5    1.1  drochner  * All rights reserved.
      6    1.1  drochner  *
      7    1.1  drochner  * Author: Chris G. Demetriou
      8   1.81     perry  *
      9    1.1  drochner  * Permission to use, copy, modify and distribute this software and
     10    1.1  drochner  * its documentation is hereby granted, provided that both the copyright
     11    1.1  drochner  * notice and this permission notice appear in all copies of the
     12    1.1  drochner  * software, derivative works or modified versions, and any portions
     13    1.1  drochner  * thereof, and that both notices appear in supporting documentation.
     14   1.81     perry  *
     15   1.81     perry  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     16   1.81     perry  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     17    1.1  drochner  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     18   1.81     perry  *
     19    1.1  drochner  * Carnegie Mellon requests users of this software to return to
     20    1.1  drochner  *
     21    1.1  drochner  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     22    1.1  drochner  *  School of Computer Science
     23    1.1  drochner  *  Carnegie Mellon University
     24    1.1  drochner  *  Pittsburgh PA 15213-3890
     25    1.1  drochner  *
     26    1.1  drochner  * any improvements or extensions that they make and grant Carnegie the
     27    1.1  drochner  * rights to redistribute these changes.
     28    1.1  drochner  */
     29   1.43     lukem 
     30   1.94       dsl #include <sys/cdefs.h>
     31  1.120   thorpej __KERNEL_RCSID(0, "$NetBSD: vga.c,v 1.120 2021/08/07 16:19:12 thorpej Exp $");
     32   1.94       dsl 
     33  1.112   mlelstv #include "opt_vga.h"
     34   1.87      jmmv /* for WSCONS_SUPPORT_PCVTFONTS */
     35   1.75      jmmv #include "opt_wsdisplay_compat.h"
     36   1.76      jmmv /* for WSDISPLAY_CUSTOM_BORDER */
     37   1.76      jmmv #include "opt_wsdisplay_border.h"
     38   1.75      jmmv /* for WSDISPLAY_CUSTOM_OUTPUT */
     39   1.75      jmmv #include "opt_wsmsgattrs.h"
     40   1.75      jmmv 
     41    1.1  drochner #include <sys/param.h>
     42    1.1  drochner #include <sys/systm.h>
     43   1.26   thorpej #include <sys/callout.h>
     44    1.1  drochner #include <sys/kernel.h>
     45    1.1  drochner #include <sys/device.h>
     46    1.1  drochner #include <sys/malloc.h>
     47    1.1  drochner #include <sys/queue.h>
     48   1.96        ad #include <sys/bus.h>
     49    1.1  drochner 
     50    1.4  drochner #include <dev/ic/mc6845reg.h>
     51    1.4  drochner #include <dev/ic/pcdisplayvar.h>
     52    1.4  drochner #include <dev/ic/vgareg.h>
     53    1.4  drochner #include <dev/ic/vgavar.h>
     54    1.4  drochner 
     55    1.1  drochner #include <dev/wscons/wsdisplayvar.h>
     56    1.1  drochner #include <dev/wscons/wsconsio.h>
     57   1.14  drochner #include <dev/wscons/unicode.h>
     58   1.37  drochner #include <dev/wsfont/wsfont.h>
     59    1.1  drochner 
     60    1.3  drochner #include <dev/ic/pcdisplay.h>
     61    1.1  drochner 
     62   1.68   tsutsui int vga_no_builtinfont = 0;
     63   1.68   tsutsui 
     64   1.37  drochner static struct wsdisplay_font _vga_builtinfont = {
     65   1.66   tsutsui 	"builtin",			/* typeface name */
     66   1.66   tsutsui 	0,				/* firstchar */
     67   1.66   tsutsui 	256,				/* numbers */
     68   1.66   tsutsui 	WSDISPLAY_FONTENC_IBM,		/* encoding */
     69   1.66   tsutsui 	8,				/* width */
     70   1.66   tsutsui 	16,				/* height */
     71   1.66   tsutsui 	1,				/* stride */
     72   1.66   tsutsui 	WSDISPLAY_FONTORDER_L2R,	/* bit order */
     73   1.66   tsutsui 	0,				/* byte order */
     74   1.66   tsutsui 	NULL				/* data */
     75   1.12  drochner };
     76   1.12  drochner 
     77   1.37  drochner struct egavga_font {
     78   1.37  drochner 	struct wsdisplay_font *wsfont;
     79   1.58  drochner 	int cookie; /* wsfont handle, -1 invalid */
     80   1.37  drochner 	int slot; /* in adapter RAM */
     81   1.37  drochner 	int usecount;
     82   1.37  drochner 	TAILQ_ENTRY(egavga_font) next; /* LRU queue */
     83   1.37  drochner };
     84   1.37  drochner 
     85   1.37  drochner static struct egavga_font vga_builtinfont = {
     86   1.89  christos 	.wsfont = &_vga_builtinfont,
     87   1.89  christos 	.cookie = -1,
     88   1.89  christos 	.slot = 0,
     89   1.37  drochner };
     90   1.37  drochner 
     91   1.38  drochner #ifdef VGA_CONSOLE_SCREENTYPE
     92   1.38  drochner static struct egavga_font vga_consolefont;
     93   1.38  drochner #endif
     94   1.38  drochner 
     95    1.1  drochner struct vgascreen {
     96    1.4  drochner 	struct pcdisplayscreen pcs;
     97    1.4  drochner 
     98    1.1  drochner 	LIST_ENTRY(vgascreen) next;
     99    1.1  drochner 
    100    1.1  drochner 	struct vga_config *cfg;
    101    1.1  drochner 
    102    1.1  drochner 	/* videostate */
    103   1.37  drochner 	struct egavga_font *fontset1, *fontset2;
    104    1.1  drochner 	/* font data */
    105    1.8  drochner 
    106    1.8  drochner 	int mindispoffset, maxdispoffset;
    107   1.72  christos 	int vga_rollover;
    108   1.72  christos 	int visibleoffset;
    109    1.1  drochner };
    110    1.1  drochner 
    111    1.1  drochner static int vgaconsole, vga_console_type, vga_console_attached;
    112    1.1  drochner static struct vgascreen vga_console_screen;
    113    1.1  drochner static struct vga_config vga_console_vc;
    114    1.1  drochner 
    115  1.110   mlelstv static struct egavga_font *egavga_getfont(struct vga_config *, struct vgascreen *,
    116   1.69  jdolecek 				   const char *, int);
    117  1.110   mlelstv static void egavga_unreffont(struct vga_config *, struct egavga_font *);
    118   1.37  drochner 
    119  1.110   mlelstv static int vga_selectfont(struct vga_config *, struct vgascreen *, const char *,
    120   1.69  jdolecek 				   const char *);
    121  1.110   mlelstv static void vga_init_screen(struct vga_config *, struct vgascreen *,
    122   1.45  junyoung 		     const struct wsscreen_descr *, int, long *);
    123  1.110   mlelstv static void vga_init(struct vga_config *, bus_space_tag_t, bus_space_tag_t);
    124   1.45  junyoung static void vga_setfont(struct vga_config *, struct vgascreen *);
    125   1.45  junyoung 
    126   1.45  junyoung static int vga_mapchar(void *, int, unsigned int *);
    127  1.110   mlelstv static void vga_putchar(void *, int, int, u_int, long);
    128   1.59  junyoung static int vga_allocattr(void *, int, int, int, long *);
    129   1.45  junyoung static void vga_copyrows(void *, int, int, int);
    130   1.74  christos #ifdef WSDISPLAY_SCROLLSUPPORT
    131  1.110   mlelstv static void vga_scroll (void *, void *, int);
    132   1.74  christos #endif
    133    1.1  drochner 
    134    1.1  drochner const struct wsdisplay_emulops vga_emulops = {
    135    1.4  drochner 	pcdisplay_cursor,
    136   1.12  drochner 	vga_mapchar,
    137   1.72  christos 	vga_putchar,
    138    1.4  drochner 	pcdisplay_copycols,
    139    1.4  drochner 	pcdisplay_erasecols,
    140    1.8  drochner 	vga_copyrows,
    141    1.4  drochner 	pcdisplay_eraserows,
    142   1.75      jmmv 	vga_allocattr,
    143   1.75      jmmv #ifdef WSDISPLAY_CUSTOM_OUTPUT
    144   1.75      jmmv 	pcdisplay_replaceattr,
    145   1.75      jmmv #else
    146   1.75      jmmv 	NULL,
    147   1.75      jmmv #endif
    148    1.3  drochner };
    149    1.3  drochner 
    150    1.3  drochner /*
    151    1.3  drochner  * translate WS(=ANSI) color codes to standard pc ones
    152    1.3  drochner  */
    153   1.35  jdolecek static const unsigned char fgansitopc[] = {
    154    1.3  drochner #ifdef __alpha__
    155    1.3  drochner 	/*
    156    1.3  drochner 	 * XXX DEC HAS SWITCHED THE CODES FOR BLUE AND RED!!!
    157    1.3  drochner 	 * XXX We should probably not bother with this
    158    1.3  drochner 	 * XXX (reinitialize the palette registers).
    159    1.3  drochner 	 */
    160    1.3  drochner 	FG_BLACK, FG_BLUE, FG_GREEN, FG_CYAN, FG_RED,
    161    1.3  drochner 	FG_MAGENTA, FG_BROWN, FG_LIGHTGREY
    162    1.3  drochner #else
    163    1.3  drochner 	FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
    164    1.3  drochner 	FG_MAGENTA, FG_CYAN, FG_LIGHTGREY
    165    1.3  drochner #endif
    166    1.3  drochner }, bgansitopc[] = {
    167    1.3  drochner #ifdef __alpha__
    168    1.3  drochner 	BG_BLACK, BG_BLUE, BG_GREEN, BG_CYAN, BG_RED,
    169    1.3  drochner 	BG_MAGENTA, BG_BROWN, BG_LIGHTGREY
    170    1.3  drochner #else
    171    1.3  drochner 	BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
    172    1.3  drochner 	BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
    173    1.3  drochner #endif
    174    1.1  drochner };
    175    1.1  drochner 
    176   1.33     lukem const struct wsscreen_descr vga_25lscreen = {
    177    1.1  drochner 	"80x25", 80, 25,
    178    1.1  drochner 	&vga_emulops,
    179    1.3  drochner 	8, 16,
    180   1.89  christos 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK,
    181   1.89  christos 	NULL,
    182   1.33     lukem }, vga_25lscreen_mono = {
    183    1.3  drochner 	"80x25", 80, 25,
    184    1.3  drochner 	&vga_emulops,
    185    1.3  drochner 	8, 16,
    186   1.89  christos 	WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE,
    187   1.89  christos 	NULL,
    188   1.33     lukem }, vga_25lscreen_bf = {
    189   1.12  drochner 	"80x25bf", 80, 25,
    190   1.12  drochner 	&vga_emulops,
    191   1.12  drochner 	8, 16,
    192   1.89  christos 	WSSCREEN_WSCOLORS | WSSCREEN_BLINK,
    193   1.89  christos 	NULL,
    194   1.17  drochner }, vga_40lscreen = {
    195   1.17  drochner 	"80x40", 80, 40,
    196   1.17  drochner 	&vga_emulops,
    197   1.17  drochner 	8, 10,
    198   1.89  christos 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK,
    199   1.89  christos 	NULL,
    200   1.17  drochner }, vga_40lscreen_mono = {
    201   1.17  drochner 	"80x40", 80, 40,
    202   1.17  drochner 	&vga_emulops,
    203   1.17  drochner 	8, 10,
    204   1.89  christos 	WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE,
    205   1.89  christos 	NULL,
    206   1.17  drochner }, vga_40lscreen_bf = {
    207   1.17  drochner 	"80x40bf", 80, 40,
    208   1.17  drochner 	&vga_emulops,
    209   1.17  drochner 	8, 10,
    210   1.89  christos 	WSSCREEN_WSCOLORS | WSSCREEN_BLINK,
    211   1.89  christos 	NULL,
    212   1.12  drochner }, vga_50lscreen = {
    213    1.1  drochner 	"80x50", 80, 50,
    214    1.1  drochner 	&vga_emulops,
    215    1.3  drochner 	8, 8,
    216   1.89  christos 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK,
    217   1.89  christos 	NULL,
    218    1.3  drochner }, vga_50lscreen_mono = {
    219    1.3  drochner 	"80x50", 80, 50,
    220    1.3  drochner 	&vga_emulops,
    221    1.3  drochner 	8, 8,
    222   1.89  christos 	WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE,
    223   1.89  christos 	NULL,
    224   1.12  drochner }, vga_50lscreen_bf = {
    225   1.12  drochner 	"80x50bf", 80, 50,
    226   1.12  drochner 	&vga_emulops,
    227   1.12  drochner 	8, 8,
    228   1.89  christos 	WSSCREEN_WSCOLORS | WSSCREEN_BLINK,
    229   1.89  christos 	NULL,
    230   1.30  drochner }, vga_24lscreen = {
    231   1.30  drochner 	"80x24", 80, 24,
    232   1.30  drochner 	&vga_emulops,
    233   1.30  drochner 	8, 16,
    234   1.89  christos 	WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_BLINK,
    235   1.89  christos 	NULL,
    236   1.30  drochner }, vga_24lscreen_mono = {
    237   1.30  drochner 	"80x24", 80, 24,
    238   1.30  drochner 	&vga_emulops,
    239   1.30  drochner 	8, 16,
    240   1.89  christos 	WSSCREEN_HILIT | WSSCREEN_UNDERLINE | WSSCREEN_BLINK | WSSCREEN_REVERSE,
    241   1.89  christos 	NULL,
    242   1.30  drochner }, vga_24lscreen_bf = {
    243   1.30  drochner 	"80x24bf", 80, 24,
    244   1.30  drochner 	&vga_emulops,
    245   1.30  drochner 	8, 16,
    246   1.89  christos 	WSSCREEN_WSCOLORS | WSSCREEN_BLINK,
    247   1.89  christos 	NULL,
    248    1.1  drochner };
    249    1.1  drochner 
    250   1.12  drochner #define VGA_SCREEN_CANTWOFONTS(type) (!((type)->capabilities & WSSCREEN_HILIT))
    251   1.12  drochner 
    252    1.2  drochner const struct wsscreen_descr *_vga_scrlist[] = {
    253   1.33     lukem 	&vga_25lscreen,
    254   1.33     lukem 	&vga_25lscreen_bf,
    255   1.17  drochner 	&vga_40lscreen,
    256   1.17  drochner 	&vga_40lscreen_bf,
    257    1.1  drochner 	&vga_50lscreen,
    258   1.12  drochner 	&vga_50lscreen_bf,
    259   1.30  drochner 	&vga_24lscreen,
    260   1.30  drochner 	&vga_24lscreen_bf,
    261    1.1  drochner 	/* XXX other formats, graphics screen? */
    262    1.3  drochner }, *_vga_scrlist_mono[] = {
    263   1.33     lukem 	&vga_25lscreen_mono,
    264   1.17  drochner 	&vga_40lscreen_mono,
    265    1.3  drochner 	&vga_50lscreen_mono,
    266   1.30  drochner 	&vga_24lscreen_mono,
    267    1.3  drochner 	/* XXX other formats, graphics screen? */
    268    1.1  drochner };
    269    1.1  drochner 
    270    1.3  drochner const struct wsscreen_list vga_screenlist = {
    271    1.3  drochner 	sizeof(_vga_scrlist) / sizeof(struct wsscreen_descr *),
    272    1.3  drochner 	_vga_scrlist
    273    1.3  drochner }, vga_screenlist_mono = {
    274    1.3  drochner 	sizeof(_vga_scrlist_mono) / sizeof(struct wsscreen_descr *),
    275    1.3  drochner 	_vga_scrlist_mono
    276    1.1  drochner };
    277    1.1  drochner 
    278   1.92  christos static int	vga_ioctl(void *, void *, u_long, void *, int, struct lwp *);
    279   1.86      jmmv static paddr_t	vga_mmap(void *, void *, off_t, int);
    280   1.45  junyoung static int	vga_alloc_screen(void *, const struct wsscreen_descr *,
    281   1.45  junyoung 				 void **, int *, int *, long *);
    282   1.45  junyoung static void	vga_free_screen(void *, void *);
    283   1.45  junyoung static int	vga_show_screen(void *, void *, int,
    284   1.45  junyoung 				void (*)(void *, int, int), void *);
    285   1.45  junyoung static int	vga_load_font(void *, void *, struct wsdisplay_font *);
    286   1.76      jmmv #ifdef WSDISPLAY_CUSTOM_BORDER
    287   1.85  drochner static int	vga_getborder(struct vga_config *, u_int *);
    288   1.85  drochner static int	vga_setborder(struct vga_config *, u_int);
    289   1.76      jmmv #endif /* WSDISPLAY_CUSTOM_BORDER */
    290    1.1  drochner 
    291  1.110   mlelstv static void vga_doswitch(struct vga_config *);
    292  1.110   mlelstv static void    vga_save_palette(struct vga_config *);
    293  1.110   mlelstv static void    vga_restore_palette(struct vga_config *);
    294  1.110   mlelstv 
    295   1.22  drochner 
    296    1.1  drochner const struct wsdisplay_accessops vga_accessops = {
    297    1.1  drochner 	vga_ioctl,
    298    1.1  drochner 	vga_mmap,
    299    1.1  drochner 	vga_alloc_screen,
    300    1.1  drochner 	vga_free_screen,
    301    1.1  drochner 	vga_show_screen,
    302   1.53  christos 	vga_load_font,
    303   1.53  christos 	NULL,
    304   1.73  christos #ifdef WSDISPLAY_SCROLLSUPPORT
    305   1.73  christos 	vga_scroll,
    306   1.73  christos #else
    307   1.73  christos 	NULL,
    308   1.73  christos #endif
    309    1.1  drochner };
    310    1.1  drochner 
    311   1.12  drochner /*
    312   1.15  drochner  * We want at least ASCII 32..127 be present in the
    313   1.15  drochner  * first font slot.
    314   1.12  drochner  */
    315   1.12  drochner #define vga_valid_primary_font(f) \
    316   1.37  drochner 	(f->wsfont->encoding == WSDISPLAY_FONTENC_IBM || \
    317   1.37  drochner 	f->wsfont->encoding == WSDISPLAY_FONTENC_ISO || \
    318  1.107  drochner 	f->wsfont->encoding == WSDISPLAY_FONTENC_ISO2 || \
    319  1.107  drochner 	f->wsfont->encoding == WSDISPLAY_FONTENC_ISO7 || \
    320  1.107  drochner 	f->wsfont->encoding == WSDISPLAY_FONTENC_KOI8_R)
    321   1.37  drochner 
    322  1.110   mlelstv static struct egavga_font *
    323   1.69  jdolecek egavga_getfont(struct vga_config *vc, struct vgascreen *scr, const char *name,
    324   1.45  junyoung 	       int primary)
    325   1.37  drochner {
    326   1.37  drochner 	struct egavga_font *f;
    327   1.37  drochner 	int cookie;
    328   1.37  drochner 	struct wsdisplay_font *wf;
    329   1.37  drochner 
    330   1.37  drochner 	TAILQ_FOREACH(f, &vc->vc_fontlist, next) {
    331   1.37  drochner 		if (wsfont_matches(f->wsfont, name,
    332  1.108  macallan 		    8, scr->pcs.type->fontheight, 0, WSFONT_FIND_BITMAP) &&
    333   1.37  drochner 		    (!primary || vga_valid_primary_font(f))) {
    334   1.37  drochner #ifdef VGAFONTDEBUG
    335   1.37  drochner 			if (scr != &vga_console_screen || vga_console_attached)
    336   1.37  drochner 				printf("vga_getfont: %s already present\n",
    337   1.66   tsutsui 				    name ? name : "<default>");
    338   1.37  drochner #endif
    339   1.37  drochner 			goto found;
    340   1.37  drochner 		}
    341   1.37  drochner 	}
    342   1.37  drochner 
    343   1.48        ad 	cookie = wsfont_find(name, 8, scr->pcs.type->fontheight, 0,
    344  1.108  macallan 	    WSDISPLAY_FONTORDER_L2R, 0, WSFONT_FIND_BITMAP);
    345   1.37  drochner 	/* XXX obey "primary" */
    346   1.37  drochner 	if (cookie == -1) {
    347   1.37  drochner #ifdef VGAFONTDEBUG
    348   1.37  drochner 		if (scr != &vga_console_screen || vga_console_attached)
    349   1.51  drochner 			printf("vga_getfont: %s not found\n",
    350   1.66   tsutsui 			    name ? name : "<default>");
    351   1.37  drochner #endif
    352   1.37  drochner 		return (0);
    353   1.37  drochner 	}
    354   1.37  drochner 
    355   1.47        ad 	if (wsfont_lock(cookie, &wf))
    356   1.37  drochner 		return (0);
    357   1.37  drochner 
    358   1.38  drochner #ifdef VGA_CONSOLE_SCREENTYPE
    359   1.38  drochner 	if (scr == &vga_console_screen)
    360   1.38  drochner 		f = &vga_consolefont;
    361   1.38  drochner 	else
    362   1.38  drochner #endif
    363  1.116       chs 	f = malloc(sizeof(struct egavga_font), M_DEVBUF, M_WAITOK);
    364   1.37  drochner 	f->wsfont = wf;
    365   1.37  drochner 	f->cookie = cookie;
    366   1.37  drochner 	f->slot = -1; /* not yet loaded */
    367   1.37  drochner 	f->usecount = 0; /* incremented below */
    368   1.37  drochner 	TAILQ_INSERT_TAIL(&vc->vc_fontlist, f, next);
    369   1.37  drochner 
    370   1.37  drochner found:
    371   1.37  drochner 	f->usecount++;
    372   1.37  drochner #ifdef VGAFONTDEBUG
    373   1.37  drochner 	if (scr != &vga_console_screen || vga_console_attached)
    374   1.37  drochner 		printf("vga_getfont: usecount=%d\n", f->usecount);
    375   1.37  drochner #endif
    376   1.37  drochner 	return (f);
    377   1.37  drochner }
    378   1.37  drochner 
    379  1.110   mlelstv static void
    380   1.45  junyoung egavga_unreffont(struct vga_config *vc, struct egavga_font *f)
    381   1.37  drochner {
    382   1.37  drochner 
    383   1.37  drochner 	f->usecount--;
    384   1.37  drochner #ifdef VGAFONTDEBUG
    385   1.37  drochner 	printf("vga_unreffont: usecount=%d\n", f->usecount);
    386   1.37  drochner #endif
    387   1.58  drochner 	if (f->usecount == 0 && f->cookie != -1) {
    388   1.37  drochner 		TAILQ_REMOVE(&vc->vc_fontlist, f, next);
    389   1.41  drochner 		if (f->slot != -1) {
    390   1.41  drochner 			KASSERT(vc->vc_fonts[f->slot] == f);
    391   1.41  drochner 			vc->vc_fonts[f->slot] = 0;
    392   1.41  drochner 		}
    393   1.37  drochner 		wsfont_unlock(f->cookie);
    394   1.38  drochner #ifdef VGA_CONSOLE_SCREENTYPE
    395   1.38  drochner 		if (f != &vga_consolefont)
    396   1.38  drochner #endif
    397   1.37  drochner 		free(f, M_DEVBUF);
    398   1.37  drochner 	}
    399   1.37  drochner }
    400   1.12  drochner 
    401  1.110   mlelstv static int
    402   1.69  jdolecek vga_selectfont(struct vga_config *vc, struct vgascreen *scr, const char *name1,
    403   1.69  jdolecek 	       const char *name2)
    404   1.12  drochner {
    405   1.12  drochner 	const struct wsscreen_descr *type = scr->pcs.type;
    406   1.37  drochner 	struct egavga_font *f1, *f2;
    407   1.12  drochner 
    408   1.37  drochner 	f1 = egavga_getfont(vc, scr, name1, 1);
    409   1.37  drochner 	if (!f1)
    410   1.37  drochner 		return (ENXIO);
    411   1.12  drochner 
    412   1.37  drochner 	if (VGA_SCREEN_CANTWOFONTS(type) && name2) {
    413   1.37  drochner 		f2 = egavga_getfont(vc, scr, name2, 0);
    414   1.37  drochner 		if (!f2) {
    415   1.37  drochner 			egavga_unreffont(vc, f1);
    416   1.37  drochner 			return (ENXIO);
    417   1.12  drochner 		}
    418   1.37  drochner 	} else
    419   1.37  drochner 		f2 = 0;
    420   1.12  drochner 
    421   1.12  drochner #ifdef VGAFONTDEBUG
    422   1.37  drochner 	if (scr != &vga_console_screen || vga_console_attached) {
    423   1.37  drochner 		printf("vga (%s): font1=%s (slot %d)", type->name,
    424   1.66   tsutsui 		    f1->wsfont->name, f1->slot);
    425   1.37  drochner 		if (f2)
    426   1.37  drochner 			printf(", font2=%s (slot %d)",
    427   1.66   tsutsui 			    f2->wsfont->name, f2->slot);
    428   1.37  drochner 		printf("\n");
    429   1.37  drochner 	}
    430   1.12  drochner #endif
    431   1.37  drochner 	if (scr->fontset1)
    432   1.37  drochner 		egavga_unreffont(vc, scr->fontset1);
    433   1.37  drochner 	scr->fontset1 = f1;
    434   1.37  drochner 	if (scr->fontset2)
    435   1.37  drochner 		egavga_unreffont(vc, scr->fontset2);
    436   1.37  drochner 	scr->fontset2 = f2;
    437   1.37  drochner 	return (0);
    438   1.12  drochner }
    439   1.12  drochner 
    440  1.110   mlelstv static void
    441   1.45  junyoung vga_init_screen(struct vga_config *vc, struct vgascreen *scr,
    442   1.45  junyoung 		const struct wsscreen_descr *type, int existing, long *attrp)
    443    1.1  drochner {
    444    1.8  drochner 	int cpos;
    445  1.111  christos 	int res __diagused;
    446    1.1  drochner 
    447    1.4  drochner 	scr->cfg = vc;
    448    1.4  drochner 	scr->pcs.hdl = (struct pcdisplay_handle *)&vc->hdl;
    449    1.4  drochner 	scr->pcs.type = type;
    450   1.39  drochner 	scr->pcs.active = existing;
    451    1.8  drochner 	scr->mindispoffset = 0;
    452   1.63  drochner 	if (vc->vc_quirks & VGA_QUIRK_NOFASTSCROLL)
    453   1.63  drochner 		scr->maxdispoffset = 0;
    454   1.63  drochner 	else
    455   1.63  drochner 		scr->maxdispoffset = 0x8000 - type->nrows * type->ncols * 2;
    456    1.1  drochner 
    457    1.1  drochner 	if (existing) {
    458   1.39  drochner 		vc->active = scr;
    459   1.39  drochner 
    460    1.1  drochner 		cpos = vga_6845_read(&vc->hdl, cursorh) << 8;
    461    1.1  drochner 		cpos |= vga_6845_read(&vc->hdl, cursorl);
    462    1.1  drochner 
    463    1.1  drochner 		/* make sure we have a valid cursor position */
    464    1.1  drochner 		if (cpos < 0 || cpos >= type->nrows * type->ncols)
    465    1.1  drochner 			cpos = 0;
    466    1.8  drochner 
    467    1.8  drochner 		scr->pcs.dispoffset = vga_6845_read(&vc->hdl, startadrh) << 9;
    468    1.8  drochner 		scr->pcs.dispoffset |= vga_6845_read(&vc->hdl, startadrl) << 1;
    469    1.8  drochner 
    470    1.8  drochner 		/* make sure we have a valid memory offset */
    471    1.8  drochner 		if (scr->pcs.dispoffset < scr->mindispoffset ||
    472    1.8  drochner 		    scr->pcs.dispoffset > scr->maxdispoffset)
    473    1.8  drochner 			scr->pcs.dispoffset = scr->mindispoffset;
    474   1.40  drochner 
    475   1.40  drochner 		if (type != vc->currenttype) {
    476   1.40  drochner 			vga_setscreentype(&vc->hdl, type);
    477   1.40  drochner 			vc->currenttype = type;
    478   1.40  drochner 		}
    479    1.8  drochner 	} else {
    480    1.8  drochner 		cpos = 0;
    481    1.8  drochner 		scr->pcs.dispoffset = scr->mindispoffset;
    482    1.1  drochner 	}
    483    1.1  drochner 
    484   1.72  christos 	scr->pcs.visibleoffset = scr->pcs.dispoffset;
    485   1.72  christos 	scr->vga_rollover = 0;
    486   1.72  christos 
    487   1.60  junyoung 	scr->pcs.cursorrow = cpos / type->ncols;
    488   1.60  junyoung 	scr->pcs.cursorcol = cpos % type->ncols;
    489   1.25        ad 	pcdisplay_cursor_init(&scr->pcs, existing);
    490    1.1  drochner 
    491    1.1  drochner #ifdef __alpha__
    492    1.4  drochner 	if (!vc->hdl.vh_mono)
    493    1.3  drochner 		/*
    494    1.3  drochner 		 * DEC firmware uses a blue background.
    495   1.75      jmmv 		 * XXX These should be specified as kernel options for
    496   1.75      jmmv 		 * XXX alpha only, not hardcoded here (which is wrong
    497   1.75      jmmv 		 * XXX anyway because the emulation layer will assume
    498   1.75      jmmv 		 * XXX the default attribute is white on black).
    499    1.3  drochner 		 */
    500   1.59  junyoung 		res = vga_allocattr(scr, WSCOL_WHITE, WSCOL_BLUE,
    501   1.66   tsutsui 		    WSATTR_WSCOLORS, attrp);
    502    1.3  drochner 	else
    503    1.3  drochner #endif
    504   1.59  junyoung 	res = vga_allocattr(scr, 0, 0, 0, attrp);
    505    1.3  drochner #ifdef DIAGNOSTIC
    506    1.3  drochner 	if (res)
    507    1.3  drochner 		panic("vga_init_screen: attribute botch");
    508    1.1  drochner #endif
    509    1.1  drochner 
    510    1.4  drochner 	scr->pcs.mem = NULL;
    511   1.15  drochner 
    512   1.15  drochner 	scr->fontset1 = scr->fontset2 = 0;
    513   1.12  drochner 	if (vga_selectfont(vc, scr, 0, 0)) {
    514   1.12  drochner 		if (scr == &vga_console_screen)
    515   1.12  drochner 			panic("vga_init_screen: no font");
    516   1.12  drochner 		else
    517   1.12  drochner 			printf("vga_init_screen: no font\n");
    518   1.12  drochner 	}
    519   1.40  drochner 	if (existing)
    520   1.40  drochner 		vga_setfont(vc, scr);
    521   1.15  drochner 
    522    1.1  drochner 	vc->nscreens++;
    523    1.1  drochner 	LIST_INSERT_HEAD(&vc->screens, scr, next);
    524    1.1  drochner }
    525    1.1  drochner 
    526  1.110   mlelstv static void
    527   1.45  junyoung vga_init(struct vga_config *vc, bus_space_tag_t iot, bus_space_tag_t memt)
    528    1.1  drochner {
    529    1.1  drochner 	struct vga_handle *vh = &vc->hdl;
    530  1.106  christos 	uint8_t mor;
    531   1.12  drochner 	int i;
    532    1.1  drochner 
    533   1.66   tsutsui 	vh->vh_iot = iot;
    534   1.66   tsutsui 	vh->vh_memt = memt;
    535    1.1  drochner 
    536   1.66   tsutsui 	if (bus_space_map(vh->vh_iot, 0x3c0, 0x10, 0, &vh->vh_ioh_vga))
    537   1.66   tsutsui 		panic("vga_init: couldn't map vga io");
    538    1.1  drochner 
    539    1.1  drochner 	/* read "misc output register" */
    540  1.106  christos 	mor = vga_raw_read(vh, VGA_MISC_DATAR);
    541    1.4  drochner 	vh->vh_mono = !(mor & 1);
    542    1.1  drochner 
    543    1.4  drochner 	if (bus_space_map(vh->vh_iot, (vh->vh_mono ? 0x3b0 : 0x3d0), 0x10, 0,
    544   1.66   tsutsui 	    &vh->vh_ioh_6845))
    545   1.66   tsutsui 		panic("vga_init: couldn't map 6845 io");
    546    1.1  drochner 
    547  1.117        ad 	if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000,
    548  1.118        ad 	    BUS_SPACE_MAP_CACHEABLE, &vh->vh_allmemh))
    549   1.66   tsutsui 		panic("vga_init: couldn't map memory");
    550    1.1  drochner 
    551   1.66   tsutsui 	if (bus_space_subregion(vh->vh_memt, vh->vh_allmemh,
    552   1.66   tsutsui 	    (vh->vh_mono ? 0x10000 : 0x18000), 0x8000, &vh->vh_memh))
    553   1.66   tsutsui 		panic("vga_init: mem subrange failed");
    554    1.5  drochner 
    555    1.1  drochner 	vc->nscreens = 0;
    556    1.1  drochner 	LIST_INIT(&vc->screens);
    557    1.1  drochner 	vc->active = NULL;
    558   1.34  drochner 	vc->currenttype = vh->vh_mono ? &vga_25lscreen_mono : &vga_25lscreen;
    559   1.93        ad 	callout_init(&vc->vc_switch_callout, 0);
    560   1.12  drochner 
    561   1.68   tsutsui 	wsfont_init();
    562   1.68   tsutsui 	if (vga_no_builtinfont) {
    563   1.68   tsutsui 		struct wsdisplay_font *wf;
    564   1.68   tsutsui 		int cookie;
    565   1.68   tsutsui 
    566   1.68   tsutsui 		cookie = wsfont_find(NULL, 8, 16, 0,
    567  1.108  macallan 		     WSDISPLAY_FONTORDER_L2R, 0, WSFONT_FIND_BITMAP);
    568   1.68   tsutsui 		if (cookie == -1 || wsfont_lock(cookie, &wf))
    569   1.68   tsutsui 			panic("vga_init: can't load console font");
    570   1.68   tsutsui 		vga_loadchars(&vc->hdl, 0, wf->firstchar, wf->numchars,
    571   1.68   tsutsui 		    wf->fontheight, wf->data);
    572   1.68   tsutsui 		vga_builtinfont.wsfont = wf;
    573   1.68   tsutsui 		vga_builtinfont.cookie = cookie;
    574   1.68   tsutsui 		vga_builtinfont.slot = 0;
    575   1.68   tsutsui 	}
    576   1.12  drochner 	vc->vc_fonts[0] = &vga_builtinfont;
    577   1.23  drochner 	for (i = 1; i < 8; i++)
    578   1.12  drochner 		vc->vc_fonts[i] = 0;
    579   1.37  drochner 	TAILQ_INIT(&vc->vc_fontlist);
    580   1.37  drochner 	TAILQ_INSERT_HEAD(&vc->vc_fontlist, &vga_builtinfont, next);
    581   1.12  drochner 
    582   1.12  drochner 	vc->currentfontset1 = vc->currentfontset2 = 0;
    583   1.76      jmmv 
    584   1.78      jmmv 	if (!vh->vh_mono && (u_int)WSDISPLAY_BORDER_COLOR < sizeof(fgansitopc))
    585   1.78      jmmv 		_vga_attr_write(vh, VGA_ATC_OVERSCAN,
    586   1.78      jmmv 		                fgansitopc[WSDISPLAY_BORDER_COLOR]);
    587  1.106  christos 	vga_save_palette(vc);
    588    1.1  drochner }
    589    1.1  drochner 
    590    1.1  drochner void
    591   1.45  junyoung vga_common_attach(struct vga_softc *sc, bus_space_tag_t iot,
    592   1.56  drochner 		  bus_space_tag_t memt, int type, int quirks,
    593   1.56  drochner 		  const struct vga_funcs *vf)
    594   1.28      soda {
    595    1.1  drochner 	int console;
    596    1.1  drochner 	struct vga_config *vc;
    597    1.1  drochner 	struct wsemuldisplaydev_attach_args aa;
    598    1.1  drochner 
    599    1.1  drochner 	console = vga_is_console(iot, type);
    600    1.1  drochner 
    601    1.1  drochner 	if (console) {
    602    1.1  drochner 		vc = &vga_console_vc;
    603    1.1  drochner 		vga_console_attached = 1;
    604    1.1  drochner 	} else {
    605    1.1  drochner 		vc = malloc(sizeof(struct vga_config), M_DEVBUF, M_WAITOK);
    606    1.1  drochner 		vga_init(vc, iot, memt);
    607    1.1  drochner 	}
    608    1.1  drochner 
    609   1.58  drochner 	if (quirks & VGA_QUIRK_ONEFONT) {
    610   1.58  drochner 		vc->vc_nfontslots = 1;
    611   1.58  drochner #ifndef VGA_CONSOLE_ATI_BROKEN_FONTSEL
    612   1.58  drochner 		/*
    613   1.58  drochner 		 * XXX maybe invalidate font in slot > 0, but this can
    614   1.58  drochner 		 * only be happen with VGA_CONSOLE_SCREENTYPE, and then
    615   1.58  drochner 		 * we require VGA_CONSOLE_ATI_BROKEN_FONTSEL anyway.
    616   1.58  drochner 		 */
    617   1.58  drochner #endif
    618   1.58  drochner 	} else {
    619   1.58  drochner 		vc->vc_nfontslots = 8;
    620   1.58  drochner #ifndef VGA_CONSOLE_ATI_BROKEN_FONTSEL
    621   1.58  drochner 		/*
    622   1.58  drochner 		 * XXX maybe validate builtin font shifted to slot 1 if
    623   1.58  drochner 		 * slot 0 got overwritten because of VGA_CONSOLE_SCREENTYPE,
    624   1.58  drochner 		 * but it will be reloaded anyway if needed.
    625   1.58  drochner 		 */
    626   1.58  drochner #endif
    627   1.58  drochner 	}
    628   1.58  drochner 
    629   1.58  drochner 	/*
    630   1.58  drochner 	 * Save the builtin font to memory. In case it got overwritten
    631   1.58  drochner 	 * in console initialization, use the copy in slot 1.
    632   1.58  drochner 	 */
    633   1.58  drochner #ifdef VGA_CONSOLE_ATI_BROKEN_FONTSEL
    634   1.58  drochner #define BUILTINFONTLOC (vga_builtinfont.slot == -1 ? 1 : 0)
    635   1.58  drochner #else
    636   1.58  drochner 	KASSERT(vga_builtinfont.slot == 0);
    637   1.58  drochner #define BUILTINFONTLOC (0)
    638   1.58  drochner #endif
    639   1.68   tsutsui 	if (!vga_no_builtinfont) {
    640   1.69  jdolecek 		char *data =
    641   1.68   tsutsui 		    malloc(256 * vga_builtinfont.wsfont->fontheight,
    642   1.68   tsutsui 		    M_DEVBUF, M_WAITOK);
    643   1.68   tsutsui 		vga_readoutchars(&vc->hdl, BUILTINFONTLOC, 0, 256,
    644   1.69  jdolecek 		    vga_builtinfont.wsfont->fontheight, data);
    645   1.69  jdolecek 		vga_builtinfont.wsfont->data = data;
    646   1.68   tsutsui 	}
    647   1.56  drochner 
    648   1.42   thorpej 	vc->vc_type = type;
    649   1.42   thorpej 	vc->vc_funcs = vf;
    650   1.63  drochner 	vc->vc_quirks = quirks;
    651   1.42   thorpej 
    652   1.42   thorpej 	sc->sc_vc = vc;
    653   1.42   thorpej 	vc->softc = sc;
    654   1.28      soda 
    655    1.1  drochner 	aa.console = console;
    656    1.4  drochner 	aa.scrdata = (vc->hdl.vh_mono ? &vga_screenlist_mono : &vga_screenlist);
    657    1.1  drochner 	aa.accessops = &vga_accessops;
    658    1.1  drochner 	aa.accesscookie = vc;
    659    1.1  drochner 
    660  1.119   thorpej 	config_found(sc->sc_dev, &aa, wsemuldisplaydevprint,
    661  1.120   thorpej 	    CFARGS(.iattr = "wsemuldisplaydev"));
    662    1.1  drochner }
    663    1.1  drochner 
    664    1.1  drochner int
    665   1.45  junyoung vga_cnattach(bus_space_tag_t iot, bus_space_tag_t memt, int type, int check)
    666    1.1  drochner {
    667    1.3  drochner 	long defattr;
    668    1.3  drochner 	const struct wsscreen_descr *scr;
    669    1.3  drochner 
    670    1.1  drochner 	if (check && !vga_common_probe(iot, memt))
    671    1.1  drochner 		return (ENXIO);
    672    1.1  drochner 
    673    1.1  drochner 	/* set up bus-independent VGA configuration */
    674    1.1  drochner 	vga_init(&vga_console_vc, iot, memt);
    675   1.34  drochner #ifdef VGA_CONSOLE_SCREENTYPE
    676   1.34  drochner 	scr = wsdisplay_screentype_pick(vga_console_vc.hdl.vh_mono ?
    677   1.66   tsutsui 	    &vga_screenlist_mono : &vga_screenlist, VGA_CONSOLE_SCREENTYPE);
    678   1.34  drochner 	if (!scr)
    679   1.34  drochner 		panic("vga_cnattach: invalid screen type");
    680   1.34  drochner #else
    681   1.11  drochner 	scr = vga_console_vc.currenttype;
    682   1.34  drochner #endif
    683   1.56  drochner #ifdef VGA_CONSOLE_ATI_BROKEN_FONTSEL
    684   1.56  drochner 	/*
    685   1.56  drochner 	 * On some (most/all?) ATI cards, only font slot 0 is usable.
    686   1.56  drochner 	 * vga_init_screen() might need font slot 0 for a non-default
    687   1.58  drochner 	 * console font, so save the builtin VGA font to another font slot.
    688   1.58  drochner 	 * The attach() code will take care later.
    689   1.56  drochner 	 */
    690   1.63  drochner 	vga_console_vc.vc_quirks |= VGA_QUIRK_ONEFONT; /* redundant */
    691   1.56  drochner 	vga_copyfont01(&vga_console_vc.hdl);
    692   1.56  drochner 	vga_console_vc.vc_nfontslots = 1;
    693   1.56  drochner #else
    694   1.56  drochner 	vga_console_vc.vc_nfontslots = 8;
    695   1.56  drochner #endif
    696   1.79  christos #ifdef notdef
    697   1.63  drochner 	/* until we know better, assume "fast scrolling" does not work */
    698   1.63  drochner 	vga_console_vc.vc_quirks |= VGA_QUIRK_NOFASTSCROLL;
    699   1.79  christos #endif
    700   1.63  drochner 
    701    1.4  drochner 	vga_init_screen(&vga_console_vc, &vga_console_screen, scr, 1, &defattr);
    702    1.1  drochner 
    703    1.3  drochner 	wsdisplay_cnattach(scr, &vga_console_screen,
    704   1.66   tsutsui 	    vga_console_screen.pcs.cursorcol,
    705   1.66   tsutsui 	    vga_console_screen.pcs.cursorrow, defattr);
    706    1.1  drochner 
    707    1.1  drochner 	vgaconsole = 1;
    708    1.1  drochner 	vga_console_type = type;
    709    1.1  drochner 	return (0);
    710    1.1  drochner }
    711    1.1  drochner 
    712    1.1  drochner int
    713   1.88  jmcneill vga_cndetach(void)
    714   1.88  jmcneill {
    715   1.88  jmcneill 	struct vga_config *vc;
    716   1.88  jmcneill 	struct vga_handle *vh;
    717   1.88  jmcneill 
    718   1.88  jmcneill 	vc = &vga_console_vc;
    719   1.88  jmcneill 	vh = &vc->hdl;
    720   1.88  jmcneill 
    721   1.88  jmcneill 	if (vgaconsole) {
    722  1.112   mlelstv 		wsdisplay_cndetach();
    723  1.112   mlelstv 
    724   1.88  jmcneill 		bus_space_unmap(vh->vh_iot, vh->vh_ioh_vga, 0x10);
    725   1.88  jmcneill 		bus_space_unmap(vh->vh_iot, vh->vh_ioh_6845, 0x10);
    726  1.115   mlelstv 		bus_space_unmap(vh->vh_memt, vh->vh_allmemh, 0x20000);
    727   1.88  jmcneill 
    728  1.112   mlelstv 		vga_console_attached = 0;
    729  1.112   mlelstv 		vgaconsole = 0;
    730  1.112   mlelstv 
    731   1.88  jmcneill 		return 1;
    732   1.88  jmcneill 	}
    733   1.88  jmcneill 
    734   1.88  jmcneill 	return 0;
    735   1.88  jmcneill }
    736   1.88  jmcneill 
    737   1.88  jmcneill int
    738   1.45  junyoung vga_is_console(bus_space_tag_t iot, int type)
    739    1.1  drochner {
    740    1.1  drochner 	if (vgaconsole &&
    741    1.1  drochner 	    !vga_console_attached &&
    742  1.104    dyoung 	    bus_space_is_equal(iot, vga_console_vc.hdl.vh_iot) &&
    743    1.1  drochner 	    (vga_console_type == -1 || (type == vga_console_type)))
    744    1.1  drochner 		return (1);
    745    1.1  drochner 	return (0);
    746    1.1  drochner }
    747    1.1  drochner 
    748   1.46     lukem static int
    749   1.46     lukem vga_get_video(struct vga_config *vc)
    750   1.46     lukem {
    751   1.67   tsutsui 
    752   1.67   tsutsui 	return (vga_ts_read(&vc->hdl, mode) & VGA_TS_MODE_BLANK) == 0;
    753   1.46     lukem }
    754   1.46     lukem 
    755   1.46     lukem static void
    756   1.46     lukem vga_set_video(struct vga_config *vc, int state)
    757   1.46     lukem {
    758   1.46     lukem 	int val;
    759   1.46     lukem 
    760   1.46     lukem 	vga_ts_write(&vc->hdl, syncreset, 0x01);
    761   1.46     lukem 	if (state) {					/* unblank screen */
    762   1.46     lukem 		val = vga_ts_read(&vc->hdl, mode);
    763   1.67   tsutsui 		vga_ts_write(&vc->hdl, mode, val & ~VGA_TS_MODE_BLANK);
    764   1.46     lukem #ifndef VGA_NO_VBLANK
    765   1.46     lukem 		val = vga_6845_read(&vc->hdl, mode);
    766   1.46     lukem 		vga_6845_write(&vc->hdl, mode, val | 0x80);
    767   1.46     lukem #endif
    768   1.46     lukem 	} else {					/* blank screen */
    769   1.46     lukem 		val = vga_ts_read(&vc->hdl, mode);
    770   1.67   tsutsui 		vga_ts_write(&vc->hdl, mode, val | VGA_TS_MODE_BLANK);
    771   1.46     lukem #ifndef VGA_NO_VBLANK
    772   1.46     lukem 		val = vga_6845_read(&vc->hdl, mode);
    773   1.46     lukem 		vga_6845_write(&vc->hdl, mode, val & ~0x80);
    774   1.46     lukem #endif
    775   1.46     lukem 	}
    776   1.46     lukem 	vga_ts_write(&vc->hdl, syncreset, 0x03);
    777   1.46     lukem }
    778   1.46     lukem 
    779  1.110   mlelstv static int
    780   1.92  christos vga_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
    781    1.1  drochner {
    782    1.1  drochner 	struct vga_config *vc = v;
    783   1.87      jmmv 	struct vgascreen *scr = vs;
    784   1.42   thorpej 	const struct vga_funcs *vf = vc->vc_funcs;
    785    1.1  drochner 
    786    1.1  drochner 	switch (cmd) {
    787  1.106  christos 	case WSDISPLAYIO_SMODE:
    788  1.106  christos 		if (*(u_int *)data == WSDISPLAYIO_MODE_EMUL)
    789  1.106  christos 			vga_restore_palette(vc);
    790  1.106  christos 		return 0;
    791  1.106  christos 
    792    1.1  drochner 	case WSDISPLAYIO_GTYPE:
    793    1.1  drochner 		*(int *)data = vc->vc_type;
    794   1.10  augustss 		return 0;
    795   1.12  drochner 
    796    1.1  drochner 	case WSDISPLAYIO_GINFO:
    797   1.42   thorpej 		/* XXX should get detailed hardware information here */
    798   1.49    atatat 		return EPASSTHROUGH;
    799   1.42   thorpej 
    800   1.46     lukem 	case WSDISPLAYIO_GVIDEO:
    801   1.66   tsutsui 		*(int *)data = (vga_get_video(vc) ?
    802   1.66   tsutsui 		    WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF);
    803   1.46     lukem 		return 0;
    804   1.46     lukem 
    805   1.46     lukem 	case WSDISPLAYIO_SVIDEO:
    806   1.46     lukem 		vga_set_video(vc, *(int *)data == WSDISPLAYIO_VIDEO_ON);
    807   1.46     lukem 		return 0;
    808   1.46     lukem 
    809   1.87      jmmv 	case WSDISPLAYIO_GETWSCHAR:
    810   1.87      jmmv 		KASSERT(scr != NULL);
    811   1.87      jmmv 		return pcdisplay_getwschar(&scr->pcs,
    812   1.87      jmmv 		    (struct wsdisplay_char *)data);
    813   1.87      jmmv 
    814   1.87      jmmv 	case WSDISPLAYIO_PUTWSCHAR:
    815   1.87      jmmv 		KASSERT(scr != NULL);
    816   1.87      jmmv 		return pcdisplay_putwschar(&scr->pcs,
    817   1.87      jmmv 		    (struct wsdisplay_char *)data);
    818   1.87      jmmv 
    819   1.85  drochner #ifdef WSDISPLAY_CUSTOM_BORDER
    820   1.85  drochner 	case WSDISPLAYIO_GBORDER:
    821   1.85  drochner 		return (vga_getborder(vc, (u_int *)data));
    822   1.85  drochner 
    823   1.85  drochner 	case WSDISPLAYIO_SBORDER:
    824   1.85  drochner 		return (vga_setborder(vc, *(u_int *)data));
    825   1.85  drochner #endif
    826   1.85  drochner 
    827    1.1  drochner 	case WSDISPLAYIO_GETCMAP:
    828    1.1  drochner 	case WSDISPLAYIO_PUTCMAP:
    829    1.1  drochner 	case WSDISPLAYIO_GCURPOS:
    830    1.1  drochner 	case WSDISPLAYIO_SCURPOS:
    831    1.1  drochner 	case WSDISPLAYIO_GCURMAX:
    832    1.1  drochner 	case WSDISPLAYIO_GCURSOR:
    833    1.1  drochner 	case WSDISPLAYIO_SCURSOR:
    834    1.1  drochner 		/* NONE of these operations are by the generic VGA driver. */
    835   1.49    atatat 		return EPASSTHROUGH;
    836    1.1  drochner 	}
    837   1.12  drochner 
    838   1.42   thorpej 	if (vc->vc_funcs == NULL)
    839   1.49    atatat 		return (EPASSTHROUGH);
    840   1.42   thorpej 
    841   1.42   thorpej 	if (vf->vf_ioctl == NULL)
    842   1.49    atatat 		return (EPASSTHROUGH);
    843   1.42   thorpej 
    844   1.83  christos 	return ((*vf->vf_ioctl)(v, cmd, data, flag, l));
    845    1.1  drochner }
    846    1.1  drochner 
    847   1.29    simonb static paddr_t
    848   1.91  christos vga_mmap(void *v, void *vs, off_t offset, int prot)
    849    1.1  drochner {
    850   1.42   thorpej 	struct vga_config *vc = v;
    851   1.42   thorpej 	const struct vga_funcs *vf = vc->vc_funcs;
    852    1.1  drochner 
    853   1.42   thorpej 	if (vc->vc_funcs == NULL)
    854   1.42   thorpej 		return (-1);
    855   1.28      soda 
    856   1.42   thorpej 	if (vf->vf_mmap == NULL)
    857   1.42   thorpej 		return (-1);
    858   1.32   thorpej 
    859   1.42   thorpej 	return ((*vf->vf_mmap)(v, offset, prot));
    860    1.1  drochner }
    861    1.1  drochner 
    862  1.110   mlelstv static int
    863   1.45  junyoung vga_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
    864   1.45  junyoung 		 int *curxp, int *curyp, long *defattrp)
    865    1.1  drochner {
    866    1.1  drochner 	struct vga_config *vc = v;
    867    1.1  drochner 	struct vgascreen *scr;
    868    1.1  drochner 
    869    1.1  drochner 	if (vc->nscreens == 1) {
    870   1.38  drochner 		struct vgascreen *scr1 = vc->screens.lh_first;
    871    1.1  drochner 		/*
    872    1.1  drochner 		 * When allocating the second screen, get backing store
    873    1.1  drochner 		 * for the first one too.
    874    1.1  drochner 		 * XXX We could be more clever and use video RAM.
    875    1.1  drochner 		 */
    876   1.38  drochner 		scr1->pcs.mem =
    877   1.66   tsutsui 		    malloc(scr1->pcs.type->ncols * scr1->pcs.type->nrows * 2,
    878   1.66   tsutsui 		    M_DEVBUF, M_WAITOK);
    879    1.1  drochner 	}
    880    1.1  drochner 
    881    1.1  drochner 	scr = malloc(sizeof(struct vgascreen), M_DEVBUF, M_WAITOK);
    882    1.4  drochner 	vga_init_screen(vc, scr, type, vc->nscreens == 0, defattrp);
    883    1.1  drochner 
    884   1.39  drochner 	if (vc->nscreens > 1) {
    885    1.4  drochner 		scr->pcs.mem = malloc(type->ncols * type->nrows * 2,
    886   1.66   tsutsui 		    M_DEVBUF, M_WAITOK);
    887    1.4  drochner 		pcdisplay_eraserows(&scr->pcs, 0, type->nrows, *defattrp);
    888    1.1  drochner 	}
    889    1.1  drochner 
    890    1.1  drochner 	*cookiep = scr;
    891   1.60  junyoung 	*curxp = scr->pcs.cursorcol;
    892   1.60  junyoung 	*curyp = scr->pcs.cursorrow;
    893    1.1  drochner 
    894    1.1  drochner 	return (0);
    895    1.1  drochner }
    896    1.1  drochner 
    897  1.110   mlelstv static void
    898   1.91  christos vga_free_screen(void *v, void *cookie)
    899    1.1  drochner {
    900    1.1  drochner 	struct vgascreen *vs = cookie;
    901   1.11  drochner 	struct vga_config *vc = vs->cfg;
    902    1.1  drochner 
    903    1.1  drochner 	LIST_REMOVE(vs, next);
    904   1.82       dbj 	vc->nscreens--;
    905   1.38  drochner 	if (vs->fontset1)
    906   1.38  drochner 		egavga_unreffont(vc, vs->fontset1);
    907   1.38  drochner 	if (vs->fontset2)
    908   1.38  drochner 		egavga_unreffont(vc, vs->fontset2);
    909   1.38  drochner 
    910    1.1  drochner 	if (vs != &vga_console_screen)
    911    1.1  drochner 		free(vs, M_DEVBUF);
    912    1.1  drochner 	else
    913    1.1  drochner 		panic("vga_free_screen: console");
    914   1.11  drochner 
    915   1.11  drochner 	if (vc->active == vs)
    916   1.11  drochner 		vc->active = 0;
    917    1.1  drochner }
    918    1.1  drochner 
    919   1.40  drochner static void vga_usefont(struct vga_config *, struct egavga_font *);
    920   1.37  drochner 
    921   1.40  drochner static void
    922   1.45  junyoung vga_usefont(struct vga_config *vc, struct egavga_font *f)
    923   1.37  drochner {
    924   1.37  drochner 	int slot;
    925   1.37  drochner 	struct egavga_font *of;
    926   1.37  drochner 
    927   1.37  drochner 	if (f->slot != -1)
    928   1.37  drochner 		goto toend;
    929   1.37  drochner 
    930   1.51  drochner 	for (slot = 0; slot < vc->vc_nfontslots; slot++) {
    931   1.37  drochner 		if (!vc->vc_fonts[slot])
    932   1.37  drochner 			goto loadit;
    933   1.37  drochner 	}
    934   1.37  drochner 
    935   1.37  drochner 	/* have to kick out another one */
    936   1.37  drochner 	TAILQ_FOREACH(of, &vc->vc_fontlist, next) {
    937   1.37  drochner 		if (of->slot != -1) {
    938   1.37  drochner 			KASSERT(vc->vc_fonts[of->slot] == of);
    939   1.37  drochner 			slot = of->slot;
    940   1.37  drochner 			of->slot = -1;
    941   1.37  drochner 			goto loadit;
    942   1.37  drochner 		}
    943   1.37  drochner 	}
    944   1.54  junyoung 	panic("vga_usefont");
    945   1.37  drochner 
    946   1.37  drochner loadit:
    947   1.52  drochner 	vga_loadchars(&vc->hdl, slot, f->wsfont->firstchar,
    948   1.66   tsutsui 	    f->wsfont->numchars, f->wsfont->fontheight, f->wsfont->data);
    949   1.37  drochner 	f->slot = slot;
    950   1.37  drochner 	vc->vc_fonts[slot] = f;
    951   1.37  drochner 
    952   1.37  drochner toend:
    953   1.37  drochner 	TAILQ_REMOVE(&vc->vc_fontlist, f, next);
    954   1.37  drochner 	TAILQ_INSERT_TAIL(&vc->vc_fontlist, f, next);
    955   1.37  drochner }
    956   1.37  drochner 
    957   1.12  drochner static void
    958   1.45  junyoung vga_setfont(struct vga_config *vc, struct vgascreen *scr)
    959   1.12  drochner {
    960   1.12  drochner 	int fontslot1, fontslot2;
    961   1.12  drochner 
    962   1.37  drochner 	if (scr->fontset1)
    963   1.37  drochner 		vga_usefont(vc, scr->fontset1);
    964   1.37  drochner 	if (scr->fontset2)
    965   1.37  drochner 		vga_usefont(vc, scr->fontset2);
    966   1.37  drochner 
    967   1.12  drochner 	fontslot1 = (scr->fontset1 ? scr->fontset1->slot : 0);
    968   1.12  drochner 	fontslot2 = (scr->fontset2 ? scr->fontset2->slot : fontslot1);
    969   1.12  drochner 	if (vc->currentfontset1 != fontslot1 ||
    970   1.12  drochner 	    vc->currentfontset2 != fontslot2) {
    971   1.12  drochner 		vga_setfontset(&vc->hdl, fontslot1, fontslot2);
    972   1.12  drochner 		vc->currentfontset1 = fontslot1;
    973   1.12  drochner 		vc->currentfontset2 = fontslot2;
    974   1.12  drochner 	}
    975   1.12  drochner }
    976   1.12  drochner 
    977  1.110   mlelstv static int
    978   1.91  christos vga_show_screen(void *v, void *cookie, int waitok,
    979   1.45  junyoung 		void (*cb)(void *, int, int), void *cbarg)
    980    1.1  drochner {
    981    1.4  drochner 	struct vgascreen *scr = cookie, *oldscr;
    982    1.1  drochner 	struct vga_config *vc = scr->cfg;
    983   1.22  drochner 
    984   1.22  drochner 	oldscr = vc->active; /* can be NULL! */
    985   1.22  drochner 	if (scr == oldscr) {
    986   1.22  drochner 		return (0);
    987   1.22  drochner 	}
    988   1.22  drochner 
    989   1.22  drochner 	vc->wantedscreen = cookie;
    990   1.22  drochner 	vc->switchcb = cb;
    991   1.22  drochner 	vc->switchcbarg = cbarg;
    992   1.22  drochner 	if (cb) {
    993   1.26   thorpej 		callout_reset(&vc->vc_switch_callout, 0,
    994   1.26   thorpej 		    (void(*)(void *))vga_doswitch, vc);
    995   1.22  drochner 		return (EAGAIN);
    996   1.22  drochner 	}
    997   1.22  drochner 
    998   1.22  drochner 	vga_doswitch(vc);
    999   1.22  drochner 	return (0);
   1000   1.22  drochner }
   1001   1.22  drochner 
   1002  1.110   mlelstv static void
   1003   1.45  junyoung vga_doswitch(struct vga_config *vc)
   1004   1.22  drochner {
   1005   1.22  drochner 	struct vgascreen *scr, *oldscr;
   1006    1.1  drochner 	struct vga_handle *vh = &vc->hdl;
   1007   1.22  drochner 	const struct wsscreen_descr *type;
   1008    1.1  drochner 
   1009   1.22  drochner 	scr = vc->wantedscreen;
   1010   1.22  drochner 	if (!scr) {
   1011   1.22  drochner 		printf("vga_doswitch: disappeared\n");
   1012   1.22  drochner 		(*vc->switchcb)(vc->switchcbarg, EIO, 0);
   1013   1.22  drochner 		return;
   1014   1.22  drochner 	}
   1015   1.22  drochner 	type = scr->pcs.type;
   1016   1.11  drochner 	oldscr = vc->active; /* can be NULL! */
   1017    1.4  drochner #ifdef DIAGNOSTIC
   1018   1.11  drochner 	if (oldscr) {
   1019   1.11  drochner 		if (!oldscr->pcs.active)
   1020   1.11  drochner 			panic("vga_show_screen: not active");
   1021   1.11  drochner 		if (oldscr->pcs.type != vc->currenttype)
   1022   1.11  drochner 			panic("vga_show_screen: bad type");
   1023   1.11  drochner 	}
   1024    1.4  drochner #endif
   1025    1.4  drochner 	if (scr == oldscr) {
   1026    1.1  drochner 		return;
   1027    1.4  drochner 	}
   1028    1.4  drochner #ifdef DIAGNOSTIC
   1029    1.4  drochner 	if (scr->pcs.active)
   1030    1.4  drochner 		panic("vga_show_screen: active");
   1031    1.4  drochner #endif
   1032    1.4  drochner 
   1033   1.11  drochner 	if (oldscr) {
   1034   1.11  drochner 		const struct wsscreen_descr *oldtype = oldscr->pcs.type;
   1035    1.1  drochner 
   1036   1.11  drochner 		oldscr->pcs.active = 0;
   1037   1.11  drochner 		bus_space_read_region_2(vh->vh_memt, vh->vh_memh,
   1038   1.66   tsutsui 		    oldscr->pcs.dispoffset, oldscr->pcs.mem,
   1039   1.66   tsutsui 		    oldtype->ncols * oldtype->nrows);
   1040   1.11  drochner 	}
   1041    1.1  drochner 
   1042   1.11  drochner 	if (vc->currenttype != type) {
   1043    1.4  drochner 		vga_setscreentype(vh, type);
   1044   1.11  drochner 		vc->currenttype = type;
   1045   1.11  drochner 	}
   1046   1.12  drochner 
   1047   1.12  drochner 	vga_setfont(vc, scr);
   1048  1.106  christos 	vga_restore_palette(vc);
   1049    1.1  drochner 
   1050   1.80   mycroft 	scr->pcs.visibleoffset = scr->pcs.dispoffset = scr->mindispoffset;
   1051   1.11  drochner 	if (!oldscr || (scr->pcs.dispoffset != oldscr->pcs.dispoffset)) {
   1052    1.8  drochner 		vga_6845_write(vh, startadrh, scr->pcs.dispoffset >> 9);
   1053    1.8  drochner 		vga_6845_write(vh, startadrl, scr->pcs.dispoffset >> 1);
   1054    1.8  drochner 	}
   1055    1.8  drochner 
   1056   1.11  drochner 	bus_space_write_region_2(vh->vh_memt, vh->vh_memh,
   1057   1.66   tsutsui 	    scr->pcs.dispoffset, scr->pcs.mem, type->ncols * type->nrows);
   1058   1.11  drochner 	scr->pcs.active = 1;
   1059    1.1  drochner 
   1060    1.4  drochner 	vc->active = scr;
   1061    1.1  drochner 
   1062    1.4  drochner 	pcdisplay_cursor(&scr->pcs, scr->pcs.cursoron,
   1063   1.66   tsutsui 	    scr->pcs.cursorrow, scr->pcs.cursorcol);
   1064   1.22  drochner 
   1065   1.22  drochner 	vc->wantedscreen = 0;
   1066   1.22  drochner 	if (vc->switchcb)
   1067   1.22  drochner 		(*vc->switchcb)(vc->switchcbarg, 0, 0);
   1068    1.1  drochner }
   1069    1.1  drochner 
   1070    1.1  drochner static int
   1071   1.45  junyoung vga_load_font(void *v, void *cookie, struct wsdisplay_font *data)
   1072    1.1  drochner {
   1073   1.12  drochner 	struct vga_config *vc = v;
   1074    1.1  drochner 	struct vgascreen *scr = cookie;
   1075   1.12  drochner 	char *name2;
   1076   1.37  drochner 	int res;
   1077   1.12  drochner 
   1078   1.12  drochner 	if (scr) {
   1079   1.50   hannken 		name2 = NULL;
   1080   1.50   hannken 		if (data->name) {
   1081   1.50   hannken 			name2 = strchr(data->name, ',');
   1082   1.50   hannken 			if (name2)
   1083   1.50   hannken 				*name2++ = '\0';
   1084   1.50   hannken 		}
   1085   1.12  drochner 		res = vga_selectfont(vc, scr, data->name, name2);
   1086   1.52  drochner 		if (!res && scr->pcs.active)
   1087   1.12  drochner 			vga_setfont(vc, scr);
   1088   1.12  drochner 		return (res);
   1089   1.12  drochner 	}
   1090    1.1  drochner 
   1091    1.1  drochner 	return (0);
   1092    1.1  drochner }
   1093    1.1  drochner 
   1094    1.3  drochner static int
   1095   1.59  junyoung vga_allocattr(void *id, int fg, int bg, int flags, long *attrp)
   1096    1.3  drochner {
   1097    1.3  drochner 	struct vgascreen *scr = id;
   1098    1.3  drochner 	struct vga_config *vc = scr->cfg;
   1099    1.3  drochner 
   1100   1.95       mjf 	if (__predict_false((unsigned int)fg >= sizeof(fgansitopc) ||
   1101   1.95       mjf 	    (unsigned int)bg >= sizeof(bgansitopc)))
   1102   1.95       mjf 		return (EINVAL);
   1103   1.95       mjf 
   1104    1.4  drochner 	if (vc->hdl.vh_mono) {
   1105    1.3  drochner 		if (flags & WSATTR_WSCOLORS)
   1106    1.3  drochner 			return (EINVAL);
   1107    1.3  drochner 		if (flags & WSATTR_REVERSE)
   1108    1.3  drochner 			*attrp = 0x70;
   1109    1.3  drochner 		else
   1110    1.3  drochner 			*attrp = 0x07;
   1111    1.3  drochner 		if (flags & WSATTR_UNDERLINE)
   1112    1.3  drochner 			*attrp |= FG_UNDERLINE;
   1113    1.3  drochner 		if (flags & WSATTR_HILIT)
   1114    1.3  drochner 			*attrp |= FG_INTENSE;
   1115    1.3  drochner 	} else {
   1116    1.3  drochner 		if (flags & (WSATTR_UNDERLINE | WSATTR_REVERSE))
   1117    1.3  drochner 			return (EINVAL);
   1118    1.3  drochner 		if (flags & WSATTR_WSCOLORS)
   1119    1.3  drochner 			*attrp = fgansitopc[fg] | bgansitopc[bg];
   1120    1.3  drochner 		else
   1121    1.3  drochner 			*attrp = 7;
   1122    1.3  drochner 		if (flags & WSATTR_HILIT)
   1123    1.3  drochner 			*attrp += 8;
   1124    1.3  drochner 	}
   1125    1.3  drochner 	if (flags & WSATTR_BLINK)
   1126    1.3  drochner 		*attrp |= FG_BLINK;
   1127    1.3  drochner 	return (0);
   1128    1.8  drochner }
   1129    1.8  drochner 
   1130   1.45  junyoung static void
   1131   1.45  junyoung vga_copyrows(void *id, int srcrow, int dstrow, int nrows)
   1132    1.8  drochner {
   1133    1.8  drochner 	struct vgascreen *scr = id;
   1134    1.8  drochner 	bus_space_tag_t memt = scr->pcs.hdl->ph_memt;
   1135    1.8  drochner 	bus_space_handle_t memh = scr->pcs.hdl->ph_memh;
   1136    1.8  drochner 	int ncols = scr->pcs.type->ncols;
   1137    1.8  drochner 	bus_size_t srcoff, dstoff;
   1138    1.8  drochner 
   1139    1.8  drochner 	srcoff = srcrow * ncols + 0;
   1140    1.8  drochner 	dstoff = dstrow * ncols + 0;
   1141    1.8  drochner 
   1142    1.8  drochner 	if (scr->pcs.active) {
   1143    1.8  drochner 		if (dstrow == 0 && (srcrow + nrows == scr->pcs.type->nrows)) {
   1144   1.18        ad #ifdef PCDISPLAY_SOFTCURSOR
   1145   1.20        ad 			int cursoron = scr->pcs.cursoron;
   1146   1.20        ad 
   1147   1.21   mycroft 			if (cursoron)
   1148   1.21   mycroft 				pcdisplay_cursor(&scr->pcs, 0,
   1149   1.60  junyoung 				    scr->pcs.cursorrow, scr->pcs.cursorcol);
   1150   1.18        ad #endif
   1151    1.8  drochner 			/* scroll up whole screen */
   1152    1.8  drochner 			if ((scr->pcs.dispoffset + srcrow * ncols * 2)
   1153    1.8  drochner 			    <= scr->maxdispoffset) {
   1154    1.8  drochner 				scr->pcs.dispoffset += srcrow * ncols * 2;
   1155    1.8  drochner 			} else {
   1156    1.8  drochner 				bus_space_copy_region_2(memt, memh,
   1157   1.66   tsutsui 				    scr->pcs.dispoffset + srcoff * 2,
   1158   1.66   tsutsui 				    memh, scr->mindispoffset, nrows * ncols);
   1159    1.8  drochner 				scr->pcs.dispoffset = scr->mindispoffset;
   1160    1.8  drochner 			}
   1161    1.8  drochner 			vga_6845_write(&scr->cfg->hdl, startadrh,
   1162   1.66   tsutsui 			    scr->pcs.dispoffset >> 9);
   1163    1.8  drochner 			vga_6845_write(&scr->cfg->hdl, startadrl,
   1164   1.66   tsutsui 			    scr->pcs.dispoffset >> 1);
   1165   1.18        ad #ifdef PCDISPLAY_SOFTCURSOR
   1166   1.21   mycroft 			if (cursoron)
   1167   1.21   mycroft 				pcdisplay_cursor(&scr->pcs, 1,
   1168   1.60  junyoung 				    scr->pcs.cursorrow, scr->pcs.cursorcol);
   1169   1.18        ad #endif
   1170    1.8  drochner 		} else {
   1171    1.8  drochner 			bus_space_copy_region_2(memt, memh,
   1172   1.66   tsutsui 			    scr->pcs.dispoffset + srcoff * 2,
   1173   1.66   tsutsui 			    memh, scr->pcs.dispoffset + dstoff * 2,
   1174   1.66   tsutsui 			    nrows * ncols);
   1175    1.8  drochner 		}
   1176    1.8  drochner 	} else
   1177   1.36   thorpej 		memcpy(&scr->pcs.mem[dstoff], &scr->pcs.mem[srcoff],
   1178   1.66   tsutsui 		    nrows * ncols * 2);
   1179   1.12  drochner }
   1180   1.12  drochner 
   1181   1.12  drochner #ifdef WSCONS_SUPPORT_PCVTFONTS
   1182   1.12  drochner 
   1183   1.12  drochner #define NOTYET 0xffff
   1184  1.106  christos static const uint16_t pcvt_unichars[0xa0] = {
   1185   1.44     bjh21 /* 0 */	_e006U, /* N/L control */
   1186   1.14  drochner 	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1187   1.12  drochner 	NOTYET,
   1188   1.12  drochner 	0x2409, /* SYMBOL FOR HORIZONTAL TABULATION */
   1189   1.12  drochner 	0x240a, /* SYMBOL FOR LINE FEED */
   1190   1.12  drochner 	0x240b, /* SYMBOL FOR VERTICAL TABULATION */
   1191   1.12  drochner 	0x240c, /* SYMBOL FOR FORM FEED */
   1192   1.12  drochner 	0x240d, /* SYMBOL FOR CARRIAGE RETURN */
   1193   1.12  drochner 	NOTYET, NOTYET,
   1194   1.14  drochner /* 1 */	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1195   1.12  drochner 	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1196   1.12  drochner /* 2 */	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1197   1.12  drochner 	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1198   1.14  drochner /* 3 */	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1199   1.12  drochner 	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1200   1.12  drochner /* 4 */	0x03c1, /* GREEK SMALL LETTER RHO */
   1201   1.12  drochner 	0x03c8, /* GREEK SMALL LETTER PSI */
   1202   1.12  drochner 	0x2202, /* PARTIAL DIFFERENTIAL */
   1203   1.12  drochner 	0x03bb, /* GREEK SMALL LETTER LAMDA */
   1204   1.12  drochner 	0x03b9, /* GREEK SMALL LETTER IOTA */
   1205   1.12  drochner 	0x03b7, /* GREEK SMALL LETTER ETA */
   1206   1.12  drochner 	0x03b5, /* GREEK SMALL LETTER EPSILON */
   1207   1.12  drochner 	0x03c7, /* GREEK SMALL LETTER CHI */
   1208   1.12  drochner 	0x2228, /* LOGICAL OR */
   1209   1.12  drochner 	0x2227, /* LOGICAL AND */
   1210   1.12  drochner 	0x222a, /* UNION */
   1211   1.12  drochner 	0x2283, /* SUPERSET OF */
   1212   1.12  drochner 	0x2282, /* SUBSET OF */
   1213   1.12  drochner 	0x03a5, /* GREEK CAPITAL LETTER UPSILON */
   1214   1.12  drochner 	0x039e, /* GREEK CAPITAL LETTER XI */
   1215   1.12  drochner 	0x03a8, /* GREEK CAPITAL LETTER PSI */
   1216   1.14  drochner /* 5 */	0x03a0, /* GREEK CAPITAL LETTER PI */
   1217   1.12  drochner 	0x21d2, /* RIGHTWARDS DOUBLE ARROW */
   1218   1.12  drochner 	0x21d4, /* LEFT RIGHT DOUBLE ARROW */
   1219   1.12  drochner 	0x039b, /* GREEK CAPITAL LETTER LAMDA */
   1220   1.12  drochner 	0x0398, /* GREEK CAPITAL LETTER THETA */
   1221   1.12  drochner 	0x2243, /* ASYMPTOTICALLY EQUAL TO */
   1222   1.12  drochner 	0x2207, /* NABLA */
   1223   1.12  drochner 	0x2206, /* INCREMENT */
   1224   1.12  drochner 	0x221d, /* PROPORTIONAL TO */
   1225   1.12  drochner 	0x2234, /* THEREFORE */
   1226   1.12  drochner 	0x222b, /* INTEGRAL */
   1227   1.12  drochner 	0x2215, /* DIVISION SLASH */
   1228   1.12  drochner 	0x2216, /* SET MINUS */
   1229   1.44     bjh21 	_e00eU, /* angle? */
   1230   1.44     bjh21 	_e00dU, /* inverted angle? */
   1231   1.44     bjh21 	_e00bU, /* braceleftmid */
   1232   1.44     bjh21 /* 6 */	_e00cU, /* bracerightmid */
   1233   1.44     bjh21 	_e007U, /* bracelefttp */
   1234   1.44     bjh21 	_e008U, /* braceleftbt */
   1235   1.44     bjh21 	_e009U, /* bracerighttp */
   1236   1.44     bjh21 	_e00aU, /* bracerightbt */
   1237   1.12  drochner 	0x221a, /* SQUARE ROOT */
   1238   1.12  drochner 	0x03c9, /* GREEK SMALL LETTER OMEGA */
   1239   1.12  drochner 	0x00a5, /* YEN SIGN */
   1240   1.12  drochner 	0x03be, /* GREEK SMALL LETTER XI */
   1241   1.12  drochner 	0x00fd, /* LATIN SMALL LETTER Y WITH ACUTE */
   1242   1.12  drochner 	0x00fe, /* LATIN SMALL LETTER THORN */
   1243   1.12  drochner 	0x00f0, /* LATIN SMALL LETTER ETH */
   1244   1.12  drochner 	0x00de, /* LATIN CAPITAL LETTER THORN */
   1245   1.12  drochner 	0x00dd, /* LATIN CAPITAL LETTER Y WITH ACUTE */
   1246   1.12  drochner 	0x00d7, /* MULTIPLICATION SIGN */
   1247   1.12  drochner 	0x00d0, /* LATIN CAPITAL LETTER ETH */
   1248   1.14  drochner /* 7 */	0x00be, /* VULGAR FRACTION THREE QUARTERS */
   1249   1.12  drochner 	0x00b8, /* CEDILLA */
   1250   1.12  drochner 	0x00b4, /* ACUTE ACCENT */
   1251   1.12  drochner 	0x00af, /* MACRON */
   1252   1.12  drochner 	0x00ae, /* REGISTERED SIGN */
   1253   1.12  drochner 	0x00ad, /* SOFT HYPHEN */
   1254   1.12  drochner 	0x00ac, /* NOT SIGN */
   1255   1.12  drochner 	0x00a8, /* DIAERESIS */
   1256   1.12  drochner 	0x2260, /* NOT EQUAL TO */
   1257  1.102  drochner 	0x23bd, /* scan 9 */
   1258  1.102  drochner 	0x23bc, /* scan 7 */
   1259  1.102  drochner 	0x2500, /* scan 5 */
   1260  1.102  drochner 	0x23bb, /* scan 3 */
   1261  1.102  drochner 	0x23ba, /* scan 1 */
   1262   1.12  drochner 	0x03c5, /* GREEK SMALL LETTER UPSILON */
   1263   1.12  drochner 	0x00f8, /* LATIN SMALL LETTER O WITH STROKE */
   1264   1.12  drochner /* 8 */	0x0153, /* LATIN SMALL LIGATURE OE */
   1265   1.12  drochner 	0x00f5, /* LATIN SMALL LETTER O WITH TILDE !!!doc bug */
   1266   1.12  drochner 	0x00e3, /* LATIN SMALL LETTER A WITH TILDE */
   1267   1.12  drochner 	0x0178, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
   1268   1.12  drochner 	0x00db, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
   1269   1.12  drochner 	0x00da, /* LATIN CAPITAL LETTER U WITH ACUTE */
   1270   1.12  drochner 	0x00d9, /* LATIN CAPITAL LETTER U WITH GRAVE */
   1271   1.12  drochner 	0x00d8, /* LATIN CAPITAL LETTER O WITH STROKE */
   1272   1.12  drochner 	0x0152, /* LATIN CAPITAL LIGATURE OE */
   1273   1.12  drochner 	0x00d5, /* LATIN CAPITAL LETTER O WITH TILDE */
   1274   1.12  drochner 	0x00d4, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
   1275   1.12  drochner 	0x00d3, /* LATIN CAPITAL LETTER O WITH ACUTE */
   1276   1.12  drochner 	0x00d2, /* LATIN CAPITAL LETTER O WITH GRAVE */
   1277   1.12  drochner 	0x00cf, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
   1278   1.12  drochner 	0x00ce, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
   1279   1.12  drochner 	0x00cd, /* LATIN CAPITAL LETTER I WITH ACUTE */
   1280   1.14  drochner /* 9 */	0x00cc, /* LATIN CAPITAL LETTER I WITH GRAVE */
   1281   1.12  drochner 	0x00cb, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
   1282   1.12  drochner 	0x00ca, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
   1283   1.12  drochner 	0x00c8, /* LATIN CAPITAL LETTER E WITH GRAVE */
   1284   1.12  drochner 	0x00c3, /* LATIN CAPITAL LETTER A WITH TILDE */
   1285   1.12  drochner 	0x00c2, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
   1286   1.12  drochner 	0x00c1, /* LATIN CAPITAL LETTER A WITH ACUTE */
   1287   1.12  drochner 	0x00c0, /* LATIN CAPITAL LETTER A WITH GRAVE */
   1288   1.12  drochner 	0x00b9, /* SUPERSCRIPT ONE */
   1289   1.12  drochner 	0x00b7, /* MIDDLE DOT */
   1290   1.12  drochner 	0x03b6, /* GREEK SMALL LETTER ZETA */
   1291   1.12  drochner 	0x00b3, /* SUPERSCRIPT THREE */
   1292   1.12  drochner 	0x00a9, /* COPYRIGHT SIGN */
   1293   1.12  drochner 	0x00a4, /* CURRENCY SIGN */
   1294   1.12  drochner 	0x03ba, /* GREEK SMALL LETTER KAPPA */
   1295   1.44     bjh21 	_e000U  /* mirrored question mark? */
   1296   1.12  drochner };
   1297   1.12  drochner 
   1298   1.45  junyoung static int vga_pcvt_mapchar(int, u_int *);
   1299   1.12  drochner 
   1300   1.12  drochner static int
   1301   1.45  junyoung vga_pcvt_mapchar(int uni, u_int *index)
   1302   1.12  drochner {
   1303   1.12  drochner 	int i;
   1304   1.12  drochner 
   1305   1.12  drochner 	for (i = 0; i < 0xa0; i++) /* 0xa0..0xff are reserved */
   1306   1.13  drochner 		if (uni == pcvt_unichars[i]) {
   1307   1.13  drochner 			*index = i;
   1308   1.13  drochner 			return (5);
   1309   1.13  drochner 		}
   1310   1.13  drochner 	*index = 0x99; /* middle dot */
   1311   1.13  drochner 	return (0);
   1312   1.12  drochner }
   1313   1.12  drochner 
   1314   1.12  drochner #endif /* WSCONS_SUPPORT_PCVTFONTS */
   1315   1.12  drochner 
   1316   1.34  drochner #ifdef WSCONS_SUPPORT_ISO7FONTS
   1317   1.34  drochner 
   1318   1.34  drochner static int
   1319   1.45  junyoung vga_iso7_mapchar(int uni, u_int *index)
   1320   1.34  drochner {
   1321   1.34  drochner 
   1322   1.34  drochner 	/*
   1323   1.34  drochner 	 * U+0384 (GREEK TONOS) to
   1324   1.34  drochner 	 * U+03ce (GREEK SMALL LETTER OMEGA WITH TONOS)
   1325   1.34  drochner 	 * map directly to the iso-9 font
   1326   1.34  drochner 	 */
   1327   1.34  drochner 	if (uni >= 0x0384 && uni <= 0x03ce) {
   1328   1.34  drochner 		/* U+0384 is at offset 0xb4 in the font */
   1329   1.34  drochner 		*index = uni - 0x0384 + 0xb4;
   1330   1.34  drochner 		return (5);
   1331   1.34  drochner 	}
   1332   1.34  drochner 
   1333   1.34  drochner 	/* XXX more chars in the iso-9 font */
   1334   1.34  drochner 
   1335   1.34  drochner 	*index = 0xa4; /* shaded rectangle */
   1336   1.34  drochner 	return (0);
   1337   1.34  drochner }
   1338   1.34  drochner 
   1339   1.34  drochner #endif /* WSCONS_SUPPORT_ISO7FONTS */
   1340   1.34  drochner 
   1341  1.107  drochner static const uint16_t iso2_unichars[0x60] = {
   1342  1.107  drochner 	0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
   1343  1.107  drochner 	0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
   1344  1.107  drochner 	0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
   1345  1.107  drochner 	0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
   1346  1.107  drochner 	0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
   1347  1.107  drochner 	0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
   1348  1.107  drochner 	0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
   1349  1.107  drochner 	0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
   1350  1.107  drochner 	0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
   1351  1.107  drochner 	0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
   1352  1.107  drochner 	0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
   1353  1.107  drochner 	0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
   1354  1.107  drochner };
   1355  1.107  drochner 
   1356  1.107  drochner static const uint16_t koi8_unichars[0x40] = {
   1357  1.107  drochner 	0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
   1358  1.107  drochner 	0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
   1359  1.107  drochner 	0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
   1360  1.107  drochner 	0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
   1361  1.107  drochner 	0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
   1362  1.107  drochner 	0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
   1363  1.107  drochner 	0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
   1364  1.107  drochner 	0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
   1365  1.107  drochner };
   1366  1.107  drochner 
   1367   1.45  junyoung static int _vga_mapchar(void *, const struct egavga_font *, int, u_int *);
   1368   1.12  drochner 
   1369   1.12  drochner static int
   1370   1.45  junyoung _vga_mapchar(void *id, const struct egavga_font *font, int uni, u_int *index)
   1371   1.12  drochner {
   1372   1.12  drochner 
   1373   1.37  drochner 	switch (font->wsfont->encoding) {
   1374   1.12  drochner 	case WSDISPLAY_FONTENC_ISO:
   1375   1.13  drochner 		if (uni < 256) {
   1376   1.13  drochner 			*index = uni;
   1377   1.13  drochner 			return (5);
   1378   1.13  drochner 		} else {
   1379   1.13  drochner 			*index = ' ';
   1380   1.13  drochner 			return (0);
   1381   1.13  drochner 		}
   1382  1.107  drochner 	case WSDISPLAY_FONTENC_ISO2:
   1383  1.107  drochner 		if (uni < 0xa0) {
   1384  1.107  drochner 			*index = uni;
   1385  1.107  drochner 			return (5);
   1386  1.107  drochner 		} else {
   1387  1.107  drochner 			int i;
   1388  1.107  drochner 			for (i = 0; i < 0x60; i++) {
   1389  1.107  drochner 				if (uni == iso2_unichars[i]) {
   1390  1.107  drochner 					*index = i + 0xa0;
   1391  1.107  drochner 					return (5);
   1392  1.107  drochner 				}
   1393  1.107  drochner 			}
   1394  1.107  drochner 			*index = 0xa4; /* currency sign */
   1395  1.107  drochner 			return (0);
   1396  1.107  drochner 		}
   1397  1.107  drochner 	case WSDISPLAY_FONTENC_KOI8_R:
   1398  1.107  drochner 		if (uni < 0x80) {
   1399  1.107  drochner 			*index = uni;
   1400  1.107  drochner 			return (5);
   1401  1.107  drochner 		} else {
   1402  1.107  drochner 			int i;
   1403  1.107  drochner 			for (i = 0; i < 0x40; i++) {
   1404  1.107  drochner 				if (uni == koi8_unichars[i]) {
   1405  1.107  drochner 					*index = i + 0xc0;
   1406  1.107  drochner 					return (5);
   1407  1.107  drochner 				}
   1408  1.107  drochner 			}
   1409  1.107  drochner 			*index = 0x94; /* box */
   1410  1.107  drochner 			return (0);
   1411  1.107  drochner 		}
   1412   1.12  drochner 	case WSDISPLAY_FONTENC_IBM:
   1413   1.13  drochner 		return (pcdisplay_mapchar(id, uni, index));
   1414   1.12  drochner #ifdef WSCONS_SUPPORT_PCVTFONTS
   1415   1.12  drochner 	case WSDISPLAY_FONTENC_PCVT:
   1416   1.13  drochner 		return (vga_pcvt_mapchar(uni, index));
   1417   1.34  drochner #endif
   1418   1.34  drochner #ifdef WSCONS_SUPPORT_ISO7FONTS
   1419   1.34  drochner 	case WSDISPLAY_FONTENC_ISO7:
   1420   1.34  drochner 		return (vga_iso7_mapchar(uni, index));
   1421   1.12  drochner #endif
   1422   1.13  drochner 	default:
   1423   1.16  drochner #ifdef VGAFONTDEBUG
   1424   1.37  drochner 		printf("_vga_mapchar: encoding=%d\n", font->wsfont->encoding);
   1425   1.16  drochner #endif
   1426   1.13  drochner 		*index = ' ';
   1427   1.13  drochner 		return (0);
   1428   1.12  drochner 	}
   1429   1.12  drochner }
   1430   1.12  drochner 
   1431   1.13  drochner static int
   1432   1.45  junyoung vga_mapchar(void *id, int uni, u_int *index)
   1433   1.12  drochner {
   1434   1.12  drochner 	struct vgascreen *scr = id;
   1435   1.45  junyoung 	u_int idx1, idx2;
   1436   1.13  drochner 	int res1, res2;
   1437   1.12  drochner 
   1438   1.13  drochner 	res1 = 0;
   1439   1.13  drochner 	idx1 = ' '; /* space */
   1440   1.13  drochner 	if (scr->fontset1)
   1441   1.13  drochner 		res1 = _vga_mapchar(id, scr->fontset1, uni, &idx1);
   1442   1.13  drochner 	res2 = -1;
   1443   1.12  drochner 	if (scr->fontset2) {
   1444   1.12  drochner 		KASSERT(VGA_SCREEN_CANTWOFONTS(scr->pcs.type));
   1445   1.13  drochner 		res2 = _vga_mapchar(id, scr->fontset2, uni, &idx2);
   1446   1.12  drochner 	}
   1447   1.13  drochner 	if (res2 > res1) {
   1448   1.14  drochner 		*index = idx2 | 0x0800; /* attribute bit 3 */
   1449   1.14  drochner 		return (res2);
   1450   1.13  drochner 	}
   1451   1.13  drochner 	*index = idx1;
   1452   1.13  drochner 	return (res1);
   1453   1.53  christos }
   1454   1.53  christos 
   1455   1.72  christos #ifdef WSDISPLAY_SCROLLSUPPORT
   1456  1.110   mlelstv static void
   1457   1.72  christos vga_scroll(void *v, void *cookie, int lines)
   1458   1.72  christos {
   1459   1.72  christos 	struct vga_config *vc = v;
   1460   1.72  christos 	struct vgascreen *scr = cookie;
   1461   1.72  christos 	struct vga_handle *vh = &vc->hdl;
   1462   1.72  christos 
   1463   1.72  christos 	if (lines == 0) {
   1464   1.72  christos 		if (scr->pcs.visibleoffset == scr->pcs.dispoffset)
   1465   1.72  christos 			return;
   1466   1.72  christos 
   1467   1.72  christos 		scr->pcs.visibleoffset = scr->pcs.dispoffset;
   1468   1.72  christos 	}
   1469   1.72  christos 	else {
   1470   1.72  christos 		int vga_scr_end;
   1471   1.72  christos 		int margin = scr->pcs.type->ncols * 2;
   1472   1.72  christos 		int ul, we, p, st;
   1473   1.72  christos 
   1474   1.72  christos 		vga_scr_end = (scr->pcs.dispoffset + scr->pcs.type->ncols *
   1475   1.72  christos 		    scr->pcs.type->nrows * 2);
   1476   1.72  christos 		if (scr->vga_rollover > vga_scr_end + margin) {
   1477   1.72  christos 			ul = vga_scr_end;
   1478   1.72  christos 			we = scr->vga_rollover + scr->pcs.type->ncols * 2;
   1479   1.72  christos 		} else {
   1480   1.72  christos 			ul = 0;
   1481   1.72  christos 			we = 0x8000;
   1482   1.72  christos 		}
   1483   1.72  christos 		p = (scr->pcs.visibleoffset - ul + we) % we + lines *
   1484   1.72  christos 		    (scr->pcs.type->ncols * 2);
   1485   1.72  christos 		st = (scr->pcs.dispoffset - ul + we) % we;
   1486   1.72  christos 		if (p < margin)
   1487   1.72  christos 			p = 0;
   1488   1.72  christos 		if (p > st - margin)
   1489   1.72  christos 			p = st;
   1490   1.72  christos 		scr->pcs.visibleoffset = (p + ul) % we;
   1491   1.72  christos 	}
   1492   1.81     perry 
   1493   1.72  christos 	vga_6845_write(vh, startadrh, scr->pcs.visibleoffset >> 9);
   1494   1.72  christos 	vga_6845_write(vh, startadrl, scr->pcs.visibleoffset >> 1);
   1495   1.72  christos }
   1496   1.72  christos #endif
   1497   1.72  christos 
   1498  1.110   mlelstv static void
   1499   1.72  christos vga_putchar(void *c, int row, int col, u_int uc, long attr)
   1500   1.72  christos {
   1501   1.72  christos 
   1502   1.72  christos 	pcdisplay_putchar(c, row, col, uc, attr);
   1503   1.72  christos }
   1504   1.72  christos 
   1505   1.76      jmmv #ifdef WSDISPLAY_CUSTOM_BORDER
   1506   1.85  drochner static int
   1507   1.85  drochner vga_getborder(struct vga_config *vc, u_int *valuep)
   1508   1.76      jmmv {
   1509   1.85  drochner 	struct vga_handle *vh = &vc->hdl;
   1510   1.76      jmmv 	u_int idx;
   1511  1.106  christos 	uint8_t value;
   1512   1.76      jmmv 
   1513   1.85  drochner 	if (vh->vh_mono)
   1514   1.85  drochner 		return ENODEV;
   1515   1.76      jmmv 
   1516   1.76      jmmv 	value = _vga_attr_read(vh, VGA_ATC_OVERSCAN);
   1517   1.85  drochner 	for (idx = 0; idx < sizeof(fgansitopc); idx++) {
   1518   1.85  drochner 		if (fgansitopc[idx] == value) {
   1519   1.85  drochner 			*valuep = idx;
   1520   1.85  drochner 			return (0);
   1521   1.85  drochner 		}
   1522   1.85  drochner 	}
   1523   1.85  drochner 	return (EIO);
   1524   1.76      jmmv }
   1525   1.76      jmmv 
   1526   1.76      jmmv static int
   1527   1.85  drochner vga_setborder(struct vga_config *vc, u_int value)
   1528   1.76      jmmv {
   1529   1.85  drochner 	struct vga_handle *vh = &vc->hdl;
   1530   1.76      jmmv 
   1531   1.85  drochner 	if (vh->vh_mono)
   1532   1.85  drochner 		return ENODEV;
   1533   1.85  drochner 	if (value >= sizeof(fgansitopc))
   1534   1.85  drochner 		return EINVAL;
   1535   1.76      jmmv 
   1536   1.76      jmmv 	_vga_attr_write(vh, VGA_ATC_OVERSCAN, fgansitopc[value]);
   1537   1.76      jmmv 	return (0);
   1538   1.76      jmmv }
   1539   1.76      jmmv #endif /* WSDISPLAY_CUSTOM_BORDER */
   1540   1.97  jmcneill 
   1541   1.97  jmcneill void
   1542   1.97  jmcneill vga_resume(struct vga_softc *sc)
   1543   1.97  jmcneill {
   1544   1.97  jmcneill #ifdef VGA_RESET_ON_RESUME
   1545   1.97  jmcneill 	vga_initregs(&sc->sc_vc->hdl);
   1546   1.97  jmcneill #endif
   1547  1.105  jmcneill #ifdef PCDISPLAY_SOFTCURSOR
   1548  1.105  jmcneill 	/* Disable the hardware cursor */
   1549  1.105  jmcneill 	vga_6845_write(&sc->sc_vc->hdl, curstart, 0x20);
   1550  1.105  jmcneill 	vga_6845_write(&sc->sc_vc->hdl, curend, 0x00);
   1551  1.105  jmcneill #endif
   1552   1.97  jmcneill }
   1553  1.106  christos 
   1554  1.110   mlelstv static void
   1555  1.106  christos vga_save_palette(struct vga_config *vc)
   1556  1.106  christos {
   1557  1.106  christos 	struct vga_handle *vh = &vc->hdl;
   1558  1.106  christos 	size_t i;
   1559  1.106  christos 	uint8_t *palette = vc->palette;
   1560  1.106  christos 
   1561  1.106  christos 	if (vh->vh_mono)
   1562  1.106  christos 		return;
   1563  1.106  christos 
   1564  1.106  christos 	vga_raw_write(vh, VGA_DAC_PELMASK, 0xff);
   1565  1.106  christos 	vga_raw_write(vh, VGA_DAC_ADDRR, 0x00);
   1566  1.106  christos 	for (i = 0; i < sizeof(vc->palette); i++)
   1567  1.106  christos 		*palette++ = vga_raw_read(vh, VGA_DAC_PALETTE);
   1568  1.106  christos 
   1569  1.109       uwe 	vga_reset_state(vh);			/* reset flip/flop */
   1570  1.106  christos }
   1571  1.106  christos 
   1572  1.110   mlelstv static void
   1573  1.106  christos vga_restore_palette(struct vga_config *vc)
   1574  1.106  christos {
   1575  1.106  christos 	struct vga_handle *vh = &vc->hdl;
   1576  1.106  christos 	size_t i;
   1577  1.106  christos 	uint8_t *palette = vc->palette;
   1578  1.106  christos 
   1579  1.106  christos 	if (vh->vh_mono)
   1580  1.106  christos 		return;
   1581  1.106  christos 
   1582  1.106  christos 	vga_raw_write(vh, VGA_DAC_PELMASK, 0xff);
   1583  1.106  christos 	vga_raw_write(vh, VGA_DAC_ADDRW, 0x00);
   1584  1.106  christos 	for (i = 0; i < sizeof(vc->palette); i++)
   1585  1.106  christos 		vga_raw_write(vh, VGA_DAC_PALETTE, *palette++);
   1586  1.106  christos 
   1587  1.109       uwe 	vga_reset_state(vh);			/* reset flip/flop */
   1588  1.106  christos 	vga_enable(vh);
   1589  1.106  christos }
   1590