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