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