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