summaryrefslogtreecommitdiff
path: root/sys/arch/atari/dev/grf.c
diff options
context:
space:
mode:
authorleo <leo@NetBSD.org>1995-03-26 07:12:03 +0000
committerleo <leo@NetBSD.org>1995-03-26 07:12:03 +0000
commit8b0113cfceadf3ee3bc427c4680b6b46bb57ceea (patch)
tree2a5b7db0400149a733175c4b1a56774b2d4c1eb7 /sys/arch/atari/dev/grf.c
parent282052c7a8346370f47965457329f3b0b3fa01b7 (diff)
NetBSD/Atari, port by Leo Weppelman.
Diffstat (limited to 'sys/arch/atari/dev/grf.c')
-rw-r--r--sys/arch/atari/dev/grf.c559
1 files changed, 559 insertions, 0 deletions
diff --git a/sys/arch/atari/dev/grf.c b/sys/arch/atari/dev/grf.c
new file mode 100644
index 00000000000..0feec1999da
--- /dev/null
+++ b/sys/arch/atari/dev/grf.c
@@ -0,0 +1,559 @@
+/* $NetBSD: grf.c,v 1.1.1.1 1995/03/26 07:12:12 leo Exp $ */
+
+/*
+ * Copyright (c) 1995 Leo Weppelman
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Utah $Hdr: grf.c 1.31 91/01/21$
+ *
+ * @(#)grf.c 7.8 (Berkeley) 5/7/91
+ */
+
+/*
+ * Graphics display driver for the Atari
+ * This is the hardware-independent portion of the driver.
+ * Hardware access is through the grf_softc->g_mode routine.
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+#include <sys/file.h>
+#include <sys/malloc.h>
+#include <sys/conf.h>
+#include <sys/systm.h>
+#include <sys/vnode.h>
+#include <sys/mman.h>
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+#include <machine/cpu.h>
+#include <atari/atari/device.h>
+#include <atari/dev/grfioctl.h>
+#include <atari/dev/grfabs_reg.h>
+#include <atari/dev/grfvar.h>
+#include <atari/dev/itevar.h>
+#include <atari/dev/viewioctl.h>
+#include <atari/dev/viewvar.h>
+
+#include "grf.h"
+#if NGRF > 0
+
+#include "ite.h"
+#if NITE == 0
+#define ite_on(u,f)
+#define ite_off(u,f)
+#define ite_reinit(d)
+#endif
+
+int grfopen __P((dev_t, int, int, struct proc *));
+int grfclose __P((dev_t, int));
+int grfioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
+int grfselect __P((dev_t, int));
+int grfmap __P((dev_t, int, int));
+
+int grfon __P((dev_t));
+int grfoff __P((dev_t));
+int grfsinfo __P((dev_t, struct grfdyninfo *));
+#ifdef BANKEDDEVPAGER
+int grfbanked_get __P((dev_t, off_t, int));
+int grfbanked_cur __P((dev_t));
+int grfbanked_set __P((dev_t, int));
+#endif
+static void grf_viewsync __P((struct grf_softc *));
+static int grf_mode __P((struct grf_softc *, int, void *, int, int));
+
+int grfbusprint __P((void *auxp, char *));
+int grfbusmatch __P((struct device *, struct cfdata *, void *));
+void grfbusattach __P((struct device *, struct device *, void *));
+
+void grfattach __P((struct device *, struct device *, void *));
+int grfmatch __P((struct device *, struct cfdata *, void *));
+int grfprint __P((void *, char *));
+/*
+ * pointers to grf drivers device structs
+ */
+struct grf_softc *grfsp[NGRF];
+
+
+struct cfdriver grfbuscd = {
+ NULL, "grfbus", (cfmatch_t)grfbusmatch, grfbusattach, DV_DULL,
+ sizeof(struct device)
+};
+
+struct cfdriver grfcd = {
+ NULL, "grf", (cfmatch_t)grfmatch, grfattach, DV_DULL,
+ sizeof(struct grf_softc), NULL, 0
+};
+
+/*
+ * only used in console init.
+ */
+static struct cfdata *cfdata_gbus = NULL;
+static struct cfdata *cfdata_grf = NULL;
+
+int
+grfbusmatch(pdp, cfp, auxp)
+struct device *pdp;
+struct cfdata *cfp;
+void *auxp;
+{
+ if(strcmp(auxp, grfbuscd.cd_name))
+ return(0);
+
+ if((atari_realconfig == 0) || (cfdata_gbus == NULL)) {
+ /*
+ * Probe layers we depend on
+ */
+ if(grfabs_probe() == 0)
+ return(0);
+ viewprobe();
+
+ if(atari_realconfig == 0) {
+ /*
+ * XXX: console init opens view 0
+ */
+ if(viewopen(0, 0))
+ return(0);
+ cfdata_gbus = cfp;
+ }
+ }
+ return(1); /* Always there */
+}
+
+void
+grfbusattach(pdp, dp, auxp)
+struct device *pdp, *dp;
+void *auxp;
+{
+ static int did_cons = 0;
+ int i;
+
+ if(dp == NULL) { /* Console init */
+ did_cons = 1;
+ i = 0;
+ atari_config_found(cfdata_gbus, NULL, (void*)&i, grfbusprint);
+ }
+ else {
+ printf("\n");
+ for(i = 0; i < NGRF; i++) {
+ /*
+ * Skip opening view[0] when we this is the console.
+ */
+ if(!did_cons || (i > 0))
+ if(viewopen(i, 0))
+ break;
+ config_found(dp, (void*)&i, grfbusprint);
+ }
+ }
+}
+
+int
+grfbusprint(auxp, name)
+void *auxp;
+char *name;
+{
+ if(name == NULL)
+ return(UNCONF);
+ return(QUIET);
+}
+
+
+int
+grfmatch(pdp, cfp, auxp)
+struct device *pdp;
+struct cfdata *cfp;
+void *auxp;
+{
+ int unit = *(int*)auxp;
+
+ /*
+ * Match only on unit indicated by grfbus attach.
+ */
+ if(cfp->cf_unit != unit)
+ return(0);
+
+ cfdata_grf = cfp;
+ return(1);
+}
+
+/*
+ * attach: initialize the grf-structure and try to attach an ite to us.
+ * note : dp is NULL during early console init.
+ */
+void
+grfattach(pdp, dp, auxp)
+struct device *pdp, *dp;
+void *auxp;
+{
+ extern struct view_softc views[];
+ static struct grf_softc congrf;
+ struct grf_softc *gp;
+ int maj;
+
+ /*
+ * find our major device number
+ */
+ for(maj = 0; maj < nchrdev; maj++)
+ if (cdevsw[maj].d_open == grfopen)
+ break;
+
+ /*
+ * Handle exeption case: early console init
+ */
+ if(dp == NULL) {
+ congrf.g_unit = 0;
+ congrf.g_grfdev = makedev(maj, 0);
+ congrf.g_flags = GF_ALIVE;
+ congrf.g_mode = grf_mode;
+ congrf.g_conpri = grfcc_cnprobe();
+ congrf.g_view = views[0].view; /* XXX */
+ congrf.g_viewdev = congrf.g_unit;
+ grfcc_iteinit(&congrf);
+ grf_viewsync(&congrf);
+
+ /* Attach console ite */
+ atari_config_found(cfdata_grf, NULL, &congrf, grfprint);
+ return;
+ }
+
+ gp = (struct grf_softc *)dp;
+ gp->g_unit = gp->g_device.dv_unit;
+ grfsp[gp->g_unit] = gp;
+
+ if((cfdata_grf != NULL) && (gp->g_unit == 0)) {
+ /*
+ * We inited earlier just copy the info, take care
+ * not to copy the device struct though.
+ */
+ bcopy(&congrf.g_display, &gp->g_display,
+ (char *)&gp[1] - (char *)&gp->g_display);
+ }
+ else {
+ gp->g_grfdev = makedev(maj, gp->g_unit);
+ gp->g_flags = GF_ALIVE;
+ gp->g_mode = grf_mode;
+ gp->g_conpri = 0;
+ gp->g_view = views[gp->g_unit].view; /* XXX */
+ gp->g_viewdev = gp->g_unit;
+ grfcc_iteinit(gp);
+ grf_viewsync(gp);
+ }
+
+ printf(": width %d height %d", gp->g_display.gd_dwidth,
+ gp->g_display.gd_dheight);
+ if(gp->g_display.gd_colors == 2)
+ printf(" monochrome\n");
+ else printf(" colors %d\n", gp->g_display.gd_colors);
+
+ /*
+ * try and attach an ite
+ */
+ config_found(dp, gp, grfprint);
+}
+
+int
+grfprint(auxp, pnp)
+void *auxp;
+char *pnp;
+{
+ if(pnp)
+ printf("ite at %s", pnp);
+ return(UNCONF);
+}
+
+/*ARGSUSED*/
+int
+grfopen(dev, flags, devtype, p)
+ dev_t dev;
+ int flags, devtype;
+ struct proc *p;
+{
+ struct grf_softc *gp;
+
+ if (GRFUNIT(dev) >= NGRF)
+ return(ENXIO);
+
+ gp = grfsp[GRFUNIT(dev)];
+
+ if ((gp->g_flags & GF_ALIVE) == 0)
+ return(ENXIO);
+
+ if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE))
+ return(EBUSY);
+
+ return(0);
+}
+
+/*ARGSUSED*/
+int
+grfclose(dev, flags)
+ dev_t dev;
+ int flags;
+{
+ struct grf_softc *gp;
+
+ gp = grfsp[GRFUNIT(dev)];
+ (void)grfoff(dev);
+ gp->g_flags &= GF_ALIVE;
+ return(0);
+}
+
+/*ARGSUSED*/
+int
+grfioctl(dev, cmd, data, flag, p)
+dev_t dev;
+u_long cmd;
+int flag;
+caddr_t data;
+struct proc *p;
+{
+ struct grf_softc *gp;
+ int error;
+
+ gp = grfsp[GRFUNIT(dev)];
+ error = 0;
+
+ switch (cmd) {
+ case OGRFIOCGINFO:
+ /* argl.. no bank-member.. */
+ bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)-4);
+ break;
+ case GRFIOCGINFO:
+ bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo));
+ break;
+ case GRFIOCON:
+ error = grfon(dev);
+ break;
+ case GRFIOCOFF:
+ error = grfoff(dev);
+ break;
+ case GRFIOCSINFO:
+ error = grfsinfo(dev, (struct grfdyninfo *) data);
+ break;
+ case GRFGETVMODE:
+ return(gp->g_mode(gp, GM_GRFGETVMODE, data));
+ case GRFSETVMODE:
+ error = gp->g_mode(gp, GM_GRFSETVMODE, data);
+ if (error == 0 && gp->g_itedev)
+ ite_reinit(gp->g_itedev);
+ break;
+ case GRFGETNUMVM:
+ return(gp->g_mode(gp, GM_GRFGETNUMVM, data));
+ /*
+ * these are all hardware dependant, and have to be resolved
+ * in the respective driver.
+ */
+ case GRFIOCPUTCMAP:
+ case GRFIOCGETCMAP:
+ case GRFIOCSSPRITEPOS:
+ case GRFIOCGSPRITEPOS:
+ case GRFIOCSSPRITEINF:
+ case GRFIOCGSPRITEINF:
+ case GRFIOCGSPRITEMAX:
+ default:
+ /*
+ * check to see whether it's a command recognized by the
+ * view code.
+ */
+ if(gp->g_view != NULL)
+ return(viewioctl(gp->g_viewdev, cmd, data, flag, p));
+ error = EINVAL;
+ break;
+
+ }
+ return(error);
+}
+
+/*ARGSUSED*/
+int
+grfselect(dev, rw)
+ dev_t dev;
+ int rw;
+{
+ if (rw == FREAD)
+ return(0);
+ return(1);
+}
+
+/*
+ * map the contents of a graphics display card into process'
+ * memory space.
+ */
+int
+grfmap(dev, off, prot)
+dev_t dev;
+int off, prot;
+{
+panic("No grfmap\n"); /* LWP */
+}
+
+int
+grfon(dev)
+ dev_t dev;
+{
+ struct grf_softc *gp;
+
+ gp = grfsp[GRFUNIT(dev)];
+
+ if (gp->g_flags & GF_GRFON)
+ return(0);
+
+ gp->g_flags |= GF_GRFON;
+ if (gp->g_itedev != NODEV)
+ ite_off(gp->g_itedev, 3);
+
+ return(gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVON : GM_GRFON));
+}
+
+int
+grfoff(dev)
+ dev_t dev;
+{
+ struct grf_softc *gp;
+ int error;
+
+ gp = grfsp[GRFUNIT(dev)];
+
+ if ((gp->g_flags & GF_GRFON) == 0)
+ return(0);
+
+ gp->g_flags &= ~GF_GRFON;
+ error = gp->g_mode(gp, (dev & GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF);
+
+ /*
+ * Closely tied together no X's
+ */
+ if (gp->g_itedev != NODEV)
+ ite_on(gp->g_itedev, 2);
+
+ return(error);
+}
+
+int
+grfsinfo(dev, dyninfo)
+ dev_t dev;
+ struct grfdyninfo *dyninfo;
+{
+ struct grf_softc *gp;
+ int error;
+
+ gp = grfsp[GRFUNIT(dev)];
+ error = gp->g_mode(gp, GM_GRFCONFIG, dyninfo);
+
+ /*
+ * Closely tied together no X's
+ */
+ if (gp->g_itedev != NODEV)
+ ite_reinit(gp->g_itedev);
+ return(error);
+}
+
+/*
+ * Get the grf-info in sync with underlying view.
+ */
+static void
+grf_viewsync(gp)
+struct grf_softc *gp;
+{
+ struct view_size vs;
+ bmap_t bm;
+ struct grfinfo *gi;
+
+ gi = &gp->g_display;
+
+ viewioctl(gp->g_viewdev, VIOCGBMAP, &bm, 0, -1);
+
+ gp->g_data = (caddr_t) 0xDeadBeaf; /* not particularly clean.. */
+
+ gi->gd_fbaddr = bm.hw_address;
+ gi->gd_fbsize = bm.depth*bm.bytes_per_row*bm.rows;
+
+ if(viewioctl(gp->g_viewdev, VIOCGSIZE, &vs, 0, -1)) {
+ /*
+ * fill in some default values...
+ * XXX: Should _never_ happen
+ */
+ vs.width = 640;
+ vs.height = 400;
+ vs.depth = 2;
+ }
+ gi->gd_colors = 1 << vs.depth;
+ gi->gd_planes = vs.depth;
+
+ gi->gd_fbwidth = vs.width;
+ gi->gd_fbheight = vs.height;
+ gi->gd_dyn.gdi_fbx = 0;
+ gi->gd_dyn.gdi_fby = 0;
+ gi->gd_dyn.gdi_dwidth = vs.width;
+ gi->gd_dyn.gdi_dheight = vs.height;
+ gi->gd_dyn.gdi_dx = 0;
+ gi->gd_dyn.gdi_dy = 0;
+}
+
+/*
+ * Change the mode of the display.
+ * Right now all we can do is grfon/grfoff.
+ * Return a UNIX error number or 0 for success.
+ */
+/*ARGSUSED*/
+static int
+grf_mode(gp, cmd, arg, a2, a3)
+struct grf_softc *gp;
+int cmd, a2, a3;
+void *arg;
+{
+ switch (cmd) {
+ case GM_GRFON:
+ /*
+ * Get in sync with view, ite might have changed it.
+ */
+ grf_viewsync(gp);
+ viewioctl(gp->g_viewdev, VIOCDISPLAY, NULL, 0, -1);
+ return(0);
+ case GM_GRFOFF:
+ viewioctl(gp->g_viewdev, VIOCREMOVE, NULL, 0, -1);
+ return(0);
+ case GM_GRFCONFIG:
+ default:
+ break;
+ }
+ return(EINVAL);
+}
+#endif /* NGRF > 0 */