Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / atari / dev / grfabs_et.c
blobdb96eba0164ae35af91661270fe8d5141e36cf62
1 /* $NetBSD: grfabs_et.c,v 1.32 2009/07/19 05:43:22 tsutsui Exp $ */
3 /*
4 * Copyright (c) 1996 Leo Weppelman.
5 * All rights reserved.
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.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * Most of the lower-level et4000 stuff was derived from:
30 * .../amiga/dev/grf_et.c
32 * Which was copyrighted by:
33 * Copyright (c) 1996 Tobias Abt
34 * Copyright (c) 1995 Ezra Story
35 * Copyright (c) 1995 Kari Mettinen
36 * Copyright (c) 1994 Markus Wild
37 * Copyright (c) 1994 Lutz Vieweg
39 * Thanks guys!
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: grfabs_et.c,v 1.32 2009/07/19 05:43:22 tsutsui Exp $");
46 #include <sys/param.h>
47 #include <sys/queue.h>
48 #include <sys/malloc.h>
49 #include <sys/device.h>
50 #include <sys/systm.h>
52 #include <uvm/uvm_extern.h>
55 * For PCI probing...
57 #include <dev/pci/pcireg.h>
58 #include <dev/pci/pcivar.h>
59 #include <dev/pci/pcidevs.h>
61 #include <machine/iomap.h>
62 #include <machine/video.h>
63 #include <machine/mfp.h>
64 #include <machine/cpu.h>
65 #include <atari/atari/device.h>
66 #include <atari/dev/grfioctl.h>
67 #include <atari/dev/grfabs_reg.h>
68 #include <atari/dev/grfabs_et.h>
69 #include <atari/dev/grf_etreg.h>
71 #define SAVEBUF_SIZE (32*1024 + sizeof(save_area_t))
74 * Allow a 16Kb io-region and a 4MB frame buffer to be mapped. This
75 * is more or less required by the XFree server.
77 #define REG_MAPPABLE (16 * 1024)
78 #define FRAME_MAPPABLE (4 * 1024 * 1024)
79 #define VGA_MAPPABLE (128 * 1024)
80 #define VGA_BASE 0xa0000
83 * Linear memory base, near the end of the pci area
85 #define PCI_LINMEMBASE 0x0e000000
88 * Function decls
90 static void init_view(view_t *, bmap_t *, dmode_t *, box_t *);
91 static colormap_t *alloc_colormap(dmode_t *);
92 static void et_display_view(view_t *);
93 static view_t *et_alloc_view(dmode_t *, dimen_t *, u_char);
94 static void et_free_view(view_t *);
95 static void et_loadmode(struct grfvideo_mode *, et_sv_reg_t *);
96 static void et_remove_view(view_t *);
97 static void et_save_view(view_t *);
98 static int et_use_colormap(view_t *, colormap_t *);
101 * Our function switch table
103 struct grfabs_sw et_vid_sw = {
104 et_display_view,
105 et_alloc_view,
106 et_free_view,
107 et_remove_view,
108 et_save_view,
109 et_use_colormap
112 static struct grfvideo_mode hw_modes[] = {
114 0, "", 22450000, /* num, descr, pix-clock */
115 640, 400, 4, /* width, height, depth */
116 632/8, 672/8, 688/8, 808/8, 768/8,/* HBS, HBE, HSS, HSE, HT */
117 399, 450, 408, 413, 449 /* VBS, VBE, VSS, VSE, VT */
120 0, "", 25175000, /* num, descr, pix-clock */
121 640, 480, 4, /* width, height, depth */
122 632/8, 672/8, 688/8, 752/8, 752/8,/* HBS, HBE, HSS, HSE, HT */
123 481, 522, 490, 498, 522 /* VBS, VBE, VSS, VSE, VT */
127 static dmode_t vid_modes[] = {
128 { { NULL, NULL },
129 "640x400", { 640, 400 }, 1, (void*)&hw_modes[0], &et_vid_sw },
130 { { NULL, NULL },
131 "640x480", { 640, 480 }, 1, (void*)&hw_modes[1], &et_vid_sw },
132 { { NULL, NULL }, NULL, }
135 #define ET_NUMCLOCKS 32
137 static u_int et_clockfreqs[ET_NUMCLOCKS] = {
138 6293750, 7080500, 7875000, 8125000,
139 9000000, 9375000, 10000000, 11225000,
140 12587500, 14161000, 15750000, 16250000,
141 18000000, 18750000, 20000000, 22450000,
142 25175000, 28322000, 31500000, 32500000,
143 36000000, 37500000, 40000000, 44900000,
144 50350000, 56644000, 63000000, 65000000,
145 72000000, 75000000, 80000000, 89800000
148 static bmap_t con_bm; /* XXX */
150 struct grfabs_et_priv {
151 pcitag_t pci_tag;
152 void *regkva;
153 void *memkva;
154 u_int linbase;
155 int regsz;
156 int memsz;
157 int board_type;
158 } et_priv;
161 * Board types:
163 #define BT_ET4000 1
164 #define BT_ET6000 2
167 * XXX: called from ite console init routine.
168 * Initialize list of posible video modes.
170 void
171 et_probe_video(MODES *modelp)
173 dmode_t *dm;
174 int i;
176 for (i = 0; (dm = &vid_modes[i])->name != NULL; i++) {
177 LIST_INSERT_HEAD(modelp, dm, link);
181 static void
182 et_display_view(view_t *v)
184 dmode_t *dm = v->mode;
185 bmap_t *bm = v->bitmap;
186 int sv_size;
187 u_short *src, *dst;
188 save_area_t *sa;
190 if (dm->current_view && (dm->current_view != v)) {
192 * Mark current view for this mode as no longer displayed
194 dm->current_view->flags &= ~VF_DISPLAY;
196 dm->current_view = v;
197 v->flags |= VF_DISPLAY;
199 if ((sa = (save_area_t*)v->save_area) == NULL)
200 return; /* XXX: Can't happen.... */
203 * Restore register settings and turn the plane pointer
204 * to the card-memory
206 et_hwrest(&sa->sv_regs);
207 bm->plane = et_priv.memkva;
209 et_use_colormap(v, v->colormap);
212 * Copy the backing store to card-memory
214 sv_size = sa->fb_size;
215 src = sa->sv_fb;
216 dst = (u_short *)bm->plane;
217 while (sv_size--)
218 *dst++ = *src++;
221 void
222 et_remove_view(view_t *v)
224 dmode_t *mode = v->mode;
226 if (mode->current_view == v) {
227 #if 0
228 if (v->flags & VF_DISPLAY)
229 panic("Cannot shutdown display"); /* XXX */
230 #endif
231 mode->current_view = NULL;
233 v->flags &= ~VF_DISPLAY;
236 void
237 et_save_view(view_t *v)
239 bmap_t *bm = v->bitmap;
240 u_char font_height;
241 int sv_size;
242 u_short *src, *dst;
243 save_area_t *sa;
244 volatile u_char *ba;
246 if (!atari_realconfig)
247 return;
249 ba = et_priv.regkva;
251 if (RGfx(ba, GCT_ID_MISC) & 1) {
252 #if 0 /* XXX: Can't use printf here.... */
253 printf("et_save_view: Don't know how to save"
254 " a graphics mode\n");
255 #endif
256 return;
258 if (v->save_area == NULL)
259 v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_NOWAIT);
262 * Calculate the size of the copy
264 font_height = RCrt(ba, CRT_ID_MAX_ROW_ADDRESS) & 0x1f;
265 sv_size = bm->bytes_per_row * (bm->rows / (font_height + 1));
266 sv_size = min(SAVEBUF_SIZE, sv_size);
269 * Save all we need to know....
271 sa = (save_area_t *)v->save_area;
272 et_hwsave(&sa->sv_regs);
273 sa->fb_size = sv_size;
274 src = (u_short *)bm->plane;
275 dst = sa->sv_fb;
276 while (sv_size--)
277 *dst++ = *src++;
278 bm->plane = (u_char *)sa->sv_fb;
281 void
282 et_free_view(view_t *v)
284 if(v) {
285 et_remove_view(v);
286 if (v->colormap != &gra_con_cmap)
287 free(v->colormap, M_DEVBUF);
288 if (v->save_area != NULL)
289 free(v->save_area, M_DEVBUF);
290 if (v != &gra_con_view) {
291 free(v->bitmap, M_DEVBUF);
292 free(v, M_DEVBUF);
297 static int
298 et_use_colormap(view_t *v, colormap_t *cm)
300 return (0); /* XXX: Nothing here for now... */
303 static view_t *
304 et_alloc_view(dmode_t *mode, dimen_t *dim, u_char depth)
306 view_t *v;
307 bmap_t *bm;
308 box_t box;
309 save_area_t *sa;
311 if (!atari_realconfig) {
312 v = &gra_con_view;
313 bm = &con_bm;
315 else {
316 v = malloc(sizeof(*v), M_DEVBUF, M_WAITOK);
317 bm = malloc(sizeof(*bm), M_DEVBUF, M_WAITOK);
319 v->bitmap = bm;
322 * Initialize the bitmap
324 bm->plane = et_priv.memkva;
325 bm->vga_address = (void *)kvtop(et_priv.memkva);
326 bm->vga_base = VGA_BASE;
327 bm->hw_address = (void *)(PCI_MEM_PHYS | et_priv.linbase);
328 bm->lin_base = et_priv.linbase;
329 bm->regs = et_priv.regkva;
330 bm->hw_regs = (void *)kvtop(et_priv.regkva);
331 bm->reg_size = REG_MAPPABLE;
332 bm->phys_mappable = FRAME_MAPPABLE;
333 bm->vga_mappable = VGA_MAPPABLE;
335 bm->bytes_per_row = (mode->size.width * depth) / NBBY;
336 bm->rows = mode->size.height;
337 bm->depth = depth;
340 * Allocate a save_area.
341 * Note: If atari_realconfig is false, no save area is (can be)
342 * allocated. This means that the plane is the video memory,
343 * which is what's wanted in this case.
345 if (atari_realconfig) {
346 v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_WAITOK);
347 sa = (save_area_t*)v->save_area;
348 sa->fb_size = 0;
349 bm->plane = (u_char *)sa->sv_fb;
350 et_loadmode(mode->data, &sa->sv_regs);
352 else v->save_area = NULL;
354 v->colormap = alloc_colormap(mode);
355 if (v->colormap) {
356 INIT_BOX(&box,0,0,mode->size.width,mode->size.height);
357 init_view(v, bm, mode, &box);
358 return (v);
360 if (v != &gra_con_view) {
361 free(v, M_DEVBUF);
362 free(bm, M_DEVBUF);
364 return (NULL);
367 static void
368 init_view(view_t *v, bmap_t *bm, dmode_t *mode, box_t *dbox)
370 v->bitmap = bm;
371 v->mode = mode;
372 v->flags = 0;
373 memcpy(&v->display, dbox, sizeof(box_t));
376 /* XXX: No more than a stub... */
377 static colormap_t *
378 alloc_colormap(dmode_t *dm)
380 colormap_t *cm;
381 int i;
383 cm = &gra_con_cmap;
384 cm->entry = gra_con_colors;
386 cm->first = 0;
387 cm->size = 2;
389 for (i = 0; i < 2; i++)
390 cm->entry[i] = gra_def_color16[i % 16];
391 return (cm);
395 * Go look for a VGA card on the PCI-bus. This search is a
396 * stripped down version of the PCI-probe. It only looks on
397 * bus0 for et4000/et6000 cards. The first card found is used.
400 et_probe_card(void)
402 pci_chipset_tag_t pc = NULL; /* XXX */
403 pcitag_t tag;
404 int device, found, id, maxndevs;
406 found = 0;
407 tag = 0;
408 id = 0;
409 maxndevs = pci_bus_maxdevs(pc, 0);
411 for (device = 0; !found && (device < maxndevs); device++) {
413 tag = pci_make_tag(pc, 0, device, 0);
414 id = pci_conf_read(pc, tag, PCI_ID_REG);
415 if (id == 0 || id == 0xffffffff)
416 continue;
417 switch (PCI_PRODUCT(id)) {
418 case PCI_PRODUCT_TSENG_ET6000:
419 case PCI_PRODUCT_TSENG_ET4000_W32P_A:
420 case PCI_PRODUCT_TSENG_ET4000_W32P_B:
421 case PCI_PRODUCT_TSENG_ET4000_W32P_C:
422 case PCI_PRODUCT_TSENG_ET4000_W32P_D:
423 found = 1;
424 break;
425 default:
426 break;
429 if (!found)
430 return (0);
432 if (PCI_PRODUCT(id) == PCI_PRODUCT_TSENG_ET6000)
433 et_priv.board_type = BT_ET6000;
434 else {
435 #ifdef ET4000_HAS_2MB_MEM
436 volatile u_char *ba;
437 #endif
439 et_priv.board_type = BT_ET4000;
441 #ifdef ET4000_HAS_2MB_MEM
442 /* set KEY to access the tseng private registers */
443 ba = (volatile void *)pci_io_addr;
444 vgaw(ba, GREG_HERCULESCOMPAT, 0x03);
445 vgaw(ba, GREG_DISPMODECONTROL, 0xa0);
447 /* enable memory interleave */
448 WCrt(ba, CRT_ID_RASCAS_CONFIG, 0xa0);
449 WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x89);
450 #endif
453 et_priv.pci_tag = tag;
456 * The things below are setup in atari_init.c
458 et_priv.regkva = (void *)pci_io_addr;
459 et_priv.memkva = (void *)pci_mem_addr;
460 et_priv.linbase = PCI_LINMEMBASE; /* XXX pci_conf_read??? */
461 et_priv.memsz = PCI_VGA_SIZE;
462 et_priv.regsz = PCI_IO_SIZE;
464 if (!atari_realconfig) {
465 et_loadmode(&hw_modes[0], NULL);
466 return (1);
469 return (1);
472 static void
473 et_loadmode(struct grfvideo_mode *mode, et_sv_reg_t *regs)
475 unsigned short HDE, VDE;
476 int lace, dblscan;
477 int uplim, lowlim;
478 int i;
479 unsigned char clock, tmp;
480 volatile u_char *ba;
481 et_sv_reg_t loc_regs;
483 if (regs == NULL)
484 regs = &loc_regs;
486 ba = et_priv.regkva;
487 HDE = mode->disp_width / 8 - 1;
488 VDE = mode->disp_height - 1;
490 /* figure out whether lace or dblscan is needed */
492 uplim = mode->disp_height + (mode->disp_height / 4);
493 lowlim = mode->disp_height - (mode->disp_height / 4);
494 lace = (((mode->vtotal * 2) > lowlim)
495 && ((mode->vtotal * 2) < uplim)) ? 1 : 0;
496 dblscan = (((mode->vtotal / 2) > lowlim)
497 && ((mode->vtotal / 2) < uplim)) ? 1 : 0;
499 /* adjustments */
500 if (lace)
501 VDE /= 2;
503 regs->misc_output = 0x23; /* Page 0, Color mode */
504 regs->seg_sel = 0x00;
505 regs->state_ctl = 0x00;
507 regs->seq[SEQ_ID_RESET] = 0x03; /* reset off */
508 regs->seq[SEQ_ID_CLOCKING_MODE] = 0x21; /* Turn off screen */
509 regs->seq[SEQ_ID_MAP_MASK] = 0xff; /* CPU writes all planes*/
510 regs->seq[SEQ_ID_CHAR_MAP_SELECT] = 0x00; /* Char. generator 0 */
511 regs->seq[SEQ_ID_MEMORY_MODE] = 0x0e; /* Seq. Memory mode */
514 * Set the clock...
516 for(clock = ET_NUMCLOCKS-1; clock > 0; clock--) {
517 if (et_clockfreqs[clock] <= mode->pixel_clock)
518 break;
520 regs->misc_output |= (clock & 3) << 2;
521 regs->aux_mode = 0xb4 | ((clock & 8) << 3);
522 regs->compat_6845 = (clock & 4) ? 0x0a : 0x08;
525 * The display parameters...
527 regs->crt[CRT_ID_HOR_TOTAL] = mode->htotal;
528 regs->crt[CRT_ID_HOR_DISP_ENA_END] = ((HDE >= mode->hblank_start)
529 ? mode->hblank_stop - 1
530 : HDE);
531 regs->crt[CRT_ID_START_HOR_BLANK] = mode->hblank_start;
532 regs->crt[CRT_ID_END_HOR_BLANK] = (mode->hblank_stop & 0x1f) | 0x80;
533 regs->crt[CRT_ID_START_HOR_RETR] = mode->hsync_start;
534 regs->crt[CRT_ID_END_HOR_RETR] = (mode->hsync_stop & 0x1f)
535 | ((mode->hblank_stop & 0x20)
536 ? 0x80 : 0x00);
537 regs->crt[CRT_ID_VER_TOTAL] = mode->vtotal;
538 regs->crt[CRT_ID_START_VER_RETR] = mode->vsync_start;
539 regs->crt[CRT_ID_END_VER_RETR] = (mode->vsync_stop & 0x0f) | 0x30;
540 regs->crt[CRT_ID_VER_DISP_ENA_END] = VDE;
541 regs->crt[CRT_ID_START_VER_BLANK] = mode->vblank_start;
542 regs->crt[CRT_ID_END_VER_BLANK] = mode->vblank_stop;
543 regs->crt[CRT_ID_MODE_CONTROL] = 0xab;
544 regs->crt[CRT_ID_START_ADDR_HIGH] = 0x00;
545 regs->crt[CRT_ID_START_ADDR_LOW] = 0x00;
546 regs->crt[CRT_ID_LINE_COMPARE] = 0xff;
547 regs->crt[CRT_ID_UNDERLINE_LOC] = 0x00;
548 regs->crt[CRT_ID_PRESET_ROW_SCAN] = 0x00;
549 regs->crt[CRT_ID_OFFSET] = mode->disp_width/16;
550 regs->crt[CRT_ID_MAX_ROW_ADDRESS] =
551 0x40 |
552 (dblscan ? 0x80 : 0x00) |
553 ((mode->vblank_start & 0x200) ? 0x20 : 0x00);
554 regs->crt[CRT_ID_OVERFLOW] =
555 0x10 |
556 ((mode->vtotal & 0x100) ? 0x01 : 0x00) |
557 ((VDE & 0x100) ? 0x02 : 0x00) |
558 ((mode->vsync_start & 0x100) ? 0x04 : 0x00) |
559 ((mode->vblank_start & 0x100) ? 0x08 : 0x00) |
560 ((mode->vtotal & 0x200) ? 0x20 : 0x00) |
561 ((VDE & 0x200) ? 0x40 : 0x00) |
562 ((mode->vsync_start & 0x200) ? 0x80 : 0x00);
563 regs->overfl_high =
564 0x10 |
565 ((mode->vblank_start & 0x400) ? 0x01 : 0x00) |
566 ((mode->vtotal & 0x400) ? 0x02 : 0x00) |
567 ((VDE & 0x400) ? 0x04 : 0x00) |
568 ((mode->vsync_start & 0x400) ? 0x08 : 0x00) |
569 (lace ? 0x80 : 0x00);
570 regs->hor_overfl =
571 ((mode->htotal & 0x100) ? 0x01 : 0x00) |
572 ((mode->hblank_start & 0x100) ? 0x04 : 0x00) |
573 ((mode->hsync_start & 0x100) ? 0x10 : 0x00);
575 regs->grf[GCT_ID_SET_RESET] = 0x00;
576 regs->grf[GCT_ID_ENABLE_SET_RESET] = 0x00;
577 regs->grf[GCT_ID_COLOR_COMPARE] = 0x00;
578 regs->grf[GCT_ID_DATA_ROTATE] = 0x00;
579 regs->grf[GCT_ID_READ_MAP_SELECT] = 0x00;
580 regs->grf[GCT_ID_GRAPHICS_MODE] = mode->depth == 1 ? 0x00: 0x40;
581 regs->grf[GCT_ID_MISC] = 0x01;
582 regs->grf[GCT_ID_COLOR_XCARE] = 0x0f;
583 regs->grf[GCT_ID_BITMASK] = 0xff;
585 for (i = 0; i < 0x10; i++)
586 regs->attr[i] = i;
587 regs->attr[ACT_ID_ATTR_MODE_CNTL] = 0x01;
588 regs->attr[ACT_ID_OVERSCAN_COLOR] = 0x00;
589 regs->attr[ACT_ID_COLOR_PLANE_ENA] = 0x0f;
590 regs->attr[ACT_ID_HOR_PEL_PANNING] = 0x00;
591 regs->attr[ACT_ID_COLOR_SELECT] = 0x00;
592 regs->attr[ACT_ID_MISCELLANEOUS] = 0x00;
595 * XXX: This works for depth == 4. I need some better docs
596 * to fix the other modes....
599 * What we need would be probe functions for RAMDAC/clock chip
601 vgar(ba, VDAC_ADDRESS); /* clear old state */
602 vgar(ba, VDAC_MASK);
603 vgar(ba, VDAC_MASK);
604 vgar(ba, VDAC_MASK);
605 vgar(ba, VDAC_MASK);
607 vgaw(ba, VDAC_MASK, 0); /* set to palette */
608 vgar(ba, VDAC_ADDRESS); /* clear state */
610 vgaw(ba, VDAC_MASK, 0xff);
612 * End of depth stuff
616 * Compute Hsync & Vsync polarity
617 * Note: This seems to be some kind of a black art :-(
619 tmp = regs->misc_output & 0x3f;
620 #if 1 /* This is according to my BW monitor & Xfree... */
621 if (VDE < 400)
622 tmp |= 0x40; /* -hsync +vsync */
623 else if (VDE < 480)
624 tmp |= 0xc0; /* -hsync -vsync */
625 #else /* This is according to my color monitor.... */
626 if (VDE < 400)
627 tmp |= 0x00; /* +hsync +vsync */
628 else if (VDE < 480)
629 tmp |= 0x80; /* +hsync -vsync */
630 #endif
631 /* I'm unable to try the rest.... */
632 regs->misc_output = tmp;
634 if(regs == &loc_regs)
635 et_hwrest(regs);
638 void
639 et_hwsave(et_sv_reg_t *et_regs)
641 volatile u_char *ba;
642 int i, s;
644 ba = et_priv.regkva;
646 s = splhigh();
649 * General VGA registers
651 et_regs->misc_output = vgar(ba, GREG_MISC_OUTPUT_R);
652 for(i = 0; i < 25; i++)
653 et_regs->crt[i] = RCrt(ba, i);
654 for(i = 0; i < 21; i++)
655 et_regs->attr[i] = RAttr(ba, i | 0x20);
656 for(i = 0; i < 9; i++)
657 et_regs->grf[i] = RGfx(ba, i);
658 for(i = 0; i < 5; i++)
659 et_regs->seq[i] = RSeq(ba, i);
662 * ET4000 extensions
664 et_regs->ext_start = RCrt(ba, CTR_ID_EXT_START);
665 et_regs->compat_6845 = RCrt(ba, CRT_ID_6845_COMPAT);
666 et_regs->overfl_high = RCrt(ba, CRT_ID_OVERFLOW_HIGH);
667 et_regs->hor_overfl = RCrt(ba, CRT_ID_HOR_OVERFLOW);
668 et_regs->state_ctl = RSeq(ba, SEQ_ID_STATE_CONTROL);
669 et_regs->aux_mode = RSeq(ba, SEQ_ID_AUXILIARY_MODE);
670 et_regs->seg_sel = vgar(ba, GREG_SEGMENTSELECT);
672 splx(s);
675 void
676 et_hwrest(et_sv_reg_t *et_regs)
678 volatile u_char *ba;
679 int i, s;
681 ba = et_priv.regkva;
683 s = splhigh();
685 vgaw(ba, GREG_SEGMENTSELECT, 0);
686 vgaw(ba, GREG_MISC_OUTPUT_W, et_regs->misc_output);
689 * General VGA registers
691 WSeq(ba, SEQ_ID_RESET, 0x01);
692 for(i = 1; i < 5; i++)
693 WSeq(ba, i, et_regs->seq[i]);
694 WSeq(ba, SEQ_ID_RESET, 0x03);
697 * Make sure we're allowed to write all crt-registers
699 WCrt(ba, CRT_ID_END_VER_RETR,
700 et_regs->crt[CRT_ID_END_VER_RETR] & 0x7f);
701 for(i = 0; i < 25; i++)
702 WCrt(ba, i, et_regs->crt[i]);
703 for(i = 0; i < 9; i++)
704 WGfx(ba, i, et_regs->grf[i]);
705 for(i = 0; i < 21; i++)
706 WAttr(ba, i | 0x20, et_regs->attr[i]);
709 * ET4000 extensions
711 WSeq(ba, SEQ_ID_STATE_CONTROL, et_regs->state_ctl);
712 WSeq(ba, SEQ_ID_AUXILIARY_MODE, et_regs->aux_mode);
713 WCrt(ba, CTR_ID_EXT_START, et_regs->ext_start);
714 WCrt(ba, CRT_ID_6845_COMPAT, et_regs->compat_6845);
715 WCrt(ba, CRT_ID_OVERFLOW_HIGH, et_regs->overfl_high);
716 WCrt(ba, CRT_ID_HOR_OVERFLOW, et_regs->hor_overfl);
717 vgaw(ba, GREG_SEGMENTSELECT, et_regs->seg_sel);
719 i = et_regs->seq[SEQ_ID_CLOCKING_MODE] & ~0x20;
720 WSeq(ba, SEQ_ID_CLOCKING_MODE, i);
722 splx(s);