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