grf_et.c revision 1.29 1 1.29 phx /* $NetBSD: grf_et.c,v 1.29 2011/12/15 14:25:13 phx Exp $ */
2 1.1 veego
3 1.1 veego /*
4 1.9 veego * Copyright (c) 1997 Klaus Burkert
5 1.1 veego * Copyright (c) 1996 Tobias Abt
6 1.1 veego * Copyright (c) 1995 Ezra Story
7 1.1 veego * Copyright (c) 1995 Kari Mettinen
8 1.1 veego * Copyright (c) 1994 Markus Wild
9 1.1 veego * Copyright (c) 1994 Lutz Vieweg
10 1.1 veego * All rights reserved.
11 1.1 veego *
12 1.1 veego * Redistribution and use in source and binary forms, with or without
13 1.1 veego * modification, are permitted provided that the following conditions
14 1.1 veego * are met:
15 1.1 veego * 1. Redistributions of source code must retain the above copyright
16 1.1 veego * notice, this list of conditions and the following disclaimer.
17 1.1 veego * 2. Redistributions in binary form must reproduce the above copyright
18 1.1 veego * notice, this list of conditions and the following disclaimer in the
19 1.1 veego * documentation and/or other materials provided with the distribution.
20 1.1 veego * 3. All advertising materials mentioning features or use of this software
21 1.1 veego * must display the following acknowledgement:
22 1.1 veego * This product includes software developed by Lutz Vieweg.
23 1.1 veego * 4. The name of the author may not be used to endorse or promote products
24 1.1 veego * derived from this software without specific prior written permission
25 1.1 veego *
26 1.1 veego * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 1.1 veego * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 1.1 veego * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 1.1 veego * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 1.1 veego * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 1.1 veego * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 1.1 veego * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 1.1 veego * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 1.1 veego * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 1.1 veego * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 1.1 veego */
37 1.12 is #include "opt_amigacons.h"
38 1.14 aymeric
39 1.14 aymeric #include <sys/cdefs.h>
40 1.29 phx __KERNEL_RCSID(0, "$NetBSD: grf_et.c,v 1.29 2011/12/15 14:25:13 phx Exp $");
41 1.14 aymeric
42 1.1 veego #include "grfet.h"
43 1.29 phx #include "ite.h"
44 1.1 veego #if NGRFET > 0
45 1.1 veego
46 1.1 veego /*
47 1.1 veego * Graphics routines for Tseng ET4000 (&W32) boards,
48 1.1 veego *
49 1.1 veego * This code offers low-level routines to access Tseng ET4000
50 1.1 veego * graphics-boards from within NetBSD for the Amiga.
51 1.1 veego * No warranties for any kind of function at all - this
52 1.1 veego * code may crash your hardware and scratch your harddisk. Use at your
53 1.1 veego * own risk. Freely distributable.
54 1.1 veego *
55 1.1 veego * Modified for Tseng ET4000 from
56 1.1 veego * Kari Mettinen's Cirrus driver by Tobias Abt
57 1.1 veego *
58 1.9 veego * Fixed Merlin in Z-III, fixed LACE and DBLSCAN, added Domino16M proto
59 1.13 aymeric * and AT&T ATT20c491 DAC, added memory-size detection by Klaus Burkert.
60 1.13 aymeric *
61 1.1 veego *
62 1.1 veego * TODO:
63 1.1 veego *
64 1.1 veego */
65 1.1 veego
66 1.1 veego #include <sys/param.h>
67 1.1 veego #include <sys/systm.h>
68 1.1 veego #include <sys/errno.h>
69 1.1 veego #include <sys/ioctl.h>
70 1.1 veego #include <sys/device.h>
71 1.1 veego #include <sys/malloc.h>
72 1.1 veego
73 1.1 veego #include <machine/cpu.h>
74 1.1 veego #include <dev/cons.h>
75 1.1 veego #ifdef TSENGCONSOLE
76 1.1 veego #include <amiga/dev/itevar.h>
77 1.1 veego #endif
78 1.1 veego #include <amiga/amiga/device.h>
79 1.1 veego #include <amiga/dev/grfioctl.h>
80 1.1 veego #include <amiga/dev/grfvar.h>
81 1.1 veego #include <amiga/dev/grf_etreg.h>
82 1.1 veego #include <amiga/dev/zbusvar.h>
83 1.1 veego
84 1.13 aymeric int et_mondefok(struct grfvideo_mode *gv);
85 1.13 aymeric void et_boardinit(struct grf_softc *gp);
86 1.13 aymeric static void et_CompFQ(u_int fq, u_char *num, u_char *denom);
87 1.13 aymeric int et_getvmode(struct grf_softc *gp, struct grfvideo_mode *vm);
88 1.13 aymeric int et_setvmode(struct grf_softc *gp, unsigned int mode);
89 1.13 aymeric int et_toggle(struct grf_softc *gp, unsigned short);
90 1.13 aymeric int et_getcmap(struct grf_softc *gfp, struct grf_colormap *cmap);
91 1.13 aymeric int et_putcmap(struct grf_softc *gfp, struct grf_colormap *cmap);
92 1.1 veego #ifndef TSENGCONSOLE
93 1.13 aymeric void et_off(struct grf_softc *gp);
94 1.1 veego #endif
95 1.13 aymeric void et_inittextmode(struct grf_softc *gp);
96 1.13 aymeric int et_ioctl(register struct grf_softc *gp, u_long cmd, void *data);
97 1.13 aymeric int et_getmousepos(struct grf_softc *gp, struct grf_position *data);
98 1.13 aymeric void et_writesprpos(volatile char *ba, short x, short y);
99 1.13 aymeric int et_setmousepos(struct grf_softc *gp, struct grf_position *data);
100 1.13 aymeric static int et_setspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *data);
101 1.13 aymeric int et_getspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *data);
102 1.13 aymeric static int et_getspritemax(struct grf_softc *gp, struct grf_position *data);
103 1.13 aymeric int et_setmonitor(struct grf_softc *gp, struct grfvideo_mode *gv);
104 1.13 aymeric int et_blank(struct grf_softc *gp, int *on);
105 1.13 aymeric static int et_getControllerType(struct grf_softc *gp);
106 1.13 aymeric static int et_getDACType(struct grf_softc *gp);
107 1.13 aymeric
108 1.13 aymeric int grfetmatch(struct device *, struct cfdata *, void *);
109 1.13 aymeric void grfetattach(struct device *, struct device *, void *);
110 1.13 aymeric int grfetprint(void *, const char *);
111 1.24 he void et_memset(volatile unsigned char *d, unsigned char c, int l);
112 1.1 veego
113 1.3 veego /*
114 1.3 veego * Graphics display definitions.
115 1.1 veego * These are filled by 'grfconfig' using GRFIOCSETMON.
116 1.1 veego */
117 1.10 veego #define monitor_def_max 24
118 1.10 veego static struct grfvideo_mode monitor_def[24] = {
119 1.10 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
120 1.10 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
121 1.1 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}
122 1.1 veego };
123 1.1 veego static struct grfvideo_mode *monitor_current = &monitor_def[0];
124 1.1 veego
125 1.1 veego /* Console display definition.
126 1.1 veego * Default hardcoded text mode. This grf_et is set up to
127 1.1 veego * use one text mode only, and this is it. You may use
128 1.1 veego * grfconfig to change the mode after boot.
129 1.1 veego */
130 1.1 veego /* Console font */
131 1.1 veego #ifdef KFONT_8X11
132 1.1 veego #define TSENGFONT kernel_font_8x11
133 1.1 veego #define TSENGFONTY 11
134 1.1 veego #else
135 1.1 veego #define TSENGFONT kernel_font_8x8
136 1.1 veego #define TSENGFONTY 8
137 1.1 veego #endif
138 1.1 veego extern unsigned char TSENGFONT[];
139 1.1 veego
140 1.1 veego struct grfettext_mode etconsole_mode = {
141 1.10 veego {255, "", 25000000, 640, 480, 4, 640/8, 680/8, 768/8, 800/8,
142 1.10 veego 481, 491, 493, 525, 0},
143 1.1 veego 8, TSENGFONTY, 640 / 8, 480 / TSENGFONTY, TSENGFONT, 32, 255
144 1.1 veego };
145 1.1 veego
146 1.1 veego /* Console colors */
147 1.1 veego unsigned char etconscolors[3][3] = { /* background, foreground, hilite */
148 1.1 veego {0, 0x40, 0x50}, {152, 152, 152}, {255, 255, 255}
149 1.1 veego };
150 1.1 veego
151 1.1 veego int ettype = 0; /* oMniBus, Domino or Merlin */
152 1.1 veego int etctype = 0; /* ET4000 or ETW32 */
153 1.1 veego int etdtype = 0; /* Type of DAC (see grf_etregs.h) */
154 1.1 veego
155 1.1 veego char etcmap_shift = 0; /* 6 or 8 bit cmap entries */
156 1.1 veego unsigned char pass_toggle; /* passthru status tracker */
157 1.1 veego
158 1.1 veego unsigned char Merlin_switch = 0;
159 1.1 veego
160 1.3 veego /*
161 1.3 veego * Because all Tseng-boards have 2 configdev entries, one for
162 1.1 veego * framebuffer mem and the other for regs, we have to hold onto
163 1.1 veego * the pointers globally until we match on both. This and 'ettype'
164 1.1 veego * are the primary obsticles to multiple board support, but if you
165 1.1 veego * have multiple boards you have bigger problems than grf_et.
166 1.1 veego */
167 1.1 veego static void *et_fbaddr = 0; /* framebuffer */
168 1.1 veego static void *et_regaddr = 0; /* registers */
169 1.1 veego static int et_fbsize; /* framebuffer size */
170 1.1 veego
171 1.1 veego /* current sprite info, if you add support for multiple boards
172 1.1 veego * make this an array or something
173 1.1 veego */
174 1.1 veego struct grf_spriteinfo et_cursprite;
175 1.1 veego
176 1.1 veego /* sprite bitmaps in kernel stack, you'll need to arrayize these too if
177 1.1 veego * you add multiple board support
178 1.1 veego */
179 1.1 veego static unsigned char et_imageptr[8 * 64], et_maskptr[8 * 64];
180 1.1 veego static unsigned char et_sprred[2], et_sprgreen[2], et_sprblue[2];
181 1.1 veego
182 1.1 veego /* standard driver stuff */
183 1.18 thorpej CFATTACH_DECL(grfet, sizeof(struct grf_softc),
184 1.18 thorpej grfetmatch, grfetattach, NULL, NULL);
185 1.3 veego
186 1.1 veego static struct cfdata *cfdata;
187 1.1 veego
188 1.1 veego int
189 1.13 aymeric grfetmatch(struct device *pdp, struct cfdata *cfp, void *auxp)
190 1.1 veego {
191 1.1 veego struct zbus_args *zap;
192 1.9 veego static int regprod, regprod2 = 0, fbprod;
193 1.1 veego
194 1.1 veego zap = auxp;
195 1.1 veego
196 1.1 veego #ifndef TSENGCONSOLE
197 1.1 veego if (amiga_realconfig == 0)
198 1.1 veego return (0);
199 1.1 veego #endif
200 1.1 veego
201 1.1 veego /* Grab the first board we encounter as the preferred one. This will
202 1.1 veego * allow one board to work in a multiple Tseng board system, but not
203 1.1 veego * multiple boards at the same time. */
204 1.1 veego if (ettype == 0) {
205 1.1 veego switch (zap->manid) {
206 1.1 veego case OMNIBUS:
207 1.1 veego if (zap->prodid != 0)
208 1.1 veego return (0);
209 1.1 veego regprod = 0;
210 1.1 veego fbprod = 0;
211 1.1 veego break;
212 1.1 veego case DOMINO:
213 1.9 veego /* 2167/3 is Domino16M proto (crest) */
214 1.9 veego if (zap->prodid != 3 && zap->prodid != 2 && zap->prodid != 1)
215 1.1 veego return (0);
216 1.1 veego regprod = 2;
217 1.9 veego regprod2 = 3;
218 1.1 veego fbprod = 1;
219 1.1 veego break;
220 1.1 veego case MERLIN:
221 1.1 veego if (zap->prodid != 3 && zap->prodid != 4)
222 1.1 veego return (0);
223 1.1 veego regprod = 4;
224 1.1 veego fbprod = 3;
225 1.1 veego break;
226 1.1 veego default:
227 1.1 veego return (0);
228 1.1 veego }
229 1.1 veego ettype = zap->manid;
230 1.1 veego } else {
231 1.1 veego if (ettype != zap->manid) {
232 1.1 veego return (0);
233 1.1 veego }
234 1.1 veego }
235 1.1 veego
236 1.1 veego /* Configure either registers or framebuffer in any order */
237 1.1 veego /* as said before, oMniBus does not support ProdID */
238 1.1 veego if (ettype == OMNIBUS) {
239 1.1 veego if (zap->size == 64 * 1024) {
240 1.1 veego /* register area */
241 1.1 veego et_regaddr = zap->va;
242 1.1 veego } else {
243 1.1 veego /* memory area */
244 1.1 veego et_fbaddr = zap->va;
245 1.1 veego et_fbsize = zap->size;
246 1.1 veego }
247 1.1 veego } else {
248 1.9 veego if (zap->prodid == regprod || zap->prodid == regprod2) {
249 1.1 veego et_regaddr = zap->va;
250 1.1 veego } else {
251 1.1 veego if (zap->prodid == fbprod) {
252 1.1 veego et_fbaddr = zap->va;
253 1.1 veego et_fbsize = zap->size;
254 1.1 veego } else {
255 1.1 veego return (0);
256 1.1 veego }
257 1.1 veego }
258 1.1 veego }
259 1.1 veego
260 1.1 veego #ifdef TSENGCONSOLE
261 1.1 veego if (amiga_realconfig == 0) {
262 1.1 veego cfdata = cfp;
263 1.1 veego }
264 1.1 veego #endif
265 1.1 veego
266 1.1 veego return (1);
267 1.1 veego }
268 1.1 veego
269 1.1 veego
270 1.1 veego void
271 1.13 aymeric grfetattach(struct device *pdp, struct device *dp, void *auxp)
272 1.1 veego {
273 1.1 veego static struct grf_softc congrf;
274 1.1 veego struct zbus_args *zap;
275 1.1 veego struct grf_softc *gp;
276 1.1 veego static char attachflag = 0;
277 1.1 veego
278 1.1 veego zap = auxp;
279 1.1 veego
280 1.7 christos printf("\n");
281 1.1 veego
282 1.1 veego /* make sure both halves have matched */
283 1.1 veego if (!et_regaddr || !et_fbaddr)
284 1.1 veego return;
285 1.1 veego
286 1.1 veego /* do all that messy console/grf stuff */
287 1.1 veego if (dp == NULL)
288 1.1 veego gp = &congrf;
289 1.1 veego else
290 1.1 veego gp = (struct grf_softc *) dp;
291 1.1 veego
292 1.1 veego if (dp != NULL && congrf.g_regkva != 0) {
293 1.1 veego /*
294 1.1 veego * inited earlier, just copy (not device struct)
295 1.1 veego */
296 1.28 cegger memcpy(&gp->g_display, &congrf.g_display,
297 1.1 veego (char *) &gp[1] - (char *) &gp->g_display);
298 1.1 veego } else {
299 1.23 christos gp->g_regkva = (volatile void *) et_regaddr;
300 1.23 christos gp->g_fbkva = (volatile void *) et_fbaddr;
301 1.1 veego
302 1.1 veego gp->g_unit = GRF_ET4000_UNIT;
303 1.1 veego gp->g_mode = et_mode;
304 1.29 phx #if NITE > 0
305 1.1 veego gp->g_conpri = grfet_cnprobe();
306 1.29 phx #endif
307 1.1 veego gp->g_flags = GF_ALIVE;
308 1.1 veego
309 1.1 veego /* wakeup the board */
310 1.1 veego et_boardinit(gp);
311 1.1 veego
312 1.1 veego #ifdef TSENGCONSOLE
313 1.29 phx #if NITE > 0
314 1.1 veego grfet_iteinit(gp);
315 1.29 phx #endif
316 1.1 veego (void) et_load_mon(gp, &etconsole_mode);
317 1.1 veego #endif
318 1.1 veego }
319 1.1 veego
320 1.1 veego /*
321 1.1 veego * attach grf (once)
322 1.1 veego */
323 1.1 veego if (amiga_config_found(cfdata, &gp->g_device, gp, grfetprint)) {
324 1.1 veego attachflag = 1;
325 1.7 christos printf("grfet: %dMB ", et_fbsize / 0x100000);
326 1.1 veego switch (ettype) {
327 1.1 veego case OMNIBUS:
328 1.7 christos printf("oMniBus");
329 1.1 veego break;
330 1.1 veego case DOMINO:
331 1.7 christos printf("Domino");
332 1.1 veego break;
333 1.1 veego case MERLIN:
334 1.7 christos printf("Merlin");
335 1.1 veego break;
336 1.1 veego }
337 1.7 christos printf(" with ");
338 1.1 veego switch (etctype) {
339 1.1 veego case ET4000:
340 1.7 christos printf("Tseng ET4000");
341 1.1 veego break;
342 1.1 veego case ETW32:
343 1.7 christos printf("Tseng ETW32");
344 1.1 veego break;
345 1.1 veego }
346 1.7 christos printf(" and ");
347 1.1 veego switch (etdtype) {
348 1.1 veego case SIERRA11483:
349 1.7 christos printf("Sierra SC11483 DAC");
350 1.1 veego break;
351 1.1 veego case SIERRA15025:
352 1.7 christos printf("Sierra SC15025 DAC");
353 1.1 veego break;
354 1.1 veego case MUSICDAC:
355 1.7 christos printf("MUSIC DAC");
356 1.1 veego break;
357 1.1 veego case MERLINDAC:
358 1.9 veego printf("BrookTree Bt482 DAC");
359 1.9 veego break;
360 1.9 veego case ATT20C491:
361 1.9 veego printf("AT&T ATT20c491 DAC");
362 1.1 veego break;
363 1.1 veego }
364 1.7 christos printf(" being used\n");
365 1.1 veego } else {
366 1.1 veego if (!attachflag)
367 1.7 christos printf("grfet unattached!!\n");
368 1.1 veego }
369 1.1 veego }
370 1.1 veego
371 1.1 veego
372 1.1 veego int
373 1.13 aymeric grfetprint(void *auxp, const char *pnp)
374 1.1 veego {
375 1.1 veego if (pnp)
376 1.19 thorpej aprint_normal("ite at %s: ", pnp);
377 1.1 veego return (UNCONF);
378 1.1 veego }
379 1.1 veego
380 1.1 veego
381 1.1 veego void
382 1.13 aymeric et_boardinit(struct grf_softc *gp)
383 1.1 veego {
384 1.24 he volatile unsigned char *ba = gp->g_regkva;
385 1.1 veego int x;
386 1.1 veego
387 1.1 veego /* wakeup board and flip passthru OFF */
388 1.1 veego
389 1.1 veego RegWakeup(ba);
390 1.1 veego RegOnpass(ba);
391 1.1 veego
392 1.1 veego if (ettype == MERLIN) {
393 1.3 veego /* Merlin needs some special initialisations */
394 1.3 veego vgaw(ba, MERLIN_SWITCH_REG, 0);
395 1.3 veego delay(20000);
396 1.3 veego vgaw(ba, MERLIN_SWITCH_REG, 8);
397 1.3 veego delay(20000);
398 1.3 veego vgaw(ba, MERLIN_SWITCH_REG, 0);
399 1.3 veego delay(20000);
400 1.3 veego vgaw(ba, MERLIN_VDAC_DATA, 1);
401 1.3 veego
402 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x00);
403 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0xff);
404 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x01);
405 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0x0f);
406 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x02);
407 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0x42);
408 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x03);
409 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0x00);
410 1.1 veego
411 1.3 veego vgaw(ba, MERLIN_VDAC_DATA, 0);
412 1.1 veego }
413 1.1 veego
414 1.13 aymeric
415 1.1 veego /* setup initial unchanging parameters */
416 1.1 veego
417 1.3 veego vgaw(ba, GREG_HERCULESCOMPAT + ((ettype == DOMINO) ? 0x0fff : 0), 0x03);
418 1.1 veego vgaw(ba, GREG_DISPMODECONTROL, 0xa0);
419 1.1 veego vgaw(ba, GREG_MISC_OUTPUT_W, 0x63);
420 1.1 veego
421 1.3 veego if (ettype == DOMINO)
422 1.3 veego {
423 1.3 veego vgaw(ba, CRT_ADDRESS, CRT_ID_VIDEO_CONFIG1);
424 1.3 veego vgaw(ba, CRT_ADDRESS_W + 0x0fff,
425 1.3 veego 0xc0 | vgar(ba, CRT_ADDRESS_R + 0x0fff));
426 1.3 veego }
427 1.3 veego
428 1.1 veego WSeq(ba, SEQ_ID_RESET, 0x03);
429 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21); /* 8 dot, Display off */
430 1.1 veego WSeq(ba, SEQ_ID_MAP_MASK, 0x0f);
431 1.1 veego WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
432 1.1 veego WSeq(ba, SEQ_ID_MEMORY_MODE, 0x0e);
433 1.9 veego WSeq(ba, SEQ_ID_STATE_CONTROL, 0x00);
434 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf4);
435 1.1 veego
436 1.1 veego WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00);
437 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, 0x00);
438 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, 0x08);
439 1.1 veego WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
440 1.1 veego WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
441 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
442 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
443 1.1 veego
444 1.9 veego WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x67);
445 1.9 veego WCrt(ba, CRT_ID_MODE_CONTROL, 0xc3);
446 1.9 veego WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
447 1.9 veego
448 1.9 veego /* ET4000 special */
449 1.1 veego WCrt(ba, CRT_ID_RASCAS_CONFIG, 0x28);
450 1.9 veego WCrt(ba, CRT_ID_EXT_START, 0x00);
451 1.1 veego WCrt(ba, CRT_ID_6845_COMPAT, 0x08);
452 1.9 veego
453 1.9 veego /* ET4000/W32 special (currently only for Merlin (crest) */
454 1.9 veego if (ettype == MERLIN) {
455 1.9 veego WCrt(ba, CRT_ID_SEGMENT_COMP, 0x1c);
456 1.9 veego WCrt(ba, CRT_ID_GENERAL_PURPOSE, 0x00);
457 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0x93);
458 1.9 veego }
459 1.9 veego else {
460 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xd3);
461 1.3 veego }
462 1.3 veego
463 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x0f);
464 1.1 veego WCrt(ba, CRT_ID_HOR_OVERFLOW, 0x00);
465 1.1 veego
466 1.9 veego vgaw(ba, GREG_SEGMENTSELECT, 0x00);
467 1.9 veego
468 1.1 veego WGfx(ba, GCT_ID_SET_RESET, 0x00);
469 1.1 veego WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
470 1.1 veego WGfx(ba, GCT_ID_COLOR_COMPARE, 0x00);
471 1.1 veego WGfx(ba, GCT_ID_DATA_ROTATE, 0x00);
472 1.1 veego WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
473 1.9 veego WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x40);
474 1.1 veego WGfx(ba, GCT_ID_MISC, 0x01);
475 1.1 veego WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f);
476 1.1 veego WGfx(ba, GCT_ID_BITMASK, 0xff);
477 1.1 veego
478 1.1 veego for (x = 0; x < 0x10; x++)
479 1.1 veego WAttr(ba, x, x);
480 1.1 veego WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x01);
481 1.1 veego WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00);
482 1.1 veego WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
483 1.1 veego WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
484 1.1 veego WAttr(ba, ACT_ID_COLOR_SELECT, 0x00);
485 1.1 veego WAttr(ba, ACT_ID_MISCELLANEOUS, 0x00);
486 1.1 veego
487 1.1 veego vgaw(ba, VDAC_MASK, 0xff);
488 1.1 veego delay(200000);
489 1.9 veego vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3);
490 1.1 veego
491 1.1 veego /* colors initially set to greyscale */
492 1.1 veego switch(ettype) {
493 1.1 veego case MERLIN:
494 1.1 veego vgaw(ba, MERLIN_VDAC_INDEX, 0);
495 1.1 veego for (x = 255; x >= 0; x--) {
496 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, x);
497 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, x);
498 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, x);
499 1.1 veego }
500 1.1 veego break;
501 1.1 veego default:
502 1.1 veego vgaw(ba, VDAC_ADDRESS_W, 0);
503 1.1 veego for (x = 255; x >= 0; x--) {
504 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), x);
505 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), x);
506 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), x);
507 1.1 veego }
508 1.1 veego break;
509 1.1 veego }
510 1.1 veego /* set sprite bitmap pointers */
511 1.1 veego /* should work like that */
512 1.1 veego et_cursprite.image = et_imageptr;
513 1.1 veego et_cursprite.mask = et_maskptr;
514 1.1 veego et_cursprite.cmap.red = et_sprred;
515 1.1 veego et_cursprite.cmap.green = et_sprgreen;
516 1.1 veego et_cursprite.cmap.blue = et_sprblue;
517 1.9 veego
518 1.9 veego /* card specific initialisations */
519 1.1 veego switch(ettype) {
520 1.1 veego case OMNIBUS:
521 1.1 veego etctype = et_getControllerType(gp);
522 1.1 veego etdtype = et_getDACType(gp);
523 1.1 veego break;
524 1.1 veego case MERLIN:
525 1.9 veego vgaw(ba, GREG_SEGMENTSELECT2, 0x00);
526 1.9 veego if (((vgar(ba, GREG_FEATURE_CONTROL_R) & 12) |
527 1.9 veego (vgar(ba, GREG_STATUS0_R) & 0x60)) == 0x24) {
528 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x07); /* 1Mx4 RAM */
529 1.9 veego et_fbsize = 0x400000; /* 4 MB */
530 1.9 veego }
531 1.9 veego else {
532 1.9 veego /* check for 1MB or 2MB board (crest) */
533 1.9 veego /* has there a 1MB Merlin ever been sold ??? */
534 1.9 veego volatile unsigned long *et_fbtestaddr;
535 1.9 veego et_fbtestaddr = (volatile unsigned long *)gp->g_fbkva;
536 1.9 veego *et_fbtestaddr = 0x0;
537 1.9 veego vgaw(ba, GREG_SEGMENTSELECT2, 0x11); /* 1MB offset */
538 1.9 veego *et_fbtestaddr = 0x12345678;
539 1.9 veego vgaw(ba, GREG_SEGMENTSELECT2, 0x00);
540 1.13 aymeric if (*et_fbtestaddr == 0x0)
541 1.9 veego et_fbsize = 0x200000; /* 2 MB */
542 1.9 veego else
543 1.9 veego et_fbsize = 0x100000; /* 1 MB */
544 1.9 veego }
545 1.9 veego /* ZorroII can map 2 MB max ... */
546 1.24 he if (!iszthreepa(kvtop(__UNVOLATILE(gp->g_fbkva))) &&
547 1.24 he et_fbsize == 0x400000)
548 1.9 veego et_fbsize = 0x200000;
549 1.1 veego etctype = ETW32;
550 1.1 veego etdtype = MERLINDAC;
551 1.3 veego break;
552 1.1 veego case DOMINO:
553 1.1 veego etctype = ET4000;
554 1.9 veego etdtype = et_getDACType(gp);
555 1.1 veego break;
556 1.1 veego }
557 1.1 veego }
558 1.1 veego
559 1.1 veego
560 1.1 veego int
561 1.13 aymeric et_getvmode(struct grf_softc *gp, struct grfvideo_mode *vm)
562 1.1 veego {
563 1.1 veego struct grfvideo_mode *gv;
564 1.1 veego
565 1.1 veego #ifdef TSENGCONSOLE
566 1.1 veego /* Handle grabbing console mode */
567 1.1 veego if (vm->mode_num == 255) {
568 1.28 cegger memcpy(vm, &etconsole_mode, sizeof(struct grfvideo_mode));
569 1.9 veego /* XXX so grfconfig can tell us the correct text dimensions. */
570 1.1 veego vm->depth = etconsole_mode.fy;
571 1.9 veego } else
572 1.1 veego #endif
573 1.3 veego {
574 1.3 veego if (vm->mode_num == 0)
575 1.3 veego vm->mode_num = (monitor_current - monitor_def) + 1;
576 1.3 veego if (vm->mode_num < 1 || vm->mode_num > monitor_def_max)
577 1.3 veego return (EINVAL);
578 1.3 veego gv = monitor_def + (vm->mode_num - 1);
579 1.3 veego if (gv->mode_num == 0)
580 1.3 veego return (EINVAL);
581 1.3 veego
582 1.28 cegger memcpy(vm, gv, sizeof(struct grfvideo_mode));
583 1.3 veego }
584 1.3 veego
585 1.3 veego /* adjust internal values to pixel values */
586 1.3 veego
587 1.3 veego vm->hblank_start *= 8;
588 1.3 veego vm->hsync_start *= 8;
589 1.3 veego vm->hsync_stop *= 8;
590 1.3 veego vm->htotal *= 8;
591 1.3 veego
592 1.1 veego return (0);
593 1.1 veego }
594 1.1 veego
595 1.1 veego
596 1.1 veego int
597 1.13 aymeric et_setvmode(struct grf_softc *gp, unsigned mode)
598 1.1 veego {
599 1.1 veego if (!mode || (mode > monitor_def_max) ||
600 1.1 veego monitor_def[mode - 1].mode_num == 0)
601 1.1 veego return (EINVAL);
602 1.1 veego
603 1.1 veego monitor_current = monitor_def + (mode - 1);
604 1.1 veego
605 1.1 veego return (0);
606 1.1 veego }
607 1.1 veego
608 1.1 veego
609 1.1 veego #ifndef TSENGCONSOLE
610 1.1 veego void
611 1.13 aymeric et_off(struct grf_softc *gp)
612 1.1 veego {
613 1.1 veego char *ba = gp->g_regkva;
614 1.1 veego
615 1.1 veego RegOnpass(ba);
616 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21);
617 1.1 veego }
618 1.1 veego #endif
619 1.1 veego
620 1.1 veego
621 1.1 veego int
622 1.13 aymeric et_blank(struct grf_softc *gp, int *on)
623 1.1 veego {
624 1.9 veego WSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE, *on > 0 ? 0x01 : 0x21);
625 1.9 veego return(0);
626 1.1 veego }
627 1.3 veego
628 1.1 veego
629 1.1 veego /*
630 1.1 veego * Change the mode of the display.
631 1.1 veego * Return a UNIX error number or 0 for success.
632 1.1 veego */
633 1.1 veego int
634 1.13 aymeric et_mode(register struct grf_softc *gp, u_long cmd, void *arg, u_long a2,
635 1.13 aymeric int a3)
636 1.1 veego {
637 1.3 veego int error;
638 1.1 veego
639 1.1 veego switch (cmd) {
640 1.1 veego case GM_GRFON:
641 1.1 veego error = et_load_mon(gp,
642 1.1 veego (struct grfettext_mode *) monitor_current) ? 0 : EINVAL;
643 1.1 veego return (error);
644 1.1 veego
645 1.1 veego case GM_GRFOFF:
646 1.1 veego #ifndef TSENGCONSOLE
647 1.1 veego et_off(gp);
648 1.1 veego #else
649 1.1 veego et_load_mon(gp, &etconsole_mode);
650 1.1 veego #endif
651 1.1 veego return (0);
652 1.1 veego
653 1.1 veego case GM_GRFCONFIG:
654 1.1 veego return (0);
655 1.1 veego
656 1.1 veego case GM_GRFGETVMODE:
657 1.1 veego return (et_getvmode(gp, (struct grfvideo_mode *) arg));
658 1.1 veego
659 1.1 veego case GM_GRFSETVMODE:
660 1.1 veego error = et_setvmode(gp, *(unsigned *) arg);
661 1.1 veego if (!error && (gp->g_flags & GF_GRFON))
662 1.1 veego et_load_mon(gp,
663 1.1 veego (struct grfettext_mode *) monitor_current);
664 1.1 veego return (error);
665 1.1 veego
666 1.1 veego case GM_GRFGETNUMVM:
667 1.1 veego *(int *) arg = monitor_def_max;
668 1.1 veego return (0);
669 1.1 veego
670 1.1 veego case GM_GRFIOCTL:
671 1.1 veego return (et_ioctl(gp, a2, arg));
672 1.1 veego
673 1.1 veego default:
674 1.1 veego break;
675 1.1 veego }
676 1.1 veego
677 1.15 atatat return (EPASSTHROUGH);
678 1.1 veego }
679 1.1 veego
680 1.3 veego
681 1.1 veego int
682 1.13 aymeric et_ioctl(register struct grf_softc *gp, u_long cmd, void *data)
683 1.1 veego {
684 1.1 veego switch (cmd) {
685 1.1 veego case GRFIOCGSPRITEPOS:
686 1.1 veego return (et_getmousepos(gp, (struct grf_position *) data));
687 1.1 veego
688 1.1 veego case GRFIOCSSPRITEPOS:
689 1.1 veego return (et_setmousepos(gp, (struct grf_position *) data));
690 1.1 veego
691 1.1 veego case GRFIOCSSPRITEINF:
692 1.1 veego return (et_setspriteinfo(gp, (struct grf_spriteinfo *) data));
693 1.1 veego
694 1.1 veego case GRFIOCGSPRITEINF:
695 1.1 veego return (et_getspriteinfo(gp, (struct grf_spriteinfo *) data));
696 1.1 veego
697 1.1 veego case GRFIOCGSPRITEMAX:
698 1.1 veego return (et_getspritemax(gp, (struct grf_position *) data));
699 1.1 veego
700 1.1 veego case GRFIOCGETCMAP:
701 1.1 veego return (et_getcmap(gp, (struct grf_colormap *) data));
702 1.1 veego
703 1.1 veego case GRFIOCPUTCMAP:
704 1.1 veego return (et_putcmap(gp, (struct grf_colormap *) data));
705 1.1 veego
706 1.1 veego case GRFIOCBITBLT:
707 1.1 veego break;
708 1.1 veego
709 1.1 veego case GRFTOGGLE:
710 1.1 veego return (et_toggle(gp, 0));
711 1.1 veego
712 1.1 veego case GRFIOCSETMON:
713 1.1 veego return (et_setmonitor(gp, (struct grfvideo_mode *) data));
714 1.1 veego
715 1.3 veego case GRFIOCBLANK:
716 1.1 veego return (et_blank(gp, (int *)data));
717 1.1 veego }
718 1.15 atatat return (EPASSTHROUGH);
719 1.1 veego }
720 1.1 veego
721 1.1 veego
722 1.1 veego int
723 1.13 aymeric et_getmousepos(struct grf_softc *gp, struct grf_position *data)
724 1.1 veego {
725 1.1 veego data->x = et_cursprite.pos.x;
726 1.1 veego data->y = et_cursprite.pos.y;
727 1.3 veego
728 1.1 veego return (0);
729 1.1 veego }
730 1.1 veego
731 1.1 veego
732 1.1 veego void
733 1.13 aymeric et_writesprpos(volatile char *ba, short x, short y)
734 1.1 veego {
735 1.1 veego }
736 1.1 veego
737 1.1 veego
738 1.1 veego int
739 1.13 aymeric et_setmousepos(struct grf_softc *gp, struct grf_position *data)
740 1.1 veego {
741 1.1 veego volatile char *ba = gp->g_regkva;
742 1.1 veego short rx, ry, prx, pry;
743 1.1 veego
744 1.1 veego /* no movement */
745 1.1 veego if (et_cursprite.pos.x == data->x && et_cursprite.pos.y == data->y)
746 1.1 veego return (0);
747 1.1 veego
748 1.3 veego /* current and previous real coordinates */
749 1.1 veego rx = data->x - et_cursprite.hot.x;
750 1.1 veego ry = data->y - et_cursprite.hot.y;
751 1.1 veego prx = et_cursprite.pos.x - et_cursprite.hot.x;
752 1.1 veego pry = et_cursprite.pos.y - et_cursprite.hot.y;
753 1.1 veego
754 1.3 veego /* if we are/were on an edge, create (un)shifted bitmap --
755 1.3 veego * ripped out optimization (not extremely worthwhile,
756 1.3 veego * and kind of buggy anyhow).
757 1.3 veego */
758 1.1 veego
759 1.3 veego /* do movement, save position */
760 1.3 veego et_writesprpos(ba, rx < 0 ? 0 : rx, ry < 0 ? 0 : ry);
761 1.1 veego et_cursprite.pos.x = data->x;
762 1.1 veego et_cursprite.pos.y = data->y;
763 1.1 veego
764 1.1 veego return (0);
765 1.1 veego }
766 1.1 veego
767 1.1 veego
768 1.1 veego int
769 1.13 aymeric et_getspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *data)
770 1.1 veego {
771 1.1 veego
772 1.1 veego return(EINVAL);
773 1.1 veego }
774 1.1 veego
775 1.1 veego
776 1.1 veego static int
777 1.13 aymeric et_setspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *data)
778 1.1 veego {
779 1.1 veego
780 1.1 veego return(EINVAL);
781 1.1 veego }
782 1.1 veego
783 1.1 veego
784 1.1 veego static int
785 1.13 aymeric et_getspritemax(struct grf_softc *gp, struct grf_position *data)
786 1.1 veego {
787 1.1 veego
788 1.1 veego return(EINVAL);
789 1.1 veego }
790 1.1 veego
791 1.1 veego
792 1.1 veego int
793 1.13 aymeric et_setmonitor(struct grf_softc *gp, struct grfvideo_mode *gv)
794 1.1 veego {
795 1.1 veego struct grfvideo_mode *md;
796 1.1 veego
797 1.3 veego if (!et_mondefok(gv))
798 1.3 veego return(EINVAL);
799 1.1 veego
800 1.1 veego #ifdef TSENGCONSOLE
801 1.1 veego /* handle interactive setting of console mode */
802 1.1 veego if (gv->mode_num == 255) {
803 1.28 cegger memcpy(&etconsole_mode.gv, gv, sizeof(struct grfvideo_mode));
804 1.3 veego etconsole_mode.gv.hblank_start /= 8;
805 1.3 veego etconsole_mode.gv.hsync_start /= 8;
806 1.3 veego etconsole_mode.gv.hsync_stop /= 8;
807 1.3 veego etconsole_mode.gv.htotal /= 8;
808 1.1 veego etconsole_mode.rows = gv->disp_height / etconsole_mode.fy;
809 1.1 veego etconsole_mode.cols = gv->disp_width / etconsole_mode.fx;
810 1.1 veego if (!(gp->g_flags & GF_GRFON))
811 1.1 veego et_load_mon(gp, &etconsole_mode);
812 1.29 phx #if NITE > 0
813 1.1 veego ite_reinit(gp->g_itedev);
814 1.29 phx #endif
815 1.1 veego return (0);
816 1.1 veego }
817 1.1 veego #endif
818 1.1 veego
819 1.1 veego md = monitor_def + (gv->mode_num - 1);
820 1.28 cegger memcpy(md, gv, sizeof(struct grfvideo_mode));
821 1.1 veego
822 1.3 veego /* adjust pixel oriented values to internal rep. */
823 1.1 veego
824 1.3 veego md->hblank_start /= 8;
825 1.3 veego md->hsync_start /= 8;
826 1.3 veego md->hsync_stop /= 8;
827 1.3 veego md->htotal /= 8;
828 1.1 veego
829 1.1 veego return (0);
830 1.1 veego }
831 1.1 veego
832 1.1 veego
833 1.1 veego int
834 1.13 aymeric et_getcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
835 1.1 veego {
836 1.1 veego volatile unsigned char *ba;
837 1.3 veego u_char red[256], green[256], blue[256], *rp, *gp, *bp;
838 1.3 veego short x;
839 1.3 veego int error;
840 1.1 veego
841 1.1 veego if (cmap->count == 0 || cmap->index >= 256)
842 1.1 veego return 0;
843 1.1 veego
844 1.16 itojun if (cmap->count > 256 - cmap->index)
845 1.1 veego cmap->count = 256 - cmap->index;
846 1.1 veego
847 1.1 veego ba = gfp->g_regkva;
848 1.1 veego /* first read colors out of the chip, then copyout to userspace */
849 1.1 veego x = cmap->count - 1;
850 1.1 veego
851 1.1 veego rp = red + cmap->index;
852 1.1 veego gp = green + cmap->index;
853 1.1 veego bp = blue + cmap->index;
854 1.1 veego
855 1.1 veego switch(ettype) {
856 1.1 veego case MERLIN:
857 1.1 veego vgaw(ba, MERLIN_VDAC_INDEX, cmap->index);
858 1.1 veego do {
859 1.1 veego *rp++ = vgar(ba, MERLIN_VDAC_COLORS);
860 1.1 veego *gp++ = vgar(ba, MERLIN_VDAC_COLORS);
861 1.1 veego *bp++ = vgar(ba, MERLIN_VDAC_COLORS);
862 1.1 veego } while (x-- > 0);
863 1.1 veego break;
864 1.1 veego default:
865 1.3 veego vgaw(ba, VDAC_ADDRESS_R+((ettype==DOMINO)?0x0fff:0), cmap->index);
866 1.1 veego do {
867 1.3 veego *rp++ = vgar(ba, VDAC_DATA+((ettype==DOMINO)?0x0fff:0)) << etcmap_shift;
868 1.3 veego *gp++ = vgar(ba, VDAC_DATA+((ettype==DOMINO)?0x0fff:0)) << etcmap_shift;
869 1.3 veego *bp++ = vgar(ba, VDAC_DATA+((ettype==DOMINO)?0x0fff:0)) << etcmap_shift;
870 1.1 veego } while (x-- > 0);
871 1.1 veego break;
872 1.1 veego }
873 1.1 veego
874 1.3 veego error = copyout(red + cmap->index, cmap->red, cmap->count);
875 1.3 veego if (!error)
876 1.3 veego error = copyout(green + cmap->index, cmap->green, cmap->count);
877 1.3 veego if (!error)
878 1.3 veego error = copyout(blue + cmap->index, cmap->blue, cmap->count);
879 1.1 veego
880 1.1 veego return (error);
881 1.1 veego }
882 1.1 veego
883 1.1 veego
884 1.1 veego int
885 1.13 aymeric et_putcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
886 1.1 veego {
887 1.1 veego volatile unsigned char *ba;
888 1.3 veego u_char red[256], green[256], blue[256], *rp, *gp, *bp;
889 1.3 veego short x;
890 1.3 veego int error;
891 1.1 veego
892 1.1 veego if (cmap->count == 0 || cmap->index >= 256)
893 1.1 veego return (0);
894 1.1 veego
895 1.16 itojun if (cmap->count > 256 - cmap->index)
896 1.1 veego cmap->count = 256 - cmap->index;
897 1.1 veego
898 1.1 veego /* first copy the colors into kernelspace */
899 1.3 veego if ((error = copyin(cmap->red, red + cmap->index, cmap->count)))
900 1.3 veego return (error);
901 1.3 veego
902 1.3 veego if ((error = copyin(cmap->green, green + cmap->index, cmap->count)))
903 1.3 veego return (error);
904 1.1 veego
905 1.3 veego if ((error = copyin(cmap->blue, blue + cmap->index, cmap->count)))
906 1.1 veego return (error);
907 1.3 veego
908 1.3 veego ba = gfp->g_regkva;
909 1.3 veego x = cmap->count - 1;
910 1.3 veego
911 1.3 veego rp = red + cmap->index;
912 1.3 veego gp = green + cmap->index;
913 1.3 veego bp = blue + cmap->index;
914 1.3 veego
915 1.3 veego switch(ettype){
916 1.3 veego case MERLIN:
917 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, cmap->index);
918 1.3 veego do {
919 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, *rp++);
920 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, *gp++);
921 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, *bp++);
922 1.3 veego } while (x-- > 0);
923 1.3 veego break;
924 1.3 veego default:
925 1.3 veego vgaw(ba, VDAC_ADDRESS_W, cmap->index);
926 1.3 veego do {
927 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
928 1.3 veego *rp++ >> etcmap_shift);
929 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
930 1.3 veego *gp++ >> etcmap_shift);
931 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
932 1.3 veego *bp++ >> etcmap_shift);
933 1.3 veego } while (x-- > 0);
934 1.3 veego break;
935 1.3 veego }
936 1.3 veego
937 1.3 veego return (0);
938 1.1 veego }
939 1.1 veego
940 1.1 veego
941 1.1 veego int
942 1.13 aymeric et_toggle(struct grf_softc *gp, unsigned short wopp)
943 1.13 aymeric /* (variable wopp) don't need that one yet, ill */
944 1.1 veego {
945 1.1 veego volatile unsigned char *ba;
946 1.1 veego
947 1.1 veego ba = gp->g_regkva;
948 1.1 veego
949 1.1 veego if (pass_toggle) {
950 1.1 veego RegOffpass(ba);
951 1.1 veego } else {
952 1.1 veego RegOnpass(ba);
953 1.1 veego }
954 1.1 veego return (0);
955 1.1 veego }
956 1.1 veego
957 1.3 veego
958 1.1 veego #define ET_NUMCLOCKS 32
959 1.1 veego
960 1.1 veego static u_char et_clocks[ET_NUMCLOCKS] = {
961 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5,
962 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5,
963 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5,
964 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5
965 1.1 veego };
966 1.1 veego
967 1.1 veego static u_char et_clockdividers[ET_NUMCLOCKS] = {
968 1.1 veego 3, 3, 3, 3, 3, 3, 3, 3,
969 1.1 veego 2, 2, 2, 2, 2, 2, 2, 2,
970 1.1 veego 1, 1, 1, 1, 1, 1, 1, 1,
971 1.1 veego 0, 0, 0, 0, 0, 0, 0, 0
972 1.1 veego };
973 1.1 veego
974 1.1 veego static u_int et_clockfreqs[ET_NUMCLOCKS] = {
975 1.3 veego 6293750, 7080500, 7875000, 8125000,
976 1.3 veego 9000000, 9375000, 10000000, 11225000,
977 1.3 veego 12587500, 14161000, 15750000, 16250000,
978 1.3 veego 18000000, 18750000, 20000000, 22450000,
979 1.3 veego 25175000, 28322000, 31500000, 32500000,
980 1.3 veego 36000000, 37500000, 40000000, 44900000,
981 1.3 veego 50350000, 56644000, 63000000, 65000000,
982 1.3 veego 72000000, 75000000, 80000000, 89800000
983 1.1 veego };
984 1.1 veego
985 1.1 veego
986 1.1 veego static void
987 1.13 aymeric et_CompFQ(u_int fq, u_char *num, u_char *denom)
988 1.1 veego {
989 1.1 veego int i;
990 1.1 veego
991 1.1 veego for (i=0; i < ET_NUMCLOCKS;) {
992 1.1 veego if (fq <= et_clockfreqs[i++]) {
993 1.1 veego break;
994 1.1 veego }
995 1.3 veego }
996 1.1 veego
997 1.1 veego *num = et_clocks[--i];
998 1.1 veego *denom = et_clockdividers[i];
999 1.1 veego
1000 1.1 veego return;
1001 1.1 veego }
1002 1.1 veego
1003 1.1 veego
1004 1.1 veego int
1005 1.13 aymeric et_mondefok(struct grfvideo_mode *gv)
1006 1.1 veego {
1007 1.9 veego unsigned long maxpix;
1008 1.3 veego
1009 1.1 veego if (gv->mode_num < 1 || gv->mode_num > monitor_def_max)
1010 1.3 veego if (gv->mode_num != 255 || gv->depth != 4)
1011 1.3 veego return(0);
1012 1.1 veego
1013 1.1 veego switch (gv->depth) {
1014 1.1 veego case 4:
1015 1.3 veego if (gv->mode_num != 255)
1016 1.3 veego return(0);
1017 1.1 veego case 1:
1018 1.1 veego case 8:
1019 1.9 veego maxpix = 85000000;
1020 1.9 veego break;
1021 1.1 veego case 15:
1022 1.1 veego case 16:
1023 1.9 veego maxpix = 45000000;
1024 1.9 veego break;
1025 1.1 veego case 24:
1026 1.9 veego maxpix = 28000000;
1027 1.9 veego break;
1028 1.9 veego case 32:
1029 1.9 veego maxpix = 21000000;
1030 1.9 veego break;
1031 1.1 veego default:
1032 1.10 veego printf("grfet: Illegal depth in mode %d\n",
1033 1.10 veego (int) gv->mode_num);
1034 1.1 veego return (0);
1035 1.1 veego }
1036 1.10 veego
1037 1.10 veego if (gv->pixel_clock > maxpix) {
1038 1.10 veego printf("grfet: Pixelclock too high in mode %d\n",
1039 1.10 veego (int) gv->mode_num);
1040 1.9 veego return (0);
1041 1.10 veego }
1042 1.10 veego
1043 1.10 veego if (gv->disp_flags & GRF_FLAGS_SYNC_ON_GREEN) {
1044 1.10 veego printf("grfet: sync-on-green is not supported\n");
1045 1.10 veego return (0);
1046 1.10 veego }
1047 1.10 veego
1048 1.3 veego return (1);
1049 1.1 veego }
1050 1.1 veego
1051 1.1 veego
1052 1.1 veego int
1053 1.13 aymeric et_load_mon(struct grf_softc *gp, struct grfettext_mode *md)
1054 1.1 veego {
1055 1.1 veego struct grfvideo_mode *gv;
1056 1.1 veego struct grfinfo *gi;
1057 1.1 veego volatile unsigned char *ba;
1058 1.1 veego unsigned char num0, denom0;
1059 1.1 veego unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
1060 1.1 veego VSE, VT;
1061 1.10 veego unsigned char hvsync_pulse, seq;
1062 1.10 veego char TEXT;
1063 1.9 veego int hmul;
1064 1.1 veego
1065 1.1 veego /* identity */
1066 1.1 veego gv = &md->gv;
1067 1.1 veego TEXT = (gv->depth == 4);
1068 1.1 veego
1069 1.1 veego if (!et_mondefok(gv)) {
1070 1.10 veego printf("grfet: Monitor definition not ok\n");
1071 1.1 veego return (0);
1072 1.1 veego }
1073 1.10 veego
1074 1.1 veego ba = gp->g_regkva;
1075 1.1 veego
1076 1.22 wiz /* provide all needed information in grf device-independent locations */
1077 1.23 christos gp->g_data = (void *) gv;
1078 1.1 veego gi = &gp->g_display;
1079 1.25 is gi->gd_regaddr = ztwopa(__UNVOLATILE(ba));
1080 1.1 veego gi->gd_regsize = 64 * 1024;
1081 1.24 he gi->gd_fbaddr = (void *) kvtop(__UNVOLATILE(gp->g_fbkva));
1082 1.1 veego gi->gd_fbsize = et_fbsize;
1083 1.1 veego gi->gd_colors = 1 << gv->depth;
1084 1.1 veego gi->gd_planes = gv->depth;
1085 1.1 veego gi->gd_fbwidth = gv->disp_width;
1086 1.1 veego gi->gd_fbheight = gv->disp_height;
1087 1.1 veego gi->gd_fbx = 0;
1088 1.1 veego gi->gd_fby = 0;
1089 1.1 veego if (TEXT) {
1090 1.1 veego gi->gd_dwidth = md->fx * md->cols;
1091 1.1 veego gi->gd_dheight = md->fy * md->rows;
1092 1.1 veego } else {
1093 1.1 veego gi->gd_dwidth = gv->disp_width;
1094 1.1 veego gi->gd_dheight = gv->disp_height;
1095 1.1 veego }
1096 1.1 veego gi->gd_dx = 0;
1097 1.1 veego gi->gd_dy = 0;
1098 1.1 veego
1099 1.1 veego /* get display mode parameters */
1100 1.1 veego
1101 1.1 veego HBS = gv->hblank_start;
1102 1.1 veego HSS = gv->hsync_start;
1103 1.1 veego HSE = gv->hsync_stop;
1104 1.10 veego HBE = gv->htotal - 1;
1105 1.1 veego HT = gv->htotal;
1106 1.1 veego VBS = gv->vblank_start;
1107 1.1 veego VSS = gv->vsync_start;
1108 1.1 veego VSE = gv->vsync_stop;
1109 1.10 veego VBE = gv->vtotal - 1;
1110 1.1 veego VT = gv->vtotal;
1111 1.1 veego
1112 1.1 veego if (TEXT)
1113 1.1 veego HDE = ((gv->disp_width + md->fx - 1) / md->fx) - 1;
1114 1.1 veego else
1115 1.1 veego HDE = (gv->disp_width + 3) / 8 - 1; /* HBS; */
1116 1.1 veego VDE = gv->disp_height - 1;
1117 1.1 veego
1118 1.9 veego /* adjustments (crest) */
1119 1.9 veego switch (gv->depth) {
1120 1.9 veego case 15:
1121 1.10 veego case 16:
1122 1.10 veego hmul = 2;
1123 1.10 veego break;
1124 1.10 veego case 24:
1125 1.10 veego hmul = 3;
1126 1.10 veego break;
1127 1.10 veego case 32:
1128 1.10 veego hmul = 4;
1129 1.10 veego break;
1130 1.10 veego default:
1131 1.10 veego hmul = 1;
1132 1.10 veego break;
1133 1.9 veego }
1134 1.1 veego
1135 1.9 veego HDE *= hmul;
1136 1.9 veego HBS *= hmul;
1137 1.9 veego HSS *= hmul;
1138 1.9 veego HSE *= hmul;
1139 1.9 veego HBE *= hmul;
1140 1.9 veego HT *= hmul;
1141 1.9 veego
1142 1.10 veego if (gv->disp_flags & GRF_FLAGS_LACE) {
1143 1.10 veego VDE /= 2;
1144 1.10 veego VT = VT + 1;
1145 1.10 veego }
1146 1.10 veego
1147 1.10 veego if (gv->disp_flags & GRF_FLAGS_DBLSCAN) {
1148 1.10 veego VDE *= 2;
1149 1.10 veego VBS *= 2;
1150 1.9 veego VSS *= 2;
1151 1.9 veego VSE *= 2;
1152 1.9 veego VBE *= 2;
1153 1.10 veego VT *= 2;
1154 1.9 veego }
1155 1.9 veego
1156 1.1 veego WSeq(ba, SEQ_ID_MEMORY_MODE, (TEXT || (gv->depth == 1)) ? 0x06 : 0x0e);
1157 1.1 veego
1158 1.1 veego WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
1159 1.1 veego WSeq(ba, SEQ_ID_MAP_MASK, (gv->depth == 1) ? 0x01 : 0xff);
1160 1.1 veego WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
1161 1.1 veego
1162 1.1 veego /* Set clock */
1163 1.9 veego et_CompFQ( gv->pixel_clock * hmul, &num0, &denom0);
1164 1.1 veego
1165 1.10 veego /* Horizontal/Vertical Sync Pulse */
1166 1.10 veego hvsync_pulse = 0xe3;
1167 1.10 veego if (gv->disp_flags & GRF_FLAGS_PHSYNC)
1168 1.10 veego hvsync_pulse &= ~0x40;
1169 1.10 veego else
1170 1.10 veego hvsync_pulse |= 0x40;
1171 1.10 veego if (gv->disp_flags & GRF_FLAGS_PVSYNC)
1172 1.10 veego hvsync_pulse &= ~0x80;
1173 1.10 veego else
1174 1.10 veego hvsync_pulse |= 0x80;
1175 1.10 veego
1176 1.10 veego vgaw(ba, GREG_MISC_OUTPUT_W, hvsync_pulse | ((num0 & 3) << 2));
1177 1.1 veego WCrt(ba, CRT_ID_6845_COMPAT, (num0 & 4) ? 0x0a : 0x08);
1178 1.10 veego seq = RSeq(ba, SEQ_ID_CLOCKING_MODE);
1179 1.1 veego switch(denom0) {
1180 1.1 veego case 0:
1181 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xb4);
1182 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7);
1183 1.1 veego break;
1184 1.1 veego case 1:
1185 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf4);
1186 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7);
1187 1.1 veego break;
1188 1.1 veego case 2:
1189 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf5);
1190 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7);
1191 1.1 veego break;
1192 1.1 veego case 3:
1193 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf5);
1194 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq | 0x08);
1195 1.1 veego break;
1196 1.9 veego }
1197 1.9 veego
1198 1.1 veego /* load display parameters into board */
1199 1.1 veego WCrt(ba, CRT_ID_HOR_TOTAL, HT);
1200 1.1 veego WCrt(ba, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? HBS - 1 : HDE));
1201 1.1 veego WCrt(ba, CRT_ID_START_HOR_BLANK, HBS);
1202 1.9 veego WCrt(ba, CRT_ID_END_HOR_BLANK, (HBE & 0x1f) | 0x80);
1203 1.1 veego WCrt(ba, CRT_ID_START_HOR_RETR, HSS);
1204 1.1 veego WCrt(ba, CRT_ID_END_HOR_RETR,
1205 1.1 veego (HSE & 0x1f) |
1206 1.1 veego ((HBE & 0x20) ? 0x80 : 0x00));
1207 1.1 veego WCrt(ba, CRT_ID_VER_TOTAL, VT);
1208 1.1 veego WCrt(ba, CRT_ID_OVERFLOW,
1209 1.1 veego 0x10 |
1210 1.1 veego ((VT & 0x100) ? 0x01 : 0x00) |
1211 1.1 veego ((VDE & 0x100) ? 0x02 : 0x00) |
1212 1.1 veego ((VSS & 0x100) ? 0x04 : 0x00) |
1213 1.1 veego ((VBS & 0x100) ? 0x08 : 0x00) |
1214 1.1 veego ((VT & 0x200) ? 0x20 : 0x00) |
1215 1.1 veego ((VDE & 0x200) ? 0x40 : 0x00) |
1216 1.1 veego ((VSS & 0x200) ? 0x80 : 0x00));
1217 1.1 veego
1218 1.1 veego WCrt(ba, CRT_ID_MAX_ROW_ADDRESS,
1219 1.9 veego 0x40 | /* splitscreen not visible */
1220 1.10 veego ((gv->disp_flags & GRF_FLAGS_DBLSCAN) ? 0x80 : 0x00) |
1221 1.1 veego ((VBS & 0x200) ? 0x20 : 0x00) |
1222 1.1 veego (TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
1223 1.1 veego
1224 1.1 veego WCrt(ba, CRT_ID_MODE_CONTROL,
1225 1.1 veego ((TEXT || (gv->depth == 1)) ? 0xc3 : 0xab));
1226 1.1 veego
1227 1.1 veego /* text cursor */
1228 1.1 veego if (TEXT) {
1229 1.1 veego #if ET_ULCURSOR
1230 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, (md->fy & 0x1f) - 2);
1231 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, (md->fy & 0x1f) - 1);
1232 1.1 veego #else
1233 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, 0x00);
1234 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, md->fy & 0x1f);
1235 1.1 veego #endif
1236 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
1237 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
1238 1.1 veego }
1239 1.1 veego
1240 1.1 veego WCrt(ba, CRT_ID_UNDERLINE_LOC, ((md->fy - 1) & 0x1f)
1241 1.1 veego | ((TEXT || (gv->depth == 1)) ? 0x00 : 0x60));
1242 1.1 veego
1243 1.1 veego WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
1244 1.1 veego WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
1245 1.1 veego
1246 1.1 veego WCrt(ba, CRT_ID_START_VER_RETR, VSS);
1247 1.1 veego WCrt(ba, CRT_ID_END_VER_RETR, (VSE & 0x0f) | 0x30);
1248 1.1 veego WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE);
1249 1.1 veego WCrt(ba, CRT_ID_START_VER_BLANK, VBS);
1250 1.1 veego WCrt(ba, CRT_ID_END_VER_BLANK, VBE);
1251 1.1 veego
1252 1.1 veego WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
1253 1.1 veego
1254 1.1 veego WCrt(ba, CRT_ID_OVERFLOW_HIGH,
1255 1.3 veego ((VBS & 0x400) ? 0x01 : 0x00) |
1256 1.3 veego ((VT & 0x400) ? 0x02 : 0x00) |
1257 1.3 veego ((VDE & 0x400) ? 0x04 : 0x00) |
1258 1.3 veego ((VSS & 0x400) ? 0x08 : 0x00) |
1259 1.3 veego 0x10 |
1260 1.10 veego ((gv->disp_flags & GRF_FLAGS_LACE) ? 0x80 : 0x00));
1261 1.3 veego
1262 1.3 veego WCrt(ba, CRT_ID_HOR_OVERFLOW,
1263 1.3 veego ((HT & 0x100) ? 0x01 : 0x00) |
1264 1.3 veego ((HBS & 0x100) ? 0x04 : 0x00) |
1265 1.3 veego ((HSS & 0x100) ? 0x10 : 0x00)
1266 1.3 veego );
1267 1.1 veego
1268 1.1 veego /* depth dependent stuff */
1269 1.1 veego
1270 1.1 veego WGfx(ba, GCT_ID_GRAPHICS_MODE,
1271 1.1 veego ((TEXT || (gv->depth == 1)) ? 0x00 : 0x40));
1272 1.1 veego WGfx(ba, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
1273 1.1 veego
1274 1.1 veego vgaw(ba, VDAC_MASK, 0xff);
1275 1.1 veego vgar(ba, VDAC_MASK);
1276 1.1 veego vgar(ba, VDAC_MASK);
1277 1.1 veego vgar(ba, VDAC_MASK);
1278 1.1 veego vgar(ba, VDAC_MASK);
1279 1.1 veego switch (gv->depth) {
1280 1.1 veego case 1:
1281 1.1 veego case 4: /* text */
1282 1.1 veego switch(etdtype) {
1283 1.1 veego case SIERRA11483:
1284 1.1 veego case SIERRA15025:
1285 1.1 veego case MUSICDAC:
1286 1.1 veego vgaw(ba, VDAC_MASK, 0);
1287 1.1 veego break;
1288 1.9 veego case ATT20C491:
1289 1.9 veego vgaw(ba, VDAC_MASK, 0x02);
1290 1.9 veego break;
1291 1.1 veego case MERLINDAC:
1292 1.1 veego setMerlinDACmode(ba, 0);
1293 1.1 veego break;
1294 1.1 veego }
1295 1.1 veego HDE = gv->disp_width / 16;
1296 1.1 veego break;
1297 1.1 veego case 8:
1298 1.1 veego switch(etdtype) {
1299 1.1 veego case SIERRA11483:
1300 1.1 veego case SIERRA15025:
1301 1.1 veego case MUSICDAC:
1302 1.1 veego vgaw(ba, VDAC_MASK, 0);
1303 1.1 veego break;
1304 1.9 veego case ATT20C491:
1305 1.9 veego vgaw(ba, VDAC_MASK, 0x02);
1306 1.9 veego break;
1307 1.1 veego case MERLINDAC:
1308 1.1 veego setMerlinDACmode(ba, 0);
1309 1.1 veego break;
1310 1.1 veego }
1311 1.1 veego HDE = gv->disp_width / 8;
1312 1.1 veego break;
1313 1.1 veego case 15:
1314 1.1 veego switch(etdtype) {
1315 1.1 veego case SIERRA11483:
1316 1.1 veego case SIERRA15025:
1317 1.1 veego case MUSICDAC:
1318 1.9 veego case ATT20C491:
1319 1.1 veego vgaw(ba, VDAC_MASK, 0xa0);
1320 1.1 veego break;
1321 1.1 veego case MERLINDAC:
1322 1.1 veego setMerlinDACmode(ba, 0xa0);
1323 1.1 veego break;
1324 1.1 veego }
1325 1.1 veego HDE = gv->disp_width / 4;
1326 1.1 veego break;
1327 1.1 veego case 16:
1328 1.1 veego switch(etdtype) {
1329 1.1 veego case SIERRA11483:
1330 1.1 veego vgaw(ba, VDAC_MASK, 0); /* illegal mode! */
1331 1.1 veego break;
1332 1.1 veego case SIERRA15025:
1333 1.1 veego vgaw(ba, VDAC_MASK, 0xe0);
1334 1.1 veego break;
1335 1.1 veego case MUSICDAC:
1336 1.9 veego case ATT20C491:
1337 1.1 veego vgaw(ba, VDAC_MASK, 0xc0);
1338 1.1 veego break;
1339 1.1 veego case MERLINDAC:
1340 1.1 veego setMerlinDACmode(ba, 0xe0);
1341 1.1 veego break;
1342 1.1 veego }
1343 1.1 veego HDE = gv->disp_width / 4;
1344 1.1 veego break;
1345 1.1 veego case 24:
1346 1.1 veego switch(etdtype) {
1347 1.1 veego case SIERRA11483:
1348 1.1 veego vgaw(ba, VDAC_MASK, 0); /* illegal mode! */
1349 1.1 veego break;
1350 1.1 veego case SIERRA15025:
1351 1.1 veego vgaw(ba, VDAC_MASK, 0xe1);
1352 1.1 veego break;
1353 1.1 veego case MUSICDAC:
1354 1.9 veego case ATT20C491:
1355 1.1 veego vgaw(ba, VDAC_MASK, 0xe0);
1356 1.1 veego break;
1357 1.1 veego case MERLINDAC:
1358 1.1 veego setMerlinDACmode(ba, 0xf0);
1359 1.1 veego break;
1360 1.1 veego }
1361 1.1 veego HDE = (gv->disp_width / 8) * 3;
1362 1.1 veego break;
1363 1.1 veego case 32:
1364 1.1 veego switch(etdtype) {
1365 1.1 veego case SIERRA11483:
1366 1.1 veego case MUSICDAC:
1367 1.9 veego case ATT20C491:
1368 1.1 veego vgaw(ba, VDAC_MASK, 0); /* illegal mode! */
1369 1.1 veego break;
1370 1.1 veego case SIERRA15025:
1371 1.1 veego vgaw(ba, VDAC_MASK, 0x61);
1372 1.1 veego break;
1373 1.1 veego case MERLINDAC:
1374 1.1 veego setMerlinDACmode(ba, 0xb0);
1375 1.1 veego break;
1376 1.1 veego }
1377 1.1 veego HDE = gv->disp_width / 2;
1378 1.1 veego break;
1379 1.1 veego }
1380 1.1 veego WAttr(ba, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x0a : 0x01));
1381 1.1 veego WAttr(ba, 0x20 | ACT_ID_COLOR_PLANE_ENA,
1382 1.1 veego (gv->depth == 1) ? 0x01 : 0x0f);
1383 1.1 veego
1384 1.1 veego WCrt(ba, CRT_ID_OFFSET, HDE);
1385 1.9 veego vgaw(ba, CRT_ADDRESS, CRT_ID_HOR_OVERFLOW);
1386 1.9 veego vgaw(ba, CRT_ADDRESS_W,
1387 1.9 veego (vgar(ba, CRT_ADDRESS_R) & 0x7f)
1388 1.9 veego | ((HDE & 0x100) ? 0x80: 0x00));
1389 1.1 veego
1390 1.1 veego /* text initialization */
1391 1.1 veego if (TEXT) {
1392 1.1 veego et_inittextmode(gp);
1393 1.1 veego }
1394 1.1 veego
1395 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x01);
1396 1.1 veego
1397 1.1 veego /* Pass-through */
1398 1.1 veego RegOffpass(ba);
1399 1.1 veego
1400 1.1 veego return (1);
1401 1.1 veego }
1402 1.1 veego
1403 1.1 veego
1404 1.1 veego void
1405 1.13 aymeric et_inittextmode(struct grf_softc *gp)
1406 1.1 veego {
1407 1.1 veego struct grfettext_mode *tm = (struct grfettext_mode *) gp->g_data;
1408 1.1 veego volatile unsigned char *ba = gp->g_regkva;
1409 1.24 he volatile unsigned char *fb = gp->g_fbkva;
1410 1.24 he volatile unsigned char *c;
1411 1.24 he unsigned char *f, y;
1412 1.1 veego unsigned short z;
1413 1.1 veego
1414 1.1 veego
1415 1.3 veego /*
1416 1.3 veego * load text font into beginning of display memory. Each character
1417 1.3 veego * cell is 32 bytes long (enough for 4 planes)
1418 1.3 veego */
1419 1.1 veego
1420 1.1 veego SetTextPlane(ba, 0x02);
1421 1.1 veego et_memset(fb, 0, 256 * 32);
1422 1.24 he c = fb + (32 * tm->fdstart);
1423 1.1 veego f = tm->fdata;
1424 1.1 veego for (z = tm->fdstart; z <= tm->fdend; z++, c += (32 - tm->fy))
1425 1.1 veego for (y = 0; y < tm->fy; y++)
1426 1.1 veego *c++ = *f++;
1427 1.1 veego
1428 1.1 veego /* clear out text/attr planes (three screens worth) */
1429 1.1 veego
1430 1.1 veego SetTextPlane(ba, 0x01);
1431 1.1 veego et_memset(fb, 0x07, tm->cols * tm->rows * 3);
1432 1.1 veego SetTextPlane(ba, 0x00);
1433 1.1 veego et_memset(fb, 0x20, tm->cols * tm->rows * 3);
1434 1.1 veego
1435 1.1 veego /* print out a little init msg */
1436 1.1 veego
1437 1.24 he c = fb + (tm->cols - 16);
1438 1.24 he strcpy(__UNVOLATILE(c), "TSENG");
1439 1.9 veego c[5] = 0x20;
1440 1.1 veego
1441 1.1 veego /* set colors (B&W) */
1442 1.1 veego
1443 1.1 veego switch(ettype) {
1444 1.1 veego case MERLIN:
1445 1.1 veego vgaw(ba, MERLIN_VDAC_INDEX, 0);
1446 1.1 veego for (z = 0; z < 256; z++) {
1447 1.1 veego y = (z & 1) ? ((z > 7) ? 2 : 1) : 0;
1448 1.9 veego
1449 1.1 veego vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][0]);
1450 1.1 veego vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][1]);
1451 1.1 veego vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][2]);
1452 1.1 veego }
1453 1.1 veego break;
1454 1.1 veego default:
1455 1.1 veego vgaw(ba, VDAC_ADDRESS_W, 0);
1456 1.1 veego for (z = 0; z < 256; z++) {
1457 1.1 veego y = (z & 1) ? ((z > 7) ? 2 : 1) : 0;
1458 1.9 veego
1459 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
1460 1.3 veego etconscolors[y][0] >> etcmap_shift);
1461 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
1462 1.3 veego etconscolors[y][1] >> etcmap_shift);
1463 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
1464 1.3 veego etconscolors[y][2] >> etcmap_shift);
1465 1.1 veego }
1466 1.1 veego break;
1467 1.1 veego }
1468 1.1 veego }
1469 1.1 veego
1470 1.1 veego
1471 1.1 veego void
1472 1.24 he et_memset(volatile unsigned char *d, unsigned char c, int l)
1473 1.1 veego {
1474 1.1 veego for (; l > 0; l--)
1475 1.1 veego *d++ = c;
1476 1.1 veego }
1477 1.1 veego
1478 1.1 veego
1479 1.1 veego static int
1480 1.13 aymeric et_getControllerType(struct grf_softc *gp)
1481 1.1 veego {
1482 1.24 he volatile unsigned char *ba = gp->g_regkva; /* register base */
1483 1.24 he volatile unsigned char *mem = gp->g_fbkva; /* memory base */
1484 1.24 he volatile unsigned char *mmu = mem + MMU_APERTURE0; /* MMU aperture 0 base */
1485 1.1 veego
1486 1.1 veego *mem = 0;
1487 1.1 veego
1488 1.1 veego /* make ACL visible */
1489 1.10 veego if (ettype == MERLIN) {
1490 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xbb);
1491 1.10 veego } else {
1492 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xfb);
1493 1.9 veego }
1494 1.9 veego
1495 1.1 veego WIma(ba, IMA_PORTCONTROL, 0x01);
1496 1.1 veego
1497 1.24 he *((volatile unsigned long *)mmu) = 0;
1498 1.1 veego *(mem + 0x13) = 0x38;
1499 1.3 veego
1500 1.1 veego *mmu = 0xff;
1501 1.1 veego
1502 1.1 veego /* hide ACL */
1503 1.1 veego WIma(ba, IMA_PORTCONTROL, 0x00);
1504 1.3 veego
1505 1.10 veego if (ettype == MERLIN) {
1506 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0x93);
1507 1.10 veego } else {
1508 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xd3);
1509 1.9 veego }
1510 1.10 veego return ((*mem == 0xff) ? ETW32 : ET4000);
1511 1.1 veego }
1512 1.1 veego
1513 1.1 veego
1514 1.1 veego static int
1515 1.13 aymeric et_getDACType(struct grf_softc *gp)
1516 1.1 veego {
1517 1.24 he volatile unsigned char *ba = gp->g_regkva;
1518 1.1 veego union {
1519 1.1 veego int tt;
1520 1.1 veego char cc[4];
1521 1.1 veego } check;
1522 1.1 veego
1523 1.1 veego /* check for Sierra SC 15025 */
1524 1.1 veego
1525 1.3 veego /* We MUST do 4 HW reads to switch into command mode */
1526 1.3 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1527 1.3 veego vgaw(ba, VDAC_COMMAND, 0x10); /* set ERPF */
1528 1.3 veego
1529 1.3 veego vgaw(ba, VDAC_XINDEX, 9);
1530 1.3 veego check.cc[0] = vgar(ba, VDAC_XDATA);
1531 1.3 veego vgaw(ba, VDAC_XINDEX, 10);
1532 1.3 veego check.cc[1] = vgar(ba, VDAC_XDATA);
1533 1.3 veego vgaw(ba, VDAC_XINDEX, 11);
1534 1.3 veego check.cc[2] = vgar(ba, VDAC_XDATA);
1535 1.3 veego vgaw(ba, VDAC_XINDEX, 12);
1536 1.3 veego check.cc[3] = vgar(ba, VDAC_XDATA);
1537 1.3 veego
1538 1.3 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1539 1.3 veego vgaw(ba, VDAC_COMMAND, 0x00); /* clear ERPF */
1540 1.3 veego
1541 1.3 veego if (check.tt == 0x533ab141) {
1542 1.3 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1543 1.3 veego vgaw(ba, VDAC_COMMAND, 0x10); /* set ERPF */
1544 1.3 veego
1545 1.3 veego /* switch to 8 bits per color */
1546 1.3 veego vgaw(ba, VDAC_XINDEX, 8);
1547 1.3 veego vgaw(ba, VDAC_XDATA, 1);
1548 1.3 veego /* do not shift color values */
1549 1.3 veego etcmap_shift = 0;
1550 1.3 veego
1551 1.3 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1552 1.3 veego vgaw(ba, VDAC_COMMAND, 0x00); /* clear ERPF */
1553 1.3 veego
1554 1.3 veego vgaw(ba, VDAC_MASK, 0xff);
1555 1.3 veego return (SIERRA15025);
1556 1.3 veego }
1557 1.3 veego
1558 1.3 veego /* check for MUSIC DAC */
1559 1.3 veego
1560 1.3 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1561 1.3 veego vgaw(ba, VDAC_COMMAND, 0x02); /* set some strange MUSIC mode (???) */
1562 1.3 veego
1563 1.3 veego vgaw(ba, VDAC_XINDEX, 0x01);
1564 1.3 veego if (vgar(ba, VDAC_XDATA) == 0x01) {
1565 1.3 veego /* shift color values by 2 */
1566 1.3 veego etcmap_shift = 2;
1567 1.1 veego
1568 1.3 veego vgaw(ba, VDAC_MASK, 0xff);
1569 1.3 veego return (MUSICDAC);
1570 1.9 veego }
1571 1.9 veego
1572 1.9 veego /* check for AT&T ATT20c491 DAC (crest) */
1573 1.9 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1574 1.9 veego vgaw(ba, HDR, 0xff);
1575 1.9 veego vgaw(ba, VDAC_MASK, 0x01);
1576 1.9 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1577 1.9 veego if (vgar(ba, HDR) == 0xff) {
1578 1.9 veego /* do not shift color values */
1579 1.9 veego etcmap_shift = 0;
1580 1.9 veego
1581 1.9 veego vgaw(ba, VDAC_MASK, 0xff);
1582 1.9 veego return (ATT20C491);
1583 1.9 veego }
1584 1.9 veego
1585 1.9 veego /* restore PowerUp settings (crest) */
1586 1.9 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1587 1.9 veego vgaw(ba, HDR, 0x00);
1588 1.3 veego
1589 1.3 veego /*
1590 1.3 veego * nothing else found, so let us pretend it is a stupid
1591 1.3 veego * Sierra SC 11483
1592 1.3 veego */
1593 1.1 veego
1594 1.1 veego /* shift color values by 2 */
1595 1.1 veego etcmap_shift = 2;
1596 1.3 veego
1597 1.1 veego vgaw(ba, VDAC_MASK, 0xff);
1598 1.9 veego return (SIERRA11483);
1599 1.1 veego }
1600 1.1 veego
1601 1.1 veego #endif /* NGRFET */
1602