1 /* $NetBSD: grf_et.c,v 1.27 2009/03/18 17:06:42 cegger Exp $ */
4 * Copyright (c) 1997 Klaus Burkert
5 * Copyright (c) 1996 Tobias Abt
6 * Copyright (c) 1995 Ezra Story
7 * Copyright (c) 1995 Kari Mettinen
8 * Copyright (c) 1994 Markus Wild
9 * Copyright (c) 1994 Lutz Vieweg
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by Lutz Vieweg.
23 * 4. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include "opt_amigacons.h"
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: grf_et.c,v 1.27 2009/03/18 17:06:42 cegger Exp $");
46 * Graphics routines for Tseng ET4000 (&W32) boards,
48 * This code offers low-level routines to access Tseng ET4000
49 * graphics-boards from within NetBSD for the Amiga.
50 * No warranties for any kind of function at all - this
51 * code may crash your hardware and scratch your harddisk. Use at your
52 * own risk. Freely distributable.
54 * Modified for Tseng ET4000 from
55 * Kari Mettinen's Cirrus driver by Tobias Abt
57 * Fixed Merlin in Z-III, fixed LACE and DBLSCAN, added Domino16M proto
58 * and AT&T ATT20c491 DAC, added memory-size detection by Klaus Burkert.
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/errno.h>
68 #include <sys/ioctl.h>
69 #include <sys/device.h>
70 #include <sys/malloc.h>
72 #include <machine/cpu.h>
75 #include <amiga/dev/itevar.h>
77 #include <amiga/amiga/device.h>
78 #include <amiga/dev/grfioctl.h>
79 #include <amiga/dev/grfvar.h>
80 #include <amiga/dev/grf_etreg.h>
81 #include <amiga/dev/zbusvar.h>
83 int et_mondefok(struct grfvideo_mode
*gv
);
84 void et_boardinit(struct grf_softc
*gp
);
85 static void et_CompFQ(u_int fq
, u_char
*num
, u_char
*denom
);
86 int et_getvmode(struct grf_softc
*gp
, struct grfvideo_mode
*vm
);
87 int et_setvmode(struct grf_softc
*gp
, unsigned int mode
);
88 int et_toggle(struct grf_softc
*gp
, unsigned short);
89 int et_getcmap(struct grf_softc
*gfp
, struct grf_colormap
*cmap
);
90 int et_putcmap(struct grf_softc
*gfp
, struct grf_colormap
*cmap
);
92 void et_off(struct grf_softc
*gp
);
94 void et_inittextmode(struct grf_softc
*gp
);
95 int et_ioctl(register struct grf_softc
*gp
, u_long cmd
, void *data
);
96 int et_getmousepos(struct grf_softc
*gp
, struct grf_position
*data
);
97 void et_writesprpos(volatile char *ba
, short x
, short y
);
98 int et_setmousepos(struct grf_softc
*gp
, struct grf_position
*data
);
99 static int et_setspriteinfo(struct grf_softc
*gp
, struct grf_spriteinfo
*data
);
100 int et_getspriteinfo(struct grf_softc
*gp
, struct grf_spriteinfo
*data
);
101 static int et_getspritemax(struct grf_softc
*gp
, struct grf_position
*data
);
102 int et_setmonitor(struct grf_softc
*gp
, struct grfvideo_mode
*gv
);
103 int et_blank(struct grf_softc
*gp
, int *on
);
104 static int et_getControllerType(struct grf_softc
*gp
);
105 static int et_getDACType(struct grf_softc
*gp
);
107 int grfetmatch(struct device
*, struct cfdata
*, void *);
108 void grfetattach(struct device
*, struct device
*, void *);
109 int grfetprint(void *, const char *);
110 void et_memset(volatile unsigned char *d
, unsigned char c
, int l
);
113 * Graphics display definitions.
114 * These are filled by 'grfconfig' using GRFIOCSETMON.
116 #define monitor_def_max 24
117 static struct grfvideo_mode monitor_def
[24] = {
118 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
119 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
120 {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}
122 static struct grfvideo_mode
*monitor_current
= &monitor_def
[0];
124 /* Console display definition.
125 * Default hardcoded text mode. This grf_et is set up to
126 * use one text mode only, and this is it. You may use
127 * grfconfig to change the mode after boot.
131 #define TSENGFONT kernel_font_8x11
132 #define TSENGFONTY 11
134 #define TSENGFONT kernel_font_8x8
137 extern unsigned char TSENGFONT
[];
139 struct grfettext_mode etconsole_mode
= {
140 {255, "", 25000000, 640, 480, 4, 640/8, 680/8, 768/8, 800/8,
141 481, 491, 493, 525, 0},
142 8, TSENGFONTY
, 640 / 8, 480 / TSENGFONTY
, TSENGFONT
, 32, 255
146 unsigned char etconscolors
[3][3] = { /* background, foreground, hilite */
147 {0, 0x40, 0x50}, {152, 152, 152}, {255, 255, 255}
150 int ettype
= 0; /* oMniBus, Domino or Merlin */
151 int etctype
= 0; /* ET4000 or ETW32 */
152 int etdtype
= 0; /* Type of DAC (see grf_etregs.h) */
154 char etcmap_shift
= 0; /* 6 or 8 bit cmap entries */
155 unsigned char pass_toggle
; /* passthru status tracker */
157 unsigned char Merlin_switch
= 0;
160 * Because all Tseng-boards have 2 configdev entries, one for
161 * framebuffer mem and the other for regs, we have to hold onto
162 * the pointers globally until we match on both. This and 'ettype'
163 * are the primary obsticles to multiple board support, but if you
164 * have multiple boards you have bigger problems than grf_et.
166 static void *et_fbaddr
= 0; /* framebuffer */
167 static void *et_regaddr
= 0; /* registers */
168 static int et_fbsize
; /* framebuffer size */
170 /* current sprite info, if you add support for multiple boards
171 * make this an array or something
173 struct grf_spriteinfo et_cursprite
;
175 /* sprite bitmaps in kernel stack, you'll need to arrayize these too if
176 * you add multiple board support
178 static unsigned char et_imageptr
[8 * 64], et_maskptr
[8 * 64];
179 static unsigned char et_sprred
[2], et_sprgreen
[2], et_sprblue
[2];
181 /* standard driver stuff */
182 CFATTACH_DECL(grfet
, sizeof(struct grf_softc
),
183 grfetmatch
, grfetattach
, NULL
, NULL
);
185 static struct cfdata
*cfdata
;
188 grfetmatch(struct device
*pdp
, struct cfdata
*cfp
, void *auxp
)
190 struct zbus_args
*zap
;
191 static int regprod
, regprod2
= 0, fbprod
;
196 if (amiga_realconfig
== 0)
200 /* Grab the first board we encounter as the preferred one. This will
201 * allow one board to work in a multiple Tseng board system, but not
202 * multiple boards at the same time. */
204 switch (zap
->manid
) {
206 if (zap
->prodid
!= 0)
212 /* 2167/3 is Domino16M proto (crest) */
213 if (zap
->prodid
!= 3 && zap
->prodid
!= 2 && zap
->prodid
!= 1)
220 if (zap
->prodid
!= 3 && zap
->prodid
!= 4)
230 if (ettype
!= zap
->manid
) {
235 /* Configure either registers or framebuffer in any order */
236 /* as said before, oMniBus does not support ProdID */
237 if (ettype
== OMNIBUS
) {
238 if (zap
->size
== 64 * 1024) {
240 et_regaddr
= zap
->va
;
244 et_fbsize
= zap
->size
;
247 if (zap
->prodid
== regprod
|| zap
->prodid
== regprod2
) {
248 et_regaddr
= zap
->va
;
250 if (zap
->prodid
== fbprod
) {
252 et_fbsize
= zap
->size
;
260 if (amiga_realconfig
== 0) {
270 grfetattach(struct device
*pdp
, struct device
*dp
, void *auxp
)
272 static struct grf_softc congrf
;
273 struct zbus_args
*zap
;
274 struct grf_softc
*gp
;
275 static char attachflag
= 0;
281 /* make sure both halves have matched */
282 if (!et_regaddr
|| !et_fbaddr
)
285 /* do all that messy console/grf stuff */
289 gp
= (struct grf_softc
*) dp
;
291 if (dp
!= NULL
&& congrf
.g_regkva
!= 0) {
293 * inited earlier, just copy (not device struct)
295 memcpy(&gp
->g_display
, &congrf
.g_display
,
296 (char *) &gp
[1] - (char *) &gp
->g_display
);
298 gp
->g_regkva
= (volatile void *) et_regaddr
;
299 gp
->g_fbkva
= (volatile void *) et_fbaddr
;
301 gp
->g_unit
= GRF_ET4000_UNIT
;
302 gp
->g_mode
= et_mode
;
303 gp
->g_conpri
= grfet_cnprobe();
304 gp
->g_flags
= GF_ALIVE
;
306 /* wakeup the board */
311 (void) et_load_mon(gp
, &etconsole_mode
);
318 if (amiga_config_found(cfdata
, &gp
->g_device
, gp
, grfetprint
)) {
320 printf("grfet: %dMB ", et_fbsize
/ 0x100000);
335 printf("Tseng ET4000");
338 printf("Tseng ETW32");
344 printf("Sierra SC11483 DAC");
347 printf("Sierra SC15025 DAC");
353 printf("BrookTree Bt482 DAC");
356 printf("AT&T ATT20c491 DAC");
359 printf(" being used\n");
362 printf("grfet unattached!!\n");
368 grfetprint(void *auxp
, const char *pnp
)
371 aprint_normal("ite at %s: ", pnp
);
377 et_boardinit(struct grf_softc
*gp
)
379 volatile unsigned char *ba
= gp
->g_regkva
;
382 /* wakeup board and flip passthru OFF */
387 if (ettype
== MERLIN
) {
388 /* Merlin needs some special initialisations */
389 vgaw(ba
, MERLIN_SWITCH_REG
, 0);
391 vgaw(ba
, MERLIN_SWITCH_REG
, 8);
393 vgaw(ba
, MERLIN_SWITCH_REG
, 0);
395 vgaw(ba
, MERLIN_VDAC_DATA
, 1);
397 vgaw(ba
, MERLIN_VDAC_INDEX
, 0x00);
398 vgaw(ba
, MERLIN_VDAC_SPRITE
, 0xff);
399 vgaw(ba
, MERLIN_VDAC_INDEX
, 0x01);
400 vgaw(ba
, MERLIN_VDAC_SPRITE
, 0x0f);
401 vgaw(ba
, MERLIN_VDAC_INDEX
, 0x02);
402 vgaw(ba
, MERLIN_VDAC_SPRITE
, 0x42);
403 vgaw(ba
, MERLIN_VDAC_INDEX
, 0x03);
404 vgaw(ba
, MERLIN_VDAC_SPRITE
, 0x00);
406 vgaw(ba
, MERLIN_VDAC_DATA
, 0);
410 /* setup initial unchanging parameters */
412 vgaw(ba
, GREG_HERCULESCOMPAT
+ ((ettype
== DOMINO
) ? 0x0fff : 0), 0x03);
413 vgaw(ba
, GREG_DISPMODECONTROL
, 0xa0);
414 vgaw(ba
, GREG_MISC_OUTPUT_W
, 0x63);
416 if (ettype
== DOMINO
)
418 vgaw(ba
, CRT_ADDRESS
, CRT_ID_VIDEO_CONFIG1
);
419 vgaw(ba
, CRT_ADDRESS_W
+ 0x0fff,
420 0xc0 | vgar(ba
, CRT_ADDRESS_R
+ 0x0fff));
423 WSeq(ba
, SEQ_ID_RESET
, 0x03);
424 WSeq(ba
, SEQ_ID_CLOCKING_MODE
, 0x21); /* 8 dot, Display off */
425 WSeq(ba
, SEQ_ID_MAP_MASK
, 0x0f);
426 WSeq(ba
, SEQ_ID_CHAR_MAP_SELECT
, 0x00);
427 WSeq(ba
, SEQ_ID_MEMORY_MODE
, 0x0e);
428 WSeq(ba
, SEQ_ID_STATE_CONTROL
, 0x00);
429 WSeq(ba
, SEQ_ID_AUXILIARY_MODE
, 0xf4);
431 WCrt(ba
, CRT_ID_PRESET_ROW_SCAN
, 0x00);
432 WCrt(ba
, CRT_ID_CURSOR_START
, 0x00);
433 WCrt(ba
, CRT_ID_CURSOR_END
, 0x08);
434 WCrt(ba
, CRT_ID_START_ADDR_HIGH
, 0x00);
435 WCrt(ba
, CRT_ID_START_ADDR_LOW
, 0x00);
436 WCrt(ba
, CRT_ID_CURSOR_LOC_HIGH
, 0x00);
437 WCrt(ba
, CRT_ID_CURSOR_LOC_LOW
, 0x00);
439 WCrt(ba
, CRT_ID_UNDERLINE_LOC
, 0x67);
440 WCrt(ba
, CRT_ID_MODE_CONTROL
, 0xc3);
441 WCrt(ba
, CRT_ID_LINE_COMPARE
, 0xff);
444 WCrt(ba
, CRT_ID_RASCAS_CONFIG
, 0x28);
445 WCrt(ba
, CRT_ID_EXT_START
, 0x00);
446 WCrt(ba
, CRT_ID_6845_COMPAT
, 0x08);
448 /* ET4000/W32 special (currently only for Merlin (crest) */
449 if (ettype
== MERLIN
) {
450 WCrt(ba
, CRT_ID_SEGMENT_COMP
, 0x1c);
451 WCrt(ba
, CRT_ID_GENERAL_PURPOSE
, 0x00);
452 WCrt(ba
, CRT_ID_VIDEO_CONFIG1
, 0x93);
455 WCrt(ba
, CRT_ID_VIDEO_CONFIG1
, 0xd3);
458 WCrt(ba
, CRT_ID_VIDEO_CONFIG2
, 0x0f);
459 WCrt(ba
, CRT_ID_HOR_OVERFLOW
, 0x00);
461 vgaw(ba
, GREG_SEGMENTSELECT
, 0x00);
463 WGfx(ba
, GCT_ID_SET_RESET
, 0x00);
464 WGfx(ba
, GCT_ID_ENABLE_SET_RESET
, 0x00);
465 WGfx(ba
, GCT_ID_COLOR_COMPARE
, 0x00);
466 WGfx(ba
, GCT_ID_DATA_ROTATE
, 0x00);
467 WGfx(ba
, GCT_ID_READ_MAP_SELECT
, 0x00);
468 WGfx(ba
, GCT_ID_GRAPHICS_MODE
, 0x40);
469 WGfx(ba
, GCT_ID_MISC
, 0x01);
470 WGfx(ba
, GCT_ID_COLOR_XCARE
, 0x0f);
471 WGfx(ba
, GCT_ID_BITMASK
, 0xff);
473 for (x
= 0; x
< 0x10; x
++)
475 WAttr(ba
, ACT_ID_ATTR_MODE_CNTL
, 0x01);
476 WAttr(ba
, ACT_ID_OVERSCAN_COLOR
, 0x00);
477 WAttr(ba
, ACT_ID_COLOR_PLANE_ENA
, 0x0f);
478 WAttr(ba
, ACT_ID_HOR_PEL_PANNING
, 0x00);
479 WAttr(ba
, ACT_ID_COLOR_SELECT
, 0x00);
480 WAttr(ba
, ACT_ID_MISCELLANEOUS
, 0x00);
482 vgaw(ba
, VDAC_MASK
, 0xff);
484 vgaw(ba
, GREG_MISC_OUTPUT_W
, 0xe3);
486 /* colors initially set to greyscale */
489 vgaw(ba
, MERLIN_VDAC_INDEX
, 0);
490 for (x
= 255; x
>= 0; x
--) {
491 vgaw(ba
, MERLIN_VDAC_COLORS
, x
);
492 vgaw(ba
, MERLIN_VDAC_COLORS
, x
);
493 vgaw(ba
, MERLIN_VDAC_COLORS
, x
);
497 vgaw(ba
, VDAC_ADDRESS_W
, 0);
498 for (x
= 255; x
>= 0; x
--) {
499 vgaw(ba
, VDAC_DATA
+ ((ettype
== DOMINO
) ? 0x0fff : 0), x
);
500 vgaw(ba
, VDAC_DATA
+ ((ettype
== DOMINO
) ? 0x0fff : 0), x
);
501 vgaw(ba
, VDAC_DATA
+ ((ettype
== DOMINO
) ? 0x0fff : 0), x
);
505 /* set sprite bitmap pointers */
506 /* should work like that */
507 et_cursprite
.image
= et_imageptr
;
508 et_cursprite
.mask
= et_maskptr
;
509 et_cursprite
.cmap
.red
= et_sprred
;
510 et_cursprite
.cmap
.green
= et_sprgreen
;
511 et_cursprite
.cmap
.blue
= et_sprblue
;
513 /* card specific initialisations */
516 etctype
= et_getControllerType(gp
);
517 etdtype
= et_getDACType(gp
);
520 vgaw(ba
, GREG_SEGMENTSELECT2
, 0x00);
521 if (((vgar(ba
, GREG_FEATURE_CONTROL_R
) & 12) |
522 (vgar(ba
, GREG_STATUS0_R
) & 0x60)) == 0x24) {
523 WCrt(ba
, CRT_ID_VIDEO_CONFIG2
, 0x07); /* 1Mx4 RAM */
524 et_fbsize
= 0x400000; /* 4 MB */
527 /* check for 1MB or 2MB board (crest) */
528 /* has there a 1MB Merlin ever been sold ??? */
529 volatile unsigned long *et_fbtestaddr
;
530 et_fbtestaddr
= (volatile unsigned long *)gp
->g_fbkva
;
531 *et_fbtestaddr
= 0x0;
532 vgaw(ba
, GREG_SEGMENTSELECT2
, 0x11); /* 1MB offset */
533 *et_fbtestaddr
= 0x12345678;
534 vgaw(ba
, GREG_SEGMENTSELECT2
, 0x00);
535 if (*et_fbtestaddr
== 0x0)
536 et_fbsize
= 0x200000; /* 2 MB */
538 et_fbsize
= 0x100000; /* 1 MB */
540 /* ZorroII can map 2 MB max ... */
541 if (!iszthreepa(kvtop(__UNVOLATILE(gp
->g_fbkva
))) &&
542 et_fbsize
== 0x400000)
543 et_fbsize
= 0x200000;
549 etdtype
= et_getDACType(gp
);
556 et_getvmode(struct grf_softc
*gp
, struct grfvideo_mode
*vm
)
558 struct grfvideo_mode
*gv
;
561 /* Handle grabbing console mode */
562 if (vm
->mode_num
== 255) {
563 memcpy(vm
, &etconsole_mode
, sizeof(struct grfvideo_mode
));
564 /* XXX so grfconfig can tell us the correct text dimensions. */
565 vm
->depth
= etconsole_mode
.fy
;
569 if (vm
->mode_num
== 0)
570 vm
->mode_num
= (monitor_current
- monitor_def
) + 1;
571 if (vm
->mode_num
< 1 || vm
->mode_num
> monitor_def_max
)
573 gv
= monitor_def
+ (vm
->mode_num
- 1);
574 if (gv
->mode_num
== 0)
577 memcpy(vm
, gv
, sizeof(struct grfvideo_mode
));
580 /* adjust internal values to pixel values */
582 vm
->hblank_start
*= 8;
583 vm
->hsync_start
*= 8;
592 et_setvmode(struct grf_softc
*gp
, unsigned mode
)
594 if (!mode
|| (mode
> monitor_def_max
) ||
595 monitor_def
[mode
- 1].mode_num
== 0)
598 monitor_current
= monitor_def
+ (mode
- 1);
606 et_off(struct grf_softc
*gp
)
608 char *ba
= gp
->g_regkva
;
611 WSeq(ba
, SEQ_ID_CLOCKING_MODE
, 0x21);
617 et_blank(struct grf_softc
*gp
, int *on
)
619 WSeq(gp
->g_regkva
, SEQ_ID_CLOCKING_MODE
, *on
> 0 ? 0x01 : 0x21);
625 * Change the mode of the display.
626 * Return a UNIX error number or 0 for success.
629 et_mode(register struct grf_softc
*gp
, u_long cmd
, void *arg
, u_long a2
,
636 error
= et_load_mon(gp
,
637 (struct grfettext_mode
*) monitor_current
) ? 0 : EINVAL
;
644 et_load_mon(gp
, &etconsole_mode
);
652 return (et_getvmode(gp
, (struct grfvideo_mode
*) arg
));
655 error
= et_setvmode(gp
, *(unsigned *) arg
);
656 if (!error
&& (gp
->g_flags
& GF_GRFON
))
658 (struct grfettext_mode
*) monitor_current
);
662 *(int *) arg
= monitor_def_max
;
666 return (et_ioctl(gp
, a2
, arg
));
672 return (EPASSTHROUGH
);
677 et_ioctl(register struct grf_softc
*gp
, u_long cmd
, void *data
)
680 case GRFIOCGSPRITEPOS
:
681 return (et_getmousepos(gp
, (struct grf_position
*) data
));
683 case GRFIOCSSPRITEPOS
:
684 return (et_setmousepos(gp
, (struct grf_position
*) data
));
686 case GRFIOCSSPRITEINF
:
687 return (et_setspriteinfo(gp
, (struct grf_spriteinfo
*) data
));
689 case GRFIOCGSPRITEINF
:
690 return (et_getspriteinfo(gp
, (struct grf_spriteinfo
*) data
));
692 case GRFIOCGSPRITEMAX
:
693 return (et_getspritemax(gp
, (struct grf_position
*) data
));
696 return (et_getcmap(gp
, (struct grf_colormap
*) data
));
699 return (et_putcmap(gp
, (struct grf_colormap
*) data
));
705 return (et_toggle(gp
, 0));
708 return (et_setmonitor(gp
, (struct grfvideo_mode
*) data
));
711 return (et_blank(gp
, (int *)data
));
713 return (EPASSTHROUGH
);
718 et_getmousepos(struct grf_softc
*gp
, struct grf_position
*data
)
720 data
->x
= et_cursprite
.pos
.x
;
721 data
->y
= et_cursprite
.pos
.y
;
728 et_writesprpos(volatile char *ba
, short x
, short y
)
734 et_setmousepos(struct grf_softc
*gp
, struct grf_position
*data
)
736 volatile char *ba
= gp
->g_regkva
;
737 short rx
, ry
, prx
, pry
;
740 if (et_cursprite
.pos
.x
== data
->x
&& et_cursprite
.pos
.y
== data
->y
)
743 /* current and previous real coordinates */
744 rx
= data
->x
- et_cursprite
.hot
.x
;
745 ry
= data
->y
- et_cursprite
.hot
.y
;
746 prx
= et_cursprite
.pos
.x
- et_cursprite
.hot
.x
;
747 pry
= et_cursprite
.pos
.y
- et_cursprite
.hot
.y
;
749 /* if we are/were on an edge, create (un)shifted bitmap --
750 * ripped out optimization (not extremely worthwhile,
751 * and kind of buggy anyhow).
754 /* do movement, save position */
755 et_writesprpos(ba
, rx
< 0 ? 0 : rx
, ry
< 0 ? 0 : ry
);
756 et_cursprite
.pos
.x
= data
->x
;
757 et_cursprite
.pos
.y
= data
->y
;
764 et_getspriteinfo(struct grf_softc
*gp
, struct grf_spriteinfo
*data
)
772 et_setspriteinfo(struct grf_softc
*gp
, struct grf_spriteinfo
*data
)
780 et_getspritemax(struct grf_softc
*gp
, struct grf_position
*data
)
788 et_setmonitor(struct grf_softc
*gp
, struct grfvideo_mode
*gv
)
790 struct grfvideo_mode
*md
;
792 if (!et_mondefok(gv
))
796 /* handle interactive setting of console mode */
797 if (gv
->mode_num
== 255) {
798 memcpy(&etconsole_mode
.gv
, gv
, sizeof(struct grfvideo_mode
));
799 etconsole_mode
.gv
.hblank_start
/= 8;
800 etconsole_mode
.gv
.hsync_start
/= 8;
801 etconsole_mode
.gv
.hsync_stop
/= 8;
802 etconsole_mode
.gv
.htotal
/= 8;
803 etconsole_mode
.rows
= gv
->disp_height
/ etconsole_mode
.fy
;
804 etconsole_mode
.cols
= gv
->disp_width
/ etconsole_mode
.fx
;
805 if (!(gp
->g_flags
& GF_GRFON
))
806 et_load_mon(gp
, &etconsole_mode
);
807 ite_reinit(gp
->g_itedev
);
812 md
= monitor_def
+ (gv
->mode_num
- 1);
813 memcpy(md
, gv
, sizeof(struct grfvideo_mode
));
815 /* adjust pixel oriented values to internal rep. */
817 md
->hblank_start
/= 8;
818 md
->hsync_start
/= 8;
827 et_getcmap(struct grf_softc
*gfp
, struct grf_colormap
*cmap
)
829 volatile unsigned char *ba
;
830 u_char red
[256], green
[256], blue
[256], *rp
, *gp
, *bp
;
834 if (cmap
->count
== 0 || cmap
->index
>= 256)
837 if (cmap
->count
> 256 - cmap
->index
)
838 cmap
->count
= 256 - cmap
->index
;
841 /* first read colors out of the chip, then copyout to userspace */
844 rp
= red
+ cmap
->index
;
845 gp
= green
+ cmap
->index
;
846 bp
= blue
+ cmap
->index
;
850 vgaw(ba
, MERLIN_VDAC_INDEX
, cmap
->index
);
852 *rp
++ = vgar(ba
, MERLIN_VDAC_COLORS
);
853 *gp
++ = vgar(ba
, MERLIN_VDAC_COLORS
);
854 *bp
++ = vgar(ba
, MERLIN_VDAC_COLORS
);
858 vgaw(ba
, VDAC_ADDRESS_R
+((ettype
==DOMINO
)?0x0fff:0), cmap
->index
);
860 *rp
++ = vgar(ba
, VDAC_DATA
+((ettype
==DOMINO
)?0x0fff:0)) << etcmap_shift
;
861 *gp
++ = vgar(ba
, VDAC_DATA
+((ettype
==DOMINO
)?0x0fff:0)) << etcmap_shift
;
862 *bp
++ = vgar(ba
, VDAC_DATA
+((ettype
==DOMINO
)?0x0fff:0)) << etcmap_shift
;
867 error
= copyout(red
+ cmap
->index
, cmap
->red
, cmap
->count
);
869 error
= copyout(green
+ cmap
->index
, cmap
->green
, cmap
->count
);
871 error
= copyout(blue
+ cmap
->index
, cmap
->blue
, cmap
->count
);
878 et_putcmap(struct grf_softc
*gfp
, struct grf_colormap
*cmap
)
880 volatile unsigned char *ba
;
881 u_char red
[256], green
[256], blue
[256], *rp
, *gp
, *bp
;
885 if (cmap
->count
== 0 || cmap
->index
>= 256)
888 if (cmap
->count
> 256 - cmap
->index
)
889 cmap
->count
= 256 - cmap
->index
;
891 /* first copy the colors into kernelspace */
892 if ((error
= copyin(cmap
->red
, red
+ cmap
->index
, cmap
->count
)))
895 if ((error
= copyin(cmap
->green
, green
+ cmap
->index
, cmap
->count
)))
898 if ((error
= copyin(cmap
->blue
, blue
+ cmap
->index
, cmap
->count
)))
904 rp
= red
+ cmap
->index
;
905 gp
= green
+ cmap
->index
;
906 bp
= blue
+ cmap
->index
;
910 vgaw(ba
, MERLIN_VDAC_INDEX
, cmap
->index
);
912 vgaw(ba
, MERLIN_VDAC_COLORS
, *rp
++);
913 vgaw(ba
, MERLIN_VDAC_COLORS
, *gp
++);
914 vgaw(ba
, MERLIN_VDAC_COLORS
, *bp
++);
918 vgaw(ba
, VDAC_ADDRESS_W
, cmap
->index
);
920 vgaw(ba
, VDAC_DATA
+ ((ettype
== DOMINO
) ? 0x0fff : 0),
921 *rp
++ >> etcmap_shift
);
922 vgaw(ba
, VDAC_DATA
+ ((ettype
== DOMINO
) ? 0x0fff : 0),
923 *gp
++ >> etcmap_shift
);
924 vgaw(ba
, VDAC_DATA
+ ((ettype
== DOMINO
) ? 0x0fff : 0),
925 *bp
++ >> etcmap_shift
);
935 et_toggle(struct grf_softc
*gp
, unsigned short wopp
)
936 /* (variable wopp) don't need that one yet, ill */
938 volatile unsigned char *ba
;
951 #define ET_NUMCLOCKS 32
953 static u_char et_clocks
[ET_NUMCLOCKS
] = {
954 0, 1, 6, 2, 3, 7, 4, 5,
955 0, 1, 6, 2, 3, 7, 4, 5,
956 0, 1, 6, 2, 3, 7, 4, 5,
957 0, 1, 6, 2, 3, 7, 4, 5
960 static u_char et_clockdividers
[ET_NUMCLOCKS
] = {
961 3, 3, 3, 3, 3, 3, 3, 3,
962 2, 2, 2, 2, 2, 2, 2, 2,
963 1, 1, 1, 1, 1, 1, 1, 1,
964 0, 0, 0, 0, 0, 0, 0, 0
967 static u_int et_clockfreqs
[ET_NUMCLOCKS
] = {
968 6293750, 7080500, 7875000, 8125000,
969 9000000, 9375000, 10000000, 11225000,
970 12587500, 14161000, 15750000, 16250000,
971 18000000, 18750000, 20000000, 22450000,
972 25175000, 28322000, 31500000, 32500000,
973 36000000, 37500000, 40000000, 44900000,
974 50350000, 56644000, 63000000, 65000000,
975 72000000, 75000000, 80000000, 89800000
980 et_CompFQ(u_int fq
, u_char
*num
, u_char
*denom
)
984 for (i
=0; i
< ET_NUMCLOCKS
;) {
985 if (fq
<= et_clockfreqs
[i
++]) {
990 *num
= et_clocks
[--i
];
991 *denom
= et_clockdividers
[i
];
998 et_mondefok(struct grfvideo_mode
*gv
)
1000 unsigned long maxpix
;
1002 if (gv
->mode_num
< 1 || gv
->mode_num
> monitor_def_max
)
1003 if (gv
->mode_num
!= 255 || gv
->depth
!= 4)
1006 switch (gv
->depth
) {
1008 if (gv
->mode_num
!= 255)
1025 printf("grfet: Illegal depth in mode %d\n",
1026 (int) gv
->mode_num
);
1030 if (gv
->pixel_clock
> maxpix
) {
1031 printf("grfet: Pixelclock too high in mode %d\n",
1032 (int) gv
->mode_num
);
1036 if (gv
->disp_flags
& GRF_FLAGS_SYNC_ON_GREEN
) {
1037 printf("grfet: sync-on-green is not supported\n");
1046 et_load_mon(struct grf_softc
*gp
, struct grfettext_mode
*md
)
1048 struct grfvideo_mode
*gv
;
1050 volatile unsigned char *ba
;
1051 unsigned char num0
, denom0
;
1052 unsigned short HT
, HDE
, HBS
, HBE
, HSS
, HSE
, VDE
, VBS
, VBE
, VSS
,
1054 unsigned char hvsync_pulse
, seq
;
1060 TEXT
= (gv
->depth
== 4);
1062 if (!et_mondefok(gv
)) {
1063 printf("grfet: Monitor definition not ok\n");
1069 /* provide all needed information in grf device-independent locations */
1070 gp
->g_data
= (void *) gv
;
1071 gi
= &gp
->g_display
;
1072 gi
->gd_regaddr
= ztwopa(__UNVOLATILE(ba
));
1073 gi
->gd_regsize
= 64 * 1024;
1074 gi
->gd_fbaddr
= (void *) kvtop(__UNVOLATILE(gp
->g_fbkva
));
1075 gi
->gd_fbsize
= et_fbsize
;
1076 gi
->gd_colors
= 1 << gv
->depth
;
1077 gi
->gd_planes
= gv
->depth
;
1078 gi
->gd_fbwidth
= gv
->disp_width
;
1079 gi
->gd_fbheight
= gv
->disp_height
;
1083 gi
->gd_dwidth
= md
->fx
* md
->cols
;
1084 gi
->gd_dheight
= md
->fy
* md
->rows
;
1086 gi
->gd_dwidth
= gv
->disp_width
;
1087 gi
->gd_dheight
= gv
->disp_height
;
1092 /* get display mode parameters */
1094 HBS
= gv
->hblank_start
;
1095 HSS
= gv
->hsync_start
;
1096 HSE
= gv
->hsync_stop
;
1097 HBE
= gv
->htotal
- 1;
1099 VBS
= gv
->vblank_start
;
1100 VSS
= gv
->vsync_start
;
1101 VSE
= gv
->vsync_stop
;
1102 VBE
= gv
->vtotal
- 1;
1106 HDE
= ((gv
->disp_width
+ md
->fx
- 1) / md
->fx
) - 1;
1108 HDE
= (gv
->disp_width
+ 3) / 8 - 1; /* HBS; */
1109 VDE
= gv
->disp_height
- 1;
1111 /* adjustments (crest) */
1112 switch (gv
->depth
) {
1135 if (gv
->disp_flags
& GRF_FLAGS_LACE
) {
1140 if (gv
->disp_flags
& GRF_FLAGS_DBLSCAN
) {
1149 WSeq(ba
, SEQ_ID_MEMORY_MODE
, (TEXT
|| (gv
->depth
== 1)) ? 0x06 : 0x0e);
1151 WGfx(ba
, GCT_ID_READ_MAP_SELECT
, 0x00);
1152 WSeq(ba
, SEQ_ID_MAP_MASK
, (gv
->depth
== 1) ? 0x01 : 0xff);
1153 WSeq(ba
, SEQ_ID_CHAR_MAP_SELECT
, 0x00);
1156 et_CompFQ( gv
->pixel_clock
* hmul
, &num0
, &denom0
);
1158 /* Horizontal/Vertical Sync Pulse */
1159 hvsync_pulse
= 0xe3;
1160 if (gv
->disp_flags
& GRF_FLAGS_PHSYNC
)
1161 hvsync_pulse
&= ~0x40;
1163 hvsync_pulse
|= 0x40;
1164 if (gv
->disp_flags
& GRF_FLAGS_PVSYNC
)
1165 hvsync_pulse
&= ~0x80;
1167 hvsync_pulse
|= 0x80;
1169 vgaw(ba
, GREG_MISC_OUTPUT_W
, hvsync_pulse
| ((num0
& 3) << 2));
1170 WCrt(ba
, CRT_ID_6845_COMPAT
, (num0
& 4) ? 0x0a : 0x08);
1171 seq
= RSeq(ba
, SEQ_ID_CLOCKING_MODE
);
1174 WSeq(ba
, SEQ_ID_AUXILIARY_MODE
, 0xb4);
1175 WSeq(ba
, SEQ_ID_CLOCKING_MODE
, seq
& 0xf7);
1178 WSeq(ba
, SEQ_ID_AUXILIARY_MODE
, 0xf4);
1179 WSeq(ba
, SEQ_ID_CLOCKING_MODE
, seq
& 0xf7);
1182 WSeq(ba
, SEQ_ID_AUXILIARY_MODE
, 0xf5);
1183 WSeq(ba
, SEQ_ID_CLOCKING_MODE
, seq
& 0xf7);
1186 WSeq(ba
, SEQ_ID_AUXILIARY_MODE
, 0xf5);
1187 WSeq(ba
, SEQ_ID_CLOCKING_MODE
, seq
| 0x08);
1191 /* load display parameters into board */
1192 WCrt(ba
, CRT_ID_HOR_TOTAL
, HT
);
1193 WCrt(ba
, CRT_ID_HOR_DISP_ENA_END
, ((HDE
>= HBS
) ? HBS
- 1 : HDE
));
1194 WCrt(ba
, CRT_ID_START_HOR_BLANK
, HBS
);
1195 WCrt(ba
, CRT_ID_END_HOR_BLANK
, (HBE
& 0x1f) | 0x80);
1196 WCrt(ba
, CRT_ID_START_HOR_RETR
, HSS
);
1197 WCrt(ba
, CRT_ID_END_HOR_RETR
,
1199 ((HBE
& 0x20) ? 0x80 : 0x00));
1200 WCrt(ba
, CRT_ID_VER_TOTAL
, VT
);
1201 WCrt(ba
, CRT_ID_OVERFLOW
,
1203 ((VT
& 0x100) ? 0x01 : 0x00) |
1204 ((VDE
& 0x100) ? 0x02 : 0x00) |
1205 ((VSS
& 0x100) ? 0x04 : 0x00) |
1206 ((VBS
& 0x100) ? 0x08 : 0x00) |
1207 ((VT
& 0x200) ? 0x20 : 0x00) |
1208 ((VDE
& 0x200) ? 0x40 : 0x00) |
1209 ((VSS
& 0x200) ? 0x80 : 0x00));
1211 WCrt(ba
, CRT_ID_MAX_ROW_ADDRESS
,
1212 0x40 | /* splitscreen not visible */
1213 ((gv
->disp_flags
& GRF_FLAGS_DBLSCAN
) ? 0x80 : 0x00) |
1214 ((VBS
& 0x200) ? 0x20 : 0x00) |
1215 (TEXT
? ((md
->fy
- 1) & 0x1f) : 0x00));
1217 WCrt(ba
, CRT_ID_MODE_CONTROL
,
1218 ((TEXT
|| (gv
->depth
== 1)) ? 0xc3 : 0xab));
1223 WCrt(ba
, CRT_ID_CURSOR_START
, (md
->fy
& 0x1f) - 2);
1224 WCrt(ba
, CRT_ID_CURSOR_END
, (md
->fy
& 0x1f) - 1);
1226 WCrt(ba
, CRT_ID_CURSOR_START
, 0x00);
1227 WCrt(ba
, CRT_ID_CURSOR_END
, md
->fy
& 0x1f);
1229 WCrt(ba
, CRT_ID_CURSOR_LOC_HIGH
, 0x00);
1230 WCrt(ba
, CRT_ID_CURSOR_LOC_LOW
, 0x00);
1233 WCrt(ba
, CRT_ID_UNDERLINE_LOC
, ((md
->fy
- 1) & 0x1f)
1234 | ((TEXT
|| (gv
->depth
== 1)) ? 0x00 : 0x60));
1236 WCrt(ba
, CRT_ID_START_ADDR_HIGH
, 0x00);
1237 WCrt(ba
, CRT_ID_START_ADDR_LOW
, 0x00);
1239 WCrt(ba
, CRT_ID_START_VER_RETR
, VSS
);
1240 WCrt(ba
, CRT_ID_END_VER_RETR
, (VSE
& 0x0f) | 0x30);
1241 WCrt(ba
, CRT_ID_VER_DISP_ENA_END
, VDE
);
1242 WCrt(ba
, CRT_ID_START_VER_BLANK
, VBS
);
1243 WCrt(ba
, CRT_ID_END_VER_BLANK
, VBE
);
1245 WCrt(ba
, CRT_ID_LINE_COMPARE
, 0xff);
1247 WCrt(ba
, CRT_ID_OVERFLOW_HIGH
,
1248 ((VBS
& 0x400) ? 0x01 : 0x00) |
1249 ((VT
& 0x400) ? 0x02 : 0x00) |
1250 ((VDE
& 0x400) ? 0x04 : 0x00) |
1251 ((VSS
& 0x400) ? 0x08 : 0x00) |
1253 ((gv
->disp_flags
& GRF_FLAGS_LACE
) ? 0x80 : 0x00));
1255 WCrt(ba
, CRT_ID_HOR_OVERFLOW
,
1256 ((HT
& 0x100) ? 0x01 : 0x00) |
1257 ((HBS
& 0x100) ? 0x04 : 0x00) |
1258 ((HSS
& 0x100) ? 0x10 : 0x00)
1261 /* depth dependent stuff */
1263 WGfx(ba
, GCT_ID_GRAPHICS_MODE
,
1264 ((TEXT
|| (gv
->depth
== 1)) ? 0x00 : 0x40));
1265 WGfx(ba
, GCT_ID_MISC
, (TEXT
? 0x04 : 0x01));
1267 vgaw(ba
, VDAC_MASK
, 0xff);
1268 vgar(ba
, VDAC_MASK
);
1269 vgar(ba
, VDAC_MASK
);
1270 vgar(ba
, VDAC_MASK
);
1271 vgar(ba
, VDAC_MASK
);
1272 switch (gv
->depth
) {
1279 vgaw(ba
, VDAC_MASK
, 0);
1282 vgaw(ba
, VDAC_MASK
, 0x02);
1285 setMerlinDACmode(ba
, 0);
1288 HDE
= gv
->disp_width
/ 16;
1295 vgaw(ba
, VDAC_MASK
, 0);
1298 vgaw(ba
, VDAC_MASK
, 0x02);
1301 setMerlinDACmode(ba
, 0);
1304 HDE
= gv
->disp_width
/ 8;
1312 vgaw(ba
, VDAC_MASK
, 0xa0);
1315 setMerlinDACmode(ba
, 0xa0);
1318 HDE
= gv
->disp_width
/ 4;
1323 vgaw(ba
, VDAC_MASK
, 0); /* illegal mode! */
1326 vgaw(ba
, VDAC_MASK
, 0xe0);
1330 vgaw(ba
, VDAC_MASK
, 0xc0);
1333 setMerlinDACmode(ba
, 0xe0);
1336 HDE
= gv
->disp_width
/ 4;
1341 vgaw(ba
, VDAC_MASK
, 0); /* illegal mode! */
1344 vgaw(ba
, VDAC_MASK
, 0xe1);
1348 vgaw(ba
, VDAC_MASK
, 0xe0);
1351 setMerlinDACmode(ba
, 0xf0);
1354 HDE
= (gv
->disp_width
/ 8) * 3;
1361 vgaw(ba
, VDAC_MASK
, 0); /* illegal mode! */
1364 vgaw(ba
, VDAC_MASK
, 0x61);
1367 setMerlinDACmode(ba
, 0xb0);
1370 HDE
= gv
->disp_width
/ 2;
1373 WAttr(ba
, ACT_ID_ATTR_MODE_CNTL
, (TEXT
? 0x0a : 0x01));
1374 WAttr(ba
, 0x20 | ACT_ID_COLOR_PLANE_ENA
,
1375 (gv
->depth
== 1) ? 0x01 : 0x0f);
1377 WCrt(ba
, CRT_ID_OFFSET
, HDE
);
1378 vgaw(ba
, CRT_ADDRESS
, CRT_ID_HOR_OVERFLOW
);
1379 vgaw(ba
, CRT_ADDRESS_W
,
1380 (vgar(ba
, CRT_ADDRESS_R
) & 0x7f)
1381 | ((HDE
& 0x100) ? 0x80: 0x00));
1383 /* text initialization */
1385 et_inittextmode(gp
);
1388 WSeq(ba
, SEQ_ID_CLOCKING_MODE
, 0x01);
1398 et_inittextmode(struct grf_softc
*gp
)
1400 struct grfettext_mode
*tm
= (struct grfettext_mode
*) gp
->g_data
;
1401 volatile unsigned char *ba
= gp
->g_regkva
;
1402 volatile unsigned char *fb
= gp
->g_fbkva
;
1403 volatile unsigned char *c
;
1404 unsigned char *f
, y
;
1409 * load text font into beginning of display memory. Each character
1410 * cell is 32 bytes long (enough for 4 planes)
1413 SetTextPlane(ba
, 0x02);
1414 et_memset(fb
, 0, 256 * 32);
1415 c
= fb
+ (32 * tm
->fdstart
);
1417 for (z
= tm
->fdstart
; z
<= tm
->fdend
; z
++, c
+= (32 - tm
->fy
))
1418 for (y
= 0; y
< tm
->fy
; y
++)
1421 /* clear out text/attr planes (three screens worth) */
1423 SetTextPlane(ba
, 0x01);
1424 et_memset(fb
, 0x07, tm
->cols
* tm
->rows
* 3);
1425 SetTextPlane(ba
, 0x00);
1426 et_memset(fb
, 0x20, tm
->cols
* tm
->rows
* 3);
1428 /* print out a little init msg */
1430 c
= fb
+ (tm
->cols
- 16);
1431 strcpy(__UNVOLATILE(c
), "TSENG");
1434 /* set colors (B&W) */
1438 vgaw(ba
, MERLIN_VDAC_INDEX
, 0);
1439 for (z
= 0; z
< 256; z
++) {
1440 y
= (z
& 1) ? ((z
> 7) ? 2 : 1) : 0;
1442 vgaw(ba
, MERLIN_VDAC_COLORS
, etconscolors
[y
][0]);
1443 vgaw(ba
, MERLIN_VDAC_COLORS
, etconscolors
[y
][1]);
1444 vgaw(ba
, MERLIN_VDAC_COLORS
, etconscolors
[y
][2]);
1448 vgaw(ba
, VDAC_ADDRESS_W
, 0);
1449 for (z
= 0; z
< 256; z
++) {
1450 y
= (z
& 1) ? ((z
> 7) ? 2 : 1) : 0;
1452 vgaw(ba
, VDAC_DATA
+ ((ettype
== DOMINO
) ? 0x0fff : 0),
1453 etconscolors
[y
][0] >> etcmap_shift
);
1454 vgaw(ba
, VDAC_DATA
+ ((ettype
== DOMINO
) ? 0x0fff : 0),
1455 etconscolors
[y
][1] >> etcmap_shift
);
1456 vgaw(ba
, VDAC_DATA
+ ((ettype
== DOMINO
) ? 0x0fff : 0),
1457 etconscolors
[y
][2] >> etcmap_shift
);
1465 et_memset(volatile unsigned char *d
, unsigned char c
, int l
)
1473 et_getControllerType(struct grf_softc
*gp
)
1475 volatile unsigned char *ba
= gp
->g_regkva
; /* register base */
1476 volatile unsigned char *mem
= gp
->g_fbkva
; /* memory base */
1477 volatile unsigned char *mmu
= mem
+ MMU_APERTURE0
; /* MMU aperture 0 base */
1481 /* make ACL visible */
1482 if (ettype
== MERLIN
) {
1483 WCrt(ba
, CRT_ID_VIDEO_CONFIG1
, 0xbb);
1485 WCrt(ba
, CRT_ID_VIDEO_CONFIG1
, 0xfb);
1488 WIma(ba
, IMA_PORTCONTROL
, 0x01);
1490 *((volatile unsigned long *)mmu
) = 0;
1491 *(mem
+ 0x13) = 0x38;
1496 WIma(ba
, IMA_PORTCONTROL
, 0x00);
1498 if (ettype
== MERLIN
) {
1499 WCrt(ba
, CRT_ID_VIDEO_CONFIG1
, 0x93);
1501 WCrt(ba
, CRT_ID_VIDEO_CONFIG1
, 0xd3);
1503 return ((*mem
== 0xff) ? ETW32
: ET4000
);
1508 et_getDACType(struct grf_softc
*gp
)
1510 volatile unsigned char *ba
= gp
->g_regkva
;
1516 /* check for Sierra SC 15025 */
1518 /* We MUST do 4 HW reads to switch into command mode */
1519 if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
));
1520 vgaw(ba
, VDAC_COMMAND
, 0x10); /* set ERPF */
1522 vgaw(ba
, VDAC_XINDEX
, 9);
1523 check
.cc
[0] = vgar(ba
, VDAC_XDATA
);
1524 vgaw(ba
, VDAC_XINDEX
, 10);
1525 check
.cc
[1] = vgar(ba
, VDAC_XDATA
);
1526 vgaw(ba
, VDAC_XINDEX
, 11);
1527 check
.cc
[2] = vgar(ba
, VDAC_XDATA
);
1528 vgaw(ba
, VDAC_XINDEX
, 12);
1529 check
.cc
[3] = vgar(ba
, VDAC_XDATA
);
1531 if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
));
1532 vgaw(ba
, VDAC_COMMAND
, 0x00); /* clear ERPF */
1534 if (check
.tt
== 0x533ab141) {
1535 if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
));
1536 vgaw(ba
, VDAC_COMMAND
, 0x10); /* set ERPF */
1538 /* switch to 8 bits per color */
1539 vgaw(ba
, VDAC_XINDEX
, 8);
1540 vgaw(ba
, VDAC_XDATA
, 1);
1541 /* do not shift color values */
1544 if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
));
1545 vgaw(ba
, VDAC_COMMAND
, 0x00); /* clear ERPF */
1547 vgaw(ba
, VDAC_MASK
, 0xff);
1548 return (SIERRA15025
);
1551 /* check for MUSIC DAC */
1553 if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
));
1554 vgaw(ba
, VDAC_COMMAND
, 0x02); /* set some strange MUSIC mode (???) */
1556 vgaw(ba
, VDAC_XINDEX
, 0x01);
1557 if (vgar(ba
, VDAC_XDATA
) == 0x01) {
1558 /* shift color values by 2 */
1561 vgaw(ba
, VDAC_MASK
, 0xff);
1565 /* check for AT&T ATT20c491 DAC (crest) */
1566 if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
));
1567 vgaw(ba
, HDR
, 0xff);
1568 vgaw(ba
, VDAC_MASK
, 0x01);
1569 if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
));
1570 if (vgar(ba
, HDR
) == 0xff) {
1571 /* do not shift color values */
1574 vgaw(ba
, VDAC_MASK
, 0xff);
1578 /* restore PowerUp settings (crest) */
1579 if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
)); if (vgar(ba
, HDR
));
1580 vgaw(ba
, HDR
, 0x00);
1583 * nothing else found, so let us pretend it is a stupid
1587 /* shift color values by 2 */
1590 vgaw(ba
, VDAC_MASK
, 0xff);
1591 return (SIERRA11483
);