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