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