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