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