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