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