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