Home | History | Annotate | Line # | Download | only in dev
grf_rt.c revision 1.9
      1  1.6  chopps /*
      2  1.9  chopps  *	$Id: grf_rt.c,v 1.9 1994/04/22 01:35:16 chopps Exp $
      3  1.6  chopps  */
      4  1.6  chopps 
      5  1.1      mw #include "grf.h"
      6  1.1      mw #if NGRF > 0
      7  1.1      mw 
      8  1.1      mw /* Graphics routines for the Retina board,
      9  1.1      mw    using the NCR 77C22E+ VGA controller. */
     10  1.1      mw 
     11  1.4      mw #include <sys/param.h>
     12  1.4      mw #include <sys/errno.h>
     13  1.4      mw #include <sys/ioctl.h>
     14  1.7  chopps #include <amiga/dev/grfioctl.h>
     15  1.7  chopps #include <amiga/dev/grfvar.h>
     16  1.7  chopps #include <amiga/dev/grf_rtreg.h>
     17  1.4      mw #include <machine/cpu.h>
     18  1.7  chopps #include <amiga/dev/device.h>
     19  1.1      mw 
     20  1.1      mw extern caddr_t ZORRO2ADDR;
     21  1.1      mw 
     22  1.8  chopps /* marked true early so that retina_cnprobe() can tell if we are alive. */
     23  1.8  chopps int	retina_inited;
     24  1.8  chopps 
     25  1.8  chopps 
     26  1.1      mw /* NOTE: this driver for the MacroSystem Retina board was only possible,
     27  1.1      mw          because MacroSystem provided information about the pecularities
     28  1.1      mw          of the board. THANKS! Competition in Europe among gfx board
     29  1.1      mw          manufacturers is rather tough, so Lutz Vieweg, who wrote the
     30  1.1      mw          initial driver, has made an agreement with MS not to document
     31  1.1      mw          the driver source (see also his Copyright disclaimer below).
     32  1.1      mw          -> ALL comments after
     33  1.1      mw 	 -> "/* -------------- START OF CODE -------------- * /"
     34  1.1      mw 	 -> have been added by myself (mw) from studying the publically
     35  1.1      mw 	 -> available "NCR 77C22E+" Data Manual
     36  1.1      mw 
     37  1.1      mw 	 Lutz' original driver source (without any of my comments) is
     38  1.1      mw 	 available on request. */
     39  1.1      mw 
     40  1.1      mw 
     41  1.1      mw /* This code offers low-level routines to access the Retina graphics-board
     42  1.1      mw    manufactured by MS MacroSystem GmbH from within NetBSD for the Amiga.
     43  1.1      mw    No warranties for any kind of function at all - this code may crash
     44  1.1      mw    your hardware and scratch your harddisk.
     45  1.1      mw    Use at your own risk.
     46  1.1      mw    Freely distributable.
     47  1.1      mw 
     48  1.1      mw    Written by Lutz Vieweg 07/93
     49  1.1      mw 
     50  1.1      mw    Thanks to MacroSystem for providing me with the neccessary information
     51  1.1      mw    to create theese routines. The sparse documentation of this code
     52  1.1      mw    results from the agreements between MS and me.
     53  1.1      mw */
     54  1.1      mw 
     55  1.9  chopps extern unsigned char kernel_font_8x8_width, kernel_font_8x8_height;
     56  1.9  chopps extern unsigned char kernel_font_8x8_lo, kernel_font_8x8_hi;
     57  1.9  chopps extern unsigned char kernel_font_8x8[];
     58  1.1      mw 
     59  1.1      mw 
     60  1.1      mw #define MDF_DBL 1
     61  1.1      mw #define MDF_LACE 2
     62  1.1      mw #define MDF_CLKDIV2 4
     63  1.1      mw 
     64  1.1      mw 
     65  1.1      mw /* standard-palette definition */
     66  1.1      mw 
     67  1.1      mw unsigned char NCRStdPalette[16*3] = {
     68  1.1      mw /*   R   G   B  */
     69  1.1      mw 	  0,  0,  0,
     70  1.1      mw 	192,192,192,
     71  1.1      mw 	128,  0,  0,
     72  1.1      mw 	  0,128,  0,
     73  1.1      mw 	  0,  0,128,
     74  1.1      mw 	128,128,  0,
     75  1.1      mw 	  0,128,128,
     76  1.1      mw 	128,  0,128,
     77  1.1      mw 	 64, 64, 64, /* the higher 8 colors have more intensity for  */
     78  1.1      mw 	255,255,255, /* compatibility with standard attributes       */
     79  1.1      mw 	255,  0,  0,
     80  1.1      mw 	  0,255,  0,
     81  1.1      mw 	  0,  0,255,
     82  1.1      mw 	255,255,  0,
     83  1.1      mw 	  0,255,255,
     84  1.1      mw 	255,  0,255
     85  1.1      mw };
     86  1.1      mw 
     87  1.1      mw 
     88  1.1      mw /* The following structures are examples for monitor-definitions. To make one
     89  1.1      mw    of your own, first use "DefineMonitor" and create the 8-bit monitor-mode of
     90  1.1      mw    your dreams. Then save it, and make a structure from the values provided in
     91  1.1      mw    the file DefineMonitor stored - the labels in the comment above the
     92  1.1      mw    structure definition show where to put what value.
     93  1.1      mw 
     94  1.1      mw    Then you'll need to adapt your monitor-definition to the font you want to
     95  1.1      mw    use. Be FX the width of the font, then the following modifications have to
     96  1.1      mw    be applied to your values:
     97  1.1      mw 
     98  1.1      mw    HBS = (HBS * 4) / FX
     99  1.1      mw    HSS = (HSS * 4) / FX
    100  1.1      mw    HSE = (HSE * 4) / FX
    101  1.1      mw    HBE = (HBE * 4) / FX
    102  1.1      mw    HT  = (HT  * 4) / FX
    103  1.1      mw 
    104  1.1      mw    Make sure your maximum width (MW) and height (MH) are even multiples of
    105  1.1      mw    the fonts' width and height.
    106  1.1      mw */
    107  1.1      mw 
    108  1.1      mw #if 0
    109  1.1      mw /* horizontal 31.5 kHz */
    110  1.1      mw 
    111  1.1      mw /*                                      FQ     FLG    MW   MH   HBS HSS HSE HBE  HT  VBS  VSS  VSE  VBE   VT  */
    112  1.1      mw    struct MonDef MON_640_512_60  = { 50000000,  28,  640, 512,   81, 86, 93, 98, 95, 513, 513, 521, 535, 535,
    113  1.1      mw    /* Depth,           PAL, TX,  TY,    XY,FontX, FontY,    FontData,  FLo,  Fhi */
    114  1.9  chopps           4, NCRStdPalette, 80,  64,  5120,    8,     8, kernel_font_8x8,   32,  255};
    115  1.1      mw 
    116  1.4      mw  struct MonDef MON_640_480_62_G  = { 50000000,   4,  640, 480,  161,171,184,196,195, 481, 484, 492, 502, 502,
    117  1.9  chopps           8, NCRStdPalette,640,480,  5120,    8,     8, kernel_font_8x8,   32,  255};
    118  1.4      mw /* Enter higher values here ^   ^ for panning! */
    119  1.4      mw 
    120  1.1      mw /* horizontal 38kHz */
    121  1.1      mw 
    122  1.1      mw    struct MonDef MON_768_600_60  = { 75000000,  28,  768, 600,   97, 99,107,120,117, 601, 615, 625, 638, 638,
    123  1.9  chopps           4, NCRStdPalette, 96,  75,  7200,    8,     8, kernel_font_8x8,   32,  255};
    124  1.1      mw 
    125  1.1      mw /* horizontal 64kHz */
    126  1.1      mw 
    127  1.1      mw    struct MonDef MON_768_600_80  = { 50000000, 24,  768, 600,   97,104,112,122,119, 601, 606, 616, 628, 628,
    128  1.9  chopps           4, NCRStdPalette, 96,  75,  7200,    8,     8, kernel_font_8x8,   32,  255};
    129  1.1      mw 
    130  1.1      mw    struct MonDef MON_1024_768_80 = { 90000000, 24, 1024, 768,  129,130,141,172,169, 769, 770, 783, 804, 804,
    131  1.9  chopps           4, NCRStdPalette,128,  96, 12288,    8,     8, kernel_font_8x8,   32,  255};
    132  1.4      mw 
    133  1.4      mw /*                                     FQ     FLG    MW   MH   HBS HSS HSE HBE  HT  VBS  VSS  VSE  VBE   VT  */
    134  1.4      mw  struct MonDef MON_1024_768_80_G = { 90000000, 0,  1024, 768,  257,258,280,344,343, 769, 770, 783, 804, 804,
    135  1.9  chopps           8, NCRStdPalette, 1024, 768, 12288,    8,     8, kernel_font_8x8,   32,  255};
    136  1.1      mw 
    137  1.1      mw    struct MonDef MON_1024_1024_59= { 90000000, 24, 1024,1024,  129,130,141,173,170,1025,1059,1076,1087,1087,
    138  1.9  chopps           4, NCRStdPalette,128, 128, 16384,    8,     8, kernel_font_8x8,   32,  255};
    139  1.1      mw 
    140  1.1      mw /* WARNING: THE FOLLOWING MONITOR MODES EXCEED THE 90-MHz LIMIT THE PROCESSOR
    141  1.1      mw             HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
    142  1.1      mw             MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!     */
    143  1.1      mw 
    144  1.1      mw    struct MonDef MON_1280_1024_60= {110000000,  24, 1280,1024,  161,162,176,211,208,1025,1026,1043,1073,1073,
    145  1.9  chopps           4, NCRStdPalette,160, 128, 20480,    8,     8, kernel_font_8x8,   32,  255};
    146  1.1      mw 
    147  1.4      mw  struct MonDef MON_1280_1024_60_G= {110000000,   0, 1280,1024,  321,322,349,422,421,1025,1026,1043,1073,1073,
    148  1.9  chopps           8, NCRStdPalette,1280,1024, 20480,    8,     8, kernel_font_8x8,   32,  255};
    149  1.4      mw 
    150  1.1      mw /* horizontal 75kHz */
    151  1.1      mw 
    152  1.1      mw    struct MonDef MON_1280_1024_69= {120000000,  24, 1280,1024,  161,162,175,200,197,1025,1026,1043,1073,1073,
    153  1.9  chopps           4, NCRStdPalette,160, 128, 20480,    8,     8, kernel_font_8x8,   32,  255};
    154  1.1      mw 
    155  1.1      mw #else
    156  1.1      mw 
    157  1.1      mw struct MonDef monitor_defs[] = {
    158  1.1      mw /* horizontal 31.5 kHz */
    159  1.1      mw 
    160  1.1      mw    { 50000000,  28,  640, 512,   81, 86, 93, 98, 95, 513, 513, 521, 535, 535,
    161  1.9  chopps           4, NCRStdPalette, 80,  64,  5120,    8,     8, kernel_font_8x8,   32,  255},
    162  1.1      mw 
    163  1.1      mw /* horizontal 38kHz */
    164  1.1      mw 
    165  1.1      mw    { 75000000,  28,  768, 600,   97, 99,107,120,117, 601, 615, 625, 638, 638,
    166  1.9  chopps           4, NCRStdPalette, 96,  75,  7200,    8,     8, kernel_font_8x8,   32,  255},
    167  1.1      mw 
    168  1.1      mw /* horizontal 64kHz */
    169  1.1      mw 
    170  1.1      mw    { 50000000, 24,  768, 600,   97,104,112,122,119, 601, 606, 616, 628, 628,
    171  1.9  chopps           4, NCRStdPalette, 96,  75,  7200,    8,     8, kernel_font_8x8,   32,  255},
    172  1.4      mw 
    173  1.1      mw    { 90000000, 24, 1024, 768,  129,130,141,172,169, 769, 770, 783, 804, 804,
    174  1.9  chopps           4, NCRStdPalette,128,  96, 12288,    8,     8, kernel_font_8x8,   32,  255},
    175  1.1      mw 
    176  1.4      mw    /* GFX modes */
    177  1.2      mw 
    178  1.4      mw /* horizontal 31.5 kHz */
    179  1.2      mw 
    180  1.4      mw    { 50000000,   4,  640, 480,  161,171,184,196,195, 481, 484, 492, 502, 502,
    181  1.9  chopps           8, NCRStdPalette,640, 480,  5120,    8,     8, kernel_font_8x8,   32,  255},
    182  1.2      mw 
    183  1.4      mw /* horizontal 64kHz */
    184  1.2      mw 
    185  1.4      mw    { 90000000, 0,  1024, 768,  257,258,280,344,343, 769, 770, 783, 804, 804,
    186  1.9  chopps           8, NCRStdPalette, 1024, 768, 12288,    8,     8, kernel_font_8x8,   32,  255},
    187  1.1      mw 
    188  1.1      mw /* WARNING: THE FOLLOWING MONITOR MODES EXCEED THE 90-MHz LIMIT THE PROCESSOR
    189  1.1      mw             HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
    190  1.1      mw             MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!     */
    191  1.1      mw 
    192  1.4      mw    {110000000,   0, 1280,1024,  321,322,349,422,421,1025,1026,1043,1073,1073,
    193  1.9  chopps           8, NCRStdPalette,1280,1024, 20480,    8,     8, kernel_font_8x8,   32,  255},
    194  1.1      mw };
    195  1.1      mw 
    196  1.1      mw static const char *monitor_descr[] = {
    197  1.1      mw   "80x64 (640x512) 31.5kHz",
    198  1.1      mw   "96x75 (768x600) 38kHz",
    199  1.1      mw   "96x75 (768x600) 64kHz",
    200  1.1      mw   "128x96 (1024x768) 64kHz",
    201  1.4      mw 
    202  1.4      mw   "GFX (640x480) 31.5kHz",
    203  1.4      mw   "GFX (1024x768) 64kHz",
    204  1.4      mw   "GFX (1280x1024) 64kHz ***EXCEEDS CHIP LIMIT!!!***",
    205  1.1      mw };
    206  1.1      mw 
    207  1.1      mw int retina_mon_max = sizeof (monitor_defs)/sizeof (monitor_defs[0]);
    208  1.1      mw 
    209  1.1      mw /* patchable */
    210  1.1      mw int retina_default_mon = 2;
    211  1.4      mw int retina_default_gfx = 5;
    212  1.1      mw 
    213  1.1      mw #endif
    214  1.1      mw 
    215  1.1      mw 
    216  1.1      mw static struct MonDef *current_mon;
    217  1.1      mw 
    218  1.1      mw /* -------------- START OF CODE -------------- */
    219  1.1      mw 
    220  1.1      mw 
    221  1.1      mw static const long FQTab[16] =
    222  1.1      mw { 25175000,  28322000,  36000000,  65000000,
    223  1.1      mw   44900000,  50000000,  80000000,  75000000,
    224  1.1      mw   56644000,  63000000,  72000000, 130000000,
    225  1.1      mw   90000000, 100000000, 110000000, 120000000 };
    226  1.1      mw 
    227  1.1      mw 
    228  1.1      mw /*--------------------------------------------------*/
    229  1.1      mw /*--------------------------------------------------*/
    230  1.1      mw 
    231  1.1      mw #if 0
    232  1.1      mw static struct MonDef *default_monitor = &DEFAULT_MONDEF;
    233  1.1      mw #endif
    234  1.1      mw 
    235  1.1      mw 
    236  1.1      mw static int rt_load_mon (struct grf_softc *gp, struct MonDef *md)
    237  1.1      mw {
    238  1.1      mw 	struct grfinfo *gi = &gp->g_display;
    239  1.1      mw 	volatile unsigned char *ba;
    240  1.1      mw 	volatile unsigned char *fb;
    241  1.1      mw 	short FW, clksel, HDE, VDE;
    242  1.1      mw 
    243  1.1      mw 	for (clksel = 15; clksel; clksel--) {
    244  1.1      mw 		if (FQTab[clksel] == md->FQ) break;
    245  1.1      mw 	}
    246  1.1      mw 	if (clksel < 0) return 0;
    247  1.1      mw 
    248  1.1      mw 	ba = gp->g_regkva;;
    249  1.1      mw 	fb = gp->g_fbkva;
    250  1.4      mw 
    251  1.4      mw 	FW = 0;
    252  1.4      mw 	if (md->DEP == 4) {
    253  1.4      mw 		switch (md->FX) {
    254  1.4      mw 		case 4:
    255  1.4      mw 			FW = 0;
    256  1.4      mw 			break;
    257  1.4      mw 		case 7:
    258  1.4      mw 			FW = 1;
    259  1.4      mw 			break;
    260  1.4      mw 		case 8:
    261  1.4      mw 			FW = 2;
    262  1.4      mw 			break;
    263  1.4      mw 		case 9:
    264  1.4      mw 			FW = 3;
    265  1.4      mw 			break;
    266  1.4      mw 		case 10:
    267  1.4      mw 			FW = 4;
    268  1.4      mw 			break;
    269  1.4      mw 		case 11:
    270  1.4      mw 			FW = 5;
    271  1.4      mw 			break;
    272  1.4      mw 		case 12:
    273  1.4      mw 			FW = 6;
    274  1.4      mw 			break;
    275  1.4      mw 		case 13:
    276  1.4      mw 			FW = 7;
    277  1.4      mw 			break;
    278  1.4      mw 		case 14:
    279  1.4      mw 			FW = 8;
    280  1.4      mw 			break;
    281  1.4      mw 		case 15:
    282  1.4      mw 			FW = 9;
    283  1.4      mw 			break;
    284  1.4      mw 		case 16:
    285  1.4      mw 			FW = 11;
    286  1.4      mw 			break;
    287  1.4      mw 		default:
    288  1.4      mw 			return 0;
    289  1.4      mw 			break;
    290  1.4      mw 		};
    291  1.4      mw 	}
    292  1.1      mw 
    293  1.4      mw         if (md->DEP == 4) HDE = (md->MW+md->FX-1)/md->FX;
    294  1.4      mw         else              HDE = (md->MW+3)/4;
    295  1.1      mw 	VDE = md->MH-1;
    296  1.1      mw 
    297  1.1      mw 	/* hmm... */
    298  1.1      mw 	fb[0x8000] = 0;
    299  1.1      mw 
    300  1.2      mw 		/* enable extension registers */
    301  1.2      mw 	WSeq (ba, SEQ_ID_EXTENDED_ENABLE,	0x05);
    302  1.2      mw 
    303  1.2      mw #if 0
    304  1.1      mw 	/* program the clock oscillator */
    305  1.1      mw 	vgaw (ba, GREG_MISC_OUTPUT_W, 0xe3 | ((clksel & 3) * 0x04));
    306  1.1      mw 	vgaw (ba, GREG_FEATURE_CONTROL_W, 0x00);
    307  1.1      mw 
    308  1.1      mw 	/* XXXX according to the NCR specs, this register should be set to 1
    309  1.1      mw 	   XXXX before doing the MISC_OUTPUT setting and CLOCKING_MODE
    310  1.1      mw 	   XXXX setting. */
    311  1.1      mw 	WSeq (ba, SEQ_ID_RESET, 		0x03);
    312  1.1      mw 
    313  1.1      mw 	WSeq (ba, SEQ_ID_CLOCKING_MODE, 	0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8));
    314  1.1      mw 	WSeq (ba, SEQ_ID_MAP_MASK, 		0x0f);
    315  1.1      mw 	WSeq (ba, SEQ_ID_CHAR_MAP_SELECT, 	0x00);
    316  1.1      mw 		/* odd/even write select + extended memory */
    317  1.1      mw 	WSeq (ba, SEQ_ID_MEMORY_MODE, 	0x06);
    318  1.1      mw 	/* XXXX I think this order of setting RESET is wrong... */
    319  1.1      mw 	WSeq (ba, SEQ_ID_RESET, 		0x01);
    320  1.1      mw 	WSeq (ba, SEQ_ID_RESET, 		0x03);
    321  1.2      mw #else
    322  1.2      mw 	WSeq (ba, SEQ_ID_RESET, 		0x01);
    323  1.2      mw 
    324  1.2      mw 		/* set font width + rest of clocks */
    325  1.2      mw 	WSeq (ba, SEQ_ID_EXT_CLOCK_MODE,	0x30 | (FW & 0x0f) | ((clksel & 4) / 4 * 0x40) );
    326  1.2      mw 		/* another clock bit, plus hw stuff */
    327  1.2      mw 	WSeq (ba, SEQ_ID_MISC_FEATURE_SEL,	0xf4 | (clksel & 8) );
    328  1.2      mw 
    329  1.2      mw 	/* program the clock oscillator */
    330  1.2      mw 	vgaw (ba, GREG_MISC_OUTPUT_W, 		0xe3 | ((clksel & 3) * 0x04));
    331  1.2      mw 	vgaw (ba, GREG_FEATURE_CONTROL_W, 	0x00);
    332  1.2      mw 
    333  1.2      mw 	WSeq (ba, SEQ_ID_CLOCKING_MODE, 	0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8));
    334  1.2      mw 	WSeq (ba, SEQ_ID_MAP_MASK, 		0x0f);
    335  1.2      mw 	WSeq (ba, SEQ_ID_CHAR_MAP_SELECT, 	0x00);
    336  1.2      mw 		/* odd/even write select + extended memory */
    337  1.2      mw 	WSeq (ba, SEQ_ID_MEMORY_MODE, 		0x06);
    338  1.2      mw 	WSeq (ba, SEQ_ID_RESET, 		0x03);
    339  1.2      mw #endif
    340  1.1      mw 
    341  1.1      mw 		/* monochrome cursor */
    342  1.1      mw 	WSeq (ba, SEQ_ID_CURSOR_CONTROL,	0x00);
    343  1.1      mw 		/* bank0 */
    344  1.1      mw 	WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI,	0x00);
    345  1.1      mw 	WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO,	0x00);
    346  1.4      mw 	WSeq (ba, SEQ_ID_DISP_OFF_HI , 		0x00);
    347  1.4      mw 	WSeq (ba, SEQ_ID_DISP_OFF_LO , 		0x00);
    348  1.1      mw 		/* bank0 */
    349  1.1      mw 	WSeq (ba, SEQ_ID_SEC_HOST_OFF_HI,	0x00);
    350  1.1      mw 	WSeq (ba, SEQ_ID_SEC_HOST_OFF_LO,	0x00);
    351  1.1      mw 		/* 1M-chips + ena SEC + ena EMem + rw PrimA0/rw Sec/B0 */
    352  1.1      mw 	WSeq (ba, SEQ_ID_EXTENDED_MEM_ENA,	0x3 | 0x4 | 0x10 | 0x40);
    353  1.2      mw #if 0
    354  1.1      mw 		/* set font width + rest of clocks */
    355  1.1      mw 	WSeq (ba, SEQ_ID_EXT_CLOCK_MODE,	0x30 | (FW & 0x0f) | ((clksel & 4) / 4 * 0x40) );
    356  1.2      mw #endif
    357  1.4      mw 	if (md->DEP == 4) {
    358  1.4      mw 			/* no ext-chain4 + no host-addr-bit-16 */
    359  1.4      mw 		WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR,	0x00);
    360  1.4      mw 			/* no packed/nibble + no 256bit gfx format */
    361  1.4      mw 		WSeq (ba, SEQ_ID_EXT_PIXEL_CNTL,	0x00);
    362  1.4      mw 	}
    363  1.4      mw 	else {
    364  1.4      mw 		WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR,	0x02);
    365  1.4      mw 			/* 256bit gfx format */
    366  1.4      mw 		WSeq (ba, SEQ_ID_EXT_PIXEL_CNTL,	0x01);
    367  1.4      mw 	}
    368  1.1      mw 		/* AT-interface */
    369  1.1      mw 	WSeq (ba, SEQ_ID_BUS_WIDTH_FEEDB,	0x06);
    370  1.1      mw 		/* see fg/bg color expansion */
    371  1.1      mw 	WSeq (ba, SEQ_ID_COLOR_EXP_WFG,		0x01);
    372  1.1      mw 	WSeq (ba, SEQ_ID_COLOR_EXP_WBG,		0x00);
    373  1.1      mw 	WSeq (ba, SEQ_ID_EXT_RW_CONTROL,	0x00);
    374  1.2      mw #if 0
    375  1.1      mw 		/* another clock bit, plus hw stuff */
    376  1.1      mw 	WSeq (ba, SEQ_ID_MISC_FEATURE_SEL,	0xf4 | (clksel & 8) );
    377  1.2      mw #endif
    378  1.1      mw 		/* don't tristate PCLK and PIX */
    379  1.1      mw 	WSeq (ba, SEQ_ID_COLOR_KEY_CNTL,	0x40 );
    380  1.1      mw 		/* reset CRC circuit */
    381  1.1      mw 	WSeq (ba, SEQ_ID_CRC_CONTROL,		0x00 );
    382  1.1      mw 		/* set RAS/CAS swap */
    383  1.1      mw 	WSeq (ba, SEQ_ID_PERF_SELECT,		0x20);
    384  1.1      mw 
    385  1.1      mw 	WCrt (ba, CRT_ID_END_VER_RETR,		(md->VSE & 0xf ) | 0x20);
    386  1.1      mw 	WCrt (ba, CRT_ID_HOR_TOTAL,		md->HT   & 0xff);
    387  1.1      mw 	WCrt (ba, CRT_ID_HOR_DISP_ENA_END,	(HDE-1)  & 0xff);
    388  1.1      mw 	WCrt (ba, CRT_ID_START_HOR_BLANK,	md->HBS  & 0xff);
    389  1.1      mw 	WCrt (ba, CRT_ID_END_HOR_BLANK,		(md->HBE & 0x1f) | 0x80);
    390  1.1      mw 
    391  1.1      mw 	WCrt (ba, CRT_ID_START_HOR_RETR,	md->HSS  & 0xff);
    392  1.1      mw 	WCrt (ba, CRT_ID_END_HOR_RETR,		(md->HSE & 0x1f) | ((md->HBE & 0x20)/ 0x20 * 0x80));
    393  1.1      mw 	WCrt (ba, CRT_ID_VER_TOTAL,		(md->VT  & 0xff));
    394  1.1      mw 	WCrt (ba, CRT_ID_OVERFLOW,		(( (md->VSS  & 0x200) / 0x200 * 0x80)
    395  1.1      mw 						 | ((VDE     & 0x200) / 0x200 * 0x40)
    396  1.1      mw 						 | ((md->VT  & 0x200) / 0x200 * 0x20)
    397  1.1      mw 						 | 				0x10
    398  1.1      mw 						 | ((md->VBS & 0x100) / 0x100 * 8   )
    399  1.1      mw 						 | ((md->VSS & 0x100) / 0x100 * 4   )
    400  1.1      mw 						 | ((VDE     & 0x100) / 0x100 * 2   )
    401  1.1      mw 						 | ((md->VT  & 0x100) / 0x100       )));
    402  1.1      mw 	WCrt (ba, CRT_ID_PRESET_ROW_SCAN,	0x00);
    403  1.1      mw 
    404  1.4      mw 	if (md->DEP == 4) {
    405  1.4      mw 		WCrt (ba, CRT_ID_MAX_SCAN_LINE, 	((  (md->FLG & MDF_DBL)/ MDF_DBL * 0x80)
    406  1.4      mw 							 | 				   0x40
    407  1.4      mw 							 | ((md->VBS & 0x200)/0x200	 * 0x20)
    408  1.4      mw 							 | ((md->FY-1) 			 & 0x1f)));
    409  1.4      mw 	}
    410  1.4      mw 	else {
    411  1.4      mw 		WCrt (ba, CRT_ID_MAX_SCAN_LINE, 	((  (md->FLG & MDF_DBL)/ MDF_DBL * 0x80)
    412  1.4      mw 							 | 				   0x40
    413  1.4      mw 							 | ((md->VBS & 0x200)/0x200	 * 0x20)
    414  1.4      mw 							 | (0	 			 & 0x1f)));
    415  1.4      mw 	}
    416  1.1      mw 
    417  1.1      mw 	WCrt (ba, CRT_ID_CURSOR_START,		(md->FY & 0x1f) - 2);
    418  1.1      mw 	WCrt (ba, CRT_ID_CURSOR_END,		(md->FY & 0x1f) - 1);
    419  1.1      mw 
    420  1.1      mw 	WCrt (ba, CRT_ID_START_ADDR_HIGH,	0x00);
    421  1.1      mw 	WCrt (ba, CRT_ID_START_ADDR_LOW,	0x00);
    422  1.1      mw 
    423  1.1      mw 	WCrt (ba, CRT_ID_CURSOR_LOC_HIGH,	0x00);
    424  1.1      mw 	WCrt (ba, CRT_ID_CURSOR_LOC_LOW,	0x00);
    425  1.1      mw 
    426  1.1      mw 	WCrt (ba, CRT_ID_START_VER_RETR,	md->VSS    & 0xff);
    427  1.1      mw 	WCrt (ba, CRT_ID_END_VER_RETR,		(md->VSE   & 0x0f) | 0x80 | 0x20);
    428  1.1      mw 	WCrt (ba, CRT_ID_VER_DISP_ENA_END,	VDE        & 0xff);
    429  1.4      mw 	if (md->DEP == 4)
    430  1.4      mw 		WCrt (ba, CRT_ID_OFFSET,	(HDE / 2)  & 0xff);
    431  1.4      mw 	else
    432  1.4      mw 		WCrt (ba, CRT_ID_OFFSET,	(md->TX / 8)  & 0xff);
    433  1.4      mw 
    434  1.1      mw 	WCrt (ba, CRT_ID_UNDERLINE_LOC,		(md->FY-1) & 0x1f);
    435  1.1      mw 	WCrt (ba, CRT_ID_START_VER_BLANK,	md->VBS    & 0xff);
    436  1.1      mw 	WCrt (ba, CRT_ID_END_VER_BLANK,		md->VBE    & 0xff);
    437  1.1      mw 		/* byte mode + wrap + select row scan counter + cms */
    438  1.1      mw 	WCrt (ba, CRT_ID_MODE_CONTROL,		0xe3);
    439  1.1      mw 	WCrt (ba, CRT_ID_LINE_COMPARE,		0xff);
    440  1.1      mw 
    441  1.1      mw 		/* enable extended end bits + those bits */
    442  1.1      mw 	WCrt (ba, CRT_ID_EXT_HOR_TIMING1,	(           				 0x20
    443  1.1      mw 						 | ((md->FLG & MDF_LACE)  / MDF_LACE   * 0x10)
    444  1.1      mw 						 | ((md->HT  & 0x100) / 0x100          * 0x01)
    445  1.1      mw 						 | (((HDE-1) & 0x100) / 0x100 	       * 0x02)
    446  1.1      mw 						 | ((md->HBS & 0x100) / 0x100 	       * 0x04)
    447  1.1      mw 						 | ((md->HSS & 0x100) / 0x100 	       * 0x08)));
    448  1.1      mw 
    449  1.4      mw 	if (md->DEP == 4)
    450  1.4      mw 		WCrt (ba, CRT_ID_EXT_START_ADDR,	(((HDE / 2) & 0x100)/0x100 * 16));
    451  1.4      mw 	else
    452  1.4      mw 		WCrt (ba, CRT_ID_EXT_START_ADDR,	(((md->TX / 8) & 0x100)/0x100 * 16));
    453  1.1      mw 
    454  1.1      mw 	WCrt (ba, CRT_ID_EXT_HOR_TIMING2, 	(  ((md->HT  & 0x200)/ 0x200  	       * 0x01)
    455  1.1      mw 						 | (((HDE-1) & 0x200)/ 0x200 	       * 0x02)
    456  1.1      mw 						 | ((md->HBS & 0x200)/ 0x200 	       * 0x04)
    457  1.1      mw 						 | ((md->HSS & 0x200)/ 0x200 	       * 0x08)
    458  1.1      mw 						 | ((md->HBE & 0xc0) / 0x40  	       * 0x10)
    459  1.1      mw 						 | ((md->HSE & 0x60) / 0x20  	       * 0x40)));
    460  1.1      mw 
    461  1.1      mw 	WCrt (ba, CRT_ID_EXT_VER_TIMING,	(  ((md->VSE & 0x10) / 0x10  	       * 0x80)
    462  1.1      mw 						 | ((md->VBE & 0x300)/ 0x100 	       * 0x20)
    463  1.1      mw 						 |				         0x10
    464  1.1      mw 						 | ((md->VSS & 0x400)/ 0x400 	       * 0x08)
    465  1.1      mw 						 | ((md->VBS & 0x400)/ 0x400 	       * 0x04)
    466  1.1      mw 						 | ((VDE     & 0x400)/ 0x400 	       * 0x02)
    467  1.1      mw 						 | ((md->VT  & 0x400)/ 0x400           * 0x01)));
    468  1.1      mw 
    469  1.1      mw 	WGfx (ba, GCT_ID_SET_RESET,		0x00);
    470  1.1      mw 	WGfx (ba, GCT_ID_ENABLE_SET_RESET,	0x00);
    471  1.1      mw 	WGfx (ba, GCT_ID_COLOR_COMPARE,		0x00);
    472  1.1      mw 	WGfx (ba, GCT_ID_DATA_ROTATE,		0x00);
    473  1.1      mw 	WGfx (ba, GCT_ID_READ_MAP_SELECT,	0x00);
    474  1.4      mw 	WGfx (ba, GCT_ID_GRAPHICS_MODE,		0x00);
    475  1.4      mw 	if (md->DEP == 4)
    476  1.4      mw 		WGfx (ba, GCT_ID_MISC,			0x04);
    477  1.4      mw 	else
    478  1.4      mw 		WGfx (ba, GCT_ID_MISC,			0x05);
    479  1.1      mw 	WGfx (ba, GCT_ID_COLOR_XCARE,		0xff);
    480  1.1      mw 	WGfx (ba, GCT_ID_BITMASK,		0xff);
    481  1.1      mw 
    482  1.1      mw 	/* reset the Attribute Controller flipflop */
    483  1.1      mw 	vgar (ba, GREG_STATUS1_R);
    484  1.1      mw 	WAttr (ba, ACT_ID_PALETTE0,		0x00);
    485  1.1      mw 	WAttr (ba, ACT_ID_PALETTE1,		0x01);
    486  1.1      mw 	WAttr (ba, ACT_ID_PALETTE2,		0x02);
    487  1.1      mw 	WAttr (ba, ACT_ID_PALETTE3,		0x03);
    488  1.1      mw 	WAttr (ba, ACT_ID_PALETTE4,		0x04);
    489  1.1      mw 	WAttr (ba, ACT_ID_PALETTE5,		0x05);
    490  1.1      mw 	WAttr (ba, ACT_ID_PALETTE6,		0x06);
    491  1.1      mw 	WAttr (ba, ACT_ID_PALETTE7,		0x07);
    492  1.1      mw 	WAttr (ba, ACT_ID_PALETTE8,		0x08);
    493  1.1      mw 	WAttr (ba, ACT_ID_PALETTE9,		0x09);
    494  1.1      mw 	WAttr (ba, ACT_ID_PALETTE10,		0x0a);
    495  1.1      mw 	WAttr (ba, ACT_ID_PALETTE11,		0x0b);
    496  1.1      mw 	WAttr (ba, ACT_ID_PALETTE12,		0x0c);
    497  1.1      mw 	WAttr (ba, ACT_ID_PALETTE13,		0x0d);
    498  1.1      mw 	WAttr (ba, ACT_ID_PALETTE14,		0x0e);
    499  1.1      mw 	WAttr (ba, ACT_ID_PALETTE15,		0x0f);
    500  1.1      mw 
    501  1.1      mw 	vgar (ba, GREG_STATUS1_R);
    502  1.4      mw 	if (md->DEP == 4)
    503  1.4      mw 		WAttr (ba, ACT_ID_ATTR_MODE_CNTL,	0x08);
    504  1.4      mw 	else
    505  1.4      mw 		WAttr (ba, ACT_ID_ATTR_MODE_CNTL,	0x09);
    506  1.1      mw 
    507  1.1      mw 	WAttr (ba, ACT_ID_OVERSCAN_COLOR,	0x00);
    508  1.1      mw 	WAttr (ba, ACT_ID_COLOR_PLANE_ENA,	0x0f);
    509  1.1      mw 	WAttr (ba, ACT_ID_HOR_PEL_PANNING,	0x00);
    510  1.1      mw 	WAttr (ba, ACT_ID_COLOR_SELECT,	0x00);
    511  1.1      mw 
    512  1.1      mw 	vgar (ba, GREG_STATUS1_R);
    513  1.1      mw 		/* I have *NO* idea what strobing reg-0x20 might do... */
    514  1.1      mw 	vgaw (ba, ACT_ADDRESS_W, 0x20);
    515  1.1      mw 
    516  1.4      mw 	if (md->DEP == 4)
    517  1.4      mw 		WCrt (ba, CRT_ID_MAX_SCAN_LINE,	( ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80)
    518  1.1      mw 						|	                          0x40
    519  1.1      mw 						| ((md->VBS & 0x200)/0x200	* 0x20)
    520  1.4      mw 						| ((md->FY-1) 			& 0x1f)));
    521  1.4      mw 	else
    522  1.4      mw 		WCrt (ba, CRT_ID_MAX_SCAN_LINE,	( ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80)
    523  1.4      mw 						|	                          0x40
    524  1.4      mw 						| ((md->VBS & 0x200)/0x200	* 0x20)
    525  1.4      mw 						| (0	 			& 0x1f)));
    526  1.4      mw 
    527  1.1      mw 
    528  1.1      mw 	/* not it's time for guessing... */
    529  1.1      mw 
    530  1.1      mw 	vgaw (ba, VDAC_REG_D, 	   0x02);
    531  1.1      mw 
    532  1.1      mw 		/* if this does what I think it does, it selects DAC
    533  1.1      mw 		   register 0, and writes the palette in subsequent
    534  1.1      mw 		   registers, thus it works similar to the WD33C93
    535  1.1      mw 		   select/data mechanism */
    536  1.1      mw 	vgaw (ba, VDAC_REG_SELECT, 0x00);
    537  1.1      mw 
    538  1.1      mw 	{
    539  1.1      mw 
    540  1.1      mw 		short x = 15;
    541  1.1      mw 		const unsigned char * col = md->PAL;
    542  1.1      mw 		do {
    543  1.1      mw 
    544  1.1      mw 			vgaw (ba, VDAC_REG_DATA, *col++);
    545  1.1      mw 			vgaw (ba, VDAC_REG_DATA, *col++);
    546  1.1      mw 			vgaw (ba, VDAC_REG_DATA, *col++);
    547  1.1      mw 
    548  1.1      mw 
    549  1.1      mw 		} while (x--);
    550  1.4      mw 
    551  1.4      mw 		if (md->DEP != 4) {
    552  1.4      mw 			short x = 256-17;
    553  1.4      mw 			unsigned char col = 16;
    554  1.4      mw 			do {
    555  1.4      mw 
    556  1.4      mw 				vgaw(ba, VDAC_REG_DATA, col);
    557  1.4      mw 				vgaw(ba, VDAC_REG_DATA, col);
    558  1.4      mw 				vgaw(ba, VDAC_REG_DATA, col);
    559  1.4      mw 				col++;
    560  1.4      mw 
    561  1.4      mw 			} while (x--);
    562  1.4      mw 		}
    563  1.1      mw 	}
    564  1.1      mw 
    565  1.1      mw 
    566  1.1      mw 	/* now load the font into maps 2 (and 3 for fonts wider than 8 pixels) */
    567  1.4      mw 	if (md->DEP == 4) {
    568  1.1      mw 
    569  1.1      mw 		/* first set the whole font memory to a test-pattern, so we
    570  1.1      mw 		   can see if something that shouldn't be drawn IS drawn.. */
    571  1.1      mw 		{
    572  1.5  chopps 			volatile unsigned char * c = fb;
    573  1.1      mw 			long x;
    574  1.1      mw 			Map(2);
    575  1.1      mw 
    576  1.1      mw 			for (x = 0; x < 65536; x++) {
    577  1.1      mw 				*c++ = (x & 1)? 0xaa : 0x55;
    578  1.1      mw 			}
    579  1.1      mw 		}
    580  1.1      mw 
    581  1.1      mw 		{
    582  1.5  chopps 			volatile unsigned char * c = fb;
    583  1.1      mw 			long x;
    584  1.1      mw 			Map(3);
    585  1.1      mw 
    586  1.1      mw 			for (x = 0; x < 65536; x++) {
    587  1.1      mw 				*c++ = (x & 1)? 0xaa : 0x55;
    588  1.1      mw 			}
    589  1.1      mw 		}
    590  1.1      mw 
    591  1.1      mw 		{
    592  1.1      mw 		  /* ok, now position at first defined character, and
    593  1.1      mw 		     copy over the images */
    594  1.5  chopps 		  volatile unsigned char * c = fb + md->FLo * 32;
    595  1.1      mw 		  const unsigned char * f = md->FData;
    596  1.1      mw 		  unsigned short z;
    597  1.1      mw 
    598  1.1      mw 		  Map(2);
    599  1.1      mw 		  for (z = md->FLo; z <= md->FHi; z++) {
    600  1.1      mw 
    601  1.1      mw 			short y = md->FY-1;
    602  1.1      mw 			if (md->FX > 8){
    603  1.1      mw 				do {
    604  1.1      mw 					*c++ = *f;
    605  1.1      mw 					f += 2;
    606  1.1      mw 				} while (y--);
    607  1.1      mw 			}
    608  1.1      mw 			else {
    609  1.1      mw 				do {
    610  1.1      mw 					*c++ = *f++;
    611  1.1      mw 				} while (y--);
    612  1.1      mw 			}
    613  1.1      mw 
    614  1.1      mw 			c += 32-md->FY;
    615  1.1      mw 
    616  1.1      mw 		  }
    617  1.1      mw 
    618  1.1      mw 		  if (md->FX > 8) {
    619  1.1      mw 			unsigned short z;
    620  1.1      mw 
    621  1.1      mw 			Map(3);
    622  1.1      mw 			c = fb + md->FLo*32;
    623  1.1      mw 			f = md->FData+1;
    624  1.1      mw 			for (z = md->FLo; z <= md->FHi; z++) {
    625  1.1      mw 
    626  1.1      mw 				short y = md->FY-1;
    627  1.1      mw 				do {
    628  1.1      mw 					*c++ = *f;
    629  1.1      mw 					f += 2;
    630  1.1      mw 				} while (y--);
    631  1.1      mw 
    632  1.1      mw 				c += 32-md->FY;
    633  1.1      mw 
    634  1.1      mw 			}
    635  1.1      mw 		  }
    636  1.1      mw 		}
    637  1.1      mw 
    638  1.1      mw 	}
    639  1.1      mw 
    640  1.1      mw 		/* select map 0 */
    641  1.1      mw 	WGfx (ba, GCT_ID_READ_MAP_SELECT,	0);
    642  1.4      mw 	if (md->DEP == 4)
    643  1.4      mw 			/* allow writes into maps 0 and 1 */
    644  1.4      mw 		WSeq (ba, SEQ_ID_MAP_MASK,		3);
    645  1.4      mw 	else
    646  1.4      mw 			/* allow writes into all maps */
    647  1.4      mw 		WSeq (ba, SEQ_ID_MAP_MASK,		0x0f);
    648  1.4      mw 
    649  1.1      mw 		/* select extended chain4 addressing:
    650  1.1      mw 		    !A0/!A1	map 0	character to be displayed
    651  1.1      mw 		    !A1/ A1	map 1	attribute of that character
    652  1.1      mw 		     A0/!A1	map 2	not used (masked out, ignored)
    653  1.1      mw 		     A0/ A1 	map 3	not used (masked out, ignored) */
    654  1.1      mw 	WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR,	RSeq(ba, SEQ_ID_EXT_VIDEO_ADDR) | 0x02);
    655  1.1      mw 
    656  1.4      mw 	if (md->DEP == 4) {
    657  1.1      mw 		/* position in display memory */
    658  1.1      mw 		unsigned short * c = (unsigned short *) fb;
    659  1.1      mw 
    660  1.1      mw 		/* fill with blank, white on black */
    661  1.1      mw 		const unsigned short fill_val = 0x2010;
    662  1.1      mw 		short x = md->XY;
    663  1.1      mw 		do {
    664  1.1      mw 			*c = fill_val;
    665  1.1      mw 			c += 2;
    666  1.1      mw 		} while (x--);
    667  1.1      mw 
    668  1.1      mw 		/* I won't comment this :-)) */
    669  1.1      mw 		c = (unsigned short *) fb;
    670  1.1      mw 		c += (md->TX-6)*2;
    671  1.1      mw 		{
    672  1.1      mw 		  unsigned short init_msg[6] = {0x520a, 0x450b, 0x540c, 0x490d, 0x4e0e, 0x410f};
    673  1.1      mw 		  unsigned short * f = init_msg;
    674  1.1      mw 		  x = 5;
    675  1.1      mw 		  do {
    676  1.1      mw 			*c = *f++;
    677  1.1      mw 			c += 2;
    678  1.1      mw 	 	  } while (x--);
    679  1.1      mw 	 	}
    680  1.1      mw 	}
    681  1.4      mw 	else if (md->DEP == 8) {
    682  1.4      mw 		/* could clear the gfx screen here, but that's what the X server does anyway */
    683  1.4      mw 	        ;
    684  1.4      mw 	}
    685  1.1      mw 
    686  1.3      mw 	gp->g_data	= (caddr_t) md;
    687  1.5  chopps 	gi->gd_regaddr  = (caddr_t) ((long)ba - (long)ZORRO2ADDR + (long)ZORRO2BASE);
    688  1.3      mw 	gi->gd_regsize  = 64*1024;
    689  1.1      mw 
    690  1.5  chopps 	gi->gd_fbaddr   = (caddr_t) ((long)fb - (long)ZORRO2ADDR + (long)ZORRO2BASE);
    691  1.4      mw #ifdef BANKEDDEVPAGER
    692  1.4      mw 	gi->gd_fbsize	= 4*1024*1024;  /* XXX */
    693  1.4      mw 	gi->gd_bank_size = 64*1024;
    694  1.4      mw #else
    695  1.1      mw 	gi->gd_fbsize   = 64*1024;	/* larger, but that's whats mappable */
    696  1.4      mw #endif
    697  1.1      mw 
    698  1.1      mw 	gi->gd_colors   = 1 << md->DEP;
    699  1.1      mw 	gi->gd_planes   = md->DEP;
    700  1.1      mw 
    701  1.1      mw 	gi->gd_fbwidth  = md->MW;
    702  1.1      mw 	gi->gd_fbheight = md->MH;
    703  1.1      mw 	gi->gd_fbx	= 0;
    704  1.1      mw 	gi->gd_fby	= 0;
    705  1.1      mw 	gi->gd_dwidth   = md->TX * md->FX;
    706  1.1      mw 	gi->gd_dheight  = md->TY * md->FY;
    707  1.1      mw 	gi->gd_dx	= 0;
    708  1.1      mw 	gi->gd_dy	= 0;
    709  1.1      mw 
    710  1.1      mw 	/* initialized, works, return 1 */
    711  1.1      mw 	return 1;
    712  1.1      mw }
    713  1.1      mw 
    714  1.1      mw int rt_init (struct grf_softc *gp, struct amiga_device *ad, struct amiga_hw *ahw)
    715  1.1      mw {
    716  1.1      mw   /* if already initialized, fail */
    717  1.1      mw   if (gp->g_regkva)
    718  1.1      mw     return 0;
    719  1.1      mw 
    720  1.1      mw   gp->g_regkva = ahw->hw_kva;
    721  1.1      mw   gp->g_fbkva  = ahw->hw_kva + 64*1024;
    722  1.1      mw 
    723  1.1      mw   /* don't let them patch it out of bounds */
    724  1.4      mw   if ((unsigned)retina_default_mon >= retina_mon_max
    725  1.4      mw       || monitor_defs[retina_default_mon].DEP == 8)
    726  1.1      mw     retina_default_mon = 0;
    727  1.1      mw 
    728  1.1      mw   current_mon = monitor_defs + retina_default_mon;
    729  1.1      mw 
    730  1.8  chopps   if (rt_load_mon (gp, current_mon))
    731  1.8  chopps 	  retina_inited = rt_load_mon(gp, current_mon);
    732  1.8  chopps 
    733  1.8  chopps   return(retina_inited);		/* XXX Markus maybe you */
    734  1.8  chopps 					/* XXX can make this cleaner. */
    735  1.1      mw }
    736  1.1      mw 
    737  1.1      mw static int
    738  1.1      mw rt_getvmode (gp, vm)
    739  1.1      mw      struct grf_softc *gp;
    740  1.1      mw      struct grfvideo_mode *vm;
    741  1.1      mw {
    742  1.1      mw   struct MonDef *md;
    743  1.1      mw 
    744  1.1      mw   if (vm->mode_num && vm->mode_num > retina_mon_max)
    745  1.1      mw     return EINVAL;
    746  1.1      mw 
    747  1.1      mw   if (! vm->mode_num)
    748  1.1      mw     vm->mode_num = (current_mon - monitor_defs) + 1;
    749  1.1      mw 
    750  1.1      mw   md = monitor_defs + (vm->mode_num - 1);
    751  1.1      mw   strncpy (vm->mode_descr, monitor_descr + (vm->mode_num - 1),
    752  1.1      mw 	   sizeof (vm->mode_descr));
    753  1.1      mw   vm->pixel_clock  = md->FQ;
    754  1.1      mw   vm->disp_width   = md->MW;
    755  1.1      mw   vm->disp_height  = md->MH;
    756  1.1      mw   vm->depth        = md->DEP;
    757  1.1      mw   vm->hblank_start = md->HBS;
    758  1.1      mw   vm->hblank_stop  = md->HBE;
    759  1.1      mw   vm->hsync_start  = md->HSS;
    760  1.1      mw   vm->hsync_stop   = md->HSE;
    761  1.1      mw   vm->htotal       = md->HT;
    762  1.1      mw   vm->vblank_start = md->VBS;
    763  1.1      mw   vm->vblank_stop  = md->VBE;
    764  1.1      mw   vm->vsync_start  = md->VSS;
    765  1.1      mw   vm->vsync_stop   = md->VSE;
    766  1.1      mw   vm->vtotal       = md->VT;
    767  1.1      mw 
    768  1.1      mw   return 0;
    769  1.1      mw }
    770  1.1      mw 
    771  1.1      mw 
    772  1.1      mw static int
    773  1.4      mw rt_setvmode (gp, mode, txtonly)
    774  1.1      mw      struct grf_softc *gp;
    775  1.1      mw      unsigned mode;
    776  1.4      mw      int txtonly;
    777  1.1      mw {
    778  1.1      mw   struct MonDef *md;
    779  1.4      mw   int error;
    780  1.1      mw 
    781  1.1      mw   if (!mode || mode > retina_mon_max)
    782  1.1      mw     return EINVAL;
    783  1.1      mw 
    784  1.4      mw   if (txtonly && monitor_defs[mode-1].DEP == 8)
    785  1.4      mw     return EINVAL;
    786  1.4      mw 
    787  1.1      mw   current_mon = monitor_defs + (mode - 1);
    788  1.4      mw 
    789  1.4      mw   error = rt_load_mon (gp, current_mon) ? 0 : EINVAL;
    790  1.4      mw 
    791  1.4      mw   return error;
    792  1.1      mw }
    793  1.1      mw 
    794  1.1      mw 
    795  1.1      mw /*
    796  1.1      mw  * Change the mode of the display.
    797  1.1      mw  * Return a UNIX error number or 0 for success.
    798  1.1      mw  */
    799  1.4      mw rt_mode(gp, cmd, arg, a2, a3)
    800  1.1      mw 	register struct grf_softc *gp;
    801  1.1      mw 	int cmd;
    802  1.1      mw 	void *arg;
    803  1.4      mw 	int a2, a3;
    804  1.1      mw {
    805  1.1      mw   /* implement these later... */
    806  1.1      mw 
    807  1.1      mw   switch (cmd)
    808  1.1      mw     {
    809  1.1      mw     case GM_GRFON:
    810  1.4      mw       rt_setvmode (gp, retina_default_gfx + 1, 0);
    811  1.1      mw       return 0;
    812  1.1      mw 
    813  1.1      mw     case GM_GRFOFF:
    814  1.4      mw       rt_setvmode (gp, retina_default_mon + 1, 0);
    815  1.1      mw       return 0;
    816  1.1      mw 
    817  1.1      mw     case GM_GRFCONFIG:
    818  1.1      mw       return 0;
    819  1.1      mw 
    820  1.1      mw     case GM_GRFGETVMODE:
    821  1.1      mw       return rt_getvmode (gp, (struct grfvideo_mode *) arg);
    822  1.1      mw 
    823  1.1      mw     case GM_GRFSETVMODE:
    824  1.4      mw       return rt_setvmode (gp, *(unsigned *) arg, 1);
    825  1.1      mw 
    826  1.1      mw     case GM_GRFGETNUMVM:
    827  1.1      mw       *(int *)arg = retina_mon_max;
    828  1.1      mw       return 0;
    829  1.1      mw 
    830  1.4      mw #ifdef BANKEDDEVPAGER
    831  1.4      mw     case GM_GRFGETBANK:
    832  1.4      mw       *(int *)arg = rt_getbank (gp, a2, a3);
    833  1.4      mw       return 0;
    834  1.4      mw 
    835  1.4      mw     case GM_GRFGETCURBANK:
    836  1.4      mw       *(int *)arg = rt_getcurbank (gp);
    837  1.4      mw       return 0;
    838  1.4      mw 
    839  1.4      mw     case GM_GRFSETBANK:
    840  1.4      mw       return rt_setbank (gp, arg);
    841  1.4      mw #endif
    842  1.4      mw     case GM_GRFIOCTL:
    843  1.4      mw       return rt_ioctl (gp, arg, a2);
    844  1.4      mw 
    845  1.1      mw     default:
    846  1.1      mw       break;
    847  1.1      mw     }
    848  1.1      mw 
    849  1.1      mw   return EINVAL;
    850  1.1      mw }
    851  1.4      mw 
    852  1.4      mw int
    853  1.4      mw rt_ioctl (gp, cmd, data)
    854  1.4      mw 	register struct grf_softc *gp;
    855  1.4      mw 	int cmd;
    856  1.4      mw 	void *data;
    857  1.4      mw {
    858  1.4      mw   switch (cmd)
    859  1.4      mw     {
    860  1.4      mw     case GRFIOCGSPRITEPOS:
    861  1.4      mw       return rt_getspritepos (gp, (struct grf_position *) data);
    862  1.4      mw 
    863  1.4      mw     case GRFIOCSSPRITEPOS:
    864  1.4      mw       return rt_setspritepos (gp, (struct grf_position *) data);
    865  1.4      mw 
    866  1.4      mw     case GRFIOCSSPRITEINF:
    867  1.4      mw       return rt_setspriteinfo (gp, (struct grf_spriteinfo *) data);
    868  1.4      mw 
    869  1.4      mw     case GRFIOCGSPRITEINF:
    870  1.4      mw       return rt_getspriteinfo (gp, (struct grf_spriteinfo *) data);
    871  1.4      mw 
    872  1.4      mw     case GRFIOCGSPRITEMAX:
    873  1.4      mw       return rt_getspritemax (gp, (struct grf_position *) data);
    874  1.4      mw 
    875  1.4      mw     case GRFIOCGETCMAP:
    876  1.4      mw       return rt_getcmap (gp, (struct grf_colormap *) data);
    877  1.4      mw 
    878  1.4      mw     case GRFIOCPUTCMAP:
    879  1.4      mw       return rt_putcmap (gp, (struct grf_colormap *) data);
    880  1.4      mw 
    881  1.4      mw     case GRFIOCBITBLT:
    882  1.4      mw       return rt_bitblt (gp, (struct grf_bitblt *) data);
    883  1.4      mw     }
    884  1.4      mw 
    885  1.4      mw   return EINVAL;
    886  1.4      mw }
    887  1.4      mw 
    888  1.4      mw #ifdef BANKEDDEVPAGER
    889  1.4      mw 
    890  1.4      mw /* Retina banks can overlap. Don't use this information (yet?), and
    891  1.4      mw    only switch 64k sized banks. */
    892  1.4      mw 
    893  1.4      mw int
    894  1.4      mw rt_getbank (gp, offs, prot)
    895  1.4      mw      struct grf_softc *gp;
    896  1.4      mw      off_t offs;
    897  1.4      mw      int prot;
    898  1.4      mw {
    899  1.4      mw   /* XXX */
    900  1.4      mw   if (offs <  0 || offs >= 4*1024*1024)
    901  1.4      mw     return -1;
    902  1.4      mw   else
    903  1.4      mw     return offs >> 16;
    904  1.4      mw }
    905  1.4      mw 
    906  1.4      mw int
    907  1.4      mw rt_getcurbank (gp)
    908  1.4      mw      struct grf_softc *gp;
    909  1.4      mw {
    910  1.4      mw   struct grfinfo *gi = &gp->g_display;
    911  1.4      mw   volatile unsigned char *ba;
    912  1.4      mw   int bank;
    913  1.4      mw 
    914  1.4      mw   ba = gp->g_regkva;
    915  1.4      mw   bank = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO) | (RSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI) << 8);
    916  1.4      mw 
    917  1.4      mw   /* bank register is multiple of 64 byte, make this multiple of 64k */
    918  1.4      mw   bank >>= 10;
    919  1.4      mw   return bank;
    920  1.4      mw }
    921  1.4      mw 
    922  1.4      mw int
    923  1.4      mw rt_setbank (gp, bank)
    924  1.4      mw      struct grf_softc *gp;
    925  1.4      mw      int bank;
    926  1.4      mw {
    927  1.4      mw   volatile unsigned char *ba;
    928  1.4      mw 
    929  1.4      mw   ba = gp->g_regkva;
    930  1.4      mw   /* bank register is multiple of 64 byte, make this multiple of 64k */
    931  1.4      mw   bank <<= 10;
    932  1.4      mw   WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, (unsigned char) bank);
    933  1.4      mw   bank >>= 8;
    934  1.4      mw   WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, (unsigned char) bank);
    935  1.4      mw 
    936  1.4      mw   return 0;
    937  1.4      mw }
    938  1.4      mw 
    939  1.4      mw #endif
    940  1.4      mw 
    941  1.4      mw int
    942  1.4      mw rt_getcmap (gfp, cmap)
    943  1.4      mw      struct grf_softc *gfp;
    944  1.4      mw      struct grf_colormap *cmap;
    945  1.4      mw {
    946  1.4      mw   volatile unsigned char *ba;
    947  1.4      mw   u_char red[256], green[256], blue[256], *rp, *gp, *bp;
    948  1.4      mw   short x;
    949  1.4      mw   int error;
    950  1.4      mw 
    951  1.4      mw   if (cmap->count == 0 || cmap->index >= 256)
    952  1.4      mw     return 0;
    953  1.4      mw 
    954  1.4      mw   if (cmap->index + cmap->count > 256)
    955  1.4      mw     cmap->count = 256 - cmap->index;
    956  1.4      mw 
    957  1.4      mw   ba = gfp->g_regkva;
    958  1.4      mw   /* first read colors out of the chip, then copyout to userspace */
    959  1.4      mw   vgaw (ba, VDAC_REG_SELECT, cmap->index);
    960  1.4      mw   x = cmap->count - 1;
    961  1.4      mw   rp = red + cmap->index;
    962  1.4      mw   gp = green + cmap->index;
    963  1.4      mw   bp = blue + cmap->index;
    964  1.4      mw   do
    965  1.4      mw     {
    966  1.4      mw       *rp++ = vgar (ba, VDAC_REG_DATA);
    967  1.4      mw       *gp++ = vgar (ba, VDAC_REG_DATA);
    968  1.4      mw       *bp++ = vgar (ba, VDAC_REG_DATA);
    969  1.4      mw     }
    970  1.4      mw   while (x--);
    971  1.4      mw 
    972  1.4      mw   if (!(error = copyout (red + cmap->index, cmap->red, cmap->count))
    973  1.4      mw       && !(error = copyout (green + cmap->index, cmap->green, cmap->count))
    974  1.4      mw       && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count)))
    975  1.4      mw     return 0;
    976  1.4      mw 
    977  1.4      mw   return error;
    978  1.4      mw }
    979  1.4      mw 
    980  1.4      mw int
    981  1.4      mw rt_putcmap (gfp, cmap)
    982  1.4      mw      struct grf_softc *gfp;
    983  1.4      mw      struct grf_colormap *cmap;
    984  1.4      mw {
    985  1.4      mw   volatile unsigned char *ba;
    986  1.4      mw   u_char red[256], green[256], blue[256], *rp, *gp, *bp;
    987  1.4      mw   short x;
    988  1.4      mw   int error;
    989  1.4      mw 
    990  1.4      mw   if (cmap->count == 0 || cmap->index >= 256)
    991  1.4      mw     return 0;
    992  1.4      mw 
    993  1.4      mw   if (cmap->index + cmap->count > 256)
    994  1.4      mw     cmap->count = 256 - cmap->index;
    995  1.4      mw 
    996  1.4      mw   /* first copy the colors into kernelspace */
    997  1.4      mw   if (!(error = copyin (cmap->red, red + cmap->index, cmap->count))
    998  1.4      mw       && !(error = copyin (cmap->green, green + cmap->index, cmap->count))
    999  1.4      mw       && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count)))
   1000  1.4      mw     {
   1001  1.4      mw       ba = gfp->g_regkva;
   1002  1.4      mw       vgaw (ba, VDAC_REG_SELECT, cmap->index);
   1003  1.4      mw       x = cmap->count - 1;
   1004  1.4      mw       rp = red + cmap->index;
   1005  1.4      mw       gp = green + cmap->index;
   1006  1.4      mw       bp = blue + cmap->index;
   1007  1.4      mw       do
   1008  1.4      mw 	{
   1009  1.4      mw 	  vgaw (ba, VDAC_REG_DATA, *rp++);
   1010  1.4      mw 	  vgaw (ba, VDAC_REG_DATA, *gp++);
   1011  1.4      mw 	  vgaw (ba, VDAC_REG_DATA, *bp++);
   1012  1.4      mw 	}
   1013  1.4      mw       while (x--);
   1014  1.4      mw       return 0;
   1015  1.4      mw     }
   1016  1.4      mw   else
   1017  1.4      mw     return error;
   1018  1.4      mw }
   1019  1.4      mw 
   1020  1.4      mw int
   1021  1.4      mw rt_getspritepos (gp, pos)
   1022  1.4      mw      struct grf_softc *gp;
   1023  1.4      mw      struct grf_position *pos;
   1024  1.4      mw {
   1025  1.4      mw   volatile unsigned char *ba;
   1026  1.4      mw 
   1027  1.4      mw   ba = gp->g_regkva;
   1028  1.4      mw   pos->x = vgar (ba, SEQ_ID_CURSOR_X_LOC_LO) | (vgar (ba, SEQ_ID_CURSOR_X_LOC_HI) << 8);
   1029  1.4      mw   pos->y = vgar (ba, SEQ_ID_CURSOR_Y_LOC_LO) | (vgar (ba, SEQ_ID_CURSOR_Y_LOC_HI) << 8);
   1030  1.4      mw   return 0;
   1031  1.4      mw }
   1032  1.4      mw 
   1033  1.4      mw int
   1034  1.4      mw rt_setspritepos (gp, pos)
   1035  1.4      mw      struct grf_softc *gp;
   1036  1.4      mw      struct grf_position *pos;
   1037  1.4      mw {
   1038  1.4      mw   volatile unsigned char *ba;
   1039  1.4      mw 
   1040  1.4      mw   ba = gp->g_regkva;
   1041  1.4      mw   vgaw (ba, SEQ_ID_CURSOR_X_LOC_LO, pos->x & 0xff);
   1042  1.4      mw   vgaw (ba, SEQ_ID_CURSOR_X_LOC_HI, (pos->x >> 8) & 0x07);
   1043  1.4      mw   vgaw (ba, SEQ_ID_CURSOR_Y_LOC_LO, pos->y & 0xff);
   1044  1.4      mw   vgaw (ba, SEQ_ID_CURSOR_Y_LOC_HI, (pos->y >> 8) & 0x07);
   1045  1.4      mw   return 0;
   1046  1.4      mw }
   1047  1.4      mw 
   1048  1.4      mw /* assume an at least 2M retina (XXX), sprite is last in memory.
   1049  1.4      mw    According to the bogus docs, the cursor can be at most 128 lines
   1050  1.4      mw    in height, and the x-hostspot can be placed at most at pos 31,
   1051  1.4      mw    this gives width of a long */
   1052  1.4      mw #define SPRITE_ADDR (2*1024*1024 - 128*4)
   1053  1.4      mw 
   1054  1.4      mw int
   1055  1.4      mw rt_getspriteinfo (gp, info)
   1056  1.4      mw      struct grf_softc *gp;
   1057  1.4      mw      struct grf_spriteinfo *info;
   1058  1.4      mw {
   1059  1.4      mw   volatile unsigned char *ba, *fb;
   1060  1.4      mw 
   1061  1.4      mw   ba = gp->g_regkva;
   1062  1.4      mw   fb = gp->g_fbkva;
   1063  1.4      mw   if (info->set & GRFSPRSET_ENABLE)
   1064  1.4      mw     info->enable = vgar (ba, SEQ_ID_CURSOR_CONTROL) & 0x01;
   1065  1.4      mw   if (info->set & GRFSPRSET_POS)
   1066  1.4      mw     rt_getspritepos (gp, &info->pos);
   1067  1.4      mw   if (info->set & GRFSPRSET_HOT)
   1068  1.4      mw     {
   1069  1.4      mw       info->hot.x = vgar (ba, SEQ_ID_CURSOR_X_INDEX) & 0x1f;
   1070  1.4      mw       info->hot.y = vgar (ba, SEQ_ID_CURSOR_Y_INDEX) & 0x7f;
   1071  1.4      mw     }
   1072  1.4      mw   if (info->set & GRFSPRSET_CMAP)
   1073  1.4      mw     {
   1074  1.4      mw       struct grf_colormap cmap;
   1075  1.4      mw       int index;
   1076  1.4      mw       cmap.index = 0;
   1077  1.4      mw       cmap.count = 256;
   1078  1.4      mw       rt_getcmap (gp, &cmap);
   1079  1.4      mw       index = vgar (ba, SEQ_ID_CURSOR_COLOR0);
   1080  1.4      mw       info->cmap.red[0] = cmap.red[index];
   1081  1.4      mw       info->cmap.green[0] = cmap.green[index];
   1082  1.4      mw       info->cmap.blue[0] = cmap.blue[index];
   1083  1.4      mw       index = vgar (ba, SEQ_ID_CURSOR_COLOR1);
   1084  1.4      mw       info->cmap.red[1] = cmap.red[index];
   1085  1.4      mw       info->cmap.green[1] = cmap.green[index];
   1086  1.4      mw       info->cmap.blue[1] = cmap.blue[index];
   1087  1.4      mw     }
   1088  1.4      mw   if (info->set & GRFSPRSET_SHAPE)
   1089  1.4      mw     {
   1090  1.4      mw       int saved_bank_lo = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO);
   1091  1.4      mw       int saved_bank_hi = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI);
   1092  1.4      mw       int last_bank = SPRITE_ADDR >> 6;
   1093  1.4      mw       int last_bank_lo = last_bank & 0xff;
   1094  1.4      mw       int last_bank_hi = last_bank >> 8;
   1095  1.4      mw       u_char mask;
   1096  1.4      mw       WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, last_bank_lo);
   1097  1.4      mw       WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, last_bank_hi);
   1098  1.4      mw       copyout (fb, info->image, 128*4);
   1099  1.4      mw       mask = RSeq (ba, SEQ_ID_CURSOR_PIXELMASK);
   1100  1.4      mw       WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, saved_bank_lo);
   1101  1.4      mw       WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, saved_bank_hi);
   1102  1.4      mw       copyout (&mask, info->mask, 1);
   1103  1.4      mw       info->size.x = 32; /* ??? */
   1104  1.4      mw       info->size.y = (RSeq (ba, SEQ_ID_CURSOR_CONTROL) & 6) << 4;
   1105  1.4      mw     }
   1106  1.4      mw 
   1107  1.4      mw }
   1108  1.4      mw 
   1109  1.4      mw int
   1110  1.4      mw rt_setspriteinfo (gp, info)
   1111  1.4      mw      struct grf_softc *gp;
   1112  1.4      mw      struct grf_spriteinfo *info;
   1113  1.4      mw {
   1114  1.4      mw   volatile unsigned char *ba, *fb;
   1115  1.4      mw   u_char control;
   1116  1.4      mw 
   1117  1.4      mw   ba = gp->g_regkva;
   1118  1.4      mw   fb = gp->g_fbkva;
   1119  1.4      mw   control = vgar (ba, SEQ_ID_CURSOR_CONTROL);
   1120  1.4      mw   if (info->set & GRFSPRSET_ENABLE)
   1121  1.4      mw     {
   1122  1.4      mw       if (info->enable)
   1123  1.4      mw 	control |= 1;
   1124  1.4      mw       else
   1125  1.4      mw 	control &= ~1;
   1126  1.4      mw       vgaw (ba, SEQ_ID_CURSOR_CONTROL, control);
   1127  1.4      mw     }
   1128  1.4      mw   if (info->set & GRFSPRSET_POS)
   1129  1.4      mw     rt_setspritepos (gp, &info->pos);
   1130  1.4      mw   if (info->set & GRFSPRSET_HOT)
   1131  1.4      mw     {
   1132  1.4      mw       vgaw (ba, SEQ_ID_CURSOR_X_INDEX, info->hot.x & 0x1f);
   1133  1.4      mw       vgaw (ba, SEQ_ID_CURSOR_Y_INDEX, info->hot.y & 0x7f);
   1134  1.4      mw     }
   1135  1.4      mw   if (info->set & GRFSPRSET_CMAP)
   1136  1.4      mw     {
   1137  1.4      mw       /* hey cheat a bit here.. XXX */
   1138  1.4      mw       vgaw (ba, SEQ_ID_CURSOR_COLOR0, 0);
   1139  1.4      mw       vgaw (ba, SEQ_ID_CURSOR_COLOR1, 1);
   1140  1.4      mw     }
   1141  1.4      mw   if (info->set & GRFSPRSET_SHAPE)
   1142  1.4      mw     {
   1143  1.4      mw       int saved_bank_lo = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO);
   1144  1.4      mw       int saved_bank_hi = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI);
   1145  1.4      mw       int last_bank = SPRITE_ADDR >> 6;
   1146  1.4      mw       int last_bank_lo = last_bank & 0xff;
   1147  1.4      mw       int last_bank_hi = last_bank >> 8;
   1148  1.4      mw       u_char mask;
   1149  1.4      mw       WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, last_bank_lo);
   1150  1.4      mw       WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, last_bank_hi);
   1151  1.4      mw       copyin (info->image, fb, 128*4);
   1152  1.4      mw       WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, saved_bank_lo);
   1153  1.4      mw       WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, saved_bank_hi);
   1154  1.4      mw       copyin (info->mask, &mask, 1);
   1155  1.4      mw       WSeq (ba, SEQ_ID_CURSOR_PIXELMASK, mask);
   1156  1.4      mw       /* info->size.x = 32; *//* ??? */
   1157  1.4      mw 
   1158  1.4      mw       info->size.y = (RSeq (ba, SEQ_ID_CURSOR_CONTROL) & 6) << 4;
   1159  1.4      mw       control = (control & ~6) | ((info->size.y >> 4) & 6);
   1160  1.4      mw       vgaw (ba, SEQ_ID_CURSOR_CONTROL, control);
   1161  1.4      mw 
   1162  1.4      mw       /* sick intel bull-addressing.. */
   1163  1.4      mw       WSeq (ba, SEQ_ID_CURSOR_STORE_LO, SPRITE_ADDR & 0x0f);
   1164  1.4      mw       WSeq (ba, SEQ_ID_CURSOR_STORE_HI, 0);
   1165  1.4      mw       WSeq (ba, SEQ_ID_CURSOR_ST_OFF_LO, (SPRITE_ADDR >> 4) & 0xff);
   1166  1.4      mw       WSeq (ba, SEQ_ID_CURSOR_ST_OFF_HI, ((SPRITE_ADDR >> 4) >> 8) & 0xff);
   1167  1.4      mw     }
   1168  1.4      mw 
   1169  1.4      mw   return 0;
   1170  1.4      mw }
   1171  1.4      mw 
   1172  1.4      mw int
   1173  1.4      mw rt_getspritemax (gp, pos)
   1174  1.4      mw      struct grf_softc *gp;
   1175  1.4      mw      struct grf_position *pos;
   1176  1.4      mw {
   1177  1.4      mw   pos->x = 32;
   1178  1.4      mw   pos->y = 128;
   1179  1.4      mw 
   1180  1.4      mw   return 0;
   1181  1.4      mw }
   1182  1.4      mw 
   1183  1.4      mw 
   1184  1.4      mw /*
   1185  1.4      mw  * !!! THIS AREA UNDER CONSTRUCTION !!!
   1186  1.4      mw  */
   1187  1.4      mw 
   1188  1.4      mw int
   1189  1.4      mw rt_bitblt (gp, bb)
   1190  1.4      mw      struct grf_softc *gp;
   1191  1.4      mw      struct grf_bitblt *bb;
   1192  1.4      mw {
   1193  1.4      mw   return EINVAL;
   1194  1.4      mw 
   1195  1.4      mw 
   1196  1.4      mw #if 0
   1197  1.4      mw   volatile unsigned char *ba, *fb;
   1198  1.4      mw   u_char control;
   1199  1.4      mw   u_char saved_bank_lo;
   1200  1.4      mw   u_char saved_bank_hi;
   1201  1.4      mw   u_char src_bank_lo, src_bank_hi;
   1202  1.4      mw   u_char dst_bank_lo, dst_bank_hi;
   1203  1.4      mw   u_long src_offset, dst_offset;
   1204  1.4      mw   u_short src_bank, dst_bank;
   1205  1.4      mw   u_char *srcp, *dstp;
   1206  1.4      mw   short x, y;
   1207  1.4      mw   u_long tot;
   1208  1.4      mw 
   1209  1.4      mw   ba = gp->g_regkva;
   1210  1.4      mw   fb = gp->g_fbkva;
   1211  1.4      mw 
   1212  1.4      mw   saved_bank_lo = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO);
   1213  1.4      mw   saved_bank_hi = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI);
   1214  1.4      mw 
   1215  1.4      mw   /* for now, only GRFBBcopy is supported, and only for depth 8. No
   1216  1.4      mw      clipping is performed, either... */
   1217  1.4      mw 
   1218  1.4      mw   if (bb->op != GRFBBcopy && gp->g_display.gd_planes != 8)
   1219  1.4      mw     return EINVAL;
   1220  1.4      mw 
   1221  1.4      mw   src_offset = op->src_x + op->src_y * gp->g_display.gd_fbwidth;
   1222  1.4      mw   dst_offset = op->dst_x + op->dst_y * gp->g_display.gd_fbwidth;
   1223  1.4      mw   tot = op->w * op->h;
   1224  1.4      mw 
   1225  1.4      mw   /* set write mode 1, "[...] data in the read latches is written
   1226  1.4      mw      to memory during CPU memory write cycles. [...]" */
   1227  1.4      mw   WGfx (ba, GCT_ID_GRAPHICS_MODE, (RGfx(ba, GCT_ID_GRAPHICS_MODE) & 0xfc) | 1);
   1228  1.4      mw   /* write to primary, read from secondary */
   1229  1.4      mw   WSeq (ba, SEQ_ID_EXTENDED_MEM_ENA, (RSeq(ba, SEQ_ID_EXTENDED_MEM_ENA) & 0x1f) | 0 );
   1230  1.4      mw 
   1231  1.4      mw   if (src_offset < dst_offset)
   1232  1.4      mw     {
   1233  1.4      mw       /* start at end */
   1234  1.4      mw       src_offset += tot;
   1235  1.4      mw       dst_offset += tot;
   1236  1.4      mw     }
   1237  1.4      mw 
   1238  1.4      mw   src_bank_lo = (src_offset >> 6) & 0xff;
   1239  1.4      mw   src_bank_hi = (src_offset >> 14) & 0xff;
   1240  1.4      mw   dst_bank_lo = (dst_offset >> 6) & 0xff;
   1241  1.4      mw   dst_bank_hi = (dst_offset >> 14) & 0xff;
   1242  1.4      mw 
   1243  1.4      mw   while (tot)
   1244  1.4      mw     {
   1245  1.4      mw       WSeq (ba, SEQ_ID_SEC_HOST_OFF_LO, src_bank_lo);
   1246  1.4      mw       WSeq (ba, SEQ_ID_SEC_HOST_OFF_HI, src_bank_hi);
   1247  1.4      mw       WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, dst_bank_lo);
   1248  1.4      mw       WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, dst_bank_hi);
   1249  1.4      mw 
   1250  1.4      mw       if (src_offset < dst_offset)
   1251  1.4      mw 	{
   1252  1.4      mw 
   1253  1.4      mw 
   1254  1.4      mw 	}
   1255  1.4      mw       else
   1256  1.4      mw 	{
   1257  1.4      mw 
   1258  1.4      mw 	}
   1259  1.4      mw     }
   1260  1.4      mw 
   1261  1.4      mw 
   1262  1.4      mw #endif
   1263  1.4      mw }
   1264  1.4      mw 
   1265  1.1      mw 
   1266  1.1      mw #endif	/* NGRF */
   1267