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