Home | History | Annotate | Line # | Download | only in dev
grf_ul.c revision 1.24
      1  1.24     veego /*	$NetBSD: grf_ul.c,v 1.24 1997/07/29 17:50:01 veego Exp $	*/
      2   1.1    chopps #define UL_DEBUG
      3   1.1    chopps 
      4   1.1    chopps /*
      5   1.1    chopps  * Copyright (c) 1995 Ignatios Souvatzis
      6   1.1    chopps  * All rights reserved.
      7   1.1    chopps  *
      8   1.1    chopps  * Redistribution and use in source and binary forms, with or without
      9   1.1    chopps  * modification, are permitted provided that the following conditions
     10   1.1    chopps  * are met:
     11   1.1    chopps  * 1. Redistributions of source code must retain the above copyright
     12   1.1    chopps  *    notice, this list of conditions and the following disclaimer.
     13   1.1    chopps  * 2. Redistributions in binary form must reproduce the above copyright
     14   1.1    chopps  *    notice, this list of conditions and the following disclaimer in the
     15   1.1    chopps  *    documentation and/or other materials provided with the distribution.
     16   1.1    chopps  * 3. All advertising materials mentioning features or use of this software
     17   1.1    chopps  *    must display the following acknowledgement:
     18  1.19        is  *      This product includes software developed by Ignatios Souvatzis for
     19  1.19        is  *      the NetBSD project.
     20  1.19        is  * 4. The name of the authors may not be used to endorse or promote products
     21   1.1    chopps  *    derived from this software without specific prior written permission
     22   1.1    chopps  *
     23   1.1    chopps  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     24   1.1    chopps  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     25   1.1    chopps  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26   1.1    chopps  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     27   1.1    chopps  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     28   1.1    chopps  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     29   1.1    chopps  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     30   1.1    chopps  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     31   1.1    chopps  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     32   1.1    chopps  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33   1.1    chopps  */
     34   1.1    chopps #include "grful.h"
     35   1.1    chopps #if NGRFUL > 0
     36   1.1    chopps 
     37   1.1    chopps /* Graphics routines for the University of Lowell A2410 board,
     38   1.1    chopps    using the TMS34010 processor. */
     39   1.1    chopps 
     40   1.1    chopps #include <sys/param.h>
     41   1.3    chopps #include <sys/systm.h>
     42   1.1    chopps #include <sys/errno.h>
     43   1.1    chopps #include <sys/ioctl.h>
     44   1.1    chopps #include <sys/device.h>
     45   1.1    chopps #include <sys/malloc.h>
     46   1.1    chopps #include <sys/syslog.h>
     47   1.1    chopps 
     48   1.1    chopps #include <machine/cpu.h>
     49   1.1    chopps 
     50   1.1    chopps #include <amiga/amiga/device.h>
     51   1.1    chopps #include <amiga/amiga/isr.h>
     52   1.1    chopps #include <amiga/dev/zbusvar.h>
     53   1.1    chopps #include <amiga/dev/grfioctl.h>
     54   1.1    chopps #include <amiga/dev/grfvar.h>
     55   1.1    chopps #include <amiga/dev/grf_ulreg.h>
     56   1.6    chopps 
     57   1.8       jtc extern u_int16_t tmscode[];
     58   1.1    chopps 
     59   1.5    chopps int ul_ioctl __P((struct grf_softc *, u_long, void *, dev_t));
     60   1.5    chopps int ul_getcmap __P((struct grf_softc *, struct grf_colormap *, dev_t));
     61   1.5    chopps int ul_putcmap __P((struct grf_softc *, struct grf_colormap *, dev_t));
     62   1.5    chopps int ul_bitblt __P((struct grf_softc *, struct grf_bitblt *, dev_t));
     63  1.10    chopps int ul_blank __P((struct grf_softc *, int *, dev_t));
     64   1.1    chopps 
     65  1.15     veego static int ulisr __P((void *));
     66  1.15     veego int ulowell_alive __P((struct grfvideo_mode *));
     67  1.15     veego static void ul_load_code __P((struct grf_softc *));
     68  1.15     veego static int ul_load_mon __P((struct grf_softc *, struct grfvideo_mode *));
     69  1.15     veego static int ul_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
     70  1.15     veego static int ul_setvmode __P((struct grf_softc *, unsigned));
     71  1.15     veego static __inline void ul_setfb __P((struct grf_softc *, u_long));
     72  1.15     veego 
     73   1.1    chopps /*
     74   1.1    chopps  * marked true early so that ulowell_cnprobe() can tell if we are alive.
     75   1.1    chopps  */
     76   1.1    chopps int ulowell_inited;
     77   1.1    chopps 
     78   1.1    chopps /* standard-palette definition */
     79   1.1    chopps u_int8_t ul_std_palette[] = {
     80   1.1    chopps 	0,128,  0,128,   0,128,  0,128,  0,255,  0,255,   0,255,  0,255,
     81   1.1    chopps 	0,  0,128,128,   0,  0,128,128,  0,  0,255,255,   0,  0,255,255,
     82   1.1    chopps 	0,  0,  0,  0, 128,128,128,128,  0,  0,  0,  0, 255,255,255,255};
     83   1.1    chopps 
     84   1.1    chopps u_int8_t ul_ovl_palette[] = {
     85   1.1    chopps 	128, 0, 0, 0,
     86   1.1    chopps 	128, 0, 0, 0,
     87   1.1    chopps 	128, 0, 0, 0};
     88   1.1    chopps 
     89   1.2    chopps struct grfvideo_mode ul_monitor_defs[] = {
     90   1.1    chopps 
     91   1.1    chopps  	/*
     92  1.24     veego 	 * We give all these values in MI units, that is:
     93  1.24     veego 	 * horizontal timings in units of pixels
     94  1.24     veego 	 * vertical timings in units of lines
     95  1.24     veego 	 * point of reference is blanking end.
     96   1.1    chopps 	 *
     97  1.24     veego 	 * The ul_load_mon transforms these values right before loading
     98  1.24     veego 	 * them into the chip.
     99   1.1    chopps 	 *
    100  1.24     veego 	 * This leaves us with a single point where things are transformed,
    101  1.24     veego 	 * which should make life easier if we ever change things again.
    102   1.1    chopps 	 */
    103   1.1    chopps 
    104   1.1    chopps 	/* 1024x768, 60Hz */
    105  1.24     veego 	{1,"1024x768", 66667000,	1024,768,8,	1024,1088,1296,1392,
    106  1.24     veego 		768,771,774,798, 0},
    107   1.1    chopps 	/* 864x648, 70Hz */
    108  1.24     veego 	{2,"864x648", 50000000,		864,648,8,	864,928,992,1056,
    109  1.24     veego 		648,658,663,678, 0},
    110   1.1    chopps 	/* 800x600, 60Hz */
    111  1.24     veego 	{3, "800x600", 36000000,	800,600,8,	800,864,928,992,
    112  1.24     veego 		600,610,615,630, 0},
    113   1.1    chopps 	/* 640x400, 60 Hz, interlaced */
    114  1.24     veego 	{4, "640x400i", 14318000,	640,400,8,	640,768,832,912,
    115  1.24     veego 		200,223,203,240, 1},
    116   1.1    chopps 	/* 1024x768, 65Hz interlaced, s.th. is strange */
    117  1.24     veego 	{5, "1024x768?i", 44980000,	1024,768,8,	1024,1072,1136,1280,
    118  1.24     veego 		488,509,512,534, 1},
    119   1.1    chopps 	/* 1024x1024, 60Hz */
    120  1.24     veego 	{6, "1024x1024", 80000000,	1024,1024,8,	1024,1040,1120,1248,
    121  1.24     veego 		1024,1027,1030,1055, 0},
    122   1.1    chopps 	/* 736x480, 60 Hz */
    123  1.24     veego 	{7, "736x480", 28636300,	736,480,8,	736,784,848,928,
    124  1.24     veego 		480,491,495,515, 0},
    125   1.1    chopps };
    126   1.1    chopps 
    127   1.2    chopps int ulowell_mon_max = sizeof (ul_monitor_defs)/sizeof (ul_monitor_defs[0]);
    128   1.1    chopps 
    129   1.1    chopps /* option settable */
    130   1.1    chopps #ifndef ULOWELL_OSC1
    131   1.1    chopps #define ULOWELL_OSC1 36000000
    132   1.1    chopps #endif
    133   1.1    chopps 
    134   1.1    chopps #ifndef ULOWELL_OSC2
    135   1.1    chopps #define ULOWELL_OSC2 66667000
    136   1.1    chopps #endif
    137   1.1    chopps 
    138   1.1    chopps #ifndef ULOWELL_DEFAULT_MON
    139   1.1    chopps #define ULOWELL_DEFAULT_MON 1
    140   1.1    chopps #endif
    141   1.1    chopps 
    142   1.1    chopps /* patchable */
    143   1.1    chopps int ulowell_default_mon = ULOWELL_DEFAULT_MON;
    144   1.1    chopps int ulowell_default_gfx = ULOWELL_DEFAULT_MON;
    145   1.1    chopps 
    146   1.1    chopps /*
    147   1.1    chopps  * yes, this should be per board. We don't pay service to multiple boards,
    148   1.1    chopps  * anyway.
    149   1.1    chopps  */
    150   1.1    chopps 
    151   1.4    chopps u_long ulowell_clock[2] = { ULOWELL_OSC2, ULOWELL_OSC1 };
    152   1.1    chopps 
    153   1.1    chopps static struct grfvideo_mode *current_mon;
    154   1.1    chopps 
    155   1.1    chopps /*
    156   1.1    chopps  * We dont use ints at the moment, but will need this later to avoid
    157   1.1    chopps  * busy_waiting in gsp_write, and we use it for spurious int warnings.
    158   1.1    chopps  */
    159   1.1    chopps 
    160   1.1    chopps static int
    161  1.15     veego ulisr(arg)
    162  1.15     veego 	void *arg;
    163   1.1    chopps {
    164  1.15     veego 	struct grf_softc *gp = arg;
    165   1.1    chopps 	struct gspregs *ba;
    166   1.1    chopps 	u_int16_t	thebits;
    167   1.1    chopps 
    168   1.1    chopps 	if (gp == NULL)
    169   1.1    chopps 		return 0;
    170   1.1    chopps 
    171   1.1    chopps 	ba = (struct gspregs *)gp->g_regkva;
    172   1.1    chopps 
    173   1.1    chopps 	if (ba == NULL)
    174   1.1    chopps 		return 0;
    175   1.1    chopps 
    176   1.1    chopps 	thebits = ba->ctrl;
    177   1.1    chopps 	if (thebits & INTOUT) {
    178   1.1    chopps 		log(LOG_INFO, "grf4: got interrupt, ctrl=0x%4x\n", thebits);
    179   1.1    chopps 		/* clear int */
    180   1.1    chopps 		ba->ctrl = thebits & ~INTOUT;
    181   1.1    chopps 		return 1;
    182   1.1    chopps 	}
    183   1.1    chopps 	return 0;
    184   1.1    chopps }
    185   1.1    chopps 
    186   1.1    chopps /*
    187   1.1    chopps  * used to query the ulowell board to see if its alive.
    188   1.1    chopps  * for the moment, a NOP.
    189   1.1    chopps  */
    190   1.1    chopps int
    191   1.1    chopps ulowell_alive(mdp)
    192   1.1    chopps 	struct grfvideo_mode *mdp;
    193   1.1    chopps {
    194   1.1    chopps 	return 1;
    195   1.1    chopps }
    196   1.1    chopps 
    197   1.1    chopps /*
    198   1.1    chopps  * Load the (mostly) ite support code and the default colormaps.
    199   1.1    chopps  */
    200   1.1    chopps static void
    201   1.1    chopps ul_load_code(gp)
    202   1.1    chopps 	struct grf_softc *gp;
    203   1.1    chopps {
    204   1.1    chopps 	struct grf_ul_softc *gup;
    205   1.1    chopps 	struct gspregs *ba;
    206   1.1    chopps 	struct grfinfo *gi;
    207  1.15     veego 	int i,j;
    208  1.15     veego #if 0
    209   1.1    chopps 	struct grf_colormap gcm;
    210  1.15     veego #endif
    211   1.1    chopps 
    212   1.1    chopps 	gup = (struct grf_ul_softc *)gp;
    213   1.1    chopps 	ba = (struct gspregs *)gp->g_regkva;
    214   1.1    chopps 	gi = &gp->g_display;
    215   1.1    chopps 
    216   1.1    chopps 	gi->gd_regaddr	= ztwopa((caddr_t)ba);
    217   1.1    chopps 	gi->gd_regsize	= sizeof(struct gspregs);
    218   1.1    chopps 	gi->gd_fbaddr	= NULL;
    219   1.1    chopps 	gi->gd_fbsize	= 0;
    220   1.1    chopps 	gi->gd_fbwidth	= 1024;
    221   1.1    chopps 	gi->gd_fbheight	= 1024;
    222   1.1    chopps 	gi->gd_colors	= 256;
    223   1.1    chopps 
    224  1.15     veego 	ba->ctrl = (ba->ctrl & ~INCR) | (LBL | INCW);
    225   1.1    chopps 	ba->hstadrh = 0xC000;
    226   1.1    chopps 	ba->hstadrl = 0x0080;
    227   1.1    chopps 	ba->data = 0x0;		/* disable screen refresh and video output */
    228   1.1    chopps 	ba->data = 0xFFFC;	/* screen refresh base address */
    229   1.1    chopps 	ba->data = 0xFFFF;	/* no display int possible */
    230   1.1    chopps 	ba->data = 0x000C;	/* CAS before RAS refresh each 64 local clks */
    231   1.1    chopps 
    232   1.5    chopps 	ba->ctrl = (ba->ctrl & ~INCW) | LBL;
    233   1.1    chopps 	ba->hstadrh = 0xfe80;
    234   1.1    chopps 	ba->hstadrl = 0;
    235   1.1    chopps 	ba->data = 4;
    236   1.1    chopps 	ba->hstadrl = 0x20;
    237   1.1    chopps 	ba->data = 0xFF;	/* all color planes visible */
    238   1.1    chopps 
    239   1.1    chopps 	ba->hstadrl = 0;
    240   1.1    chopps 	ba->data = 5;
    241   1.1    chopps 	ba->hstadrl = 0x20;
    242   1.1    chopps 	ba->data = 0;		/* no color planes blinking */
    243   1.1    chopps 
    244   1.1    chopps 	ba->hstadrl = 0;
    245   1.1    chopps 	ba->data = 6;
    246   1.1    chopps 	ba->hstadrl = 0x20;
    247   1.1    chopps 	ba->data = gup->gus_ovslct = 0x43;
    248   1.1    chopps 	/* overlay visible, no overlay blinking, overlay color 0 transparent */
    249   1.1    chopps 
    250   1.1    chopps 	ba->hstadrl = 0;
    251   1.1    chopps 	ba->data = 7;
    252   1.1    chopps 	ba->hstadrl = 0x20;
    253   1.1    chopps 	ba->data = 0;		/* voodoo */
    254   1.1    chopps 
    255   1.1    chopps 	/* clear overlay planes */
    256   1.1    chopps 	ba->ctrl |= INCW;
    257   1.1    chopps 	ba->hstadrh = 0xff80;
    258   1.1    chopps 	ba->hstadrl = 0x0000;
    259   1.1    chopps 	for (i=0xff80000; i< 0xffa0000; ++i) {
    260   1.1    chopps 		ba->data = 0;
    261   1.1    chopps 	}
    262   1.1    chopps 
    263   1.1    chopps 	/* download tms code */
    264   1.1    chopps 
    265   1.1    chopps 	ba->ctrl = LBL | INCW | NMI | NMIM | HLT | CF;
    266   1.1    chopps 
    267  1.22  christos 	printf("\ndownloading TMS code");
    268   1.5    chopps 	i=0;
    269   1.5    chopps 	while ((j = tmscode[i++])) {
    270  1.22  christos 		printf(".");
    271   1.5    chopps 		ba->hstadrh = tmscode[i++];
    272   1.5    chopps 		ba->hstadrl = tmscode[i++];
    273   1.5    chopps 		while (j-- > 0) {
    274   1.5    chopps 			ba->data = tmscode[i++];
    275   1.1    chopps 		}
    276   1.1    chopps 	}
    277   1.1    chopps 
    278   1.1    chopps 	/* font info was uploaded in ite_ul.c(ite_ulinit). */
    279   1.1    chopps 
    280   1.9    chopps #if 1
    281   1.1    chopps 	/* XXX load image palette with some initial values, slightly hacky */
    282   1.1    chopps 
    283   1.1    chopps 	ba->hstadrh = 0xfe80;
    284   1.1    chopps 	ba->hstadrl = 0x0000;
    285   1.1    chopps 	ba->ctrl |= INCW;
    286   1.1    chopps 	ba->data = 0;
    287   1.1    chopps 	ba->ctrl &= ~INCW;
    288   1.1    chopps 
    289   1.1    chopps 	for (i=0; i<16; ++i) {
    290   1.1    chopps 		ba->data = gup->gus_imcmap[i+  0] = ul_std_palette[i+ 0];
    291   1.1    chopps 		ba->data = gup->gus_imcmap[i+256] = ul_std_palette[i+16];
    292   1.1    chopps 		ba->data = gup->gus_imcmap[i+512] = ul_std_palette[i+32];
    293   1.1    chopps 	}
    294   1.1    chopps 
    295   1.1    chopps 	/*
    296   1.1    chopps 	 * XXX load shadow overlay palette with what the TMS code will load
    297   1.9    chopps 	 * into the real one some time after the TMS code is started below.
    298   1.9    chopps 	 * This might be considered a rude hack.
    299   1.1    chopps 	 */
    300   1.1    chopps 	bcopy(ul_ovl_palette, gup->gus_ovcmap, 3*4);
    301   1.9    chopps 
    302   1.9    chopps 	/*
    303   1.9    chopps 	 * Unflush cache, unhalt cpu -> nmi starts to run. This MUST NOT BE
    304   1.9    chopps 	 * DONE before the image color map initialization above, to guarantee
    305  1.12        is 	 * the index register in the BT458 is not used by more than one CPU
    306   1.9    chopps 	 * at once.
    307   1.9    chopps 	 *
    308   1.9    chopps 	 * XXX For the same reason, we'll have to rething ul_putcmap(). For
    309   1.9    chopps 	 * details, look at comment there.
    310   1.9    chopps 	 */
    311   1.9    chopps 	ba->ctrl &= ~(HLT|CF);
    312   1.9    chopps 
    313   1.1    chopps #else
    314   1.9    chopps 	/*
    315   1.9    chopps 	 * XXX I wonder why this partially ever worked.
    316   1.9    chopps 	 *
    317   1.9    chopps 	 * This can't possibly work this way, as we are copyin()ing data in
    318   1.9    chopps 	 * ul_putcmap.
    319   1.9    chopps 	 *
    320   1.9    chopps 	 * I guess this partially worked because SFC happened to point to
    321   1.9    chopps 	 * to supervisor data space on 68030 machines coming from the old
    322   1.9    chopps 	 * boot loader.
    323   1.9    chopps 	 *
    324   1.9    chopps 	 * While this looks more correct than the hack in the other part of the
    325   1.9    chopps 	 * loop, we would have to do our own version of the loop through
    326   1.9    chopps 	 * colormap entries, set up command buffer, and call gsp_write(), or
    327   1.9    chopps 	 * factor out some code.
    328   1.9    chopps 	 */
    329   1.9    chopps 
    330   1.9    chopps 	/*
    331   1.9    chopps 	 * XXX This version will work for the overlay, if our queue codes
    332   1.1    chopps 	 * initial conditions are set at load time (not start time).
    333   1.1    chopps 	 * It further assumes that ul_putcmap only uses the
    334   1.1    chopps 	 * GRFIMDEV/GRFOVDEV bits of the dev parameter.
    335   1.1    chopps 	 */
    336   1.1    chopps 
    337   1.9    chopps 
    338   1.9    chopps 	/* unflush cache, unhalt cpu first -> nmi starts to run */
    339   1.9    chopps 	ba->ctrl &= ~(HLT|CF);
    340   1.9    chopps 
    341   1.1    chopps 	gcm.index = 0;
    342   1.1    chopps 	gcm.count = 16;
    343   1.1    chopps 	gcm.red   = ul_std_palette +  0;
    344   1.1    chopps 	gcm.green = ul_std_palette + 16;
    345   1.1    chopps 	gcm.blue  = ul_std_palette + 32;
    346   1.1    chopps 	ul_putcmap(gp, &gcm, GRFIMDEV);
    347   1.1    chopps 
    348   1.1    chopps 	gcm.index = 0;
    349   1.1    chopps 	gcm.count = 4;
    350   1.1    chopps 	gcm.red   = ul_ovl_palette + 0;
    351   1.1    chopps 	gcm.green = ul_ovl_palette + 4;
    352   1.1    chopps 	gcm.blue  = ul_ovl_palette + 8;
    353   1.1    chopps 	ul_putcmap(gp, &gcm, GRFOVDEV);
    354   1.1    chopps #endif
    355   1.1    chopps 
    356   1.1    chopps }
    357   1.1    chopps 
    358   1.1    chopps static int
    359   1.1    chopps ul_load_mon(gp, md)
    360   1.1    chopps 	struct grf_softc *gp;
    361   1.1    chopps 	struct grfvideo_mode *md;
    362   1.1    chopps {
    363   1.1    chopps 	struct grf_ul_softc *gup;
    364   1.1    chopps 	struct grfinfo *gi;
    365   1.1    chopps 	struct gspregs *ba;
    366   1.1    chopps 	u_int16_t buf[8];
    367   1.1    chopps 
    368   1.1    chopps 	gup = (struct grf_ul_softc *)gp;
    369   1.1    chopps 	gi = &gp->g_display;
    370   1.1    chopps 	ba = (struct gspregs *)gp->g_regkva;
    371   1.1    chopps 
    372   1.1    chopps 	gi->gd_dyn.gdi_fbx	= 0;
    373   1.1    chopps 	gi->gd_dyn.gdi_fby	= 0;
    374   1.1    chopps 	gi->gd_dyn.gdi_dwidth	= md->disp_width;
    375   1.1    chopps 	gi->gd_dyn.gdi_dheight	= md->disp_height;
    376   1.1    chopps 	gi->gd_dyn.gdi_dx	= 0;
    377   1.1    chopps 	gi->gd_dyn.gdi_dy	= 0;
    378   1.1    chopps 
    379  1.15     veego 	ba->ctrl = (ba->ctrl & ~INCR) | (LBL | INCW); /* XXX */
    380   1.1    chopps 
    381   1.1    chopps 	ba->hstadrh = 0xC000;
    382   1.1    chopps 	ba->hstadrl = 0x0000;
    383  1.24     veego 
    384  1.24     veego 	ba->data = (md->hsync_stop - md->hsync_start)/16;
    385  1.24     veego 	ba->data = (md->htotal - md->hsync_start)/16 - 1;
    386  1.24     veego 	ba->data = (md->hblank_start + md->htotal - md->hsync_start)/16 - 1;
    387  1.24     veego 	ba->data = md->htotal/16 - 1;
    388  1.24     veego 
    389  1.24     veego 	ba->data = md->vsync_stop - md->vsync_start;
    390  1.24     veego 	ba->data = md->vtotal - md->vsync_start - 1;
    391  1.24     veego 	ba->data = md->vblank_start + md->vtotal - md->vsync_start - 1;
    392  1.24     veego 	ba->data = md->vtotal - 1;
    393   1.1    chopps 
    394   1.1    chopps 	ba->ctrl &= ~INCW;
    395   1.1    chopps 	ba->hstadrh = 0xFE90;
    396   1.1    chopps 	ba->hstadrl = 0x0000;
    397   1.1    chopps 
    398   1.1    chopps 	if (abs(md->pixel_clock - ulowell_clock[0]) >
    399   1.1    chopps 	    abs(md->pixel_clock - ulowell_clock[1])) {
    400   1.1    chopps 
    401   1.5    chopps 		ba->data = (ba->data & 0xFC) | 2 | 1;
    402   1.1    chopps 		md->pixel_clock = ulowell_clock[1];
    403   1.1    chopps 
    404   1.1    chopps 	} else {
    405   1.5    chopps 		ba->data = (ba->data & 0xFC) | 2 | 0;
    406   1.1    chopps 		md->pixel_clock = ulowell_clock[0];
    407   1.1    chopps 	}
    408   1.1    chopps 
    409  1.15     veego 	ba->ctrl |= LBL | INCW;
    410   1.1    chopps 	ba->hstadrh = 0xC000;
    411   1.1    chopps 	ba->hstadrl = 0x0080;
    412  1.24     veego 	ba->data = md->disp_flags & GRF_FLAGS_LACE ? 0xb020 : 0xf020;
    413   1.1    chopps 
    414   1.1    chopps 	/* I guess this should be in the yet unimplemented mode select ioctl */
    415   1.1    chopps 	/* Hm.. maybe not. We always put the console on overlay plane no 0. */
    416   1.1    chopps 	/* Anyway, this _IS_ called in the mode select ioctl. */
    417   1.1    chopps 
    418   1.1    chopps 	/* ite support code parameters: */
    419   1.1    chopps 	buf[0] = GCMD_MCHG;
    420   1.1    chopps 	buf[1] = md->disp_width;	/* display width */
    421   1.1    chopps 	buf[2] = md->disp_height;	/* display height */
    422   1.1    chopps 	buf[3] = 0;			/* LSW of frame buffer origin */
    423   1.1    chopps 	buf[4] = 0xFF80;		/* MSW of frame buffer origin */
    424   1.1    chopps 	buf[5] = gi->gd_fbwidth * 1;	/* frame buffer pitch */
    425   1.1    chopps 	buf[6] = 1;			/* frame buffer depth */
    426   1.1    chopps 	gsp_write(ba, buf, 7);
    427   1.1    chopps 
    428   1.1    chopps 	return(1);
    429   1.1    chopps }
    430   1.1    chopps 
    431  1.15     veego int ul_mode __P((struct grf_softc *, u_long, void *, u_long, int));
    432   1.1    chopps 
    433   1.1    chopps void grfulattach __P((struct device *, struct device *, void *));
    434  1.20       cgd int grfulprint __P((void *, const char *));
    435  1.23     veego int grfulmatch __P((struct device *, struct cfdata *, void *));
    436   1.1    chopps 
    437  1.13   thorpej struct cfattach grful_ca = {
    438  1.13   thorpej 	sizeof(struct grf_ul_softc), grfulmatch, grfulattach
    439  1.13   thorpej };
    440  1.13   thorpej 
    441  1.14    mhitch struct cfdriver grful_cd = {
    442  1.13   thorpej 	NULL, "grful", DV_DULL, NULL, 0
    443  1.13   thorpej };
    444   1.1    chopps 
    445   1.1    chopps /*
    446   1.1    chopps  * only used in console init
    447   1.1    chopps  */
    448   1.1    chopps static struct cfdata *cfdata;
    449   1.1    chopps 
    450   1.1    chopps /*
    451   1.1    chopps  * we make sure to only init things once.  this is somewhat
    452   1.1    chopps  * tricky regarding the console.
    453   1.1    chopps  */
    454   1.1    chopps int
    455  1.23     veego grfulmatch(pdp, cfp, auxp)
    456   1.1    chopps 	struct device *pdp;
    457  1.23     veego 	struct cfdata *cfp;
    458  1.23     veego 	void *auxp;
    459   1.1    chopps {
    460  1.16     veego #ifdef ULOWELLCONSOLE
    461   1.1    chopps 	static int ulconunit = -1;
    462   1.1    chopps #endif
    463   1.1    chopps 	struct zbus_args *zap;
    464   1.1    chopps 
    465   1.1    chopps 	zap = auxp;
    466   1.1    chopps 
    467   1.1    chopps 	/*
    468   1.1    chopps 	 * allow only one ulowell console
    469   1.1    chopps 	 */
    470   1.1    chopps         if (amiga_realconfig == 0)
    471   1.1    chopps #ifdef ULOWELLCONSOLE
    472   1.1    chopps 		if (ulconunit != -1)
    473   1.1    chopps #endif
    474   1.1    chopps 			return(0);
    475   1.1    chopps 
    476   1.1    chopps 	if (zap->manid != 1030 || zap->prodid != 0)
    477   1.1    chopps 		return(0);
    478   1.1    chopps 
    479   1.1    chopps #ifdef ULOWELLCONSOLE
    480   1.1    chopps 	if (amiga_realconfig == 0 || ulconunit != cfp->cf_unit) {
    481   1.1    chopps #endif
    482  1.11    chopps 		if ((unsigned)ulowell_default_mon > ulowell_mon_max)
    483   1.1    chopps 			ulowell_default_mon = 1;
    484   1.1    chopps 
    485   1.2    chopps 		current_mon = ul_monitor_defs + ulowell_default_mon - 1;
    486   1.1    chopps 		if (ulowell_alive(current_mon) == 0)
    487   1.1    chopps 			return(0);
    488   1.1    chopps #ifdef ULOWELLCONSOLE
    489   1.1    chopps 		if (amiga_realconfig == 0) {
    490   1.1    chopps 			ulconunit = cfp->cf_unit;
    491   1.1    chopps 			cfdata = cfp;
    492   1.1    chopps 		}
    493   1.1    chopps 	}
    494   1.1    chopps #endif
    495   1.1    chopps 	return(1);
    496   1.1    chopps }
    497   1.1    chopps 
    498   1.1    chopps /*
    499   1.1    chopps  * attach to the grfbus (zbus)
    500   1.1    chopps  */
    501   1.1    chopps void
    502   1.1    chopps grfulattach(pdp, dp, auxp)
    503   1.1    chopps 	struct device *pdp, *dp;
    504   1.1    chopps 	void *auxp;
    505   1.1    chopps {
    506   1.1    chopps 	static struct grf_ul_softc congrf;
    507   1.1    chopps 	struct zbus_args *zap;
    508   1.1    chopps 	struct grf_softc *gp;
    509   1.1    chopps 	struct grf_ul_softc *gup;
    510   1.1    chopps 
    511   1.1    chopps 	zap = auxp;
    512   1.1    chopps 
    513   1.1    chopps 	if (dp == NULL)
    514   1.1    chopps 		gup = &congrf;
    515   1.1    chopps 	else
    516   1.1    chopps 		gup = (struct grf_ul_softc *)dp;
    517   1.1    chopps 
    518   1.1    chopps 	gp = &gup->gus_sc;
    519   1.1    chopps 
    520   1.1    chopps 	if (dp != NULL && congrf.gus_sc.g_regkva != 0) {
    521   1.1    chopps 		/*
    522   1.1    chopps 		 * inited earlier, just copy (not device struct)
    523   1.1    chopps 		 */
    524   1.1    chopps 		bcopy(&congrf.gus_sc.g_display, &gp->g_display,
    525   1.1    chopps 		    (char *)&gup->gus_isr - (char *)&gp->g_display);
    526   1.1    chopps 
    527   1.1    chopps 		/* ...and transfer the isr */
    528   1.1    chopps 		gup->gus_isr.isr_ipl = 2;
    529   1.1    chopps 		gup->gus_isr.isr_intr = ulisr;
    530   1.1    chopps 		gup->gus_isr.isr_arg = (void *)gp;
    531   1.1    chopps 		/*
    532   1.1    chopps 		 * To make sure ints are always catched, first add new isr
    533   1.1    chopps 		 * then remove old:
    534   1.1    chopps 		 */
    535   1.1    chopps 		add_isr(&gup->gus_isr);
    536   1.1    chopps 		remove_isr(&congrf.gus_isr);
    537   1.1    chopps 	} else {
    538   1.1    chopps 		gp->g_regkva = (caddr_t)zap->va;
    539   1.1    chopps 		gp->g_fbkva = NULL;
    540   1.1    chopps 		gp->g_unit = GRF_ULOWELL_UNIT;
    541   1.1    chopps 		gp->g_flags = GF_ALIVE;
    542   1.1    chopps 		gp->g_mode = ul_mode;
    543   1.1    chopps 		gp->g_conpri = grful_cnprobe();
    544   1.1    chopps 		gp->g_data = NULL;
    545   1.1    chopps 
    546   1.1    chopps 		gup->gus_isr.isr_ipl = 2;
    547   1.1    chopps 		gup->gus_isr.isr_intr = ulisr;
    548   1.1    chopps 		gup->gus_isr.isr_arg = (void *)gp;
    549   1.1    chopps 		add_isr(&gup->gus_isr);
    550   1.1    chopps 
    551   1.1    chopps 		(void)ul_load_code(gp);
    552   1.1    chopps 		(void)ul_load_mon(gp, current_mon);
    553   1.1    chopps 		grful_iteinit(gp);
    554   1.1    chopps 	}
    555   1.1    chopps 	if (dp != NULL)
    556  1.22  christos 		printf("\n");
    557   1.1    chopps 	/*
    558   1.1    chopps 	 * attach grf
    559   1.1    chopps 	 */
    560   1.1    chopps 	amiga_config_found(cfdata, &gp->g_device, gp, grfulprint);
    561   1.1    chopps }
    562   1.1    chopps 
    563   1.1    chopps int
    564   1.1    chopps grfulprint(auxp, pnp)
    565   1.1    chopps 	void *auxp;
    566  1.20       cgd 	const char *pnp;
    567   1.1    chopps {
    568   1.1    chopps 	if (pnp)
    569  1.22  christos 		printf("grf%d at %s", ((struct grf_softc *)auxp)->g_unit,
    570   1.1    chopps 			pnp);
    571   1.1    chopps 	return(UNCONF);
    572   1.1    chopps }
    573   1.1    chopps 
    574   1.1    chopps static int
    575   1.1    chopps ul_getvmode (gp, vm)
    576   1.1    chopps 	struct grf_softc *gp;
    577   1.1    chopps 	struct grfvideo_mode *vm;
    578   1.1    chopps {
    579   1.1    chopps 	struct grfvideo_mode *md;
    580   1.1    chopps 
    581   1.1    chopps 	if (vm->mode_num && vm->mode_num > ulowell_mon_max)
    582   1.1    chopps 		return EINVAL;
    583   1.1    chopps 
    584   1.1    chopps 	if (! vm->mode_num)
    585   1.2    chopps 		vm->mode_num = current_mon - ul_monitor_defs + 1;
    586   1.1    chopps 
    587   1.2    chopps 	md = ul_monitor_defs + vm->mode_num - 1;
    588   1.3    chopps 	strncpy (vm->mode_descr, md->mode_descr,
    589   1.1    chopps 		sizeof (vm->mode_descr));
    590   1.1    chopps 
    591   1.1    chopps 	/* XXX should tell TMS to measure it */
    592   1.1    chopps 	vm->pixel_clock  = md->pixel_clock;
    593   1.1    chopps 	vm->disp_width   = md->disp_width;
    594   1.1    chopps 	vm->disp_height  = md->disp_height;
    595   1.1    chopps 	vm->depth        = md->depth;
    596   1.1    chopps 
    597  1.24     veego 	vm->hblank_start = md->hblank_start;
    598  1.24     veego 	vm->hsync_start  = md->hsync_start;
    599  1.24     veego 	vm->hsync_stop   = md->hsync_stop;
    600  1.24     veego 	vm->htotal       = md->htotal;
    601  1.24     veego 
    602  1.24     veego 	vm->vblank_start = md->vblank_start;
    603  1.24     veego 	vm->vsync_start  = md->vsync_start;
    604  1.24     veego 	vm->vsync_stop   = md->vsync_stop;
    605   1.1    chopps 	vm->vtotal       = md->vtotal;
    606   1.1    chopps 
    607  1.24     veego 	vm->disp_flags	 = md->disp_flags;
    608   1.1    chopps 	return 0;
    609   1.1    chopps }
    610   1.1    chopps 
    611   1.1    chopps 
    612   1.1    chopps static int
    613   1.1    chopps ul_setvmode (gp, mode)
    614   1.1    chopps 	struct grf_softc *gp;
    615   1.1    chopps 	unsigned mode;
    616   1.1    chopps {
    617   1.1    chopps 	struct grf_ul_softc *gup;
    618   1.1    chopps 	struct gspregs *ba;
    619   1.1    chopps 	int error;
    620   1.1    chopps 
    621   1.1    chopps 	if (!mode || mode > ulowell_mon_max)
    622   1.1    chopps 		return EINVAL;
    623   1.1    chopps 
    624   1.1    chopps 	ba = (struct gspregs *)gp->g_regkva;
    625   1.1    chopps 	gup = (struct grf_ul_softc *)gp;
    626   1.2    chopps 	current_mon = ul_monitor_defs + mode - 1;
    627   1.1    chopps 
    628   1.1    chopps 	error = ul_load_mon (gp, current_mon) ? 0 : EINVAL;
    629   1.1    chopps 
    630   1.1    chopps 	return error;
    631   1.1    chopps }
    632   1.1    chopps 
    633   1.1    chopps /*
    634   1.1    chopps  * Set the frame buffer or overlay planes on or off.
    635   1.1    chopps  * Always succeeds.
    636   1.1    chopps  */
    637   1.1    chopps 
    638   1.1    chopps static __inline void
    639   1.1    chopps ul_setfb(gp, cmd)
    640   1.1    chopps 	struct grf_softc *gp;
    641  1.15     veego 	u_long cmd;
    642   1.1    chopps {
    643   1.1    chopps 	struct grf_ul_softc *gup;
    644   1.1    chopps 	struct gspregs *ba;
    645   1.1    chopps 
    646   1.1    chopps 	gup = (struct grf_ul_softc *)gp;
    647   1.1    chopps 
    648   1.1    chopps 	ba = (struct gspregs *)gp->g_regkva;
    649   1.1    chopps 	ba->ctrl = LBL;
    650   1.1    chopps 	ba->hstadrh = 0xfe80;
    651   1.1    chopps 	ba->hstadrl = 0x0000;
    652   1.1    chopps 	ba->data = 6;
    653   1.1    chopps 	ba->hstadrl = 0x0020;
    654   1.1    chopps 
    655   1.1    chopps 	switch (cmd) {
    656   1.1    chopps 	case GM_GRFON:
    657   1.1    chopps 		gup->gus_ovslct |= 0x40;
    658   1.1    chopps 		break;
    659   1.1    chopps 	case GM_GRFOFF:
    660   1.1    chopps 		gup->gus_ovslct &= ~0x40;
    661   1.1    chopps 		break;
    662   1.1    chopps 	case GM_GRFOVON:
    663   1.1    chopps 		gup->gus_ovslct |= 3;
    664   1.1    chopps 		break;
    665   1.1    chopps 	case GM_GRFOVOFF:
    666   1.1    chopps 		gup->gus_ovslct &= ~3;
    667   1.1    chopps 		break;
    668   1.1    chopps 	}
    669   1.1    chopps 	ba->data = gup->gus_ovslct;
    670   1.1    chopps }
    671   1.1    chopps 
    672   1.1    chopps /*
    673   1.1    chopps  * Change the mode of the display.
    674   1.1    chopps  * Return a UNIX error number or 0 for success.
    675   1.1    chopps  */
    676   1.1    chopps int
    677   1.1    chopps ul_mode(gp, cmd, arg, a2, a3)
    678   1.1    chopps 	struct grf_softc *gp;
    679  1.15     veego 	u_long cmd;
    680   1.1    chopps 	void *arg;
    681  1.15     veego 	u_long a2;
    682  1.15     veego 	int a3;
    683   1.1    chopps {
    684   1.1    chopps 	int i;
    685   1.1    chopps 	struct grfdyninfo *gd;
    686   1.1    chopps 
    687   1.1    chopps 	switch (cmd) {
    688   1.1    chopps 	case GM_GRFON:
    689   1.1    chopps 	case GM_GRFOFF:
    690   1.1    chopps 	case GM_GRFOVON:
    691   1.1    chopps 	case GM_GRFOVOFF:
    692   1.1    chopps 		ul_setfb (gp, cmd);
    693   1.1    chopps 		return 0;
    694   1.1    chopps 
    695   1.1    chopps 	case GM_GRFCONFIG:
    696   1.1    chopps 		gd = (struct grfdyninfo *)arg;
    697   1.1    chopps 		for (i=0; i<ulowell_mon_max; ++i) {
    698   1.2    chopps 			if (ul_monitor_defs[i].disp_width == gd->gdi_dwidth &&
    699   1.2    chopps 			    ul_monitor_defs[i].disp_height == gd->gdi_dheight)
    700   1.1    chopps 				return ul_setvmode(gp, i+1);
    701   1.1    chopps 		}
    702   1.1    chopps 		return EINVAL;
    703   1.1    chopps 
    704   1.1    chopps 	case GM_GRFGETVMODE:
    705   1.1    chopps 		return ul_getvmode (gp, (struct grfvideo_mode *) arg);
    706   1.1    chopps 
    707   1.1    chopps 	case GM_GRFSETVMODE:
    708   1.1    chopps 		return ul_setvmode (gp, *(unsigned *) arg);
    709   1.1    chopps 
    710   1.1    chopps 	case GM_GRFGETNUMVM:
    711   1.1    chopps 		*(int *)arg = ulowell_mon_max;
    712   1.1    chopps 		return 0;
    713   1.1    chopps 
    714   1.1    chopps 	case GM_GRFIOCTL:
    715  1.15     veego 		return ul_ioctl (gp, a2, arg, (dev_t)a3);
    716   1.1    chopps 
    717   1.1    chopps 	default:
    718   1.1    chopps 		break;
    719   1.1    chopps 	}
    720   1.1    chopps 
    721   1.1    chopps 	return EINVAL;
    722   1.1    chopps }
    723   1.1    chopps 
    724   1.1    chopps int
    725   1.1    chopps ul_ioctl (gp, cmd, data, dev)
    726   1.1    chopps 	register struct grf_softc *gp;
    727   1.1    chopps 	u_long cmd;
    728   1.1    chopps 	void *data;
    729   1.1    chopps 	dev_t dev;
    730   1.1    chopps {
    731   1.1    chopps 	switch (cmd) {
    732   1.1    chopps #if 0
    733   1.1    chopps 	/*
    734   1.1    chopps 	 * XXX we have no hardware sprites, but might implement them
    735   1.1    chopps 	 * later in TMS code.
    736   1.1    chopps 	 */
    737   1.1    chopps 
    738   1.1    chopps 	case GRFIOCGSPRITEPOS:
    739   1.1    chopps 		return ul_getspritepos (gp, (struct grf_position *) data);
    740   1.1    chopps 
    741   1.1    chopps 	case GRFIOCSSPRITEPOS:
    742   1.1    chopps 		return ul_setspritepos (gp, (struct grf_position *) data);
    743   1.1    chopps 
    744   1.1    chopps 	case GRFIOCSSPRITEINF:
    745   1.1    chopps 		return ul_setspriteinfo (gp, (struct grf_spriteinfo *) data);
    746   1.1    chopps 
    747   1.1    chopps 	case GRFIOCGSPRITEINF:
    748   1.1    chopps 		return ul_getspriteinfo (gp, (struct grf_spriteinfo *) data);
    749   1.1    chopps 
    750   1.1    chopps 	case GRFIOCGSPRITEMAX:
    751   1.1    chopps 		return ul_getspritemax (gp, (struct grf_position *) data);
    752   1.1    chopps 
    753   1.1    chopps #endif
    754   1.1    chopps 
    755   1.1    chopps 	case GRFIOCGETCMAP:
    756   1.1    chopps 		return ul_getcmap (gp, (struct grf_colormap *) data, dev);
    757   1.1    chopps 
    758   1.1    chopps 	case GRFIOCPUTCMAP:
    759   1.1    chopps 		return ul_putcmap (gp, (struct grf_colormap *) data, dev);
    760   1.1    chopps 
    761   1.1    chopps 	case GRFIOCBITBLT:
    762   1.1    chopps 		return ul_bitblt (gp, (struct grf_bitblt *) data, dev);
    763  1.10    chopps 
    764  1.10    chopps 	case GRFIOCBLANK:
    765  1.10    chopps 		return ul_blank (gp, (int *) data, dev);
    766   1.1    chopps 	}
    767   1.1    chopps 
    768   1.1    chopps 	return EINVAL;
    769   1.1    chopps }
    770   1.1    chopps 
    771   1.1    chopps int
    772   1.1    chopps ul_getcmap (gp, cmap, dev)
    773   1.1    chopps 	struct grf_softc *gp;
    774   1.1    chopps 	struct grf_colormap *cmap;
    775   1.1    chopps 	dev_t dev;
    776   1.1    chopps {
    777   1.1    chopps 	struct grf_ul_softc *gup;
    778   1.1    chopps 	u_int8_t *mymap;
    779   1.5    chopps 	int mxidx, error;
    780   1.1    chopps 
    781   1.1    chopps 	gup = (struct grf_ul_softc *)gp;
    782   1.1    chopps 
    783   1.1    chopps 	if (minor(dev) & GRFIMDEV) {
    784   1.1    chopps 		mxidx = 256;
    785   1.1    chopps 		mymap = gup->gus_imcmap;
    786   1.1    chopps 	} else {
    787   1.1    chopps 		mxidx = 4;
    788   1.1    chopps 		mymap = gup->gus_ovcmap;
    789   1.1    chopps 	}
    790   1.1    chopps 
    791   1.1    chopps 	if (cmap->count == 0 || cmap->index >= mxidx)
    792   1.1    chopps 		return 0;
    793   1.1    chopps 
    794   1.1    chopps 	if (cmap->index + cmap->count > mxidx)
    795   1.1    chopps 		cmap->count = mxidx - cmap->index;
    796   1.1    chopps 
    797   1.1    chopps 	/* just copyout from the shadow color map */
    798   1.1    chopps 
    799   1.1    chopps 	if ((error = copyout(mymap + cmap->index, cmap->red, cmap->count))
    800   1.1    chopps 
    801   1.1    chopps 	    || (error = copyout(mymap + mxidx + cmap->index, cmap->green,
    802   1.1    chopps 		cmap->count))
    803   1.1    chopps 
    804   1.1    chopps 	    || (error = copyout(mymap + mxidx * 2 + cmap->index, cmap->blue,
    805   1.1    chopps 		cmap->count)))
    806   1.1    chopps 
    807   1.1    chopps 		return(error);
    808   1.1    chopps 
    809   1.1    chopps 	return(0);
    810   1.1    chopps }
    811   1.1    chopps 
    812   1.1    chopps int
    813   1.1    chopps ul_putcmap (gp, cmap, dev)
    814   1.1    chopps 	struct grf_softc *gp;
    815   1.1    chopps 	struct grf_colormap *cmap;
    816   1.1    chopps 	dev_t dev;
    817   1.1    chopps {
    818   1.1    chopps 	struct grf_ul_softc *gup;
    819   1.1    chopps 	struct gspregs *ba;
    820   1.1    chopps 	u_int16_t cmd[8];
    821   1.1    chopps 	int x, mxidx, error;
    822   1.1    chopps 	u_int8_t *mymap;
    823   1.1    chopps 
    824   1.1    chopps 	gup = (struct grf_ul_softc *)gp;
    825   1.1    chopps 
    826   1.1    chopps 	if (minor(dev) & GRFIMDEV) {
    827   1.1    chopps 		mxidx = 256;
    828   1.1    chopps 		mymap = gup->gus_imcmap;
    829   1.1    chopps 	} else {
    830   1.1    chopps 		mxidx = 4;
    831   1.1    chopps 		mymap = gup->gus_ovcmap;
    832   1.1    chopps 	}
    833   1.1    chopps 
    834   1.1    chopps 	if (cmap->count == 0 || cmap->index >= mxidx)
    835   1.1    chopps 		return 0;
    836   1.1    chopps 
    837   1.1    chopps 	if (cmap->index + cmap->count > mxidx)
    838   1.1    chopps 		cmap->count = mxidx - cmap->index;
    839   1.1    chopps 
    840   1.1    chopps 	/* first copyin to our shadow color map */
    841   1.1    chopps 
    842   1.1    chopps 	if ((error = copyin(cmap->red, mymap + cmap->index, cmap->count))
    843   1.1    chopps 
    844   1.1    chopps 	    || (error = copyin(cmap->green, mymap + cmap->index + mxidx,
    845   1.1    chopps 		cmap->count))
    846   1.1    chopps 
    847   1.1    chopps 	    || (error = copyin(cmap->blue,  mymap + cmap->index + mxidx*2,
    848   1.1    chopps 		cmap->count)))
    849   1.1    chopps 
    850   1.1    chopps 		return error;
    851   1.1    chopps 
    852   1.1    chopps 
    853   1.1    chopps 	/* then write from there to the hardware */
    854   1.1    chopps 	ba = (struct gspregs *)gp->g_regkva;
    855   1.9    chopps 	/*
    856   1.9    chopps 	 * XXX This is a bad thing to do.
    857   1.9    chopps 	 * We should always use the gsp call, or have a means to arbitrate
    858  1.12        is 	 * the usage of the BT458 index register. Else there might be a
    859   1.9    chopps 	 * race condition (when writing both colormaps at nearly the same
    860   1.9    chopps 	 * time), where one CPU changes the index register when the other
    861   1.9    chopps 	 * one has not finished using it.
    862   1.9    chopps 	 */
    863   1.1    chopps 	if (mxidx > 4) {
    864   1.1    chopps 		/* image color map: we can write, with a hack, directly */
    865   1.1    chopps 		ba->ctrl = LBL;
    866   1.1    chopps 		ba->hstadrh = 0xfe80;
    867   1.1    chopps 		ba->hstadrl = 0x0000;
    868   1.1    chopps 		ba->ctrl |= INCW;
    869   1.1    chopps 		ba->data = cmap->index;
    870   1.1    chopps 		ba->ctrl &= ~INCW;
    871   1.1    chopps 
    872   1.1    chopps 		for (x=cmap->index; x < cmap->index + cmap->count; ++x) {
    873   1.1    chopps 			ba->data = (u_int16_t) mymap[x];
    874   1.1    chopps 			ba->data = (u_int16_t) mymap[x + mxidx];
    875   1.1    chopps 			ba->data = (u_int16_t) mymap[x + mxidx * 2];
    876   1.1    chopps 		}
    877   1.1    chopps 	} else {
    878   1.1    chopps 
    879   1.1    chopps 		/* overlay planes color map: have to call tms to do it */
    880   1.1    chopps 		cmd[0] = GCMD_CMAP;
    881   1.1    chopps 		cmd[1] = 1;
    882   1.1    chopps 		for (x=cmap->index; x < cmap->index + cmap->count; ++x) {
    883   1.1    chopps 			cmd[2] = x;
    884   1.1    chopps 			cmd[3] = mymap[x];
    885   1.1    chopps 			cmd[4] = mymap[x + mxidx];
    886   1.1    chopps 			cmd[5] = mymap[x + mxidx * 2];
    887   1.1    chopps 			gsp_write(ba, cmd, 6);
    888   1.1    chopps 		}
    889   1.1    chopps 	}
    890   1.1    chopps 	return 0;
    891   1.1    chopps }
    892   1.1    chopps 
    893  1.10    chopps int
    894  1.10    chopps ul_blank(gp, onoff, dev)
    895  1.10    chopps 	struct grf_softc *gp;
    896  1.10    chopps 	int *onoff;
    897  1.10    chopps 	dev_t dev;
    898  1.10    chopps {
    899  1.10    chopps 	struct gspregs *gsp;
    900  1.17        is 
    901  1.10    chopps 	gsp = (struct gspregs *)gp->g_regkva;
    902  1.15     veego 	gsp->ctrl = (gsp->ctrl & ~(INCR | INCW)) | LBL;
    903  1.10    chopps 	gsp->hstadrh = 0xC000;
    904  1.10    chopps 	gsp->hstadrl = 0x0080;
    905  1.18        is 	if (*onoff > 0)
    906  1.10    chopps 		gsp->data |= 0x9000;
    907  1.10    chopps 	else
    908  1.10    chopps 		gsp->data &= ~0x9000;
    909  1.10    chopps 
    910  1.10    chopps 	return 0;
    911  1.10    chopps }
    912   1.1    chopps /*
    913   1.1    chopps  * !!! THIS AREA UNDER CONSTRUCTION !!!
    914   1.1    chopps  */
    915   1.1    chopps int ul_BltOpMap[16] = {
    916   1.1    chopps 	3, 1, 2, 0, 11,  9, 10, 8,
    917   1.1    chopps 	7, 5, 6, 4, 15, 13, 14, 12
    918   1.1    chopps };
    919   1.1    chopps 
    920   1.1    chopps int
    921   1.1    chopps ul_bitblt (gp, bb, dev)
    922   1.1    chopps 	struct grf_softc *gp;
    923   1.1    chopps 	struct grf_bitblt *bb;
    924   1.1    chopps 	dev_t dev;
    925   1.1    chopps {
    926   1.1    chopps 	/* XXX not yet implemented, but pretty trivial */
    927   1.1    chopps 	return EINVAL;
    928   1.1    chopps }
    929   1.1    chopps 
    930   1.1    chopps void
    931   1.1    chopps gsp_write(gsp, ptr, size)
    932   1.1    chopps 	struct gspregs *gsp;
    933   1.1    chopps 	u_short *ptr;
    934   1.1    chopps 	size_t size;
    935   1.1    chopps {
    936   1.1    chopps 	u_short put, new_put, next, oc;
    937   1.1    chopps 	u_long put_hi, oa;
    938   1.1    chopps 	size_t n;
    939   1.1    chopps 
    940   1.1    chopps 	if (size == 0 || size > 8)
    941   1.1    chopps 	        return;
    942   1.1    chopps 
    943   1.1    chopps 	n = size;
    944   1.1    chopps 
    945   1.1    chopps 	oc = gsp->ctrl;
    946   1.1    chopps 	oa = GSPGETHADRS(gsp);
    947   1.1    chopps 
    948   1.5    chopps 	gsp->ctrl = (oc & ~INCR) | LBL | INCW;
    949   1.5    chopps 	GSPSETHADRS(gsp, GSP_MODE_ADRS);
    950   1.1    chopps 	gsp->data &= ~GMODE_FLUSH;
    951   1.1    chopps 
    952   1.5    chopps 	GSPSETHADRS(gsp, PUT_HI_PTR_ADRS);
    953   1.1    chopps 	put_hi = gsp->data << 16;
    954   1.1    chopps 
    955   1.5    chopps 	GSPSETHADRS(gsp, PUT_PTR_ADRS);
    956   1.1    chopps 	put = gsp->data;
    957   1.1    chopps 	new_put = put + (8<<4);
    958   1.1    chopps 
    959   1.5    chopps 	GSPSETHADRS(gsp, GET_PTR_ADRS);
    960   1.1    chopps 	next = gsp->data;
    961   1.1    chopps 
    962   1.1    chopps 	while (next == new_put) {
    963   1.1    chopps 		/*
    964   1.1    chopps 		 * we should use an intr. here. unfortunately, we already
    965   1.1    chopps 		 * are called from an interupt and can't use tsleep.
    966   1.1    chopps 		 * so we do busy waiting, at least for the moment.
    967   1.1    chopps 		 */
    968   1.1    chopps 
    969   1.1    chopps 		GSPSETHADRS(gsp,GET_PTR_ADRS);
    970   1.1    chopps 		next = gsp->data;
    971   1.1    chopps 	}
    972   1.1    chopps 
    973   1.1    chopps 	GSPSETHADRS(gsp,put|put_hi);
    974   1.1    chopps 	gsp->data = *ptr++ | 8<<4;
    975   1.1    chopps 	while ( --n > 0) {
    976   1.1    chopps 		gsp->data = *ptr++;
    977   1.1    chopps 	}
    978   1.1    chopps 
    979   1.1    chopps 	GSPSETHADRS(gsp,PUT_PTR_ADRS);
    980   1.1    chopps 	gsp->data = new_put;
    981   1.1    chopps 	GSPSETHADRS(gsp,oa);
    982   1.1    chopps 	gsp->ctrl = oc;
    983   1.1    chopps 
    984   1.1    chopps 	return;
    985   1.1    chopps }
    986   1.1    chopps 
    987   1.1    chopps #endif	/* NGRF */
    988