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