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