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