Home | History | Annotate | Line # | Download | only in dev
grf_rh.c revision 1.28
      1 /*	$NetBSD: grf_rh.c,v 1.28 1998/01/12 10:39:37 thorpej 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 static struct cfdata *cfdata;
   1539 
   1540 int
   1541 grfrhmatch(pdp, cfp, auxp)
   1542 	struct device *pdp;
   1543 	struct cfdata *cfp;
   1544 	void *auxp;
   1545 {
   1546 #ifdef RETINACONSOLE
   1547 	static int rhconunit = -1;
   1548 #endif
   1549 	struct zbus_args *zap;
   1550 
   1551 	zap = auxp;
   1552 
   1553 	if (amiga_realconfig == 0)
   1554 #ifdef RETINACONSOLE
   1555 		if (rhconunit != -1)
   1556 #endif
   1557 			return(0);
   1558 	if (zap->manid != 18260 ||
   1559 			((zap->prodid != 16) && (zap->prodid != 19)))
   1560 		return(0);
   1561 #ifdef RETINACONSOLE
   1562 	if (amiga_realconfig == 0 || rhconunit != cfp->cf_unit) {
   1563 #endif
   1564 		if ((unsigned)rh_default_mon >= rh_mon_max ||
   1565 		    monitor_defs[rh_default_mon].DEP == 8)
   1566 			rh_default_mon = 0;
   1567 		current_mon = monitor_defs + rh_default_mon;
   1568 		if (rh_mondefok(current_mon) == 0)
   1569 			return(0);
   1570 #ifdef RETINACONSOLE
   1571 		if (amiga_realconfig == 0) {
   1572 			rhconunit = cfp->cf_unit;
   1573 			cfdata = cfp;
   1574 		}
   1575 	}
   1576 #endif
   1577 	return(1);
   1578 }
   1579 
   1580 void
   1581 grfrhattach(pdp, dp, auxp)
   1582 	struct device *pdp, *dp;
   1583 	void *auxp;
   1584 {
   1585 	static struct grf_softc congrf;
   1586 	struct zbus_args *zap;
   1587 	struct grf_softc *gp;
   1588 
   1589 	zap = auxp;
   1590 
   1591 	if (dp == NULL)
   1592 		gp = &congrf;
   1593 	else
   1594 		gp = (struct grf_softc *)dp;
   1595 	if (dp != NULL && congrf.g_regkva != 0) {
   1596 		/*
   1597 		 * inited earlier, just copy (not device struct)
   1598 		 */
   1599 		bcopy(&congrf.g_display, &gp->g_display,
   1600 		    (char *)&gp[1] - (char *)&gp->g_display);
   1601 	} else {
   1602 		gp->g_regkva = (volatile caddr_t)zap->va;
   1603 		gp->g_fbkva = (volatile caddr_t)zap->va + LM_OFFSET;
   1604 		gp->g_unit = GRF_RETINAIII_UNIT;
   1605 		gp->g_mode = rh_mode;
   1606 		gp->g_conpri = grfrh_cnprobe();
   1607 		gp->g_flags = GF_ALIVE;
   1608 		grfrh_iteinit(gp);
   1609 		(void)rh_load_mon(gp, current_mon);
   1610 	}
   1611 	if (dp != NULL)
   1612 		printf("\n");
   1613 	/*
   1614 	 * attach grf
   1615 	 */
   1616 	amiga_config_found(cfdata, &gp->g_device, gp, grfrhprint);
   1617 }
   1618 
   1619 int
   1620 grfrhprint(auxp, pnp)
   1621 	void *auxp;
   1622 	const char *pnp;
   1623 {
   1624 	if (pnp)
   1625 		printf("ite at %s", pnp);
   1626 	return(UNCONF);
   1627 }
   1628 
   1629 int
   1630 rh_getvmode(gp, vm)
   1631 	struct grf_softc *gp;
   1632 	struct grfvideo_mode *vm;
   1633 {
   1634 	struct MonDef *md;
   1635 	int vmul;
   1636 
   1637 	if (vm->mode_num && vm->mode_num > rh_mon_max)
   1638 		return(EINVAL);
   1639 
   1640 	if (! vm->mode_num)
   1641 		vm->mode_num = (current_mon - monitor_defs) + 1;
   1642 
   1643 	md = monitor_defs + (vm->mode_num - 1);
   1644 	strncpy (vm->mode_descr, monitor_descr[vm->mode_num - 1],
   1645 	   sizeof (vm->mode_descr));
   1646 	vm->pixel_clock  = md->FQ;
   1647         vm->disp_width   = (md->DEP == 4) ? md->MW : md->TX;
   1648         vm->disp_height  = (md->DEP == 4) ? md->MH : md->TY;
   1649 	vm->depth        = md->DEP;
   1650 
   1651 	/*
   1652 	 * From observation of the monitor definition table above, I guess
   1653 	 * that the horizontal timings are in units of longwords. Hence, I
   1654 	 * get the pixels by multiplication with 32 and division by the depth.
   1655 	 * The text modes, apparently marked by depth == 4, are even more
   1656 	 * wierd. According to a comment above, they are computed from a
   1657 	 * depth==8 mode thats for us: * 32 / 8) by applying another factor
   1658 	 * of 4 / font width.
   1659 	 * Reverse applying the latter formula most of the constants cancel
   1660 	 * themselves and we are left with a nice (* font width).
   1661 	 * That is, internal timings are in units of longwords for graphics
   1662 	 * modes, or in units of characters widths for text modes.
   1663 	 * We better don't WRITE modes until this has been real live checked.
   1664 	 *                    - Ignatios Souvatzis
   1665 	 */
   1666 
   1667 	if (md->DEP != 4) {
   1668 		vm->hblank_start = md->HBS * 32 / md->DEP;
   1669 		vm->hsync_start  = md->HSS * 32 / md->DEP;
   1670 		vm->hsync_stop   = md->HSE * 32 / md->DEP;
   1671 		vm->htotal       = md->HT * 32 / md->DEP;
   1672 	} else {
   1673 		vm->hblank_start = md->HBS * md->FX;
   1674 		vm->hsync_start  = md->HSS * md->FX;
   1675 		vm->hsync_stop   = md->HSE * md->FX;
   1676 		vm->htotal       = md->HT * md->FX;
   1677 	}
   1678 
   1679 	/* XXX move vm->disp_flags and vmul to rh_load_mon
   1680 	 * if rh_setvmode can add new modes with grfconfig */
   1681 	vm->disp_flags = 0;
   1682 	vmul = 2;
   1683 	if (md->FLG & MDF_DBL) {
   1684 		vm->disp_flags |= GRF_FLAGS_DBLSCAN;
   1685 		vmul = 4;
   1686 	}
   1687 	if (md->FLG & MDF_LACE) {
   1688 		vm->disp_flags |= GRF_FLAGS_LACE;
   1689 		vmul = 1;
   1690 	}
   1691 	vm->vblank_start = md->VBS * vmul / 2;
   1692 	vm->vsync_start  = md->VSS * vmul / 2;
   1693 	vm->vsync_stop   = md->VSE * vmul / 2;
   1694 	vm->vtotal       = md->VT * vmul / 2;
   1695 
   1696 	return(0);
   1697 }
   1698 
   1699 
   1700 int
   1701 rh_setvmode(gp, mode, type)
   1702 	struct grf_softc *gp;
   1703 	unsigned mode;
   1704         enum mode_type type;
   1705 {
   1706 	int error;
   1707 
   1708 	if (!mode || mode > rh_mon_max)
   1709 		return(EINVAL);
   1710 
   1711         if ((type == MT_TXTONLY && monitor_defs[mode-1].DEP != 4)
   1712             || (type == MT_GFXONLY && monitor_defs[mode-1].DEP == 4))
   1713 		return(EINVAL);
   1714 
   1715 	current_mon = monitor_defs + (mode - 1);
   1716 
   1717 	error = rh_load_mon (gp, current_mon) ? 0 : EINVAL;
   1718 
   1719 	return(error);
   1720 }
   1721 
   1722 
   1723 /*
   1724  * Change the mode of the display.
   1725  * Return a UNIX error number or 0 for success.
   1726  */
   1727 int
   1728 rh_mode(gp, cmd, arg, a2, a3)
   1729 	register struct grf_softc *gp;
   1730 	u_long cmd;
   1731 	void *arg;
   1732 	u_long a2;
   1733 	int a3;
   1734 {
   1735 	switch (cmd) {
   1736 	    case GM_GRFON:
   1737                 rh_setvmode (gp, rh_default_gfx + 1, MT_GFXONLY);
   1738 		return(0);
   1739 
   1740 	    case GM_GRFOFF:
   1741                 rh_setvmode (gp, rh_default_mon + 1, MT_TXTONLY);
   1742 		return(0);
   1743 
   1744 	    case GM_GRFCONFIG:
   1745 		return(0);
   1746 
   1747 	    case GM_GRFGETVMODE:
   1748 		return(rh_getvmode (gp, (struct grfvideo_mode *) arg));
   1749 
   1750 	    case GM_GRFSETVMODE:
   1751                 return(rh_setvmode (gp, *(unsigned *) arg,
   1752                                     (gp->g_flags & GF_GRFON) ? MT_GFXONLY : MT_TXTONLY));
   1753 
   1754 	    case GM_GRFGETNUMVM:
   1755 		*(int *)arg = rh_mon_max;
   1756 		return(0);
   1757 
   1758 #ifdef BANKEDDEVPAGER
   1759 	    case GM_GRFGETBANK:
   1760 	    case GM_GRFGETCURBANK:
   1761 	    case GM_GRFSETBANK:
   1762 		return(EINVAL);
   1763 #endif
   1764 	    case GM_GRFIOCTL:
   1765 		return(rh_ioctl (gp, a2, arg));
   1766 
   1767 	    default:
   1768 		break;
   1769 	}
   1770 
   1771 	return(EINVAL);
   1772 }
   1773 
   1774 int
   1775 rh_ioctl (gp, cmd, data)
   1776 	register struct grf_softc *gp;
   1777 	u_long cmd;
   1778 	void *data;
   1779 {
   1780 	switch (cmd) {
   1781 #ifdef RH_HARDWARECURSOR
   1782 	    case GRFIOCGSPRITEPOS:
   1783 		return(rh_getspritepos (gp, (struct grf_position *) data));
   1784 
   1785 	    case GRFIOCSSPRITEPOS:
   1786 		return(rh_setspritepos (gp, (struct grf_position *) data));
   1787 
   1788 	    case GRFIOCSSPRITEINF:
   1789 		return(rh_setspriteinfo (gp, (struct grf_spriteinfo *) data));
   1790 
   1791 	    case GRFIOCGSPRITEINF:
   1792 		return(rh_getspriteinfo (gp, (struct grf_spriteinfo *) data));
   1793 
   1794 	    case GRFIOCGSPRITEMAX:
   1795 		return(rh_getspritemax (gp, (struct grf_position *) data));
   1796 #else /* RH_HARDWARECURSOR */
   1797 	    case GRFIOCGSPRITEPOS:
   1798 	    case GRFIOCSSPRITEPOS:
   1799 	    case GRFIOCSSPRITEINF:
   1800 	    case GRFIOCGSPRITEMAX:
   1801 		break;
   1802 #endif /* RH_HARDWARECURSOR */
   1803 
   1804 	    case GRFIOCGETCMAP:
   1805 		return(rh_getcmap (gp, (struct grf_colormap *) data));
   1806 
   1807 	    case GRFIOCPUTCMAP:
   1808 		return(rh_putcmap (gp, (struct grf_colormap *) data));
   1809 
   1810 	    case GRFIOCBITBLT:
   1811 		return(rh_bitblt (gp, (struct grf_bitblt *) data));
   1812 
   1813 	    case GRFIOCBLANK:
   1814 		return (rh_blank(gp, (int *)data));
   1815 	}
   1816 
   1817 	return(EINVAL);
   1818 }
   1819 
   1820 
   1821 int
   1822 rh_getcmap (gfp, cmap)
   1823 	struct grf_softc *gfp;
   1824 	struct grf_colormap *cmap;
   1825 {
   1826 	volatile unsigned char *ba;
   1827 	u_char red[256], green[256], blue[256], *rp, *gp, *bp;
   1828 	short x;
   1829 	int error;
   1830 
   1831 	if (cmap->count == 0 || cmap->index >= 256)
   1832 		return 0;
   1833 
   1834 	if (cmap->index + cmap->count > 256)
   1835 		cmap->count = 256 - cmap->index;
   1836 
   1837 	ba = gfp->g_regkva;
   1838 	/* first read colors out of the chip, then copyout to userspace */
   1839 	vgaw (ba, VDAC_ADDRESS_W, cmap->index);
   1840 	x = cmap->count - 1;
   1841 	rp = red + cmap->index;
   1842 	gp = green + cmap->index;
   1843 	bp = blue + cmap->index;
   1844 	do {
   1845 		*rp++ = vgar (ba, VDAC_DATA) << 2;
   1846 		*gp++ = vgar (ba, VDAC_DATA) << 2;
   1847 		*bp++ = vgar (ba, VDAC_DATA) << 2;
   1848 	} while (x-- > 0);
   1849 
   1850 	if (!(error = copyout (red + cmap->index, cmap->red, cmap->count))
   1851 	    && !(error = copyout (green + cmap->index, cmap->green, cmap->count))
   1852 	    && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count)))
   1853 		return(0);
   1854 
   1855 	return(error);
   1856 }
   1857 
   1858 int
   1859 rh_putcmap (gfp, cmap)
   1860 	struct grf_softc *gfp;
   1861 	struct grf_colormap *cmap;
   1862 {
   1863 	volatile unsigned char *ba;
   1864 	u_char red[256], green[256], blue[256], *rp, *gp, *bp;
   1865 	short x;
   1866 	int error;
   1867 
   1868 	if (cmap->count == 0 || cmap->index >= 256)
   1869 		return(0);
   1870 
   1871 	if (cmap->index + cmap->count > 256)
   1872 		cmap->count = 256 - cmap->index;
   1873 
   1874 	/* first copy the colors into kernelspace */
   1875 	if (!(error = copyin (cmap->red, red + cmap->index, cmap->count))
   1876 	    && !(error = copyin (cmap->green, green + cmap->index, cmap->count))
   1877 	    && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count))) {
   1878 		/* argl.. LoadPalette wants a different format, so do it like with
   1879 		* Retina2.. */
   1880 		ba = gfp->g_regkva;
   1881 		vgaw (ba, VDAC_ADDRESS_W, cmap->index);
   1882 		x = cmap->count - 1;
   1883 		rp = red + cmap->index;
   1884 		gp = green + cmap->index;
   1885 		bp = blue + cmap->index;
   1886 		do {
   1887 			vgaw (ba, VDAC_DATA, *rp++ >> 2);
   1888 			vgaw (ba, VDAC_DATA, *gp++ >> 2);
   1889 			vgaw (ba, VDAC_DATA, *bp++ >> 2);
   1890 		} while (x-- > 0);
   1891 		return(0);
   1892 	}
   1893 	else
   1894 		return(error);
   1895 }
   1896 
   1897 int
   1898 rh_getspritepos (gp, pos)
   1899 	struct grf_softc *gp;
   1900 	struct grf_position *pos;
   1901 {
   1902 	struct grfinfo *gi = &gp->g_display;
   1903 #if 1
   1904 	volatile unsigned char *ba = gp->g_regkva;
   1905 
   1906 	pos->x = (RSeq(ba, SEQ_ID_CURSOR_X_LOC_HI) << 8) |
   1907 	    RSeq(ba, SEQ_ID_CURSOR_X_LOC_LO);
   1908 	pos->y = (RSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI) << 8) |
   1909 	    RSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO);
   1910 #else
   1911 	volatile unsigned char *acm = gp->g_regkva + ACM_OFFSET;
   1912 
   1913 	pos->x = acm[ACM_CURSOR_POSITION + 0] +
   1914 	    (acm[ACM_CURSOR_POSITION + 1] << 8);
   1915 	pos->y = acm[ACM_CURSOR_POSITION + 2] +
   1916 	    (acm[ACM_CURSOR_POSITION + 3] << 8);
   1917 #endif
   1918 	pos->x += gi->gd_fbx;
   1919 	pos->y += gi->gd_fby;
   1920 
   1921 	return(0);
   1922 }
   1923 
   1924 int
   1925 rh_setspritepos (gp, pos)
   1926 	struct grf_softc *gp;
   1927 	struct grf_position *pos;
   1928 {
   1929 	RZ3SetHWCloc (gp, pos->x, pos->y);
   1930 	return(0);
   1931 }
   1932 
   1933 int
   1934 rh_getspriteinfo (gp, info)
   1935 	struct grf_softc *gp;
   1936 	struct grf_spriteinfo *info;
   1937 {
   1938 	volatile unsigned char *ba, *fb;
   1939 
   1940 	ba = gp->g_regkva;
   1941 	fb = gp->g_fbkva;
   1942 	if (info->set & GRFSPRSET_ENABLE)
   1943 		info->enable = RSeq (ba, SEQ_ID_CURSOR_CONTROL) & 0x01;
   1944 	if (info->set & GRFSPRSET_POS)
   1945 		rh_getspritepos (gp, &info->pos);
   1946 	if (info->set & GRFSPRSET_HOT) {
   1947 		info->hot.x = RSeq (ba, SEQ_ID_CURSOR_X_INDEX) & 0x3f;
   1948 		info->hot.y = RSeq (ba, SEQ_ID_CURSOR_Y_INDEX) & 0x7f;
   1949 	}
   1950 	if (info->set & GRFSPRSET_CMAP) {
   1951 		struct grf_colormap cmap;
   1952 		int index;
   1953 		cmap.index = 0;
   1954 		cmap.count = 256;
   1955 		rh_getcmap (gp, &cmap);
   1956 		index = RSeq (ba, SEQ_ID_CURSOR_COLOR0);
   1957 		info->cmap.red[0] = cmap.red[index];
   1958 		info->cmap.green[0] = cmap.green[index];
   1959 		info->cmap.blue[0] = cmap.blue[index];
   1960 		index = RSeq (ba, SEQ_ID_CURSOR_COLOR1);
   1961 		info->cmap.red[1] = cmap.red[index];
   1962 		info->cmap.green[1] = cmap.green[index];
   1963 		info->cmap.blue[1] = cmap.blue[index];
   1964 	}
   1965 	if (info->set & GRFSPRSET_SHAPE) {
   1966 		u_char image[128], mask[128];
   1967 		volatile u_long *hwp;
   1968 		u_char *imp, *mp;
   1969 		short row;
   1970 
   1971 		/* sprite bitmap is WEIRD in this chip.. see grf_rhvar.h
   1972 		 * for an explanation. To convert to "our" format, the
   1973 		 * following holds:
   1974 		 *   col2   = !image & mask
   1975 		 *   col1   = image & mask
   1976 		 *   transp = !mask
   1977 		 * and thus:
   1978 		 *   image  = col1
   1979 		 *   mask   = col1 | col2
   1980 		 * hope I got these bool-eqs right below..
   1981 		 */
   1982 
   1983 #ifdef RH_64BIT_SPRITE
   1984 		info->size.x = 64;
   1985 		info->size.y = 64;
   1986 		for (row = 0, hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF),
   1987 		    mp = mask, imp = image;
   1988 		    row < 64;
   1989 		    row++) {
   1990 			u_long bp10, bp20, bp11, bp21;
   1991 			bp10 = *hwp++;
   1992 			bp20 = *hwp++;
   1993 			bp11 = *hwp++;
   1994 			bp21 = *hwp++;
   1995 			M2I (bp10);
   1996 			M2I (bp20);
   1997 			M2I (bp11);
   1998 			M2I (bp21);
   1999 			*imp++ = (~bp10) & bp11;
   2000 			*imp++ = (~bp20) & bp21;
   2001 			*mp++  = (~bp10) | (bp10 & ~bp11);
   2002 			*mp++  = (~bp20) & (bp20 & ~bp21);
   2003 		}
   2004 #else
   2005                 info->size.x = 32;
   2006                 info->size.y = 32;
   2007                 for (row = 0, hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF),
   2008                     mp = mask, imp = image;
   2009                     row < 32;
   2010                     row++) {
   2011                         u_long bp10, bp11;
   2012                         bp10 = *hwp++;
   2013                         bp11 = *hwp++;
   2014                         M2I (bp10);
   2015                         M2I (bp11);
   2016                         *imp++ = (~bp10) & bp11;
   2017                         *mp++  = (~bp10) | (bp10 & ~bp11);
   2018                 }
   2019 #endif
   2020 		copyout (image, info->image, sizeof (image));
   2021 		copyout (mask, info->mask, sizeof (mask));
   2022 	}
   2023 	return(0);
   2024 }
   2025 
   2026 int
   2027 rh_setspriteinfo (gp, info)
   2028 	struct grf_softc *gp;
   2029 	struct grf_spriteinfo *info;
   2030 {
   2031 	volatile unsigned char *ba, *fb;
   2032 #if 0
   2033 	u_char control;
   2034 #endif
   2035 
   2036 	ba = gp->g_regkva;
   2037 	fb = gp->g_fbkva;
   2038 
   2039 	if (info->set & GRFSPRSET_SHAPE) {
   2040 		/*
   2041 		 * For an explanation of these weird actions here, see above
   2042 		 * when reading the shape.  We set the shape directly into
   2043 		 * the video memory, there's no reason to keep 1k on the
   2044 		 * kernel stack just as template
   2045 		 */
   2046 		u_char *image, *mask;
   2047 		volatile u_long *hwp;
   2048 		u_char *imp, *mp;
   2049 		short row;
   2050 
   2051 #ifdef RH_64BIT_SPRITE
   2052 		if (info->size.y > 64)
   2053 			info->size.y = 64;
   2054 		if (info->size.x > 64)
   2055 			info->size.x = 64;
   2056 #else
   2057                 if (info->size.y > 32)
   2058                         info->size.y = 32;
   2059                 if (info->size.x > 32)
   2060                         info->size.x = 32;
   2061 #endif
   2062 
   2063 		if (info->size.x < 32)
   2064 			info->size.x = 32;
   2065 
   2066 		image = malloc(HWC_MEM_SIZE, M_TEMP, M_WAITOK);
   2067 		mask  = image + HWC_MEM_SIZE/2;
   2068 
   2069 		copyin(info->image, image, info->size.y * info->size.x / 8);
   2070 		copyin(info->mask, mask, info->size.y * info->size.x / 8);
   2071 
   2072 		hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF);
   2073 
   2074 		/*
   2075 		 * setting it is slightly more difficult, because we can't
   2076 		 * force the application to not pass a *smaller* than
   2077 		 * supported bitmap
   2078 		 */
   2079 
   2080 		for (row = 0, mp = mask, imp = image;
   2081 		    row < info->size.y;
   2082 		    row++) {
   2083 			u_long im1, im2, m1, m2;
   2084 
   2085 			im1 = *(unsigned long *)imp;
   2086 			imp += 4;
   2087 			m1  = *(unsigned long *)mp;
   2088 			mp  += 4;
   2089 #ifdef RH_64BIT_SPRITE
   2090 			if (info->size.x > 32) {
   2091 	      			im2 = *(unsigned long *)imp;
   2092 				imp += 4;
   2093 				m2  = *(unsigned long *)mp;
   2094 				mp  += 4;
   2095 			}
   2096 			else
   2097 #endif
   2098 				im2 = m2 = 0;
   2099 
   2100 			M2I(im1);
   2101 			M2I(im2);
   2102 			M2I(m1);
   2103 			M2I(m2);
   2104 
   2105 			*hwp++ = ~m1;
   2106 #ifdef RH_64BIT_SPRITE
   2107 			*hwp++ = ~m2;
   2108 #endif
   2109 			*hwp++ = m1 & im1;
   2110 #ifdef RH_64BIT_SPRITE
   2111 			*hwp++ = m2 & im2;
   2112 #endif
   2113 		}
   2114 #ifdef RH_64BIT_SPRITE
   2115 		for (; row < 64; row++) {
   2116 			*hwp++ = 0xffffffff;
   2117 			*hwp++ = 0xffffffff;
   2118 			*hwp++ = 0x00000000;
   2119 			*hwp++ = 0x00000000;
   2120 		}
   2121 #else
   2122                 for (; row < 32; row++) {
   2123                         *hwp++ = 0xffffffff;
   2124                         *hwp++ = 0x00000000;
   2125                 }
   2126 #endif
   2127 
   2128 		free(image, M_TEMP);
   2129 		RZ3SetupHWC(gp, 1, 0, 0, 0, 0);
   2130 	}
   2131 	if (info->set & GRFSPRSET_CMAP) {
   2132 		/* hey cheat a bit here.. XXX */
   2133 		WSeq(ba, SEQ_ID_CURSOR_COLOR0, 0);
   2134 		WSeq(ba, SEQ_ID_CURSOR_COLOR1, 1);
   2135 	}
   2136 	if (info->set & GRFSPRSET_ENABLE) {
   2137 #if 0
   2138 		if (info->enable)
   2139 			control = 0x85;
   2140 		else
   2141 			control = 0;
   2142 		WSeq(ba, SEQ_ID_CURSOR_CONTROL, control);
   2143 #endif
   2144 	}
   2145 	if (info->set & GRFSPRSET_POS)
   2146 		rh_setspritepos(gp, &info->pos);
   2147 	if (info->set & GRFSPRSET_HOT) {
   2148 		WSeq(ba, SEQ_ID_CURSOR_X_INDEX, info->hot.x & 0x3f);
   2149 		WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, info->hot.y & 0x7f);
   2150 	}
   2151 
   2152 	return(0);
   2153 }
   2154 
   2155 int
   2156 rh_getspritemax (gp, pos)
   2157 	struct grf_softc *gp;
   2158 	struct grf_position *pos;
   2159 {
   2160 #ifdef RH_64BIT_SPRITE
   2161 	pos->x = 64;
   2162 	pos->y = 64;
   2163 #else
   2164         pos->x = 32;
   2165         pos->y = 32;
   2166 #endif
   2167 
   2168 	return(0);
   2169 }
   2170 
   2171 
   2172 int
   2173 rh_bitblt (gp, bb)
   2174 	struct grf_softc *gp;
   2175 	struct grf_bitblt *bb;
   2176 {
   2177 	struct MonDef *md = (struct MonDef *)gp->g_data;
   2178         if (md->DEP <= 8)
   2179 		RZ3BitBlit(gp, bb);
   2180         else if (md->DEP <= 16)
   2181 		RZ3BitBlit16(gp, bb);
   2182         else
   2183                 RZ3BitBlit24(gp, bb);
   2184 
   2185 	return(0);
   2186 }
   2187 
   2188 
   2189 int
   2190 rh_blank(gp, on)
   2191 	struct grf_softc *gp;
   2192 	int *on;
   2193 {
   2194 	struct MonDef *md = (struct MonDef *)gp->g_data;
   2195 	int r;
   2196 
   2197 	r = 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8);
   2198 
   2199 	WSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE, *on > 0 ? r : 0x21);
   2200 
   2201 	return(0);
   2202 }
   2203 
   2204 #endif	/* NGRF */
   2205