Home | History | Annotate | Line # | Download | only in ic
vga.c revision 1.115
      1  1.115   mlelstv /* $NetBSD: vga.c,v 1.115 2015/03/01 07:05:59 mlelstv 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.115   mlelstv __KERNEL_RCSID(0, "$NetBSD: vga.c,v 1.115 2015/03/01 07:05:59 mlelstv 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.37  drochner 	f = malloc(sizeof(struct egavga_font), M_DEVBUF, M_NOWAIT);
    364   1.37  drochner 	if (!f) {
    365   1.37  drochner 		wsfont_unlock(cookie);
    366   1.37  drochner 		return (0);
    367   1.37  drochner 	}
    368   1.37  drochner 	f->wsfont = wf;
    369   1.37  drochner 	f->cookie = cookie;
    370   1.37  drochner 	f->slot = -1; /* not yet loaded */
    371   1.37  drochner 	f->usecount = 0; /* incremented below */
    372   1.37  drochner 	TAILQ_INSERT_TAIL(&vc->vc_fontlist, f, next);
    373   1.37  drochner 
    374   1.37  drochner found:
    375   1.37  drochner 	f->usecount++;
    376   1.37  drochner #ifdef VGAFONTDEBUG
    377   1.37  drochner 	if (scr != &vga_console_screen || vga_console_attached)
    378   1.37  drochner 		printf("vga_getfont: usecount=%d\n", f->usecount);
    379   1.37  drochner #endif
    380   1.37  drochner 	return (f);
    381   1.37  drochner }
    382   1.37  drochner 
    383  1.110   mlelstv static void
    384   1.45  junyoung egavga_unreffont(struct vga_config *vc, struct egavga_font *f)
    385   1.37  drochner {
    386   1.37  drochner 
    387   1.37  drochner 	f->usecount--;
    388   1.37  drochner #ifdef VGAFONTDEBUG
    389   1.37  drochner 	printf("vga_unreffont: usecount=%d\n", f->usecount);
    390   1.37  drochner #endif
    391   1.58  drochner 	if (f->usecount == 0 && f->cookie != -1) {
    392   1.37  drochner 		TAILQ_REMOVE(&vc->vc_fontlist, f, next);
    393   1.41  drochner 		if (f->slot != -1) {
    394   1.41  drochner 			KASSERT(vc->vc_fonts[f->slot] == f);
    395   1.41  drochner 			vc->vc_fonts[f->slot] = 0;
    396   1.41  drochner 		}
    397   1.37  drochner 		wsfont_unlock(f->cookie);
    398   1.38  drochner #ifdef VGA_CONSOLE_SCREENTYPE
    399   1.38  drochner 		if (f != &vga_consolefont)
    400   1.38  drochner #endif
    401   1.37  drochner 		free(f, M_DEVBUF);
    402   1.37  drochner 	}
    403   1.37  drochner }
    404   1.12  drochner 
    405  1.110   mlelstv static int
    406   1.69  jdolecek vga_selectfont(struct vga_config *vc, struct vgascreen *scr, const char *name1,
    407   1.69  jdolecek 	       const char *name2)
    408   1.12  drochner {
    409   1.12  drochner 	const struct wsscreen_descr *type = scr->pcs.type;
    410   1.37  drochner 	struct egavga_font *f1, *f2;
    411   1.12  drochner 
    412   1.37  drochner 	f1 = egavga_getfont(vc, scr, name1, 1);
    413   1.37  drochner 	if (!f1)
    414   1.37  drochner 		return (ENXIO);
    415   1.12  drochner 
    416   1.37  drochner 	if (VGA_SCREEN_CANTWOFONTS(type) && name2) {
    417   1.37  drochner 		f2 = egavga_getfont(vc, scr, name2, 0);
    418   1.37  drochner 		if (!f2) {
    419   1.37  drochner 			egavga_unreffont(vc, f1);
    420   1.37  drochner 			return (ENXIO);
    421   1.12  drochner 		}
    422   1.37  drochner 	} else
    423   1.37  drochner 		f2 = 0;
    424   1.12  drochner 
    425   1.12  drochner #ifdef VGAFONTDEBUG
    426   1.37  drochner 	if (scr != &vga_console_screen || vga_console_attached) {
    427   1.37  drochner 		printf("vga (%s): font1=%s (slot %d)", type->name,
    428   1.66   tsutsui 		    f1->wsfont->name, f1->slot);
    429   1.37  drochner 		if (f2)
    430   1.37  drochner 			printf(", font2=%s (slot %d)",
    431   1.66   tsutsui 			    f2->wsfont->name, f2->slot);
    432   1.37  drochner 		printf("\n");
    433   1.37  drochner 	}
    434   1.12  drochner #endif
    435   1.37  drochner 	if (scr->fontset1)
    436   1.37  drochner 		egavga_unreffont(vc, scr->fontset1);
    437   1.37  drochner 	scr->fontset1 = f1;
    438   1.37  drochner 	if (scr->fontset2)
    439   1.37  drochner 		egavga_unreffont(vc, scr->fontset2);
    440   1.37  drochner 	scr->fontset2 = f2;
    441   1.37  drochner 	return (0);
    442   1.12  drochner }
    443   1.12  drochner 
    444  1.110   mlelstv static void
    445   1.45  junyoung vga_init_screen(struct vga_config *vc, struct vgascreen *scr,
    446   1.45  junyoung 		const struct wsscreen_descr *type, int existing, long *attrp)
    447    1.1  drochner {
    448    1.8  drochner 	int cpos;
    449  1.111  christos 	int res __diagused;
    450    1.1  drochner 
    451    1.4  drochner 	scr->cfg = vc;
    452    1.4  drochner 	scr->pcs.hdl = (struct pcdisplay_handle *)&vc->hdl;
    453    1.4  drochner 	scr->pcs.type = type;
    454   1.39  drochner 	scr->pcs.active = existing;
    455    1.8  drochner 	scr->mindispoffset = 0;
    456   1.63  drochner 	if (vc->vc_quirks & VGA_QUIRK_NOFASTSCROLL)
    457   1.63  drochner 		scr->maxdispoffset = 0;
    458   1.63  drochner 	else
    459   1.63  drochner 		scr->maxdispoffset = 0x8000 - type->nrows * type->ncols * 2;
    460    1.1  drochner 
    461    1.1  drochner 	if (existing) {
    462   1.39  drochner 		vc->active = scr;
    463   1.39  drochner 
    464    1.1  drochner 		cpos = vga_6845_read(&vc->hdl, cursorh) << 8;
    465    1.1  drochner 		cpos |= vga_6845_read(&vc->hdl, cursorl);
    466    1.1  drochner 
    467    1.1  drochner 		/* make sure we have a valid cursor position */
    468    1.1  drochner 		if (cpos < 0 || cpos >= type->nrows * type->ncols)
    469    1.1  drochner 			cpos = 0;
    470    1.8  drochner 
    471    1.8  drochner 		scr->pcs.dispoffset = vga_6845_read(&vc->hdl, startadrh) << 9;
    472    1.8  drochner 		scr->pcs.dispoffset |= vga_6845_read(&vc->hdl, startadrl) << 1;
    473    1.8  drochner 
    474    1.8  drochner 		/* make sure we have a valid memory offset */
    475    1.8  drochner 		if (scr->pcs.dispoffset < scr->mindispoffset ||
    476    1.8  drochner 		    scr->pcs.dispoffset > scr->maxdispoffset)
    477    1.8  drochner 			scr->pcs.dispoffset = scr->mindispoffset;
    478   1.40  drochner 
    479   1.40  drochner 		if (type != vc->currenttype) {
    480   1.40  drochner 			vga_setscreentype(&vc->hdl, type);
    481   1.40  drochner 			vc->currenttype = type;
    482   1.40  drochner 		}
    483    1.8  drochner 	} else {
    484    1.8  drochner 		cpos = 0;
    485    1.8  drochner 		scr->pcs.dispoffset = scr->mindispoffset;
    486    1.1  drochner 	}
    487    1.1  drochner 
    488   1.72  christos 	scr->pcs.visibleoffset = scr->pcs.dispoffset;
    489   1.72  christos 	scr->vga_rollover = 0;
    490   1.72  christos 
    491   1.60  junyoung 	scr->pcs.cursorrow = cpos / type->ncols;
    492   1.60  junyoung 	scr->pcs.cursorcol = cpos % type->ncols;
    493   1.25        ad 	pcdisplay_cursor_init(&scr->pcs, existing);
    494    1.1  drochner 
    495    1.1  drochner #ifdef __alpha__
    496    1.4  drochner 	if (!vc->hdl.vh_mono)
    497    1.3  drochner 		/*
    498    1.3  drochner 		 * DEC firmware uses a blue background.
    499   1.75      jmmv 		 * XXX These should be specified as kernel options for
    500   1.75      jmmv 		 * XXX alpha only, not hardcoded here (which is wrong
    501   1.75      jmmv 		 * XXX anyway because the emulation layer will assume
    502   1.75      jmmv 		 * XXX the default attribute is white on black).
    503    1.3  drochner 		 */
    504   1.59  junyoung 		res = vga_allocattr(scr, WSCOL_WHITE, WSCOL_BLUE,
    505   1.66   tsutsui 		    WSATTR_WSCOLORS, attrp);
    506    1.3  drochner 	else
    507    1.3  drochner #endif
    508   1.59  junyoung 	res = vga_allocattr(scr, 0, 0, 0, attrp);
    509    1.3  drochner #ifdef DIAGNOSTIC
    510    1.3  drochner 	if (res)
    511    1.3  drochner 		panic("vga_init_screen: attribute botch");
    512    1.1  drochner #endif
    513    1.1  drochner 
    514    1.4  drochner 	scr->pcs.mem = NULL;
    515   1.15  drochner 
    516   1.15  drochner 	scr->fontset1 = scr->fontset2 = 0;
    517   1.12  drochner 	if (vga_selectfont(vc, scr, 0, 0)) {
    518   1.12  drochner 		if (scr == &vga_console_screen)
    519   1.12  drochner 			panic("vga_init_screen: no font");
    520   1.12  drochner 		else
    521   1.12  drochner 			printf("vga_init_screen: no font\n");
    522   1.12  drochner 	}
    523   1.40  drochner 	if (existing)
    524   1.40  drochner 		vga_setfont(vc, scr);
    525   1.15  drochner 
    526    1.1  drochner 	vc->nscreens++;
    527    1.1  drochner 	LIST_INSERT_HEAD(&vc->screens, scr, next);
    528    1.1  drochner }
    529    1.1  drochner 
    530  1.110   mlelstv static void
    531   1.45  junyoung vga_init(struct vga_config *vc, bus_space_tag_t iot, bus_space_tag_t memt)
    532    1.1  drochner {
    533    1.1  drochner 	struct vga_handle *vh = &vc->hdl;
    534  1.106  christos 	uint8_t mor;
    535   1.12  drochner 	int i;
    536    1.1  drochner 
    537   1.66   tsutsui 	vh->vh_iot = iot;
    538   1.66   tsutsui 	vh->vh_memt = memt;
    539    1.1  drochner 
    540   1.66   tsutsui 	if (bus_space_map(vh->vh_iot, 0x3c0, 0x10, 0, &vh->vh_ioh_vga))
    541   1.66   tsutsui 		panic("vga_init: couldn't map vga io");
    542    1.1  drochner 
    543    1.1  drochner 	/* read "misc output register" */
    544  1.106  christos 	mor = vga_raw_read(vh, VGA_MISC_DATAR);
    545    1.4  drochner 	vh->vh_mono = !(mor & 1);
    546    1.1  drochner 
    547    1.4  drochner 	if (bus_space_map(vh->vh_iot, (vh->vh_mono ? 0x3b0 : 0x3d0), 0x10, 0,
    548   1.66   tsutsui 	    &vh->vh_ioh_6845))
    549   1.66   tsutsui 		panic("vga_init: couldn't map 6845 io");
    550    1.1  drochner 
    551   1.66   tsutsui 	if (bus_space_map(vh->vh_memt, 0xa0000, 0x20000, 0, &vh->vh_allmemh))
    552   1.66   tsutsui 		panic("vga_init: couldn't map memory");
    553    1.1  drochner 
    554   1.66   tsutsui 	if (bus_space_subregion(vh->vh_memt, vh->vh_allmemh,
    555   1.66   tsutsui 	    (vh->vh_mono ? 0x10000 : 0x18000), 0x8000, &vh->vh_memh))
    556   1.66   tsutsui 		panic("vga_init: mem subrange failed");
    557    1.5  drochner 
    558    1.1  drochner 	vc->nscreens = 0;
    559    1.1  drochner 	LIST_INIT(&vc->screens);
    560    1.1  drochner 	vc->active = NULL;
    561   1.34  drochner 	vc->currenttype = vh->vh_mono ? &vga_25lscreen_mono : &vga_25lscreen;
    562   1.93        ad 	callout_init(&vc->vc_switch_callout, 0);
    563   1.12  drochner 
    564   1.68   tsutsui 	wsfont_init();
    565   1.68   tsutsui 	if (vga_no_builtinfont) {
    566   1.68   tsutsui 		struct wsdisplay_font *wf;
    567   1.68   tsutsui 		int cookie;
    568   1.68   tsutsui 
    569   1.68   tsutsui 		cookie = wsfont_find(NULL, 8, 16, 0,
    570  1.108  macallan 		     WSDISPLAY_FONTORDER_L2R, 0, WSFONT_FIND_BITMAP);
    571   1.68   tsutsui 		if (cookie == -1 || wsfont_lock(cookie, &wf))
    572   1.68   tsutsui 			panic("vga_init: can't load console font");
    573   1.68   tsutsui 		vga_loadchars(&vc->hdl, 0, wf->firstchar, wf->numchars,
    574   1.68   tsutsui 		    wf->fontheight, wf->data);
    575   1.68   tsutsui 		vga_builtinfont.wsfont = wf;
    576   1.68   tsutsui 		vga_builtinfont.cookie = cookie;
    577   1.68   tsutsui 		vga_builtinfont.slot = 0;
    578   1.68   tsutsui 	}
    579   1.12  drochner 	vc->vc_fonts[0] = &vga_builtinfont;
    580   1.23  drochner 	for (i = 1; i < 8; i++)
    581   1.12  drochner 		vc->vc_fonts[i] = 0;
    582   1.37  drochner 	TAILQ_INIT(&vc->vc_fontlist);
    583   1.37  drochner 	TAILQ_INSERT_HEAD(&vc->vc_fontlist, &vga_builtinfont, next);
    584   1.12  drochner 
    585   1.12  drochner 	vc->currentfontset1 = vc->currentfontset2 = 0;
    586   1.76      jmmv 
    587   1.78      jmmv 	if (!vh->vh_mono && (u_int)WSDISPLAY_BORDER_COLOR < sizeof(fgansitopc))
    588   1.78      jmmv 		_vga_attr_write(vh, VGA_ATC_OVERSCAN,
    589   1.78      jmmv 		                fgansitopc[WSDISPLAY_BORDER_COLOR]);
    590  1.106  christos 	vga_save_palette(vc);
    591    1.1  drochner }
    592    1.1  drochner 
    593    1.1  drochner void
    594   1.45  junyoung vga_common_attach(struct vga_softc *sc, bus_space_tag_t iot,
    595   1.56  drochner 		  bus_space_tag_t memt, int type, int quirks,
    596   1.56  drochner 		  const struct vga_funcs *vf)
    597   1.28      soda {
    598    1.1  drochner 	int console;
    599    1.1  drochner 	struct vga_config *vc;
    600    1.1  drochner 	struct wsemuldisplaydev_attach_args aa;
    601    1.1  drochner 
    602    1.1  drochner 	console = vga_is_console(iot, type);
    603    1.1  drochner 
    604    1.1  drochner 	if (console) {
    605    1.1  drochner 		vc = &vga_console_vc;
    606    1.1  drochner 		vga_console_attached = 1;
    607    1.1  drochner 	} else {
    608    1.1  drochner 		vc = malloc(sizeof(struct vga_config), M_DEVBUF, M_WAITOK);
    609    1.1  drochner 		vga_init(vc, iot, memt);
    610    1.1  drochner 	}
    611    1.1  drochner 
    612   1.58  drochner 	if (quirks & VGA_QUIRK_ONEFONT) {
    613   1.58  drochner 		vc->vc_nfontslots = 1;
    614   1.58  drochner #ifndef VGA_CONSOLE_ATI_BROKEN_FONTSEL
    615   1.58  drochner 		/*
    616   1.58  drochner 		 * XXX maybe invalidate font in slot > 0, but this can
    617   1.58  drochner 		 * only be happen with VGA_CONSOLE_SCREENTYPE, and then
    618   1.58  drochner 		 * we require VGA_CONSOLE_ATI_BROKEN_FONTSEL anyway.
    619   1.58  drochner 		 */
    620   1.58  drochner #endif
    621   1.58  drochner 	} else {
    622   1.58  drochner 		vc->vc_nfontslots = 8;
    623   1.58  drochner #ifndef VGA_CONSOLE_ATI_BROKEN_FONTSEL
    624   1.58  drochner 		/*
    625   1.58  drochner 		 * XXX maybe validate builtin font shifted to slot 1 if
    626   1.58  drochner 		 * slot 0 got overwritten because of VGA_CONSOLE_SCREENTYPE,
    627   1.58  drochner 		 * but it will be reloaded anyway if needed.
    628   1.58  drochner 		 */
    629   1.58  drochner #endif
    630   1.58  drochner 	}
    631   1.58  drochner 
    632   1.58  drochner 	/*
    633   1.58  drochner 	 * Save the builtin font to memory. In case it got overwritten
    634   1.58  drochner 	 * in console initialization, use the copy in slot 1.
    635   1.58  drochner 	 */
    636   1.58  drochner #ifdef VGA_CONSOLE_ATI_BROKEN_FONTSEL
    637   1.58  drochner #define BUILTINFONTLOC (vga_builtinfont.slot == -1 ? 1 : 0)
    638   1.58  drochner #else
    639   1.58  drochner 	KASSERT(vga_builtinfont.slot == 0);
    640   1.58  drochner #define BUILTINFONTLOC (0)
    641   1.58  drochner #endif
    642   1.68   tsutsui 	if (!vga_no_builtinfont) {
    643   1.69  jdolecek 		char *data =
    644   1.68   tsutsui 		    malloc(256 * vga_builtinfont.wsfont->fontheight,
    645   1.68   tsutsui 		    M_DEVBUF, M_WAITOK);
    646   1.68   tsutsui 		vga_readoutchars(&vc->hdl, BUILTINFONTLOC, 0, 256,
    647   1.69  jdolecek 		    vga_builtinfont.wsfont->fontheight, data);
    648   1.69  jdolecek 		vga_builtinfont.wsfont->data = data;
    649   1.68   tsutsui 	}
    650   1.56  drochner 
    651   1.42   thorpej 	vc->vc_type = type;
    652   1.42   thorpej 	vc->vc_funcs = vf;
    653   1.63  drochner 	vc->vc_quirks = quirks;
    654   1.42   thorpej 
    655   1.42   thorpej 	sc->sc_vc = vc;
    656   1.42   thorpej 	vc->softc = sc;
    657   1.28      soda 
    658    1.1  drochner 	aa.console = console;
    659    1.4  drochner 	aa.scrdata = (vc->hdl.vh_mono ? &vga_screenlist_mono : &vga_screenlist);
    660    1.1  drochner 	aa.accessops = &vga_accessops;
    661    1.1  drochner 	aa.accesscookie = vc;
    662    1.1  drochner 
    663   1.98      cube 	config_found_ia(sc->sc_dev, "wsemuldisplaydev", &aa, wsemuldisplaydevprint);
    664    1.1  drochner }
    665    1.1  drochner 
    666    1.1  drochner int
    667   1.45  junyoung vga_cnattach(bus_space_tag_t iot, bus_space_tag_t memt, int type, int check)
    668    1.1  drochner {
    669    1.3  drochner 	long defattr;
    670    1.3  drochner 	const struct wsscreen_descr *scr;
    671    1.3  drochner 
    672    1.1  drochner 	if (check && !vga_common_probe(iot, memt))
    673    1.1  drochner 		return (ENXIO);
    674    1.1  drochner 
    675    1.1  drochner 	/* set up bus-independent VGA configuration */
    676    1.1  drochner 	vga_init(&vga_console_vc, iot, memt);
    677   1.34  drochner #ifdef VGA_CONSOLE_SCREENTYPE
    678   1.34  drochner 	scr = wsdisplay_screentype_pick(vga_console_vc.hdl.vh_mono ?
    679   1.66   tsutsui 	    &vga_screenlist_mono : &vga_screenlist, VGA_CONSOLE_SCREENTYPE);
    680   1.34  drochner 	if (!scr)
    681   1.34  drochner 		panic("vga_cnattach: invalid screen type");
    682   1.34  drochner #else
    683   1.11  drochner 	scr = vga_console_vc.currenttype;
    684   1.34  drochner #endif
    685   1.56  drochner #ifdef VGA_CONSOLE_ATI_BROKEN_FONTSEL
    686   1.56  drochner 	/*
    687   1.56  drochner 	 * On some (most/all?) ATI cards, only font slot 0 is usable.
    688   1.56  drochner 	 * vga_init_screen() might need font slot 0 for a non-default
    689   1.58  drochner 	 * console font, so save the builtin VGA font to another font slot.
    690   1.58  drochner 	 * The attach() code will take care later.
    691   1.56  drochner 	 */
    692   1.63  drochner 	vga_console_vc.vc_quirks |= VGA_QUIRK_ONEFONT; /* redundant */
    693   1.56  drochner 	vga_copyfont01(&vga_console_vc.hdl);
    694   1.56  drochner 	vga_console_vc.vc_nfontslots = 1;
    695   1.56  drochner #else
    696   1.56  drochner 	vga_console_vc.vc_nfontslots = 8;
    697   1.56  drochner #endif
    698   1.79  christos #ifdef notdef
    699   1.63  drochner 	/* until we know better, assume "fast scrolling" does not work */
    700   1.63  drochner 	vga_console_vc.vc_quirks |= VGA_QUIRK_NOFASTSCROLL;
    701   1.79  christos #endif
    702   1.63  drochner 
    703    1.4  drochner 	vga_init_screen(&vga_console_vc, &vga_console_screen, scr, 1, &defattr);
    704    1.1  drochner 
    705    1.3  drochner 	wsdisplay_cnattach(scr, &vga_console_screen,
    706   1.66   tsutsui 	    vga_console_screen.pcs.cursorcol,
    707   1.66   tsutsui 	    vga_console_screen.pcs.cursorrow, defattr);
    708    1.1  drochner 
    709    1.1  drochner 	vgaconsole = 1;
    710    1.1  drochner 	vga_console_type = type;
    711    1.1  drochner 	return (0);
    712    1.1  drochner }
    713    1.1  drochner 
    714    1.1  drochner int
    715   1.88  jmcneill vga_cndetach(void)
    716   1.88  jmcneill {
    717   1.88  jmcneill 	struct vga_config *vc;
    718   1.88  jmcneill 	struct vga_handle *vh;
    719   1.88  jmcneill 
    720   1.88  jmcneill 	vc = &vga_console_vc;
    721   1.88  jmcneill 	vh = &vc->hdl;
    722   1.88  jmcneill 
    723   1.88  jmcneill 	if (vgaconsole) {
    724  1.112   mlelstv 		wsdisplay_cndetach();
    725  1.112   mlelstv 
    726   1.88  jmcneill 		bus_space_unmap(vh->vh_iot, vh->vh_ioh_vga, 0x10);
    727   1.88  jmcneill 		bus_space_unmap(vh->vh_iot, vh->vh_ioh_6845, 0x10);
    728  1.115   mlelstv 		bus_space_unmap(vh->vh_memt, vh->vh_allmemh, 0x20000);
    729   1.88  jmcneill 
    730  1.112   mlelstv 		vga_console_attached = 0;
    731  1.112   mlelstv 		vgaconsole = 0;
    732  1.112   mlelstv 
    733   1.88  jmcneill 		return 1;
    734   1.88  jmcneill 	}
    735   1.88  jmcneill 
    736   1.88  jmcneill 	return 0;
    737   1.88  jmcneill }
    738   1.88  jmcneill 
    739   1.88  jmcneill int
    740   1.45  junyoung vga_is_console(bus_space_tag_t iot, int type)
    741    1.1  drochner {
    742    1.1  drochner 	if (vgaconsole &&
    743    1.1  drochner 	    !vga_console_attached &&
    744  1.104    dyoung 	    bus_space_is_equal(iot, vga_console_vc.hdl.vh_iot) &&
    745    1.1  drochner 	    (vga_console_type == -1 || (type == vga_console_type)))
    746    1.1  drochner 		return (1);
    747    1.1  drochner 	return (0);
    748    1.1  drochner }
    749    1.1  drochner 
    750   1.46     lukem static int
    751   1.46     lukem vga_get_video(struct vga_config *vc)
    752   1.46     lukem {
    753   1.67   tsutsui 
    754   1.67   tsutsui 	return (vga_ts_read(&vc->hdl, mode) & VGA_TS_MODE_BLANK) == 0;
    755   1.46     lukem }
    756   1.46     lukem 
    757   1.46     lukem static void
    758   1.46     lukem vga_set_video(struct vga_config *vc, int state)
    759   1.46     lukem {
    760   1.46     lukem 	int val;
    761   1.46     lukem 
    762   1.46     lukem 	vga_ts_write(&vc->hdl, syncreset, 0x01);
    763   1.46     lukem 	if (state) {					/* unblank screen */
    764   1.46     lukem 		val = vga_ts_read(&vc->hdl, mode);
    765   1.67   tsutsui 		vga_ts_write(&vc->hdl, mode, val & ~VGA_TS_MODE_BLANK);
    766   1.46     lukem #ifndef VGA_NO_VBLANK
    767   1.46     lukem 		val = vga_6845_read(&vc->hdl, mode);
    768   1.46     lukem 		vga_6845_write(&vc->hdl, mode, val | 0x80);
    769   1.46     lukem #endif
    770   1.46     lukem 	} else {					/* blank screen */
    771   1.46     lukem 		val = vga_ts_read(&vc->hdl, mode);
    772   1.67   tsutsui 		vga_ts_write(&vc->hdl, mode, val | VGA_TS_MODE_BLANK);
    773   1.46     lukem #ifndef VGA_NO_VBLANK
    774   1.46     lukem 		val = vga_6845_read(&vc->hdl, mode);
    775   1.46     lukem 		vga_6845_write(&vc->hdl, mode, val & ~0x80);
    776   1.46     lukem #endif
    777   1.46     lukem 	}
    778   1.46     lukem 	vga_ts_write(&vc->hdl, syncreset, 0x03);
    779   1.46     lukem }
    780   1.46     lukem 
    781  1.110   mlelstv static int
    782   1.92  christos vga_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
    783    1.1  drochner {
    784    1.1  drochner 	struct vga_config *vc = v;
    785   1.87      jmmv 	struct vgascreen *scr = vs;
    786   1.42   thorpej 	const struct vga_funcs *vf = vc->vc_funcs;
    787    1.1  drochner 
    788    1.1  drochner 	switch (cmd) {
    789  1.106  christos 	case WSDISPLAYIO_SMODE:
    790  1.106  christos 		if (*(u_int *)data == WSDISPLAYIO_MODE_EMUL)
    791  1.106  christos 			vga_restore_palette(vc);
    792  1.106  christos 		return 0;
    793  1.106  christos 
    794    1.1  drochner 	case WSDISPLAYIO_GTYPE:
    795    1.1  drochner 		*(int *)data = vc->vc_type;
    796   1.10  augustss 		return 0;
    797   1.12  drochner 
    798    1.1  drochner 	case WSDISPLAYIO_GINFO:
    799   1.42   thorpej 		/* XXX should get detailed hardware information here */
    800   1.49    atatat 		return EPASSTHROUGH;
    801   1.42   thorpej 
    802   1.46     lukem 	case WSDISPLAYIO_GVIDEO:
    803   1.66   tsutsui 		*(int *)data = (vga_get_video(vc) ?
    804   1.66   tsutsui 		    WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF);
    805   1.46     lukem 		return 0;
    806   1.46     lukem 
    807   1.46     lukem 	case WSDISPLAYIO_SVIDEO:
    808   1.46     lukem 		vga_set_video(vc, *(int *)data == WSDISPLAYIO_VIDEO_ON);
    809   1.46     lukem 		return 0;
    810   1.46     lukem 
    811   1.87      jmmv 	case WSDISPLAYIO_GETWSCHAR:
    812   1.87      jmmv 		KASSERT(scr != NULL);
    813   1.87      jmmv 		return pcdisplay_getwschar(&scr->pcs,
    814   1.87      jmmv 		    (struct wsdisplay_char *)data);
    815   1.87      jmmv 
    816   1.87      jmmv 	case WSDISPLAYIO_PUTWSCHAR:
    817   1.87      jmmv 		KASSERT(scr != NULL);
    818   1.87      jmmv 		return pcdisplay_putwschar(&scr->pcs,
    819   1.87      jmmv 		    (struct wsdisplay_char *)data);
    820   1.87      jmmv 
    821   1.85  drochner #ifdef WSDISPLAY_CUSTOM_BORDER
    822   1.85  drochner 	case WSDISPLAYIO_GBORDER:
    823   1.85  drochner 		return (vga_getborder(vc, (u_int *)data));
    824   1.85  drochner 
    825   1.85  drochner 	case WSDISPLAYIO_SBORDER:
    826   1.85  drochner 		return (vga_setborder(vc, *(u_int *)data));
    827   1.85  drochner #endif
    828   1.85  drochner 
    829    1.1  drochner 	case WSDISPLAYIO_GETCMAP:
    830    1.1  drochner 	case WSDISPLAYIO_PUTCMAP:
    831    1.1  drochner 	case WSDISPLAYIO_GCURPOS:
    832    1.1  drochner 	case WSDISPLAYIO_SCURPOS:
    833    1.1  drochner 	case WSDISPLAYIO_GCURMAX:
    834    1.1  drochner 	case WSDISPLAYIO_GCURSOR:
    835    1.1  drochner 	case WSDISPLAYIO_SCURSOR:
    836    1.1  drochner 		/* NONE of these operations are by the generic VGA driver. */
    837   1.49    atatat 		return EPASSTHROUGH;
    838    1.1  drochner 	}
    839   1.12  drochner 
    840   1.42   thorpej 	if (vc->vc_funcs == NULL)
    841   1.49    atatat 		return (EPASSTHROUGH);
    842   1.42   thorpej 
    843   1.42   thorpej 	if (vf->vf_ioctl == NULL)
    844   1.49    atatat 		return (EPASSTHROUGH);
    845   1.42   thorpej 
    846   1.83  christos 	return ((*vf->vf_ioctl)(v, cmd, data, flag, l));
    847    1.1  drochner }
    848    1.1  drochner 
    849   1.29    simonb static paddr_t
    850   1.91  christos vga_mmap(void *v, void *vs, off_t offset, int prot)
    851    1.1  drochner {
    852   1.42   thorpej 	struct vga_config *vc = v;
    853   1.42   thorpej 	const struct vga_funcs *vf = vc->vc_funcs;
    854    1.1  drochner 
    855   1.42   thorpej 	if (vc->vc_funcs == NULL)
    856   1.42   thorpej 		return (-1);
    857   1.28      soda 
    858   1.42   thorpej 	if (vf->vf_mmap == NULL)
    859   1.42   thorpej 		return (-1);
    860   1.32   thorpej 
    861   1.42   thorpej 	return ((*vf->vf_mmap)(v, offset, prot));
    862    1.1  drochner }
    863    1.1  drochner 
    864  1.110   mlelstv static int
    865   1.45  junyoung vga_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
    866   1.45  junyoung 		 int *curxp, int *curyp, long *defattrp)
    867    1.1  drochner {
    868    1.1  drochner 	struct vga_config *vc = v;
    869    1.1  drochner 	struct vgascreen *scr;
    870    1.1  drochner 
    871    1.1  drochner 	if (vc->nscreens == 1) {
    872   1.38  drochner 		struct vgascreen *scr1 = vc->screens.lh_first;
    873    1.1  drochner 		/*
    874    1.1  drochner 		 * When allocating the second screen, get backing store
    875    1.1  drochner 		 * for the first one too.
    876    1.1  drochner 		 * XXX We could be more clever and use video RAM.
    877    1.1  drochner 		 */
    878   1.38  drochner 		scr1->pcs.mem =
    879   1.66   tsutsui 		    malloc(scr1->pcs.type->ncols * scr1->pcs.type->nrows * 2,
    880   1.66   tsutsui 		    M_DEVBUF, M_WAITOK);
    881    1.1  drochner 	}
    882    1.1  drochner 
    883    1.1  drochner 	scr = malloc(sizeof(struct vgascreen), M_DEVBUF, M_WAITOK);
    884    1.4  drochner 	vga_init_screen(vc, scr, type, vc->nscreens == 0, defattrp);
    885    1.1  drochner 
    886   1.39  drochner 	if (vc->nscreens > 1) {
    887    1.4  drochner 		scr->pcs.mem = malloc(type->ncols * type->nrows * 2,
    888   1.66   tsutsui 		    M_DEVBUF, M_WAITOK);
    889    1.4  drochner 		pcdisplay_eraserows(&scr->pcs, 0, type->nrows, *defattrp);
    890    1.1  drochner 	}
    891    1.1  drochner 
    892    1.1  drochner 	*cookiep = scr;
    893   1.60  junyoung 	*curxp = scr->pcs.cursorcol;
    894   1.60  junyoung 	*curyp = scr->pcs.cursorrow;
    895    1.1  drochner 
    896    1.1  drochner 	return (0);
    897    1.1  drochner }
    898    1.1  drochner 
    899  1.110   mlelstv static void
    900   1.91  christos vga_free_screen(void *v, void *cookie)
    901    1.1  drochner {
    902    1.1  drochner 	struct vgascreen *vs = cookie;
    903   1.11  drochner 	struct vga_config *vc = vs->cfg;
    904    1.1  drochner 
    905    1.1  drochner 	LIST_REMOVE(vs, next);
    906   1.82       dbj 	vc->nscreens--;
    907   1.38  drochner 	if (vs->fontset1)
    908   1.38  drochner 		egavga_unreffont(vc, vs->fontset1);
    909   1.38  drochner 	if (vs->fontset2)
    910   1.38  drochner 		egavga_unreffont(vc, vs->fontset2);
    911   1.38  drochner 
    912    1.1  drochner 	if (vs != &vga_console_screen)
    913    1.1  drochner 		free(vs, M_DEVBUF);
    914    1.1  drochner 	else
    915    1.1  drochner 		panic("vga_free_screen: console");
    916   1.11  drochner 
    917   1.11  drochner 	if (vc->active == vs)
    918   1.11  drochner 		vc->active = 0;
    919    1.1  drochner }
    920    1.1  drochner 
    921   1.40  drochner static void vga_usefont(struct vga_config *, struct egavga_font *);
    922   1.37  drochner 
    923   1.40  drochner static void
    924   1.45  junyoung vga_usefont(struct vga_config *vc, struct egavga_font *f)
    925   1.37  drochner {
    926   1.37  drochner 	int slot;
    927   1.37  drochner 	struct egavga_font *of;
    928   1.37  drochner 
    929   1.37  drochner 	if (f->slot != -1)
    930   1.37  drochner 		goto toend;
    931   1.37  drochner 
    932   1.51  drochner 	for (slot = 0; slot < vc->vc_nfontslots; slot++) {
    933   1.37  drochner 		if (!vc->vc_fonts[slot])
    934   1.37  drochner 			goto loadit;
    935   1.37  drochner 	}
    936   1.37  drochner 
    937   1.37  drochner 	/* have to kick out another one */
    938   1.37  drochner 	TAILQ_FOREACH(of, &vc->vc_fontlist, next) {
    939   1.37  drochner 		if (of->slot != -1) {
    940   1.37  drochner 			KASSERT(vc->vc_fonts[of->slot] == of);
    941   1.37  drochner 			slot = of->slot;
    942   1.37  drochner 			of->slot = -1;
    943   1.37  drochner 			goto loadit;
    944   1.37  drochner 		}
    945   1.37  drochner 	}
    946   1.54  junyoung 	panic("vga_usefont");
    947   1.37  drochner 
    948   1.37  drochner loadit:
    949   1.52  drochner 	vga_loadchars(&vc->hdl, slot, f->wsfont->firstchar,
    950   1.66   tsutsui 	    f->wsfont->numchars, f->wsfont->fontheight, f->wsfont->data);
    951   1.37  drochner 	f->slot = slot;
    952   1.37  drochner 	vc->vc_fonts[slot] = f;
    953   1.37  drochner 
    954   1.37  drochner toend:
    955   1.37  drochner 	TAILQ_REMOVE(&vc->vc_fontlist, f, next);
    956   1.37  drochner 	TAILQ_INSERT_TAIL(&vc->vc_fontlist, f, next);
    957   1.37  drochner }
    958   1.37  drochner 
    959   1.12  drochner static void
    960   1.45  junyoung vga_setfont(struct vga_config *vc, struct vgascreen *scr)
    961   1.12  drochner {
    962   1.12  drochner 	int fontslot1, fontslot2;
    963   1.12  drochner 
    964   1.37  drochner 	if (scr->fontset1)
    965   1.37  drochner 		vga_usefont(vc, scr->fontset1);
    966   1.37  drochner 	if (scr->fontset2)
    967   1.37  drochner 		vga_usefont(vc, scr->fontset2);
    968   1.37  drochner 
    969   1.12  drochner 	fontslot1 = (scr->fontset1 ? scr->fontset1->slot : 0);
    970   1.12  drochner 	fontslot2 = (scr->fontset2 ? scr->fontset2->slot : fontslot1);
    971   1.12  drochner 	if (vc->currentfontset1 != fontslot1 ||
    972   1.12  drochner 	    vc->currentfontset2 != fontslot2) {
    973   1.12  drochner 		vga_setfontset(&vc->hdl, fontslot1, fontslot2);
    974   1.12  drochner 		vc->currentfontset1 = fontslot1;
    975   1.12  drochner 		vc->currentfontset2 = fontslot2;
    976   1.12  drochner 	}
    977   1.12  drochner }
    978   1.12  drochner 
    979  1.110   mlelstv static int
    980   1.91  christos vga_show_screen(void *v, void *cookie, int waitok,
    981   1.45  junyoung 		void (*cb)(void *, int, int), void *cbarg)
    982    1.1  drochner {
    983    1.4  drochner 	struct vgascreen *scr = cookie, *oldscr;
    984    1.1  drochner 	struct vga_config *vc = scr->cfg;
    985   1.22  drochner 
    986   1.22  drochner 	oldscr = vc->active; /* can be NULL! */
    987   1.22  drochner 	if (scr == oldscr) {
    988   1.22  drochner 		return (0);
    989   1.22  drochner 	}
    990   1.22  drochner 
    991   1.22  drochner 	vc->wantedscreen = cookie;
    992   1.22  drochner 	vc->switchcb = cb;
    993   1.22  drochner 	vc->switchcbarg = cbarg;
    994   1.22  drochner 	if (cb) {
    995   1.26   thorpej 		callout_reset(&vc->vc_switch_callout, 0,
    996   1.26   thorpej 		    (void(*)(void *))vga_doswitch, vc);
    997   1.22  drochner 		return (EAGAIN);
    998   1.22  drochner 	}
    999   1.22  drochner 
   1000   1.22  drochner 	vga_doswitch(vc);
   1001   1.22  drochner 	return (0);
   1002   1.22  drochner }
   1003   1.22  drochner 
   1004  1.110   mlelstv static void
   1005   1.45  junyoung vga_doswitch(struct vga_config *vc)
   1006   1.22  drochner {
   1007   1.22  drochner 	struct vgascreen *scr, *oldscr;
   1008    1.1  drochner 	struct vga_handle *vh = &vc->hdl;
   1009   1.22  drochner 	const struct wsscreen_descr *type;
   1010    1.1  drochner 
   1011   1.22  drochner 	scr = vc->wantedscreen;
   1012   1.22  drochner 	if (!scr) {
   1013   1.22  drochner 		printf("vga_doswitch: disappeared\n");
   1014   1.22  drochner 		(*vc->switchcb)(vc->switchcbarg, EIO, 0);
   1015   1.22  drochner 		return;
   1016   1.22  drochner 	}
   1017   1.22  drochner 	type = scr->pcs.type;
   1018   1.11  drochner 	oldscr = vc->active; /* can be NULL! */
   1019    1.4  drochner #ifdef DIAGNOSTIC
   1020   1.11  drochner 	if (oldscr) {
   1021   1.11  drochner 		if (!oldscr->pcs.active)
   1022   1.11  drochner 			panic("vga_show_screen: not active");
   1023   1.11  drochner 		if (oldscr->pcs.type != vc->currenttype)
   1024   1.11  drochner 			panic("vga_show_screen: bad type");
   1025   1.11  drochner 	}
   1026    1.4  drochner #endif
   1027    1.4  drochner 	if (scr == oldscr) {
   1028    1.1  drochner 		return;
   1029    1.4  drochner 	}
   1030    1.4  drochner #ifdef DIAGNOSTIC
   1031    1.4  drochner 	if (scr->pcs.active)
   1032    1.4  drochner 		panic("vga_show_screen: active");
   1033    1.4  drochner #endif
   1034    1.4  drochner 
   1035   1.11  drochner 	if (oldscr) {
   1036   1.11  drochner 		const struct wsscreen_descr *oldtype = oldscr->pcs.type;
   1037    1.1  drochner 
   1038   1.11  drochner 		oldscr->pcs.active = 0;
   1039   1.11  drochner 		bus_space_read_region_2(vh->vh_memt, vh->vh_memh,
   1040   1.66   tsutsui 		    oldscr->pcs.dispoffset, oldscr->pcs.mem,
   1041   1.66   tsutsui 		    oldtype->ncols * oldtype->nrows);
   1042   1.11  drochner 	}
   1043    1.1  drochner 
   1044   1.11  drochner 	if (vc->currenttype != type) {
   1045    1.4  drochner 		vga_setscreentype(vh, type);
   1046   1.11  drochner 		vc->currenttype = type;
   1047   1.11  drochner 	}
   1048   1.12  drochner 
   1049   1.12  drochner 	vga_setfont(vc, scr);
   1050  1.106  christos 	vga_restore_palette(vc);
   1051    1.1  drochner 
   1052   1.80   mycroft 	scr->pcs.visibleoffset = scr->pcs.dispoffset = scr->mindispoffset;
   1053   1.11  drochner 	if (!oldscr || (scr->pcs.dispoffset != oldscr->pcs.dispoffset)) {
   1054    1.8  drochner 		vga_6845_write(vh, startadrh, scr->pcs.dispoffset >> 9);
   1055    1.8  drochner 		vga_6845_write(vh, startadrl, scr->pcs.dispoffset >> 1);
   1056    1.8  drochner 	}
   1057    1.8  drochner 
   1058   1.11  drochner 	bus_space_write_region_2(vh->vh_memt, vh->vh_memh,
   1059   1.66   tsutsui 	    scr->pcs.dispoffset, scr->pcs.mem, type->ncols * type->nrows);
   1060   1.11  drochner 	scr->pcs.active = 1;
   1061    1.1  drochner 
   1062    1.4  drochner 	vc->active = scr;
   1063    1.1  drochner 
   1064    1.4  drochner 	pcdisplay_cursor(&scr->pcs, scr->pcs.cursoron,
   1065   1.66   tsutsui 	    scr->pcs.cursorrow, scr->pcs.cursorcol);
   1066   1.22  drochner 
   1067   1.22  drochner 	vc->wantedscreen = 0;
   1068   1.22  drochner 	if (vc->switchcb)
   1069   1.22  drochner 		(*vc->switchcb)(vc->switchcbarg, 0, 0);
   1070    1.1  drochner }
   1071    1.1  drochner 
   1072    1.1  drochner static int
   1073   1.45  junyoung vga_load_font(void *v, void *cookie, struct wsdisplay_font *data)
   1074    1.1  drochner {
   1075   1.12  drochner 	struct vga_config *vc = v;
   1076    1.1  drochner 	struct vgascreen *scr = cookie;
   1077   1.12  drochner 	char *name2;
   1078   1.37  drochner 	int res;
   1079   1.12  drochner 
   1080   1.12  drochner 	if (scr) {
   1081   1.50   hannken 		name2 = NULL;
   1082   1.50   hannken 		if (data->name) {
   1083   1.50   hannken 			name2 = strchr(data->name, ',');
   1084   1.50   hannken 			if (name2)
   1085   1.50   hannken 				*name2++ = '\0';
   1086   1.50   hannken 		}
   1087   1.12  drochner 		res = vga_selectfont(vc, scr, data->name, name2);
   1088   1.52  drochner 		if (!res && scr->pcs.active)
   1089   1.12  drochner 			vga_setfont(vc, scr);
   1090   1.12  drochner 		return (res);
   1091   1.12  drochner 	}
   1092    1.1  drochner 
   1093    1.1  drochner 	return (0);
   1094    1.1  drochner }
   1095    1.1  drochner 
   1096    1.3  drochner static int
   1097   1.59  junyoung vga_allocattr(void *id, int fg, int bg, int flags, long *attrp)
   1098    1.3  drochner {
   1099    1.3  drochner 	struct vgascreen *scr = id;
   1100    1.3  drochner 	struct vga_config *vc = scr->cfg;
   1101    1.3  drochner 
   1102   1.95       mjf 	if (__predict_false((unsigned int)fg >= sizeof(fgansitopc) ||
   1103   1.95       mjf 	    (unsigned int)bg >= sizeof(bgansitopc)))
   1104   1.95       mjf 		return (EINVAL);
   1105   1.95       mjf 
   1106    1.4  drochner 	if (vc->hdl.vh_mono) {
   1107    1.3  drochner 		if (flags & WSATTR_WSCOLORS)
   1108    1.3  drochner 			return (EINVAL);
   1109    1.3  drochner 		if (flags & WSATTR_REVERSE)
   1110    1.3  drochner 			*attrp = 0x70;
   1111    1.3  drochner 		else
   1112    1.3  drochner 			*attrp = 0x07;
   1113    1.3  drochner 		if (flags & WSATTR_UNDERLINE)
   1114    1.3  drochner 			*attrp |= FG_UNDERLINE;
   1115    1.3  drochner 		if (flags & WSATTR_HILIT)
   1116    1.3  drochner 			*attrp |= FG_INTENSE;
   1117    1.3  drochner 	} else {
   1118    1.3  drochner 		if (flags & (WSATTR_UNDERLINE | WSATTR_REVERSE))
   1119    1.3  drochner 			return (EINVAL);
   1120    1.3  drochner 		if (flags & WSATTR_WSCOLORS)
   1121    1.3  drochner 			*attrp = fgansitopc[fg] | bgansitopc[bg];
   1122    1.3  drochner 		else
   1123    1.3  drochner 			*attrp = 7;
   1124    1.3  drochner 		if (flags & WSATTR_HILIT)
   1125    1.3  drochner 			*attrp += 8;
   1126    1.3  drochner 	}
   1127    1.3  drochner 	if (flags & WSATTR_BLINK)
   1128    1.3  drochner 		*attrp |= FG_BLINK;
   1129    1.3  drochner 	return (0);
   1130    1.8  drochner }
   1131    1.8  drochner 
   1132   1.45  junyoung static void
   1133   1.45  junyoung vga_copyrows(void *id, int srcrow, int dstrow, int nrows)
   1134    1.8  drochner {
   1135    1.8  drochner 	struct vgascreen *scr = id;
   1136    1.8  drochner 	bus_space_tag_t memt = scr->pcs.hdl->ph_memt;
   1137    1.8  drochner 	bus_space_handle_t memh = scr->pcs.hdl->ph_memh;
   1138    1.8  drochner 	int ncols = scr->pcs.type->ncols;
   1139    1.8  drochner 	bus_size_t srcoff, dstoff;
   1140    1.8  drochner 
   1141    1.8  drochner 	srcoff = srcrow * ncols + 0;
   1142    1.8  drochner 	dstoff = dstrow * ncols + 0;
   1143    1.8  drochner 
   1144    1.8  drochner 	if (scr->pcs.active) {
   1145    1.8  drochner 		if (dstrow == 0 && (srcrow + nrows == scr->pcs.type->nrows)) {
   1146   1.18        ad #ifdef PCDISPLAY_SOFTCURSOR
   1147   1.20        ad 			int cursoron = scr->pcs.cursoron;
   1148   1.20        ad 
   1149   1.21   mycroft 			if (cursoron)
   1150   1.21   mycroft 				pcdisplay_cursor(&scr->pcs, 0,
   1151   1.60  junyoung 				    scr->pcs.cursorrow, scr->pcs.cursorcol);
   1152   1.18        ad #endif
   1153    1.8  drochner 			/* scroll up whole screen */
   1154    1.8  drochner 			if ((scr->pcs.dispoffset + srcrow * ncols * 2)
   1155    1.8  drochner 			    <= scr->maxdispoffset) {
   1156    1.8  drochner 				scr->pcs.dispoffset += srcrow * ncols * 2;
   1157    1.8  drochner 			} else {
   1158    1.8  drochner 				bus_space_copy_region_2(memt, memh,
   1159   1.66   tsutsui 				    scr->pcs.dispoffset + srcoff * 2,
   1160   1.66   tsutsui 				    memh, scr->mindispoffset, nrows * ncols);
   1161    1.8  drochner 				scr->pcs.dispoffset = scr->mindispoffset;
   1162    1.8  drochner 			}
   1163    1.8  drochner 			vga_6845_write(&scr->cfg->hdl, startadrh,
   1164   1.66   tsutsui 			    scr->pcs.dispoffset >> 9);
   1165    1.8  drochner 			vga_6845_write(&scr->cfg->hdl, startadrl,
   1166   1.66   tsutsui 			    scr->pcs.dispoffset >> 1);
   1167   1.18        ad #ifdef PCDISPLAY_SOFTCURSOR
   1168   1.21   mycroft 			if (cursoron)
   1169   1.21   mycroft 				pcdisplay_cursor(&scr->pcs, 1,
   1170   1.60  junyoung 				    scr->pcs.cursorrow, scr->pcs.cursorcol);
   1171   1.18        ad #endif
   1172    1.8  drochner 		} else {
   1173    1.8  drochner 			bus_space_copy_region_2(memt, memh,
   1174   1.66   tsutsui 			    scr->pcs.dispoffset + srcoff * 2,
   1175   1.66   tsutsui 			    memh, scr->pcs.dispoffset + dstoff * 2,
   1176   1.66   tsutsui 			    nrows * ncols);
   1177    1.8  drochner 		}
   1178    1.8  drochner 	} else
   1179   1.36   thorpej 		memcpy(&scr->pcs.mem[dstoff], &scr->pcs.mem[srcoff],
   1180   1.66   tsutsui 		    nrows * ncols * 2);
   1181   1.12  drochner }
   1182   1.12  drochner 
   1183   1.12  drochner #ifdef WSCONS_SUPPORT_PCVTFONTS
   1184   1.12  drochner 
   1185   1.12  drochner #define NOTYET 0xffff
   1186  1.106  christos static const uint16_t pcvt_unichars[0xa0] = {
   1187   1.44     bjh21 /* 0 */	_e006U, /* N/L control */
   1188   1.14  drochner 	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1189   1.12  drochner 	NOTYET,
   1190   1.12  drochner 	0x2409, /* SYMBOL FOR HORIZONTAL TABULATION */
   1191   1.12  drochner 	0x240a, /* SYMBOL FOR LINE FEED */
   1192   1.12  drochner 	0x240b, /* SYMBOL FOR VERTICAL TABULATION */
   1193   1.12  drochner 	0x240c, /* SYMBOL FOR FORM FEED */
   1194   1.12  drochner 	0x240d, /* SYMBOL FOR CARRIAGE RETURN */
   1195   1.12  drochner 	NOTYET, NOTYET,
   1196   1.14  drochner /* 1 */	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1197   1.12  drochner 	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1198   1.12  drochner /* 2 */	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1199   1.12  drochner 	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1200   1.14  drochner /* 3 */	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1201   1.12  drochner 	NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET, NOTYET,
   1202   1.12  drochner /* 4 */	0x03c1, /* GREEK SMALL LETTER RHO */
   1203   1.12  drochner 	0x03c8, /* GREEK SMALL LETTER PSI */
   1204   1.12  drochner 	0x2202, /* PARTIAL DIFFERENTIAL */
   1205   1.12  drochner 	0x03bb, /* GREEK SMALL LETTER LAMDA */
   1206   1.12  drochner 	0x03b9, /* GREEK SMALL LETTER IOTA */
   1207   1.12  drochner 	0x03b7, /* GREEK SMALL LETTER ETA */
   1208   1.12  drochner 	0x03b5, /* GREEK SMALL LETTER EPSILON */
   1209   1.12  drochner 	0x03c7, /* GREEK SMALL LETTER CHI */
   1210   1.12  drochner 	0x2228, /* LOGICAL OR */
   1211   1.12  drochner 	0x2227, /* LOGICAL AND */
   1212   1.12  drochner 	0x222a, /* UNION */
   1213   1.12  drochner 	0x2283, /* SUPERSET OF */
   1214   1.12  drochner 	0x2282, /* SUBSET OF */
   1215   1.12  drochner 	0x03a5, /* GREEK CAPITAL LETTER UPSILON */
   1216   1.12  drochner 	0x039e, /* GREEK CAPITAL LETTER XI */
   1217   1.12  drochner 	0x03a8, /* GREEK CAPITAL LETTER PSI */
   1218   1.14  drochner /* 5 */	0x03a0, /* GREEK CAPITAL LETTER PI */
   1219   1.12  drochner 	0x21d2, /* RIGHTWARDS DOUBLE ARROW */
   1220   1.12  drochner 	0x21d4, /* LEFT RIGHT DOUBLE ARROW */
   1221   1.12  drochner 	0x039b, /* GREEK CAPITAL LETTER LAMDA */
   1222   1.12  drochner 	0x0398, /* GREEK CAPITAL LETTER THETA */
   1223   1.12  drochner 	0x2243, /* ASYMPTOTICALLY EQUAL TO */
   1224   1.12  drochner 	0x2207, /* NABLA */
   1225   1.12  drochner 	0x2206, /* INCREMENT */
   1226   1.12  drochner 	0x221d, /* PROPORTIONAL TO */
   1227   1.12  drochner 	0x2234, /* THEREFORE */
   1228   1.12  drochner 	0x222b, /* INTEGRAL */
   1229   1.12  drochner 	0x2215, /* DIVISION SLASH */
   1230   1.12  drochner 	0x2216, /* SET MINUS */
   1231   1.44     bjh21 	_e00eU, /* angle? */
   1232   1.44     bjh21 	_e00dU, /* inverted angle? */
   1233   1.44     bjh21 	_e00bU, /* braceleftmid */
   1234   1.44     bjh21 /* 6 */	_e00cU, /* bracerightmid */
   1235   1.44     bjh21 	_e007U, /* bracelefttp */
   1236   1.44     bjh21 	_e008U, /* braceleftbt */
   1237   1.44     bjh21 	_e009U, /* bracerighttp */
   1238   1.44     bjh21 	_e00aU, /* bracerightbt */
   1239   1.12  drochner 	0x221a, /* SQUARE ROOT */
   1240   1.12  drochner 	0x03c9, /* GREEK SMALL LETTER OMEGA */
   1241   1.12  drochner 	0x00a5, /* YEN SIGN */
   1242   1.12  drochner 	0x03be, /* GREEK SMALL LETTER XI */
   1243   1.12  drochner 	0x00fd, /* LATIN SMALL LETTER Y WITH ACUTE */
   1244   1.12  drochner 	0x00fe, /* LATIN SMALL LETTER THORN */
   1245   1.12  drochner 	0x00f0, /* LATIN SMALL LETTER ETH */
   1246   1.12  drochner 	0x00de, /* LATIN CAPITAL LETTER THORN */
   1247   1.12  drochner 	0x00dd, /* LATIN CAPITAL LETTER Y WITH ACUTE */
   1248   1.12  drochner 	0x00d7, /* MULTIPLICATION SIGN */
   1249   1.12  drochner 	0x00d0, /* LATIN CAPITAL LETTER ETH */
   1250   1.14  drochner /* 7 */	0x00be, /* VULGAR FRACTION THREE QUARTERS */
   1251   1.12  drochner 	0x00b8, /* CEDILLA */
   1252   1.12  drochner 	0x00b4, /* ACUTE ACCENT */
   1253   1.12  drochner 	0x00af, /* MACRON */
   1254   1.12  drochner 	0x00ae, /* REGISTERED SIGN */
   1255   1.12  drochner 	0x00ad, /* SOFT HYPHEN */
   1256   1.12  drochner 	0x00ac, /* NOT SIGN */
   1257   1.12  drochner 	0x00a8, /* DIAERESIS */
   1258   1.12  drochner 	0x2260, /* NOT EQUAL TO */
   1259  1.102  drochner 	0x23bd, /* scan 9 */
   1260  1.102  drochner 	0x23bc, /* scan 7 */
   1261  1.102  drochner 	0x2500, /* scan 5 */
   1262  1.102  drochner 	0x23bb, /* scan 3 */
   1263  1.102  drochner 	0x23ba, /* scan 1 */
   1264   1.12  drochner 	0x03c5, /* GREEK SMALL LETTER UPSILON */
   1265   1.12  drochner 	0x00f8, /* LATIN SMALL LETTER O WITH STROKE */
   1266   1.12  drochner /* 8 */	0x0153, /* LATIN SMALL LIGATURE OE */
   1267   1.12  drochner 	0x00f5, /* LATIN SMALL LETTER O WITH TILDE !!!doc bug */
   1268   1.12  drochner 	0x00e3, /* LATIN SMALL LETTER A WITH TILDE */
   1269   1.12  drochner 	0x0178, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
   1270   1.12  drochner 	0x00db, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
   1271   1.12  drochner 	0x00da, /* LATIN CAPITAL LETTER U WITH ACUTE */
   1272   1.12  drochner 	0x00d9, /* LATIN CAPITAL LETTER U WITH GRAVE */
   1273   1.12  drochner 	0x00d8, /* LATIN CAPITAL LETTER O WITH STROKE */
   1274   1.12  drochner 	0x0152, /* LATIN CAPITAL LIGATURE OE */
   1275   1.12  drochner 	0x00d5, /* LATIN CAPITAL LETTER O WITH TILDE */
   1276   1.12  drochner 	0x00d4, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
   1277   1.12  drochner 	0x00d3, /* LATIN CAPITAL LETTER O WITH ACUTE */
   1278   1.12  drochner 	0x00d2, /* LATIN CAPITAL LETTER O WITH GRAVE */
   1279   1.12  drochner 	0x00cf, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
   1280   1.12  drochner 	0x00ce, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
   1281   1.12  drochner 	0x00cd, /* LATIN CAPITAL LETTER I WITH ACUTE */
   1282   1.14  drochner /* 9 */	0x00cc, /* LATIN CAPITAL LETTER I WITH GRAVE */
   1283   1.12  drochner 	0x00cb, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
   1284   1.12  drochner 	0x00ca, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
   1285   1.12  drochner 	0x00c8, /* LATIN CAPITAL LETTER E WITH GRAVE */
   1286   1.12  drochner 	0x00c3, /* LATIN CAPITAL LETTER A WITH TILDE */
   1287   1.12  drochner 	0x00c2, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
   1288   1.12  drochner 	0x00c1, /* LATIN CAPITAL LETTER A WITH ACUTE */
   1289   1.12  drochner 	0x00c0, /* LATIN CAPITAL LETTER A WITH GRAVE */
   1290   1.12  drochner 	0x00b9, /* SUPERSCRIPT ONE */
   1291   1.12  drochner 	0x00b7, /* MIDDLE DOT */
   1292   1.12  drochner 	0x03b6, /* GREEK SMALL LETTER ZETA */
   1293   1.12  drochner 	0x00b3, /* SUPERSCRIPT THREE */
   1294   1.12  drochner 	0x00a9, /* COPYRIGHT SIGN */
   1295   1.12  drochner 	0x00a4, /* CURRENCY SIGN */
   1296   1.12  drochner 	0x03ba, /* GREEK SMALL LETTER KAPPA */
   1297   1.44     bjh21 	_e000U  /* mirrored question mark? */
   1298   1.12  drochner };
   1299   1.12  drochner 
   1300   1.45  junyoung static int vga_pcvt_mapchar(int, u_int *);
   1301   1.12  drochner 
   1302   1.12  drochner static int
   1303   1.45  junyoung vga_pcvt_mapchar(int uni, u_int *index)
   1304   1.12  drochner {
   1305   1.12  drochner 	int i;
   1306   1.12  drochner 
   1307   1.12  drochner 	for (i = 0; i < 0xa0; i++) /* 0xa0..0xff are reserved */
   1308   1.13  drochner 		if (uni == pcvt_unichars[i]) {
   1309   1.13  drochner 			*index = i;
   1310   1.13  drochner 			return (5);
   1311   1.13  drochner 		}
   1312   1.13  drochner 	*index = 0x99; /* middle dot */
   1313   1.13  drochner 	return (0);
   1314   1.12  drochner }
   1315   1.12  drochner 
   1316   1.12  drochner #endif /* WSCONS_SUPPORT_PCVTFONTS */
   1317   1.12  drochner 
   1318   1.34  drochner #ifdef WSCONS_SUPPORT_ISO7FONTS
   1319   1.34  drochner 
   1320   1.34  drochner static int
   1321   1.45  junyoung vga_iso7_mapchar(int uni, u_int *index)
   1322   1.34  drochner {
   1323   1.34  drochner 
   1324   1.34  drochner 	/*
   1325   1.34  drochner 	 * U+0384 (GREEK TONOS) to
   1326   1.34  drochner 	 * U+03ce (GREEK SMALL LETTER OMEGA WITH TONOS)
   1327   1.34  drochner 	 * map directly to the iso-9 font
   1328   1.34  drochner 	 */
   1329   1.34  drochner 	if (uni >= 0x0384 && uni <= 0x03ce) {
   1330   1.34  drochner 		/* U+0384 is at offset 0xb4 in the font */
   1331   1.34  drochner 		*index = uni - 0x0384 + 0xb4;
   1332   1.34  drochner 		return (5);
   1333   1.34  drochner 	}
   1334   1.34  drochner 
   1335   1.34  drochner 	/* XXX more chars in the iso-9 font */
   1336   1.34  drochner 
   1337   1.34  drochner 	*index = 0xa4; /* shaded rectangle */
   1338   1.34  drochner 	return (0);
   1339   1.34  drochner }
   1340   1.34  drochner 
   1341   1.34  drochner #endif /* WSCONS_SUPPORT_ISO7FONTS */
   1342   1.34  drochner 
   1343  1.107  drochner static const uint16_t iso2_unichars[0x60] = {
   1344  1.107  drochner 	0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
   1345  1.107  drochner 	0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
   1346  1.107  drochner 	0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
   1347  1.107  drochner 	0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
   1348  1.107  drochner 	0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
   1349  1.107  drochner 	0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
   1350  1.107  drochner 	0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
   1351  1.107  drochner 	0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
   1352  1.107  drochner 	0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
   1353  1.107  drochner 	0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
   1354  1.107  drochner 	0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
   1355  1.107  drochner 	0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
   1356  1.107  drochner };
   1357  1.107  drochner 
   1358  1.107  drochner static const uint16_t koi8_unichars[0x40] = {
   1359  1.107  drochner 	0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
   1360  1.107  drochner 	0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
   1361  1.107  drochner 	0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
   1362  1.107  drochner 	0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
   1363  1.107  drochner 	0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
   1364  1.107  drochner 	0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
   1365  1.107  drochner 	0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
   1366  1.107  drochner 	0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A
   1367  1.107  drochner };
   1368  1.107  drochner 
   1369   1.45  junyoung static int _vga_mapchar(void *, const struct egavga_font *, int, u_int *);
   1370   1.12  drochner 
   1371   1.12  drochner static int
   1372   1.45  junyoung _vga_mapchar(void *id, const struct egavga_font *font, int uni, u_int *index)
   1373   1.12  drochner {
   1374   1.12  drochner 
   1375   1.37  drochner 	switch (font->wsfont->encoding) {
   1376   1.12  drochner 	case WSDISPLAY_FONTENC_ISO:
   1377   1.13  drochner 		if (uni < 256) {
   1378   1.13  drochner 			*index = uni;
   1379   1.13  drochner 			return (5);
   1380   1.13  drochner 		} else {
   1381   1.13  drochner 			*index = ' ';
   1382   1.13  drochner 			return (0);
   1383   1.13  drochner 		}
   1384  1.107  drochner 	case WSDISPLAY_FONTENC_ISO2:
   1385  1.107  drochner 		if (uni < 0xa0) {
   1386  1.107  drochner 			*index = uni;
   1387  1.107  drochner 			return (5);
   1388  1.107  drochner 		} else {
   1389  1.107  drochner 			int i;
   1390  1.107  drochner 			for (i = 0; i < 0x60; i++) {
   1391  1.107  drochner 				if (uni == iso2_unichars[i]) {
   1392  1.107  drochner 					*index = i + 0xa0;
   1393  1.107  drochner 					return (5);
   1394  1.107  drochner 				}
   1395  1.107  drochner 			}
   1396  1.107  drochner 			*index = 0xa4; /* currency sign */
   1397  1.107  drochner 			return (0);
   1398  1.107  drochner 		}
   1399  1.107  drochner 	case WSDISPLAY_FONTENC_KOI8_R:
   1400  1.107  drochner 		if (uni < 0x80) {
   1401  1.107  drochner 			*index = uni;
   1402  1.107  drochner 			return (5);
   1403  1.107  drochner 		} else {
   1404  1.107  drochner 			int i;
   1405  1.107  drochner 			for (i = 0; i < 0x40; i++) {
   1406  1.107  drochner 				if (uni == koi8_unichars[i]) {
   1407  1.107  drochner 					*index = i + 0xc0;
   1408  1.107  drochner 					return (5);
   1409  1.107  drochner 				}
   1410  1.107  drochner 			}
   1411  1.107  drochner 			*index = 0x94; /* box */
   1412  1.107  drochner 			return (0);
   1413  1.107  drochner 		}
   1414   1.12  drochner 	case WSDISPLAY_FONTENC_IBM:
   1415   1.13  drochner 		return (pcdisplay_mapchar(id, uni, index));
   1416   1.12  drochner #ifdef WSCONS_SUPPORT_PCVTFONTS
   1417   1.12  drochner 	case WSDISPLAY_FONTENC_PCVT:
   1418   1.13  drochner 		return (vga_pcvt_mapchar(uni, index));
   1419   1.34  drochner #endif
   1420   1.34  drochner #ifdef WSCONS_SUPPORT_ISO7FONTS
   1421   1.34  drochner 	case WSDISPLAY_FONTENC_ISO7:
   1422   1.34  drochner 		return (vga_iso7_mapchar(uni, index));
   1423   1.12  drochner #endif
   1424   1.13  drochner 	default:
   1425   1.16  drochner #ifdef VGAFONTDEBUG
   1426   1.37  drochner 		printf("_vga_mapchar: encoding=%d\n", font->wsfont->encoding);
   1427   1.16  drochner #endif
   1428   1.13  drochner 		*index = ' ';
   1429   1.13  drochner 		return (0);
   1430   1.12  drochner 	}
   1431   1.12  drochner }
   1432   1.12  drochner 
   1433   1.13  drochner static int
   1434   1.45  junyoung vga_mapchar(void *id, int uni, u_int *index)
   1435   1.12  drochner {
   1436   1.12  drochner 	struct vgascreen *scr = id;
   1437   1.45  junyoung 	u_int idx1, idx2;
   1438   1.13  drochner 	int res1, res2;
   1439   1.12  drochner 
   1440   1.13  drochner 	res1 = 0;
   1441   1.13  drochner 	idx1 = ' '; /* space */
   1442   1.13  drochner 	if (scr->fontset1)
   1443   1.13  drochner 		res1 = _vga_mapchar(id, scr->fontset1, uni, &idx1);
   1444   1.13  drochner 	res2 = -1;
   1445   1.12  drochner 	if (scr->fontset2) {
   1446   1.12  drochner 		KASSERT(VGA_SCREEN_CANTWOFONTS(scr->pcs.type));
   1447   1.13  drochner 		res2 = _vga_mapchar(id, scr->fontset2, uni, &idx2);
   1448   1.12  drochner 	}
   1449   1.13  drochner 	if (res2 > res1) {
   1450   1.14  drochner 		*index = idx2 | 0x0800; /* attribute bit 3 */
   1451   1.14  drochner 		return (res2);
   1452   1.13  drochner 	}
   1453   1.13  drochner 	*index = idx1;
   1454   1.13  drochner 	return (res1);
   1455   1.53  christos }
   1456   1.53  christos 
   1457   1.72  christos #ifdef WSDISPLAY_SCROLLSUPPORT
   1458  1.110   mlelstv static void
   1459   1.72  christos vga_scroll(void *v, void *cookie, int lines)
   1460   1.72  christos {
   1461   1.72  christos 	struct vga_config *vc = v;
   1462   1.72  christos 	struct vgascreen *scr = cookie;
   1463   1.72  christos 	struct vga_handle *vh = &vc->hdl;
   1464   1.72  christos 
   1465   1.72  christos 	if (lines == 0) {
   1466   1.72  christos 		if (scr->pcs.visibleoffset == scr->pcs.dispoffset)
   1467   1.72  christos 			return;
   1468   1.72  christos 
   1469   1.72  christos 		scr->pcs.visibleoffset = scr->pcs.dispoffset;
   1470   1.72  christos 	}
   1471   1.72  christos 	else {
   1472   1.72  christos 		int vga_scr_end;
   1473   1.72  christos 		int margin = scr->pcs.type->ncols * 2;
   1474   1.72  christos 		int ul, we, p, st;
   1475   1.72  christos 
   1476   1.72  christos 		vga_scr_end = (scr->pcs.dispoffset + scr->pcs.type->ncols *
   1477   1.72  christos 		    scr->pcs.type->nrows * 2);
   1478   1.72  christos 		if (scr->vga_rollover > vga_scr_end + margin) {
   1479   1.72  christos 			ul = vga_scr_end;
   1480   1.72  christos 			we = scr->vga_rollover + scr->pcs.type->ncols * 2;
   1481   1.72  christos 		} else {
   1482   1.72  christos 			ul = 0;
   1483   1.72  christos 			we = 0x8000;
   1484   1.72  christos 		}
   1485   1.72  christos 		p = (scr->pcs.visibleoffset - ul + we) % we + lines *
   1486   1.72  christos 		    (scr->pcs.type->ncols * 2);
   1487   1.72  christos 		st = (scr->pcs.dispoffset - ul + we) % we;
   1488   1.72  christos 		if (p < margin)
   1489   1.72  christos 			p = 0;
   1490   1.72  christos 		if (p > st - margin)
   1491   1.72  christos 			p = st;
   1492   1.72  christos 		scr->pcs.visibleoffset = (p + ul) % we;
   1493   1.72  christos 	}
   1494   1.81     perry 
   1495   1.72  christos 	vga_6845_write(vh, startadrh, scr->pcs.visibleoffset >> 9);
   1496   1.72  christos 	vga_6845_write(vh, startadrl, scr->pcs.visibleoffset >> 1);
   1497   1.72  christos }
   1498   1.72  christos #endif
   1499   1.72  christos 
   1500  1.110   mlelstv static void
   1501   1.72  christos vga_putchar(void *c, int row, int col, u_int uc, long attr)
   1502   1.72  christos {
   1503   1.72  christos 
   1504   1.72  christos 	pcdisplay_putchar(c, row, col, uc, attr);
   1505   1.72  christos }
   1506   1.72  christos 
   1507   1.76      jmmv #ifdef WSDISPLAY_CUSTOM_BORDER
   1508   1.85  drochner static int
   1509   1.85  drochner vga_getborder(struct vga_config *vc, u_int *valuep)
   1510   1.76      jmmv {
   1511   1.85  drochner 	struct vga_handle *vh = &vc->hdl;
   1512   1.76      jmmv 	u_int idx;
   1513  1.106  christos 	uint8_t value;
   1514   1.76      jmmv 
   1515   1.85  drochner 	if (vh->vh_mono)
   1516   1.85  drochner 		return ENODEV;
   1517   1.76      jmmv 
   1518   1.76      jmmv 	value = _vga_attr_read(vh, VGA_ATC_OVERSCAN);
   1519   1.85  drochner 	for (idx = 0; idx < sizeof(fgansitopc); idx++) {
   1520   1.85  drochner 		if (fgansitopc[idx] == value) {
   1521   1.85  drochner 			*valuep = idx;
   1522   1.85  drochner 			return (0);
   1523   1.85  drochner 		}
   1524   1.85  drochner 	}
   1525   1.85  drochner 	return (EIO);
   1526   1.76      jmmv }
   1527   1.76      jmmv 
   1528   1.76      jmmv static int
   1529   1.85  drochner vga_setborder(struct vga_config *vc, u_int value)
   1530   1.76      jmmv {
   1531   1.85  drochner 	struct vga_handle *vh = &vc->hdl;
   1532   1.76      jmmv 
   1533   1.85  drochner 	if (vh->vh_mono)
   1534   1.85  drochner 		return ENODEV;
   1535   1.85  drochner 	if (value >= sizeof(fgansitopc))
   1536   1.85  drochner 		return EINVAL;
   1537   1.76      jmmv 
   1538   1.76      jmmv 	_vga_attr_write(vh, VGA_ATC_OVERSCAN, fgansitopc[value]);
   1539   1.76      jmmv 	return (0);
   1540   1.76      jmmv }
   1541   1.76      jmmv #endif /* WSDISPLAY_CUSTOM_BORDER */
   1542   1.97  jmcneill 
   1543   1.97  jmcneill void
   1544   1.97  jmcneill vga_resume(struct vga_softc *sc)
   1545   1.97  jmcneill {
   1546   1.97  jmcneill #ifdef VGA_RESET_ON_RESUME
   1547   1.97  jmcneill 	vga_initregs(&sc->sc_vc->hdl);
   1548   1.97  jmcneill #endif
   1549  1.105  jmcneill #ifdef PCDISPLAY_SOFTCURSOR
   1550  1.105  jmcneill 	/* Disable the hardware cursor */
   1551  1.105  jmcneill 	vga_6845_write(&sc->sc_vc->hdl, curstart, 0x20);
   1552  1.105  jmcneill 	vga_6845_write(&sc->sc_vc->hdl, curend, 0x00);
   1553  1.105  jmcneill #endif
   1554   1.97  jmcneill }
   1555  1.106  christos 
   1556  1.110   mlelstv static void
   1557  1.106  christos vga_save_palette(struct vga_config *vc)
   1558  1.106  christos {
   1559  1.106  christos 	struct vga_handle *vh = &vc->hdl;
   1560  1.106  christos 	size_t i;
   1561  1.106  christos 	uint8_t *palette = vc->palette;
   1562  1.106  christos 
   1563  1.106  christos 	if (vh->vh_mono)
   1564  1.106  christos 		return;
   1565  1.106  christos 
   1566  1.106  christos 	vga_raw_write(vh, VGA_DAC_PELMASK, 0xff);
   1567  1.106  christos 	vga_raw_write(vh, VGA_DAC_ADDRR, 0x00);
   1568  1.106  christos 	for (i = 0; i < sizeof(vc->palette); i++)
   1569  1.106  christos 		*palette++ = vga_raw_read(vh, VGA_DAC_PALETTE);
   1570  1.106  christos 
   1571  1.109       uwe 	vga_reset_state(vh);			/* reset flip/flop */
   1572  1.106  christos }
   1573  1.106  christos 
   1574  1.110   mlelstv static void
   1575  1.106  christos vga_restore_palette(struct vga_config *vc)
   1576  1.106  christos {
   1577  1.106  christos 	struct vga_handle *vh = &vc->hdl;
   1578  1.106  christos 	size_t i;
   1579  1.106  christos 	uint8_t *palette = vc->palette;
   1580  1.106  christos 
   1581  1.106  christos 	if (vh->vh_mono)
   1582  1.106  christos 		return;
   1583  1.106  christos 
   1584  1.106  christos 	vga_raw_write(vh, VGA_DAC_PELMASK, 0xff);
   1585  1.106  christos 	vga_raw_write(vh, VGA_DAC_ADDRW, 0x00);
   1586  1.106  christos 	for (i = 0; i < sizeof(vc->palette); i++)
   1587  1.106  christos 		vga_raw_write(vh, VGA_DAC_PALETTE, *palette++);
   1588  1.106  christos 
   1589  1.109       uwe 	vga_reset_state(vh);			/* reset flip/flop */
   1590  1.106  christos 	vga_enable(vh);
   1591  1.106  christos }
   1592