grf_rh.c revision 1.28 1 /* $NetBSD: grf_rh.c,v 1.28 1998/01/12 10:39:37 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1994 Markus Wild
5 * Copyright (c) 1994 Lutz Vieweg
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Lutz Vieweg.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 #include "grfrh.h"
34 #if NGRFRH > 0
35
36 /*
37 * Graphics routines for the Retina BLT Z3 board,
38 * using the NCR 77C32BLT VGA controller.
39 */
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/errno.h>
44 #include <sys/ioctl.h>
45 #include <sys/device.h>
46 #include <sys/malloc.h>
47 #include <machine/cpu.h>
48 #include <amiga/amiga/device.h>
49 #include <amiga/dev/grfioctl.h>
50 #include <amiga/dev/grfvar.h>
51 #include <amiga/dev/grf_rhreg.h>
52 #include <amiga/dev/zbusvar.h>
53
54 enum mode_type { MT_TXTONLY, MT_GFXONLY, MT_BOTH };
55
56 int rh_mondefok __P((struct MonDef *));
57
58 u_short rh_CompFQ __P((u_int fq));
59 int rh_load_mon __P((struct grf_softc *gp, struct MonDef *md));
60 int rh_getvmode __P((struct grf_softc *gp, struct grfvideo_mode *vm));
61 int rh_setvmode __P((struct grf_softc *gp, unsigned int mode,
62 enum mode_type type));
63
64 /* make it patchable, and settable by kernel config option */
65 #ifndef RH_MEMCLK
66 #define RH_MEMCLK 61000000 /* this is the memory clock value, you shouldn't
67 set it to less than 61000000, higher values may
68 speed up blits a little bit, if you raise this
69 value too much, some trash will appear on your
70 screen. */
71 #endif
72 int rh_memclk = RH_MEMCLK;
73
74
75 extern unsigned char kernel_font_8x8_width, kernel_font_8x8_height;
76 extern unsigned char kernel_font_8x8_lo, kernel_font_8x8_hi;
77 extern unsigned char kernel_font_8x8[];
78 #ifdef KFONT_8X11
79 extern unsigned char kernel_font_8x11_width, kernel_font_8x11_height;
80 extern unsigned char kernel_font_8x11_lo, kernel_font_8x11_hi;
81 extern unsigned char kernel_font_8x11[];
82 #endif
83
84 /*
85 * This driver for the MacroSystem Retina board was only possible,
86 * because MacroSystem provided information about the pecularities
87 * of the board. THANKS! Competition in Europe among gfx board
88 * manufacturers is rather tough, so Lutz Vieweg, who wrote the
89 * initial driver, has made an agreement with MS not to document
90 * the driver source (see also his comment below).
91 * -> ALL comments after
92 * -> " -------------- START OF CODE -------------- "
93 * -> have been added by myself (mw) from studying the publically
94 * -> available "NCR 77C32BLT" Data Manual
95 */
96 /*
97 * This code offers low-level routines to access the Retina BLT Z3
98 * graphics-board manufactured by MS MacroSystem GmbH from within NetBSD
99 * for the Amiga.
100 *
101 * Thanks to MacroSystem for providing me with the neccessary information
102 * to create theese routines. The sparse documentation of this code
103 * results from the agreements between MS and me.
104 */
105
106
107
108 #define MDF_DBL 1
109 #define MDF_LACE 2
110 #define MDF_CLKDIV2 4
111
112 /* set this as an option in your kernel config file! */
113 /* #define RH_64BIT_SPRITE */
114
115 /* -------------- START OF CODE -------------- */
116
117 /* Convert big-endian long into little-endian long. */
118
119 #define M2I(val) \
120 asm volatile (" rorw #8,%0 ; \
121 swap %0 ; \
122 rorw #8,%0 ; " : "=d" (val) : "0" (val));
123
124 #define M2INS(val) \
125 asm volatile (" rorw #8,%0 ; \
126 swap %0 ; \
127 rorw #8,%0 ; \
128 swap %0 ; " : "=d" (val) : "0" (val));
129
130 #define ACM_OFFSET (0x00b00000)
131 #define LM_OFFSET (0x00c00000)
132
133 static unsigned char optab[] = {
134 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
135 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0
136 };
137 static char optabs[] = {
138 0, -1, -1, -1, -1, 0, -1, -1,
139 -1, -1, 0, -1, -1, -1, -1, 0
140 };
141
142 void
143 RZ3DisableHWC(gp)
144 struct grf_softc *gp;
145 {
146 volatile void *ba = gp->g_regkva;
147
148 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, 0x00);
149 }
150
151 void
152 RZ3SetupHWC(gp, col1, col2, hsx, hsy, data)
153 struct grf_softc *gp;
154 unsigned char col1;
155 unsigned col2;
156 unsigned char hsx;
157 unsigned char hsy;
158 const unsigned long *data;
159 {
160 volatile unsigned char *ba = gp->g_regkva;
161 unsigned long *c = (unsigned long *)(ba + LM_OFFSET + HWC_MEM_OFF);
162 const unsigned long *s = data;
163 struct MonDef *MonitorDef = (struct MonDef *) gp->g_data;
164 #ifdef RH_64BIT_SPRITE
165 short x = (HWC_MEM_SIZE / (4*4)) - 1;
166 #else
167 short x = (HWC_MEM_SIZE / (4*4*2)) - 1;
168 #endif
169 /* copy only, if there is a data pointer. */
170 if (data) do {
171 *c++ = *s++;
172 *c++ = *s++;
173 *c++ = *s++;
174 *c++ = *s++;
175 } while (x-- > 0);
176
177 WSeq(ba, SEQ_ID_CURSOR_COLOR1, col1);
178 WSeq(ba, SEQ_ID_CURSOR_COLOR0, col2);
179 if (MonitorDef->DEP <= 8) {
180 #ifdef RH_64BIT_SPRITE
181 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x85);
182 #else
183 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x03);
184 #endif
185 }
186 else if (MonitorDef->DEP <= 16) {
187 #ifdef RH_64BIT_SPRITE
188 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0xa5);
189 #else
190 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x23);
191 #endif
192 }
193 else {
194 #ifdef RH_64BIT_SPRITE
195 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0xc5);
196 #else
197 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x43);
198 #endif
199 }
200 WSeq(ba, SEQ_ID_CURSOR_X_LOC_HI, 0x00);
201 WSeq(ba, SEQ_ID_CURSOR_X_LOC_LO, 0x00);
202 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI, 0x00);
203 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO, 0x00);
204 WSeq(ba, SEQ_ID_CURSOR_X_INDEX, hsx);
205 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, hsy);
206 WSeq(ba, SEQ_ID_CURSOR_STORE_HI, 0x00);
207 WSeq(ba, SEQ_ID_CURSOR_STORE_LO, ((HWC_MEM_OFF / 4) & 0x0000f));
208 WSeq(ba, SEQ_ID_CURSOR_ST_OFF_HI, (((HWC_MEM_OFF / 4) & 0xff000) >> 12));
209 WSeq(ba, SEQ_ID_CURSOR_ST_OFF_LO, (((HWC_MEM_OFF / 4) & 0x00ff0) >> 4));
210 WSeq(ba, SEQ_ID_CURSOR_PIXELMASK, 0xff);
211 }
212
213 void
214 RZ3AlphaErase (gp, xd, yd, w, h)
215 struct grf_softc *gp;
216 unsigned short xd;
217 unsigned short yd;
218 unsigned short w;
219 unsigned short h;
220 {
221 const struct MonDef * md = (struct MonDef *) gp->g_data;
222 RZ3AlphaCopy(gp, xd, yd+md->TY, xd, yd, w, h);
223 }
224
225 void
226 RZ3AlphaCopy (gp, xs, ys, xd, yd, w, h)
227 struct grf_softc *gp;
228 unsigned short xs;
229 unsigned short ys;
230 unsigned short xd;
231 unsigned short yd;
232 unsigned short w;
233 unsigned short h;
234 {
235 volatile unsigned char *ba = gp->g_regkva;
236 const struct MonDef *md = (struct MonDef *) gp->g_data;
237 volatile unsigned long *acm = (unsigned long *) (ba + ACM_OFFSET);
238 unsigned short mod;
239
240 xs *= 4;
241 ys *= 4;
242 xd *= 4;
243 yd *= 4;
244 w *= 4;
245
246 {
247 /* anyone got Windoze GDI opcodes handy?... */
248 unsigned long tmp = 0x0000ca00;
249 *(acm + ACM_RASTEROP_ROTATION/4) = tmp;
250 }
251
252 mod = 0xc0c2;
253
254 {
255 unsigned long pat = 8 * PAT_MEM_OFF;
256 unsigned long dst = 8 * (xd + yd * md->TX);
257
258 unsigned long src = 8 * (xs + ys * md->TX);
259
260 if (xd > xs) {
261 mod &= ~0x8000;
262 src += 8 * (w - 1);
263 dst += 8 * (w - 1);
264 pat += 8 * 2;
265 }
266 if (yd > ys) {
267 mod &= ~0x4000;
268 src += 8 * (h - 1) * md->TX * 4;
269 dst += 8 * (h - 1) * md->TX * 4;
270 pat += 8 * 4;
271 }
272
273 M2I(src);
274 *(acm + ACM_SOURCE/4) = src;
275
276 M2I(pat);
277 *(acm + ACM_PATTERN/4) = pat;
278
279 M2I(dst);
280 *(acm + ACM_DESTINATION/4) = dst;
281 }
282 {
283
284 unsigned long tmp = mod << 16;
285 *(acm + ACM_CONTROL/4) = tmp;
286 }
287 {
288
289 unsigned long tmp = w | (h << 16);
290 M2I(tmp);
291 *(acm + ACM_BITMAP_DIMENSION/4) = tmp;
292 }
293
294 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;
295 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;
296
297 while ((*(((volatile unsigned char *)acm) +
298 (ACM_START_STATUS + 2)) & 1) == 0);
299 }
300
301 void
302 RZ3BitBlit (gp, gbb)
303 struct grf_softc *gp;
304 struct grf_bitblt * gbb;
305 {
306 volatile unsigned char *ba = gp->g_regkva;
307 volatile unsigned char *lm = ba + LM_OFFSET;
308 volatile unsigned long *acm = (unsigned long *) (ba + ACM_OFFSET);
309 const struct MonDef *md = (struct MonDef *) gp->g_data;
310 unsigned short mod;
311
312 {
313 unsigned long * pt = (unsigned long *) (lm + PAT_MEM_OFF);
314 unsigned long tmp = gbb->mask | ((unsigned long)gbb->mask << 16);
315 *pt++ = tmp;
316 *pt = tmp;
317 }
318
319 {
320
321 unsigned long tmp = optab[ gbb->op ] << 8;
322 *(acm + ACM_RASTEROP_ROTATION/4) = tmp;
323 }
324
325 mod = 0xc0c2;
326
327 {
328 unsigned long pat = 8 * PAT_MEM_OFF;
329 unsigned long dst = 8 * (gbb->dst_x + gbb->dst_y * md->TX);
330
331 if (optabs[gbb->op]) {
332 unsigned long src = 8 * (gbb->src_x + gbb->src_y * md->TX);
333
334 if (gbb->dst_x > gbb->src_x) {
335 mod &= ~0x8000;
336 src += 8 * (gbb->w - 1);
337 dst += 8 * (gbb->w - 1);
338 pat += 8 * 2;
339 }
340 if (gbb->dst_y > gbb->src_y) {
341 mod &= ~0x4000;
342 src += 8 * (gbb->h - 1) * md->TX;
343 dst += 8 * (gbb->h - 1) * md->TX;
344 pat += 8 * 4;
345 }
346
347 M2I(src);
348 *(acm + ACM_SOURCE/4) = src;
349 }
350
351 M2I(pat);
352 *(acm + ACM_PATTERN/4) = pat;
353
354 M2I(dst);
355 *(acm + ACM_DESTINATION/4) = dst;
356 }
357 {
358
359 unsigned long tmp = mod << 16;
360 *(acm + ACM_CONTROL/4) = tmp;
361 }
362 {
363 unsigned long tmp = gbb->w | (gbb->h << 16);
364 M2I(tmp);
365 *(acm + ACM_BITMAP_DIMENSION/4) = tmp;
366 }
367
368 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;
369 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;
370
371 while ((*(((volatile unsigned char *)acm) +
372 (ACM_START_STATUS + 2)) & 1) == 0);
373 }
374
375 void
376 RZ3BitBlit16 (gp, gbb)
377 struct grf_softc *gp;
378 struct grf_bitblt * gbb;
379 {
380 volatile unsigned char *ba = gp->g_regkva;
381 volatile unsigned char *lm = ba + LM_OFFSET;
382 volatile unsigned long * acm = (unsigned long *) (ba + ACM_OFFSET);
383 const struct MonDef * md = (struct MonDef *) gp->g_data;
384 unsigned short mod;
385
386 {
387 unsigned long * pt = (unsigned long *) (lm + PAT_MEM_OFF);
388 unsigned long tmp = gbb->mask | ((unsigned long)gbb->mask << 16);
389 *pt++ = tmp;
390 *pt++ = tmp;
391 *pt++ = tmp;
392 *pt = tmp;
393 }
394
395 {
396
397 unsigned long tmp = optab[ gbb->op ] << 8;
398 *(acm + ACM_RASTEROP_ROTATION/4) = tmp;
399 }
400
401 mod = 0xc0c2;
402
403 {
404 unsigned long pat = 8 * PAT_MEM_OFF;
405 unsigned long dst = 8 * 2 * (gbb->dst_x + gbb->dst_y * md->TX);
406
407 if (optabs[gbb->op]) {
408 unsigned long src = 8 * 2 * (gbb->src_x + gbb->src_y * md->TX);
409
410 if (gbb->dst_x > gbb->src_x) {
411 mod &= ~0x8000;
412 src += 8 * 2 * (gbb->w);
413 dst += 8 * 2 * (gbb->w);
414 pat += 8 * 2 * 2;
415 }
416 if (gbb->dst_y > gbb->src_y) {
417 mod &= ~0x4000;
418 src += 8 * 2 * (gbb->h - 1) * md->TX;
419 dst += 8 * 2 * (gbb->h - 1) * md->TX;
420 pat += 8 * 4 * 2;
421 }
422
423 M2I(src);
424 *(acm + ACM_SOURCE/4) = src;
425 }
426
427 M2I(pat);
428 *(acm + ACM_PATTERN/4) = pat;
429
430 M2I(dst);
431 *(acm + ACM_DESTINATION/4) = dst;
432 }
433 {
434
435 unsigned long tmp = mod << 16;
436 *(acm + ACM_CONTROL/4) = tmp;
437 }
438 {
439
440 unsigned long tmp = gbb->w | (gbb->h << 16);
441 M2I(tmp);
442 *(acm + ACM_BITMAP_DIMENSION/4) = tmp;
443 }
444
445 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;
446 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;
447
448 while ((*(((volatile unsigned char *)acm) +
449 (ACM_START_STATUS+ 2)) & 1) == 0);
450 }
451
452 void
453 RZ3BitBlit24 (gp, gbb)
454 struct grf_softc *gp;
455 struct grf_bitblt * gbb;
456 {
457 volatile unsigned char *ba = gp->g_regkva;
458 volatile unsigned char *lm = ba + LM_OFFSET;
459 volatile unsigned long * acm = (unsigned long *) (ba + ACM_OFFSET);
460 const struct MonDef * md = (struct MonDef *) gp->g_data;
461 unsigned short mod;
462
463
464 {
465 unsigned long * pt = (unsigned long *) (lm + PAT_MEM_OFF);
466 unsigned long tmp = gbb->mask | ((unsigned long)gbb->mask << 16);
467 *pt++ = tmp;
468 *pt++ = tmp;
469 *pt++ = tmp;
470 *pt++ = tmp;
471 *pt++ = tmp;
472 *pt = tmp;
473 }
474
475 {
476
477 unsigned long tmp = optab[ gbb->op ] << 8;
478 *(acm + ACM_RASTEROP_ROTATION/4) = tmp;
479 }
480
481 mod = 0xc0c2;
482
483 {
484 unsigned long pat = 8 * PAT_MEM_OFF;
485 unsigned long dst = 8 * 3 * (gbb->dst_x + gbb->dst_y * md->TX);
486
487 if (optabs[gbb->op]) {
488 unsigned long src = 8 * 3 * (gbb->src_x + gbb->src_y * md->TX);
489
490 if (gbb->dst_x > gbb->src_x ) {
491 mod &= ~0x8000;
492 src += 8 * 3 * (gbb->w);
493 dst += 8 * 3 * (gbb->w);
494 pat += 8 * 3 * 2;
495 }
496 if (gbb->dst_y > gbb->src_y) {
497 mod &= ~0x4000;
498 src += 8 * 3 * (gbb->h - 1) * md->TX;
499 dst += 8 * 3 * (gbb->h - 1) * md->TX;
500 pat += 8 * 4 * 3;
501 }
502
503 M2I(src);
504 *(acm + ACM_SOURCE/4) = src;
505 }
506
507
508 M2I(pat);
509 *(acm + ACM_PATTERN/4) = pat;
510
511
512 M2I(dst);
513 *(acm + ACM_DESTINATION/4) = dst;
514 }
515 {
516
517 unsigned long tmp = mod << 16;
518 *(acm + ACM_CONTROL/4) = tmp;
519 }
520 {
521
522 unsigned long tmp = gbb->w | (gbb->h << 16);
523 M2I(tmp);
524 *(acm + ACM_BITMAP_DIMENSION/4) = tmp;
525 }
526
527
528 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;
529 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;
530
531 while ( (*(((volatile unsigned char *)acm)
532 + (ACM_START_STATUS+ 2)) & 1) == 0 ) {};
533
534 }
535
536
537 void
538 RZ3SetCursorPos (gp, pos)
539 struct grf_softc *gp;
540 unsigned short pos;
541 {
542 volatile unsigned char *ba = gp->g_regkva;
543
544 WCrt(ba, CRT_ID_CURSOR_LOC_LOW, (unsigned char)pos);
545 WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, (unsigned char)(pos >> 8));
546
547 }
548
549 void
550 RZ3LoadPalette (gp, pal, firstcol, colors)
551 struct grf_softc *gp;
552 unsigned char * pal;
553 unsigned char firstcol;
554 unsigned char colors;
555 {
556 volatile unsigned char *ba = gp->g_regkva;
557
558 if (colors == 0)
559 return;
560
561 vgaw(ba, VDAC_ADDRESS_W, firstcol);
562
563 {
564
565 short x = colors-1;
566 const unsigned char * col = pal;
567 do {
568
569 vgaw(ba, VDAC_DATA, (*col++ >> 2));
570 vgaw(ba, VDAC_DATA, (*col++ >> 2));
571 vgaw(ba, VDAC_DATA, (*col++ >> 2));
572
573 } while (x-- > 0);
574
575 }
576 }
577
578 void
579 RZ3SetPalette (gp, colornum, red, green, blue)
580 struct grf_softc *gp;
581 unsigned char colornum;
582 unsigned char red, green, blue;
583 {
584 volatile unsigned char *ba = gp->g_regkva;
585
586 vgaw(ba, VDAC_ADDRESS_W, colornum);
587
588 vgaw(ba, VDAC_DATA, (red >> 2));
589 vgaw(ba, VDAC_DATA, (green >> 2));
590 vgaw(ba, VDAC_DATA, (blue >> 2));
591
592 }
593
594 void
595 RZ3SetPanning (gp, xoff, yoff)
596 struct grf_softc *gp;
597 unsigned short xoff, yoff;
598 {
599 volatile unsigned char *ba = gp->g_regkva;
600 struct grfinfo *gi = &gp->g_display;
601 const struct MonDef * md = (struct MonDef *) gp->g_data;
602 unsigned long off;
603
604 gi->gd_fbx = xoff;
605 gi->gd_fby = yoff;
606
607 if (md->DEP > 8 && md->DEP <= 16) xoff *= 2;
608 else if (md->DEP > 16) xoff *= 3;
609
610 vgar(ba, ACT_ADDRESS_RESET);
611 WAttr(ba, ACT_ID_HOR_PEL_PANNING, (unsigned char)((xoff << 1) & 0x07));
612 /* have the color lookup function normally again */
613 vgaw(ba, ACT_ADDRESS_W, 0x20);
614
615 if (md->DEP == 8)
616 off = ((yoff * md->TX)/ 4) + (xoff >> 2);
617 else if (md->DEP == 16)
618 off = ((yoff * md->TX * 2)/ 4) + (xoff >> 2);
619 else
620 off = ((yoff * md->TX * 3)/ 4) + (xoff >> 2);
621 WCrt(ba, CRT_ID_START_ADDR_LOW, ((unsigned char)off));
622 off >>= 8;
623 WCrt(ba, CRT_ID_START_ADDR_HIGH, ((unsigned char)off));
624 off >>= 8;
625 WCrt(ba, CRT_ID_EXT_START_ADDR,
626 ((RCrt(ba, CRT_ID_EXT_START_ADDR) & 0xf0) | (off & 0x0f)));
627
628
629 }
630
631 void
632 RZ3SetHWCloc (gp, x, y)
633 struct grf_softc *gp;
634 unsigned short x, y;
635 {
636 volatile unsigned char *ba = gp->g_regkva;
637 const struct MonDef *md = (struct MonDef *) gp->g_data;
638 /*volatile unsigned char *acm = ba + ACM_OFFSET;*/
639 struct grfinfo *gi = &gp->g_display;
640
641 if (x < gi->gd_fbx)
642 RZ3SetPanning(gp, x, gi->gd_fby);
643
644 if (x >= (gi->gd_fbx+md->MW))
645 RZ3SetPanning(gp, (1 + x - md->MW) , gi->gd_fby);
646
647 if (y < gi->gd_fby)
648 RZ3SetPanning(gp, gi->gd_fbx, y);
649
650 if (y >= (gi->gd_fby+md->MH))
651 RZ3SetPanning(gp, gi->gd_fbx, (1 + y - md->MH));
652
653 x -= gi->gd_fbx;
654 y -= gi->gd_fby;
655
656 #if 1
657 WSeq(ba, SEQ_ID_CURSOR_X_LOC_HI, x >> 8);
658 WSeq(ba, SEQ_ID_CURSOR_X_LOC_LO, x & 0xff);
659 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI, y >> 8);
660 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO, y & 0xff);
661 #else
662 *(acm + (ACM_CURSOR_POSITION+1)) = x >> 8;
663 *(acm + (ACM_CURSOR_POSITION+0)) = x & 0xff;
664 *(acm + (ACM_CURSOR_POSITION+3)) = y >> 8;
665 *(acm + (ACM_CURSOR_POSITION+2)) = y & 0xff;
666 #endif
667 }
668
669 u_short
670 rh_CompFQ(fq)
671 u_int fq;
672 {
673 /* yuck... this sure could need some explanation.. */
674
675 unsigned long f = fq;
676 long n2 = 3;
677 long abw = 0x7fffffff;
678 long n1 = 3;
679 unsigned long m;
680 unsigned short erg = 0;
681
682 f *= 8;
683
684 do {
685
686 if (f <= 250000000)
687 break;
688 f /= 2;
689
690 } while (n2-- > 0);
691
692 if (n2 < 0)
693 return(0);
694
695
696 do {
697 long tmp;
698
699 f = fq;
700 f >>= 3;
701 f <<= n2;
702 f >>= 7;
703
704 m = (f * n1) / (14318180/1024);
705
706 if (m > 129)
707 break;
708
709 tmp = (((m * 14318180) >> n2) / n1) - fq;
710 if (tmp < 0)
711 tmp = -tmp;
712
713 if (tmp < abw) {
714 abw = tmp;
715 erg = (((n2 << 5) | (n1-2)) << 8) | (m-2);
716 }
717
718 } while ( (++n1) <= 21);
719
720 return(erg);
721 }
722
723 int
724 rh_mondefok(mdp)
725 struct MonDef *mdp;
726 {
727 switch(mdp->DEP) {
728 case 8:
729 case 16:
730 case 24:
731 return(1);
732 case 4:
733 if (mdp->FX == 4 || (mdp->FX >= 7 && mdp->FX <= 16))
734 return(1);
735 /*FALLTHROUGH*/
736 default:
737 return(0);
738 }
739 }
740
741
742 int
743 rh_load_mon(gp, md)
744 struct grf_softc *gp;
745 struct MonDef *md;
746 {
747 struct grfinfo *gi = &gp->g_display;
748 volatile caddr_t ba;
749 volatile caddr_t fb;
750 short FW, clksel, HDE = 0, VDE;
751 unsigned short *c, z;
752 const unsigned char *f;
753
754 ba = gp->g_regkva;;
755 fb = gp->g_fbkva;
756
757 /* provide all needed information in grf device-independant
758 * locations */
759 gp->g_data = (caddr_t) md;
760 gi->gd_regaddr = (caddr_t) kvtop (ba);
761 gi->gd_regsize = LM_OFFSET;
762 gi->gd_fbaddr = (caddr_t) kvtop (fb);
763 gi->gd_fbsize = MEMSIZE *1024*1024;
764 #ifdef BANKEDDEVPAGER
765 /* we're not using banks NO MORE! */
766 gi->gd_bank_size = 0;
767 #endif
768 gi->gd_colors = 1 << md->DEP;
769 gi->gd_planes = md->DEP;
770
771 if (md->DEP == 4) {
772 gi->gd_fbwidth = md->MW;
773 gi->gd_fbheight = md->MH;
774 gi->gd_fbx = 0;
775 gi->gd_fby = 0;
776 gi->gd_dwidth = md->TX * md->FX;
777 gi->gd_dheight = md->TY * md->FY;
778 gi->gd_dx = 0;
779 gi->gd_dy = 0;
780 } else {
781 gi->gd_fbwidth = md->TX;
782 gi->gd_fbheight = md->TY;
783 gi->gd_fbx = 0;
784 gi->gd_fby = 0;
785 gi->gd_dwidth = md->MW;
786 gi->gd_dheight = md->MH;
787 gi->gd_dx = 0;
788 gi->gd_dy = 0;
789 }
790
791 FW =0;
792 if (md->DEP == 4) { /* XXX some text-mode! */
793 switch (md->FX) {
794 case 4:
795 FW = 0;
796 break;
797 case 7:
798 FW = 1;
799 break;
800 case 8:
801 FW = 2;
802 break;
803 case 9:
804 FW = 3;
805 break;
806 case 10:
807 FW = 4;
808 break;
809 case 11:
810 FW = 5;
811 break;
812 case 12:
813 FW = 6;
814 break;
815 case 13:
816 FW = 7;
817 break;
818 case 14:
819 FW = 8;
820 break;
821 case 15:
822 FW = 9;
823 break;
824 case 16:
825 FW = 11;
826 break;
827 default:
828 return(0);
829 break;
830 }
831 }
832
833 if (md->DEP == 4) HDE = (md->MW+md->FX-1)/md->FX;
834 else if (md->DEP == 8) HDE = (md->MW+3)/4;
835 else if (md->DEP == 16) HDE = (md->MW*2+3)/4;
836 else if (md->DEP == 24) HDE = (md->MW*3+3)/4;
837
838 VDE = md->MH-1;
839
840 clksel = 0;
841
842 vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3 | ((clksel & 3) * 0x04));
843 vgaw(ba, GREG_FEATURE_CONTROL_W, 0x00);
844
845 WSeq(ba, SEQ_ID_RESET, 0x00);
846 WSeq(ba, SEQ_ID_RESET, 0x03);
847 WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8));
848 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f);
849 WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
850 WSeq(ba, SEQ_ID_MEMORY_MODE, 0x06);
851 WSeq(ba, SEQ_ID_RESET, 0x01);
852 WSeq(ba, SEQ_ID_RESET, 0x03);
853
854 WSeq(ba, SEQ_ID_EXTENDED_ENABLE, 0x05);
855 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x00);
856 WSeq(ba, SEQ_ID_PRIM_HOST_OFF_HI, 0x00);
857 WSeq(ba, SEQ_ID_PRIM_HOST_OFF_HI, 0x00);
858 WSeq(ba, SEQ_ID_LINEAR_0, 0x4a);
859 WSeq(ba, SEQ_ID_LINEAR_1, 0x00);
860
861 WSeq(ba, SEQ_ID_SEC_HOST_OFF_HI, 0x00);
862 WSeq(ba, SEQ_ID_SEC_HOST_OFF_LO, 0x00);
863 WSeq(ba, SEQ_ID_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40);
864 WSeq(ba, SEQ_ID_EXT_CLOCK_MODE, 0x10 | (FW & 0x0f));
865 WSeq(ba, SEQ_ID_EXT_VIDEO_ADDR, 0x03);
866 if (md->DEP == 4) {
867 /* 8bit pixel, no gfx byte path */
868 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x00);
869 }
870 else if (md->DEP == 8) {
871 /* 8bit pixel, gfx byte path */
872 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x01);
873 }
874 else if (md->DEP == 16) {
875 /* 16bit pixel, gfx byte path */
876 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x11);
877 }
878 else if (md->DEP == 24) {
879 /* 24bit pixel, gfx byte path */
880 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x21);
881 }
882 WSeq(ba, SEQ_ID_BUS_WIDTH_FEEDB, 0x04);
883 WSeq(ba, SEQ_ID_COLOR_EXP_WFG, 0x01);
884 WSeq(ba, SEQ_ID_COLOR_EXP_WBG, 0x00);
885 WSeq(ba, SEQ_ID_EXT_RW_CONTROL, 0x00);
886 WSeq(ba, SEQ_ID_MISC_FEATURE_SEL, (0x51 | (clksel & 8)));
887 WSeq(ba, SEQ_ID_COLOR_KEY_CNTL, 0x40);
888 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH0, 0x00);
889 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH1, 0x00);
890 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH2, 0x00);
891 WSeq(ba, SEQ_ID_CRC_CONTROL, 0x00);
892 WSeq(ba, SEQ_ID_PERF_SELECT, 0x10);
893 WSeq(ba, SEQ_ID_ACM_APERTURE_1, 0x00);
894 WSeq(ba, SEQ_ID_ACM_APERTURE_2, 0x30);
895 WSeq(ba, SEQ_ID_ACM_APERTURE_3, 0x00);
896 WSeq(ba, SEQ_ID_MEMORY_MAP_CNTL, 0x03); /* was 7, but stupid cursor */
897
898 WCrt(ba, CRT_ID_END_VER_RETR, (md->VSE & 0xf) | 0x20);
899 WCrt(ba, CRT_ID_HOR_TOTAL, md->HT & 0xff);
900 WCrt(ba, CRT_ID_HOR_DISP_ENA_END, (HDE-1) & 0xff);
901 WCrt(ba, CRT_ID_START_HOR_BLANK, md->HBS & 0xff);
902 WCrt(ba, CRT_ID_END_HOR_BLANK, (md->HBE & 0x1f) | 0x80);
903
904 WCrt(ba, CRT_ID_START_HOR_RETR, md->HSS & 0xff);
905 WCrt(ba, CRT_ID_END_HOR_RETR,
906 (md->HSE & 0x1f) |
907 ((md->HBE & 0x20)/ 0x20 * 0x80));
908 WCrt(ba, CRT_ID_VER_TOTAL, (md->VT & 0xff));
909 WCrt(ba, CRT_ID_OVERFLOW,
910 ((md->VSS & 0x200) / 0x200 * 0x80) |
911 ((VDE & 0x200) / 0x200 * 0x40) |
912 ((md->VT & 0x200) / 0x200 * 0x20) |
913 0x10 |
914 ((md->VBS & 0x100) / 0x100 * 8) |
915 ((md->VSS & 0x100) / 0x100 * 4) |
916 ((VDE & 0x100) / 0x100 * 2) |
917 ((md->VT & 0x100) / 0x100));
918 WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00);
919
920 if (md->DEP == 4) {
921 WCrt(ba, CRT_ID_MAX_SCAN_LINE,
922 ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80) |
923 0x40 |
924 ((md->VBS & 0x200)/0x200*0x20) |
925 ((md->FY-1) & 0x1f));
926 } else {
927 WCrt(ba, CRT_ID_MAX_SCAN_LINE,
928 ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80) |
929 0x40 |
930 ((md->VBS & 0x200)/0x200*0x20) |
931 (0 & 0x1f));
932 }
933
934 /* I prefer "_" cursor to "block" cursor.. */
935 #if 1
936 WCrt(ba, CRT_ID_CURSOR_START, (md->FY & 0x1f) - 2);
937 WCrt(ba, CRT_ID_CURSOR_END, (md->FY & 0x1f) - 1);
938 #else
939 WCrt(ba, CRT_ID_CURSOR_START, 0x00);
940 WCrt(ba, CRT_ID_CURSOR_END, md->FY & 0x1f);
941 #endif
942
943 WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
944 WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
945
946 WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
947 WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
948
949 WCrt(ba, CRT_ID_START_VER_RETR, md->VSS & 0xff);
950 WCrt(ba, CRT_ID_END_VER_RETR, (md->VSE & 0xf) | 0x80 | 0x20);
951 WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE & 0xff);
952
953 if (md->DEP == 4) {
954 WCrt(ba, CRT_ID_OFFSET, (HDE / 2) & 0xff );
955 }
956 /* all gfx-modes are in byte-mode, means values are multiplied by 8 */
957 else if (md->DEP == 8) {
958 WCrt(ba, CRT_ID_OFFSET, (md->TX / 8) & 0xff );
959 } else if (md->DEP == 16) {
960 WCrt(ba, CRT_ID_OFFSET, (md->TX / 4) & 0xff );
961 } else {
962 WCrt(ba, CRT_ID_OFFSET, (md->TX * 3 / 8) & 0xff );
963 }
964
965 WCrt(ba, CRT_ID_UNDERLINE_LOC, (md->FY-1) & 0x1f);
966 WCrt(ba, CRT_ID_START_VER_BLANK, md->VBS & 0xff);
967 WCrt(ba, CRT_ID_END_VER_BLANK, md->VBE & 0xff);
968 WCrt(ba, CRT_ID_MODE_CONTROL, 0xe3);
969 WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
970
971 WCrt(ba, CRT_ID_EXT_HOR_TIMING1,
972 0 | 0x20 |
973 ((md->FLG & MDF_LACE) / MDF_LACE * 0x10) |
974 ((md->HT & 0x100) / 0x100) |
975 (((HDE-1) & 0x100) / 0x100 * 2) |
976 ((md->HBS & 0x100) / 0x100 * 4) |
977 ((md->HSS & 0x100) / 0x100 * 8));
978
979 if (md->DEP == 4) {
980 WCrt(ba, CRT_ID_EXT_START_ADDR, (((HDE / 2) & 0x100)/0x100 * 16));
981 }
982 else if (md->DEP == 8) {
983 WCrt(ba, CRT_ID_EXT_START_ADDR, (((md->TX / 8) & 0x100)/0x100 * 16));
984 } else if (md->DEP == 16) {
985 WCrt(ba, CRT_ID_EXT_START_ADDR, (((md->TX / 4) & 0x100)/0x100 * 16));
986 } else {
987 WCrt(ba, CRT_ID_EXT_START_ADDR, (((md->TX * 3 / 8) & 0x100)/0x100 * 16));
988 }
989
990 WCrt(ba, CRT_ID_EXT_HOR_TIMING2,
991 ((md->HT & 0x200)/ 0x200) |
992 (((HDE-1) & 0x200)/ 0x200 * 2 ) |
993 ((md->HBS & 0x200)/ 0x200 * 4 ) |
994 ((md->HSS & 0x200)/ 0x200 * 8 ) |
995 ((md->HBE & 0xc0) / 0x40 * 16 ) |
996 ((md->HSE & 0x60) / 0x20 * 64));
997
998 WCrt(ba, CRT_ID_EXT_VER_TIMING,
999 ((md->VSE & 0x10) / 0x10 * 0x80 ) |
1000 ((md->VBE & 0x300)/ 0x100 * 0x20 ) |
1001 0x10 |
1002 ((md->VSS & 0x400)/ 0x400 * 8 ) |
1003 ((md->VBS & 0x400)/ 0x400 * 4 ) |
1004 ((VDE & 0x400)/ 0x400 * 2 ) |
1005 ((md->VT & 0x400)/ 0x400));
1006 WCrt(ba, CRT_ID_MONITOR_POWER, 0x00);
1007
1008 {
1009 unsigned short tmp = rh_CompFQ(md->FQ);
1010 WPLL(ba, 2 , tmp);
1011 tmp = rh_CompFQ(rh_memclk);
1012 WPLL(ba,10 , tmp);
1013 WPLL(ba,14 , 0x22);
1014 }
1015
1016 WGfx(ba, GCT_ID_SET_RESET, 0x00);
1017 WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
1018 WGfx(ba, GCT_ID_COLOR_COMPARE, 0x00);
1019 WGfx(ba, GCT_ID_DATA_ROTATE, 0x00);
1020 WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
1021 WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00);
1022 if (md->DEP == 4)
1023 WGfx(ba, GCT_ID_MISC, 0x04);
1024 else
1025 WGfx(ba, GCT_ID_MISC, 0x05);
1026 WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f);
1027 WGfx(ba, GCT_ID_BITMASK, 0xff);
1028
1029 vgar(ba, ACT_ADDRESS_RESET);
1030 WAttr(ba, ACT_ID_PALETTE0 , 0x00);
1031 WAttr(ba, ACT_ID_PALETTE1 , 0x01);
1032 WAttr(ba, ACT_ID_PALETTE2 , 0x02);
1033 WAttr(ba, ACT_ID_PALETTE3 , 0x03);
1034 WAttr(ba, ACT_ID_PALETTE4 , 0x04);
1035 WAttr(ba, ACT_ID_PALETTE5 , 0x05);
1036 WAttr(ba, ACT_ID_PALETTE6 , 0x06);
1037 WAttr(ba, ACT_ID_PALETTE7 , 0x07);
1038 WAttr(ba, ACT_ID_PALETTE8 , 0x08);
1039 WAttr(ba, ACT_ID_PALETTE9 , 0x09);
1040 WAttr(ba, ACT_ID_PALETTE10, 0x0a);
1041 WAttr(ba, ACT_ID_PALETTE11, 0x0b);
1042 WAttr(ba, ACT_ID_PALETTE12, 0x0c);
1043 WAttr(ba, ACT_ID_PALETTE13, 0x0d);
1044 WAttr(ba, ACT_ID_PALETTE14, 0x0e);
1045 WAttr(ba, ACT_ID_PALETTE15, 0x0f);
1046
1047 vgar(ba, ACT_ADDRESS_RESET);
1048 if (md->DEP == 4)
1049 WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x08);
1050 else
1051 WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x09);
1052
1053 WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00);
1054 WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
1055 WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
1056 WAttr(ba, ACT_ID_COLOR_SELECT, 0x00);
1057
1058 vgar(ba, ACT_ADDRESS_RESET);
1059 vgaw(ba, ACT_ADDRESS_W, 0x20);
1060
1061 vgaw(ba, VDAC_MASK, 0xff);
1062 /* probably some PLL timing stuff here. The value
1063 for 24bit was found by trial&error :-) */
1064 if (md->DEP < 16) {
1065 vgaw(ba, 0x83c6, ((0 & 7) << 5) );
1066 }
1067 else if (md->DEP == 16) {
1068 /* well... */
1069 vgaw(ba, 0x83c6, ((3 & 7) << 5) );
1070 }
1071 else if (md->DEP == 24) {
1072 vgaw(ba, 0x83c6, 0xe0);
1073 }
1074 vgaw(ba, VDAC_ADDRESS_W, 0x00);
1075
1076 if (md->DEP < 16) {
1077 short x = 256-17;
1078 unsigned char cl = 16;
1079 RZ3LoadPalette(gp, md->PAL, 0, 16);
1080 do {
1081 vgaw(ba, VDAC_DATA, (cl >> 2));
1082 vgaw(ba, VDAC_DATA, (cl >> 2));
1083 vgaw(ba, VDAC_DATA, (cl >> 2));
1084 cl++;
1085 } while (x-- > 0);
1086 }
1087
1088 if (md->DEP == 4) {
1089 {
1090 struct grf_bitblt bb = {
1091 GRFBBOPset,
1092 0, 0,
1093 0, 0,
1094 md->TX*4, 2*md->TY,
1095 EMPTY_ALPHA
1096 };
1097 RZ3BitBlit(gp, &bb);
1098 }
1099
1100 c = (unsigned short *)(ba + LM_OFFSET);
1101 c += 2 * md->FLo*32;
1102 c += 1;
1103 f = md->FData;
1104 for (z = md->FLo; z <= md->FHi; z++) {
1105 short y = md->FY-1;
1106 if (md->FX > 8){
1107 do {
1108 *c = *((const unsigned short *)f);
1109 c += 2;
1110 f += 2;
1111 } while (y-- > 0);
1112 } else {
1113 do {
1114 *c = (*f++) << 8;
1115 c += 2;
1116 } while (y-- > 0);
1117 }
1118
1119 c += 2 * (32-md->FY);
1120 }
1121 {
1122 unsigned long * pt = (unsigned long *) (ba + LM_OFFSET + PAT_MEM_OFF);
1123 unsigned long tmp = 0xffff0000;
1124 *pt++ = tmp;
1125 *pt = tmp;
1126 }
1127
1128 WSeq(ba, SEQ_ID_MAP_MASK, 3);
1129
1130 c = (unsigned short *)(ba + LM_OFFSET);
1131 c += (md->TX-6)*2;
1132 {
1133 /* it's show-time :-) */
1134 static unsigned short init_msg[6] = {
1135 0x520a, 0x450b, 0x540c, 0x490d, 0x4e0e, 0x410f
1136 };
1137 unsigned short * m = init_msg;
1138 short x = 5;
1139 do {
1140 *c = *m++;
1141 c += 2;
1142 } while (x-- > 0);
1143 }
1144
1145 return(1);
1146 } else if (md->DEP == 8) {
1147 struct grf_bitblt bb = {
1148 GRFBBOPset,
1149 0, 0,
1150 0, 0,
1151 md->TX, md->TY,
1152 0x0000
1153 };
1154 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f);
1155
1156 RZ3BitBlit(gp, &bb);
1157
1158 gi->gd_fbx = 0;
1159 gi->gd_fby = 0;
1160
1161 return(1);
1162 } else if (md->DEP == 16) {
1163 struct grf_bitblt bb = {
1164 GRFBBOPset,
1165 0, 0,
1166 0, 0,
1167 md->TX, md->TY,
1168 0x0000
1169 };
1170 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f);
1171
1172 RZ3BitBlit16(gp, &bb);
1173
1174 gi->gd_fbx = 0;
1175 gi->gd_fby = 0;
1176
1177 return(1);
1178 } else if (md->DEP == 24) {
1179 struct grf_bitblt bb = {
1180 GRFBBOPset,
1181 0, 0,
1182 0, 0,
1183 md->TX, md->TY,
1184 0x0000
1185 };
1186 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f );
1187
1188 RZ3BitBlit24(gp, &bb );
1189
1190 gi->gd_fbx = 0;
1191 gi->gd_fby = 0;
1192
1193 return 1;
1194 } else
1195 return(0);
1196 }
1197
1198 /* standard-palette definition */
1199
1200 unsigned char RZ3StdPalette[16*3] = {
1201 /* R G B */
1202 0, 0, 0,
1203 192,192,192,
1204 128, 0, 0,
1205 0,128, 0,
1206 0, 0,128,
1207 128,128, 0,
1208 0,128,128,
1209 128, 0,128,
1210 64, 64, 64, /* the higher 8 colors have more intensity for */
1211 255,255,255, /* compatibility with standard attributes */
1212 255, 0, 0,
1213 0,255, 0,
1214 0, 0,255,
1215 255,255, 0,
1216 0,255,255,
1217 255, 0,255
1218 };
1219
1220 /*
1221 * The following structures are examples for monitor-definitions. To make one
1222 * of your own, first use "DefineMonitor" and create the 8-bit or 16-bit
1223 * monitor-mode of your dreams. Then save it, and make a structure from the
1224 * values provided in the file DefineMonitor stored - the labels in the comment
1225 * above the structure definition show where to put what value.
1226 *
1227 * If you want to use your definition for the text-mode, you'll need to adapt
1228 * your 8-bit monitor-definition to the font you want to use. Be FX the width of
1229 * the font, then the following modifications have to be applied to your values:
1230 *
1231 * HBS = (HBS * 4) / FX
1232 * HSS = (HSS * 4) / FX
1233 * HSE = (HSE * 4) / FX
1234 * HBE = (HBE * 4) / FX
1235 * HT = (HT * 4) / FX
1236 *
1237 * Make sure your maximum width (MW) and height (MH) are even multiples of
1238 * the fonts' width and height.
1239 *
1240 * You may use definitons created by the old DefineMonitor, but you'll get
1241 * better results with the new DefineMonitor supplied along with the Retin Z3.
1242 */
1243
1244 /*
1245 * FQ FLG MW MH HBS HSS HSE HBE HT VBS VSS VSE VBE VT
1246 * Depth, PAL, TX, TY, XY,FontX, FontY, FontData, FLo, Fhi
1247 */
1248 #ifdef KFONT_8X11
1249 #define KERNEL_FONT kernel_font_8x11
1250 #define FY 11
1251 #define FX 8
1252 #else
1253 #define KERNEL_FONT kernel_font_8x8
1254 #define FY 8
1255 #define FX 8
1256 #endif
1257
1258
1259 static struct MonDef monitor_defs[] = {
1260 /* Text-mode definitions */
1261
1262 /* horizontal 31.5 kHz */
1263 { 50000000, 28, 640, 512, 81, 86, 93, 98, 95, 513, 513, 521, 535, 535,
1264 4, RZ3StdPalette, 80, 64, 5120, FX, FY, KERNEL_FONT, 32, 255},
1265
1266 /* horizontal 38kHz */
1267 { 75000000, 28, 768, 600, 97, 99,107,120,117, 601, 615, 625, 638, 638,
1268 4, RZ3StdPalette, 96, 75, 7200, FX, FY, KERNEL_FONT, 32, 255},
1269
1270 /* horizontal 64kHz */
1271 { 50000000, 24, 768, 600, 97,104,112,122,119, 601, 606, 616, 628, 628,
1272 4, RZ3StdPalette, 96, 75, 7200, FX, FY, KERNEL_FONT, 32, 255},
1273
1274 /* 8-bit gfx-mode definitions */
1275
1276 /* IMPORTANT: the "logical" screen size can be up to 2048x2048 pixels,
1277 independent from the "physical" screen size. If your code does NOT
1278 support panning, please adjust the "logical" screen sizes below to
1279 match the physical ones
1280 */
1281
1282 #ifdef RH_HARDWARECURSOR
1283
1284 /* 640 x 480, 8 Bit, 31862 Hz, 63 Hz */
1285 { 26000000, 0, 640, 480, 161,175,188,200,199, 481, 483, 491, 502, 502,
1286 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1287 /* This is the logical ^ ^ screen size */
1288
1289 /* 640 x 480, 8 Bit, 38366 Hz, 76 Hz */
1290 { 31000000, 0, 640, 480, 161,169,182,198,197, 481, 482, 490, 502, 502,
1291 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1292
1293 /* 800 x 600, 8 Bit, 38537 Hz, 61 Hz */
1294 { 39000000, 0, 800, 600, 201,211,227,249,248, 601, 603, 613, 628, 628,
1295 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1296
1297 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1298 { 82000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1299 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1300
1301 /* 1120 x 896, 8 Bit, 64000 Hz, 69 Hz */
1302 { 97000000, 0, 1120, 896, 281,283,306,369,368, 897, 898, 913, 938, 938,
1303 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1304
1305 /* 1152 x 910, 8 Bit, 76177 Hz, 79 Hz */
1306 {110000000, 0, 1152, 910, 289,310,333,357,356, 911, 923, 938, 953, 953,
1307 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1308
1309 /* 1184 x 848, 8 Bit, 73529 Hz, 82 Hz */
1310 {110000000, 0, 1184, 848, 297,319,342,370,369, 849, 852, 866, 888, 888,
1311 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1312
1313 /* 1280 x 1024, 8 Bit, 64516 Hz, 60 Hz */
1314 {104000000, 0, 1280,1024, 321,323,348,399,398,1025,1026,1043,1073,1073,
1315 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1316
1317 /*
1318 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1319 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1320 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1321 */
1322 /* 1280 x 1024, 8 Bit, 75436 Hz, 70 Hz */
1323 {121000000, 0, 1280,1024, 321,322,347,397,396,1025,1026,1043,1073,1073,
1324 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1325
1326
1327 /* 16-bit gfx-mode definitions */
1328
1329 /* 640 x 480, 16 Bit, 31795 Hz, 63 Hz */
1330 { 51000000, 0, 640, 480, 321,344,369,397,396, 481, 482, 490, 502, 502,
1331 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1332
1333 /* 800 x 600, 16 Bit, 38500 Hz, 61 Hz */
1334 { 77000000, 0, 800, 600, 401,418,449,496,495, 601, 602, 612, 628, 628,
1335 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1336
1337 /* 1024 x 768, 16 Bit, 42768 Hz, 53 Hz */
1338 {110000000, 0, 1024, 768, 513,514,554,639,638, 769, 770, 783, 804, 804,
1339 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1340
1341 /* 864 x 648, 16 Bit, 50369 Hz, 74 Hz */
1342 {109000000, 0, 864, 648, 433,434,468,537,536, 649, 650, 661, 678, 678,
1343 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1344
1345 /*
1346 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1347 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1348 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1349 */
1350 /* 1024 x 768, 16 Bit, 48437 Hz, 60 Hz */
1351 {124000000, 0, 1024, 768, 513,537,577,636,635, 769, 770, 783, 804, 804,
1352 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1353
1354
1355 /* 24-bit gfx-mode definitions */
1356
1357 /* 320 x 200, 24 Bit, 35060 Hz, 83 Hz d */
1358 { 46000000, 1, 320, 200, 241,268,287,324,323, 401, 405, 412, 418, 418,
1359 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1360
1361 /* 640 x 400, 24 Bit, 31404 Hz, 75 Hz */
1362 { 76000000, 0, 640, 400, 481,514,552,601,600, 401, 402, 409, 418, 418,
1363 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1364
1365 /* 724 x 482, 24 Bit, 36969 Hz, 73 Hz */
1366 {101000000, 0, 724, 482, 544,576,619,682,678, 483, 487, 495, 495, 504,
1367 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1368
1369 /* 800 x 600, 24 Bit, 37826 Hz, 60 Hz */
1370 {110000000, 0, 800, 600, 601,602,647,723,722, 601, 602, 612, 628, 628,
1371 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1372
1373 /* 800 x 600, 24 Bit, 43824 Hz, 69 Hz */
1374 {132000000, 0, 800, 600, 601,641,688,749,748, 601, 611, 621, 628, 628,
1375 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1376
1377 /*1024 x 768, 24 Bit, 32051 Hz, 79 Hz i */
1378 {110000000, 2, 1024, 768, 769,770,824,854,853, 385, 386, 392, 401, 401,
1379 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1380
1381 #else /* RH_HARDWARECURSOR */
1382
1383 /* 640 x 480, 8 Bit, 31862 Hz, 63 Hz */
1384 { 26000000, 0, 640, 480, 161,175,188,200,199, 481, 483, 491, 502, 502,
1385 8, RZ3StdPalette, 640, 480, 5120, FX, FY, KERNEL_FONT, 32, 255},
1386 /* This is the logical ^ ^ screen size */
1387
1388 /* 640 x 480, 8 Bit, 38366 Hz, 76 Hz */
1389 { 31000000, 0, 640, 480, 161,169,182,198,197, 481, 482, 490, 502, 502,
1390 8, RZ3StdPalette, 640, 480, 5120, FX, FY, KERNEL_FONT, 32, 255},
1391
1392 /* 800 x 600, 8 Bit, 38537 Hz, 61 Hz */
1393 { 39000000, 0, 800, 600, 201,211,227,249,248, 601, 603, 613, 628, 628,
1394 8, RZ3StdPalette, 800, 600, 5120, FX, FY, KERNEL_FONT, 32, 255},
1395
1396 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1397 { 82000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1398 8, RZ3StdPalette, 1024, 768, 5120, FX, FY, KERNEL_FONT, 32, 255},
1399
1400 /* 1120 x 896, 8 Bit, 64000 Hz, 69 Hz */
1401 { 97000000, 0, 1120, 896, 281,283,306,369,368, 897, 898, 913, 938, 938,
1402 8, RZ3StdPalette, 1120, 896, 5120, FX, FY, KERNEL_FONT, 32, 255},
1403
1404 /* 1152 x 910, 8 Bit, 76177 Hz, 79 Hz */
1405 {110000000, 0, 1152, 910, 289,310,333,357,356, 911, 923, 938, 953, 953,
1406 8, RZ3StdPalette, 1152, 910, 5120, FX, FY, KERNEL_FONT, 32, 255},
1407
1408 /* 1184 x 848, 8 Bit, 73529 Hz, 82 Hz */
1409 {110000000, 0, 1184, 848, 297,319,342,370,369, 849, 852, 866, 888, 888,
1410 8, RZ3StdPalette, 1184, 848, 5120, FX, FY, KERNEL_FONT, 32, 255},
1411
1412 /* 1280 x 1024, 8 Bit, 64516 Hz, 60 Hz */
1413 {104000000, 0, 1280,1024, 321,323,348,399,398,1025,1026,1043,1073,1073,
1414 8, RZ3StdPalette, 1280, 1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1415
1416 /*
1417 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1418 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1419 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1420 */
1421 /* 1280 x 1024, 8 Bit, 75436 Hz, 70 Hz */
1422 {121000000, 0, 1280,1024, 321,322,347,397,396,1025,1026,1043,1073,1073,
1423 8, RZ3StdPalette, 1280, 1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1424
1425
1426 /* 16-bit gfx-mode definitions */
1427
1428 /* 640 x 480, 16 Bit, 31795 Hz, 63 Hz */
1429 { 51000000, 0, 640, 480, 321,344,369,397,396, 481, 482, 490, 502, 502,
1430 16, 0, 640, 480, 7200, FX, FY, KERNEL_FONT, 32, 255},
1431
1432 /* 800 x 600, 16 Bit, 38500 Hz, 61 Hz */
1433 { 77000000, 0, 800, 600, 401,418,449,496,495, 601, 602, 612, 628, 628,
1434 16, 0, 800, 600, 7200, FX, FY, KERNEL_FONT, 32, 255},
1435
1436 /* 1024 x 768, 16 Bit, 42768 Hz, 53 Hz */
1437 {110000000, 0, 1024, 768, 513,514,554,639,638, 769, 770, 783, 804, 804,
1438 16, 0, 1024, 768, 7200, FX, FY, KERNEL_FONT, 32, 255},
1439
1440 /* 864 x 648, 16 Bit, 50369 Hz, 74 Hz */
1441 {109000000, 0, 864, 648, 433,434,468,537,536, 649, 650, 661, 678, 678,
1442 16, 0, 864, 648, 7200, FX, FY, KERNEL_FONT, 32, 255},
1443
1444 /*
1445 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1446 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1447 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1448 */
1449 /* 1024 x 768, 16 Bit, 48437 Hz, 60 Hz */
1450 {124000000, 0, 1024, 768, 513,537,577,636,635, 769, 770, 783, 804, 804,
1451 16, 0, 1024, 768, 7200, FX, FY, KERNEL_FONT, 32, 255},
1452
1453
1454 /* 24-bit gfx-mode definitions */
1455
1456 /* 320 x 200, 24 Bit, 35060 Hz, 83 Hz d */
1457 { 46000000, 1, 320, 200, 241,268,287,324,323, 401, 405, 412, 418, 418,
1458 24, 0, 320, 200, 7200, FX, FY, KERNEL_FONT, 32, 255},
1459
1460 /* 640 x 400, 24 Bit, 31404 Hz, 75 Hz */
1461 { 76000000, 0, 640, 400, 481,514,552,601,600, 401, 402, 409, 418, 418,
1462 24, 0, 640, 400, 7200, FX, FY, KERNEL_FONT, 32, 255},
1463
1464 /* 724 x 482, 24 Bit, 36969 Hz, 73 Hz */
1465 {101000000, 0, 724, 482, 544,576,619,682,678, 483, 487, 495, 495, 504,
1466 24, 0, 724, 482, 7200, FX, FY, KERNEL_FONT, 32, 255},
1467
1468 /* 800 x 600, 24 Bit, 37826 Hz, 60 Hz */
1469 {110000000, 0, 800, 600, 601,602,647,723,722, 601, 602, 612, 628, 628,
1470 24, 0, 800, 600, 7200, FX, FY, KERNEL_FONT, 32, 255},
1471
1472 /* 800 x 600, 24 Bit, 43824 Hz, 69 Hz */
1473 {132000000, 0, 800, 600, 601,641,688,749,748, 601, 611, 621, 628, 628,
1474 24, 0, 800, 600, 7200, FX, FY, KERNEL_FONT, 32, 255},
1475
1476 /*1024 x 768, 24 Bit, 32051 Hz, 79 Hz i */
1477 {110000000, 2, 1024, 768, 769,770,824,854,853, 385, 386, 392, 401, 401,
1478 24, 0, 1024, 768, 7200, FX, FY, KERNEL_FONT, 32, 255},
1479
1480 #endif /* RH_HARDWARECURSOR */
1481 };
1482 #undef KERNEL_FONT
1483 #undef FX
1484 #undef FY
1485
1486 static const char *monitor_descr[] = {
1487 #ifdef KFONT_8X11
1488 "80x46 (640x506) 31.5kHz",
1489 "96x54 (768x594) 38kHz",
1490 "96x54 (768x594) 64kHz",
1491 #else
1492 "80x64 (640x512) 31.5kHz",
1493 "96x75 (768x600) 38kHz",
1494 "96x75 (768x600) 64kHz",
1495 #endif
1496
1497 "GFX-8 (640x480) 31.5kHz",
1498 "GFX-8 (640x480) 38kHz",
1499 "GFX-8 (800x600) 38.5kHz",
1500 "GFX-8 (1024x768) 64kHz",
1501 "GFX-8 (1120x896) 64kHz",
1502 "GFX-8 (1152x910) 76kHz",
1503 "GFX-8 (1182x848) 73kHz",
1504 "GFX-8 (1280x1024) 64.5kHz",
1505 "GFX-8 (1280x1024) 75.5kHz ***EXCEEDS CHIP LIMIT!!!***",
1506
1507 "GFX-16 (640x480) 31.8kHz",
1508 "GFX-16 (800x600) 38.5kHz",
1509 "GFX-16 (1024x768) 42.8kHz",
1510 "GFX-16 (864x648) 50kHz",
1511 "GFX-16 (1024x768) 48.5kHz ***EXCEEDS CHIP LIMIT!!!***",
1512
1513 "GFX-24 (320x200 d) 35kHz",
1514 "GFX-24 (640x400) 31.4kHz",
1515 "GFX-24 (724x482) 37kHz",
1516 "GFX-24 (800x600) 38kHz",
1517 "GFX-24 (800x600) 44kHz ***EXCEEDS CHIP LIMIT!!!***",
1518 "GFX-24 (1024x768) 32kHz-i",
1519 };
1520
1521 int rh_mon_max = sizeof (monitor_defs)/sizeof (monitor_defs[0]);
1522
1523 /* patchable */
1524 int rh_default_mon = 0;
1525 int rh_default_gfx = 4;
1526
1527 static struct MonDef *current_mon; /* EVIL */
1528
1529 int rh_mode __P((struct grf_softc *, u_long, void *, u_long, int));
1530 void grfrhattach __P((struct device *, struct device *, void *));
1531 int grfrhprint __P((void *, const char *));
1532 int grfrhmatch __P((struct device *, struct cfdata *, void *));
1533
1534 struct cfattach grfrh_ca = {
1535 sizeof(struct grf_softc), grfrhmatch, grfrhattach
1536 };
1537
1538 static struct cfdata *cfdata;
1539
1540 int
1541 grfrhmatch(pdp, cfp, auxp)
1542 struct device *pdp;
1543 struct cfdata *cfp;
1544 void *auxp;
1545 {
1546 #ifdef RETINACONSOLE
1547 static int rhconunit = -1;
1548 #endif
1549 struct zbus_args *zap;
1550
1551 zap = auxp;
1552
1553 if (amiga_realconfig == 0)
1554 #ifdef RETINACONSOLE
1555 if (rhconunit != -1)
1556 #endif
1557 return(0);
1558 if (zap->manid != 18260 ||
1559 ((zap->prodid != 16) && (zap->prodid != 19)))
1560 return(0);
1561 #ifdef RETINACONSOLE
1562 if (amiga_realconfig == 0 || rhconunit != cfp->cf_unit) {
1563 #endif
1564 if ((unsigned)rh_default_mon >= rh_mon_max ||
1565 monitor_defs[rh_default_mon].DEP == 8)
1566 rh_default_mon = 0;
1567 current_mon = monitor_defs + rh_default_mon;
1568 if (rh_mondefok(current_mon) == 0)
1569 return(0);
1570 #ifdef RETINACONSOLE
1571 if (amiga_realconfig == 0) {
1572 rhconunit = cfp->cf_unit;
1573 cfdata = cfp;
1574 }
1575 }
1576 #endif
1577 return(1);
1578 }
1579
1580 void
1581 grfrhattach(pdp, dp, auxp)
1582 struct device *pdp, *dp;
1583 void *auxp;
1584 {
1585 static struct grf_softc congrf;
1586 struct zbus_args *zap;
1587 struct grf_softc *gp;
1588
1589 zap = auxp;
1590
1591 if (dp == NULL)
1592 gp = &congrf;
1593 else
1594 gp = (struct grf_softc *)dp;
1595 if (dp != NULL && congrf.g_regkva != 0) {
1596 /*
1597 * inited earlier, just copy (not device struct)
1598 */
1599 bcopy(&congrf.g_display, &gp->g_display,
1600 (char *)&gp[1] - (char *)&gp->g_display);
1601 } else {
1602 gp->g_regkva = (volatile caddr_t)zap->va;
1603 gp->g_fbkva = (volatile caddr_t)zap->va + LM_OFFSET;
1604 gp->g_unit = GRF_RETINAIII_UNIT;
1605 gp->g_mode = rh_mode;
1606 gp->g_conpri = grfrh_cnprobe();
1607 gp->g_flags = GF_ALIVE;
1608 grfrh_iteinit(gp);
1609 (void)rh_load_mon(gp, current_mon);
1610 }
1611 if (dp != NULL)
1612 printf("\n");
1613 /*
1614 * attach grf
1615 */
1616 amiga_config_found(cfdata, &gp->g_device, gp, grfrhprint);
1617 }
1618
1619 int
1620 grfrhprint(auxp, pnp)
1621 void *auxp;
1622 const char *pnp;
1623 {
1624 if (pnp)
1625 printf("ite at %s", pnp);
1626 return(UNCONF);
1627 }
1628
1629 int
1630 rh_getvmode(gp, vm)
1631 struct grf_softc *gp;
1632 struct grfvideo_mode *vm;
1633 {
1634 struct MonDef *md;
1635 int vmul;
1636
1637 if (vm->mode_num && vm->mode_num > rh_mon_max)
1638 return(EINVAL);
1639
1640 if (! vm->mode_num)
1641 vm->mode_num = (current_mon - monitor_defs) + 1;
1642
1643 md = monitor_defs + (vm->mode_num - 1);
1644 strncpy (vm->mode_descr, monitor_descr[vm->mode_num - 1],
1645 sizeof (vm->mode_descr));
1646 vm->pixel_clock = md->FQ;
1647 vm->disp_width = (md->DEP == 4) ? md->MW : md->TX;
1648 vm->disp_height = (md->DEP == 4) ? md->MH : md->TY;
1649 vm->depth = md->DEP;
1650
1651 /*
1652 * From observation of the monitor definition table above, I guess
1653 * that the horizontal timings are in units of longwords. Hence, I
1654 * get the pixels by multiplication with 32 and division by the depth.
1655 * The text modes, apparently marked by depth == 4, are even more
1656 * wierd. According to a comment above, they are computed from a
1657 * depth==8 mode thats for us: * 32 / 8) by applying another factor
1658 * of 4 / font width.
1659 * Reverse applying the latter formula most of the constants cancel
1660 * themselves and we are left with a nice (* font width).
1661 * That is, internal timings are in units of longwords for graphics
1662 * modes, or in units of characters widths for text modes.
1663 * We better don't WRITE modes until this has been real live checked.
1664 * - Ignatios Souvatzis
1665 */
1666
1667 if (md->DEP != 4) {
1668 vm->hblank_start = md->HBS * 32 / md->DEP;
1669 vm->hsync_start = md->HSS * 32 / md->DEP;
1670 vm->hsync_stop = md->HSE * 32 / md->DEP;
1671 vm->htotal = md->HT * 32 / md->DEP;
1672 } else {
1673 vm->hblank_start = md->HBS * md->FX;
1674 vm->hsync_start = md->HSS * md->FX;
1675 vm->hsync_stop = md->HSE * md->FX;
1676 vm->htotal = md->HT * md->FX;
1677 }
1678
1679 /* XXX move vm->disp_flags and vmul to rh_load_mon
1680 * if rh_setvmode can add new modes with grfconfig */
1681 vm->disp_flags = 0;
1682 vmul = 2;
1683 if (md->FLG & MDF_DBL) {
1684 vm->disp_flags |= GRF_FLAGS_DBLSCAN;
1685 vmul = 4;
1686 }
1687 if (md->FLG & MDF_LACE) {
1688 vm->disp_flags |= GRF_FLAGS_LACE;
1689 vmul = 1;
1690 }
1691 vm->vblank_start = md->VBS * vmul / 2;
1692 vm->vsync_start = md->VSS * vmul / 2;
1693 vm->vsync_stop = md->VSE * vmul / 2;
1694 vm->vtotal = md->VT * vmul / 2;
1695
1696 return(0);
1697 }
1698
1699
1700 int
1701 rh_setvmode(gp, mode, type)
1702 struct grf_softc *gp;
1703 unsigned mode;
1704 enum mode_type type;
1705 {
1706 int error;
1707
1708 if (!mode || mode > rh_mon_max)
1709 return(EINVAL);
1710
1711 if ((type == MT_TXTONLY && monitor_defs[mode-1].DEP != 4)
1712 || (type == MT_GFXONLY && monitor_defs[mode-1].DEP == 4))
1713 return(EINVAL);
1714
1715 current_mon = monitor_defs + (mode - 1);
1716
1717 error = rh_load_mon (gp, current_mon) ? 0 : EINVAL;
1718
1719 return(error);
1720 }
1721
1722
1723 /*
1724 * Change the mode of the display.
1725 * Return a UNIX error number or 0 for success.
1726 */
1727 int
1728 rh_mode(gp, cmd, arg, a2, a3)
1729 register struct grf_softc *gp;
1730 u_long cmd;
1731 void *arg;
1732 u_long a2;
1733 int a3;
1734 {
1735 switch (cmd) {
1736 case GM_GRFON:
1737 rh_setvmode (gp, rh_default_gfx + 1, MT_GFXONLY);
1738 return(0);
1739
1740 case GM_GRFOFF:
1741 rh_setvmode (gp, rh_default_mon + 1, MT_TXTONLY);
1742 return(0);
1743
1744 case GM_GRFCONFIG:
1745 return(0);
1746
1747 case GM_GRFGETVMODE:
1748 return(rh_getvmode (gp, (struct grfvideo_mode *) arg));
1749
1750 case GM_GRFSETVMODE:
1751 return(rh_setvmode (gp, *(unsigned *) arg,
1752 (gp->g_flags & GF_GRFON) ? MT_GFXONLY : MT_TXTONLY));
1753
1754 case GM_GRFGETNUMVM:
1755 *(int *)arg = rh_mon_max;
1756 return(0);
1757
1758 #ifdef BANKEDDEVPAGER
1759 case GM_GRFGETBANK:
1760 case GM_GRFGETCURBANK:
1761 case GM_GRFSETBANK:
1762 return(EINVAL);
1763 #endif
1764 case GM_GRFIOCTL:
1765 return(rh_ioctl (gp, a2, arg));
1766
1767 default:
1768 break;
1769 }
1770
1771 return(EINVAL);
1772 }
1773
1774 int
1775 rh_ioctl (gp, cmd, data)
1776 register struct grf_softc *gp;
1777 u_long cmd;
1778 void *data;
1779 {
1780 switch (cmd) {
1781 #ifdef RH_HARDWARECURSOR
1782 case GRFIOCGSPRITEPOS:
1783 return(rh_getspritepos (gp, (struct grf_position *) data));
1784
1785 case GRFIOCSSPRITEPOS:
1786 return(rh_setspritepos (gp, (struct grf_position *) data));
1787
1788 case GRFIOCSSPRITEINF:
1789 return(rh_setspriteinfo (gp, (struct grf_spriteinfo *) data));
1790
1791 case GRFIOCGSPRITEINF:
1792 return(rh_getspriteinfo (gp, (struct grf_spriteinfo *) data));
1793
1794 case GRFIOCGSPRITEMAX:
1795 return(rh_getspritemax (gp, (struct grf_position *) data));
1796 #else /* RH_HARDWARECURSOR */
1797 case GRFIOCGSPRITEPOS:
1798 case GRFIOCSSPRITEPOS:
1799 case GRFIOCSSPRITEINF:
1800 case GRFIOCGSPRITEMAX:
1801 break;
1802 #endif /* RH_HARDWARECURSOR */
1803
1804 case GRFIOCGETCMAP:
1805 return(rh_getcmap (gp, (struct grf_colormap *) data));
1806
1807 case GRFIOCPUTCMAP:
1808 return(rh_putcmap (gp, (struct grf_colormap *) data));
1809
1810 case GRFIOCBITBLT:
1811 return(rh_bitblt (gp, (struct grf_bitblt *) data));
1812
1813 case GRFIOCBLANK:
1814 return (rh_blank(gp, (int *)data));
1815 }
1816
1817 return(EINVAL);
1818 }
1819
1820
1821 int
1822 rh_getcmap (gfp, cmap)
1823 struct grf_softc *gfp;
1824 struct grf_colormap *cmap;
1825 {
1826 volatile unsigned char *ba;
1827 u_char red[256], green[256], blue[256], *rp, *gp, *bp;
1828 short x;
1829 int error;
1830
1831 if (cmap->count == 0 || cmap->index >= 256)
1832 return 0;
1833
1834 if (cmap->index + cmap->count > 256)
1835 cmap->count = 256 - cmap->index;
1836
1837 ba = gfp->g_regkva;
1838 /* first read colors out of the chip, then copyout to userspace */
1839 vgaw (ba, VDAC_ADDRESS_W, cmap->index);
1840 x = cmap->count - 1;
1841 rp = red + cmap->index;
1842 gp = green + cmap->index;
1843 bp = blue + cmap->index;
1844 do {
1845 *rp++ = vgar (ba, VDAC_DATA) << 2;
1846 *gp++ = vgar (ba, VDAC_DATA) << 2;
1847 *bp++ = vgar (ba, VDAC_DATA) << 2;
1848 } while (x-- > 0);
1849
1850 if (!(error = copyout (red + cmap->index, cmap->red, cmap->count))
1851 && !(error = copyout (green + cmap->index, cmap->green, cmap->count))
1852 && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count)))
1853 return(0);
1854
1855 return(error);
1856 }
1857
1858 int
1859 rh_putcmap (gfp, cmap)
1860 struct grf_softc *gfp;
1861 struct grf_colormap *cmap;
1862 {
1863 volatile unsigned char *ba;
1864 u_char red[256], green[256], blue[256], *rp, *gp, *bp;
1865 short x;
1866 int error;
1867
1868 if (cmap->count == 0 || cmap->index >= 256)
1869 return(0);
1870
1871 if (cmap->index + cmap->count > 256)
1872 cmap->count = 256 - cmap->index;
1873
1874 /* first copy the colors into kernelspace */
1875 if (!(error = copyin (cmap->red, red + cmap->index, cmap->count))
1876 && !(error = copyin (cmap->green, green + cmap->index, cmap->count))
1877 && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count))) {
1878 /* argl.. LoadPalette wants a different format, so do it like with
1879 * Retina2.. */
1880 ba = gfp->g_regkva;
1881 vgaw (ba, VDAC_ADDRESS_W, cmap->index);
1882 x = cmap->count - 1;
1883 rp = red + cmap->index;
1884 gp = green + cmap->index;
1885 bp = blue + cmap->index;
1886 do {
1887 vgaw (ba, VDAC_DATA, *rp++ >> 2);
1888 vgaw (ba, VDAC_DATA, *gp++ >> 2);
1889 vgaw (ba, VDAC_DATA, *bp++ >> 2);
1890 } while (x-- > 0);
1891 return(0);
1892 }
1893 else
1894 return(error);
1895 }
1896
1897 int
1898 rh_getspritepos (gp, pos)
1899 struct grf_softc *gp;
1900 struct grf_position *pos;
1901 {
1902 struct grfinfo *gi = &gp->g_display;
1903 #if 1
1904 volatile unsigned char *ba = gp->g_regkva;
1905
1906 pos->x = (RSeq(ba, SEQ_ID_CURSOR_X_LOC_HI) << 8) |
1907 RSeq(ba, SEQ_ID_CURSOR_X_LOC_LO);
1908 pos->y = (RSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI) << 8) |
1909 RSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO);
1910 #else
1911 volatile unsigned char *acm = gp->g_regkva + ACM_OFFSET;
1912
1913 pos->x = acm[ACM_CURSOR_POSITION + 0] +
1914 (acm[ACM_CURSOR_POSITION + 1] << 8);
1915 pos->y = acm[ACM_CURSOR_POSITION + 2] +
1916 (acm[ACM_CURSOR_POSITION + 3] << 8);
1917 #endif
1918 pos->x += gi->gd_fbx;
1919 pos->y += gi->gd_fby;
1920
1921 return(0);
1922 }
1923
1924 int
1925 rh_setspritepos (gp, pos)
1926 struct grf_softc *gp;
1927 struct grf_position *pos;
1928 {
1929 RZ3SetHWCloc (gp, pos->x, pos->y);
1930 return(0);
1931 }
1932
1933 int
1934 rh_getspriteinfo (gp, info)
1935 struct grf_softc *gp;
1936 struct grf_spriteinfo *info;
1937 {
1938 volatile unsigned char *ba, *fb;
1939
1940 ba = gp->g_regkva;
1941 fb = gp->g_fbkva;
1942 if (info->set & GRFSPRSET_ENABLE)
1943 info->enable = RSeq (ba, SEQ_ID_CURSOR_CONTROL) & 0x01;
1944 if (info->set & GRFSPRSET_POS)
1945 rh_getspritepos (gp, &info->pos);
1946 if (info->set & GRFSPRSET_HOT) {
1947 info->hot.x = RSeq (ba, SEQ_ID_CURSOR_X_INDEX) & 0x3f;
1948 info->hot.y = RSeq (ba, SEQ_ID_CURSOR_Y_INDEX) & 0x7f;
1949 }
1950 if (info->set & GRFSPRSET_CMAP) {
1951 struct grf_colormap cmap;
1952 int index;
1953 cmap.index = 0;
1954 cmap.count = 256;
1955 rh_getcmap (gp, &cmap);
1956 index = RSeq (ba, SEQ_ID_CURSOR_COLOR0);
1957 info->cmap.red[0] = cmap.red[index];
1958 info->cmap.green[0] = cmap.green[index];
1959 info->cmap.blue[0] = cmap.blue[index];
1960 index = RSeq (ba, SEQ_ID_CURSOR_COLOR1);
1961 info->cmap.red[1] = cmap.red[index];
1962 info->cmap.green[1] = cmap.green[index];
1963 info->cmap.blue[1] = cmap.blue[index];
1964 }
1965 if (info->set & GRFSPRSET_SHAPE) {
1966 u_char image[128], mask[128];
1967 volatile u_long *hwp;
1968 u_char *imp, *mp;
1969 short row;
1970
1971 /* sprite bitmap is WEIRD in this chip.. see grf_rhvar.h
1972 * for an explanation. To convert to "our" format, the
1973 * following holds:
1974 * col2 = !image & mask
1975 * col1 = image & mask
1976 * transp = !mask
1977 * and thus:
1978 * image = col1
1979 * mask = col1 | col2
1980 * hope I got these bool-eqs right below..
1981 */
1982
1983 #ifdef RH_64BIT_SPRITE
1984 info->size.x = 64;
1985 info->size.y = 64;
1986 for (row = 0, hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF),
1987 mp = mask, imp = image;
1988 row < 64;
1989 row++) {
1990 u_long bp10, bp20, bp11, bp21;
1991 bp10 = *hwp++;
1992 bp20 = *hwp++;
1993 bp11 = *hwp++;
1994 bp21 = *hwp++;
1995 M2I (bp10);
1996 M2I (bp20);
1997 M2I (bp11);
1998 M2I (bp21);
1999 *imp++ = (~bp10) & bp11;
2000 *imp++ = (~bp20) & bp21;
2001 *mp++ = (~bp10) | (bp10 & ~bp11);
2002 *mp++ = (~bp20) & (bp20 & ~bp21);
2003 }
2004 #else
2005 info->size.x = 32;
2006 info->size.y = 32;
2007 for (row = 0, hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF),
2008 mp = mask, imp = image;
2009 row < 32;
2010 row++) {
2011 u_long bp10, bp11;
2012 bp10 = *hwp++;
2013 bp11 = *hwp++;
2014 M2I (bp10);
2015 M2I (bp11);
2016 *imp++ = (~bp10) & bp11;
2017 *mp++ = (~bp10) | (bp10 & ~bp11);
2018 }
2019 #endif
2020 copyout (image, info->image, sizeof (image));
2021 copyout (mask, info->mask, sizeof (mask));
2022 }
2023 return(0);
2024 }
2025
2026 int
2027 rh_setspriteinfo (gp, info)
2028 struct grf_softc *gp;
2029 struct grf_spriteinfo *info;
2030 {
2031 volatile unsigned char *ba, *fb;
2032 #if 0
2033 u_char control;
2034 #endif
2035
2036 ba = gp->g_regkva;
2037 fb = gp->g_fbkva;
2038
2039 if (info->set & GRFSPRSET_SHAPE) {
2040 /*
2041 * For an explanation of these weird actions here, see above
2042 * when reading the shape. We set the shape directly into
2043 * the video memory, there's no reason to keep 1k on the
2044 * kernel stack just as template
2045 */
2046 u_char *image, *mask;
2047 volatile u_long *hwp;
2048 u_char *imp, *mp;
2049 short row;
2050
2051 #ifdef RH_64BIT_SPRITE
2052 if (info->size.y > 64)
2053 info->size.y = 64;
2054 if (info->size.x > 64)
2055 info->size.x = 64;
2056 #else
2057 if (info->size.y > 32)
2058 info->size.y = 32;
2059 if (info->size.x > 32)
2060 info->size.x = 32;
2061 #endif
2062
2063 if (info->size.x < 32)
2064 info->size.x = 32;
2065
2066 image = malloc(HWC_MEM_SIZE, M_TEMP, M_WAITOK);
2067 mask = image + HWC_MEM_SIZE/2;
2068
2069 copyin(info->image, image, info->size.y * info->size.x / 8);
2070 copyin(info->mask, mask, info->size.y * info->size.x / 8);
2071
2072 hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF);
2073
2074 /*
2075 * setting it is slightly more difficult, because we can't
2076 * force the application to not pass a *smaller* than
2077 * supported bitmap
2078 */
2079
2080 for (row = 0, mp = mask, imp = image;
2081 row < info->size.y;
2082 row++) {
2083 u_long im1, im2, m1, m2;
2084
2085 im1 = *(unsigned long *)imp;
2086 imp += 4;
2087 m1 = *(unsigned long *)mp;
2088 mp += 4;
2089 #ifdef RH_64BIT_SPRITE
2090 if (info->size.x > 32) {
2091 im2 = *(unsigned long *)imp;
2092 imp += 4;
2093 m2 = *(unsigned long *)mp;
2094 mp += 4;
2095 }
2096 else
2097 #endif
2098 im2 = m2 = 0;
2099
2100 M2I(im1);
2101 M2I(im2);
2102 M2I(m1);
2103 M2I(m2);
2104
2105 *hwp++ = ~m1;
2106 #ifdef RH_64BIT_SPRITE
2107 *hwp++ = ~m2;
2108 #endif
2109 *hwp++ = m1 & im1;
2110 #ifdef RH_64BIT_SPRITE
2111 *hwp++ = m2 & im2;
2112 #endif
2113 }
2114 #ifdef RH_64BIT_SPRITE
2115 for (; row < 64; row++) {
2116 *hwp++ = 0xffffffff;
2117 *hwp++ = 0xffffffff;
2118 *hwp++ = 0x00000000;
2119 *hwp++ = 0x00000000;
2120 }
2121 #else
2122 for (; row < 32; row++) {
2123 *hwp++ = 0xffffffff;
2124 *hwp++ = 0x00000000;
2125 }
2126 #endif
2127
2128 free(image, M_TEMP);
2129 RZ3SetupHWC(gp, 1, 0, 0, 0, 0);
2130 }
2131 if (info->set & GRFSPRSET_CMAP) {
2132 /* hey cheat a bit here.. XXX */
2133 WSeq(ba, SEQ_ID_CURSOR_COLOR0, 0);
2134 WSeq(ba, SEQ_ID_CURSOR_COLOR1, 1);
2135 }
2136 if (info->set & GRFSPRSET_ENABLE) {
2137 #if 0
2138 if (info->enable)
2139 control = 0x85;
2140 else
2141 control = 0;
2142 WSeq(ba, SEQ_ID_CURSOR_CONTROL, control);
2143 #endif
2144 }
2145 if (info->set & GRFSPRSET_POS)
2146 rh_setspritepos(gp, &info->pos);
2147 if (info->set & GRFSPRSET_HOT) {
2148 WSeq(ba, SEQ_ID_CURSOR_X_INDEX, info->hot.x & 0x3f);
2149 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, info->hot.y & 0x7f);
2150 }
2151
2152 return(0);
2153 }
2154
2155 int
2156 rh_getspritemax (gp, pos)
2157 struct grf_softc *gp;
2158 struct grf_position *pos;
2159 {
2160 #ifdef RH_64BIT_SPRITE
2161 pos->x = 64;
2162 pos->y = 64;
2163 #else
2164 pos->x = 32;
2165 pos->y = 32;
2166 #endif
2167
2168 return(0);
2169 }
2170
2171
2172 int
2173 rh_bitblt (gp, bb)
2174 struct grf_softc *gp;
2175 struct grf_bitblt *bb;
2176 {
2177 struct MonDef *md = (struct MonDef *)gp->g_data;
2178 if (md->DEP <= 8)
2179 RZ3BitBlit(gp, bb);
2180 else if (md->DEP <= 16)
2181 RZ3BitBlit16(gp, bb);
2182 else
2183 RZ3BitBlit24(gp, bb);
2184
2185 return(0);
2186 }
2187
2188
2189 int
2190 rh_blank(gp, on)
2191 struct grf_softc *gp;
2192 int *on;
2193 {
2194 struct MonDef *md = (struct MonDef *)gp->g_data;
2195 int r;
2196
2197 r = 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8);
2198
2199 WSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE, *on > 0 ? r : 0x21);
2200
2201 return(0);
2202 }
2203
2204 #endif /* NGRF */
2205