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