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