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