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