Home | History | Annotate | Line # | Download | only in dev
grfabs_et.c revision 1.6
      1 /*	$NetBSD: grfabs_et.c,v 1.6 1997/01/10 20:59:27 leo Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1996 Leo Weppelman.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *      This product includes software developed by Leo Weppelman.
     18  * 4. The name of the author may not be used to endorse or promote products
     19  *    derived from this software without specific prior written permission
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 /*
     34  * Most of the lower-level et4000 stuff was derived from:
     35  *	.../amiga/dev/grf_et.c
     36  *
     37  * Which was copyrighted by:
     38  *	Copyright (c) 1996 Tobias Abt
     39  *	Copyright (c) 1995 Ezra Story
     40  *	Copyright (c) 1995 Kari Mettinen
     41  *	Copyright (c) 1994 Markus Wild
     42  *	Copyright (c) 1994 Lutz Vieweg
     43  *
     44  * Thanks guys!
     45  *
     46  */
     47 #include <sys/param.h>
     48 #include <sys/queue.h>
     49 #include <sys/malloc.h>
     50 #include <sys/device.h>
     51 #include <sys/systm.h>
     52 
     53 /*
     54  * For PCI probing...
     55  */
     56 #include <dev/pci/pcireg.h>
     57 #include <dev/pci/pcivar.h>
     58 
     59 #include <machine/iomap.h>
     60 #include <machine/video.h>
     61 #include <machine/mfp.h>
     62 #include <machine/cpu.h>
     63 #include <atari/atari/device.h>
     64 #include <atari/dev/grfioctl.h>
     65 #include <atari/dev/grfabs_reg.h>
     66 #include <atari/dev/grfabs_et.h>
     67 #include <atari/dev/grf_etreg.h>
     68 
     69 #define	SAVEBUF_SIZE	(32*1024 + sizeof(save_area_t))
     70 
     71 /*
     72  * Function decls
     73  */
     74 static void       init_view __P((view_t *, bmap_t *, dmode_t *, box_t *));
     75 static colormap_t *alloc_colormap __P((dmode_t *));
     76 static void	  et_display_view __P((view_t *));
     77 static view_t	  *et_alloc_view __P((dmode_t *, dimen_t *, u_char));
     78 static void	  et_boardinit __P((void));
     79 static void	  et_free_view __P((view_t *));
     80 static void	  et_loadmode __P((struct grfvideo_mode *, et_sv_reg_t *));
     81 static void	  et_remove_view __P((view_t *));
     82 static void	  et_save_view __P((view_t *));
     83 static int	  et_use_colormap __P((view_t *, colormap_t *));
     84 
     85 /*
     86  * Our function switch table
     87  */
     88 struct grfabs_sw et_vid_sw = {
     89 	et_display_view,
     90 	et_alloc_view,
     91 	et_free_view,
     92 	et_remove_view,
     93 	et_save_view,
     94 	et_use_colormap
     95 };
     96 
     97 static struct grfvideo_mode hw_modes[] = {
     98     {
     99 	0, "", 25175000,		/* num, descr, pix-clock	*/
    100 	640, 400, 4,			/* width, height, depth		*/
    101 	632/8, 672/8, 688/8, 808/8, 768/8,/* HBS, HBE, HSS, HSE, HT	*/
    102 	399, 450, 408, 413, 449		/* VBS, VBE, VSS, VSE, VT	*/
    103     },
    104     {
    105 	0, "", 25175000,		/* num, descr, pix-clock	*/
    106 	640, 480, 4,			/* width, height, depth		*/
    107 	632/8, 672/8, 688/8, 752/8, 752/8,/* HBS, HBE, HSS, HSE, HT	*/
    108 	481, 522, 490, 498, 522		/* VBS, VBE, VSS, VSE, VT	*/
    109     }
    110 };
    111 
    112 static dmode_t vid_modes[] = {
    113     { { NULL, NULL },
    114 	"640x400", { 640, 400 }, 1, (void*)&hw_modes[0], &et_vid_sw },
    115     { { NULL, NULL },
    116 	"640x480", { 640, 480 }, 1, (void*)&hw_modes[1], &et_vid_sw },
    117     { { NULL, NULL }, NULL,  }
    118 };
    119 
    120 #define	ET_NUMCLOCKS	32
    121 
    122 static u_int et_clockfreqs[ET_NUMCLOCKS] = {
    123 	 6293750,  7080500,  7875000,  8125000,
    124 	 9000000,  9375000, 10000000, 11225000,
    125 	12587500, 14161000, 15750000, 16250000,
    126 	18000000, 18750000, 20000000, 22450000,
    127 	25175000, 28322000, 31500000, 32500000,
    128 	36000000, 37500000, 40000000, 44900000,
    129 	50350000, 56644000, 63000000, 65000000,
    130 	72000000, 75000000, 80000000, 89800000
    131 };
    132 
    133 static bmap_t	con_bm; /* XXX */
    134 
    135 struct grfabs_et_priv {
    136 	pcitag_t		pci_tag;
    137 	volatile caddr_t	regkva;
    138 	volatile caddr_t	memkva;
    139 	int			regsz;
    140 	int			memsz;
    141 } et_priv;
    142 
    143 /*
    144  * XXX: called from ite console init routine.
    145  * Initialize list of posible video modes.
    146  */
    147 void
    148 et_probe_video(modelp)
    149 MODES	*modelp;
    150 {
    151 	dmode_t	*dm;
    152 	int	i;
    153 
    154 	for (i = 0; (dm = &vid_modes[i])->name != NULL; i++) {
    155 		LIST_INSERT_HEAD(modelp, dm, link);
    156 	}
    157 }
    158 
    159 static void
    160 et_display_view(v)
    161 view_t *v;
    162 {
    163 	dmode_t		*dm = v->mode;
    164 	bmap_t		*bm = v->bitmap;
    165 	int		sv_size;
    166 	u_short		*src, *dst;
    167 	save_area_t	*sa;
    168 
    169 	if (dm->current_view && (dm->current_view != v)) {
    170 		/*
    171 		 * Mark current view for this mode as no longer displayed
    172 		 */
    173 		dm->current_view->flags &= ~VF_DISPLAY;
    174 	}
    175 	dm->current_view = v;
    176 	v->flags |= VF_DISPLAY;
    177 
    178 	if ((sa = (save_area_t*)v->save_area) == NULL)
    179 		return; /* XXX: Can't happen.... */
    180 
    181 	/*
    182 	 * Restore register settings and turn the plane pointer
    183 	 * to the card-memory
    184 	 */
    185 	et_hwrest(&sa->sv_regs);
    186 	bm->plane = et_priv.memkva;
    187 
    188 	et_use_colormap(v, v->colormap);
    189 
    190 	/*
    191 	 * Copy the backing store to card-memory
    192 	 */
    193 	sv_size = sa->fb_size;
    194 	src     = sa->sv_fb;
    195 	dst     = (u_short *)bm->plane;
    196 	while (sv_size--)
    197 		*dst++ = *src++;
    198 }
    199 
    200 void
    201 et_remove_view(v)
    202 view_t *v;
    203 {
    204 	dmode_t *mode = v->mode;
    205 
    206 	if (mode->current_view == v) {
    207 #if 0
    208 		if (v->flags & VF_DISPLAY)
    209 			panic("Cannot shutdown display\n"); /* XXX */
    210 #endif
    211 		mode->current_view = NULL;
    212 	}
    213 	v->flags &= ~VF_DISPLAY;
    214 }
    215 
    216 void
    217 et_save_view(v)
    218 view_t *v;
    219 {
    220 	bmap_t		*bm = v->bitmap;
    221 	u_char		font_height;
    222 	int		sv_size;
    223 	u_short		*src, *dst;
    224 	save_area_t	*sa;
    225 
    226 	if (!atari_realconfig)
    227 		return;
    228 
    229 	if (RGfx(et_priv.regkva, GCT_ID_MISC) & 1) {
    230 #if 0 /* XXX: Can't use printf here.... */
    231 		printf("et_save_view: Don't know how to save"
    232 			" a graphics mode\n");
    233 #endif
    234 		return;
    235 	}
    236 	if (v->save_area == NULL)
    237 		v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_WAITOK);
    238 
    239 	/*
    240 	 * Calculate the size of the copy
    241 	 */
    242 	font_height = RCrt(et_priv.regkva, CRT_ID_MAX_ROW_ADDRESS) & 0x1f;
    243 	sv_size = bm->bytes_per_row * (bm->rows / (font_height + 1));
    244 	sv_size = min(SAVEBUF_SIZE, sv_size);
    245 
    246 	/*
    247 	 * Save all we need to know....
    248 	 */
    249 	sa  = (save_area_t *)v->save_area;
    250 	et_hwsave(&sa->sv_regs);
    251 	sa->fb_size = sv_size;
    252 	src = (u_short *)bm->plane;
    253 	dst = sa->sv_fb;
    254 	while (sv_size--)
    255 		*dst++ = *src++;
    256 	bm->plane = (u_char *)sa->sv_fb;
    257 }
    258 
    259 void
    260 et_free_view(v)
    261 view_t *v;
    262 {
    263 	if(v) {
    264 		et_remove_view(v);
    265 		if (v->colormap != &gra_con_cmap)
    266 			free(v->colormap, M_DEVBUF);
    267 		if (v->save_area != NULL)
    268 			free(v->save_area, M_DEVBUF);
    269 		if (v != &gra_con_view) {
    270 			free(v->bitmap, M_DEVBUF);
    271 			free(v, M_DEVBUF);
    272 		}
    273 	}
    274 }
    275 
    276 static int
    277 et_use_colormap(v, cm)
    278 view_t		*v;
    279 colormap_t	*cm;
    280 {
    281 	return (0); /* XXX: Nothing here for now... */
    282 }
    283 
    284 static view_t *
    285 et_alloc_view(mode, dim, depth)
    286 dmode_t	*mode;
    287 dimen_t	*dim;
    288 u_char   depth;
    289 {
    290 	view_t		*v;
    291 	bmap_t		*bm;
    292 	box_t		box;
    293 	save_area_t	*sa;
    294 
    295 	if (!atari_realconfig) {
    296 		v  = &gra_con_view;
    297 		bm = &con_bm;
    298 	}
    299 	else {
    300 		v  = malloc(sizeof(*v), M_DEVBUF, M_WAITOK);
    301 		bm = malloc(sizeof(*bm), M_DEVBUF, M_WAITOK);
    302 	}
    303 	v->bitmap = bm;
    304 
    305 	/*
    306 	 * Initialize the bitmap
    307 	 */
    308 	bm->plane         = et_priv.memkva;
    309 	bm->hw_address    = (caddr_t)kvtop(et_priv.memkva);
    310 	bm->regs          = et_priv.regkva;
    311 	bm->hw_regs       = (caddr_t)kvtop(et_priv.regkva);
    312 	bm->reg_size      = et_priv.regsz;
    313 
    314 	bm->bytes_per_row = (mode->size.width * depth) / NBBY;
    315 	bm->rows          = mode->size.height;
    316 	bm->depth         = depth;
    317 
    318 	/*
    319 	 * Allocate a save_area.
    320 	 * Note: If atari_realconfig is false, no save area is (can be)
    321 	 * allocated. This means that the plane is the video memory,
    322 	 * which is what's wanted in this case.
    323 	 */
    324 	if (atari_realconfig) {
    325 		v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_WAITOK);
    326 		sa           = (save_area_t*)v->save_area;
    327 		sa->fb_size  = 0;
    328 		bm->plane    = (u_char *)sa->sv_fb;
    329 		et_loadmode(mode->data, &sa->sv_regs);
    330 	}
    331 	else v->save_area = NULL;
    332 
    333 	v->colormap = alloc_colormap(mode);
    334 	if (v->colormap) {
    335 		INIT_BOX(&box,0,0,mode->size.width,mode->size.height);
    336 		init_view(v, bm, mode, &box);
    337 		return (v);
    338 	}
    339 	if (v != &gra_con_view) {
    340 		free(v, M_DEVBUF);
    341 		free(bm, M_DEVBUF);
    342 	}
    343 	return (NULL);
    344 }
    345 
    346 static void
    347 init_view(v, bm, mode, dbox)
    348 view_t	*v;
    349 bmap_t	*bm;
    350 dmode_t	*mode;
    351 box_t	*dbox;
    352 {
    353 	v->bitmap    = bm;
    354 	v->mode      = mode;
    355 	v->flags     = 0;
    356 	bcopy(dbox, &v->display, sizeof(box_t));
    357 }
    358 
    359 /* XXX: No more than a stub... */
    360 static colormap_t *
    361 alloc_colormap(dm)
    362 dmode_t		*dm;
    363 {
    364 	colormap_t	*cm;
    365 	int		i;
    366 
    367 	cm = &gra_con_cmap;
    368 	cm->entry = gra_con_colors;
    369 
    370 	cm->first = 0;
    371 	cm->size  = 2;
    372 
    373 	for (i = 0; i < 2; i++)
    374 		cm->entry[i] = gra_def_color16[i % 16];
    375 	return (cm);
    376 }
    377 
    378 /*
    379  * Go look for a VGA card on the PCI-bus. This search is a
    380  * stripped down version of the PCI-probe. It only looks on
    381  * bus0 for simple cards.
    382  */
    383 int
    384 et_probe_card()
    385 {
    386 	pci_chipset_tag_t	pc = NULL; /* XXX */
    387 	pcitag_t		tag;
    388 	int			class, device, found, id, maxndevs;
    389 
    390 	found    = 0;
    391 	tag      = 0;
    392 	maxndevs = pci_bus_maxdevs(pc, 0);
    393 
    394 	for (device = 0; device < maxndevs; device++) {
    395 
    396 		tag = pci_make_tag(pc, 0, device, 0);
    397 		id  = pci_conf_read(pc, tag, PCI_ID_REG);
    398 		if (id == 0 || id == 0xffffffff)
    399 			continue;
    400 		class = pci_conf_read(pc, tag, PCI_CLASS_REG);
    401 		if (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC
    402 		    && PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA) {
    403 			found = 1;
    404 			break;
    405 		}
    406 		if (PCI_CLASS(class) == PCI_CLASS_DISPLAY
    407 		    && PCI_SUBCLASS(class) == PCI_SUBCLASS_DISPLAY_VGA) {
    408 			found = 1;
    409 			break;
    410 		}
    411 	}
    412 	if (!found)
    413 		return (0);
    414 
    415 	et_priv.pci_tag = tag;
    416 
    417 	/*
    418 	 * The things below are setup in atari_init.c
    419 	 */
    420 	et_priv.regkva  = (volatile caddr_t)pci_io_addr;
    421 	et_priv.memkva  = (volatile caddr_t)pci_mem_addr;
    422 	et_priv.memsz   = 4 * NBPG;
    423 	et_priv.regsz   = NBPG;
    424 
    425 	if (found && !atari_realconfig) {
    426 		et_boardinit();
    427 		et_loadmode(&hw_modes[0], NULL);
    428 		return (1);
    429 	}
    430 
    431 	return (1);
    432 }
    433 
    434 static void
    435 et_loadmode(mode, regs)
    436 struct grfvideo_mode	*mode;
    437 et_sv_reg_t		*regs;
    438 {
    439 	unsigned short	HDE, VDE;
    440 	int	    	lace, dblscan;
    441 	int     	uplim, lowlim;
    442 	int		i;
    443 	unsigned char	clock, tmp;
    444 	volatile u_char	*ba;
    445 	et_sv_reg_t	loc_regs;
    446 
    447 	if (regs == NULL)
    448 		regs = &loc_regs;
    449 
    450 	ba  = et_priv.regkva;
    451 	HDE = mode->disp_width / 8 - 1;
    452 	VDE = mode->disp_height - 1;
    453 
    454 	/* figure out whether lace or dblscan is needed */
    455 
    456 	uplim   = mode->disp_height + (mode->disp_height / 4);
    457 	lowlim  = mode->disp_height - (mode->disp_height / 4);
    458 	lace    = (((mode->vtotal * 2) > lowlim)
    459 		   && ((mode->vtotal * 2) < uplim)) ? 1 : 0;
    460 	dblscan = (((mode->vtotal / 2) > lowlim)
    461 		   && ((mode->vtotal / 2) < uplim)) ? 1 : 0;
    462 
    463 	/* adjustments */
    464 	if (lace)
    465 		VDE /= 2;
    466 
    467 	regs->misc_output = 0x23; /* Page 0, Color mode */
    468 	regs->seg_sel     = 0x00;
    469 	regs->state_ctl   = 0x00;
    470 
    471 	regs->seq[SEQ_ID_RESET]           = 0x03; /* reset off		*/
    472 	regs->seq[SEQ_ID_CLOCKING_MODE]   = 0x21; /* Turn off screen	*/
    473 	regs->seq[SEQ_ID_MAP_MASK]        = 0xff; /* Cpu writes all planes*/
    474 	regs->seq[SEQ_ID_CHAR_MAP_SELECT] = 0x00; /* Char. generator 0	*/
    475 	regs->seq[SEQ_ID_MEMORY_MODE]     = 0x0e; /* Seq. Memory mode	*/
    476 
    477 	/*
    478 	 * Set the clock...
    479 	 */
    480 	for(clock = ET_NUMCLOCKS-1; clock > 0; clock--) {
    481 		if (et_clockfreqs[clock] <= mode->pixel_clock)
    482 			break;
    483 	}
    484 	regs->misc_output |= (clock & 3) << 2;
    485 	regs->aux_mode     = 0xb4 | ((clock & 8) << 3);
    486 	regs->compat_6845  = (clock & 4) ? 0x0a : 0x08;
    487 
    488 	/*
    489 	 * The display parameters...
    490 	 */
    491 	regs->crt[CRT_ID_HOR_TOTAL]        =  mode->htotal;
    492 	regs->crt[CRT_ID_HOR_DISP_ENA_END] = ((HDE >= mode->hblank_start)
    493 						? mode->hblank_stop - 1
    494 						: HDE);
    495 	regs->crt[CRT_ID_START_HOR_BLANK]  = mode->hblank_start;
    496 	regs->crt[CRT_ID_END_HOR_BLANK]    = (mode->hblank_stop & 0x1f) | 0x80;
    497 	regs->crt[CRT_ID_START_HOR_RETR]   = mode->hsync_start;
    498 	regs->crt[CRT_ID_END_HOR_RETR]     = (mode->hsync_stop & 0x1f)
    499 						| ((mode->hblank_stop & 0x20)
    500 							? 0x80 : 0x00);
    501 	regs->crt[CRT_ID_VER_TOTAL]        = mode->vtotal;
    502 	regs->crt[CRT_ID_START_VER_RETR]   = mode->vsync_start;
    503 	regs->crt[CRT_ID_END_VER_RETR]     = (mode->vsync_stop & 0x0f) | 0x30;
    504 	regs->crt[CRT_ID_VER_DISP_ENA_END] = VDE;
    505 	regs->crt[CRT_ID_START_VER_BLANK]  = mode->vblank_start;
    506 	regs->crt[CRT_ID_END_VER_BLANK]    = mode->vblank_stop;
    507 	regs->crt[CRT_ID_MODE_CONTROL]     = 0xab;
    508 	regs->crt[CRT_ID_START_ADDR_HIGH]  = 0x00;
    509 	regs->crt[CRT_ID_START_ADDR_LOW]   = 0x00;
    510 	regs->crt[CRT_ID_LINE_COMPARE]     = 0xff;
    511 	regs->crt[CRT_ID_UNDERLINE_LOC]    = 0x00;
    512 	regs->crt[CRT_ID_OFFSET]           = mode->disp_width/16;
    513 	regs->crt[CRT_ID_MAX_ROW_ADDRESS]  =
    514 		0x40 |
    515 		(dblscan ? 0x80 : 0x00) |
    516 		((mode->vblank_start & 0x200) ? 0x20 : 0x00);
    517 	regs->crt[CRT_ID_OVERFLOW] =
    518 		0x10 |
    519 		((mode->vtotal       & 0x100) ? 0x01 : 0x00) |
    520 		((VDE                & 0x100) ? 0x02 : 0x00) |
    521 		((mode->vsync_start  & 0x100) ? 0x04 : 0x00) |
    522 		((mode->vblank_start & 0x100) ? 0x08 : 0x00) |
    523 		((mode->vtotal       & 0x200) ? 0x20 : 0x00) |
    524 		((VDE                & 0x200) ? 0x40 : 0x00) |
    525 		((mode->vsync_start  & 0x200) ? 0x80 : 0x00);
    526 	regs->overfl_high =
    527 		0x10 |
    528 		((mode->vblank_start & 0x400) ? 0x01 : 0x00) |
    529 		((mode->vtotal       & 0x400) ? 0x02 : 0x00) |
    530 		((VDE                & 0x400) ? 0x04 : 0x00) |
    531 		((mode->vsync_start  & 0x400) ? 0x08 : 0x00) |
    532 		(lace ? 0x80 : 0x00);
    533 	regs->hor_overfl =
    534 		((mode->htotal       & 0x100) ? 0x01 : 0x00) |
    535 		((mode->hblank_start & 0x100) ? 0x04 : 0x00) |
    536 		((mode->hsync_start  & 0x100) ? 0x10 : 0x00);
    537 
    538 	regs->grf[GCT_ID_SET_RESET]        = 0x00;
    539 	regs->grf[GCT_ID_ENABLE_SET_RESET] = 0x00;
    540 	regs->grf[GCT_ID_COLOR_COMPARE]    = 0x00;
    541 	regs->grf[GCT_ID_DATA_ROTATE]      = 0x00;
    542 	regs->grf[GCT_ID_READ_MAP_SELECT]  = 0x00;
    543 	regs->grf[GCT_ID_GRAPHICS_MODE]    = mode->depth == 1 ? 0x00: 0x40;
    544 	regs->grf[GCT_ID_MISC]             = 0x01;
    545 	regs->grf[GCT_ID_COLOR_XCARE]      = 0x0f;
    546 	regs->grf[GCT_ID_BITMASK]          = 0xff;
    547 
    548 	for (i = 0; i < 0x10; i++)
    549 		regs->attr[i] = i;
    550 	regs->attr[ACT_ID_ATTR_MODE_CNTL]  = 0x01;
    551 	regs->attr[ACT_ID_OVERSCAN_COLOR]  = 0x00;
    552 	regs->attr[ACT_ID_COLOR_PLANE_ENA] = 0x0f;
    553 	regs->attr[ACT_ID_HOR_PEL_PANNING] = 0x00;
    554 	regs->attr[ACT_ID_COLOR_SELECT]    = 0x00;
    555 	regs->attr[ACT_ID_MISCELLANEOUS]   = 0x00;
    556 
    557 	/*
    558 	 * XXX: This works for depth == 4. I need some better docs
    559 	 * to fix the other modes....
    560 	 */
    561 	vgaw(ba, VDAC_MASK, 0xff);
    562 	vgar(ba, VDAC_MASK);
    563 	vgar(ba, VDAC_MASK);
    564 	vgar(ba, VDAC_MASK);
    565 	vgar(ba, VDAC_MASK);
    566 
    567 	vgaw(ba, VDAC_MASK, 0);
    568 	/*
    569 	 * End of depth stuff
    570 	 */
    571 
    572 	/*
    573 	 * Compute Hsync & Vsync polarity
    574 	 * Note: This seems to be some kind of a black art :-(
    575 	 */
    576 	tmp = regs->misc_output & 0x3f;
    577 #if 1 /* This is according to my BW monitor & Xfree... */
    578 	if (VDE < 400)
    579 		tmp |= 0x40;	/* -hsync +vsync */
    580 	else if (VDE < 480)
    581 		tmp |= 0xc0;	/* -hsync -vsync */
    582 #else /* This is according to my color monitor.... */
    583 	if (VDE < 400)
    584 		tmp |= 0x00;	/* +hsync +vsync */
    585 	else if (VDE < 480)
    586 		tmp |= 0x80;	/* +hsync -vsync */
    587 #endif
    588 	/* I'm unable to try the rest.... */
    589 	regs->misc_output = tmp;
    590 
    591 	if(regs == &loc_regs)
    592 		et_hwrest(regs);
    593 }
    594 
    595 static void
    596 et_boardinit()
    597 {
    598 	volatile u_char *ba;
    599 	int		i, j;
    600 
    601 	ba = et_priv.regkva;
    602 
    603 	vgaw(ba, GREG_HERCULESCOMPAT,     0x03);
    604 	vgaw(ba, GREG_DISPMODECONTROL,    0xa0);
    605 	vgaw(ba, GREG_MISC_OUTPUT_W,      0x23);
    606 
    607 	WSeq(ba, SEQ_ID_RESET,            0x03);
    608 	WSeq(ba, SEQ_ID_CLOCKING_MODE,    0x21);	/* 8 dot, Display off */
    609 	WSeq(ba, SEQ_ID_MAP_MASK,         0x0f);
    610 	WSeq(ba, SEQ_ID_CHAR_MAP_SELECT,  0x00);
    611 	WSeq(ba, SEQ_ID_MEMORY_MODE,      0x0e);
    612 	WSeq(ba, SEQ_ID_AUXILIARY_MODE,   0xf4);
    613 
    614 	WCrt(ba, CRT_ID_PRESET_ROW_SCAN,  0x00);
    615 	WCrt(ba, CRT_ID_CURSOR_START,     0x00);
    616 	WCrt(ba, CRT_ID_CURSOR_END,       0x08);
    617 	WCrt(ba, CRT_ID_START_ADDR_HIGH,  0x00);
    618 	WCrt(ba, CRT_ID_START_ADDR_LOW,   0x00);
    619 	WCrt(ba, CRT_ID_CURSOR_LOC_HIGH,  0x00);
    620 	WCrt(ba, CRT_ID_CURSOR_LOC_LOW,   0x00);
    621 
    622 	WCrt(ba, CRT_ID_UNDERLINE_LOC,    0x07);
    623 	WCrt(ba, CRT_ID_MODE_CONTROL,     0xa3);
    624 	WCrt(ba, CRT_ID_LINE_COMPARE,     0xff);
    625 	/*
    626 	 * ET4000 special
    627 	 */
    628 	WCrt(ba, CRT_ID_RASCAS_CONFIG,    0x28);
    629 	WCrt(ba, CTR_ID_EXT_START,        0x00);
    630 	WCrt(ba, CRT_ID_6845_COMPAT,      0x08);
    631 	WCrt(ba, CRT_ID_VIDEO_CONFIG1,    0x73);
    632 	WCrt(ba, CRT_ID_VIDEO_CONFIG2,    0x09);
    633 
    634 	WCrt(ba, CRT_ID_HOR_OVERFLOW,     0x00);
    635 
    636 	WGfx(ba, GCT_ID_SET_RESET,        0x00);
    637 	WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
    638 	WGfx(ba, GCT_ID_COLOR_COMPARE,    0x00);
    639 	WGfx(ba, GCT_ID_DATA_ROTATE,      0x00);
    640 	WGfx(ba, GCT_ID_READ_MAP_SELECT,  0x00);
    641 	WGfx(ba, GCT_ID_GRAPHICS_MODE,    0x00);
    642 	WGfx(ba, GCT_ID_MISC,             0x01);
    643 	WGfx(ba, GCT_ID_COLOR_XCARE,      0x0f);
    644 	WGfx(ba, GCT_ID_BITMASK,          0xff);
    645 
    646 	vgaw(ba, GREG_SEGMENTSELECT,      0x00);
    647 
    648 	for (i = 0; i < 0x10; i++)
    649 		WAttr(ba, i, i);
    650 	WAttr(ba, ACT_ID_ATTR_MODE_CNTL,  0x01);
    651 	WAttr(ba, ACT_ID_OVERSCAN_COLOR,  0x00);
    652 	WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
    653 	WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
    654 	WAttr(ba, ACT_ID_COLOR_SELECT,    0x00);
    655 	WAttr(ba, ACT_ID_MISCELLANEOUS,   0x00);
    656 
    657 	vgaw(ba, VDAC_MASK, 0xff);
    658 
    659 #if 0 /* XXX: We like to do this: */
    660 	delay(200000);
    661 #else /* But because we run before the delay is initialized: */
    662 	for(i = 0; i < 4000; i++)
    663 		for(j =  0; j < 400; j++);
    664 #endif
    665 
    666 	/*
    667 	 * colors initially set to greyscale
    668 	 */
    669 	vgaw(ba, VDAC_ADDRESS_W, 0);
    670 	for (i = 255; i >= 0; i--) {
    671 		vgaw(ba, VDAC_DATA, i);
    672 		vgaw(ba, VDAC_DATA, i);
    673 		vgaw(ba, VDAC_DATA, i);
    674 	}
    675 }
    676 
    677 void
    678 et_hwsave(et_regs)
    679 et_sv_reg_t	*et_regs;
    680 {
    681 	volatile u_char *ba;
    682 	int		i, s;
    683 
    684 	ba = et_priv.regkva;
    685 
    686 	s = splhigh();
    687 
    688 	/*
    689 	 * General VGA registers
    690 	 */
    691 	et_regs->misc_output = vgar(ba, GREG_MISC_OUTPUT_R);
    692 	for(i = 0; i < 25; i++)
    693 		et_regs->crt[i]  = RCrt(ba, i);
    694 	for(i = 0; i < 21; i++)
    695 		et_regs->attr[i] = RAttr(ba, i | 0x20);
    696 	for(i = 0; i < 9; i++)
    697 		et_regs->grf[i]  = RGfx(ba, i);
    698 	for(i = 0; i < 5; i++)
    699 		et_regs->seq[i]  = RSeq(ba, i);
    700 
    701 	/*
    702 	 * ET4000 extensions
    703 	 */
    704 	et_regs->ext_start   = RCrt(ba, CTR_ID_EXT_START);
    705 	et_regs->compat_6845 = RCrt(ba, CRT_ID_6845_COMPAT);
    706 	et_regs->overfl_high = RCrt(ba, CRT_ID_OVERFLOW_HIGH);
    707 	et_regs->hor_overfl  = RCrt(ba, CRT_ID_HOR_OVERFLOW);
    708 	et_regs->state_ctl   = RSeq(ba, SEQ_ID_STATE_CONTROL);
    709 	et_regs->aux_mode    = RSeq(ba, SEQ_ID_AUXILIARY_MODE);
    710 	et_regs->seg_sel     = vgar(ba, GREG_SEGMENTSELECT);
    711 
    712 	s = splx(s);
    713 }
    714 
    715 void
    716 et_hwrest(et_regs)
    717 et_sv_reg_t	*et_regs;
    718 {
    719 	volatile u_char *ba;
    720 	int		i, s;
    721 
    722 	ba = et_priv.regkva;
    723 
    724 	s = splhigh();
    725 
    726 	vgaw(ba, GREG_SEGMENTSELECT, 0);
    727 	vgaw(ba, GREG_MISC_OUTPUT_W, et_regs->misc_output);
    728 
    729 	/*
    730 	 * General VGA registers
    731 	 */
    732 	for(i = 0; i < 5; i++)
    733 		WSeq(ba, i, et_regs->seq[i]);
    734 
    735 	/*
    736 	 * Make sure we're allowed to write all crt-registers
    737 	 */
    738 	WCrt(ba, CRT_ID_END_VER_RETR,
    739 		et_regs->crt[CRT_ID_END_VER_RETR] & 0x7f);
    740 	for(i = 0; i < 25; i++)
    741 		WCrt(ba, i, et_regs->crt[i]);
    742 	for(i = 0; i < 9; i++)
    743 		WGfx(ba, i, et_regs->grf[i]);
    744 	for(i = 0; i < 21; i++)
    745 		WAttr(ba, i | 0x20, et_regs->attr[i]);
    746 
    747 	/*
    748 	 * ET4000 extensions
    749 	 */
    750 	WSeq(ba, SEQ_ID_STATE_CONTROL, et_regs->state_ctl);
    751 	WSeq(ba, SEQ_ID_AUXILIARY_MODE, et_regs->aux_mode);
    752 	WCrt(ba, CTR_ID_EXT_START, et_regs->ext_start);
    753 	WCrt(ba, CRT_ID_6845_COMPAT, et_regs->compat_6845);
    754 	WCrt(ba, CRT_ID_OVERFLOW_HIGH, et_regs->overfl_high);
    755 	WCrt(ba, CRT_ID_HOR_OVERFLOW, et_regs->hor_overfl);
    756 	vgaw(ba, GREG_SEGMENTSELECT, et_regs->seg_sel);
    757 
    758 	i = et_regs->seq[SEQ_ID_CLOCKING_MODE] & ~0x20;
    759 	WSeq(ba, SEQ_ID_CLOCKING_MODE, i);
    760 
    761 	s = splx(s);
    762 }
    763