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