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