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