grf_rh.c revision 1.57 1 /* $NetBSD: grf_rh.c,v 1.57 2014/01/22 00:25:16 christos 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.57 2014/01/22 00:25:16 christos 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(device_t, device_t, void *);
1533 int grfrhprint(void *, const char *);
1534 int grfrhmatch(device_t, cfdata_t, void *);
1535
1536 CFATTACH_DECL_NEW(grfrh, sizeof(struct grf_softc),
1537 grfrhmatch, grfrhattach, NULL, NULL);
1538
1539 static struct cfdata *cfdata;
1540
1541 int
1542 grfrhmatch(device_t parent, cfdata_t cf, void *aux)
1543 {
1544 #ifdef RETINACONSOLE
1545 static int rhconunit = -1;
1546 #endif
1547 struct zbus_args *zap;
1548
1549 zap = aux;
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 != cf->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 = cf->cf_unit;
1571 cfdata = cf;
1572 }
1573 }
1574 #endif
1575 return(1);
1576 }
1577
1578 void
1579 grfrhattach(device_t parent, device_t self, void *aux)
1580 {
1581 static struct grf_softc congrf;
1582 struct device temp;
1583 struct zbus_args *zap;
1584 struct grf_softc *gp;
1585
1586 zap = aux;
1587
1588 if (self == NULL) {
1589 gp = &congrf;
1590 gp->g_device = &temp;
1591 temp.dv_private = gp;
1592 } else {
1593 gp = device_private(self);
1594 gp->g_device = self;
1595 }
1596
1597 if (self != NULL && congrf.g_regkva != 0) {
1598 /*
1599 * inited earlier, just copy (not device struct)
1600 */
1601 memcpy(&gp->g_display, &congrf.g_display,
1602 (char *)&gp[1] - (char *)&gp->g_display);
1603 } else {
1604 gp->g_regkva = (volatile void *)zap->va;
1605 gp->g_fbkva = (volatile char *)zap->va + LM_OFFSET;
1606 gp->g_unit = GRF_RETINAIII_UNIT;
1607 gp->g_mode = rh_mode;
1608 gp->g_flags = GF_ALIVE;
1609 #if NITE > 0
1610 gp->g_conpri = grfrh_cnprobe();
1611 grfrh_iteinit(gp);
1612 #endif
1613 (void)rh_load_mon(gp, current_mon);
1614 }
1615 if (self != NULL)
1616 printf("\n");
1617 /*
1618 * attach grf
1619 */
1620 amiga_config_found(cfdata, gp->g_device, gp, grfrhprint);
1621 }
1622
1623 int
1624 grfrhprint(void *aux, const char *pnp)
1625 {
1626 if (pnp)
1627 aprint_normal("ite at %s", pnp);
1628 return(UNCONF);
1629 }
1630
1631 int
1632 rh_getvmode(struct grf_softc *gp, 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 * weird. 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(struct grf_softc *gp, unsigned mode, enum mode_type type)
1702 {
1703 int error;
1704
1705 if (!mode || mode > rh_mon_max)
1706 return(EINVAL);
1707
1708 if ((type == MT_TXTONLY && monitor_defs[mode-1].DEP != 4)
1709 || (type == MT_GFXONLY && monitor_defs[mode-1].DEP == 4))
1710 return(EINVAL);
1711
1712 current_mon = monitor_defs + (mode - 1);
1713
1714 error = rh_load_mon (gp, current_mon) ? 0 : EINVAL;
1715
1716 return(error);
1717 }
1718
1719
1720 /*
1721 * Change the mode of the display.
1722 * Return a UNIX error number or 0 for success.
1723 */
1724 int
1725 rh_mode(register struct grf_softc *gp, u_long cmd, void *arg, u_long a2,
1726 int a3)
1727 {
1728 switch (cmd) {
1729 case GM_GRFON:
1730 rh_setvmode (gp, rh_default_gfx + 1, MT_GFXONLY);
1731 return(0);
1732
1733 case GM_GRFOFF:
1734 rh_setvmode (gp, rh_default_mon + 1, MT_TXTONLY);
1735 return(0);
1736
1737 case GM_GRFCONFIG:
1738 return(0);
1739
1740 case GM_GRFGETVMODE:
1741 return(rh_getvmode (gp, (struct grfvideo_mode *) arg));
1742
1743 case GM_GRFSETVMODE:
1744 return(rh_setvmode(gp, *(unsigned *) arg,
1745 (gp->g_flags & GF_GRFON) ? MT_GFXONLY : MT_TXTONLY));
1746
1747 case GM_GRFGETNUMVM:
1748 *(int *)arg = rh_mon_max;
1749 return(0);
1750
1751 case GM_GRFIOCTL:
1752 return(rh_ioctl (gp, a2, arg));
1753
1754 default:
1755 break;
1756 }
1757
1758 return(EPASSTHROUGH);
1759 }
1760
1761 int
1762 rh_ioctl(register struct grf_softc *gp, u_long cmd, void *data)
1763 {
1764 switch (cmd) {
1765 #ifdef RH_HARDWARECURSOR
1766 case GRFIOCGSPRITEPOS:
1767 return(rh_getspritepos (gp, (struct grf_position *) data));
1768
1769 case GRFIOCSSPRITEPOS:
1770 return(rh_setspritepos (gp, (struct grf_position *) data));
1771
1772 case GRFIOCSSPRITEINF:
1773 return(rh_setspriteinfo (gp, (struct grf_spriteinfo *) data));
1774
1775 case GRFIOCGSPRITEINF:
1776 return(rh_getspriteinfo (gp, (struct grf_spriteinfo *) data));
1777
1778 case GRFIOCGSPRITEMAX:
1779 return(rh_getspritemax (gp, (struct grf_position *) data));
1780 #else /* RH_HARDWARECURSOR */
1781 case GRFIOCGSPRITEPOS:
1782 case GRFIOCSSPRITEPOS:
1783 case GRFIOCSSPRITEINF:
1784 case GRFIOCGSPRITEMAX:
1785 break;
1786 #endif /* RH_HARDWARECURSOR */
1787
1788 case GRFIOCGETCMAP:
1789 return(rh_getcmap (gp, (struct grf_colormap *) data));
1790
1791 case GRFIOCPUTCMAP:
1792 return(rh_putcmap (gp, (struct grf_colormap *) data));
1793
1794 case GRFIOCBITBLT:
1795 return(rh_bitblt (gp, (struct grf_bitblt *) data));
1796
1797 case GRFIOCBLANK:
1798 return (rh_blank(gp, (int *)data));
1799 }
1800
1801 return(EPASSTHROUGH);
1802 }
1803
1804
1805 int
1806 rh_getcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
1807 {
1808 volatile unsigned char *ba;
1809 u_char red[256], green[256], blue[256], *rp, *gp, *bp;
1810 short x;
1811 int error;
1812
1813 if (cmap->count == 0 || cmap->index >= 256)
1814 return 0;
1815
1816 if (cmap->count > 256 - cmap->index)
1817 cmap->count = 256 - cmap->index;
1818
1819 ba = gfp->g_regkva;
1820 /* first read colors out of the chip, then copyout to userspace */
1821 vgaw (ba, VDAC_ADDRESS_W, cmap->index);
1822 x = cmap->count - 1;
1823 rp = red + cmap->index;
1824 gp = green + cmap->index;
1825 bp = blue + cmap->index;
1826 do {
1827 *rp++ = vgar (ba, VDAC_DATA) << 2;
1828 *gp++ = vgar (ba, VDAC_DATA) << 2;
1829 *bp++ = vgar (ba, VDAC_DATA) << 2;
1830 } while (x-- > 0);
1831
1832 if (!(error = copyout (red + cmap->index, cmap->red, cmap->count))
1833 && !(error = copyout (green + cmap->index, cmap->green, cmap->count))
1834 && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count)))
1835 return(0);
1836
1837 return(error);
1838 }
1839
1840 int
1841 rh_putcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
1842 {
1843 volatile unsigned char *ba;
1844 u_char red[256], green[256], blue[256], *rp, *gp, *bp;
1845 short x;
1846 int error;
1847
1848 if (cmap->count == 0 || cmap->index >= 256)
1849 return(0);
1850
1851 if (cmap->count > 256 - cmap->index)
1852 cmap->count = 256 - cmap->index;
1853
1854 /* first copy the colors into kernelspace */
1855 if (!(error = copyin (cmap->red, red + cmap->index, cmap->count))
1856 && !(error = copyin (cmap->green, green + cmap->index, cmap->count))
1857 && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count))) {
1858 /* argl.. LoadPalette wants a different format, so do it like with
1859 * Retina2.. */
1860 ba = gfp->g_regkva;
1861 vgaw (ba, VDAC_ADDRESS_W, cmap->index);
1862 x = cmap->count - 1;
1863 rp = red + cmap->index;
1864 gp = green + cmap->index;
1865 bp = blue + cmap->index;
1866 do {
1867 vgaw (ba, VDAC_DATA, *rp++ >> 2);
1868 vgaw (ba, VDAC_DATA, *gp++ >> 2);
1869 vgaw (ba, VDAC_DATA, *bp++ >> 2);
1870 } while (x-- > 0);
1871 return(0);
1872 }
1873 else
1874 return(error);
1875 }
1876
1877 int
1878 rh_getspritepos(struct grf_softc *gp, struct grf_position *pos)
1879 {
1880 struct grfinfo *gi = &gp->g_display;
1881 #if 1
1882 volatile unsigned char *ba = gp->g_regkva;
1883
1884 pos->x = (RSeq(ba, SEQ_ID_CURSOR_X_LOC_HI) << 8) |
1885 RSeq(ba, SEQ_ID_CURSOR_X_LOC_LO);
1886 pos->y = (RSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI) << 8) |
1887 RSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO);
1888 #else
1889 volatile unsigned char *acm = gp->g_regkva + ACM_OFFSET;
1890
1891 pos->x = acm[ACM_CURSOR_POSITION + 0] +
1892 (acm[ACM_CURSOR_POSITION + 1] << 8);
1893 pos->y = acm[ACM_CURSOR_POSITION + 2] +
1894 (acm[ACM_CURSOR_POSITION + 3] << 8);
1895 #endif
1896 pos->x += gi->gd_fbx;
1897 pos->y += gi->gd_fby;
1898
1899 return(0);
1900 }
1901
1902 int
1903 rh_setspritepos (struct grf_softc *gp, struct grf_position *pos)
1904 {
1905 RZ3SetHWCloc (gp, pos->x, pos->y);
1906 return(0);
1907 }
1908
1909 int
1910 rh_getspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *info)
1911 {
1912 volatile unsigned char *ba;
1913
1914 ba = gp->g_regkva;
1915 if (info->set & GRFSPRSET_ENABLE)
1916 info->enable = RSeq (ba, SEQ_ID_CURSOR_CONTROL) & 0x01;
1917 if (info->set & GRFSPRSET_POS)
1918 rh_getspritepos (gp, &info->pos);
1919 if (info->set & GRFSPRSET_HOT) {
1920 info->hot.x = RSeq (ba, SEQ_ID_CURSOR_X_INDEX) & 0x3f;
1921 info->hot.y = RSeq (ba, SEQ_ID_CURSOR_Y_INDEX) & 0x7f;
1922 }
1923 if (info->set & GRFSPRSET_CMAP) {
1924 struct grf_colormap cmap;
1925 int index;
1926 cmap.index = 0;
1927 cmap.count = 256;
1928 rh_getcmap (gp, &cmap);
1929 index = RSeq (ba, SEQ_ID_CURSOR_COLOR0);
1930 info->cmap.red[0] = cmap.red[index];
1931 info->cmap.green[0] = cmap.green[index];
1932 info->cmap.blue[0] = cmap.blue[index];
1933 index = RSeq (ba, SEQ_ID_CURSOR_COLOR1);
1934 info->cmap.red[1] = cmap.red[index];
1935 info->cmap.green[1] = cmap.green[index];
1936 info->cmap.blue[1] = cmap.blue[index];
1937 }
1938 if (info->set & GRFSPRSET_SHAPE) {
1939 u_char image[128], mask[128];
1940 volatile u_long *hwp;
1941 u_char *imp, *mp;
1942 short row;
1943
1944 /* sprite bitmap is WEIRD in this chip.. see grf_rhvar.h
1945 * for an explanation. To convert to "our" format, the
1946 * following holds:
1947 * col2 = !image & mask
1948 * col1 = image & mask
1949 * transp = !mask
1950 * and thus:
1951 * image = col1
1952 * mask = col1 | col2
1953 * hope I got these bool-eqs right below..
1954 */
1955
1956 #ifdef RH_64BIT_SPRITE
1957 info->size.x = 64;
1958 info->size.y = 64;
1959 for (row = 0,
1960 hwp = (volatile u_long *)(ba + LM_OFFSET + HWC_MEM_OFF),
1961 mp = mask, imp = image;
1962 row < 64;
1963 row++) {
1964 u_long bp10, bp20, bp11, bp21;
1965 bp10 = *hwp++;
1966 bp20 = *hwp++;
1967 bp11 = *hwp++;
1968 bp21 = *hwp++;
1969 M2I (bp10);
1970 M2I (bp20);
1971 M2I (bp11);
1972 M2I (bp21);
1973 *imp++ = (~bp10) & bp11;
1974 *imp++ = (~bp20) & bp21;
1975 *mp++ = (~bp10) | (bp10 & ~bp11);
1976 *mp++ = (~bp20) & (bp20 & ~bp21);
1977 }
1978 #else
1979 info->size.x = 32;
1980 info->size.y = 32;
1981 for (row = 0,
1982 hwp = (volatile u_long *)(ba + LM_OFFSET + HWC_MEM_OFF),
1983 mp = mask, imp = image;
1984 row < 32;
1985 row++) {
1986 u_long bp10, bp11;
1987 bp10 = *hwp++;
1988 bp11 = *hwp++;
1989 M2I (bp10);
1990 M2I (bp11);
1991 *imp++ = (~bp10) & bp11;
1992 *mp++ = (~bp10) | (bp10 & ~bp11);
1993 }
1994 #endif
1995 copyout (image, info->image, sizeof (image));
1996 copyout (mask, info->mask, sizeof (mask));
1997 }
1998 return(0);
1999 }
2000
2001 int
2002 rh_setspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *info)
2003 {
2004 volatile unsigned char *ba;
2005 #if 0
2006 u_char control;
2007 #endif
2008
2009 ba = gp->g_regkva;
2010
2011 if (info->set & GRFSPRSET_SHAPE) {
2012 /*
2013 * For an explanation of these weird actions here, see above
2014 * when reading the shape. We set the shape directly into
2015 * the video memory, there's no reason to keep 1k on the
2016 * kernel stack just as template
2017 */
2018 u_char *image, *mask;
2019 volatile u_long *hwp;
2020 u_char *imp, *mp;
2021 short row;
2022
2023 #ifdef RH_64BIT_SPRITE
2024 if (info->size.y > 64)
2025 info->size.y = 64;
2026 if (info->size.x > 64)
2027 info->size.x = 64;
2028 #else
2029 if (info->size.y > 32)
2030 info->size.y = 32;
2031 if (info->size.x > 32)
2032 info->size.x = 32;
2033 #endif
2034
2035 if (info->size.x < 32)
2036 info->size.x = 32;
2037
2038 image = malloc(HWC_MEM_SIZE, M_TEMP, M_WAITOK);
2039 mask = image + HWC_MEM_SIZE/2;
2040
2041 copyin(info->image, image, info->size.y * info->size.x / 8);
2042 copyin(info->mask, mask, info->size.y * info->size.x / 8);
2043
2044 hwp = (volatile u_long *)(ba + LM_OFFSET + HWC_MEM_OFF);
2045
2046 /*
2047 * setting it is slightly more difficult, because we can't
2048 * force the application to not pass a *smaller* than
2049 * supported bitmap
2050 */
2051
2052 for (row = 0, mp = mask, imp = image;
2053 row < info->size.y;
2054 row++) {
2055 u_long im1, im2, m1, m2;
2056
2057 im1 = *(unsigned long *)imp;
2058 imp += 4;
2059 m1 = *(unsigned long *)mp;
2060 mp += 4;
2061 #ifdef RH_64BIT_SPRITE
2062 if (info->size.x > 32) {
2063 im2 = *(unsigned long *)imp;
2064 imp += 4;
2065 m2 = *(unsigned long *)mp;
2066 mp += 4;
2067 }
2068 else
2069 #endif
2070 im2 = m2 = 0;
2071
2072 M2I(im1);
2073 M2I(im2);
2074 M2I(m1);
2075 M2I(m2);
2076
2077 *hwp++ = ~m1;
2078 #ifdef RH_64BIT_SPRITE
2079 *hwp++ = ~m2;
2080 #endif
2081 *hwp++ = m1 & im1;
2082 #ifdef RH_64BIT_SPRITE
2083 *hwp++ = m2 & im2;
2084 #endif
2085 }
2086 #ifdef RH_64BIT_SPRITE
2087 for (; row < 64; row++) {
2088 *hwp++ = 0xffffffff;
2089 *hwp++ = 0xffffffff;
2090 *hwp++ = 0x00000000;
2091 *hwp++ = 0x00000000;
2092 }
2093 #else
2094 for (; row < 32; row++) {
2095 *hwp++ = 0xffffffff;
2096 *hwp++ = 0x00000000;
2097 }
2098 #endif
2099
2100 free(image, M_TEMP);
2101 RZ3SetupHWC(gp, 1, 0, 0, 0, 0);
2102 }
2103 if (info->set & GRFSPRSET_CMAP) {
2104 /* hey cheat a bit here.. XXX */
2105 WSeq(ba, SEQ_ID_CURSOR_COLOR0, 0);
2106 WSeq(ba, SEQ_ID_CURSOR_COLOR1, 1);
2107 }
2108 if (info->set & GRFSPRSET_ENABLE) {
2109 #if 0
2110 if (info->enable)
2111 control = 0x85;
2112 else
2113 control = 0;
2114 WSeq(ba, SEQ_ID_CURSOR_CONTROL, control);
2115 #endif
2116 }
2117 if (info->set & GRFSPRSET_POS)
2118 rh_setspritepos(gp, &info->pos);
2119 if (info->set & GRFSPRSET_HOT) {
2120 WSeq(ba, SEQ_ID_CURSOR_X_INDEX, info->hot.x & 0x3f);
2121 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, info->hot.y & 0x7f);
2122 }
2123
2124 return(0);
2125 }
2126
2127 int
2128 rh_getspritemax(struct grf_softc *gp, struct grf_position *pos)
2129 {
2130 #ifdef RH_64BIT_SPRITE
2131 pos->x = 64;
2132 pos->y = 64;
2133 #else
2134 pos->x = 32;
2135 pos->y = 32;
2136 #endif
2137
2138 return(0);
2139 }
2140
2141
2142 int
2143 rh_bitblt(struct grf_softc *gp, struct grf_bitblt *bb)
2144 {
2145 struct MonDef *md = (struct MonDef *)gp->g_data;
2146 if (md->DEP <= 8)
2147 RZ3BitBlit(gp, bb);
2148 else if (md->DEP <= 16)
2149 RZ3BitBlit16(gp, bb);
2150 else
2151 RZ3BitBlit24(gp, bb);
2152
2153 return(0);
2154 }
2155
2156
2157 int
2158 rh_blank(struct grf_softc *gp, int *on)
2159 {
2160 struct MonDef *md = (struct MonDef *)gp->g_data;
2161 int r;
2162
2163 r = 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8);
2164
2165 WSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE, *on > 0 ? r : 0x21);
2166
2167 return(0);
2168 }
2169
2170 #endif /* NGRF */
2171