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