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