summaryrefslogtreecommitdiff
path: root/sys/arch/amiga/dev
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1997-09-18 13:40:05 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1997-09-18 13:40:05 +0000
commit2157b0ba8b467d175588a39d0235e3f42cfa0167 (patch)
treeab27e576639f38402b47a6af61ab8711d85d7ce7 /sys/arch/amiga/dev
parent9557efb948677ebfd961c6f49a7b69e3c722c206 (diff)
Merge of NetBSD changes upto last week or so, with the exception of stand/
Diffstat (limited to 'sys/arch/amiga/dev')
-rw-r--r--sys/arch/amiga/dev/a2kbbc.c248
-rw-r--r--sys/arch/amiga/dev/a34kbbc.c188
-rw-r--r--sys/arch/amiga/dev/aucc.c978
-rw-r--r--sys/arch/amiga/dev/auccvar.h65
-rw-r--r--sys/arch/amiga/dev/clock.c350
-rw-r--r--sys/arch/amiga/dev/com_supio.c266
-rw-r--r--sys/arch/amiga/dev/drbbc.c205
-rw-r--r--sys/arch/amiga/dev/drcom.c1285
-rw-r--r--sys/arch/amiga/dev/drisavar.h23
-rw-r--r--sys/arch/amiga/dev/drsupio.c172
-rw-r--r--sys/arch/amiga/dev/grf_cl.c753
-rw-r--r--sys/arch/amiga/dev/grf_clreg.h10
-rw-r--r--sys/arch/amiga/dev/grf_cv.c636
-rw-r--r--sys/arch/amiga/dev/grf_cvreg.h26
-rw-r--r--sys/arch/amiga/dev/grf_et.c386
-rw-r--r--sys/arch/amiga/dev/grf_etreg.h8
-rw-r--r--sys/arch/amiga/dev/grf_rh.c30
-rw-r--r--sys/arch/amiga/dev/grf_rhreg.h32
-rw-r--r--sys/arch/amiga/dev/grf_rt.c57
-rw-r--r--sys/arch/amiga/dev/grf_ul.c97
-rw-r--r--sys/arch/amiga/dev/if_ae.c1141
-rw-r--r--sys/arch/amiga/dev/if_aereg.h156
-rw-r--r--sys/arch/amiga/dev/if_bah.c14
-rw-r--r--sys/arch/amiga/dev/if_ed.c4
-rw-r--r--sys/arch/amiga/dev/if_levar.h15
-rw-r--r--sys/arch/amiga/dev/if_qn.c7
-rw-r--r--sys/arch/amiga/dev/ite.c3
-rw-r--r--sys/arch/amiga/dev/ite_et.c6
-rw-r--r--sys/arch/amiga/dev/rtc.h25
-rw-r--r--sys/arch/amiga/dev/ser.c3
-rw-r--r--sys/arch/amiga/dev/supio.h (renamed from sys/arch/amiga/dev/drcomvar.h)25
31 files changed, 3521 insertions, 3693 deletions
diff --git a/sys/arch/amiga/dev/a2kbbc.c b/sys/arch/amiga/dev/a2kbbc.c
new file mode 100644
index 00000000000..16081b80221
--- /dev/null
+++ b/sys/arch/amiga/dev/a2kbbc.c
@@ -0,0 +1,248 @@
+/* $OpenBSD: a2kbbc.c,v 1.1 1997/09/18 13:39:41 niklas Exp $ */
+/* $NetBSD: a2kbbc.c,v 1.3 1997/07/23 10:19:44 is Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 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: clock.c 1.18 91/01/21$
+ *
+ * @(#)clock.c 7.6 (Berkeley) 5/7/91
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <machine/psl.h>
+#include <machine/cpu.h>
+#include <amiga/amiga/device.h>
+#include <amiga/amiga/custom.h>
+#include <amiga/amiga/cia.h>
+#include <amiga/dev/rtc.h>
+#include <amiga/dev/zbusvar.h>
+
+#include <dev/clock_subr.h>
+
+int a2kbbc_match __P((struct device *, void *, void *));
+void a2kbbc_attach __P((struct device *, struct device *, void *));
+
+struct cfattach a2kbbc_ca = {
+ sizeof(struct device), a2kbbc_match, a2kbbc_attach
+};
+
+struct cfdriver a2kbbc_cd = {
+ NULL, "a2kbbc", DV_DULL, NULL, 0
+};
+
+void *a2kclockaddr;
+time_t a2gettod __P((void));
+int a2settod __P((time_t));
+
+int
+a2kbbc_match(pdp, match, auxp)
+ struct device *pdp;
+ void *match;
+ void *auxp;
+{
+ struct cfdata *cfp = match;
+
+ if (!matchname("a2kbbc", auxp))
+ return (0);
+
+ if (cfp->cf_unit != 0)
+ return (0); /* only one of us please */
+
+ if (is_a1200() || is_a3000() || is_a4000()
+#ifdef DRACO
+ || is_draco()
+#endif
+ )
+ return (0);
+
+ a2kclockaddr = (void *)ztwomap(0xdc0000);
+ if (a2gettod() == 0)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Attach us to the rtc function pointers.
+ */
+void
+a2kbbc_attach(pdp, dp, auxp)
+ struct device *pdp, *dp;
+ void *auxp;
+{
+ printf("\n");
+ a2kclockaddr = (void *)ztwomap(0xdc0000);
+
+ gettod = a2gettod;
+ settod = a2settod;
+}
+
+time_t
+a2gettod()
+{
+ struct rtclock2000 *rt;
+ struct clock_ymdhms dt;
+ time_t secs;
+ int i;
+
+ rt = a2kclockaddr;
+
+ /*
+ * hold clock
+ */
+ rt->control1 |= A2CONTROL1_HOLD;
+ i = 0x1000;
+ while (rt->control1 & A2CONTROL1_BUSY && i--)
+ ;
+ if (rt->control1 & A2CONTROL1_BUSY)
+ return (0); /* Give up and say it's not there */
+
+ /* Copy the info. Careful about the order! */
+ dt.dt_sec = rt->second1 * 10 + rt->second2;
+ dt.dt_min = rt->minute1 * 10 + rt->minute2;
+ dt.dt_hour = (rt->hour1 & 3) * 10 + rt->hour2;
+ dt.dt_day = rt->day1 * 10 + rt->day2;
+ dt.dt_mon = rt->month1 * 10 + rt->month2;
+ dt.dt_year = rt->year1 * 10 + rt->year2;
+ dt.dt_wday = rt->weekday;
+
+ /*
+ * The oki clock chip has a register to put the clock into
+ * 12/24h mode.
+ *
+ * clockmode | A2HOUR1_PM
+ * 24h 12h | am = 0, pm = 1
+ * ---------------------------------
+ * 0 12 | 0
+ * 1 1 | 0
+ * .. .. | 0
+ * 11 11 | 0
+ * 12 12 | 1
+ * 13 1 | 1
+ * .. .. | 1
+ * 23 11 | 1
+ *
+ */
+
+ if ((rt->control3 & A2CONTROL3_24HMODE) == 0) {
+ if ((rt->hour1 & A2HOUR1_PM) == 0 && dt.dt_hour == 12)
+ dt.dt_hour = 0;
+ else if ((rt->hour1 & A2HOUR1_PM) && dt.dt_hour != 12)
+ dt.dt_hour += 12;
+ }
+
+ /*
+ * release the clock
+ */
+ rt->control1 &= ~A2CONTROL1_HOLD;
+
+ dt.dt_year += CLOCK_BASE_YEAR;
+
+ if ((dt.dt_hour > 23) ||
+ (dt.dt_day > 31) ||
+ (dt.dt_mon > 12) ||
+ (dt.dt_year < STARTOFTIME) || (dt.dt_year > 2036))
+ return (0);
+
+ secs = clock_ymdhms_to_secs(&dt);
+ return (secs);
+}
+
+int
+a2settod(secs)
+ time_t secs;
+{
+ struct rtclock2000 *rt;
+ struct clock_ymdhms dt;
+ int ampm, i;
+
+ rt = a2kclockaddr;
+ /*
+ * there seem to be problems with the bitfield addressing
+ * currently used..
+ */
+ if (! rt)
+ return (0);
+
+ clock_secs_to_ymdhms(secs, &dt);
+ dt.dt_year -= CLOCK_BASE_YEAR;
+
+ /*
+ * hold clock
+ */
+ rt->control1 |= A2CONTROL1_HOLD;
+ i = 0x1000;
+ while (rt->control1 & A2CONTROL1_BUSY && i--)
+ ;
+ if (rt->control1 & A2CONTROL1_BUSY)
+ return (0); /* Give up and say it's not there */
+
+ ampm = 0;
+ if ((rt->control3 & A2CONTROL3_24HMODE) == 0) {
+ if (dt.dt_hour >= 12) {
+ ampm = A2HOUR1_PM;
+ if (dt.dt_hour != 12)
+ dt.dt_hour -= 12;
+ } else if (dt.dt_hour == 0) {
+ dt.dt_hour = 12;
+ }
+ }
+ rt->hour1 = (dt.dt_hour / 10) | ampm;
+ rt->hour2 = dt.dt_hour % 10;
+ rt->second1 = dt.dt_sec / 10;
+ rt->second2 = dt.dt_sec % 10;
+ rt->minute1 = dt.dt_min / 10;
+ rt->minute2 = dt.dt_min % 10;
+ rt->day1 = dt.dt_day / 10;
+ rt->day2 = dt.dt_day % 10;
+ rt->month1 = dt.dt_mon / 10;
+ rt->month2 = dt.dt_mon % 10;
+ rt->year1 = dt.dt_year / 10;
+ rt->year2 = dt.dt_year % 10;
+ rt->weekday = dt.dt_wday;
+
+ /*
+ * release the clock
+ */
+ rt->control2 &= ~A2CONTROL1_HOLD;
+
+ return (1);
+}
diff --git a/sys/arch/amiga/dev/a34kbbc.c b/sys/arch/amiga/dev/a34kbbc.c
new file mode 100644
index 00000000000..3f4cc8af7db
--- /dev/null
+++ b/sys/arch/amiga/dev/a34kbbc.c
@@ -0,0 +1,188 @@
+/* $OpenBSD: a34kbbc.c,v 1.1 1997/09/18 13:39:42 niklas Exp $ */
+/* $NetBSD: a34kbbc.c,v 1.1 1997/07/19 00:01:42 is Exp $ */
+
+/*
+ * Copyright (c) 1988 University of Utah.
+ * Copyright (c) 1982, 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: clock.c 1.18 91/01/21$
+ *
+ * @(#)clock.c 7.6 (Berkeley) 5/7/91
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <machine/psl.h>
+#include <machine/cpu.h>
+#include <amiga/amiga/device.h>
+#include <amiga/amiga/custom.h>
+#include <amiga/amiga/cia.h>
+#include <amiga/dev/rtc.h>
+#include <amiga/dev/zbusvar.h>
+
+#include <dev/clock_subr.h>
+
+int a34kbbc_match __P((struct device *, void *, void *));
+void a34kbbc_attach __P((struct device *, struct device *, void *));
+
+struct cfattach a34kbbc_ca = {
+ sizeof(struct device), a34kbbc_match, a34kbbc_attach
+};
+
+struct cfdriver a34kbbc_cd = {
+ NULL, "a34kbbc", DV_DULL, NULL, 0
+};
+
+
+void *a34kclockaddr;
+time_t a3gettod __P((void));
+int a3settod __P((time_t));
+
+int
+a34kbbc_match(pdp, match, auxp)
+ struct device *pdp;
+ void *match;
+ void *auxp;
+{
+ struct cfdata *cfp = match;
+
+ if (!matchname("a34kbbc", auxp))
+ return(0);
+
+ if (cfp->cf_unit)
+ return(0); /* only one of us please */
+
+ if (!(is_a3000() || is_a4000()))
+ return(0);
+
+ a34kclockaddr = (void *)ztwomap(0xdc0000);
+ if (a3gettod() == 0)
+ return(0);
+
+ return(1);
+}
+
+/*
+ * Attach us to the rtc function pointers.
+ */
+void
+a34kbbc_attach(pdp, dp, auxp)
+ struct device *pdp, *dp;
+ void *auxp;
+{
+ printf("\n");
+ a34kclockaddr = (void *)ztwomap(0xdc0000);
+
+ gettod = a3gettod;
+ settod = a3settod;
+}
+
+time_t
+a3gettod()
+{
+ struct rtclock3000 *rt;
+ struct clock_ymdhms dt;
+ time_t secs;
+
+ rt = a34kclockaddr;
+
+ /* hold clock */
+ rt->control1 = A3CONTROL1_HOLD_CLOCK;
+
+ /* Copy the info. Careful about the order! */
+ dt.dt_sec = rt->second1 * 10 + rt->second2;
+ dt.dt_min = rt->minute1 * 10 + rt->minute2;
+ dt.dt_hour = rt->hour1 * 10 + rt->hour2;
+ dt.dt_wday = rt->weekday;
+ dt.dt_day = rt->day1 * 10 + rt->day2;
+ dt.dt_mon = rt->month1 * 10 + rt->month2;
+ dt.dt_year = rt->year1 * 10 + rt->year2;
+
+ dt.dt_year += CLOCK_BASE_YEAR;
+
+ /* let it run again.. */
+ rt->control1 = A3CONTROL1_FREE_CLOCK;
+
+ if ((dt.dt_hour > 23) ||
+ (dt.dt_wday > 6) ||
+ (dt.dt_day > 31) ||
+ (dt.dt_mon > 12) ||
+ (dt.dt_year < STARTOFTIME) || (dt.dt_year > 2036))
+ return (0);
+
+ secs = clock_ymdhms_to_secs(&dt);
+ return (secs);
+}
+
+int
+a3settod(secs)
+ time_t secs;
+{
+ struct rtclock3000 *rt;
+ struct clock_ymdhms dt;
+
+ rt = a34kclockaddr;
+ /*
+ * there seem to be problems with the bitfield addressing
+ * currently used..
+ */
+
+ if (! rt)
+ return (0);
+
+ clock_secs_to_ymdhms(secs, &dt);
+ dt.dt_year -= CLOCK_BASE_YEAR;
+
+ rt->control1 = A3CONTROL1_HOLD_CLOCK;
+ rt->second1 = dt.dt_sec / 10;
+ rt->second2 = dt.dt_sec % 10;
+ rt->minute1 = dt.dt_min / 10;
+ rt->minute2 = dt.dt_min % 10;
+ rt->hour1 = dt.dt_hour / 10;
+ rt->hour2 = dt.dt_hour % 10;
+ rt->weekday = dt.dt_wday;
+ rt->day1 = dt.dt_day / 10;
+ rt->day2 = dt.dt_day % 10;
+ rt->month1 = dt.dt_mon / 10;
+ rt->month2 = dt.dt_mon % 10;
+ rt->year1 = dt.dt_year / 10;
+ rt->year2 = dt.dt_year % 10;
+ rt->control1 = A3CONTROL1_FREE_CLOCK;
+
+ return (1);
+}
diff --git a/sys/arch/amiga/dev/aucc.c b/sys/arch/amiga/dev/aucc.c
new file mode 100644
index 00000000000..ba60c5b9ba8
--- /dev/null
+++ b/sys/arch/amiga/dev/aucc.c
@@ -0,0 +1,978 @@
+/* $OpenBSD: aucc.c,v 1.1 1997/09/18 13:39:42 niklas Exp $ */
+/* $NetBSD: aucc.c,v 1.18 1997/08/24 22:31:23 augustss Exp $ */
+#undef AUDIO_DEBUG
+/*
+ * Copyright (c) 1997 Stephan Thesing
+ * All rights reserved.
+ *
+ * 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 Stephan Thesing.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "aucc.h"
+#if NAUCC > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+#include <machine/cpu.h>
+
+#include <sys/audioio.h>
+#include <dev/audio_if.h>
+#include <amiga/amiga/cc.h>
+#include <amiga/amiga/custom.h>
+#include <amiga/amiga/device.h>
+#include <amiga/dev/auccvar.h>
+
+#ifdef LEV6_DEFER
+#define AUCC_MAXINT 3
+#define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2)
+#else
+#define AUCC_MAXINT 4
+#define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3)
+#endif
+/* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */
+#define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3)
+
+#ifdef AUDIO_DEBUG
+/*extern printf __P((const char *,...));*/
+int auccdebug = 1;
+#define DPRINTF(x) if (auccdebug) printf x
+#else
+#define DPRINTF(x)
+#endif
+
+#ifdef splaudio
+#undef splaudio
+#endif
+
+#define splaudio() spl4();
+
+/* clock frequency.. */
+extern int eclockfreq;
+
+/* hw audio ch */
+extern struct audio_channel channel[4];
+
+/*
+ * Software state.
+ */
+struct aucc_softc {
+ struct device sc_dev; /* base device */
+
+ int sc_open; /* single use device */
+ aucc_data_t sc_channel[4]; /* per channel freq, ... */
+ u_int sc_encoding; /* encoding AUDIO_ENCODING_.*/
+ int sc_channels; /* # of channels used */
+
+ int sc_intrcnt; /* interrupt count */
+ int sc_channelmask; /* which channels are used ? */
+};
+
+/* interrupt interfaces */
+void aucc_inthdl __P((int));
+
+/* forward declarations */
+int init_aucc __P((struct aucc_softc *));
+u_int freqtoper __P((u_int));
+u_int pertofreq __P((u_int));
+
+/* autoconfiguration driver */
+void auccattach __P((struct device *, struct device *, void *));
+int auccmatch __P((struct device *, void *, void *));
+
+struct cfattach aucc_ca = {
+ sizeof(struct aucc_softc),
+ auccmatch,
+ auccattach
+};
+
+struct cfdriver aucc_cd = {
+ NULL, "aucc", DV_DULL, NULL, 0
+};
+
+struct audio_device aucc_device = {
+ "Amiga-audio",
+ "x",
+ "aucc"
+};
+
+struct aucc_softc *aucc = NULL;
+
+unsigned char ulaw_to_lin[] = {
+ 0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e,
+ 0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe,
+ 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf,
+ 0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf,
+ 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
+ 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
+ 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf3, 0xf3, 0xf4,
+ 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8,
+ 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa,
+ 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc,
+ 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd,
+ 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe,
+ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+ 0x7d, 0x79, 0x75, 0x71, 0x6d, 0x69, 0x65, 0x61,
+ 0x5d, 0x59, 0x55, 0x51, 0x4d, 0x49, 0x45, 0x41,
+ 0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30,
+ 0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20,
+ 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17,
+ 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f,
+ 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
+ 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
+ 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05,
+ 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+/*
+ * Define our interface to the higher level audio driver.
+ */
+int aucc_open __P((void *, int));
+void aucc_close __P((void *));
+int aucc_set_out_sr __P((void *, u_long));
+int aucc_query_encoding __P((void *, struct audio_encoding *));
+int aucc_round_blocksize __P((void *, int));
+int aucc_set_out_port __P((void *, int));
+int aucc_get_out_port __P((void *));
+int aucc_set_in_port __P((void *, int));
+int aucc_get_in_port __P((void *));
+int aucc_commit_settings __P((void *));
+int aucc_start_output __P((void *, void *, int, void (*)(void *),
+ void *));
+int aucc_start_input __P((void *, void *, int, void (*)(void *),
+ void *));
+int aucc_halt_output __P((void *));
+int aucc_halt_input __P((void *));
+int aucc_cont_output __P((void *));
+int aucc_cont_input __P((void *));
+int aucc_getdev __P((void *, struct audio_device *));
+int aucc_set_port __P((void *, mixer_ctrl_t *));
+int aucc_get_port __P((void *, mixer_ctrl_t *));
+int aucc_query_devinfo __P((void *, mixer_devinfo_t *));
+void aucc_encode __P((int, int, int, u_char *, u_short **));
+int aucc_set_params __P((void *, int, int,
+ struct audio_params *, struct audio_params *));
+int aucc_get_props __P((void *));
+
+struct audio_hw_if sa_hw_if = {
+ aucc_open,
+ aucc_close,
+ NULL,
+ aucc_query_encoding,
+ aucc_set_params,
+ aucc_round_blocksize,
+ aucc_set_out_port,
+ aucc_get_out_port,
+ aucc_set_in_port,
+ aucc_get_in_port,
+ aucc_commit_settings,
+ NULL,
+ NULL,
+ aucc_start_output,
+ aucc_start_input,
+ aucc_halt_output,
+ aucc_halt_input,
+ aucc_cont_output,
+ aucc_cont_input,
+ NULL,
+ aucc_getdev,
+ NULL,
+ aucc_set_port,
+ aucc_get_port,
+ aucc_query_devinfo,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ aucc_get_props,
+};
+
+/* autoconfig routines */
+
+int
+auccmatch(pdp, match, aux)
+ struct device *pdp;
+ void *match;
+ void *aux;
+{
+ struct cfdata *cfp = match;
+
+ if (matchname((char *)aux, "aucc") &&
+#ifdef DRACO
+ !is_draco() &&
+#endif
+ (cfp->cf_unit == 0))
+ return (1);
+
+ return (0);
+}
+
+/*
+ * Audio chip found.
+ */
+void
+auccattach(parent, self, args)
+ struct device *parent, *self;
+ void *args;
+{
+ struct aucc_softc *sc = (struct aucc_softc *)self;
+ int i;
+
+ printf("\n");
+
+ if((i = init_aucc(sc)) != 0) {
+ printf("audio: no chipmem\n");
+ return;
+ }
+
+ audio_attach_mi(&sa_hw_if, 0, sc, &sc->sc_dev);
+}
+
+int
+init_aucc(sc)
+ struct aucc_softc *sc;
+{
+ int i, err=0;
+
+ /* init values per channel */
+ for (i = 0; i < 4; i++) {
+ sc->sc_channel[i].nd_freq = 8000;
+ sc->sc_channel[i].nd_per = freqtoper(8000);
+ sc->sc_channel[i].nd_busy = 0;
+ sc->sc_channel[i].nd_dma = alloc_chipmem(AUDIO_BUF_SIZE * 2);
+ if (sc->sc_channel[i].nd_dma == NULL)
+ err = 1;
+ sc->sc_channel[i].nd_dmalength = 0;
+ sc->sc_channel[i].nd_volume = 64;
+ sc->sc_channel[i].nd_intr = NULL;
+ sc->sc_channel[i].nd_intrdata = NULL;
+ sc->sc_channel[i].nd_doublebuf = 0;
+ DPRINTF(("dma buffer for channel %d is %p\n", i,
+ sc->sc_channel[i].nd_dma));
+
+ }
+
+ if (err) {
+ for(i = 0; i < 4; i++)
+ if (sc->sc_channel[i].nd_dma)
+ free_chipmem(sc->sc_channel[i].nd_dma);
+ }
+
+ sc->sc_channels = 1;
+ sc->sc_channelmask = 0xf;
+
+ /* clear interrupts and dma: */
+ custom.intena = AUCC_ALLINTF;
+ custom.dmacon = AUCC_ALLDMAF;
+
+ sc->sc_encoding = AUDIO_ENCODING_ULAW;
+
+ return (err);
+
+}
+
+int
+aucc_open(addr, flags)
+ void *addr;
+ int flags;
+{
+ struct aucc_softc *sc = addr;
+ int i;
+
+ DPRINTF(("sa_open: unit %p\n",sc));
+
+ if (sc->sc_open)
+ return (EBUSY);
+ sc->sc_open = 1;
+ for (i = 0; i < AUCC_MAXINT; i++) {
+ sc->sc_channel[i].nd_intr = NULL;
+ sc->sc_channel[i].nd_intrdata = NULL;
+ }
+ aucc = sc;
+ sc->sc_channelmask = 0xf;
+
+ DPRINTF(("saopen: ok -> sc=0x%p\n",sc));
+
+ return (0);
+}
+
+void
+aucc_close(addr)
+ void *addr;
+{
+ struct aucc_softc *sc = addr;
+
+ DPRINTF(("sa_close: sc=0x%p\n", sc));
+ /*
+ * halt i/o, clear open flag, and done.
+ */
+ aucc_halt_output(sc);
+ sc->sc_open = 0;
+
+ DPRINTF(("sa_close: closed.\n"));
+}
+
+int
+aucc_set_out_sr(addr, sr)
+ void *addr;
+ u_long sr;
+{
+ struct aucc_softc *sc = addr;
+ u_long per;
+ int i;
+
+ per = freqtoper(sr);
+ if (per > 0xffff)
+ return (EINVAL);
+ sr = pertofreq(per);
+
+ for (i = 0; i < 4; i++) {
+ sc->sc_channel[i].nd_freq = sr;
+ sc->sc_channel[i].nd_per = per;
+ }
+
+ return (0);
+}
+
+int
+aucc_query_encoding(addr, fp)
+ void *addr;
+ struct audio_encoding *fp;
+{
+ switch (fp->index) {
+ case 0:
+ strcpy(fp->name, AudioElinear);
+ fp->encoding = AUDIO_ENCODING_SLINEAR;
+ fp->precision = 8;
+ fp->flags = 0;
+ break;
+ case 1:
+ strcpy(fp->name, AudioEmulaw);
+ fp->encoding = AUDIO_ENCODING_ULAW;
+ fp->precision = 8;
+ fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
+ break;
+
+ case 2:
+ strcpy(fp->name, AudioEulinear);
+ fp->encoding = AUDIO_ENCODING_ULINEAR;
+ fp->precision = 8;
+ fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
+ break;
+
+ default:
+ return (EINVAL);
+ /*NOTREACHED*/
+ }
+ return (0);
+}
+
+int
+aucc_set_params(addr, setmode, usemode, p, r)
+ void *addr;
+ int setmode, usemode;
+ struct audio_params *p, *r;
+{
+ struct aucc_softc *sc = addr;
+
+#if 0
+ if (setmode & AUMODE_RECORD)
+ return (ENXIO);
+#endif
+
+#ifdef AUCCDEBUG
+ printf("aucc_set_params(setmode 0x%x, usemode 0x%x, enc %d, bits %d,"
+ "chn %d, sr %ld)\n",
+ setmode, usemode, p->encoding, p->precision, p->channels,
+ p->sample_rate);
+#endif
+
+ switch (p->encoding) {
+ case AUDIO_ENCODING_ULAW:
+ case AUDIO_ENCODING_SLINEAR:
+ case AUDIO_ENCODING_SLINEAR_BE:
+ case AUDIO_ENCODING_SLINEAR_LE:
+ case AUDIO_ENCODING_ULINEAR_BE:
+ case AUDIO_ENCODING_ULINEAR_LE:
+ break;
+
+ default:
+ return EINVAL;
+ /* NOTREADCHED */
+ }
+
+ if (p->precision != 8)
+ return (EINVAL);
+
+ if ((p->channels < 1) || (p->channels > 4))
+ return (EINVAL);
+
+ sc->sc_channels = p->channels;
+ sc->sc_encoding = p->encoding;
+
+ return (aucc_set_out_sr(addr, p->sample_rate));
+}
+
+int
+aucc_round_blocksize(addr, blk)
+ void *addr;
+ int blk;
+{
+ /* round up to even size */
+ return (blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk);
+}
+
+int
+aucc_set_out_port(addr, port) /* can set channels */
+ void *addr;
+ int port;
+{
+ struct aucc_softc *sc = addr;
+
+ /* port is mask for channels 0..3 */
+ if ((port < 0) || (port > 15))
+ return (EINVAL);
+
+ sc->sc_channelmask = port;
+
+ return (0);
+}
+
+int
+aucc_get_out_port(addr)
+ void *addr;
+{
+ struct aucc_softc *sc = addr;
+
+ return (sc->sc_channelmask);
+}
+
+int
+aucc_set_in_port(addr, port)
+ void *addr;
+ int port;
+{
+ return (EINVAL); /* no input possible */
+}
+
+int
+aucc_get_in_port(addr)
+ void *addr;
+{
+ return (0);
+}
+
+int
+aucc_commit_settings(addr)
+ void *addr;
+{
+ struct aucc_softc *sc = addr;
+ int i;
+
+ DPRINTF(("sa_commit.\n"));
+
+ for (i = 0; i < 4; i++) {
+ custom.aud[i].vol = sc->sc_channel[i].nd_volume;
+ custom.aud[i].per = sc->sc_channel[i].nd_per;
+ }
+
+ DPRINTF(("commit done\n"));
+
+ return (0);
+}
+
+static int masks[4] = {1, 3, 7, 15}; /* masks for n first channels */
+static int masks2[4] = {1, 2, 4, 8};
+
+int
+aucc_start_output(addr, p, cc, intr, arg)
+ void *addr;
+ void *p;
+ int cc;
+ void (*intr) __P((void *));
+ void *arg;
+{
+ struct aucc_softc *sc;
+ int mask;
+ int i, j, k;
+ u_short *dmap[4];
+ u_char *pp;
+
+ sc = addr;
+ mask = sc->sc_channelmask;
+
+ dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL;
+
+ DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
+
+ if (sc->sc_channels > 1)
+ mask &= masks[sc->sc_channels - 1];
+ /* we use first sc_channels channels */
+ if (mask == 0) /* active and used channels are disjoint */
+ return (EINVAL);
+
+ for (i = 0; i < 4; i++) { /* channels available ? */
+ if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy))
+ return (EBUSY); /* channel is busy */
+ if (channel[i].isaudio == -1)
+ return (EBUSY); /* system uses them */
+ }
+
+ /* enable interrupt on 1st channel */
+ for (i= j = 0; i < AUCC_MAXINT; i++) {
+ if (masks2[i] & mask) {
+ DPRINTF(("first channel is %d\n", i));
+ j = i;
+ sc->sc_channel[i].nd_intr = intr;
+ sc->sc_channel[i].nd_intrdata = arg;
+ break;
+ }
+ }
+
+ DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1],
+ dmap[2], dmap[3], mask));
+
+ /*
+ * disable ints, dma for channels, until all parameters set
+ * XXX dont disable DMA! custom.dmacon = mask;
+ */
+ custom.intreq = mask << INTB_AUD0;
+ custom.intena = mask << INTB_AUD0;
+
+ /* copy data to dma buffer */
+
+ pp = (u_char *)p;
+
+ if (sc->sc_channels == 1) {
+ dmap[0] = dmap[1] = dmap[2] = dmap[3] =
+ sc->sc_channel[j].nd_dma;
+ } else {
+ for (k = 0; k < 4; k++) {
+ if (masks2[k+j] & mask)
+ dmap[k] = sc->sc_channel[k+j].nd_dma;
+ }
+ }
+
+ sc->sc_channel[j].nd_doublebuf ^= 1;
+ if (sc->sc_channel[j].nd_doublebuf) {
+ dmap[0] += AUDIO_BUF_SIZE / sizeof (u_short);
+ dmap[1] += AUDIO_BUF_SIZE / sizeof (u_short);
+ dmap[2] += AUDIO_BUF_SIZE / sizeof (u_short);
+ dmap[3] += AUDIO_BUF_SIZE / sizeof (u_short);
+ }
+
+ aucc_encode(sc->sc_encoding, sc->sc_channels, cc, pp, dmap);
+
+ /* dma buffers: we use same buffer 4 all channels */
+ /* write dma location and length */
+ for (i = k = 0; i < 4; i++) {
+ if (masks2[i] & mask) {
+ DPRINTF(("turning channel %d on\n", i));
+ /* sc->sc_channel[i].nd_busy = 1;*/
+ channel[i].isaudio = 1;
+ channel[i].play_count = 1;
+ channel[i].handler = NULL;
+ custom.aud[i].per = sc->sc_channel[i].nd_per;
+ custom.aud[i].vol = sc->sc_channel[i].nd_volume;
+ custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]);
+ custom.aud[i].len = cc / (sc->sc_channels * 2);
+ sc->sc_channel[i].nd_mask = mask;
+ DPRINTF(("per is %d, vol is %d, len is %d\n",\
+ sc->sc_channel[i].nd_per,
+ sc->sc_channel[i].nd_volume, cc >> 1));
+
+ }
+ }
+
+ channel[j].handler = aucc_inthdl;
+
+ /* enable ints */
+ custom.intena = INTF_SETCLR|INTF_INTEN|(masks2[j] << INTB_AUD0);
+
+ DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0)));
+
+ /* enable dma */
+ custom.dmacon = DMAF_SETCLR|DMAF_MASTER|mask;
+
+ DPRINTF(("enabled dma, mask=0x%x\n",mask));
+
+ return (0);
+}
+
+/* ARGSUSED */
+int
+aucc_start_input(addr, p, cc, intr, arg)
+ void *addr;
+ void *p;
+ int cc;
+ void (*intr) __P((void *));
+ void *arg;
+{
+ return (ENXIO); /* no input */
+}
+
+int
+aucc_halt_output(addr)
+ void *addr;
+{
+ struct aucc_softc *sc = addr;
+ int i;
+
+ /* XXX only halt, if input is also halted ?? */
+ /* stop dma, etc */
+ custom.intena = AUCC_ALLINTF;
+ custom.dmacon = AUCC_ALLDMAF;
+ /* mark every busy unit idle */
+ for (i = 0; i < 4; i++) {
+ sc->sc_channel[i].nd_busy = sc->sc_channel[i].nd_mask = 0;
+ channel[i].isaudio = 0;
+ channel[i].play_count = 0;
+ }
+
+ return (0);
+}
+
+int
+aucc_halt_input(addr)
+ void *addr;
+{
+ /* no input */
+
+ return (ENXIO);
+}
+
+int
+aucc_cont_output(addr)
+ void *addr;
+{
+ DPRINTF(("aucc_cont_output: never called, what should it do?!\n"));
+ /* reenable DMA XXX */
+ return (ENXIO);
+}
+
+int
+aucc_cont_input(addr)
+ void *addr;
+{
+ DPRINTF(("aucc_cont_input: never called, what should it do?!\n"));
+ return (0);
+}
+
+int
+aucc_getdev(addr, retp)
+ void *addr;
+ struct audio_device *retp;
+{
+ *retp = aucc_device;
+ return (0);
+}
+
+int
+aucc_set_port(addr, cp)
+ void *addr;
+ mixer_ctrl_t *cp;
+{
+ struct aucc_softc *sc = addr;
+ int i,j;
+
+ DPRINTF(("aucc_set_port: port=%d", cp->dev));
+
+ switch (cp->type) {
+ case AUDIO_MIXER_SET:
+ if (cp->dev != AUCC_CHANNELS)
+ return (EINVAL);
+ i = cp->un.mask;
+ if ((i < 1) || (i > 15))
+ return (EINVAL);
+ sc->sc_channelmask = i;
+ break;
+
+ case AUDIO_MIXER_VALUE:
+ i = cp->un.value.num_channels;
+ if ((i < 1) || (i > 4))
+ return (EINVAL);
+
+#ifdef __XXXwhatsthat
+ if (cp->dev != AUCC_VOLUME)
+ return (EINVAL);
+#endif
+
+ /* set volume for channel 0..i-1 */
+ if (i > 1)
+ for (j = 0; j < i; j++)
+ sc->sc_channel[j].nd_volume =
+ cp->un.value.level[j] >> 2;
+ else if (sc->sc_channels > 1)
+ for (j = 0; j < sc->sc_channels; j++)
+ sc->sc_channel[j].nd_volume =
+ cp->un.value.level[0] >> 2;
+ else
+ for (j = 0; j < 4; j++)
+ sc->sc_channel[j].nd_volume =
+ cp->un.value.level[0] >> 2;
+ break;
+
+ default:
+ return (EINVAL);
+ break;
+ }
+ return (0);
+}
+
+int
+aucc_get_port(addr, cp)
+ void *addr;
+ mixer_ctrl_t *cp;
+{
+ struct aucc_softc *sc = addr;
+ int i, j;
+
+ DPRINTF(("aucc_get_port: port=%d", cp->dev));
+
+ switch (cp->type) {
+ case AUDIO_MIXER_SET:
+ if (cp->dev != AUCC_CHANNELS)
+ return (EINVAL);
+ cp->un.mask = sc->sc_channelmask;
+ break;
+
+ case AUDIO_MIXER_VALUE:
+ i = cp->un.value.num_channels;
+ if ((i < 1) || (i > 4))
+ return (EINVAL);
+
+ for (j = 0; j < i; j++)
+ cp->un.value.level[j] =
+ (sc->sc_channel[j].nd_volume << 2) +
+ (sc->sc_channel[j].nd_volume >> 4);
+ break;
+
+ default:
+ return (EINVAL);
+ }
+ return (0);
+}
+
+int
+aucc_get_props(addr)
+ void *addr;
+{
+ return 0;
+}
+
+int
+aucc_query_devinfo(addr, dip)
+ void *addr;
+ register mixer_devinfo_t *dip;
+{
+ int i;
+
+ switch (dip->index) {
+ case AUCC_CHANNELS:
+ dip->type = AUDIO_MIXER_SET;
+ dip->mixer_class = AUCC_OUTPUT_CLASS;
+ dip->prev = dip->next = AUDIO_MIXER_LAST;
+ strcpy(dip->label.name, AudioNspeaker);
+ for (i = 0; i < 16; i++) {
+ sprintf(dip->un.s.member[i].label.name,
+ "channelmask%d", i);
+ dip->un.s.member[i].mask = i;
+ }
+ dip->un.s.num_mem = 16;
+ break;
+
+ case AUCC_VOLUME:
+ dip->type = AUDIO_MIXER_VALUE;
+ dip->mixer_class = AUCC_OUTPUT_CLASS;
+ dip->prev = dip->next = AUDIO_MIXER_LAST;
+ strcpy(dip->label.name, AudioNspeaker);
+ dip->un.v.num_channels = 4;
+ strcpy(dip->un.v.units.name, AudioNvolume);
+ break;
+
+ case AUCC_OUTPUT_CLASS:
+ dip->type = AUDIO_MIXER_CLASS;
+ dip->mixer_class = AUCC_OUTPUT_CLASS;
+ dip->next = dip->prev = AUDIO_MIXER_LAST;
+ strcpy(dip->label.name, AudioCOutputs);
+ break;
+ default:
+ return (ENXIO);
+ /*NOTREACHED*/
+ }
+
+ DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
+
+ return (0);
+}
+
+
+/* audio int handler */
+void
+aucc_inthdl(ch)
+ int ch;
+{
+ int i;
+ int mask = aucc->sc_channel[ch].nd_mask;
+
+ /*
+ * For all channels in this maskgroup:
+ * disable dma, int
+ * mark idle
+ */
+ DPRINTF(("inthandler called, channel %d, mask 0x%x\n", ch, mask));
+
+ custom.intreq = mask << INTB_AUD0; /* clear request */
+
+ /*
+ * XXX: maybe we can leave ints and/or DMA on, if another sample has
+ * to be played?
+ */
+ custom.intena = mask << INTB_AUD0;
+
+ /*
+ * XXX custom.dmacon = mask; NO!!!
+ */
+ for (i = 0; i < 4; i++) {
+ if (masks2[i] && mask) {
+ DPRINTF(("marking channel %d idle\n", i));
+ aucc->sc_channel[i].nd_busy = 0;
+ aucc->sc_channel[i].nd_mask = 0;
+ channel[i].isaudio = channel[i].play_count = 0;
+ }
+ }
+
+ /* call handler */
+ if (aucc->sc_channel[ch].nd_intr) {
+ DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr));
+ (*(aucc->sc_channel[ch].nd_intr))(
+ aucc->sc_channel[ch].nd_intrdata);
+ } else
+ DPRINTF(("zero int handler\n"));
+ DPRINTF(("ints done\n"));
+}
+
+/* transform frequency to period, adjust bounds */
+u_int
+freqtoper(freq)
+ u_int freq;
+{
+ u_int per = eclockfreq * 5 / freq;
+
+ if (per < 124)
+ per = 124; /* must have at least 124 ticks between samples */
+
+ return per;
+}
+
+/* transform period to frequency */
+u_int
+pertofreq(per)
+ u_int per;
+{
+ u_int freq = eclockfreq * 5 / per;
+
+ return freq;
+}
+
+void
+aucc_encode(enc, channels, i, p, dmap)
+ int enc, channels, i;
+ u_char *p;
+ u_short **dmap;
+{
+ char *q, *r, *s, *t;
+ int off;
+ u_char *tab;
+#ifdef AUCCDEBUG
+ static int debctl = 6;
+#endif
+
+ off = 0;
+ tab = NULL;
+
+#ifdef AUCCDEBUG
+ if (--debctl >= 0)
+ printf("Enc: enc %d, chan %d, dmap %p %p %p %p\n",
+ enc, channels, dmap[0], dmap[1], dmap[2], dmap[3]);
+#endif
+
+ switch (enc) {
+ case AUDIO_ENCODING_ULAW:
+ tab = ulaw_to_lin;
+ break;
+ case AUDIO_ENCODING_ULINEAR_BE:
+ case AUDIO_ENCODING_ULINEAR_LE:
+ off = -128;
+ break;
+ case AUDIO_ENCODING_SLINEAR_BE:
+ case AUDIO_ENCODING_SLINEAR_LE:
+ break;
+ default:
+ return;
+ }
+
+ q = (char *)dmap[0];
+ r = (char *)dmap[1];
+ s = (char *)dmap[2];
+ t = (char *)dmap[3];
+
+ if (tab)
+ while (i) {
+ switch (channels) {
+ case 4: *t++ = tab[*p++];
+ case 3: *s++ = tab[*p++];
+ case 2: *r++ = tab[*p++];
+ case 1: *q++ = tab[*p++];
+ }
+ i -= channels;
+ }
+ else
+ while (i) {
+ switch (channels) {
+ case 4: *t++ = *p++ + off;
+ case 3: *s++ = *p++ + off;
+ case 2: *r++ = *p++ + off;
+ case 1: *q++ = *p++ + off;
+ }
+ i -= channels;
+ }
+
+}
+
+#endif /* NAUCC > 0 */
diff --git a/sys/arch/amiga/dev/auccvar.h b/sys/arch/amiga/dev/auccvar.h
new file mode 100644
index 00000000000..bb5e9d1ae17
--- /dev/null
+++ b/sys/arch/amiga/dev/auccvar.h
@@ -0,0 +1,65 @@
+/* $OpenBSD: auccvar.h,v 1.1 1997/09/18 13:39:43 niklas Exp $ */
+/* $NetBSD: auccvar.h,v 1.3 1997/07/04 21:00:18 is Exp $ */
+
+/*
+ * Copyright (c) 1991-1993 Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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 Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory 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.
+ */
+
+
+#ifndef _AUCCVAR_H_
+#define _AUCCVAR_H_
+
+#define AUDIO_BUF_SIZE 8192
+
+/* per channel data */
+typedef struct aucc_data {
+ u_int nd_freq; /* frequency */
+ u_int nd_per; /* period = clock/freq */
+ u_int nd_volume; /* 0..63 */
+ u_int nd_busy; /* 1, if channel is busy */
+ u_short *nd_dma; /* pointer to dma buffer */
+ u_int nd_dmalength; /* length of dma data */
+ int nd_mask; /* mask of active channels,
+ together with this one */
+ void (*nd_intr) __P((void *)); /* interrupt routine */
+ void *nd_intrdata; /* interrupt data */
+ int nd_doublebuf; /* double buffering */
+} aucc_data_t;
+
+/* mixer sets */
+#define AUCC_CHANNELS 0
+
+/* mixer values */
+#define AUCC_VOLUME 1
+#define AUCC_OUTPUT_CLASS 2
+
+#endif /* _AUCCVAR_H_ */
diff --git a/sys/arch/amiga/dev/clock.c b/sys/arch/amiga/dev/clock.c
index 6f8d075238d..2b2ffe33615 100644
--- a/sys/arch/amiga/dev/clock.c
+++ b/sys/arch/amiga/dev/clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock.c,v 1.9 1997/01/16 09:23:52 niklas Exp $ */
+/* $OpenBSD: clock.c,v 1.10 1997/09/18 13:39:43 niklas Exp $ */
/* $NetBSD: clock.c,v 1.25 1997/01/02 20:59:42 is Exp $ */
/*
@@ -100,8 +100,8 @@ struct clockframe hardclock_frame;
int clockmatch __P((struct device *, void *, void *));
void clockattach __P((struct device *, struct device *, void *));
-void calibrate_delay __P((struct device *));
void cpu_initclocks __P((void));
+void calibrate_delay __P((struct device *));
int clockintr __P((void *));
struct cfattach clock_ca = {
@@ -288,6 +288,20 @@ cpu_initclocks()
static struct isr isr;
#endif
+#ifdef DRACO
+ unsigned char dracorev;
+
+ dracorev = is_draco();
+ if (dracorev >= 4) {
+ draco_ioct->io_timerlo = CLK_INTERVAL & 0xFF;
+ draco_ioct->io_timerhi = CLK_INTERVAL >> 8;
+ draco_ioct->io_timerrst = 0; /* any value resets */
+ draco_ioct->io_status2 |= DRSTAT2_TMRINTENA;
+
+ return;
+ }
+#endif
+
/*
* enable interrupts for timer A
*/
@@ -670,18 +684,6 @@ profclock(pc, ps)
#endif
#endif
-/* this is a hook set by a clock driver for the configured realtime clock,
- returning plain current unix-time */
-long (*gettod) __P((void));
-int (*settod) __P((long));
-void *clockaddr;
-
-long a3gettod __P((void));
-long a2gettod __P((void));
-int a3settod __P((long));
-int a2settod __P((long));
-int rtcinit __P((void));
-
/*
* Initialize the time of day register, based on the time base which is, e.g.
* from a filesystem.
@@ -690,9 +692,9 @@ void
inittodr(base)
time_t base;
{
- u_long timbuf = base; /* assume no battery clock exists */
+ time_t timbuf = base; /* assume no battery clock exists */
- if (gettod == NULL && rtcinit() == 0)
+ if (gettod == NULL)
printf("WARNING: no battery clock\n");
else
timbuf = gettod();
@@ -712,319 +714,3 @@ resettodr()
if (settod && settod(time.tv_sec) == 0)
printf("Cannot set battery backed clock\n");
}
-
-int
-rtcinit()
-{
- clockaddr = (void *)ztwomap(0xdc0000);
-#ifdef DRACO
- if (is_draco()) {
- /* XXX to be done */
- gettod = (void *)0;
- settod = (void *)0;
- return 0;
- } else
-#endif
- if (is_a3000() || is_a4000()) {
- if (a3gettod() == 0)
- return(0);
- gettod = a3gettod;
- settod = a3settod;
- } else {
- if (a2gettod() == 0)
- return(0);
- gettod = a2gettod;
- settod = a2settod;
- }
- return(1);
-}
-
-static int month_days[12] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-long
-a3gettod()
-{
- struct rtclock3000 *rt;
- int i, year, month, day, wday, hour, min, sec;
- u_long tmp;
-
- rt = clockaddr;
-
- /* hold clock */
- rt->control1 = A3CONTROL1_HOLD_CLOCK;
-
- /* read it */
- sec = rt->second1 * 10 + rt->second2;
- min = rt->minute1 * 10 + rt->minute2;
- hour = rt->hour1 * 10 + rt->hour2;
- wday = rt->weekday;
- day = rt->day1 * 10 + rt->day2;
- month = rt->month1 * 10 + rt->month2;
- year = rt->year1 * 10 + rt->year2 + 1900;
-
- /* let it run again.. */
- rt->control1 = A3CONTROL1_FREE_CLOCK;
-
- if (range_test(hour, 0, 23))
- return(0);
- if (range_test(wday, 0, 6))
- return(0);
- if (range_test(day, 1, 31))
- return(0);
- if (range_test(month, 1, 12))
- return(0);
- if (range_test(year, STARTOFTIME, 2000))
- return(0);
-
- tmp = 0;
-
- for (i = STARTOFTIME; i < year; i++)
- tmp += days_in_year(i);
- if (leapyear(year) && month > FEBRUARY)
- tmp++;
-
- for (i = 1; i < month; i++)
- tmp += days_in_month(i);
-
- tmp += (day - 1);
- tmp = ((tmp * 24 + hour) * 60 + min) * 60 + sec;
-
- return(tmp);
-}
-
-int
-a3settod(tim)
- long tim;
-{
- register int i;
- register long hms, day;
- u_char sec1, sec2;
- u_char min1, min2;
- u_char hour1, hour2;
-/* u_char wday; */
- u_char day1, day2;
- u_char mon1, mon2;
- u_char year1, year2;
- struct rtclock3000 *rt;
-
- rt = clockaddr;
- /*
- * there seem to be problems with the bitfield addressing
- * currently used..
- */
-
- if (! rt)
- return 0;
-
- /* prepare values to be written to clock */
- day = tim / SECDAY;
- hms = tim % SECDAY;
-
- hour2 = hms / 3600;
- hour1 = hour2 / 10;
- hour2 %= 10;
-
- min2 = (hms % 3600) / 60;
- min1 = min2 / 10;
- min2 %= 10;
-
-
- sec2 = (hms % 3600) % 60;
- sec1 = sec2 / 10;
- sec2 %= 10;
-
- /* Number of years in days */
- for (i = STARTOFTIME - 1900; day >= days_in_year(i); i++)
- day -= days_in_year(i);
- year1 = i / 10;
- year2 = i % 10;
-
- /* Number of months in days left */
- if (leapyear(i))
- days_in_month(FEBRUARY) = 29;
- for (i = 1; day >= days_in_month(i); i++)
- day -= days_in_month(i);
- days_in_month(FEBRUARY) = 28;
-
- mon1 = i / 10;
- mon2 = i % 10;
-
- /* Days are what is left over (+1) from all that. */
- day ++;
- day1 = day / 10;
- day2 = day % 10;
-
- rt->control1 = A3CONTROL1_HOLD_CLOCK;
- rt->second1 = sec1;
- rt->second2 = sec2;
- rt->minute1 = min1;
- rt->minute2 = min2;
- rt->hour1 = hour1;
- rt->hour2 = hour2;
-/* rt->weekday = wday; */
- rt->day1 = day1;
- rt->day2 = day2;
- rt->month1 = mon1;
- rt->month2 = mon2;
- rt->year1 = year1;
- rt->year2 = year2;
- rt->control1 = A3CONTROL1_FREE_CLOCK;
-
- return 1;
-}
-
-long
-a2gettod()
-{
- struct rtclock2000 *rt;
- int i, year, month, day, hour, min, sec;
- u_long tmp;
-
- rt = clockaddr;
-
- /*
- * hold clock
- */
- rt->control1 |= A2CONTROL1_HOLD;
- i = 0x1000;
- while (rt->control1 & A2CONTROL1_BUSY && i--)
- ;
- if (rt->control1 & A2CONTROL1_BUSY)
- return (0); /* Give up and say it's not there */
-
- /*
- * read it
- */
- sec = rt->second1 * 10 + rt->second2;
- min = rt->minute1 * 10 + rt->minute2;
- hour = (rt->hour1 & 3) * 10 + rt->hour2;
- day = rt->day1 * 10 + rt->day2;
- month = rt->month1 * 10 + rt->month2;
- year = rt->year1 * 10 + rt->year2 + 1900;
-
- if ((rt->control3 & A2CONTROL3_24HMODE) == 0) {
- if ((rt->hour1 & A2HOUR1_PM) == 0 && hour == 12)
- hour = 0;
- else if ((rt->hour1 & A2HOUR1_PM) && hour != 12)
- hour += 12;
- }
-
- /*
- * release the clock
- */
- rt->control1 &= ~A2CONTROL1_HOLD;
-
- if (range_test(hour, 0, 23))
- return(0);
- if (range_test(day, 1, 31))
- return(0);
- if (range_test(month, 1, 12))
- return(0);
- if (range_test(year, STARTOFTIME, 2000))
- return(0);
-
- tmp = 0;
-
- for (i = STARTOFTIME; i < year; i++)
- tmp += days_in_year(i);
- if (leapyear(year) && month > FEBRUARY)
- tmp++;
-
- for (i = 1; i < month; i++)
- tmp += days_in_month(i);
-
- tmp += (day - 1);
- tmp = ((tmp * 24 + hour) * 60 + min) * 60 + sec;
-
- return(tmp);
-}
-
-/*
- * there is some question as to whether this works
- * I guess
- */
-int
-a2settod(tim)
- long tim;
-{
-
- int i;
- long hms, day;
- u_char sec1, sec2;
- u_char min1, min2;
- u_char hour1, hour2;
- u_char day1, day2;
- u_char mon1, mon2;
- u_char year1, year2;
- struct rtclock2000 *rt;
-
- rt = clockaddr;
- /*
- * there seem to be problems with the bitfield addressing
- * currently used..
- *
- * XXX Check out the above where we (hour1 & 3)
- */
- if (! rt)
- return 0;
-
- /* prepare values to be written to clock */
- day = tim / SECDAY;
- hms = tim % SECDAY;
-
- hour2 = hms / 3600;
- hour1 = hour2 / 10;
- hour2 %= 10;
-
- min2 = (hms % 3600) / 60;
- min1 = min2 / 10;
- min2 %= 10;
-
-
- sec2 = (hms % 3600) % 60;
- sec1 = sec2 / 10;
- sec2 %= 10;
-
- /* Number of years in days */
- for (i = STARTOFTIME - 1900; day >= days_in_year(i); i++)
- day -= days_in_year(i);
- year1 = i / 10;
- year2 = i % 10;
-
- /* Number of months in days left */
- if (leapyear(i))
- days_in_month(FEBRUARY) = 29;
- for (i = 1; day >= days_in_month(i); i++)
- day -= days_in_month(i);
- days_in_month(FEBRUARY) = 28;
-
- mon1 = i / 10;
- mon2 = i % 10;
-
- /* Days are what is left over (+1) from all that. */
- day ++;
- day1 = day / 10;
- day2 = day % 10;
-
- /*
- * XXXX spin wait as with reading???
- */
- rt->control1 |= A2CONTROL1_HOLD;
- rt->second1 = sec1;
- rt->second2 = sec2;
- rt->minute1 = min1;
- rt->minute2 = min2;
- rt->hour1 = hour1;
- rt->hour2 = hour2;
- rt->day1 = day1;
- rt->day2 = day2;
- rt->month1 = mon1;
- rt->month2 = mon2;
- rt->year1 = year1;
- rt->year2 = year2;
- rt->control2 &= ~A2CONTROL1_HOLD;
-
- return 1;
-}
diff --git a/sys/arch/amiga/dev/com_supio.c b/sys/arch/amiga/dev/com_supio.c
new file mode 100644
index 00000000000..bb2fb7563c8
--- /dev/null
+++ b/sys/arch/amiga/dev/com_supio.c
@@ -0,0 +1,266 @@
+/* $OpenBSD: com_supio.c,v 1.1 1997/09/18 13:39:44 niklas Exp $ */
+/* $NetBSD: com_supio.c,v 1.3 1997/08/27 20:41:30 is Exp $ */
+
+/*-
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * Charles M. Hannum. All rights reserved.
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * @(#)com.c 7.5 (Berkeley) 5/16/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <sys/tty.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/syslog.h>
+#include <sys/types.h>
+#include <sys/device.h>
+
+#include <machine/intr.h>
+#include <machine/bus.h>
+
+#include <dev/isa/isavar.h>
+#include <dev/ic/comreg.h>
+#include <dev/ic/comvar.h>
+
+#include <amiga/amiga/isr.h>
+#include <amiga/dev/supio.h>
+
+struct comsupio_softc {
+ struct com_softc sc_com;
+ struct isr sc_isr;
+};
+
+int com_supio_match __P((struct device *, void *, void *));
+void com_supio_attach __P((struct device *, struct device *, void *));
+void com_supio_cleanup __P((void *));
+
+static int comconsaddr;
+static bus_space_handle_t comconsioh;
+#if 0
+static int comconsattached;
+static bus_space_tag_t comconstag;
+static int comconsrate;
+static tcflag_t comconscflag;
+#endif
+
+struct cfattach com_supio_ca = {
+ sizeof(struct comsupio_softc), com_supio_match, com_supio_attach
+};
+
+/* Macros to clear/set/test flags. */
+#define SET(t, f) (t) |= (f)
+#define CLR(t, f) (t) &= ~(f)
+#define ISSET(t, f) ((t) & (f))
+
+int
+com_supio_match(parent, match, aux)
+ struct device *parent;
+ void *match;
+ void *aux;
+{
+ struct cfdata *cfp = match;
+ bus_space_tag_t iot;
+ int iobase;
+ int rv = 1;
+ struct supio_attach_args *supa = aux;
+
+ iot = supa->supio_iot;
+ iobase = supa->supio_iobase;
+
+ if (strcmp(supa->supio_name,"com") || (cfp->cf_unit > 1))
+ return 0;
+#if 0
+ /* if it's in use as console, it's there. */
+ if (iobase != comconsaddr || comconsattached) {
+ if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh)) {
+ return 0;
+ }
+ rv = comprobe1(iot, ioh, iobase);
+ bus_space_unmap(iot, ioh, COM_NPORTS);
+ }
+#endif
+ return (rv);
+}
+
+void
+com_supio_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+#ifdef __OpenBSD__
+ struct comsupio_softc *sc = (void *)self;
+ struct com_softc *csc = &sc->sc_com;
+ int iobase;
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+ struct supio_attach_args *supa = aux;
+
+ csc->sc_hwflags = 0;
+ csc->sc_swflags = 0;
+
+ iobase = csc->sc_iobase = supa->supio_iobase;
+ iot = csc->sc_iot = supa->supio_iot;
+ if (iobase != comconsaddr) {
+ if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh))
+ panic("comattach: io mapping failed");
+ } else
+ ioh = comconsioh;
+
+ csc->sc_iot = iot;
+ csc->sc_ioh = ioh;
+ csc->sc_iobase = iobase;
+
+ if (iobase == comconsaddr) {
+ comconsattached = 1;
+
+ /*
+ * Need to reset baud rate, etc. of next print so reset
+ * comconsinit. Also make sure console is always "hardwired".
+ */
+ delay(1000); /* wait for output to finish */
+ comconsinit = 0;
+ SET(csc->sc_hwflags, COM_HW_CONSOLE);
+ SET(csc->sc_swflags, COM_SW_SOFTCAR);
+ }
+
+
+ /* look for a NS 16550AF UART with FIFOs */
+ bus_space_write_1(iot, ioh, com_fifo,
+ FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
+ delay(100);
+ if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_FIFO_MASK) ==
+ IIR_FIFO_MASK)
+ if (ISSET(bus_space_read_1(iot, ioh, com_fifo),
+ FIFO_TRIGGER_14) == FIFO_TRIGGER_14) {
+ SET(csc->sc_hwflags, COM_HW_FIFO);
+ printf(": ns16550a, working fifo\n");
+ } else
+ printf(": ns16550, broken fifo\n");
+ else
+ printf(": ns8250 or ns16450, no fifo\n");
+ bus_space_write_1(iot, ioh, com_fifo, 0);
+
+ /* disable interrupts */
+ bus_space_write_1(iot, ioh, com_ier, 0);
+ bus_space_write_1(iot, ioh, com_mcr, 0);
+
+ if (amiga_ttyspl < (PSL_S|PSL_IPL5)) {
+ printf("%s: raising amiga_ttyspl from 0x%x to 0x%x\n",
+ csc->sc_dev.dv_xname, amiga_ttyspl, PSL_S|PSL_IPL5);
+ amiga_ttyspl = PSL_S|PSL_IPL5;
+ }
+ sc->sc_isr.isr_intr = comintr;
+ sc->sc_isr.isr_arg = csc;
+ sc->sc_isr.isr_ipl = 5;
+ add_isr(&sc->sc_isr);
+
+#ifdef KGDB
+ if (kgdb_dev == makedev(commajor, unit)) {
+ if (ISSET(csc->sc_hwflags, COM_HW_CONSOLE))
+ kgdb_dev = -1; /* can't debug over console port */
+ else {
+ cominit(iot, ioh, kgdb_rate);
+ if (kgdb_debug_init) {
+ /*
+ * Print prefix of device name,
+ * let kgdb_connect print the rest.
+ */
+ printf("%s: ", csc->sc_dev.dv_xname);
+ kgdb_connect(1);
+ } else
+ printf("%s: kgdb enabled\n",
+ csc->sc_dev.dv_xname);
+ }
+ }
+#endif
+
+ /* XXX maybe move up some? */
+ if (ISSET(csc->sc_hwflags, COM_HW_CONSOLE))
+ printf("%s: console\n", csc->sc_dev.dv_xname);
+#else /* __OpenBSD__ */
+ struct comsupio_softc *sc = (void *)self;
+ struct com_softc *csc = &sc->sc_com;
+ int iobase;
+ bus_space_tag_t iot;
+ struct supio_attach_args *supa = aux;
+
+ /*
+ * We're living on a superio chip.
+ */
+ iobase = csc->sc_iobase = supa->supio_iobase;
+ iot = csc->sc_iot = supa->supio_iot;
+ if (iobase != comconsaddr) {
+ if (bus_space_map(iot, iobase, COM_NPORTS, 0, &csc->sc_ioh))
+ panic("comattach: io mapping failed");
+ } else
+ csc->sc_ioh = comconsioh;
+
+ printf(" port 0x%x", iobase);
+ com_attach_subr(csc);
+
+ if (amiga_ttyspl < (PSL_S|PSL_IPL5)) {
+ printf("%s: raising amiga_ttyspl from 0x%x to 0x%x\n",
+ csc->sc_dev.dv_xname, amiga_ttyspl, PSL_S|PSL_IPL5);
+ amiga_ttyspl = PSL_S|PSL_IPL5;
+ }
+ sc->sc_isr.isr_intr = comintr;
+ sc->sc_isr.isr_arg = csc;
+ sc->sc_isr.isr_ipl = 5;
+ add_isr(&sc->sc_isr);
+
+ /*
+ * Shutdown hook for buggy BIOSs that don't recognize the UART
+ * without a disabled FIFO.
+ */
+ if (shutdownhook_establish(com_supio_cleanup, csc) == NULL)
+ panic("comsupio: could not establish shutdown hook");
+#endif /* __OpenBSD__ */
+}
+
+void
+com_supio_cleanup(arg)
+ void *arg;
+{
+ struct com_softc *sc = arg;
+
+ if (ISSET(sc->sc_hwflags, COM_HW_FIFO))
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_fifo, 0);
+}
diff --git a/sys/arch/amiga/dev/drbbc.c b/sys/arch/amiga/dev/drbbc.c
new file mode 100644
index 00000000000..da4f0612cce
--- /dev/null
+++ b/sys/arch/amiga/dev/drbbc.c
@@ -0,0 +1,205 @@
+/* $OpenBSD: drbbc.c,v 1.1 1997/09/18 13:39:44 niklas Exp $ */
+/* $NetBSD: drbbc.c,v 1.1 1997/07/17 23:29:30 is Exp $ */
+
+/*
+ * Copyright (c) 1997 Ignatios Souvatzis.
+ * All rights reserved.
+ *
+ * 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 Ignatios Souvatzis
+ * for the NetBSD project.
+ * 4. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#if 0
+#include <machine/psl.h>
+#endif
+#include <machine/cpu.h>
+#include <amiga/amiga/device.h>
+#include <amiga/amiga/custom.h>
+#include <amiga/amiga/cia.h>
+#include <amiga/amiga/drcustom.h>
+#include <amiga/dev/rtc.h>
+
+#include <dev/ic/ds.h>
+
+int draco_ds_read_bit __P((void *));
+void draco_ds_write_bit __P((void *, int));
+void draco_ds_reset __P((void *));
+
+void drbbc_attach __P((struct device *, struct device *, void *));
+int drbbc_match __P((struct device *, void *, void *));
+
+time_t dracogettod __P((void));
+#ifdef __NOTYET__
+int dracosettod __P((time_t));
+#endif
+
+struct drbbc_softc {
+ struct device sc_dev;
+ struct ds_handle sc_dsh;
+};
+
+struct cfattach drbbc_ca = {
+ sizeof(struct drbbc_softc),
+ drbbc_match,
+ drbbc_attach
+};
+
+struct cfdriver drbbc_cd = {
+ NULL, "drbbc", DV_DULL, NULL, 0
+};
+
+struct drbbc_softc *drbbc_sc;
+
+int
+drbbc_match(pdp, match, auxp)
+ struct device *pdp;
+ void *match;
+ void *auxp;
+{
+ struct cfdata *cfp = match;
+
+ if (is_draco() && matchname(auxp, "drbbc") && (cfp->cf_unit == 0))
+ return (1);
+ else
+ return (0);
+}
+
+void
+drbbc_attach(pdp, dp, auxp)
+ struct device *pdp, *dp;
+ void *auxp;
+{
+ int i;
+ struct drbbc_softc *sc;
+ u_int8_t rombuf[8];
+
+ sc = (struct drbbc_softc *)dp;
+
+ sc->sc_dsh.ds_read_bit = draco_ds_read_bit;
+ sc->sc_dsh.ds_write_bit = draco_ds_write_bit;
+ sc->sc_dsh.ds_reset = draco_ds_reset;
+ sc->sc_dsh.ds_hw_handle = (void *)(DRCCADDR + DRIOCTLPG*NBPG);
+
+ sc->sc_dsh.ds_reset(sc->sc_dsh.ds_hw_handle);
+
+ ds_write_byte(&sc->sc_dsh, DS_ROM_READ);
+ for (i=0; i<8; ++i)
+ rombuf[i] = ds_read_byte(&sc->sc_dsh);
+
+ hostid = (rombuf[3] << 24) + (rombuf[2] << 16) +
+ (rombuf[1] << 8) + rombuf[7];
+
+ printf(": ROM %02x %02x%02x%02x%02x%02x%02x %02x (DraCo sernum %ld)\n",
+ rombuf[7], rombuf[6], rombuf[5], rombuf[4],
+ rombuf[3], rombuf[2], rombuf[1], rombuf[0],
+ hostid);
+
+ gettod = dracogettod;
+ settod = (void *)0;
+ drbbc_sc = sc;
+}
+
+int
+draco_ds_read_bit(p)
+ void *p;
+{
+ struct drioct *draco_ioct;
+
+ draco_ioct = p;
+
+ while (draco_ioct->io_status & DRSTAT_CLKBUSY);
+
+ draco_ioct->io_clockw1 = 0;
+
+ while (draco_ioct->io_status & DRSTAT_CLKBUSY);
+
+ return (draco_ioct->io_status & DRSTAT_CLKDAT);
+}
+
+void
+draco_ds_write_bit(p, b)
+ void *p;
+ int b;
+{
+ struct drioct *draco_ioct;
+
+ draco_ioct = p;
+
+ while (draco_ioct->io_status & DRSTAT_CLKBUSY);
+
+ if (b)
+ draco_ioct->io_clockw1 = 0;
+ else
+ draco_ioct->io_clockw0 = 0;
+}
+
+void
+draco_ds_reset(p)
+ void *p;
+{
+ struct drioct *draco_ioct;
+
+ draco_ioct = p;
+
+ draco_ioct->io_clockrst = 0;
+}
+
+/*
+ * We could return 1/256 of a seconds, but would need to change the interface
+ */
+
+time_t
+dracogettod()
+{
+ u_int32_t clkbuf;
+
+ drbbc_sc->sc_dsh.ds_reset(drbbc_sc->sc_dsh.ds_hw_handle);
+
+ ds_write_byte(&drbbc_sc->sc_dsh, DS_ROM_SKIP);
+
+ ds_write_byte(&drbbc_sc->sc_dsh, DS_MEM_READ_MEMORY);
+ /* address of full seconds: */
+ ds_write_byte(&drbbc_sc->sc_dsh, 0x03);
+ ds_write_byte(&drbbc_sc->sc_dsh, 0x02);
+
+ clkbuf = ds_read_byte(&drbbc_sc->sc_dsh)
+ + (ds_read_byte(&drbbc_sc->sc_dsh)<<8)
+ + (ds_read_byte(&drbbc_sc->sc_dsh)<<16)
+ + (ds_read_byte(&drbbc_sc->sc_dsh)<<24);
+
+ /* BSD time is wr. 1.1.1970; AmigaOS time wrt. 1.1.1978 */
+
+ clkbuf += (8*365 + 2) * 86400;
+
+ return ((time_t)clkbuf);
+}
diff --git a/sys/arch/amiga/dev/drcom.c b/sys/arch/amiga/dev/drcom.c
deleted file mode 100644
index c4ed739439f..00000000000
--- a/sys/arch/amiga/dev/drcom.c
+++ /dev/null
@@ -1,1285 +0,0 @@
-/* $OpenBSD: drcom.c,v 1.1 1997/01/16 09:23:55 niklas Exp $ */
-/* $NetBSD: drcom.c,v 1.2 1996/12/23 09:09:56 veego Exp $ */
-
-/*-
- * Copyright (c) 1993, 1994, 1995, 1996
- * Charles M. Hannum. All rights reserved.
- * Copyright (c) 1991 The Regents of the University of California.
- * All rights reserved.
- *
- * 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.
- *
- * @(#)drcom.c 7.5 (Berkeley) 5/16/91
- */
-
-/*
- * COM driver, based on HP dca driver
- * uses National Semiconductor NS16450/NS16550AF UART
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/ioctl.h>
-#include <sys/select.h>
-#include <sys/tty.h>
-#include <sys/ttycom.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-#include <sys/file.h>
-#include <sys/uio.h>
-#include <sys/kernel.h>
-#include <sys/syslog.h>
-#include <sys/types.h>
-#include <sys/device.h>
-
-#include <sys/conf.h>
-#include <machine/conf.h>
-
-#include <machine/cpu.h>
-
-#include <amiga/amiga/device.h>
-#include <amiga/amiga/drcustom.h>
-#include <amiga/amiga/isr.h>
-
-#include <amiga/dev/drisavar.h>
-#include <amiga/dev/drcomreg.h>
-#include <amiga/dev/drcomvar.h>
-
-#include <dev/ic/ns16550reg.h>
-
-#define com_lcr com_cfcr
-
-#include "drcom.h"
-
-
-#define COM_IBUFSIZE (2 * 512)
-#define COM_IHIGHWATER ((3 * COM_IBUFSIZE) / 4)
-
-struct drcom_softc {
- struct device sc_dev;
- void *sc_ih;
- struct tty *sc_tty;
-
- int sc_overflows;
- int sc_floods;
- int sc_failures;
- int sc_errors;
-
- int sc_halt;
-
- int sc_iobase;
-
- bus_chipset_tag_t sc_bc;
- bus_io_handle_t sc_ioh;
-
- struct isr sc_isr;
-
- u_char sc_hwflags;
-#define COM_HW_NOIEN 0x01
-#define COM_HW_FIFO 0x02
-#define COM_HW_HAYESP 0x04
-#define COM_HW_CONSOLE 0x40
- u_char sc_swflags;
-#define COM_SW_SOFTCAR 0x01
-#define COM_SW_CLOCAL 0x02
-#define COM_SW_CRTSCTS 0x04
-#define COM_SW_MDMBUF 0x08
- u_char sc_msr, sc_mcr, sc_lcr, sc_ier;
- u_char sc_dtr;
-
- u_char *sc_ibuf, *sc_ibufp, *sc_ibufhigh, *sc_ibufend;
- u_char sc_ibufs[2][COM_IBUFSIZE];
-
- u_char sc_iir;
-};
-
-void drcomdiag __P((void *));
-int drcomspeed __P((long));
-int drcomparam __P((struct tty *, struct termios *));
-void drcomstart __P((struct tty *));
-void drcomsoft __P((void *));
-int drcomintr __P((void *));
-
-struct consdev;
-void drcomcnprobe __P((struct consdev *));
-void drcomcninit __P((struct consdev *));
-int drcomcngetc __P((dev_t));
-void drcomcnputc __P((dev_t, int));
-void drcomcnpollc __P((dev_t, int));
-
-static u_char tiocm_xxx2mcr __P((int));
-
-/*
- * XXX the following two cfattach structs should be different, and possibly
- * XXX elsewhere.
- */
-int drcommatch __P((struct device *, struct cfdata *, void *));
-void drcomattach __P((struct device *, struct device *, void *));
-
-struct cfattach drcom_ca = {
- sizeof(struct drcom_softc), drcommatch, drcomattach
-};
-
-struct cfdriver drcom_cd = {
- NULL, "drcom", DV_TTY
-};
-
-void drcominit __P((bus_chipset_tag_t, bus_io_handle_t, int));
-
-#ifdef COMCONSOLE
-int drcomdefaultrate = CONSPEED; /* XXX why set default? */
-#else
-int drcomdefaultrate = 1200 /*TTYDEF_SPEED*/;
-#endif
-int drcomconsaddr;
-int drcomconsinit;
-int drcomconsattached;
-bus_chipset_tag_t drcomconsbc;
-bus_io_handle_t drcomconsioh;
-tcflag_t drcomconscflag = TTYDEF_CFLAG;
-
-int drcommajor;
-int drcomsopen = 0;
-int drcomevents = 0;
-
-#ifdef KGDB
-#include <machine/remote-sl.h>
-extern int kgdb_dev;
-extern int kgdb_rate;
-extern int kgdb_debug_init;
-#endif
-
-#define COMUNIT(x) (minor(x))
-
-/* Macros to clear/set/test flags. */
-#define SET(t, f) (t) |= (f)
-#define CLR(t, f) (t) &= ~(f)
-#define ISSET(t, f) ((t) & (f))
-
-int
-drcomspeed(speed)
- long speed;
-{
-#define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
-
- int x, err;
-
- if (speed == 0)
- return 0;
- if (speed < 0)
- return -1;
- x = divrnd((COM_FREQ / 16), speed);
- if (x <= 0)
- return -1;
- err = divrnd((COM_FREQ / 16) * 1000, speed * x) - 1000;
- if (err < 0)
- err = -err;
- if (err > COM_TOLERANCE)
- return -1;
- return x;
-
-#undef divrnd(n, q)
-}
-
-int
-drcommatch(parent, cfp, auxp)
- struct device *parent;
- struct cfdata *cfp;
- void *auxp;
-{
-
- /* Exactly two of us live on the DraCo */
-
- if (is_draco() && matchname(auxp, "drcom") &&
- (cfp->cf_unit >= 0) && (cfp->cf_unit < 2))
- return 1;
-
- return 0;
-}
-
-void
-drcomattach(parent, self, auxp)
- struct device *parent, *self;
- void *auxp;
-{
- struct drcom_softc *sc = (void *)self;
- int iobase;
- bus_chipset_tag_t bc;
- bus_io_handle_t ioh;
-
- /*
- * XXX should be broken out into functions for isa attach and
- * XXX for drcommulti attach, with a helper function that contains
- * XXX most of the interesting stuff.
- */
- sc->sc_hwflags = 0;
- sc->sc_swflags = 0;
-
- bc = 0;
- iobase = self->dv_cfdata->cf_unit ? 0x2f8 : 0x3f8;
-
- if (iobase != drcomconsaddr) {
- (void)bus_io_map(bc, iobase, COM_NPORTS, &ioh);
- } else {
- ioh = drcomconsioh;
- }
-
- sc->sc_bc = bc;
- sc->sc_ioh = ioh;
- sc->sc_iobase = iobase;
-
- if (iobase == drcomconsaddr) {
- drcomconsattached = 1;
-
- /*
- * Need to reset baud rate, etc. of next print so reset
- * drcomconsinit. Also make sure console is always "hardwired".
- */
- delay(1000); /* wait for output to finish */
- drcomconsinit = 0;
- SET(sc->sc_hwflags, COM_HW_CONSOLE);
- SET(sc->sc_swflags, COM_SW_SOFTCAR);
- }
-
-
- /* look for a NS 16550AF UART with FIFOs */
- bus_io_write_1(bc, ioh, com_fifo,
- FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
- delay(100);
- if (ISSET(bus_io_read_1(bc, ioh, com_iir), IIR_FIFO_MASK) == IIR_FIFO_MASK)
- if (ISSET(bus_io_read_1(bc, ioh, com_fifo), FIFO_TRIGGER_14) == FIFO_TRIGGER_14) {
- SET(sc->sc_hwflags, COM_HW_FIFO);
- printf(": ns16550a, working fifo\n");
- } else
- printf(": ns16550, broken fifo\n");
- else
- printf(": ns8250 or ns16450, no fifo\n");
- bus_io_write_1(bc, ioh, com_fifo, 0);
-#ifdef COM_HAYESP
- }
-#endif
-
- if (amiga_ttyspl < (PSL_S|PSL_IPL5)) {
- printf("%s: raising amiga_ttyspl from 0x%x to 0x%x\n",
- sc->sc_dev.dv_xname, amiga_ttyspl, PSL_S|PSL_IPL5);
- amiga_ttyspl = PSL_S|PSL_IPL5;
- }
-
- /* disable interrupts */
- (void)bus_io_read_1(bc, ioh, com_iir);
- bus_io_write_1(bc, ioh, com_ier, 0);
- bus_io_write_1(bc, ioh, com_mcr, 0);
-
- sc->sc_isr.isr_intr = drcomintr;
- sc->sc_isr.isr_arg = sc;
- sc->sc_isr.isr_ipl = 5;
- add_isr(&sc->sc_isr);
-
-#ifdef KGDB
- if (kgdb_dev == makedev(drcommajor, unit)) {
- if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
- kgdb_dev = -1; /* can't debug over console port */
- else {
- drcominit(bc, ioh, kgdb_rate);
- if (kgdb_debug_init) {
- /*
- * Print prefix of device name,
- * let kgdb_connect print the rest.
- */
- printf("%s: ", sc->sc_dev.dv_xname);
- kgdb_connect(1);
- } else
- printf("%s: kgdb enabled\n",
- sc->sc_dev.dv_xname);
- }
- }
-#endif
-
- /* XXX maybe move up some? */
- if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
- printf("%s: console\n", sc->sc_dev.dv_xname);
-}
-
-int
-drcomopen(dev, flag, mode, p)
- dev_t dev;
- int flag, mode;
- struct proc *p;
-{
- int unit = COMUNIT(dev);
- struct drcom_softc *sc;
- bus_chipset_tag_t bc;
- bus_io_handle_t ioh;
- struct tty *tp;
- int s;
- int error = 0;
-
- if (unit >= drcom_cd.cd_ndevs)
- return ENXIO;
- sc = drcom_cd.cd_devs[unit];
- if (!sc)
- return ENXIO;
-
- if (!sc->sc_tty) {
- tp = sc->sc_tty = ttymalloc();
- tty_attach(tp);
- } else
- tp = sc->sc_tty;
-
- tp->t_oproc = drcomstart;
- tp->t_param = drcomparam;
- tp->t_dev = dev;
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- SET(tp->t_state, TS_WOPEN);
- ttychars(tp);
- tp->t_iflag = TTYDEF_IFLAG;
- tp->t_oflag = TTYDEF_OFLAG;
- if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
- tp->t_cflag = drcomconscflag;
- else
- tp->t_cflag = TTYDEF_CFLAG;
- if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
- SET(tp->t_cflag, CLOCAL);
- if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
- SET(tp->t_cflag, CRTSCTS);
- if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
- SET(tp->t_cflag, MDMBUF);
- tp->t_lflag = TTYDEF_LFLAG;
- tp->t_ispeed = tp->t_ospeed = drcomdefaultrate;
-
- s = spltty();
-
- drcomparam(tp, &tp->t_termios);
- ttsetwater(tp);
-
- if (drcomsopen++ == 0)
- timeout(drcomsoft, NULL, 1);
-
- sc->sc_ibufp = sc->sc_ibuf = sc->sc_ibufs[0];
- sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER;
- sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;
-
- bc = sc->sc_bc;
- ioh = sc->sc_ioh;
-#ifdef COM_HAYESP
- /* Setup the ESP board */
- if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
- bus_io_handle_t hayespioh = sc->sc_hayespioh;
-
- bus_io_write_1(bc, ioh, com_fifo,
- FIFO_DMA_MODE|FIFO_ENABLE|
- FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_8);
-
- /* Set 16550 drcompatibility mode */
- bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_SETMODE);
- bus_io_write_1(bc, hayespioh, HAYESP_CMD2,
- HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
- HAYESP_MODE_SCALE);
-
- /* Set RTS/CTS flow control */
- bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_SETFLOWTYPE);
- bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_FLOW_RTS);
- bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_FLOW_CTS);
-
- /* Set flow control levels */
- bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_SETRXFLOW);
- bus_io_write_1(bc, hayespioh, HAYESP_CMD2,
- HAYESP_HIBYTE(HAYESP_RXHIWMARK));
- bus_io_write_1(bc, hayespioh, HAYESP_CMD2,
- HAYESP_LOBYTE(HAYESP_RXHIWMARK));
- bus_io_write_1(bc, hayespioh, HAYESP_CMD2,
- HAYESP_HIBYTE(HAYESP_RXLOWMARK));
- bus_io_write_1(bc, hayespioh, HAYESP_CMD2,
- HAYESP_LOBYTE(HAYESP_RXLOWMARK));
- } else
-#endif
- if (ISSET(sc->sc_hwflags, COM_HW_FIFO))
- /* Set the FIFO threshold based on the receive speed. */
- bus_io_write_1(bc, ioh, com_fifo,
- FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST |
- (tp->t_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8));
- /* flush any pending I/O */
- while (ISSET(bus_io_read_1(bc, ioh, com_lsr), LSR_RXRDY))
- (void) bus_io_read_1(bc, ioh, com_data);
- /* you turn me on, baby */
- sc->sc_mcr = MCR_DTR | MCR_RTS;
- if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
- SET(sc->sc_mcr, MCR_IENABLE);
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
- bus_io_write_1(bc, ioh, com_ier, sc->sc_ier);
-
- sc->sc_msr = bus_io_read_1(bc, ioh, com_msr);
- if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) ||
- ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF))
- SET(tp->t_state, TS_CARR_ON);
- else
- CLR(tp->t_state, TS_CARR_ON);
- } else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0)
- return EBUSY;
- else
- s = spltty();
-
- /* wait for carrier if necessary */
- if (!ISSET(flag, O_NONBLOCK))
- while (!ISSET(tp->t_cflag, CLOCAL) &&
- !ISSET(tp->t_state, TS_CARR_ON)) {
- SET(tp->t_state, TS_WOPEN);
- error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
- ttopen, 0);
- if (error) {
- /* XXX should turn off chip if we're the
- only waiter */
- splx(s);
- return error;
- }
- }
- splx(s);
-
- return (*linesw[tp->t_line].l_open)(dev, tp);
-}
-
-int
-drcomclose(dev, flag, mode, p)
- dev_t dev;
- int flag, mode;
- struct proc *p;
-{
- int unit = COMUNIT(dev);
- struct drcom_softc *sc = drcom_cd.cd_devs[unit];
- struct tty *tp = sc->sc_tty;
- bus_chipset_tag_t bc = sc->sc_bc;
- bus_io_handle_t ioh = sc->sc_ioh;
- int s;
-
- /* XXX This is for cons.c. */
- if (!ISSET(tp->t_state, TS_ISOPEN))
- return 0;
-
- (*linesw[tp->t_line].l_close)(tp, flag);
- s = spltty();
- CLR(sc->sc_lcr, LCR_SBREAK);
- bus_io_write_1(bc, ioh, com_lcr, sc->sc_lcr);
- bus_io_write_1(bc, ioh, com_ier, 0);
- if (ISSET(tp->t_cflag, HUPCL) &&
- !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
- /* XXX perhaps only clear DTR */
- bus_io_write_1(bc, ioh, com_mcr, 0);
- bus_io_write_1(bc, ioh, com_fifo, FIFO_RCV_RST | FIFO_XMT_RST);
- }
- CLR(tp->t_state, TS_BUSY | TS_FLUSH);
- if (--drcomsopen == 0)
- untimeout(drcomsoft, NULL);
- splx(s);
- ttyclose(tp);
-#ifdef notyet /* XXXX */
- if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
- ttyfree(tp);
- sc->sc_tty = 0;
- }
-#endif
- return 0;
-}
-
-int
-drcomread(dev, uio, flag)
- dev_t dev;
- struct uio *uio;
- int flag;
-{
- struct drcom_softc *sc = drcom_cd.cd_devs[COMUNIT(dev)];
- struct tty *tp = sc->sc_tty;
-
- return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
-}
-
-int
-drcomwrite(dev, uio, flag)
- dev_t dev;
- struct uio *uio;
- int flag;
-{
- struct drcom_softc *sc = drcom_cd.cd_devs[COMUNIT(dev)];
- struct tty *tp = sc->sc_tty;
-
- return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
-}
-
-struct tty *
-drcomtty(dev)
- dev_t dev;
-{
- struct drcom_softc *sc = drcom_cd.cd_devs[COMUNIT(dev)];
- struct tty *tp = sc->sc_tty;
-
- return (tp);
-}
-
-static u_char
-tiocm_xxx2mcr(data)
- int data;
-{
- u_char m = 0;
-
- if (ISSET(data, TIOCM_DTR))
- SET(m, MCR_DTR);
- if (ISSET(data, TIOCM_RTS))
- SET(m, MCR_RTS);
- return m;
-}
-
-int
-drcomioctl(dev, cmd, data, flag, p)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flag;
- struct proc *p;
-{
- int unit = COMUNIT(dev);
- struct drcom_softc *sc = drcom_cd.cd_devs[unit];
- struct tty *tp = sc->sc_tty;
- bus_chipset_tag_t bc = sc->sc_bc;
- bus_io_handle_t ioh = sc->sc_ioh;
- int error;
-
- error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
- if (error >= 0)
- return error;
-
- error = ttioctl(tp, cmd, data, flag, p);
- if (error >= 0)
- return error;
-
- switch (cmd) {
- case TIOCSBRK:
- SET(sc->sc_lcr, LCR_SBREAK);
- bus_io_write_1(bc, ioh, com_lcr, sc->sc_lcr);
- break;
- case TIOCCBRK:
- CLR(sc->sc_lcr, LCR_SBREAK);
- bus_io_write_1(bc, ioh, com_lcr, sc->sc_lcr);
- break;
- case TIOCSDTR:
- SET(sc->sc_mcr, sc->sc_dtr);
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- break;
- case TIOCCDTR:
- CLR(sc->sc_mcr, sc->sc_dtr);
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- break;
- case TIOCMSET:
- CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
- case TIOCMBIS:
- SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- break;
- case TIOCMBIC:
- CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- break;
- case TIOCMGET: {
- u_char m;
- int bits = 0;
-
- m = sc->sc_mcr;
- if (ISSET(m, MCR_DTR))
- SET(bits, TIOCM_DTR);
- if (ISSET(m, MCR_RTS))
- SET(bits, TIOCM_RTS);
- m = sc->sc_msr;
- if (ISSET(m, MSR_DCD))
- SET(bits, TIOCM_CD);
- if (ISSET(m, MSR_CTS))
- SET(bits, TIOCM_CTS);
- if (ISSET(m, MSR_DSR))
- SET(bits, TIOCM_DSR);
- if (ISSET(m, MSR_RI | MSR_TERI))
- SET(bits, TIOCM_RI);
- if (bus_io_read_1(bc, ioh, com_ier))
- SET(bits, TIOCM_LE);
- *(int *)data = bits;
- break;
- }
- case TIOCGFLAGS: {
- int driverbits, userbits = 0;
-
- driverbits = sc->sc_swflags;
- if (ISSET(driverbits, COM_SW_SOFTCAR))
- SET(userbits, TIOCFLAG_SOFTCAR);
- if (ISSET(driverbits, COM_SW_CLOCAL))
- SET(userbits, TIOCFLAG_CLOCAL);
- if (ISSET(driverbits, COM_SW_CRTSCTS))
- SET(userbits, TIOCFLAG_CRTSCTS);
- if (ISSET(driverbits, COM_SW_MDMBUF))
- SET(userbits, TIOCFLAG_MDMBUF);
-
- *(int *)data = userbits;
- break;
- }
- case TIOCSFLAGS: {
- int userbits, driverbits = 0;
-
- error = suser(p->p_ucred, &p->p_acflag);
- if (error != 0) {
- return(EPERM);
- }
-
- userbits = *(int *)data;
- if (ISSET(userbits, TIOCFLAG_SOFTCAR) ||
- ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
- SET(driverbits, COM_SW_SOFTCAR);
- if (ISSET(userbits, TIOCFLAG_CLOCAL))
- SET(driverbits, COM_SW_CLOCAL);
- if (ISSET(userbits, TIOCFLAG_CRTSCTS))
- SET(driverbits, COM_SW_CRTSCTS);
- if (ISSET(userbits, TIOCFLAG_MDMBUF))
- SET(driverbits, COM_SW_MDMBUF);
-
- sc->sc_swflags = driverbits;
- break;
- }
- default:
- return ENOTTY;
- }
-
- return 0;
-}
-
-int
-drcomparam(tp, t)
- struct tty *tp;
- struct termios *t;
-{
- struct drcom_softc *sc = drcom_cd.cd_devs[COMUNIT(tp->t_dev)];
- bus_chipset_tag_t bc = sc->sc_bc;
- bus_io_handle_t ioh = sc->sc_ioh;
- int ospeed = drcomspeed(t->c_ospeed);
- u_char lcr;
- tcflag_t oldcflag;
- int s;
-
- /* check requested parameters */
- if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
- return EINVAL;
-
- lcr = ISSET(sc->sc_lcr, LCR_SBREAK);
-
- switch (ISSET(t->c_cflag, CSIZE)) {
- case CS5:
- SET(lcr, LCR_5BITS);
- break;
- case CS6:
- SET(lcr, LCR_6BITS);
- break;
- case CS7:
- SET(lcr, LCR_7BITS);
- break;
- case CS8:
- SET(lcr, LCR_8BITS);
- break;
- }
- if (ISSET(t->c_cflag, PARENB)) {
- SET(lcr, LCR_PENAB);
- if (!ISSET(t->c_cflag, PARODD))
- SET(lcr, LCR_PEVEN);
- }
- if (ISSET(t->c_cflag, CSTOPB))
- SET(lcr, LCR_STOPB);
-
- sc->sc_lcr = lcr;
-
- s = spltty();
-
- if (ospeed == 0) {
- CLR(sc->sc_mcr, MCR_DTR);
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- }
-
- /*
- * Set the FIFO threshold based on the receive speed, if we are
- * changing it.
- */
-#if 1
- if (tp->t_ispeed != t->c_ispeed) {
-#else
- if (1) {
-#endif
- if (ospeed != 0) {
- /*
- * Make sure the transmit FIFO is empty before
- * proceeding. If we don't do this, some revisions
- * of the UART will hang. Interestingly enough,
- * even if we do this will the last character is
- * still being pushed out, they don't hang. This
- * seems good enough.
- */
- while (ISSET(tp->t_state, TS_BUSY)) {
- int error;
-
- ++sc->sc_halt;
- error = ttysleep(tp, &tp->t_outq,
- TTOPRI | PCATCH, "drcomprm", 0);
- --sc->sc_halt;
- if (error) {
- splx(s);
- drcomstart(tp);
- return (error);
- }
- }
-
- bus_io_write_1(bc, ioh, com_lcr, lcr | LCR_DLAB);
- bus_io_write_1(bc, ioh, com_dlbl, ospeed);
- bus_io_write_1(bc, ioh, com_dlbh, ospeed >> 8);
- bus_io_write_1(bc, ioh, com_lcr, lcr);
- SET(sc->sc_mcr, MCR_DTR);
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- } else
- bus_io_write_1(bc, ioh, com_lcr, lcr);
-
- if (!ISSET(sc->sc_hwflags, COM_HW_HAYESP) &&
- ISSET(sc->sc_hwflags, COM_HW_FIFO))
- bus_io_write_1(bc, ioh, com_fifo,
- FIFO_ENABLE |
- (t->c_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8));
- } else
- bus_io_write_1(bc, ioh, com_lcr, lcr);
-
- /* When not using CRTSCTS, RTS follows DTR. */
- if (!ISSET(t->c_cflag, CRTSCTS)) {
- if (ISSET(sc->sc_mcr, MCR_DTR)) {
- if (!ISSET(sc->sc_mcr, MCR_RTS)) {
- SET(sc->sc_mcr, MCR_RTS);
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- }
- } else {
- if (ISSET(sc->sc_mcr, MCR_RTS)) {
- CLR(sc->sc_mcr, MCR_RTS);
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- }
- }
- sc->sc_dtr = MCR_DTR | MCR_RTS;
- } else
- sc->sc_dtr = MCR_DTR;
-
- /* and copy to tty */
- tp->t_ispeed = t->c_ispeed;
- tp->t_ospeed = t->c_ospeed;
- oldcflag = tp->t_cflag;
- tp->t_cflag = t->c_cflag;
-
- /*
- * If DCD is off and MDMBUF is changed, ask the tty layer if we should
- * stop the device.
- */
- if (!ISSET(sc->sc_msr, MSR_DCD) &&
- !ISSET(sc->sc_swflags, COM_SW_SOFTCAR) &&
- ISSET(oldcflag, MDMBUF) != ISSET(tp->t_cflag, MDMBUF) &&
- (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
- CLR(sc->sc_mcr, sc->sc_dtr);
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- }
-
- /* Just to be sure... */
- splx(s);
- drcomstart(tp);
- return 0;
-}
-
-void
-drcomstart(tp)
- struct tty *tp;
-{
- struct drcom_softc *sc = drcom_cd.cd_devs[COMUNIT(tp->t_dev)];
- bus_chipset_tag_t bc = sc->sc_bc;
- bus_io_handle_t ioh = sc->sc_ioh;
- int s;
-
- s = spltty();
- if (ISSET(tp->t_state, TS_BUSY))
- goto out;
- if (ISSET(tp->t_state, TS_TIMEOUT | TS_TTSTOP) ||
- sc->sc_halt > 0)
- goto stopped;
- if (ISSET(tp->t_cflag, CRTSCTS) && !ISSET(sc->sc_msr, MSR_CTS))
- goto stopped;
- if (tp->t_outq.c_cc <= tp->t_lowat) {
- if (ISSET(tp->t_state, TS_ASLEEP)) {
- CLR(tp->t_state, TS_ASLEEP);
- wakeup(&tp->t_outq);
- }
- if (tp->t_outq.c_cc == 0)
- goto stopped;
- selwakeup(&tp->t_wsel);
- }
- SET(tp->t_state, TS_BUSY);
-
- if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
- SET(sc->sc_ier, IER_ETXRDY);
- bus_io_write_1(bc, ioh, com_ier, sc->sc_ier);
- }
-#ifdef COM_HAYESP
- if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
- u_char buffer[1024], *cp = buffer;
- int n = q_to_b(&tp->t_outq, cp, sizeof buffer);
- do
- bus_io_write_1(bc, ioh, com_data, *cp++);
- while (--n);
- }
- else
-#endif
- if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
- u_char buffer[16], *cp = buffer;
- int n = q_to_b(&tp->t_outq, cp, sizeof buffer);
- do {
- bus_io_write_1(bc, ioh, com_data, *cp++);
- } while (--n);
- } else
- bus_io_write_1(bc, ioh, com_data, getc(&tp->t_outq));
-out:
- splx(s);
- return;
-stopped:
- if (ISSET(sc->sc_ier, IER_ETXRDY)) {
- CLR(sc->sc_ier, IER_ETXRDY);
- bus_io_write_1(bc, ioh, com_ier, sc->sc_ier);
- }
- splx(s);
-}
-
-/*
- * Stop output on a line.
- */
-void
-drcomstop(tp, flag)
- struct tty *tp;
- int flag;
-{
- int s;
-
- s = spltty();
- if (ISSET(tp->t_state, TS_BUSY))
- if (!ISSET(tp->t_state, TS_TTSTOP))
- SET(tp->t_state, TS_FLUSH);
- splx(s);
-}
-
-void
-drcomdiag(arg)
- void *arg;
-{
- struct drcom_softc *sc = arg;
- int overflows, floods, failures;
- int s;
-
- s = spltty();
- sc->sc_errors = 0;
- overflows = sc->sc_overflows;
- sc->sc_overflows = 0;
- floods = sc->sc_floods;
- sc->sc_floods = 0;
- failures = sc->sc_failures;
- sc->sc_failures = 0;
- splx(s);
-
- log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf overflow%s, %d uart failure%s\n",
- sc->sc_dev.dv_xname,
- overflows, overflows == 1 ? "" : "s",
- floods, floods == 1 ? "" : "s",
- failures, failures == 1 ? "" : "s");
-}
-
-void
-drcomsoft(arg)
- void *arg;
-{
- int unit;
- struct drcom_softc *sc;
- struct tty *tp;
- register u_char *ibufp;
- u_char *ibufend;
- register int c;
- int s;
- static int lsrmap[8] = {
- 0, TTY_PE,
- TTY_FE, TTY_PE|TTY_FE,
- TTY_FE, TTY_PE|TTY_FE,
- TTY_FE, TTY_PE|TTY_FE
- };
-
- s = spltty();
- if (drcomevents == 0) {
- splx(s);
- goto out;
- }
- drcomevents = 0;
- splx(s);
-
- for (unit = 0; unit < drcom_cd.cd_ndevs; unit++) {
- sc = drcom_cd.cd_devs[unit];
- if (sc == 0 || sc->sc_ibufp == sc->sc_ibuf)
- continue;
-
- tp = sc->sc_tty;
-
- s = spltty();
-
- ibufp = sc->sc_ibuf;
- ibufend = sc->sc_ibufp;
-
- if (ibufp == ibufend) {
- splx(s);
- continue;
- }
-
- sc->sc_ibufp = sc->sc_ibuf = (ibufp == sc->sc_ibufs[0]) ?
- sc->sc_ibufs[1] : sc->sc_ibufs[0];
- sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER;
- sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;
-
- if (tp == 0 || !ISSET(tp->t_state, TS_ISOPEN)) {
- splx(s);
- continue;
- }
-
- if (ISSET(tp->t_cflag, CRTSCTS) &&
- !ISSET(sc->sc_mcr, MCR_RTS)) {
- /* XXX */
- SET(sc->sc_mcr, MCR_RTS);
- bus_io_write_1(sc->sc_bc, sc->sc_ioh, com_mcr,
- sc->sc_mcr);
- }
-
- splx(s);
-
- while (ibufp < ibufend) {
- c = *ibufp++;
- if (*ibufp & LSR_OE) {
- sc->sc_overflows++;
- if (sc->sc_errors++ == 0)
- timeout(drcomdiag, sc, 60 * hz);
- }
- /* This is ugly, but fast. */
- c |= lsrmap[(*ibufp++ & (LSR_BI|LSR_FE|LSR_PE)) >> 2];
- (*linesw[tp->t_line].l_rint)(c, tp);
- }
- }
-
-out:
- timeout(drcomsoft, NULL, 1);
-}
-
-int
-drcomintr(arg)
- void *arg;
-{
- struct drcom_softc *sc = arg;
- bus_chipset_tag_t bc = sc->sc_bc;
- bus_io_handle_t ioh = sc->sc_ioh;
- struct tty *tp;
- u_char iir, lsr, data, msr, delta;
-#ifdef COM_DEBUG
- int n;
- struct {
- u_char iir, lsr, msr;
- } iter[32];
-#endif
-
-#ifdef COM_DEBUG
- n = 0;
- iter[n].iir =
-#endif
- iir = bus_io_read_1(bc, ioh, com_iir);
- if (ISSET(iir, IIR_NOPEND))
- return (0);
-
- tp = sc->sc_tty;
-
- for (;;) {
-#ifdef COM_DEBUG
- iter[n].lsr =
-#endif
- lsr = bus_io_read_1(bc, ioh, com_lsr);
-
- if (ISSET(lsr, LSR_RXRDY)) {
- register u_char *p = sc->sc_ibufp;
-
- drcomevents = 1;
- do {
- data = bus_io_read_1(bc, ioh, com_data);
- if (ISSET(lsr, LSR_BI)) {
-#ifdef notdef
- printf("break %02x %02x %02x %02x\n",
- sc->sc_msr, sc->sc_mcr, sc->sc_lcr,
- sc->sc_dtr);
-#endif
-#ifdef DDB
- if (ISSET(sc->sc_hwflags,
- COM_HW_CONSOLE)) {
- Debugger();
- goto next;
- }
-#endif
- }
- if (p >= sc->sc_ibufend) {
- sc->sc_floods++;
- if (sc->sc_errors++ == 0)
- timeout(drcomdiag, sc, 60 * hz);
- } else {
- *p++ = data;
- *p++ = lsr;
- if (p == sc->sc_ibufhigh &&
- ISSET(tp->t_cflag, CRTSCTS)) {
- /* XXX */
- CLR(sc->sc_mcr, MCR_RTS);
- bus_io_write_1(bc, ioh,
- com_mcr, sc->sc_mcr);
- }
- }
-#ifdef DDB
- next:
-#endif
-#ifdef COM_DEBUG
- if (++n >= 32)
- goto ohfudge;
- iter[n].lsr =
-#endif
- lsr = bus_io_read_1(bc, ioh, com_lsr);
- } while (ISSET(lsr, LSR_RXRDY));
-
- sc->sc_ibufp = p;
- } else {
-#ifdef COM_DEBUG
- if (ISSET(lsr, LSR_BI|LSR_FE|LSR_PE|LSR_OE))
- printf("weird lsr %02x\n", lsr);
-#endif
- if ((iir & IIR_IMASK) == IIR_RXRDY) {
- sc->sc_failures++;
- if (sc->sc_errors++ == 0)
- timeout(drcomdiag, sc, 60 * hz);
- bus_io_write_1(bc, ioh, com_ier, 0);
- delay(10);
- bus_io_write_1(bc, ioh, com_ier, sc->sc_ier);
- iir = IIR_NOPEND;
- continue;
- }
- }
-
-#ifdef COM_DEBUG
- iter[n].msr =
-#endif
- msr = bus_io_read_1(bc, ioh, com_msr);
-
- if (msr != sc->sc_msr) {
- delta = msr ^ sc->sc_msr;
- sc->sc_msr = msr;
- if (ISSET(delta, MSR_DCD) &&
- !ISSET(sc->sc_swflags, COM_SW_SOFTCAR) &&
- (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)) == 0) {
- CLR(sc->sc_mcr, sc->sc_dtr);
- bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr);
- }
- if (ISSET(delta & msr, MSR_CTS) &&
- ISSET(tp->t_cflag, CRTSCTS)) {
- /* the line is up and we want to do rts/cts flow control */
- (*linesw[tp->t_line].l_start)(tp);
- }
- }
-
- if (ISSET(lsr, LSR_TXRDY) && ISSET(tp->t_state, TS_BUSY)) {
- CLR(tp->t_state, TS_BUSY | TS_FLUSH);
- if (sc->sc_halt > 0)
- wakeup(&tp->t_outq);
- (*linesw[tp->t_line].l_start)(tp);
- }
-
-#ifdef COM_DEBUG
- if (++n >= 32)
- goto ohfudge;
- iter[n].iir =
-#endif
- iir = bus_io_read_1(bc, ioh, com_iir);
- if (ISSET(iir, IIR_NOPEND))
- return (1);
- }
-
-#ifdef COM_DEBUG
-ohfudge:
- printf("drcomintr: too many iterations");
- for (n = 0; n < 32; n++) {
- if ((n % 4) == 0)
- printf("\ndrcomintr: iter[%02d]", n);
- printf(" %02x %02x %02x", iter[n].iir, iter[n].lsr, iter[n].msr);
- }
- printf("\n");
- printf("drcomintr: msr %02x mcr %02x lcr %02x ier %02x\n",
- sc->sc_msr, sc->sc_mcr, sc->sc_lcr, sc->sc_ier);
- printf("drcomintr: state %08x cc %d\n", sc->sc_tty->t_state,
- sc->sc_tty->t_outq.c_cc);
- return (1);
-#endif
-}
-
-/*
- * Following are all routines needed for COM to act as console
- */
-#include <dev/cons.h>
-
-void
-drcomcnprobe(cp)
- struct consdev *cp;
-{
- /* XXX NEEDS TO BE FIXED XXX */
- bus_chipset_tag_t bc = 0;
- bus_io_handle_t ioh;
- int found;
-
- if (bus_io_map(bc, CONADDR, COM_NPORTS, &ioh)) {
- cp->cn_pri = CN_DEAD;
- return;
- }
- found = 1/*drcomprobe1(bc, ioh, CONADDR)*/;
- bus_io_unmap(bc, ioh, COM_NPORTS);
- if (!found) {
- cp->cn_pri = CN_DEAD;
- return;
- }
-
- /* locate the major number */
- for (drcommajor = 0; drcommajor < nchrdev; drcommajor++)
- if (cdevsw[drcommajor].d_open == drcomopen)
- break;
-
- /* initialize required fields */
- cp->cn_dev = makedev(drcommajor, CONUNIT);
-#ifdef COMCONSOLE
- cp->cn_pri = CN_REMOTE; /* Force a serial port console */
-#else
- cp->cn_pri = CN_NORMAL;
-#endif
-}
-
-void
-drcomcninit(cp)
- struct consdev *cp;
-{
-
-#if 0
- XXX NEEDS TO BE FIXED XXX
- drcomconsbc = ???;
-#endif
- if (bus_io_map(drcomconsbc, CONADDR, COM_NPORTS, &drcomconsioh))
- panic("drcomcninit: mapping failed");
-
- drcominit(drcomconsbc, drcomconsioh, drcomdefaultrate);
- drcomconsaddr = CONADDR;
- drcomconsinit = 0;
-}
-
-void
-drcominit(bc, ioh, rate)
- bus_chipset_tag_t bc;
- bus_io_handle_t ioh;
- int rate;
-{
- int s = splhigh();
- u_char stat;
-
- bus_io_write_1(bc, ioh, com_lcr, LCR_DLAB);
- rate = drcomspeed(drcomdefaultrate);
- bus_io_write_1(bc, ioh, com_dlbl, rate);
- bus_io_write_1(bc, ioh, com_dlbh, rate >> 8);
- bus_io_write_1(bc, ioh, com_lcr, LCR_8BITS);
- bus_io_write_1(bc, ioh, com_ier, IER_ERXRDY | IER_ETXRDY);
- bus_io_write_1(bc, ioh, com_fifo,
- FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
- bus_io_write_1(bc, ioh, com_mcr, MCR_DTR | MCR_RTS);
- DELAY(100);
- stat = bus_io_read_1(bc, ioh, com_iir);
- splx(s);
-}
-
-int
-drcomcngetc(dev)
- dev_t dev;
-{
- int s = splhigh();
- bus_chipset_tag_t bc = drcomconsbc;
- bus_io_handle_t ioh = drcomconsioh;
- u_char stat, c;
-
- while (!ISSET(stat = bus_io_read_1(bc, ioh, com_lsr), LSR_RXRDY))
- ;
- c = bus_io_read_1(bc, ioh, com_data);
- stat = bus_io_read_1(bc, ioh, com_iir);
- splx(s);
- return c;
-}
-
-/*
- * Console kernel output character routine.
- */
-void
-drcomcnputc(dev, c)
- dev_t dev;
- int c;
-{
- int s = splhigh();
- bus_chipset_tag_t bc = drcomconsbc;
- bus_io_handle_t ioh = drcomconsioh;
- u_char stat;
- register int timo;
-
-#ifdef KGDB
- if (dev != kgdb_dev)
-#endif
- if (drcomconsinit == 0) {
- drcominit(bc, ioh, drcomdefaultrate);
- drcomconsinit = 1;
- }
- /* wait for any pending transmission to finish */
- timo = 50000;
- while (!ISSET(stat = bus_io_read_1(bc, ioh, com_lsr), LSR_TXRDY) && --timo)
- ;
- bus_io_write_1(bc, ioh, com_data, c);
- /* wait for this transmission to drcomplete */
- timo = 1500000;
- while (!ISSET(stat = bus_io_read_1(bc, ioh, com_lsr), LSR_TXRDY) && --timo)
- ;
- /* clear any interrupts generated by this transmission */
- stat = bus_io_read_1(bc, ioh, com_iir);
- splx(s);
-}
-
-void
-drcomcnpollc(dev, on)
- dev_t dev;
- int on;
-{
-
-}
diff --git a/sys/arch/amiga/dev/drisavar.h b/sys/arch/amiga/dev/drisavar.h
deleted file mode 100644
index 04e102ea750..00000000000
--- a/sys/arch/amiga/dev/drisavar.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* $OpenBSD: drisavar.h,v 1.1 1997/01/16 09:23:57 niklas Exp $ */
-/* $NetBSD: drisavar.h,v 1.1 1996/11/30 00:43:05 is Exp $ */
-
-#ifndef DRISAVAR_H
-
-#ifndef DRCCADDR
-#include <amiga/amiga/drcustom.h>
-#endif
-
-#define i2drabs(io) (DRCCADDR + NBPG * DRSUPIOPG + (io << 2) + 1)
-#define i2drrel(ioh,io) (ioh + (io << 2))
-
-#define bus_chipset_tag_t void *
-#define bus_io_handle_t vm_offset_t
-
-#define bus_io_map(bc, iob, n, iohp) (*(iohp) = i2drabs(iob), 0)
-#define bus_io_unmap(bc, ioh, n) do {(void)bc; (void)ioh; (void)n;} while (0)
-
-#define bus_io_read_1(bt, ioh, off) ((void)bc, *(u_int8_t *)i2drrel(ioh, off))
-#define bus_io_write_1(bt, ioh, off, val) do {\
- (void)bt; *(u_int8_t *)i2drrel(ioh, off) = (val); } while (0)
-
-#endif
diff --git a/sys/arch/amiga/dev/drsupio.c b/sys/arch/amiga/dev/drsupio.c
new file mode 100644
index 00000000000..779fa48a741
--- /dev/null
+++ b/sys/arch/amiga/dev/drsupio.c
@@ -0,0 +1,172 @@
+/* $OpenBSD: drsupio.c,v 1.1 1997/09/18 13:39:47 niklas Exp $ */
+/* $NetBSD: drsupio.c,v 1.1 1997/08/27 19:32:53 is Exp $ */
+
+/*
+ * Copyright (c) 1997 Ignatios Souvatzis
+ * All rights reserved.
+ *
+ * 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 Ignatios Souvatzis
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+/*
+ * DraCo multi-io chip bus space stuff
+ */
+
+#include <sys/types.h>
+
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/param.h>
+
+#include <machine/bus.h>
+#include <machine/conf.h>
+
+#include <amiga/include/cpu.h>
+
+#include <amiga/amiga/device.h>
+#include <amiga/amiga/drcustom.h>
+
+#include <amiga/dev/supio.h>
+
+
+struct drsupio_softc {
+ struct device sc_dev;
+ struct amiga_bus_space sc_bst;
+};
+
+int drsupiomatch __P((struct device *, void *, void *));
+void drsupioattach __P((struct device *, struct device *, void *));
+int drsupprint __P((void *auxp, const char *));
+
+struct cfattach drsupio_ca = {
+ sizeof(struct drsupio_softc), drsupiomatch, drsupioattach
+};
+
+struct cfdriver drsupio_cd = {
+ NULL, "drsupio", DV_DULL
+};
+
+int drsupio_map __P((bus_space_tag_t, bus_addr_t, bus_size_t, int,
+ bus_space_handle_t *));
+int drsupio_unmap __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
+
+int
+drsupiomatch(parent, match, auxp)
+ struct device *parent;
+ void *match;
+ void *auxp;
+{
+ struct cfdata *cfp = match;
+
+ /* Exactly one of us lives on the DraCo */
+
+ if (is_draco() && matchname(auxp, "drsupio") && (cfp->cf_unit == 0))
+ return 1;
+
+ return 0;
+}
+
+struct drsupio_devs {
+ char *name;
+ int off;
+} drsupiodevs[] = {
+ { "com", 0x3f8 },
+ { "com", 0x2f8 },
+ { "lpt", 0x378 },
+ { "fdc", 0x3f0 },
+ /* WD port? */
+ { 0 }
+};
+
+int
+drsupio_map(bst, addr, sz, cacheable, handle)
+ bus_space_tag_t bst;
+ bus_addr_t addr;
+ bus_size_t sz;
+ int cacheable;
+ bus_space_handle_t *handle;
+{
+ *handle = DRCCADDR + NBPG * DRSUPIOPG + 1 + (addr << bst->bs_shift);
+ return (0);
+}
+
+int
+drsupio_unmap(bst, handle, sz)
+ bus_space_tag_t bst;
+ bus_space_handle_t handle;
+ bus_size_t sz;
+{
+ return (0);
+}
+
+void
+drsupioattach(parent, self, auxp)
+ struct device *parent, *self;
+ void *auxp;
+{
+ struct drsupio_softc *drsc;
+ struct drsupio_devs *drsd;
+ struct supio_attach_args supa;
+
+ drsc = (struct drsupio_softc *)self;
+ drsd = drsupiodevs;
+
+ if (parent)
+ printf("\n");
+
+ drsc->sc_bst.bs_map = drsupio_map;
+ drsc->sc_bst.bs_unmap = drsupio_unmap;
+ drsc->sc_bst.bs_swapped = 0;
+ drsc->sc_bst.bs_shift = 2;
+
+ supa.supio_iot = &drsc->sc_bst;
+
+ while (drsd->name) {
+ supa.supio_name = drsd->name;
+ supa.supio_iobase = drsd->off;
+ config_found(self, &supa, drsupprint); /* XXX */
+ ++drsd;
+ }
+}
+
+int
+drsupprint(auxp, pnp)
+ void *auxp;
+ const char *pnp;
+{
+ struct supio_attach_args *supa;
+ supa = auxp;
+
+ if (pnp == NULL)
+ return(QUIET);
+
+ printf("%s at %s port 0x%02x",
+ supa->supio_name, pnp, supa->supio_iobase);
+
+ return(UNCONF);
+}
diff --git a/sys/arch/amiga/dev/grf_cl.c b/sys/arch/amiga/dev/grf_cl.c
index 03c48dd9b1e..48d73c07712 100644
--- a/sys/arch/amiga/dev/grf_cl.c
+++ b/sys/arch/amiga/dev/grf_cl.c
@@ -1,7 +1,8 @@
-/* $OpenBSD: grf_cl.c,v 1.9 1997/01/16 09:24:10 niklas Exp $ */
-/* $NetBSD: grf_cl.c,v 1.18 1996/12/23 09:10:04 veego Exp $ */
+/* $OpenBSD: grf_cl.c,v 1.10 1997/09/18 13:39:47 niklas Exp $ */
+/* $NetBSD: grf_cl.c,v 1.20 1997/07/29 17:46:24 veego Exp $ */
/*
+ * Copyright (c) 1997 Klaus Burkert
* Copyright (c) 1995 Ezra Story
* Copyright (c) 1995 Kari Mettinen
* Copyright (c) 1994 Markus Wild
@@ -51,6 +52,10 @@
* Extensively hacked and rewritten by Ezra Story (Ezy) 01/95
* Picasso/040 patches (wee!) by crest 01/96
*
+ * PicassoIV support bz Klaus "crest" Burkert.
+ * Fixed interlace and doublescan, added clockdoubling and
+ * HiColor&TrueColor suuport by crest 01/97
+ *
* Thanks to Village Tronic Marketing Gmbh for providing me with
* a Picasso-II board.
* Thanks for Integrated Electronics Oy Ab for providing me with
@@ -78,44 +83,45 @@
#include <amiga/dev/grf_clreg.h>
#include <amiga/dev/zbusvar.h>
-int cl_mondefok __P((struct grfvideo_mode *));
-void cl_boardinit __P((struct grf_softc *));
-static void cl_CompFQ __P((u_int, u_char *, u_char *));
-int cl_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
-int cl_setvmode __P((struct grf_softc *, unsigned int));
-int cl_toggle __P((struct grf_softc *, unsigned short));
-int cl_getcmap __P((struct grf_softc *, struct grf_colormap *));
-int cl_putcmap __P((struct grf_softc *, struct grf_colormap *));
+int cl_mondefok __P((struct grfvideo_mode *));
+void cl_boardinit __P((struct grf_softc *));
+void cl_CompFQ __P((u_int, u_char *, u_char *, u_char *));
+int cl_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
+int cl_setvmode __P((struct grf_softc *, unsigned int));
+int cl_toggle __P((struct grf_softc *, unsigned short));
+int cl_getcmap __P((struct grf_softc *, struct grf_colormap *));
+int cl_putcmap __P((struct grf_softc *, struct grf_colormap *));
#ifndef CL5426CONSOLE
-void cl_off __P((struct grf_softc *));
+void cl_off __P((struct grf_softc *));
#endif
-void cl_inittextmode __P((struct grf_softc *));
-int cl_ioctl __P((register struct grf_softc *, u_long, void *));
-int cl_getmousepos __P((struct grf_softc *, struct grf_position *));
-int cl_setmousepos __P((struct grf_softc *, struct grf_position *));
-static int cl_setspriteinfo __P((struct grf_softc *, struct grf_spriteinfo *));
-int cl_getspriteinfo __P((struct grf_softc *, struct grf_spriteinfo *));
-static int cl_getspritemax __P((struct grf_softc *, struct grf_position *));
-int cl_blank __P((struct grf_softc *, int *));
-int cl_setmonitor __P((struct grf_softc *, struct grfvideo_mode *));
-void cl_writesprpos __P((volatile char *, short, short));
-void writeshifted __P((volatile char *, char, char));
-
-static void RegWakeup __P((volatile caddr_t));
-static void RegOnpass __P((volatile caddr_t));
-static void RegOffpass __P((volatile caddr_t));
-
-void grfclattach __P((struct device *, struct device *, void *));
-int grfclprint __P((void *, const char *));
-int grfclmatch __P((struct device *, void *, void *));
-void cl_memset __P((unsigned char *, unsigned char, int));
+void cl_inittextmode __P((struct grf_softc *));
+int cl_ioctl __P((register struct grf_softc *, u_long, void *));
+int cl_getmousepos __P((struct grf_softc *, struct grf_position *));
+int cl_setmousepos __P((struct grf_softc *, struct grf_position *));
+int cl_setspriteinfo __P((struct grf_softc *, struct grf_spriteinfo *));
+int cl_getspriteinfo __P((struct grf_softc *, struct grf_spriteinfo *));
+int cl_getspritemax __P((struct grf_softc *, struct grf_position *));
+int cl_blank __P((struct grf_softc *, int *));
+int cl_setmonitor __P((struct grf_softc *, struct grfvideo_mode *));
+void cl_writesprpos __P((volatile char *, short, short));
+void writeshifted __P((volatile char *, char, char));
+
+void RegWakeup __P((volatile caddr_t));
+void RegOnpass __P((volatile caddr_t));
+void RegOffpass __P((volatile caddr_t));
+
+void grfclattach __P((struct device *, struct device *, void *));
+int grfclprint __P((void *, const char *));
+int grfclmatch __P((struct device *, void *, void *));
+void cl_memset __P((unsigned char *, unsigned char, int));
/* Graphics display definitions.
* These are filled by 'grfconfig' using GRFIOCSETMON.
*/
-#define monitor_def_max 8
-static struct grfvideo_mode monitor_def[8] = {
- {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}
+#define monitor_def_max 24
+static struct grfvideo_mode monitor_def[24] = {
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
};
static struct grfvideo_mode *monitor_current = &monitor_def[0];
@@ -138,8 +144,8 @@ unsigned long cl_maxpixelclock = 86000000;
extern unsigned char CIRRUSFONT[];
struct grfcltext_mode clconsole_mode = {
- {255, "", 25200000, 640, 480, 4, 80, 100, 94, 99, 100, 481, 522, 490,
- 498, 522},
+ {255, "", 25200000, 640, 480, 4, 640/8, 752/8, 792/8, 800/8,
+ 481, 490, 498, 522, 0},
8, CIRRUSFONTY, 80, 480 / CIRRUSFONTY, CIRRUSFONT, 32, 255
};
/* Console colors */
@@ -148,10 +154,11 @@ unsigned char clconscolors[3][3] = { /* background, foreground, hilite */
};
int cltype = 0; /* Picasso, Spectrum or Piccolo */
-int cl_sd64 = 0;
+int cl_64bit = 0;
unsigned char pass_toggle; /* passthru status tracker */
-/* because all 5426-boards have 2 configdev entries, one for
+/*
+ * because all 542x-boards have 2 configdev entries, one for
* framebuffer mem and the other for regs, we have to hold onto
* the pointers globally until we match on both. This and 'cltype'
* are the primary obsticles to multiple board support, but if you
@@ -160,8 +167,10 @@ unsigned char pass_toggle; /* passthru status tracker */
static void *cl_fbaddr = 0; /* framebuffer */
static void *cl_regaddr = 0; /* registers */
static int cl_fbsize; /* framebuffer size */
+static int cl_fbautosize; /* framebuffer autoconfig size */
-/* current sprite info, if you add support for multiple boards
+/*
+ * current sprite info, if you add support for multiple boards
* make this an array or something
*/
struct grf_spriteinfo cl_cursprite;
@@ -191,9 +200,10 @@ grfclmatch(pdp, match, auxp)
struct cfdata *cfp = match;
#endif
struct zbus_args *zap;
- static int regprod, fbprod;
+ static int regprod, fbprod, fbprod2;
int error;
+ fbprod2 = 0;
zap = auxp;
#ifndef CL5426CONSOLE
@@ -207,11 +217,38 @@ grfclmatch(pdp, match, auxp)
if (cltype == 0) {
switch (zap->manid) {
case PICASSO:
- if (zap->prodid != 12 && zap->prodid != 11)
- return (0);
- regprod = 12;
- fbprod = 11;
- break;
+ switch (zap->prodid) {
+ case 11:
+ case 12:
+ regprod = 12;
+ fbprod = 11;
+ error = 0;
+ break;
+ case 22:
+ fbprod2 = 22;
+ error = 0;
+ break;
+ case 21:
+ case 23:
+ regprod = 23;
+ fbprod = 21;
+ cl_64bit = 1;
+ error = 0;
+ break;
+ case 24:
+ regprod = 24;
+ fbprod = 24;
+ cl_64bit = 1;
+ error = 0;
+ break;
+ default:
+ error = 1;
+ break;
+ }
+ if (error == 1)
+ return (0);
+ else
+ break;
case SPECTRUM:
if (zap->prodid != 2 && zap->prodid != 1)
return (0);
@@ -230,7 +267,7 @@ grfclmatch(pdp, match, auxp)
case 11:
regprod = 11;
fbprod = 10;
- cl_sd64 = 1;
+ cl_64bit = 1;
error = 0;
break;
default:
@@ -252,14 +289,39 @@ grfclmatch(pdp, match, auxp)
}
/* Configure either registers or framebuffer in any order */
- if (zap->prodid == regprod)
- cl_regaddr = zap->va;
- else
- if (zap->prodid == fbprod) {
+ if ((cltype == PICASSO) && (cl_64bit == 1)) {
+ switch (zap->prodid) {
+ case 21:
cl_fbaddr = zap->va;
- cl_fbsize = zap->size;
- } else
+ cl_fbautosize = zap->size;
+ break;
+ case 22:
+ cl_fbautosize += zap->size;
+ break;
+ case 23:
+ cl_regaddr = (void *)((unsigned long)(zap->va) +
+ 0x10000);
+ break;
+ case 24:
+ cl_regaddr = (void *)((unsigned long)(zap->va) +
+ 0x600000);
+ cl_fbaddr = (void *)((unsigned long)(zap->va) +
+ 0x01000000);
+ cl_fbautosize = 0x400000;
+ break;
+ default:
return (0);
+ }
+ } else {
+ if (zap->prodid == regprod)
+ cl_regaddr = zap->va;
+ else
+ if (zap->prodid == fbprod) {
+ cl_fbaddr = zap->va;
+ cl_fbautosize = zap->size;
+ } else
+ return (0);
+ }
#ifdef CL5426CONSOLE
if (amiga_realconfig == 0) {
@@ -326,15 +388,41 @@ grfclattach(pdp, dp, auxp)
printf("grfcl: %dMB ", cl_fbsize / 0x100000);
switch (cltype) {
case PICASSO:
- printf("Picasso II");
- cl_maxpixelclock = 86000000;
+ if (cl_64bit == 1) {
+ printf("Picasso IV");
+ /* 135MHz will be supported if we
+ * have a palette doubling mode.
+ */
+ cl_maxpixelclock = 86000000;
+ } else {
+ printf("Picasso II");
+
+ /* check for PicassoII+ (crest) */
+ if (zap->serno == 0x00100000)
+ printf("+");
+
+ /* determine used Gfx/chipset (crest) */
+ vgaw(gp->g_regkva, CRT_ADDRESS, 0x27);
+ switch(vgar(gp->g_regkva, CRT_ADDRESS_R)>>2) {
+ case 0x24:
+ printf(" (with CL-GD5426)");
+ break;
+ case 0x26:
+ printf(" (with CL-GD5428)");
+ break;
+ case 0x27:
+ printf(" (with CL-GD5429)");
+ break;
+ }
+ cl_maxpixelclock = 86000000;
+ }
break;
case SPECTRUM:
printf("Spectrum");
cl_maxpixelclock = 90000000;
break;
case PICCOLO:
- if (cl_sd64 == 1) {
+ if (cl_64bit == 1) {
printf("Piccolo SD64");
/* 110MHz will be supported if we
* have a palette doubling mode.
@@ -373,98 +461,112 @@ cl_boardinit(gp)
unsigned char *ba = gp->g_regkva;
int x;
- /* wakeup board and flip passthru OFF */
-
- RegWakeup(ba);
- RegOnpass(ba);
+ if ((cltype == PICASSO) && (cl_64bit == 1)) { /* PicassoIV */
+ /* disable capture (FlickerFixer) */
+ WCrt(ba, 0x51, 0x00);
+ /* wait some time (two frames as of now) */
+ delay(200000);
+ /* get Blitter into 542x */
+ WGfx(ba, 0x2f, 0x00);
+ /* compatibility mode */
+ WGfx(ba, GCT_ID_RESERVED, 0x00);
+ /* or at least, try so... */
+ WGfx(ba, GCT_ID_BLT_STAT_START, 0x00);
+ cl_fbsize = cl_fbautosize;
+ } else {
- vgaw(ba, 0x46e8, 0x16);
- vgaw(ba, 0x102, 1);
- vgaw(ba, 0x46e8, 0x0e);
- if (cl_sd64 != 1)
- vgaw(ba, 0x3c3, 1);
+ /* wakeup board and flip passthru OFF */
+ RegWakeup(ba);
+ RegOnpass(ba);
- /* setup initial unchanging parameters */
+ vgaw(ba, 0x46e8, 0x16);
+ vgaw(ba, 0x102, 1);
+ vgaw(ba, 0x46e8, 0x0e);
+ if (cl_64bit != 1)
+ vgaw(ba, 0x3c3, 1);
- WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21); /* 8 dot - display off */
- vgaw(ba, GREG_MISC_OUTPUT_W, 0xed); /* mem disable */
+ cl_fbsize = cl_fbautosize;
- WGfx(ba, GCT_ID_OFFSET_1, 0xec); /* magic cookie */
- WSeq(ba, SEQ_ID_UNLOCK_EXT, 0x12); /* yum! cookies! */
+ /* setup initial unchanging parameters */
- if (cl_sd64 == 1) {
- WSeq(ba, SEQ_ID_CONF_RBACK, 0x00);
- WSeq(ba, SEQ_ID_DRAM_CNTL, (cl_fbsize / 0x100000 == 2) ? 0x38 : 0xb8);
- } else {
- WSeq(ba, SEQ_ID_DRAM_CNTL, 0xb0);
- }
- WSeq(ba, SEQ_ID_RESET, 0x03);
- WSeq(ba, SEQ_ID_MAP_MASK, 0xff);
- WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
- WSeq(ba, SEQ_ID_MEMORY_MODE, 0x0e); /* a or 6? */
- WSeq(ba, SEQ_ID_EXT_SEQ_MODE, (cltype == PICASSO) ? 0x20 : 0x80);
- WSeq(ba, SEQ_ID_EEPROM_CNTL, 0x00);
- if (cl_sd64 == 1)
- WSeq(ba, SEQ_ID_PERF_TUNE, 0x5a);
- else
- WSeq(ba, SEQ_ID_PERF_TUNE, 0x0a); /* mouse 0a fa */
- WSeq(ba, SEQ_ID_SIG_CNTL, 0x02);
- WSeq(ba, SEQ_ID_CURSOR_ATTR, 0x04);
+ /* 8 dot - display off */
+ WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21);
+ vgaw(ba, GREG_MISC_OUTPUT_W, 0xed); /* mem disable */
- if (cl_sd64 == 1)
- WSeq(ba, SEQ_ID_MCLK_SELECT, 0x1c);
- else
- WSeq(ba, SEQ_ID_MCLK_SELECT, 0x22);
-
- WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00);
- WCrt(ba, CRT_ID_CURSOR_START, 0x00);
- WCrt(ba, CRT_ID_CURSOR_END, 0x08);
- WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
- WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
- WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
- WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
-
- WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x07);
- WCrt(ba, CRT_ID_MODE_CONTROL, 0xa3); /* c3 */
- WCrt(ba, CRT_ID_LINE_COMPARE, 0xff); /* ff */
- WCrt(ba, CRT_ID_EXT_DISP_CNTL, 0x22);
- if (cl_sd64 == 1) {
- WCrt(ba, CRT_ID_SYNC_ADJ_GENLOCK, 0x00);
- WCrt(ba, CRT_ID_OVERLAY_EXT_CTRL_REG, 0x40);
- }
- WSeq(ba, SEQ_ID_CURSOR_STORE, 0x3c); /* mouse 0x00 */
-
- WGfx(ba, GCT_ID_SET_RESET, 0x00);
- WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
- WGfx(ba, GCT_ID_DATA_ROTATE, 0x00);
- WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
- WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00);
- WGfx(ba, GCT_ID_MISC, 0x01);
- WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f);
- WGfx(ba, GCT_ID_BITMASK, 0xff);
- WGfx(ba, GCT_ID_MODE_EXT, 0x28);
-
- for (x = 0; x < 0x10; x++)
- WAttr(ba, x, x);
- WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x01);
- WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00);
- WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
- WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
- WAttr(ba, ACT_ID_COLOR_SELECT, 0x00);
+ WGfx(ba, GCT_ID_OFFSET_1, 0xec); /* magic cookie */
+ WSeq(ba, SEQ_ID_UNLOCK_EXT, 0x12); /* yum! cookies! */
- delay(200000);
- WAttr(ba, 0x34, 0x00);
- delay(200000);
+ if (cl_64bit == 1) {
+ WSeq(ba, SEQ_ID_CONF_RBACK, 0x00);
+ WSeq(ba, SEQ_ID_DRAM_CNTL,
+ (cl_fbsize / 0x100000 == 2) ? 0x38 : 0xb8);
+ } else {
+ WSeq(ba, SEQ_ID_DRAM_CNTL, 0xb0);
+ }
+ WSeq(ba, SEQ_ID_RESET, 0x03);
+ WSeq(ba, SEQ_ID_MAP_MASK, 0xff);
+ WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
+ WSeq(ba, SEQ_ID_MEMORY_MODE, 0x0e); /* a or 6? */
+ WSeq(ba, SEQ_ID_EXT_SEQ_MODE,
+ (cltype == PICASSO) ? 0x21 : 0x81);
+ WSeq(ba, SEQ_ID_EEPROM_CNTL, 0x00);
+ if (cl_64bit == 1)
+ WSeq(ba, SEQ_ID_PERF_TUNE, 0x5a);
+ else
+ /* mouse 0a fa */
+ WSeq(ba, SEQ_ID_PERF_TUNE, 0x0a);
+ WSeq(ba, SEQ_ID_SIG_CNTL, 0x02);
+ WSeq(ba, SEQ_ID_CURSOR_ATTR, 0x04);
+ if (cl_64bit == 1)
+ WSeq(ba, SEQ_ID_MCLK_SELECT, 0x1c);
+ else
+ WSeq(ba, SEQ_ID_MCLK_SELECT, 0x22);
- vgaw(ba, VDAC_MASK, 0xff);
- delay(200000);
- vgaw(ba, GREG_MISC_OUTPUT_W, 0xef);
+ WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00);
+ WCrt(ba, CRT_ID_CURSOR_START, 0x00);
+ WCrt(ba, CRT_ID_CURSOR_END, 0x08);
+ WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
+ WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
+ WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
+ WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
- WGfx(ba, GCT_ID_BLT_STAT_START, 0x04);
- WGfx(ba, GCT_ID_BLT_STAT_START, 0x00);
+ WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x07);
+ WCrt(ba, CRT_ID_MODE_CONTROL, 0xe3);
+ WCrt(ba, CRT_ID_LINE_COMPARE, 0xff); /* ff */
+ WCrt(ba, CRT_ID_EXT_DISP_CNTL, 0x22);
+ if (cl_64bit == 1) {
+ WCrt(ba, CRT_ID_SYNC_ADJ_GENLOCK, 0x00);
+ WCrt(ba, CRT_ID_OVERLAY_EXT_CTRL_REG, 0x40);
+ }
+ WSeq(ba, SEQ_ID_CURSOR_STORE, 0x3c); /* mouse 0x00 */
+
+ WGfx(ba, GCT_ID_SET_RESET, 0x00);
+ WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
+ WGfx(ba, GCT_ID_DATA_ROTATE, 0x00);
+ WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
+ WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00);
+ WGfx(ba, GCT_ID_MISC, 0x01);
+ WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f);
+ WGfx(ba, GCT_ID_BITMASK, 0xff);
+ WGfx(ba, GCT_ID_MODE_EXT, 0x28);
+
+ for (x = 0; x < 0x10; x++)
+ WAttr(ba, x, x);
+ WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x01);
+ WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00);
+ WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
+ WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
+ WAttr(ba, ACT_ID_COLOR_SELECT, 0x00);
+ WAttr(ba, 0x34, 0x00);
+
+ vgaw(ba, VDAC_MASK, 0xff);
+ vgaw(ba, GREG_MISC_OUTPUT_W, 0xef);
+
+ WGfx(ba, GCT_ID_BLT_STAT_START, 0x04);
+ WGfx(ba, GCT_ID_BLT_STAT_START, 0x00);
+ }
/* colors initially set to greyscale */
-
vgaw(ba, VDAC_ADDRESS_W, 0);
for (x = 255; x >= 0; x--) {
vgaw(ba, VDAC_DATA, x);
@@ -477,6 +579,23 @@ cl_boardinit(gp)
cl_cursprite.cmap.red = cl_sprred;
cl_cursprite.cmap.green = cl_sprgreen;
cl_cursprite.cmap.blue = cl_sprblue;
+
+ if (cl_64bit == 0) {
+ /* check for 1MB or 2MB board (crest) */
+ volatile unsigned long *cl_fbtestaddr;
+ cl_fbtestaddr = (volatile unsigned long *)gp->g_fbkva;
+
+ WGfx(ba, GCT_ID_OFFSET_0, 0x40);
+ *cl_fbtestaddr = 0x12345678;
+
+ if (*cl_fbtestaddr != 0x12345678) {
+ WSeq(ba, SEQ_ID_DRAM_CNTL, 0x30);
+ cl_fbsize = 0x100000;
+ } else {
+ cl_fbsize = 0x200000;
+ }
+ }
+ WGfx(ba, GCT_ID_OFFSET_0, 0x00);
}
@@ -510,7 +629,6 @@ cl_getvmode(gp, vm)
/* adjust internal values to pixel values */
vm->hblank_start *= 8;
- vm->hblank_stop *= 8;
vm->hsync_start *= 8;
vm->hsync_stop *= 8;
vm->htotal *= 8;
@@ -540,11 +658,14 @@ cl_off(gp)
{
char *ba = gp->g_regkva;
- /* we'll put the pass-through on for cc ite and set Full Bandwidth bit
+ /*
+ * we'll put the pass-through on for cc ite and set Full Bandwidth bit
* on just in case it didn't work...but then it doesn't matter does
- * it? =) */
+ * it? =)
+ */
RegOnpass(ba);
- WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21);
+ vgaw(ba, SEQ_ADDRESS, SEQ_ID_CLOCKING_MODE);
+ vgaw(ba, SEQ_ADDRESS_W, vgar(ba, SEQ_ADDRESS_W) | 0x20);
}
#endif
@@ -679,13 +800,14 @@ cl_writesprpos(ba, x, y)
cwp = ba + 0x3c4;
wp = (unsigned short *)cwp;
- /* don't ask me why, but apparently you can't do a 16-bit write with
- * x-position like with y-position below (dagge) */
+ /*
+ * don't ask me why, but apparently you can't do a 16-bit write with
+ * x-position like with y-position below (dagge)
+ */
cwp[0] = 0x10 | ((x << 5) & 0xff);
cwp[1] = (x >> 3) & 0xff;
*wp = 0x1100 | ((y & 7) << 13) | ((y >> 3) & 0xff);
-
}
void
@@ -704,7 +826,8 @@ writeshifted(to, shiftx, shifty)
shiftx = shiftx < 0 ? 0 : shiftx;
shifty = shifty < 0 ? 0 : shifty;
- /* start reading shifty lines down, and
+ /*
+ * start reading shifty lines down, and
* shift each line in by shiftx
*/
for (y = shifty; y < 64; y++) {
@@ -747,7 +870,8 @@ cl_setmousepos(gp, data)
prx = cl_cursprite.pos.x - cl_cursprite.hot.x;
pry = cl_cursprite.pos.y - cl_cursprite.hot.y;
- /* if we are/were on an edge, create (un)shifted bitmap --
+ /*
+ * if we are/were on an edge, create (un)shifted bitmap --
* ripped out optimization (not extremely worthwhile,
* and kind of buggy anyhow).
*/
@@ -776,7 +900,7 @@ cl_getspriteinfo(gp, data)
return (0);
}
-static int
+int
cl_setspriteinfo(gp, data)
struct grf_softc *gp;
struct grf_spriteinfo *data;
@@ -912,7 +1036,7 @@ cl_setspriteinfo(gp, data)
return (0);
}
-static int
+int
cl_getspritemax(gp, data)
struct grf_softc *gp;
struct grf_position *data;
@@ -938,11 +1062,10 @@ cl_setmonitor(gp, gv)
/* handle interactive setting of console mode */
if (gv->mode_num == 255) {
bcopy(gv, &clconsole_mode.gv, sizeof(struct grfvideo_mode));
- clconsole_mode.gv.hblank_start /= 8;
- clconsole_mode.gv.hblank_stop /= 8;
- clconsole_mode.gv.hsync_start /= 8;
- clconsole_mode.gv.hsync_stop /= 8;
- clconsole_mode.gv.htotal /= 8;
+ clconsole_mode.gv.hblank_start /= 8;
+ clconsole_mode.gv.hsync_start /= 8;
+ clconsole_mode.gv.hsync_stop /= 8;
+ clconsole_mode.gv.htotal /= 8;
clconsole_mode.rows = gv->disp_height / clconsole_mode.fy;
clconsole_mode.cols = gv->disp_width / clconsole_mode.fx;
if (!(gp->g_flags & GF_GRFON))
@@ -955,13 +1078,12 @@ cl_setmonitor(gp, gv)
md = monitor_def + (gv->mode_num - 1);
bcopy(gv, md, sizeof(struct grfvideo_mode));
- /* adjust pixel oriented values to internal rep. */
+ /* adjust pixel oriented values to internal rep. */
- md->hblank_start /= 8;
- md->hblank_stop /= 8;
- md->hsync_start /= 8;
- md->hsync_stop /= 8;
- md->htotal /= 8;
+ md->hblank_start /= 8;
+ md->hsync_start /= 8;
+ md->hsync_stop /= 8;
+ md->htotal /= 8;
return (0);
}
@@ -987,12 +1109,22 @@ cl_getcmap(gfp, cmap)
vgaw(ba, VDAC_ADDRESS_R, cmap->index);
x = cmap->count - 1;
-/* Some sort 'o Magic. Spectrum has some changes on the board to speed
+/*
+ * Some sort 'o Magic. Spectrum has some changes on the board to speed
* up 15 and 16Bit modes. They can access these modes with easy-to-programm
* rgbrgbrgb instead of rrrgggbbb. Side effect: when in 8Bit mode, rgb
* is swapped to bgr. I wonder if we need to check for 8Bit though, ill
*/
+/*
+ * The source for the above comment is somewhat unknow to me.
+ * The Spectrum, Piccolo and PiccoloSD64 have the analog Red and Blue
+ * lines swapped. In 24BPP this provides RGB instead of BGR as it would
+ * be native to the chipset. This requires special programming for the
+ * CLUT in 8BPP to compensate and avoid false colors.
+ * I didn't find any special stuff for 15 and 16BPP though, crest.
+ */
+
switch (cltype) {
case SPECTRUM:
case PICCOLO:
@@ -1088,19 +1220,17 @@ cl_toggle(gp, wopp)
if (pass_toggle) {
RegOffpass(ba);
} else {
- /* This was in the original.. is it needed? */
- if (cltype == PICASSO || cltype == PICCOLO)
- RegWakeup(ba);
RegOnpass(ba);
}
return (0);
}
-static void
-cl_CompFQ(fq, num, denom)
+void
+cl_CompFQ(fq, num, denom, clkdoub)
u_int fq;
u_char *num;
u_char *denom;
+ u_char *clkdoub;
{
#define OSC 14318180
/* OK, here's what we're doing here:
@@ -1136,19 +1266,34 @@ denom = 0x00 - 0x1f (1) 0x20 - 0x3e (even)
mind = 0;
p = 0;
- for (d = 1; d < 0x20; d++) {
- for (n = 1; n < 0x80; n++) {
- err = abs(count(n, d, p) - fq);
- if (err < minerr) {
- minerr = err;
- minn = n;
- mind = d;
- minp = p;
+ if ((cl_64bit == 1) && (fq >= 86000000)) {
+ for (d = 1; d < 0x20; d++) {
+ for (n = 1; n < 0x80; n++) {
+ err = abs(count(n, d, 0) - fq);
+ if (err < minerr) {
+ minerr = err;
+ minn = n;
+ mind = d;
+ minp = 1;
+ }
}
}
- if (d == 0x1f && p == 0) {
- p = 1;
- d = 0x0f;
+ *clkdoub = 1;
+ } else {
+ for (d = 1; d < 0x20; d++) {
+ for (n = 1; n < 0x80; n++) {
+ err = abs(count(n, d, p) - fq);
+ if (err < minerr) {
+ minerr = err;
+ minn = n;
+ mind = d;
+ minp = p;
+ }
+ }
+ if (d == 0x1f && p == 0) {
+ p = 1;
+ d = 0x0f;
+ }
}
}
@@ -1170,25 +1315,56 @@ cl_mondefok(gv)
return(0);
switch (gv->depth) {
- case 4:
+ case 4:
if (gv->mode_num != 255)
return(0);
- case 1:
- case 8:
- maxpix = cl_maxpixelclock;
+ case 1:
+ case 8:
+ maxpix = cl_maxpixelclock;
+ if (cl_64bit == 1)
+ {
+ if (cltype == PICASSO) /* Picasso IV */
+ maxpix = 135000000;
+ else /* Piccolo SD64 */
+ maxpix = 110000000;
+ }
break;
- case 15:
- case 16:
- maxpix = cl_maxpixelclock - (cl_maxpixelclock / 3);
+ case 15:
+ case 16:
+ if (cl_64bit == 1)
+ maxpix = 85000000;
+ else
+ maxpix = cl_maxpixelclock - (cl_maxpixelclock / 3);
break;
- case 24:
- maxpix = cl_maxpixelclock / 3;
+ case 24:
+ if ((cltype == PICASSO) && (cl_64bit == 1))
+ maxpix = 85000000;
+ else
+ maxpix = cl_maxpixelclock / 3;
+ break;
+ case 32:
+ if ((cltype == PICCOLO) && (cl_64bit == 1))
+ maxpix = 50000000;
+ else
+ maxpix = 0;
break;
default:
+ printf("grfcl: Illegal depth in mode %d\n",
+ (int) gv->mode_num);
return (0);
}
- if (gv->pixel_clock > maxpix)
+
+ if (gv->pixel_clock > maxpix) {
+ printf("grfcl: Pixelclock too high in mode %d\n",
+ (int) gv->mode_num);
return (0);
+ }
+
+ if (gv->disp_flags & GRF_FLAGS_SYNC_ON_GREEN) {
+ printf("grfcl: sync-on-green is not supported\n");
+ return (0);
+ }
+
return (1);
}
@@ -1200,31 +1376,36 @@ cl_load_mon(gp, md)
struct grfvideo_mode *gv;
struct grfinfo *gi;
volatile caddr_t ba, fb;
- unsigned char num0, denom0;
+ unsigned char num0, denom0, clkdoub;
unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
VSE, VT;
- char LACE, DBLSCAN, TEXT;
- unsigned short clkdiv;
- int uplim, lowlim;
+ int clkmul, offsmul, clkmode;
+ int vmul;
int sr15;
+ unsigned char hvsync_pulse;
+ char TEXT;
/* identity */
gv = &md->gv;
TEXT = (gv->depth == 4);
if (!cl_mondefok(gv)) {
- printf("mondef not ok\n");
+ printf("grfcl: Monitor definition not ok\n");
return (0);
}
+
ba = gp->g_regkva;
fb = gp->g_fbkva;
- /* provide all needed information in grf device-independant locations */
- gp->g_data = (caddr_t) gv;
+ /*
+ * provide all needed information in grf device-independant
+ * locations
+ */
+ gp->g_data = (caddr_t)gv;
gi = &gp->g_display;
- gi->gd_regaddr = (caddr_t) ztwopa(ba);
+ gi->gd_regaddr = (caddr_t)kvtop(ba);
gi->gd_regsize = 64 * 1024;
- gi->gd_fbaddr = (caddr_t) kvtop(fb);
+ gi->gd_fbaddr = (caddr_t)kvtop(fb);
gi->gd_fbsize = cl_fbsize;
gi->gd_colors = 1 << gv->depth;
gi->gd_planes = gv->depth;
@@ -1245,14 +1426,14 @@ cl_load_mon(gp, md)
/* get display mode parameters */
HBS = gv->hblank_start;
- HBE = gv->hblank_stop;
HSS = gv->hsync_start;
HSE = gv->hsync_stop;
+ HBE = gv->htotal - 1;
HT = gv->htotal;
VBS = gv->vblank_start;
VSS = gv->vsync_start;
VSE = gv->vsync_stop;
- VBE = gv->vblank_stop;
+ VBE = gv->vtotal - 1;
VT = gv->vtotal;
if (TEXT)
@@ -1261,27 +1442,68 @@ cl_load_mon(gp, md)
HDE = (gv->disp_width + 3) / 8 - 1; /* HBS; */
VDE = gv->disp_height - 1;
- /* figure out whether lace or dblscan is needed */
+ /* adjustments */
+ switch (gv->depth) {
+ case 8:
+ clkmul = 1;
+ offsmul = 1;
+ clkmode = 0x0;
+ break;
+ case 15:
+ case 16:
+ clkmul = 1;
+ offsmul = 2;
+ clkmode = 0x6;
+ break;
+ case 24:
+ /* Picasso IV? */
+ if ((cltype == PICASSO) && (cl_64bit == 1))
+ clkmul = 1;
+ else
+ clkmul = 3;
+ offsmul = 3;
+ clkmode = 0x4;
+ break;
+ case 32:
+ clkmul = 1;
+ offsmul = 2;
+ clkmode = 0x8;
+ break;
+ default:
+ clkmul = 1;
+ offsmul = 1;
+ clkmode = 0x0;
+ break;
+ }
- uplim = gv->disp_height + (gv->disp_height / 4);
- lowlim = gv->disp_height - (gv->disp_height / 4);
- LACE = (((VT * 2) > lowlim) && ((VT * 2) < uplim)) ? 1 : 0;
- DBLSCAN = (((VT / 2) > lowlim) && ((VT / 2) < uplim)) ? 1 : 0;
+ if ((VT > 1023) && (!(gv->disp_flags & GRF_FLAGS_LACE))) {
+ WCrt(ba, CRT_ID_MODE_CONTROL, 0xe7);
+ } else
+ WCrt(ba, CRT_ID_MODE_CONTROL, 0xe3);
- /* adjustments */
+ vmul = 2;
+ if ((VT > 1023) || (gv->disp_flags & GRF_FLAGS_LACE))
+ vmul = 1;
+ if (gv->disp_flags & GRF_FLAGS_DBLSCAN)
+ vmul = 4;
- if (LACE)
- VDE /= 2;
+ VDE = VDE * vmul / 2;
+ VBS = VBS * vmul / 2;
+ VSS = VSS * vmul / 2;
+ VSE = VSE * vmul / 2;
+ VBE = VBE * vmul / 2;
+ VT = VT * vmul / 2;
WSeq(ba, SEQ_ID_MEMORY_MODE, (TEXT || (gv->depth == 1)) ? 0x06 : 0x0e);
- if (cl_sd64 == 1) {
+ if (cl_64bit == 1) {
if (TEXT || (gv->depth == 1))
- sr15 = 0x90;
+ sr15 = 0xd0;
else
sr15 = ((cl_fbsize / 0x100000 == 2) ? 0x38 : 0xb8);
WSeq(ba, SEQ_ID_CONF_RBACK, 0x00);
} else {
sr15 = (TEXT || (gv->depth == 1)) ? 0xd0 : 0xb0;
+ sr15 &= ((cl_fbsize / 0x100000) == 2) ? 0xff : 0x7f;
}
WSeq(ba, SEQ_ID_DRAM_CNTL, sr15);
WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
@@ -1290,8 +1512,30 @@ cl_load_mon(gp, md)
/* Set clock */
- cl_CompFQ((gv->depth == 24) ? gv->pixel_clock * 3 : gv->pixel_clock,
- &num0, &denom0);
+ cl_CompFQ(gv->pixel_clock * clkmul, &num0, &denom0, &clkdoub);
+
+ /* Horizontal/Vertical Sync Pulse */
+ hvsync_pulse = vgar(ba, GREG_MISC_OUTPUT_R);
+ if (gv->disp_flags & GRF_FLAGS_PHSYNC)
+ hvsync_pulse &= ~0x40;
+ else
+ hvsync_pulse |= 0x40;
+ if (gv->disp_flags & GRF_FLAGS_PVSYNC)
+ hvsync_pulse &= ~0x80;
+ else
+ hvsync_pulse |= 0x80;
+ vgaw(ba, GREG_MISC_OUTPUT_W, hvsync_pulse);
+
+ if (clkdoub) {
+ HDE /= 2;
+ HBS /= 2;
+ HSS /= 2;
+ HSE /= 2;
+ HBE /= 2;
+ HT /= 2;
+ clkmode = 0x6;
+ }
+
WSeq(ba, SEQ_ID_VCLK_3_NUM, num0);
WSeq(ba, SEQ_ID_VCLK_3_DENOM, denom0);
@@ -1316,13 +1560,11 @@ cl_load_mon(gp, md)
((VDE & 0x200) ? 0x40 : 0x00) |
((VSS & 0x200) ? 0x80 : 0x00));
-
WCrt(ba, CRT_ID_CHAR_HEIGHT,
0x40 | /* TEXT ? 0x00 ??? */
- (DBLSCAN ? 0x80 : 0x00) |
+ ((gv->disp_flags & GRF_FLAGS_DBLSCAN) ? 0x80 : 0x00) |
((VBS & 0x200) ? 0x20 : 0x00) |
(TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
- WCrt(ba, CRT_ID_MODE_CONTROL, 0xe3);
/* text cursor */
@@ -1351,48 +1593,23 @@ cl_load_mon(gp, md)
WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
WCrt(ba, CRT_ID_LACE_END, HT / 2); /* MW/16 */
WCrt(ba, CRT_ID_LACE_CNTL,
- (LACE ? 0x01 : 0x00) |
+ ((gv->disp_flags & GRF_FLAGS_LACE) ? 0x01 : 0x00) |
((HBE & 0x40) ? 0x10 : 0x00) |
((HBE & 0x80) ? 0x20 : 0x00) |
((VBE & 0x100) ? 0x40 : 0x00) |
((VBE & 0x200) ? 0x80 : 0x00));
- /* depth dependent stuff */
-
- switch (gv->depth) {
- case 1:
- case 4:
- case 8:
- clkdiv = 0;
- break;
- case 15:
- case 16:
- clkdiv = 3;
- break;
- case 24:
- clkdiv = 2;
- break;
- default:
- clkdiv = 0;
- panic("grfcl: Unsuported depth: %i", gv->depth);
- break;
- }
-
WGfx(ba, GCT_ID_GRAPHICS_MODE,
((TEXT || (gv->depth == 1)) ? 0x00 : 0x40));
WGfx(ba, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
WSeq(ba, SEQ_ID_EXT_SEQ_MODE,
((TEXT || (gv->depth == 1)) ? 0x00 : 0x01) |
- ((cltype == PICASSO) ? 0x20 : 0x80) |
- (clkdiv << 1));
-
- delay(200000);
+ ((cltype == PICASSO) ? 0x20 : 0x80) | clkmode);
/* write 0x00 to VDAC_MASK before accessing HDR this helps
sometimes, out of "secret" application note (crest) */
vgaw(ba, VDAC_MASK, 0);
- delay(200000);
/* reset HDR "magic" access counter (crest) */
vgar(ba, VDAC_ADDRESS);
@@ -1406,53 +1623,54 @@ cl_load_mon(gp, md)
vgar(ba, VDAC_MASK);
delay(200000);
switch (gv->depth) {
- case 1:
- case 4: /* text */
+ case 1:
+ case 4: /* text */
vgaw(ba, VDAC_MASK, 0);
HDE = gv->disp_width / 16;
break;
- case 8:
- vgaw(ba, VDAC_MASK, 0);
+ case 8:
+ if (clkdoub)
+ vgaw(ba, VDAC_MASK, 0x4a); /* Clockdouble Magic */
+ else
+ vgaw(ba, VDAC_MASK, 0);
HDE = gv->disp_width / 8;
break;
- case 15:
+ case 15:
vgaw(ba, VDAC_MASK, 0xd0);
HDE = gv->disp_width / 4;
break;
- case 16:
+ case 16:
vgaw(ba, VDAC_MASK, 0xc1);
HDE = gv->disp_width / 4;
break;
- case 24:
+ case 24:
vgaw(ba, VDAC_MASK, 0xc5);
HDE = (gv->disp_width / 8) * 3;
break;
+ case 32:
+ vgaw(ba, VDAC_MASK, 0xc5);
+ HDE = (gv->disp_width / 4);
+ break;
}
- delay(20000);
/* reset HDR "magic" access counter (crest) */
vgar(ba, VDAC_ADDRESS);
- delay(200000);
/* then enable all bit in VDAC_MASK afterwards (crest) */
vgaw(ba, VDAC_MASK, 0xff);
- delay(20000);
WCrt(ba, CRT_ID_OFFSET, HDE);
- if (cl_sd64 == 1) {
+ if (cl_64bit == 1) {
WCrt(ba, CRT_ID_SYNC_ADJ_GENLOCK, 0x00);
WCrt(ba, CRT_ID_OVERLAY_EXT_CTRL_REG, 0x40);
}
WCrt(ba, CRT_ID_EXT_DISP_CNTL,
((TEXT && gv->pixel_clock > 29000000) ? 0x40 : 0x00) |
0x22 |
- ((HDE > 0xff) ? 0x10 : 0x00)); /* text? */
+ ((HDE > 0xff) ? 0x10 : 0x00));
- delay(200000);
WAttr(ba, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x0a : 0x01));
- delay(200000);
WAttr(ba, 0x20 | ACT_ID_COLOR_PLANE_ENA,
(gv->depth == 1) ? 0x01 : 0x0f);
- delay(200000);
/* text initialization */
@@ -1506,7 +1724,6 @@ cl_inittextmode(gp)
/* set colors (B&W) */
-
vgaw(ba, VDAC_ADDRESS_W, 0);
for (z = 0; z < 256; z++) {
unsigned char r, g, b;
@@ -1538,13 +1755,14 @@ cl_memset(d, c, l)
*d++ = c;
}
-/* Special wakeup/passthrough registers on graphics boards
+/*
+ * Special wakeup/passthrough registers on graphics boards
*
* The methods have diverged a bit for each board, so
* WPass(P) has been converted into a set of specific
* inline functions.
*/
-static void
+void
RegWakeup(ba)
volatile caddr_t ba;
{
@@ -1554,19 +1772,20 @@ RegWakeup(ba)
vgaw(ba, PASS_ADDRESS_W, 0x1f);
break;
case PICASSO:
- vgaw(ba, PASS_ADDRESS_W, 0xff);
+ /* Picasso needs no wakeup */
break;
case PICCOLO:
- if (cl_sd64 == 1)
+ if (cl_64bit == 1)
vgaw(ba, PASS_ADDRESS_W, 0x1f);
else
- vgaw(ba, PASS_ADDRESS_W, vgar(ba, PASS_ADDRESS) | 0x10);
+ vgaw(ba, PASS_ADDRESS_W,
+ vgar(ba, PASS_ADDRESS) | 0x10);
break;
}
delay(200000);
}
-static void
+void
RegOnpass(ba)
volatile caddr_t ba;
{
@@ -1579,7 +1798,7 @@ RegOnpass(ba)
vgaw(ba, PASS_ADDRESS_WP, 0x01);
break;
case PICCOLO:
- if (cl_sd64 == 1)
+ if (cl_64bit == 1)
vgaw(ba, PASS_ADDRESS_W, 0x4f);
else
vgaw(ba, PASS_ADDRESS_W, vgar(ba, PASS_ADDRESS) & 0xdf);
@@ -1589,7 +1808,7 @@ RegOnpass(ba)
delay(200000);
}
-static void
+void
RegOffpass(ba)
volatile caddr_t ba;
{
@@ -1599,15 +1818,15 @@ RegOffpass(ba)
vgaw(ba, PASS_ADDRESS_W, 0x6f);
break;
case PICASSO:
- vgaw(ba, PASS_ADDRESS_W, 0xff);
- delay(200000);
- vgaw(ba, PASS_ADDRESS_W, 0xff);
+ if (cl_64bit == 0)
+ vgaw(ba, PASS_ADDRESS_W, 0xff);
break;
case PICCOLO:
- if (cl_sd64 == 1)
+ if (cl_64bit == 1)
vgaw(ba, PASS_ADDRESS_W, 0x6f);
else
- vgaw(ba, PASS_ADDRESS_W, vgar(ba, PASS_ADDRESS) | 0x20);
+ vgaw(ba, PASS_ADDRESS_W,
+ vgar(ba, PASS_ADDRESS) | 0x20);
break;
}
pass_toggle = 0;
diff --git a/sys/arch/amiga/dev/grf_clreg.h b/sys/arch/amiga/dev/grf_clreg.h
index 048cc22105e..3644079e66a 100644
--- a/sys/arch/amiga/dev/grf_clreg.h
+++ b/sys/arch/amiga/dev/grf_clreg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: grf_clreg.h,v 1.6 1997/01/16 09:24:11 niklas Exp $ */
-/* $NetBSD: grf_clreg.h,v 1.5 1996/10/08 23:18:51 thorpej Exp $ */
+/* $OpenBSD: grf_clreg.h,v 1.7 1997/09/18 13:39:49 niklas Exp $ */
+/* $NetBSD: grf_clreg.h,v 1.6 1997/03/21 09:40:58 veego Exp $ */
/*
* Copyright (c) 1995 Ezra Story
@@ -264,9 +264,11 @@ struct grfcltext_mode {
/* Video DAC */
#define VDAC_ADDRESS 0x03c8
#define VDAC_ADDRESS_W 0x03c8
-#define VDAC_ADDRESS_R ((cltype==PICASSO)?0x03c7+0xfff:0x3c7)
+#define VDAC_ADDRESS_R \
+ (((cltype == PICASSO) && (cl_64bit == 0)) ? 0x03c7 + 0xfff : 0x3c7)
#define VDAC_STATE 0x03c7
-#define VDAC_DATA ((cltype==PICASSO)?0x03c9+0xfff:0x3c9)
+#define VDAC_DATA \
+ (((cltype == PICASSO) && (cl_64bit == 0)) ? 0x03c9 + 0xfff : 0x3c9)
#define VDAC_MASK 0x03c6
#define HDR 0x03c6 /* Hidden DAC register, 4 reads to access */
diff --git a/sys/arch/amiga/dev/grf_cv.c b/sys/arch/amiga/dev/grf_cv.c
index 1dc6fddfc17..034cd957ae7 100644
--- a/sys/arch/amiga/dev/grf_cv.c
+++ b/sys/arch/amiga/dev/grf_cv.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: grf_cv.c,v 1.14 1997/01/16 09:24:13 niklas Exp $ */
-/* $NetBSD: grf_cv.c,v 1.20 1996/12/23 09:10:05 veego Exp $ */
+/* $OpenBSD: grf_cv.c,v 1.15 1997/09/18 13:39:49 niklas Exp $ */
+/* $NetBSD: grf_cv.c,v 1.24 1997/07/30 11:05:55 veego Exp $ */
/*
* Copyright (c) 1995 Michael Teske
@@ -16,7 +16,7 @@
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ezra Story, by Kari
- * Mettinen and by Bernd Ernesti.
+ * Mettinen, Michael Teske and by Bernd Ernesti.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
@@ -39,18 +39,12 @@
*
* Modified for CV64 from
* Kari Mettinen's Cirrus driver by Michael Teske 10/95
- * For questions mail me at teske@mail.desy.de
*
* Thanks to Tekelec Airtronic for providing me with a S3 Trio64 documentation.
* Thanks to Bernd 'the fabulous bug-finder' Ernesti for bringing my messy
* source to NetBSD style :)
- *
- * TODO:
- * Bugfree Hardware Cursor support.
- * The HWC routines provided here are buggy in 16/24 bit
- * and may cause a Vertical Bar Crash of the Trio64.
- * On the other hand it's better to put the routines in the Xserver,
- * so please _don't_ put CV_HARDWARE_CURSOR in your config file.
+ * Thanks to Harald Koenig for providing information about undocumented
+ * Trio64 Bugs.
*/
#include <sys/param.h>
@@ -59,10 +53,16 @@
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/systm.h>
+#include <sys/syslog.h>
+
#include <machine/cpu.h>
+#include <machine/intr.h>
+
#include <dev/cons.h>
+
#include <amiga/dev/itevar.h>
#include <amiga/amiga/device.h>
+#include <amiga/amiga/isr.h>
#include <amiga/dev/grfioctl.h>
#include <amiga/dev/grfvar.h>
#include <amiga/dev/grf_cvreg.h>
@@ -72,8 +72,9 @@ int grfcvmatch __P((struct device *, void *, void *));
void grfcvattach __P((struct device *, struct device *, void *));
int grfcvprint __P((void *, const char *));
-static int cv_has_4mb __P((volatile caddr_t));
-static unsigned short cv_compute_clock __P((unsigned long));
+int cvintr __P((void *));
+int cv_has_4mb __P((volatile caddr_t));
+unsigned short cv_compute_clock __P((unsigned long));
void cv_boardinit __P((struct grf_softc *));
int cv_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
int cv_setvmode __P((struct grf_softc *, unsigned int));
@@ -87,20 +88,27 @@ int cv_toggle __P((struct grf_softc *));
int cv_mondefok __P((struct grfvideo_mode *));
int cv_load_mon __P((struct grf_softc *, struct grfcvtext_mode *));
void cv_inittextmode __P((struct grf_softc *));
-static inline void cv_write_port __P((unsigned short, volatile caddr_t));
-static inline void cvscreen __P((int, volatile caddr_t));
-static inline void gfx_on_off __P((int, volatile caddr_t));
+static __inline void cv_write_port __P((unsigned short, volatile caddr_t));
+static __inline void cvscreen __P((int, volatile caddr_t));
+static __inline void gfx_on_off __P((int, volatile caddr_t));
-#ifdef CV_HARDWARE_CURSOR
+#ifndef CV_NO_HARDWARE_CURSOR
int cv_getspritepos __P((struct grf_softc *, struct grf_position *));
int cv_setspritepos __P((struct grf_softc *, struct grf_position *));
+static __inline short M2I __P((short));
int cv_getspriteinfo __P((struct grf_softc *,struct grf_spriteinfo *));
-void cv_setup_hwc __P((struct grf_softc *,
- unsigned char, unsigned char, unsigned char, unsigned char,
- const unsigned long *));
+void cv_setup_hwc __P((struct grf_softc *));
int cv_setspriteinfo __P((struct grf_softc *,struct grf_spriteinfo *));
int cv_getspritemax __P((struct grf_softc *,struct grf_position *));
-#endif /* CV_HARDWARE_CURSOR */
+#endif /* !CV_NO_HARDWARE_CURSOR */
+
+/*
+ * Extension to grf_softc for interrupt support
+ */
+struct grf_cv_softc {
+ struct grf_softc gcs_sc;
+ struct isr gcs_isr;
+};
/* Graphics display definitions.
* These are filled by 'grfconfig' using GRFIOCSETMON.
@@ -137,8 +145,8 @@ extern unsigned char S3FONT[];
* (Internally, we still have to use hvalues/8!)
*/
struct grfcvtext_mode cvconsole_mode = {
- {255, "", 25000000, 640, 480, 4, 640/8, 784/8, 680/8, 768/8, 800/8,
- 481, 521, 491, 493, 525},
+ { 255, "", 25000000, 640, 480, 4, 640/8, 680/8, 768/8, 800/8,
+ 481, 521, 491, 493, 525 },
8, S3FONTY, 80, 480 / S3FONTY, S3FONT, 32, 255
};
@@ -250,7 +258,7 @@ long cv_memclk = 50000000;
/* standard driver stuff */
struct cfattach grfcv_ca = {
- sizeof(struct grf_softc), grfcvmatch, grfcvattach
+ sizeof(struct grf_cv_softc), grfcvmatch, grfcvattach
};
struct cfdriver grfcv_cd = {
@@ -258,6 +266,85 @@ struct cfdriver grfcv_cd = {
};
static struct cfdata *grfcv_cfdata;
+#define CV_INT_NUM 6 /* CV interrupt Level: #2 or #6 */
+#define CV_ULCURSOR 1 /* Underlined Cursor in textmode */
+
+#ifndef CV_NO_HARDWARE_CURSOR
+
+#define HWC_OFF (cv_fbsize - 1024*2)
+#define HWC_SIZE 1024
+
+static unsigned short cv_cursor_storage[HWC_SIZE/2];
+static short curs_update_flag = 0;
+#endif /* !CV_NO_HARDWARE_CURSOR */
+
+/*
+ * Interrupt handler
+ * This is used for updating the cursor shape (because it _must not_
+ * be changed while cursor is displayed)
+ * and maybe later to avoid busy waiting
+ * for Vertical Blank and/or gfx engine busy
+ */
+int
+cvintr(arg)
+ void * arg;
+{
+#ifndef CV_NO_HARDWARE_CURSOR
+ register unsigned long *csrc, *cdest;
+ int i;
+#endif /* !CV_NO_HARDWARE_CURSOR */
+ struct grf_softc *gp = arg;
+ volatile caddr_t ba = gp->g_regkva;
+ unsigned char test;
+ unsigned char cridx; /* Save the cr Register index */
+
+ if (gp == NULL)
+ return 0;
+
+ test = vgar(ba, GREG_INPUT_STATUS0_R);
+
+ if (test & 0x80) { /* VR int pending */
+ /* Save old CR index */
+ cridx = vgar (ba, CRT_ADDRESS);
+
+#if 0
+ test = RCrt(ba, CRT_ID_END_VER_RETR);
+ /* Clear int (bit 4) */
+ test &= ~0x10;
+ WCrt(ba, CRT_ID_END_VER_RETR, test);
+#else
+ vgaw(ba, CRT_ADDRESS, CRT_ID_END_VER_RETR);
+ asm volatile ("bclr #4,%0@(0x3d5);nop" : : "a" (ba));
+#endif
+
+#ifndef CV_NO_HARDWARE_CURSOR
+ /* update the hardware cursor, if necessary */
+ if (curs_update_flag) {
+ csrc = (unsigned long *)cv_cursor_storage;
+ cdest = (unsigned long *)((volatile char *)gp->g_fbkva
+ + HWC_OFF);
+ for (i = 0; i < HWC_SIZE / sizeof(long); i++)
+ *cdest++ = *csrc++;
+ curs_update_flag = 0;
+ }
+ /* Reenable int */
+#if 0
+ test |= 0x10;
+ WCrt(ba, CRT_ID_END_VER_RETR, test);
+#else
+ /* I don't trust the optimizer here... */
+ asm volatile ("bset #4,%0@(0x3d5);nop" : : "a" (ba));
+#endif
+ cv_setspritepos (gp, NULL);
+
+ /* Restore the old CR index */
+ vgaw(ba, CRT_ADDRESS, cridx);
+ __asm volatile ("nop");
+#endif /* !CV_NO_HARDWARE_CURSOR */
+ return (1);
+ }
+ return (0);
+}
/*
* Get frambuffer memory size.
@@ -265,7 +352,7 @@ static struct cfdata *grfcv_cfdata;
* so we have to do it this way.
* Return 0 for 2MB, 1 for 4MB
*/
-static int
+int
cv_has_4mb(fb)
volatile caddr_t fb;
{
@@ -301,7 +388,7 @@ grfcvmatch(pdp, match, auxp)
#ifdef CV64CONSOLE
struct cfdata *cfp = match;
static int cvcons_unit = -1;
-#endif
+#endif /* CV64CONSOLE */
struct zbus_args *zap;
zap = auxp;
@@ -309,7 +396,7 @@ grfcvmatch(pdp, match, auxp)
if (amiga_realconfig == 0)
#ifdef CV64CONSOLE
if (cvcons_unit != -1)
-#endif
+#endif /* CV64CONSOLE */
return (0);
/* Lets be Paranoid: Test man and prod id */
@@ -323,7 +410,7 @@ grfcvmatch(pdp, match, auxp)
cvcons_unit = cfp->cf_unit;
grfcv_cfdata = cfp;
}
-#endif
+#endif /* CV64CONSOLE */
return (1);
}
@@ -333,9 +420,10 @@ grfcvattach(pdp, dp, auxp)
struct device *pdp, *dp;
void *auxp;
{
- static struct grf_softc congrf;
+ static struct grf_cv_softc congrf;
struct zbus_args *zap;
struct grf_softc *gp;
+ struct grf_cv_softc *gcp;
static char attachflag = 0;
zap = auxp;
@@ -346,28 +434,32 @@ grfcvattach(pdp, dp, auxp)
*/
if (dp == NULL) /* console init */
- gp = &congrf;
+ gcp = &congrf;
else
- gp = (struct grf_softc *)dp;
+ gcp = (struct grf_cv_softc *)dp;
- if (dp != NULL && congrf.g_regkva != 0) {
+ gp = &gcp->gcs_sc;
+
+ if (dp != NULL && congrf.gcs_sc.g_regkva != 0) {
/*
* inited earlier, just copy (not device struct)
*/
printf("\n");
-#ifdef CV64CONSOLE
- bcopy(&congrf.g_display, &gp->g_display,
- (char *) &gp[1] - (char *) &gp->g_display);
-#else
- gp->g_regkva = (volatile caddr_t)cv_boardaddr + 0x02000000;
- gp->g_fbkva = (volatile caddr_t)cv_boardaddr + 0x01400000;
-
- gp->g_unit = GRF_CV64_UNIT;
- gp->g_mode = cv_mode;
- gp->g_conpri = grfcv_cnprobe();
- gp->g_flags = GF_ALIVE;
-#endif
+ bcopy(&congrf.gcs_sc.g_display, &gp->g_display,
+ (char *) &gcp->gcs_isr - (char *) &gp->g_display);
+
+ /* ... and transfer the isr */
+ gcp->gcs_isr.isr_ipl = CV_INT_NUM;
+#if CV_INT_NUM == 6
+ gcp->gcs_isr.isr_mapped_ipl = IPL_TTY;
+#endif /* CV_INT_NUM == 6 */
+ gcp->gcs_isr.isr_intr = cvintr;
+ gcp->gcs_isr.isr_arg = (void *)gp;
+
+ /* First add new isr */
+ add_isr(&gcp->gcs_isr);
+ remove_isr(&congrf.gcs_isr);
} else {
gp->g_regkva = (volatile caddr_t)cv_boardaddr + 0x02000000;
gp->g_fbkva = (volatile caddr_t)cv_boardaddr + 0x01400000;
@@ -377,13 +469,22 @@ grfcvattach(pdp, dp, auxp)
gp->g_conpri = grfcv_cnprobe();
gp->g_flags = GF_ALIVE;
+ /* add Interrupt Handler */
+ gcp->gcs_isr.isr_ipl = CV_INT_NUM;
+#if CV_INT_NUM == 6
+ gcp->gcs_isr.isr_mapped_ipl = IPL_TTY;
+#endif /* CV_INT_NUM == 6 */
+ gcp->gcs_isr.isr_intr = cvintr;
+ gcp->gcs_isr.isr_arg = (void *)gp;
+ add_isr(&gcp->gcs_isr);
+
/* wakeup the board */
cv_boardinit(gp);
#ifdef CV64CONSOLE
grfcv_iteinit(gp);
(void)cv_load_mon(gp, &cvconsole_mode);
-#endif
+#endif /* CV64CONSOLE */
}
/*
@@ -391,7 +492,8 @@ grfcvattach(pdp, dp, auxp)
*/
if (amiga_config_found(grfcv_cfdata, &gp->g_device, gp, grfcvprint)) {
if (dp != NULL)
- printf("grfcv: CyberVision64 with %dMB being used\n", cv_fbsize/0x100000);
+ printf("grfcv: CyberVision64 with %dMB being used\n",
+ cv_fbsize/0x100000);
attachflag = 1;
} else {
if (!attachflag)
@@ -421,7 +523,7 @@ grfcvprint(auxp, pnp)
* higher byte: Bits 0-6: M divider value for e.g. SR11 or SR13
*/
-static unsigned short
+unsigned short
cv_compute_clock(freq)
unsigned long freq;
{
@@ -492,6 +594,17 @@ cv_boardinit(gp)
WCrt(ba, CRT_ID_REGISTER_LOCK_1, 0x48); /* unlock S3 VGA regs */
WCrt(ba, CRT_ID_REGISTER_LOCK_2, 0xA5); /* unlock syscontrol */
+ /*
+ * The default board interrupt is #6.
+ * Set the roxxler register to use interrupt #2, not #6.
+ */
+#if CV_INT_NUM == 2
+ cv_write_port(0x8080, ba - 0x02000000);
+#endif /* CV_INT_NUM == 2 */
+
+ /* Enable board interrupts */
+ cv_write_port(0x8008, ba - 0x02000000);
+
test = RCrt(ba, CRT_ID_SYSTEM_CONFIG);
test = test | 0x01; /* enable enhaced register access */
test = test & 0xEF; /* clear bit 4, 0 wait state */
@@ -504,8 +617,8 @@ cv_boardinit(gp)
*/
vgaw(ba, ECR_ADV_FUNC_CNTL, 0x31);
- /* enable cpu acess, color mode, high 64k page */
- vgaw(ba, GREG_MISC_OUTPUT_W, 0x23);
+ /* enable color mode (bit0), cpu acess (bit1), high 64k page (bit5) */
+ vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3);
/* Cpu base addr */
WCrt(ba, CRT_ID_EXT_SYS_CNTL_4, 0x00);
@@ -752,7 +865,6 @@ cv_getvmode(gp, vm)
/* adjust internal values to pixel values */
vm->hblank_start *= 8;
- vm->hblank_stop *= 8;
vm->hsync_start *= 8;
vm->hsync_stop *= 8;
vm->htotal *= 8;
@@ -812,11 +924,11 @@ cv_mode(gp, cmd, arg, a2, a3)
case GM_GRFOFF:
#ifndef CV64CONSOLE
- cvscreen(1, gp->g_regkva - 0x02000000)
-#else
+ cvscreen(1, gp->g_regkva - 0x02000000);
+#else /* !CV64CONSOLE */
cv_load_mon(gp, &cvconsole_mode);
ite_reinit(gp->g_itedev);
-#endif
+#endif /* !CV64CONSOLE */
return (0);
case GM_GRFCONFIG:
@@ -854,7 +966,7 @@ cv_ioctl (gp, cmd, data)
void *data;
{
switch (cmd) {
-#ifdef CV_HARDWARE_CURSOR
+#ifndef CV_NO_HARDWARE_CURSOR
case GRFIOCGSPRITEPOS:
return(cv_getspritepos (gp, (struct grf_position *) data));
@@ -869,14 +981,14 @@ cv_ioctl (gp, cmd, data)
case GRFIOCGSPRITEMAX:
return(cv_getspritemax (gp, (struct grf_position *) data));
-#else /* CV_HARDWARE_CURSOR */
+#else /* !CV_NO_HARDWARE_CURSOR */
case GRFIOCGSPRITEPOS:
case GRFIOCSSPRITEPOS:
case GRFIOCSSPRITEINF:
case GRFIOCGSPRITEINF:
case GRFIOCGSPRITEMAX:
break;
-#endif /* CV_HARDWARE_CURSOR */
+#endif /* !CV_NO_HARDWARE_CURSOR */
case GRFIOCGETCMAP:
return (cv_getcmap (gp, (struct grf_colormap *) data));
@@ -915,7 +1027,6 @@ cv_setmonitor(gp, gv)
if (gv->mode_num == 255) {
bcopy(gv, &cvconsole_mode.gv, sizeof(struct grfvideo_mode));
cvconsole_mode.gv.hblank_start /= 8;
- cvconsole_mode.gv.hblank_stop /= 8;
cvconsole_mode.gv.hsync_start /= 8;
cvconsole_mode.gv.hsync_stop /= 8;
cvconsole_mode.gv.htotal /= 8;
@@ -936,7 +1047,7 @@ cv_setmonitor(gp, gv)
*/
if (gp->g_flags & GF_GRFON)
if (md == monitor_current) {
- printf("grf_cv: Changing the used mode not allowed!\n");
+ printf("grfcv: Changing the used mode not allowed!\n");
return (EINVAL);
}
@@ -945,7 +1056,6 @@ cv_setmonitor(gp, gv)
/* adjust pixel oriented values to internal rep. */
md->hblank_start /= 8;
- md->hblank_stop /= 8;
md->hsync_start /= 8;
md->hsync_stop /= 8;
md->htotal /= 8;
@@ -1091,13 +1201,13 @@ cv_mondefok(gv)
#endif
break;
default:
- printf("grf_cv: Illegal depth in mode %d\n",
+ printf("grfcv: Illegal depth in mode %d\n",
(int) gv->mode_num);
return (0);
}
if (gv->pixel_clock > maxpix) {
- printf("grf_cv: Pixelclock too high in mode %d\n",
+ printf("grfcv: Pixelclock too high in mode %d\n",
(int) gv->mode_num);
return (0);
}
@@ -1112,6 +1222,11 @@ cv_mondefok(gv)
}
}
+ if (gv->disp_flags & GRF_FLAGS_SYNC_ON_GREEN) {
+ printf("grfcv: sync-on-green is not supported\n");
+ return (0);
+ }
+
return (1);
}
@@ -1127,12 +1242,13 @@ cv_load_mon(gp, md)
unsigned short mnr;
unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
VSE, VT;
- char LACE, DBLSCAN, TEXT, CONSOLE;
- int uplim, lowlim;
int cr50, sr15, sr18, clock_mode, test;
int m, n; /* For calc'ing display FIFO */
int tfillm, temptym; /* FIFO fill and empty mclk's */
int hmul; /* Multiplier for hor. Values */
+ unsigned char hvsync_pulse;
+ char TEXT, CONSOLE;
+
/* identity */
gv = &md->gv;
@@ -1140,13 +1256,18 @@ cv_load_mon(gp, md)
CONSOLE = (gv->mode_num == 255);
if (!cv_mondefok(gv)) {
- printf("grfcv: The monitor definition is illegal.\n");
- printf("grfcv: See the manpage of grfconfig for more informations\n");
+ printf("grfcv: Monitor definition not ok\n");
return (0);
}
+
ba = gp->g_regkva;
fb = gp->g_fbkva;
+ /* Disable Interrupts */
+ test = RCrt(ba, CRT_ID_BACKWAD_COMP_1);
+ test &= ~0x10;
+ WCrt(ba, CRT_ID_BACKWAD_COMP_1, test);
+
/* turn gfx off, don't mess up the display */
gfx_on_off(1, ba);
@@ -1171,24 +1292,24 @@ cv_load_mon(gp, md)
/* get display mode parameters */
switch (gv->depth) {
- case 15:
- case 16:
- hmul = 2;
- break;
- default:
- hmul = 1;
- break;
+ case 15:
+ case 16:
+ hmul = 2;
+ break;
+ default:
+ hmul = 1;
+ break;
}
HBS = gv->hblank_start * hmul;
- HBE = gv->hblank_stop * hmul;
HSS = gv->hsync_start * hmul;
HSE = gv->hsync_stop * hmul;
- HT = gv->htotal*hmul - 5;
+ HBE = gv->htotal * hmul - 6;
+ HT = gv->htotal * hmul - 5;
VBS = gv->vblank_start - 1;
VSS = gv->vsync_start;
VSE = gv->vsync_stop;
- VBE = gv->vblank_stop;
+ VBE = gv->vtotal - 3;
VT = gv->vtotal - 2;
/* Disable enhanced Mode for text display */
@@ -1201,17 +1322,36 @@ cv_load_mon(gp, md)
HDE = (gv->disp_width + 3) * hmul / 8 - 1; /*HBS;*/
VDE = gv->disp_height - 1;
- /* figure out whether lace or dblscan is needed */
-
- uplim = gv->disp_height + (gv->disp_height / 4);
- lowlim = gv->disp_height - (gv->disp_height / 4);
- LACE = (((VT * 2) > lowlim) && ((VT * 2) < uplim)) ? 1 : 0;
- DBLSCAN = (((VT / 2) > lowlim) && ((VT / 2) < uplim)) ? 1 : 0;
-
/* adjustments */
+ if (gv->disp_flags & GRF_FLAGS_LACE) {
+ VDE = VDE / 2;
+ VBS = VBS / 2;
+ VSS = VSS / 2;
+ VSE = VSE / 2;
+ VBE = VBE / 2;
+ VT = VT / 2;
+ }
- if (LACE)
- VDE /= 2;
+ /* Horizontal/Vertical Sync Pulse */
+ /*
+ * GREG_MISC_OUTPUT_W Register:
+ * bit description (0/1)
+ * 0 Monochrome/Color emulation
+ * 1 Disable/Enable access of the display memory from the CPU
+ * 5 Select the low/high 64K page of memory
+ * 6 Select a positive/negative horizontal retrace sync pulse
+ * 7 Select a positive/negative vertical retrace sync pulse
+ */
+ hvsync_pulse = vgar(ba, GREG_MISC_OUTPUT_R);
+ if (gv->disp_flags & GRF_FLAGS_PHSYNC)
+ hvsync_pulse &= ~0x40;
+ else
+ hvsync_pulse |= 0x40;
+ if (gv->disp_flags & GRF_FLAGS_PVSYNC)
+ hvsync_pulse &= ~0x80;
+ else
+ hvsync_pulse |= 0x80;
+ vgaw(ba, GREG_MISC_OUTPUT_W, hvsync_pulse);
/* GFX hardware cursor off */
WCrt(ba, CRT_ID_HWGC_MODE, 0x00);
@@ -1269,7 +1409,7 @@ cv_load_mon(gp, md)
WCrt(ba, CRT_ID_MAX_SCAN_LINE,
0x40 | /* TEXT ? 0x00 ??? */
- (DBLSCAN ? 0x80 : 0x00) |
+ ((gv->disp_flags & GRF_FLAGS_DBLSCAN) ? 0x80 : 0x00) |
((VBS & 0x200) ? 0x20 : 0x00) |
(TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
@@ -1278,13 +1418,13 @@ cv_load_mon(gp, md)
/* text cursor */
if (TEXT) {
-#if 1
+#if CV_ULCURSOR
WCrt(ba, CRT_ID_CURSOR_START, (md->fy & 0x1f) - 2);
WCrt(ba, CRT_ID_CURSOR_END, (md->fy & 0x1f) - 1);
-#else
+#else /* CV_ULCURSOR */
WCrt(ba, CRT_ID_CURSOR_START, 0x00);
WCrt(ba, CRT_ID_CURSOR_END, md->fy & 0x1f);
-#endif
+#endif /* CV_ULCURSOR */
WCrt(ba, CRT_ID_UNDERLINE_LOC, (md->fy - 1) & 0x1f);
WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
@@ -1302,7 +1442,8 @@ cv_load_mon(gp, md)
WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
WCrt(ba, CRT_ID_LACE_RETR_START, HT / 2);
- WCrt(ba, CRT_ID_LACE_CONTROL, (LACE ? 0x20 : 0x00));
+ WCrt(ba, CRT_ID_LACE_CONTROL,
+ ((gv->disp_flags & GRF_FLAGS_LACE) ? 0x20 : 0x00));
WGfx(ba, GCT_ID_GRAPHICS_MODE,
((TEXT || (gv->depth == 1)) ? 0x00 : 0x40));
@@ -1318,9 +1459,9 @@ cv_load_mon(gp, md)
WCrt(ba, CRT_ID_BACKWAD_COMP_2, (test | 0x20));
sr15 = RSeq(ba, SEQ_ID_CLKSYN_CNTL_2);
- sr15 &= 0xef;
+ sr15 &= ~0x10;
sr18 = RSeq(ba, SEQ_ID_RAMDAC_CNTL);
- sr18 &= 0x7f;
+ sr18 &= ~0x80;
clock_mode = 0x00;
cr50 = 0x00;
@@ -1471,12 +1612,28 @@ cv_load_mon(gp, md)
}
}
- /* Some kind of Magic */
+ /* Set display enable flag */
WAttr(ba, 0x33, 0);
/* turn gfx on again */
gfx_on_off(0, ba);
+ /* enable interrupts */
+ test = RCrt(ba, CRT_ID_BACKWAD_COMP_1);
+ test |= 0x10;
+ WCrt(ba, CRT_ID_BACKWAD_COMP_1, test);
+
+ test = RCrt(ba, CRT_ID_END_VER_RETR);
+ test &= ~0x20;
+ WCrt(ba, CRT_ID_END_VER_RETR, test);
+ test &= ~0x10;
+ WCrt(ba, CRT_ID_END_VER_RETR, test);
+ test |= 0x10;
+ WCrt(ba, CRT_ID_END_VER_RETR, test);
+#ifndef CV_NO_HARDWARE_CURSOR
+ cv_setup_hwc(gp);
+#endif
+
/* Pass-through */
cvscreen(0, ba - 0x02000000);
@@ -1539,7 +1696,7 @@ cv_inittextmode(gp)
}
-static inline void
+static __inline void
cv_write_port(bits, BoardAddr)
unsigned short bits;
volatile caddr_t BoardAddr;
@@ -1566,7 +1723,7 @@ cv_write_port(bits, BoardAddr)
* 1 = Amiga Signal,
* ba = boardaddr
*/
-static inline void
+static __inline void
cvscreen(toggle, ba)
int toggle;
volatile caddr_t ba;
@@ -1581,7 +1738,7 @@ cvscreen(toggle, ba)
/* 0 = on, 1= off */
/* ba= registerbase */
-static inline void
+static __inline void
gfx_on_off(toggle, ba)
int toggle;
volatile caddr_t ba;
@@ -1592,46 +1749,55 @@ gfx_on_off(toggle, ba)
toggle = toggle << 5;
r = RSeq(ba, SEQ_ID_CLOCKING_MODE);
- r &= 0xdf; /* set Bit 5 to 0 */
+ r &= ~0x20; /* set Bit 5 to 0 */
WSeq(ba, SEQ_ID_CLOCKING_MODE, r | toggle);
}
-
-#ifdef CV_HARDWARE_CURSOR
+#ifndef CV_NO_HARDWARE_CURSOR
static unsigned char cv_hotx = 0, cv_hoty = 0;
+static char cv_cursor_on = 0;
/* Hardware Cursor handling routines */
int
-cv_getspritepos (gp, pos)
+cv_getspritepos(gp, pos)
struct grf_softc *gp;
struct grf_position *pos;
{
int hi,lo;
volatile caddr_t ba = gp->g_regkva;
- hi = RCrt (ba, CRT_ID_HWGC_ORIGIN_Y_HI);
- lo = RCrt (ba, CRT_ID_HWGC_ORIGIN_Y_LO);
+ hi = RCrt(ba, CRT_ID_HWGC_ORIGIN_Y_HI);
+ lo = RCrt(ba, CRT_ID_HWGC_ORIGIN_Y_LO);
pos->y = (hi << 8) + lo;
- hi = RCrt (ba, CRT_ID_HWGC_ORIGIN_X_HI);
- lo = RCrt (ba, CRT_ID_HWGC_ORIGIN_X_LO);
+ hi = RCrt(ba, CRT_ID_HWGC_ORIGIN_X_HI);
+ lo = RCrt(ba, CRT_ID_HWGC_ORIGIN_X_LO);
pos->x = (hi << 8) + lo;
return (0);
}
-
int
-cv_setspritepos (gp, pos)
+cv_setspritepos(gp, pos)
struct grf_softc *gp;
struct grf_position *pos;
{
volatile caddr_t ba = gp->g_regkva;
- short x = pos->x, y = pos->y;
+ short x, y;
+ static short savex, savey;
short xoff, yoff;
+ if (pos) {
+ x = pos->x;
+ y = pos->y;
+ savex = x;
+ savey= y;
+ } else { /* restore cursor */
+ x = savex;
+ y = savey;
+ }
x -= cv_hotx;
y -= cv_hoty;
if (x < 0) {
@@ -1648,37 +1814,26 @@ cv_setspritepos (gp, pos)
yoff = 0;
}
- WCrt (ba, CRT_ID_HWGC_ORIGIN_X_HI, (x >> 8));
- WCrt (ba, CRT_ID_HWGC_ORIGIN_X_LO, (x & 0xff));
+ WCrt(ba, CRT_ID_HWGC_ORIGIN_X_HI, (x >> 8));
+ WCrt(ba, CRT_ID_HWGC_ORIGIN_X_LO, (x & 0xff));
- WCrt (ba, CRT_ID_HWGC_ORIGIN_Y_LO, (y & 0xff));
- WCrt (ba, CRT_ID_HWGC_DSTART_X, xoff);
- WCrt (ba, CRT_ID_HWGC_DSTART_Y, yoff);
- WCrt (ba, CRT_ID_HWGC_ORIGIN_Y_HI, (y >> 8));
+ WCrt(ba, CRT_ID_HWGC_ORIGIN_Y_LO, (y & 0xff));
+ WCrt(ba, CRT_ID_HWGC_DSTART_X, xoff);
+ WCrt(ba, CRT_ID_HWGC_DSTART_Y, yoff);
+ WCrt(ba, CRT_ID_HWGC_ORIGIN_Y_HI, (y >> 8));
- return(0);
+ return (0);
}
-static inline short
-M2I(short val) {
- asm volatile (" rorw #8,%0 ; \
- swap %0 ; \
- rorw #8,%0 ; " : "=d" (val) : "0" (val));
- return (val);
+static __inline short
+M2I(val)
+ short val;
+{
+ return (((val & 0xff00) >> 8) | ((val & 0xff) << 8));
}
-#define M2INS(val) \
- asm volatile (" rorw #8,%0 ; \
- swap %0 ; \
- rorw #8,%0 ; \
- swap %0 ; " : "=d" (val) : "0" (val));
-
-#define HWC_OFF (cv_fbsize - 1024*2)
-#define HWC_SIZE 1024
-
-
int
-cv_getspriteinfo (gp, info)
+cv_getspriteinfo(gp, info)
struct grf_softc *gp;
struct grf_spriteinfo *info;
{
@@ -1728,40 +1883,52 @@ cv_getspriteinfo (gp, info)
void
-cv_setup_hwc (gp, col1, col2, hsx, hsy, data)
+cv_setup_hwc(gp)
struct grf_softc *gp;
- unsigned char col1;
- unsigned char col2;
- unsigned char hsx;
- unsigned char hsy;
- const unsigned long *data;
{
volatile caddr_t ba = gp->g_regkva;
- unsigned long *c = (unsigned long *)(gp->g_fbkva + HWC_OFF);
- const unsigned long *s = data;
+ volatile caddr_t hwc;
int test;
- short x = (HWC_SIZE / (4*4)) - 1;
- /* copy only, if there is a data pointer. */
- if (data) do {
- *c++ = *s++;
- *c++ = *s++;
- *c++ = *s++;
- *c++ = *s++;
- } while (x-- > 0);
+ if (gp->g_display.gd_planes <= 4)
+ cv_cursor_on = 0; /* don't enable hwc in text modes */
+ if (cv_cursor_on == 0)
+ return;
/* reset colour stack */
+#if 0
test = RCrt(ba, CRT_ID_HWGC_MODE);
- asm volatile("nop");
- WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
- WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
+ __asm volatile ("nop");
+#else
+ /* do it in assembler, the above does't seem to work */
+ __asm volatile ("moveb #0x45, %1@(0x3d4); moveb %1@(0x3d5),%0" :
+ "=r" (test) : "a" (ba));
+#endif
+
WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 0;
+ *hwc = 0;
+
+#if 0
test = RCrt(ba, CRT_ID_HWGC_MODE);
- asm volatile("nop");
- WCrt (ba, CRT_ID_HWGC_BG_STACK, 0x1);
- WCrt (ba, CRT_ID_HWGC_BG_STACK, 0x1);
- WCrt (ba, CRT_ID_HWGC_BG_STACK, 0x1);
+ __asm volatile ("nop");
+#else
+ /* do it in assembler, the above does't seem to work */
+ __asm volatile ("moveb #0x45, %1@(0x3d4); moveb %1@(0x3d5),%0" :
+ "=r" (test) : "a" (ba));
+#endif
+ switch (gp->g_display.gd_planes) {
+ case 8:
+ WCrt(ba, CRT_ID_HWGC_BG_STACK, 0x1);
+ *hwc = 1;
+ break;
+ default:
+ WCrt(ba, CRT_ID_HWGC_BG_STACK, 0xff);
+ *hwc = 0xff;
+ *hwc = 0xff;
+ }
test = HWC_OFF / HWC_SIZE;
WCrt (ba, CRT_ID_HWGC_START_AD_HI, (test >> 8));
@@ -1770,14 +1937,21 @@ cv_setup_hwc (gp, col1, col2, hsx, hsy, data)
WCrt (ba, CRT_ID_HWGC_DSTART_X , 0);
WCrt (ba, CRT_ID_HWGC_DSTART_Y , 0);
- WCrt (ba, CRT_ID_EXT_DAC_CNTL, 0x10); /* Cursor X11 Mode */
+ WCrt (ba, CRT_ID_EXT_DAC_CNTL, 0x10); /* Cursor X11 Mode */
+ /*
+ * Put it into Windoze Mode or you'll see sometimes a white stripe
+ * on the right side (in double clocking modes with a screen bigger
+ * > 1023 pixels).
+ */
+ WCrt (ba, CRT_ID_EXT_DAC_CNTL, 0x00); /* Cursor Windoze Mode */
WCrt (ba, CRT_ID_HWGC_MODE, 0x01);
}
-
-/* This is the reason why you shouldn't use the HGC in the Kernel:( */
-
+/*
+ * This was the reason why you shouldn't use the HWC in the Kernel:(
+ * Obsoleted now by use of interrupts :-)
+ */
#define VerticalRetraceWait(ba) \
{ \
while (vgar(ba, GREG_INPUT_STATUS1_R) == 0x00) ; \
@@ -1809,6 +1983,7 @@ cv_setspriteinfo (gp, info)
u_char *imp, *mp;
unsigned short row;
+#ifdef CV_NO_INT
/* Cursor off */
WCrt (ba, CRT_ID_HWGC_MODE, 0x00);
@@ -1827,6 +2002,10 @@ cv_setspriteinfo (gp, info)
* (thanks to Harald Koenig for this tip!)
*/
+ /*
+ * Remark 06/06/96: Update in interrupt obsoletes this,
+ * but the warning should stay there!
+ */
VerticalRetraceWait(ba);
WCrt (ba, CRT_ID_HWGC_ORIGIN_X_HI, 0x7);
@@ -1835,6 +2014,7 @@ cv_setspriteinfo (gp, info)
WCrt (ba, CRT_ID_HWGC_DSTART_X, 0x3f);
WCrt (ba, CRT_ID_HWGC_DSTART_Y, 0x3f);
WCrt (ba, CRT_ID_HWGC_ORIGIN_Y_HI, 0x7);
+#endif /* CV_NO_INT */
if (info->size.y > 64)
info->size.y = 64;
@@ -1849,11 +2029,14 @@ cv_setspriteinfo (gp, info)
copyin(info->image, image, info->size.y * info->size.x / 8);
copyin(info->mask, mask, info->size.y * info->size.x / 8);
- hwp = (u_short *)(fb +HWC_OFF);
+#ifdef CV_NO_INT
+ hwp = (u_short *)(fb + HWC_OFF);
/* This is necessary in order not to crash the board */
-
VerticalRetraceWait(ba);
+#else /* CV_NO_INT */
+ hwp = (u_short *) cv_cursor_storage;
+#endif /* CV_NO_INT */
/*
* setting it is slightly more difficult, because we can't
@@ -1865,28 +2048,33 @@ cv_setspriteinfo (gp, info)
row < info->size.y; row++) {
u_short im1, im2, im3, im4, m1, m2, m3, m4;
- im1 = *(unsigned short *)imp;
- imp += 2;
- m1 = *(unsigned short *)mp;
+ m1 = ~(*(unsigned short *)mp);
+ im1 = *(unsigned short *)imp & *(unsigned short *)mp;
mp += 2;
-
- im2 = *(unsigned short *)imp;
imp += 2;
- m2 = *(unsigned short *)mp;
+
+ m2 = ~(*(unsigned short *)mp);
+ im2 = *(unsigned short *)imp & *(unsigned short *)mp;
mp += 2;
+ imp += 2;
if (info->size.x > 32) {
- im3 = *(unsigned long *)imp;
- imp += 4;
- m3 = *(unsigned long *)mp;
- mp += 4;
- im4 = *(unsigned long *)imp;
- imp += 4;
- m4 = *(unsigned long *)mp;
- mp += 4;
+ m3 = ~(*(unsigned short *)mp);
+ im3 = *(unsigned short *)imp &
+ *(unsigned short *)mp;
+ mp += 2;
+ imp += 2;
+ m4 = ~(*(unsigned short *)mp);
+ im4 = *(unsigned short *)imp &
+ *(unsigned short *)mp;
+ mp += 2;
+ imp += 2;
+ } else {
+ m3 = 0xffff;
+ im3 = 0;
+ m4 = 0xffff;
+ im4 = 0;
}
- else
- im3 = m3 = im4 = m4 = 0;
switch (depth) {
case 8:
@@ -1923,68 +2111,100 @@ cv_setspriteinfo (gp, info)
break;
}
}
- for (; row < 64; row++) {
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
- *hwp++ = 0x0000;
+
+ if (depth < 24) {
+ for (; row < 64; row++) {
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ }
+ } else {
+ for (; row < 64; row++) {
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ *hwp++ = 0x0000;
+ *hwp++ = 0xffff;
+ }
}
+
free(image, M_TEMP);
- cv_setup_hwc(gp, 1, 0, 0, 0, NULL);
+ /* cv_setup_hwc(gp); */
cv_hotx = info->hot.x;
cv_hoty = info->hot.y;
+#ifdef CV_NO_INT
/* One must not write twice per vertical blank :-( */
- /* VerticalRetraceWait(ba); */
-
+ VerticalRetraceWait(ba);
cv_setspritepos (gp, &info->pos);
+#else /* CV_NO_INT */
+ cv_setspritepos (gp, &info->pos);
+ curs_update_flag = 1;
+#endif /* CV_NO_INT */
}
if (info->set & GRFSPRSET_CMAP) {
+ volatile caddr_t hwc;
int test;
- VerticalRetraceWait(ba);
-
/* reset colour stack */
test = RCrt(ba, CRT_ID_HWGC_MODE);
asm volatile("nop");
switch (depth) {
- case 32:
- case 24:
- WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
- case 16:
- case 8:
- /* info->cmap.green[1] */
+ case 8:
+ case 15:
+ case 16:
WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 0;
+ break;
+ case 32:
+ case 24:
WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 0;
+ *hwc = 0;
+ break;
}
test = RCrt(ba, CRT_ID_HWGC_MODE);
asm volatile("nop");
switch (depth) {
- case 8:
- WCrt (ba, CRT_ID_HWGC_BG_STACK, 1);
+ case 8:
WCrt (ba, CRT_ID_HWGC_BG_STACK, 1);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 1;
break;
- case 32: case 24:
- WCrt (ba, CRT_ID_HWGC_BG_STACK, 0xff);
- case 16:
+ case 15:
+ case 16:
WCrt (ba, CRT_ID_HWGC_BG_STACK, 0xff);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 0xff;
+ break;
+ case 32:
+ case 24:
WCrt (ba, CRT_ID_HWGC_BG_STACK, 0xff);
+ hwc = ba + CRT_ADDRESS_W;
+ *hwc = 0xff;
+ *hwc = 0xff;
+ break;
}
}
if (info->set & GRFSPRSET_ENABLE) {
-#if 0
- if (info->enable)
- control = 0x85;
- else
- control = 0;
- WSeq(ba, SEQ_ID_CURSOR_CONTROL, control);
-#endif
+ if (info->enable) {
+ cv_cursor_on = 1;
+ cv_setup_hwc(gp);
+ /* WCrt(ba, CRT_ID_HWGC_MODE, 0x01); */
+ } else
+ WCrt(ba, CRT_ID_HWGC_MODE, 0x00);
}
if (info->set & GRFSPRSET_POS)
cv_setspritepos(gp, &info->pos);
@@ -2009,6 +2229,6 @@ cv_getspritemax (gp, pos)
return(0);
}
-#endif /* CV_HARDWARE_CURSOR */
+#endif /* CV_NO_HARDWARE_CURSOR */
#endif /* NGRFCV */
diff --git a/sys/arch/amiga/dev/grf_cvreg.h b/sys/arch/amiga/dev/grf_cvreg.h
index 96ba25955b2..21ea223a67e 100644
--- a/sys/arch/amiga/dev/grf_cvreg.h
+++ b/sys/arch/amiga/dev/grf_cvreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: grf_cvreg.h,v 1.6 1996/05/29 10:15:04 niklas Exp $ */
+/* $OpenBSD: grf_cvreg.h,v 1.7 1997/09/18 13:39:50 niklas Exp $ */
/* $NetBSD: grf_cvreg.h,v 1.5 1996/05/19 21:05:30 veego Exp $ */
/*
@@ -84,12 +84,12 @@ struct grfcvtext_mode {
int grfcv_cnprobe __P((void));
void grfcv_iteinit __P((struct grf_softc *));
-static inline void GfxBusyWait __P((volatile caddr_t));
-static inline void GfxFifoWait __P((volatile caddr_t));
-static inline unsigned char RAttr __P((volatile caddr_t, short));
-static inline unsigned char RSeq __P((volatile caddr_t, short));
-static inline unsigned char RCrt __P((volatile caddr_t, short));
-static inline unsigned char RGfx __P((volatile caddr_t, short));
+static __inline void GfxBusyWait __P((volatile caddr_t));
+static __inline void GfxFifoWait __P((volatile caddr_t));
+static __inline unsigned char RAttr __P((volatile caddr_t, short));
+static __inline unsigned char RSeq __P((volatile caddr_t, short));
+static __inline unsigned char RCrt __P((volatile caddr_t, short));
+static __inline unsigned char RGfx __P((volatile caddr_t, short));
/*
@@ -363,7 +363,7 @@ static inline unsigned char RGfx __P((volatile caddr_t, short));
/* Gfx engine busy wait */
-static inline void
+static __inline void
GfxBusyWait (ba)
volatile caddr_t ba;
{
@@ -376,7 +376,7 @@ GfxBusyWait (ba)
}
-static inline void
+static __inline void
GfxFifoWait(ba)
volatile caddr_t ba;
{
@@ -395,7 +395,7 @@ GfxFifoWait(ba)
* inline functions.
*/
-static inline unsigned char
+static __inline unsigned char
RAttr(ba, idx)
volatile caddr_t ba;
short idx;
@@ -406,7 +406,7 @@ RAttr(ba, idx)
return vgar(ba, ACT_ADDRESS_R);
}
-static inline unsigned char
+static __inline unsigned char
RSeq(ba, idx)
volatile caddr_t ba;
short idx;
@@ -415,7 +415,7 @@ RSeq(ba, idx)
return vgar(ba, SEQ_ADDRESS_R);
}
-static inline unsigned char
+static __inline unsigned char
RCrt(ba, idx)
volatile caddr_t ba;
short idx;
@@ -424,7 +424,7 @@ RCrt(ba, idx)
return vgar(ba, CRT_ADDRESS_R);
}
-static inline unsigned char
+static __inline unsigned char
RGfx(ba, idx)
volatile caddr_t ba;
short idx;
diff --git a/sys/arch/amiga/dev/grf_et.c b/sys/arch/amiga/dev/grf_et.c
index 0459d347c3c..95712b6df7d 100644
--- a/sys/arch/amiga/dev/grf_et.c
+++ b/sys/arch/amiga/dev/grf_et.c
@@ -1,7 +1,8 @@
-/* $OpenBSD: grf_et.c,v 1.6 1997/05/29 01:15:40 niklas Exp $ */
-/* $NetBSD: grf_et.c,v 1.8 1996/12/23 09:10:06 veego Exp $ */
+/* $OpenBSD: grf_et.c,v 1.7 1997/09/18 13:39:51 niklas Exp $ */
+/* $NetBSD: grf_et.c,v 1.10 1997/07/29 17:46:31 veego Exp $ */
/*
+ * Copyright (c) 1997 Klaus Burkert
* Copyright (c) 1996 Tobias Abt
* Copyright (c) 1995 Ezra Story
* Copyright (c) 1995 Kari Mettinen
@@ -49,6 +50,8 @@
* Modified for Tseng ET4000 from
* Kari Mettinen's Cirrus driver by Tobias Abt
*
+ * Fixed Merlin in Z-III, fixed LACE and DBLSCAN, added Domino16M proto
+ * and AT&T ATT20c491 DAC, added memory-size detection by Klaus Burkert.
*
* TODO:
*
@@ -74,7 +77,7 @@
int et_mondefok __P((struct grfvideo_mode *gv));
void et_boardinit __P((struct grf_softc *gp));
-static void et_CompFQ __P((u_int fq, u_char *num, u_char *denom));
+void et_CompFQ __P((u_int fq, u_char *num, u_char *denom));
int et_getvmode __P((struct grf_softc *gp, struct grfvideo_mode *vm));
int et_setvmode __P((struct grf_softc *gp, unsigned int mode));
int et_toggle __P((struct grf_softc *gp, unsigned short));
@@ -88,16 +91,15 @@ int et_ioctl __P((register struct grf_softc *gp, u_long cmd, void *data));
int et_getmousepos __P((struct grf_softc *gp, struct grf_position *data));
void et_writesprpos __P((volatile char *ba, short x, short y));
int et_setmousepos __P((struct grf_softc *gp, struct grf_position *data));
-static int et_setspriteinfo __P((struct grf_softc *gp,
- struct grf_spriteinfo *data));
+int et_setspriteinfo __P((struct grf_softc *gp,
+ struct grf_spriteinfo *data));
int et_getspriteinfo __P((struct grf_softc *gp,
- struct grf_spriteinfo *data));
-static int et_getspritemax __P((struct grf_softc *gp,
- struct grf_position *data));
+ struct grf_spriteinfo *data));
+int et_getspritemax __P((struct grf_softc *gp, struct grf_position *data));
int et_setmonitor __P((struct grf_softc *gp, struct grfvideo_mode *gv));
int et_blank __P((struct grf_softc *gp, int *on));
-static int et_getControllerType __P((struct grf_softc *gp));
-static int et_getDACType __P((struct grf_softc *gp));
+int et_getControllerType __P((struct grf_softc *gp));
+int et_getDACType __P((struct grf_softc *gp));
int grfetmatch __P((struct device *, void *, void *));
void grfetattach __P((struct device *, struct device *, void *));
@@ -108,9 +110,11 @@ void et_memset __P((unsigned char *d, unsigned char c, int l));
* Graphics display definitions.
* These are filled by 'grfconfig' using GRFIOCSETMON.
*/
-#define monitor_def_max 8
-static struct grfvideo_mode monitor_def[8] = {
- {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}
+#define monitor_def_max 24
+static struct grfvideo_mode monitor_def[24] = {
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
};
static struct grfvideo_mode *monitor_current = &monitor_def[0];
@@ -130,8 +134,8 @@ static struct grfvideo_mode *monitor_current = &monitor_def[0];
extern unsigned char TSENGFONT[];
struct grfettext_mode etconsole_mode = {
- {255, "", 25000000, 640, 480, 4, 640/8, 784/8, 680/8, 768/8, 800/8,
- 481, 521, 491, 493, 525},
+ { 255, "", 25000000, 640, 480, 4, 640/8, 680/8, 768/8, 800/8,
+ 481, 491, 493, 525, 0 },
8, TSENGFONTY, 640 / 8, 480 / TSENGFONTY, TSENGFONT, 32, 255
};
@@ -191,7 +195,7 @@ grfetmatch(pdp, match, auxp)
struct cfdata *cfp = match;
#endif
struct zbus_args *zap;
- static int regprod, fbprod;
+ static int regprod, regprod2 = 0, fbprod;
zap = auxp;
@@ -212,9 +216,12 @@ grfetmatch(pdp, match, auxp)
fbprod = 0;
break;
case DOMINO:
- if (zap->prodid != 2 && zap->prodid != 1)
+ /* 2167/3 is Domino16M proto (crest) */
+ if (zap->prodid != 3 && zap->prodid != 2 &&
+ zap->prodid != 1)
return (0);
regprod = 2;
+ regprod2 = 3;
fbprod = 1;
break;
case MERLIN:
@@ -245,7 +252,7 @@ grfetmatch(pdp, match, auxp)
et_fbsize = zap->size;
}
} else {
- if (zap->prodid == regprod) {
+ if (zap->prodid == regprod || zap->prodid == regprod2) {
et_regaddr = zap->va;
} else {
if (zap->prodid == fbprod) {
@@ -353,7 +360,10 @@ grfetattach(pdp, dp, auxp)
printf("MUSIC DAC");
break;
case MERLINDAC:
- printf("BrookTree DAC");
+ printf("BrookTree Bt482 DAC");
+ break;
+ case ATT20C491:
+ printf("AT&T ATT20c491 DAC");
break;
}
printf(" being used\n");
@@ -428,7 +438,7 @@ et_boardinit(gp)
WSeq(ba, SEQ_ID_MAP_MASK, 0x0f);
WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
WSeq(ba, SEQ_ID_MEMORY_MODE, 0x0e);
-/* WSeq(ba, SEQ_ID_TS_STATE_CONTROL, 0x00); */
+ WSeq(ba, SEQ_ID_STATE_CONTROL, 0x00);
WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf4);
WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00);
@@ -439,36 +449,40 @@ et_boardinit(gp)
WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
- WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x07);
- WCrt(ba, CRT_ID_MODE_CONTROL, 0xa3); /* c3 */
- WCrt(ba, CRT_ID_LINE_COMPARE, 0xff); /* ff */
-/* ET4000 special */
+ WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x67);
+ WCrt(ba, CRT_ID_MODE_CONTROL, 0xc3);
+ WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
+
+ /* ET4000 special */
WCrt(ba, CRT_ID_RASCAS_CONFIG, 0x28);
- WCrt(ba, CTR_ID_EXT_START, 0x00);
+ WCrt(ba, CRT_ID_EXT_START, 0x00);
WCrt(ba, CRT_ID_6845_COMPAT, 0x08);
- WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xd3);
- WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x0f); /* assume ZorroII first */
-
- if (iszthreepa(ba)) {
- if (((vgar(ba, GREG_FEATURE_CONTROL_R) & 12) |
- (vgar(ba, GREG_STATUS0_R) & 0x60)) == 0x24 )
- WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x07); /* ZorroIII */
+
+ /* ET4000/W32 special (currently only for Merlin (crest) */
+ if (ettype == MERLIN) {
+ WCrt(ba, CRT_ID_SEGMENT_COMP, 0x1c);
+ WCrt(ba, CRT_ID_GENERAL_PURPOSE, 0x00);
+ WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0x93);
+ }
+ else {
+ WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xd3);
}
+ WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x0f);
WCrt(ba, CRT_ID_HOR_OVERFLOW, 0x00);
+ vgaw(ba, GREG_SEGMENTSELECT, 0x00);
+
WGfx(ba, GCT_ID_SET_RESET, 0x00);
WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
WGfx(ba, GCT_ID_COLOR_COMPARE, 0x00);
WGfx(ba, GCT_ID_DATA_ROTATE, 0x00);
WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
- WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00);
+ WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x40);
WGfx(ba, GCT_ID_MISC, 0x01);
WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f);
WGfx(ba, GCT_ID_BITMASK, 0xff);
- vgaw(ba, GREG_SEGMENTSELECT, 0x00);
-
for (x = 0; x < 0x10; x++)
WAttr(ba, x, x);
WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x01);
@@ -480,10 +494,9 @@ et_boardinit(gp)
vgaw(ba, VDAC_MASK, 0xff);
delay(200000);
- vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3); /* c3 */
+ vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3);
/* colors initially set to greyscale */
-
switch(ettype) {
case MERLIN:
vgaw(ba, MERLIN_VDAC_INDEX, 0);
@@ -509,20 +522,43 @@ et_boardinit(gp)
et_cursprite.cmap.red = et_sprred;
et_cursprite.cmap.green = et_sprgreen;
et_cursprite.cmap.blue = et_sprblue;
-
- /* card spezific initialisations */
+
+ /* card specific initialisations */
switch(ettype) {
case OMNIBUS:
etctype = et_getControllerType(gp);
etdtype = et_getDACType(gp);
break;
+ vgaw(ba, GREG_SEGMENTSELECT2, 0x00);
+ if (((vgar(ba, GREG_FEATURE_CONTROL_R) & 12) |
+ (vgar(ba, GREG_STATUS0_R) & 0x60)) == 0x24) {
+ WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x07); /* 1Mx4 RAM */
+ et_fbsize = 0x400000; /* 4 MB */
+ }
+ else {
+ /* check for 1MB or 2MB board (crest) */
+ /* has there a 1MB Merlin ever been sold ??? */
+ volatile unsigned long *et_fbtestaddr;
+ et_fbtestaddr = (volatile unsigned long *)gp->g_fbkva;
+ *et_fbtestaddr = 0x0;
+ vgaw(ba, GREG_SEGMENTSELECT2, 0x11); /* 1MB offset */
+ *et_fbtestaddr = 0x12345678;
+ vgaw(ba, GREG_SEGMENTSELECT2, 0x00);
+ if (*et_fbtestaddr == 0x0)
+ et_fbsize = 0x200000; /* 2 MB */
+ else
+ et_fbsize = 0x100000; /* 1 MB */
+ }
+ /* ZorroII can map 2 MB max ... */
+ if (!iszthreepa(gp->g_fbkva) && et_fbsize == 0x400000)
+ et_fbsize = 0x200000;
case MERLIN:
etctype = ETW32;
etdtype = MERLINDAC;
break;
case DOMINO:
etctype = ET4000;
- etdtype = SIERRA11483;
+ etdtype = et_getDACType(gp);
break;
}
}
@@ -558,7 +594,6 @@ et_getvmode(gp, vm)
/* adjust internal values to pixel values */
vm->hblank_start *= 8;
- vm->hblank_stop *= 8;
vm->hsync_start *= 8;
vm->hsync_stop *= 8;
vm->htotal *= 8;
@@ -566,7 +601,6 @@ et_getvmode(gp, vm)
return (0);
}
-
int
et_setvmode(gp, mode)
struct grf_softc *gp;
@@ -710,6 +744,7 @@ et_getmousepos(gp, data)
{
data->x = et_cursprite.pos.x;
data->y = et_cursprite.pos.y;
+
return (0);
}
@@ -765,7 +800,7 @@ et_getspriteinfo(gp, data)
}
-static int
+int
et_setspriteinfo(gp, data)
struct grf_softc *gp;
struct grf_spriteinfo *data;
@@ -775,7 +810,7 @@ et_setspriteinfo(gp, data)
}
-static int
+int
et_getspritemax(gp, data)
struct grf_softc *gp;
struct grf_position *data;
@@ -800,7 +835,6 @@ et_setmonitor(gp, gv)
if (gv->mode_num == 255) {
bcopy(gv, &etconsole_mode.gv, sizeof(struct grfvideo_mode));
etconsole_mode.gv.hblank_start /= 8;
- etconsole_mode.gv.hblank_stop /= 8;
etconsole_mode.gv.hsync_start /= 8;
etconsole_mode.gv.hsync_stop /= 8;
etconsole_mode.gv.htotal /= 8;
@@ -819,7 +853,6 @@ et_setmonitor(gp, gv)
/* adjust pixel oriented values to internal rep. */
md->hblank_start /= 8;
- md->hblank_stop /= 8;
md->hsync_start /= 8;
md->hsync_stop /= 8;
md->htotal /= 8;
@@ -985,7 +1018,7 @@ static u_int et_clockfreqs[ET_NUMCLOCKS] = {
};
-static void
+void
et_CompFQ(fq, num, denom)
u_int fq;
u_char *num;
@@ -1010,23 +1043,46 @@ int
et_mondefok(gv)
struct grfvideo_mode *gv;
{
+ unsigned long maxpix;
+
if (gv->mode_num < 1 || gv->mode_num > monitor_def_max)
if (gv->mode_num != 255 || gv->depth != 4)
return(0);
switch (gv->depth) {
- case 4:
+ case 4:
if (gv->mode_num != 255)
return(0);
- case 1:
- case 8:
- case 15:
- case 16:
- case 24:
+ case 1:
+ case 8:
+ maxpix = 85000000;
break;
- default:
+ case 15:
+ case 16:
+ maxpix = 45000000;
+ break;
+ case 24:
+ maxpix = 28000000;
+ break;
+ case 32:
+ maxpix = 21000000;
+ break;
+ default:
+ printf("grfet: Illegal depth in mode %d\n", (int)gv->mode_num);
return (0);
}
+
+ if (gv->pixel_clock > maxpix) {
+ printf("grfet: Pixelclock too high in mode %d\n",
+ (int)gv->mode_num);
+ return (0);
+ }
+
+ if (gv->disp_flags & GRF_FLAGS_SYNC_ON_GREEN) {
+ printf("grfet: sync-on-green is not supported\n");
+ return (0);
+ }
+
return (1);
}
@@ -1042,21 +1098,25 @@ et_load_mon(gp, md)
unsigned char num0, denom0;
unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
VSE, VT;
- char LACE, DBLSCAN, TEXT;
- unsigned char seq;
- int uplim, lowlim;
+ unsigned char hvsync_pulse, seq;
+ char TEXT;
+ int hmul;
/* identity */
gv = &md->gv;
TEXT = (gv->depth == 4);
if (!et_mondefok(gv)) {
- printf("mondef not ok\n");
+ printf("grfet: Monitor definition not ok\n");
return (0);
}
+
ba = gp->g_regkva;
- /* provide all needed information in grf device-independant locations */
+ /*
+ * Provide all needed information in grf device-independant
+ * locations.
+ */
gp->g_data = (caddr_t) gv;
gi = &gp->g_display;
gi->gd_regaddr = (caddr_t) ztwopa(ba);
@@ -1082,14 +1142,14 @@ et_load_mon(gp, md)
/* get display mode parameters */
HBS = gv->hblank_start;
- HBE = gv->hblank_stop;
HSS = gv->hsync_start;
HSE = gv->hsync_stop;
+ HBE = gv->htotal - 1;
HT = gv->htotal;
VBS = gv->vblank_start;
VSS = gv->vsync_start;
VSE = gv->vsync_stop;
- VBE = gv->vblank_stop;
+ VBE = gv->vtotal - 1;
VT = gv->vtotal;
if (TEXT)
@@ -1098,17 +1158,43 @@ et_load_mon(gp, md)
HDE = (gv->disp_width + 3) / 8 - 1; /* HBS; */
VDE = gv->disp_height - 1;
- /* figure out whether lace or dblscan is needed */
-
- uplim = gv->disp_height + (gv->disp_height / 4);
- lowlim = gv->disp_height - (gv->disp_height / 4);
- LACE = (((VT * 2) > lowlim) && ((VT * 2) < uplim)) ? 1 : 0;
- DBLSCAN = (((VT / 2) > lowlim) && ((VT / 2) < uplim)) ? 1 : 0;
+ /* adjustments (crest) */
+ switch (gv->depth) {
+ case 15:
+ case 16:
+ hmul = 2;
+ break;
+ case 24:
+ hmul = 3;
+ break;
+ case 32:
+ hmul = 4;
+ break;
+ default:
+ hmul = 1;
+ break;
+ }
- /* adjustments */
+ HDE *= hmul;
+ HBS *= hmul;
+ HSS *= hmul;
+ HSE *= hmul;
+ HBE *= hmul;
+ HT *= hmul;
- if (LACE)
+ if (gv->disp_flags & GRF_FLAGS_LACE) {
VDE /= 2;
+ VT = VT + 1;
+ }
+
+ if (gv->disp_flags & GRF_FLAGS_DBLSCAN) {
+ VDE *= 2;
+ VBS *= 2;
+ VSS *= 2;
+ VSE *= 2;
+ VBE *= 2;
+ VT *= 2;
+ }
WSeq(ba, SEQ_ID_MEMORY_MODE, (TEXT || (gv->depth == 1)) ? 0x06 : 0x0e);
@@ -1117,36 +1203,46 @@ et_load_mon(gp, md)
WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
/* Set clock */
+ et_CompFQ(gv->pixel_clock * hmul, &num0, &denom0);
- et_CompFQ( gv->pixel_clock, &num0, &denom0);
+ /* Horizontal/Vertical Sync Pulse */
+ hvsync_pulse = 0xe3;
+ if (gv->disp_flags & GRF_FLAGS_PHSYNC)
+ hvsync_pulse &= ~0x40;
+ else
+ hvsync_pulse |= 0x40;
+ if (gv->disp_flags & GRF_FLAGS_PVSYNC)
+ hvsync_pulse &= ~0x80;
+ else
+ hvsync_pulse |= 0x80;
- vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3 | ((num0 & 3) << 2));
+ vgaw(ba, GREG_MISC_OUTPUT_W, hvsync_pulse | ((num0 & 3) << 2));
WCrt(ba, CRT_ID_6845_COMPAT, (num0 & 4) ? 0x0a : 0x08);
- seq=RSeq(ba, SEQ_ID_CLOCKING_MODE);
+ seq = RSeq(ba, SEQ_ID_CLOCKING_MODE);
switch(denom0) {
- case 0:
+ case 0:
WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xb4);
WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7);
break;
- case 1:
+ case 1:
WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf4);
WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7);
break;
- case 2:
+ case 2:
WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf5);
WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7);
break;
- case 3:
+ case 3:
WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf5);
WSeq(ba, SEQ_ID_CLOCKING_MODE, seq | 0x08);
break;
- }
+ }
+
/* load display parameters into board */
-
WCrt(ba, CRT_ID_HOR_TOTAL, HT);
WCrt(ba, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? HBS - 1 : HDE));
WCrt(ba, CRT_ID_START_HOR_BLANK, HBS);
- WCrt(ba, CRT_ID_END_HOR_BLANK, (HBE & 0x1f) | 0x80); /* | 0x80? */
+ WCrt(ba, CRT_ID_END_HOR_BLANK, (HBE & 0x1f) | 0x80);
WCrt(ba, CRT_ID_START_HOR_RETR, HSS);
WCrt(ba, CRT_ID_END_HOR_RETR,
(HSE & 0x1f) |
@@ -1163,8 +1259,8 @@ et_load_mon(gp, md)
((VSS & 0x200) ? 0x80 : 0x00));
WCrt(ba, CRT_ID_MAX_ROW_ADDRESS,
- 0x40 | /* TEXT ? 0x00 ??? */
- (DBLSCAN ? 0x80 : 0x00) |
+ 0x40 | /* splitscreen not visible */
+ ((gv->disp_flags & GRF_FLAGS_DBLSCAN) ? 0x80 : 0x00) |
((VBS & 0x200) ? 0x20 : 0x00) |
(TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
@@ -1172,7 +1268,6 @@ et_load_mon(gp, md)
((TEXT || (gv->depth == 1)) ? 0xc3 : 0xab));
/* text cursor */
-
if (TEXT) {
#if ET_ULCURSOR
WCrt(ba, CRT_ID_CURSOR_START, (md->fy & 0x1f) - 2);
@@ -1205,7 +1300,7 @@ et_load_mon(gp, md)
((VDE & 0x400) ? 0x04 : 0x00) |
((VSS & 0x400) ? 0x08 : 0x00) |
0x10 |
- (LACE ? 0x80 : 0x00));
+ ((gv->disp_flags & GRF_FLAGS_LACE) ? 0x80 : 0x00));
WCrt(ba, CRT_ID_HOR_OVERFLOW,
((HT & 0x100) ? 0x01 : 0x00) |
@@ -1225,90 +1320,100 @@ et_load_mon(gp, md)
vgar(ba, VDAC_MASK);
vgar(ba, VDAC_MASK);
switch (gv->depth) {
- case 1:
- case 4: /* text */
+ case 1:
+ case 4: /* text */
switch(etdtype) {
- case SIERRA11483:
- case SIERRA15025:
- case MUSICDAC:
+ case SIERRA11483:
+ case SIERRA15025:
+ case MUSICDAC:
vgaw(ba, VDAC_MASK, 0);
break;
- case MERLINDAC:
+ case ATT20C491:
+ vgaw(ba, VDAC_MASK, 0x02);
+ break;
+ case MERLINDAC:
setMerlinDACmode(ba, 0);
break;
}
HDE = gv->disp_width / 16;
break;
- case 8:
+ case 8:
switch(etdtype) {
- case SIERRA11483:
- case SIERRA15025:
- case MUSICDAC:
+ case SIERRA11483:
+ case SIERRA15025:
+ case MUSICDAC:
vgaw(ba, VDAC_MASK, 0);
break;
- case MERLINDAC:
+ case ATT20C491:
+ vgaw(ba, VDAC_MASK, 0x02);
+ break;
+ case MERLINDAC:
setMerlinDACmode(ba, 0);
break;
}
HDE = gv->disp_width / 8;
break;
- case 15:
+ case 15:
switch(etdtype) {
- case SIERRA11483:
- case SIERRA15025:
- case MUSICDAC:
+ case SIERRA11483:
+ case SIERRA15025:
+ case MUSICDAC:
+ case ATT20C491:
vgaw(ba, VDAC_MASK, 0xa0);
break;
- case MERLINDAC:
+ case MERLINDAC:
setMerlinDACmode(ba, 0xa0);
break;
}
HDE = gv->disp_width / 4;
break;
- case 16:
+ case 16:
switch(etdtype) {
- case SIERRA11483:
+ case SIERRA11483:
vgaw(ba, VDAC_MASK, 0); /* illegal mode! */
break;
- case SIERRA15025:
+ case SIERRA15025:
vgaw(ba, VDAC_MASK, 0xe0);
break;
- case MUSICDAC:
+ case MUSICDAC:
+ case ATT20C491:
vgaw(ba, VDAC_MASK, 0xc0);
break;
- case MERLINDAC:
+ case MERLINDAC:
setMerlinDACmode(ba, 0xe0);
break;
}
HDE = gv->disp_width / 4;
break;
- case 24:
+ case 24:
switch(etdtype) {
- case SIERRA11483:
+ case SIERRA11483:
vgaw(ba, VDAC_MASK, 0); /* illegal mode! */
break;
- case SIERRA15025:
+ case SIERRA15025:
vgaw(ba, VDAC_MASK, 0xe1);
break;
- case MUSICDAC:
+ case MUSICDAC:
+ case ATT20C491:
vgaw(ba, VDAC_MASK, 0xe0);
break;
- case MERLINDAC:
+ case MERLINDAC:
setMerlinDACmode(ba, 0xf0);
break;
}
HDE = (gv->disp_width / 8) * 3;
break;
- case 32:
+ case 32:
switch(etdtype) {
- case SIERRA11483:
- case MUSICDAC:
+ case SIERRA11483:
+ case MUSICDAC:
+ case ATT20C491:
vgaw(ba, VDAC_MASK, 0); /* illegal mode! */
break;
- case SIERRA15025:
+ case SIERRA15025:
vgaw(ba, VDAC_MASK, 0x61);
break;
- case MERLINDAC:
+ case MERLINDAC:
setMerlinDACmode(ba, 0xb0);
break;
}
@@ -1320,6 +1425,9 @@ et_load_mon(gp, md)
(gv->depth == 1) ? 0x01 : 0x0f);
WCrt(ba, CRT_ID_OFFSET, HDE);
+ vgaw(ba, CRT_ADDRESS, CRT_ID_HOR_OVERFLOW);
+ vgaw(ba, CRT_ADDRESS_W,
+ (vgar(ba, CRT_ADDRESS_R) & 0x7f) | ((HDE & 0x100) ? 0x80: 0x00));
/* text initialization */
if (TEXT) {
@@ -1370,16 +1478,15 @@ et_inittextmode(gp)
c = (unsigned char *) (fb) + (tm->cols - 16);
strcpy(c, "TSENG");
- c[6] = 0x20;
+ c[5] = 0x20;
/* set colors (B&W) */
-
switch(ettype) {
case MERLIN:
vgaw(ba, MERLIN_VDAC_INDEX, 0);
for (z = 0; z < 256; z++) {
y = (z & 1) ? ((z > 7) ? 2 : 1) : 0;
-
+
vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][0]);
vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][1]);
vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][2]);
@@ -1389,7 +1496,7 @@ et_inittextmode(gp)
vgaw(ba, VDAC_ADDRESS_W, 0);
for (z = 0; z < 256; z++) {
y = (z & 1) ? ((z > 7) ? 2 : 1) : 0;
-
+
vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
etconscolors[y][0] >> etcmap_shift);
vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
@@ -1413,7 +1520,7 @@ et_memset(d, c, l)
}
-static int
+int
et_getControllerType(gp)
struct grf_softc * gp;
{
@@ -1424,7 +1531,12 @@ et_getControllerType(gp)
*mem = 0;
/* make ACL visible */
- WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xfb);
+ if (ettype == MERLIN) {
+ WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xbb);
+ } else {
+ WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xfb);
+ }
+
WIma(ba, IMA_PORTCONTROL, 0x01);
*((unsigned long *)mmu) = 0;
@@ -1434,13 +1546,17 @@ et_getControllerType(gp)
/* hide ACL */
WIma(ba, IMA_PORTCONTROL, 0x00);
- WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xd3);
- return((*mem == 0xff) ? ETW32 : ET4000);
+ if (ettype == MERLIN) {
+ WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0x93);
+ } else {
+ WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xd3);
+ }
+ return ((*mem == 0xff) ? ETW32 : ET4000);
}
-static int
+int
et_getDACType(gp)
struct grf_softc * gp;
{
@@ -1497,7 +1613,27 @@ et_getDACType(gp)
vgaw(ba, VDAC_MASK, 0xff);
return (MUSICDAC);
-}
+ }
+
+ /* check for AT&T ATT20c491 DAC (crest) */
+ if (vgar(ba, HDR)); if (vgar(ba, HDR));
+ if (vgar(ba, HDR)); if (vgar(ba, HDR));
+ vgaw(ba, HDR, 0xff);
+ vgaw(ba, VDAC_MASK, 0x01);
+ if (vgar(ba, HDR)); if (vgar(ba, HDR));
+ if (vgar(ba, HDR)); if (vgar(ba, HDR));
+ if (vgar(ba, HDR) == 0xff) {
+ /* do not shift color values */
+ etcmap_shift = 0;
+
+ vgaw(ba, VDAC_MASK, 0xff);
+ return (ATT20C491);
+ }
+
+ /* restore PowerUp settings (crest) */
+ if (vgar(ba, HDR)); if (vgar(ba, HDR));
+ if (vgar(ba, HDR)); if (vgar(ba, HDR));
+ vgaw(ba, HDR, 0x00);
/*
* nothing else found, so let us pretend it is a stupid
@@ -1508,7 +1644,7 @@ et_getDACType(gp)
etcmap_shift = 2;
vgaw(ba, VDAC_MASK, 0xff);
- return(SIERRA11483);
+ return (SIERRA11483);
}
#endif /* NGRFET */
diff --git a/sys/arch/amiga/dev/grf_etreg.h b/sys/arch/amiga/dev/grf_etreg.h
index a5b3832b7cb..e98b886100f 100644
--- a/sys/arch/amiga/dev/grf_etreg.h
+++ b/sys/arch/amiga/dev/grf_etreg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: grf_etreg.h,v 1.3 1997/01/16 09:24:17 niklas Exp $ */
-/* $NetBSD: grf_etreg.h,v 1.2 1996/06/09 13:21:11 veego Exp $ */
+/* $OpenBSD: grf_etreg.h,v 1.4 1997/09/18 13:39:51 niklas Exp $ */
+/* $NetBSD: grf_etreg.h,v 1.4 1997/07/29 17:42:06 veego Exp $ */
/*
* Copyright (c) 1996 Tobias Abt
@@ -78,6 +78,7 @@ struct grfettext_mode {
#define SIERRA15025 1 /* Sierra 15025 TrueColor DAC */
#define MUSICDAC 2 /* MUSIC TrueColor DAC */
#define MERLINDAC 3 /* Merlin's BrookTree TrueColor DAC */
+#define ATT20C491 4 /* AT&T 20c491 TrueColor DAC */
/* read VGA register */
#define vgar(ba, reg) (*(((volatile unsigned char *)ba)+reg))
@@ -112,6 +113,7 @@ struct grfettext_mode {
#define GREG_COLORSELECT 0x03D9
#define GREG_ATNTMODECONTROL 0x03DE
#define GREG_SEGMENTSELECT 0x03CD
+#define GREG_SEGMENTSELECT2 0x03CB
/* ETW32 special */
#define W32mappedRegs 0xfff00
@@ -216,7 +218,7 @@ struct grfettext_mode {
#define CRT_ID_SEGMENT_COMP 0x30
#define CRT_ID_GENERAL_PURPOSE 0x31
#define CRT_ID_RASCAS_CONFIG 0x32
-#define CTR_ID_EXT_START 0x33
+#define CRT_ID_EXT_START 0x33
#define CRT_ID_6845_COMPAT 0x34
#define CRT_ID_OVERFLOW_HIGH 0x35
#define CRT_ID_VIDEO_CONFIG1 0x36
diff --git a/sys/arch/amiga/dev/grf_rh.c b/sys/arch/amiga/dev/grf_rh.c
index 0bd1839facb..a94c31ec102 100644
--- a/sys/arch/amiga/dev/grf_rh.c
+++ b/sys/arch/amiga/dev/grf_rh.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: grf_rh.c,v 1.12 1997/01/16 09:24:18 niklas Exp $ */
-/* $NetBSD: grf_rh.c,v 1.26 1996/12/31 17:54:28 is Exp $ */
+/* $OpenBSD: grf_rh.c,v 1.13 1997/09/18 13:39:52 niklas Exp $ */
+/* $NetBSD: grf_rh.c,v 1.27 1997/07/29 17:52:05 veego Exp $ */
/*
* Copyright (c) 1994 Markus Wild
@@ -1637,6 +1637,7 @@ rh_getvmode(gp, vm)
struct grfvideo_mode *vm;
{
struct MonDef *md;
+ int vmul;
if (vm->mode_num && vm->mode_num > rh_mon_max)
return(EINVAL);
@@ -1668,25 +1669,34 @@ rh_getvmode(gp, vm)
* - Ignatios Souvatzis
*/
- if (md->DEP == 4) {
+ if (md->DEP != 4) {
vm->hblank_start = md->HBS * 32 / md->DEP;
- vm->hblank_stop = md->HBE * 32 / md->DEP;
vm->hsync_start = md->HSS * 32 / md->DEP;
vm->hsync_stop = md->HSE * 32 / md->DEP;
vm->htotal = md->HT * 32 / md->DEP;
} else {
vm->hblank_start = md->HBS * md->FX;
- vm->hblank_stop = md->HBE * md->FX;
vm->hsync_start = md->HSS * md->FX;
vm->hsync_stop = md->HSE * md->FX;
vm->htotal = md->HT * md->FX;
}
- vm->vblank_start = md->VBS;
- vm->vblank_stop = md->VBE;
- vm->vsync_start = md->VSS;
- vm->vsync_stop = md->VSE;
- vm->vtotal = md->VT;
+ /* XXX move vm->disp_flags and vmul to rh_load_mon
+ * if rh_setvmode can add new modes with grfconfig */
+ vm->disp_flags = 0;
+ vmul = 2;
+ if (md->FLG & MDF_DBL) {
+ vm->disp_flags |= GRF_FLAGS_DBLSCAN;
+ vmul = 4;
+ }
+ if (md->FLG & MDF_LACE) {
+ vm->disp_flags |= GRF_FLAGS_LACE;
+ vmul = 1;
+ }
+ vm->vblank_start = md->VBS * vmul / 2;
+ vm->vsync_start = md->VSS * vmul / 2;
+ vm->vsync_stop = md->VSE * vmul / 2;
+ vm->vtotal = md->VT * vmul / 2;
return(0);
}
diff --git a/sys/arch/amiga/dev/grf_rhreg.h b/sys/arch/amiga/dev/grf_rhreg.h
index d4dd0d0526f..454b264fcdc 100644
--- a/sys/arch/amiga/dev/grf_rhreg.h
+++ b/sys/arch/amiga/dev/grf_rhreg.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: grf_rhreg.h,v 1.3 1996/05/29 10:15:13 niklas Exp $ */
-/* $NetBSD: grf_rhreg.h,v 1.7 1996/05/19 21:05:41 veego Exp $ */
+/* $OpenBSD: grf_rhreg.h,v 1.4 1997/09/18 13:39:52 niklas Exp $ */
+/* $NetBSD: grf_rhreg.h,v 1.8 1997/07/29 17:42:09 veego Exp $ */
/*
* Copyright (c) 1994 Markus Wild
@@ -653,22 +653,42 @@ struct MonDef {
vgaw(ba, PLL_ADDRESS_W, (val >> 8)); } while (0)
-static inline unsigned char RAttr(volatile void * ba, short idx) {
+static __inline unsigned char RAttr __P((volatile void *, short));
+static __inline unsigned char
+RAttr(ba, idx)
+ volatile void *ba;
+ short idx;
+{
vgaw (ba, ACT_ADDRESS, idx);
return vgar (ba, ACT_ADDRESS_R);
}
-static inline unsigned char RSeq(volatile void * ba, short idx) {
+static __inline unsigned char RSeq __P((volatile void *, short));
+static __inline unsigned char
+RSeq(ba, idx)
+ volatile void *ba;
+ short idx;
+{
vgaw (ba, SEQ_ADDRESS, idx);
return vgar (ba, SEQ_ADDRESS_R);
}
-static inline unsigned char RCrt(volatile void * ba, short idx) {
+static __inline unsigned char RCrt __P((volatile void *, short));
+static __inline unsigned char
+RCrt(ba, idx)
+ volatile void *ba;
+ short idx;
+{
vgaw (ba, CRT_ADDRESS, idx);
return vgar (ba, CRT_ADDRESS_R);
}
-static inline unsigned char RGfx(volatile void * ba, short idx) {
+static __inline unsigned char RGfx __P((volatile void *, short));
+static __inline unsigned char
+RGfx(ba, idx)
+ volatile void *ba;
+ short idx;
+{
vgaw(ba, GCT_ADDRESS, idx);
return vgar (ba, GCT_ADDRESS_R);
}
diff --git a/sys/arch/amiga/dev/grf_rt.c b/sys/arch/amiga/dev/grf_rt.c
index 17d9013be25..27ba8c7506f 100644
--- a/sys/arch/amiga/dev/grf_rt.c
+++ b/sys/arch/amiga/dev/grf_rt.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: grf_rt.c,v 1.10 1997/01/16 09:24:20 niklas Exp $ */
-/* $NetBSD: grf_rt.c,v 1.34 1996/12/23 09:10:09 veego Exp $ */
+/* $OpenBSD: grf_rt.c,v 1.11 1997/09/18 13:39:53 niklas Exp $ */
+/* $NetBSD: grf_rt.c,v 1.35 1997/07/29 17:52:09 veego Exp $ */
/*
* Copyright (c) 1993 Markus Wild
@@ -259,7 +259,7 @@ static struct MonDef *default_monitor = &DEFAULT_MONDEF;
#endif
int retina_alive __P((struct MonDef *));
-static int rt_load_mon __P((struct grf_softc *, struct MonDef *));
+int rt_load_mon __P((struct grf_softc *, struct MonDef *));
/*
@@ -284,7 +284,7 @@ retina_alive(mdp)
return(0);
}
-static int
+int
rt_load_mon(gp, md)
struct grf_softc *gp;
struct MonDef *md;
@@ -769,8 +769,8 @@ int grfrtprint __P((void *, const char *));
int grfrtmatch __P((struct device *, void *, void *));
int rt_mode __P((struct grf_softc *, u_long, void *, u_long, int));
-static int rt_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
-static int rt_setvmode __P((struct grf_softc *, unsigned, int));
+int rt_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
+int rt_setvmode __P((struct grf_softc *, unsigned, int));
int rt_getspritepos __P((struct grf_softc *, struct grf_position *));
int rt_setspritepos __P((struct grf_softc *, struct grf_position *));
int rt_getspriteinfo __P((struct grf_softc *, struct grf_spriteinfo *));
@@ -900,12 +900,13 @@ grfrtprint(auxp, pnp)
return(UNCONF);
}
-static int
+int
rt_getvmode (gp, vm)
struct grf_softc *gp;
struct grfvideo_mode *vm;
{
struct MonDef *md;
+ int vmul;
if (vm->mode_num && vm->mode_num > retina_mon_max)
return (EINVAL);
@@ -925,41 +926,51 @@ rt_getvmode (gp, vm)
* From observation of the monitor definition table above, I guess that
* the horizontal timings are in units of longwords. Hence, I get the
* pixels by multiplication with 32 and division by the depth.
- * The text modes, apparently marked by depth == 4, are even more wierd.
- * According to a comment above, they are computed from a depth==8 mode
- * (thats for us: * 32 / 8) by applying another factor of 4 / font width.
- * Reverse applying the latter formula most of the constants cancel
- * themselves and we are left with a nice (* font width).
- * That is, internal timings are in units of longwords for graphics
- * modes, or in units of characters widths for text modes.
+ * The text modes, apparently marked by depth == 4, are even more
+ * wierd. According to a comment above, they are computed from a
+ * depth==8 mode (thats for us: * 32 / 8) by applying another factor of
+ * 4 / font width. Reverse applying the latter formula most of the
+ * constants cancel themselves and we are left with a nice (* font
+ * width). That is, internal timings are in units of longwords for
+ * graphics modes, or in units of characters widths for text modes.
* We better don't WRITE modes until this has been real live checked.
* - Ignatios Souvatzis
*/
- if (md->DEP == 4) {
+ if (md->DEP != 4) {
vm->hblank_start = md->HBS * 32 / md->DEP;
- vm->hblank_stop = md->HBE * 32 / md->DEP;
vm->hsync_start = md->HSS * 32 / md->DEP;
vm->hsync_stop = md->HSE * 32 / md->DEP;
vm->htotal = md->HT * 32 / md->DEP;
} else {
vm->hblank_start = md->HBS * md->FX;
- vm->hblank_stop = md->HBE * md->FX;
vm->hsync_start = md->HSS * md->FX;
vm->hsync_stop = md->HSE * md->FX;
vm->htotal = md->HT * md->FX;
}
- vm->vblank_start = md->VBS;
- vm->vblank_stop = md->VBE;
- vm->vsync_start = md->VSS;
- vm->vsync_stop = md->VSE;
- vm->vtotal = md->VT;
+
+ /* XXX move vm->disp_flags and vmul to rt_load_mon
+ * if rt_setvmode can add new modes with grfconfig */
+ vm->disp_flags = 0;
+ vmul = 2;
+ if (md->FLG & MDF_DBL) {
+ vm->disp_flags |= GRF_FLAGS_DBLSCAN;
+ vmul = 4;
+ }
+ if (md->FLG & MDF_LACE) {
+ vm->disp_flags |= GRF_FLAGS_LACE;
+ vmul = 1;
+ }
+ vm->vblank_start = md->VBS * vmul / 2;
+ vm->vsync_start = md->VSS * vmul / 2;
+ vm->vsync_stop = md->VSE * vmul / 2;
+ vm->vtotal = md->VT * vmul / 2;
return (0);
}
-static int
+int
rt_setvmode (gp, mode, txtonly)
struct grf_softc *gp;
unsigned mode;
diff --git a/sys/arch/amiga/dev/grf_ul.c b/sys/arch/amiga/dev/grf_ul.c
index 54ec3261e16..42491fb5afb 100644
--- a/sys/arch/amiga/dev/grf_ul.c
+++ b/sys/arch/amiga/dev/grf_ul.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: grf_ul.c,v 1.12 1997/01/16 09:24:21 niklas Exp $ */
-/* $NetBSD: grf_ul.c,v 1.23 1996/12/23 09:10:10 veego Exp $ */
+/* $OpenBSD: grf_ul.c,v 1.13 1997/09/18 13:39:54 niklas Exp $ */
+/* $NetBSD: grf_ul.c,v 1.24 1997/07/29 17:50:01 veego Exp $ */
#define UL_DEBUG
@@ -91,48 +91,45 @@ u_int8_t ul_ovl_palette[] = {
struct grfvideo_mode ul_monitor_defs[] = {
/*
- * Horizontal values are given in TMS units, that is, for the
- * A2410 board, units of 16 pixels. The ioctl multiplies (when
- * exporting) or divides (when importing) them by 16 to conform to.
+ * We give all these values in MI units, that is:
+ * horizontal timings in units of pixels
+ * vertical timings in units of lines
+ * point of reference is blanking end.
*
- * XXX This used to be in units of 8 pixel times. We
- * must also change amiga/stand/grfconfig/grfconfig.c,
- * grf_{rt,rh,cl,cv}.c and egsgrfconfig (the latter to generate the
- * horizontal timings in units of pixels instead of 8 pixels.
- * You will also have to write warnings in BIG BOLD RED BLINKING
- * LETTERS all over the docs, and still people will fry their monitors.
+ * The ul_load_mon transforms these values right before loading
+ * them into the chip.
*
- * btw, the _totals are always sync_start+1, to compute the frequencies
- * correctly. (see TMS34010 manual)
+ * This leaves us with a single point where things are transformed,
+ * which should make life easier if we ever change things again.
*/
/* 1024x768, 60Hz */
- {1, "1024x768", 66667000, 1024, 768, 8,
- 82, 18, 86, 12, 87, 794, 26, 797, 2, 798},
+ { 1, "1024x768", 66667000, 1024, 768, 8,
+ 1024, 1008, 1296, 1392, 768, 771, 774, 798, 0 },
/* 864x648, 70Hz */
- {2, "864x648", 50000000, 864, 648, 8,
- 61, 7, 65, 3, 66, 667, 19, 677, 4, 678},
+ { 2, "864x648", 50000000, 864, 648, 8,
+ 864, 928, 992, 1056, 648, 658, 663, 678, 0 },
/* 800x600, 60Hz */
- {3, "800x600", 36000000, 800, 600, 8,
- 57, 7, 61, 3, 62, 619, 19, 629, 4, 630},
+ { 3, "800x600", 36000000, 800, 600, 8,
+ 800, 864, 928, 992, 600, 610, 615, 630, 0 },
- /* 640x400, 60 Hz, interlaced */
- {4, "640x400I", 14318000, 640, 400, 8,
- 48, 8, 56, 3, 57, 239, 39, 262, 2, 240},
+ /* 640x400, 60 Hz, interlaced */
+ { 4, "640x400i", 14318000, 640, 400, 8,
+ 640, 768, 832, 912, 200, 223, 203, 240, 1 },
- /* 1024x768, 65Hz interlaced, s.th. is strange */
- {5, "1024x768?I", 44980000, 1024, 768, 8,
- 76, 12, 79, 3, 80, 512, 24, 533, 2, 534},
+ /* 1024x768, 65Hz interlaced, s.th. is strange */
+ { 5, "1024x768?i", 44980000, 1024, 768, 8,
+ 1024, 1072, 1136, 1280, 488, 509, 512, 534, 1 },
- /* 1024x1024, 60Hz */
- {6, "1024x1024", 80000000, 1024,1024, 8,
- 77, 13, 78, 5, 78,1051, 27,1054, 2,1055},
+ /* 1024x1024, 60Hz */
+ { 6, "1024x1024", 80000000, 1024, 1024, 8,
+ 1024, 1040, 1120, 1248, 1024, 1027, 1030, 1055, 0 },
- /* 736x480, 60 Hz */
- {7, "736x480", 28636300, 736, 480, 8,
- 54, 8, 57, 3, 58, 503, 23, 514, 3, 515},
+ /* 736x480, 60 Hz */
+ { 7, "736x480", 28636300, 736, 480, 8,
+ 736, 784, 848, 928, 480, 491, 495, 515, 0 },
};
int ulowell_mon_max = sizeof (ul_monitor_defs)/sizeof (ul_monitor_defs[0]);
@@ -391,14 +388,16 @@ ul_load_mon(gp, md)
ba->hstadrh = 0xC000;
ba->hstadrl = 0x0000;
- ba->data = md->hsync_stop;
- ba->data = md->hblank_stop;
- ba->data = md->hblank_start;
- ba->data = md->hsync_start;
- ba->data = md->vsync_stop;
- ba->data = md->vblank_stop;
- ba->data = md->vblank_start;
- ba->data = md->vsync_start;
+
+ ba->data = (md->hsync_stop - md->hsync_start)/16;
+ ba->data = (md->htotal - md->hsync_start)/16 - 1;
+ ba->data = (md->hblank_start + md->htotal - md->hsync_start)/16 - 1;
+ ba->data = md->htotal/16 - 1;
+
+ ba->data = md->vsync_stop - md->vsync_start;
+ ba->data = md->vtotal - md->vsync_start - 1;
+ ba->data = md->vblank_start + md->vtotal - md->vsync_start - 1;
+ ba->data = md->vtotal - 1;
ba->ctrl &= ~INCW;
ba->hstadrh = 0xFE90;
@@ -418,8 +417,7 @@ ul_load_mon(gp, md)
ba->ctrl |= LBL | INCW;
ba->hstadrh = 0xC000;
ba->hstadrl = 0x0080;
- ba->data = (md->vblank_start - md->vblank_stop == md->disp_height ?
- 0xf020 : 0xb020);
+ ba->data = md->disp_flags & GRF_FLAGS_LACE ? 0xb020 : 0xf020;
/* I guess this should be in the yet unimplemented mode select ioctl */
/* Hm.. maybe not. We always put the console on overlay plane no 0. */
@@ -604,18 +602,17 @@ ul_getvmode (gp, vm)
vm->disp_height = md->disp_height;
vm->depth = md->depth;
- vm->hblank_start = (md->hblank_start - md->hblank_stop) * 16;
- vm->hblank_stop = (md->htotal - 1) * 16;
- vm->hsync_start = (md->hsync_start - md->hblank_stop) * 16;
- vm->hsync_stop = (md->hsync_stop + md->htotal - md->hblank_stop) * 16;
- vm->htotal = md->htotal * 16;
+ vm->hblank_start = md->hblank_start;
+ vm->hsync_start = md->hsync_start;
+ vm->hsync_stop = md->hsync_stop;
+ vm->htotal = md->htotal;
- vm->vblank_start = md->vblank_start - md->vblank_stop;
- vm->vblank_stop = md->vtotal - 1;
- vm->vsync_start = md->vsync_start - md->vblank_stop;
- vm->vsync_stop = md->vsync_stop + md->vtotal - md->vblank_stop;
+ vm->vblank_start = md->vblank_start;
+ vm->vsync_start = md->vsync_start;
+ vm->vsync_stop = md->vsync_stop;
vm->vtotal = md->vtotal;
+ vm->disp_flags = md->disp_flags;
return 0;
}
diff --git a/sys/arch/amiga/dev/if_ae.c b/sys/arch/amiga/dev/if_ae.c
deleted file mode 100644
index 893ab0d478d..00000000000
--- a/sys/arch/amiga/dev/if_ae.c
+++ /dev/null
@@ -1,1141 +0,0 @@
-/* $OpenBSD: if_ae.c,v 1.9 1997/01/16 09:24:35 niklas Exp $ */
-/* $NetBSD: if_ae.c,v 1.12 1996/12/23 09:10:13 veego Exp $ */
-
-/*
- * Copyright (c) 1995 Bernd Ernesti and Klaus Burkert. All rights reserved.
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell and Rick Macklem.
- *
- * 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 Bernd Ernesti, by Klaus
- * Burkert, by Michael van Elst, and 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.
- *
- * @(#)if_le.c 8.1 (Berkeley) 6/10/93
- *
- * This is based on the original LANCE files, as the PCnet-ISA used on
- * the Ariadne is a LANCE-descendant optimized for the PC-ISA bus.
- * This causes some modifications, all data that is to go into registers
- * or to structures (buffer-descriptors, init-block) has to be
- * byte-swapped. In addition ALL write accesses to the board have to be
- * WORD or LONG, BYTE-access is prohibited!!
- */
-
-#include "ae.h"
-#if NAE > 0
-
-#include "bpfilter.h"
-
-/*
- * AMD 79C960 PCnet-ISA
- *
- * This driver will generate and accept tailer encapsulated packets even
- * though it buys us nothing. The motivation was to avoid incompatibilities
- * with VAXen, SUNs, and others that handle and benefit from them.
- * This reasoning is dubious.
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/buf.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/syslog.h>
-#include <sys/ioctl.h>
-#include <sys/errno.h>
-#include <sys/device.h>
-
-#include <net/if.h>
-#include <net/netisr.h>
-#include <net/route.h>
-
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#endif
-
-#ifdef NS
-#include <netns/ns.h>
-#include <netns/ns_if.h>
-#endif
-
-#if defined(CCITT) && defined(LLC)
-#include <sys/socketvar.h>
-#include <netccitt/x25.h>
-#include <net/if_dl.h>
-#include <net/if_llc.h>
-#include <netccitt/dll.h>
-#include <netccitt/llc_var.h>
-#include <netccitt/pk.h>
-#include <netccitt/pk_var.h>
-#include <netccitt/pk_extern.h>
-#endif
-
-#if NBPFILTER > 0
-#include <net/bpf.h>
-#include <net/bpfdesc.h>
-#endif
-
-#include <machine/cpu.h>
-#include <machine/mtpr.h>
-#include <amiga/amiga/device.h>
-#include <amiga/amiga/isr.h>
-#include <amiga/dev/zbusvar.h>
-#include <amiga/dev/if_aereg.h>
-
-/*
- * Ethernet software status per interface.
- *
- * Each interface is referenced by a network interface structure,
- * ae_if, which the routing code uses to locate the interface.
- * This structure contains the output queue for the interface, its address, ...
- */
-struct ae_softc {
- struct device sc_dev;
- struct isr sc_isr;
- struct arpcom sc_arpcom; /* common Ethernet structures */
- void *sc_base; /* base address of board */
- struct aereg1 *sc_r1; /* LANCE registers */
- struct aereg2 *sc_r2; /* dual-port RAM */
- int sc_rmd; /* predicted next rmd to process */
- int sc_tmd; /* next tmd to use */
- int sc_no_td; /* number of tmds in use */
-} ae_softc[NAE];
-
-/* offsets for: ID, REGS, MEM */
-int aestd[] = { 0, 0x0370, 0x8000 };
-static u_int16_t revision;
-
-int aematch __P((struct device *, void *, void *));
-void aeattach __P((struct device *, struct device *, void *));
-void aewatchdog __P((struct ifnet *));
-void aestop __P((struct ae_softc *));
-void aememinit __P((struct ae_softc *));
-void aereset __P((struct ae_softc *));
-void aeinit __P((struct ae_softc *));
-void aestart __P((struct ifnet *));
-int aeintr __P((void *));
-void aetint __P((struct ae_softc *));
-void aerint __P((struct ae_softc *));
-void aeread __P((struct ae_softc *, u_char *, int));
-static void wcopyfrom __P((char *, char *, int));
-static void wcopyto __P((char *, char *, int));
-static void wzero __P((char *, int));
-int aeput __P((char *, struct mbuf *));
-struct mbuf *aeget __P((struct ae_softc *, u_char *, int));
-int aeioctl __P((struct ifnet *, u_long, caddr_t));
-void aesetladrf __P((struct arpcom *, u_int16_t *));
-
-struct cfattach ae_ca = {
- sizeof(struct ae_softc), aematch, aeattach
-};
-
-struct cfdriver ae_cd = {
- NULL, "ae", DV_IFNET
-};
-
-int
-aematch(parent, match, aux)
- struct device *parent;
- void *match, *aux;
-{
- struct zbus_args *zap;
-
- zap = (struct zbus_args *)aux;
-
- /* Ariadne ethernet card */
- if (zap->manid == 2167 && zap->prodid == 201)
- return (1);
-
- return (0);
-}
-
-/*
- * Interface exists: make available by filling in network interface
- * record. System will initialize the interface when it is ready
- * to accept packets.
- */
-void
-aeattach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
- register struct aereg2 *aer2;
- struct zbus_args *zap;
- struct ae_softc *sc = (void *)self;
- struct ifnet *ifp = &sc->sc_arpcom.ac_if;
- unsigned long ser;
- int s = splhigh ();
-
- zap =(struct zbus_args *)aux;
-
- /*
- * Make config msgs look nicer.
- */
- printf("\n");
-
- sc->sc_base = zap->va;
- sc->sc_r1 = (struct aereg1 *)(aestd[1] + (int)zap->va);
- aer2 = sc->sc_r2 = (struct aereg2 *)(aestd[2] + (int)zap->va);
-
- /*
- * Serial number for board is used as host ID.
- */
- ser = (unsigned long) zap->serno;
-
- /*
- * Manufacturer decides the 3 first bytes, i.e. ethernet vendor ID.
- */
-
- sc->sc_arpcom.ac_enaddr[0] = 0x00;
- sc->sc_arpcom.ac_enaddr[1] = 0x60;
- sc->sc_arpcom.ac_enaddr[2] = 0x30;
-
- sc->sc_arpcom.ac_enaddr[3] = (ser >> 16) & 0xff;
- sc->sc_arpcom.ac_enaddr[4] = (ser >> 8) & 0xff;
- sc->sc_arpcom.ac_enaddr[5] = ser & 0xff;
-
- printf("%s: hardware address %s 32K", sc->sc_dev.dv_xname,
- ether_sprintf(sc->sc_arpcom.ac_enaddr));
-
- aestop(sc);
- delay(100);
-
- /* get the chip version of the lance chip */
- sc->sc_r1->aer1_rap = 0x5900;
- revision = ((sc->sc_r1->aer1_rdp >> 4) -2);
- printf(" chip-revision: B%x\n", revision);
-
- splx (s);
-
- bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
- ifp->if_softc = sc;
- ifp->if_ioctl = aeioctl;
- ifp->if_watchdog = aewatchdog;
- ifp->if_output = ether_output;
- ifp->if_start = aestart;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
-
- if_attach(ifp);
- ether_ifattach(ifp);
-
-#if NBPFILTER > 0
- bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
-#endif
-
- sc->sc_isr.isr_intr = aeintr;
- sc->sc_isr.isr_arg = sc;
- sc->sc_isr.isr_ipl = 2;
- add_isr (&sc->sc_isr);
- return;
-}
-
-void
-aewatchdog(ifp)
- struct ifnet *ifp;
-{
- struct ae_softc *sc = ifp->if_softc;
-
- log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
- ++sc->sc_arpcom.ac_if.if_oerrors;
-
- aereset(sc);
-}
-
-void
-aestop(sc)
- struct ae_softc *sc;
-{
- sc->sc_r1->aer1_rap = AE_CSR0;
- sc->sc_r1->aer1_rdp = AE_STOP;
-}
-
-
-/*
- * Set up the initialization block and the descriptor rings.
- */
-void
-aememinit(sc)
- register struct ae_softc *sc;
-{
-#if NBPFILTER > 0
- register struct ifnet *ifp = &sc->sc_arpcom.ac_if;
-#endif
- /*
- * This structure is referenced from the CARD's/PCnet-ISA's point
- * of view, thus the 0x8000 address which is the buffer RAM area
- * of the Ariadne card. This pointer is manipulated
- * with the PCnet-ISA's view of memory and NOT the Amiga's. FYI.
- */
- register struct aereg2 *aemem = (struct aereg2 *) 0x8000;
- register struct aereg2 *aer2 = sc->sc_r2;
- register int i;
-
-
-#if NBPFILTER > 0
- if (ifp->if_flags & IFF_PROMISC)
- /* set the promiscuous bit */
- aer2->aer2_mode = AE_MODE | AE_PROM;
- else
-#endif
- aer2->aer2_mode = AE_MODE;
- /* you know: no BYTE access.... */
- aer2->aer2_padr[0] =
- (sc->sc_arpcom.ac_enaddr[0] << 8) | sc->sc_arpcom.ac_enaddr[1];
- aer2->aer2_padr[1] =
- (sc->sc_arpcom.ac_enaddr[2] << 8) | sc->sc_arpcom.ac_enaddr[3];
- aer2->aer2_padr[2] =
- (sc->sc_arpcom.ac_enaddr[4] << 8) | sc->sc_arpcom.ac_enaddr[5];
- aesetladrf(&sc->sc_arpcom, aer2->aer2_ladrf);
-
- sc->sc_no_td = sc->sc_tmd = sc->sc_rmd = 0;
-
- aer2->aer2_rlen = SWAP(AE_RLEN);
- aer2->aer2_rdra = SWAP((int)aemem->aer2_rmd);
- aer2->aer2_tlen = SWAP(AE_TLEN);
- aer2->aer2_tdra = SWAP((int)aemem->aer2_tmd);
-
- for (i = 0; i < AERBUF; i++) {
- aer2->aer2_rmd[i].rmd0 = SWAP((int)aemem->aer2_rbuf[i]);
- aer2->aer2_rmd[i].rmd1 = AE_OWN;
- aer2->aer2_rmd[i].rmd2 = SWAP(-ETHER_MAX_LEN);
- aer2->aer2_rmd[i].rmd3 = 0;
- }
-
- for (i = 0; i < AETBUF; i++) {
- aer2->aer2_tmd[i].tmd0 = SWAP((int)aemem->aer2_tbuf[i]);
- aer2->aer2_tmd[i].tmd1 = 0;
- aer2->aer2_tmd[i].tmd2 = 0;
- aer2->aer2_tmd[i].tmd3 = 0;
- }
-}
-
-void
-aereset(sc)
- struct ae_softc *sc;
-{
- int s;
-
- s = splnet();
- aeinit(sc);
- splx(s);
-}
-
-/*
- * Initialization of interface; set up initialization block
- * and transmit/receive descriptor rings.
- */
-void
-aeinit(sc)
- struct ae_softc *sc;
-{
- register struct aereg1 *aer1 = sc->sc_r1;
- register struct ifnet *ifp = &sc->sc_arpcom.ac_if;
- register struct aereg2 *aemem = (struct aereg2 *) 0x8000;
-
- register int timo = 0;
- volatile int dummy;
-
- aestop(sc);
- delay(100);
-
- dummy = aer1->aer1_reset; /* Reset PCNet-ISA */
-
- aememinit(sc);
-
- /* Give LANCE the physical address of its init block. */
- aer1->aer1_rap = AE_CSR1;
- aer1->aer1_rdp = SWAP((int)&aemem->aer2_mode);
- aer1->aer1_rap = AE_CSR2;
- aer1->aer1_rdp = 0;
-
-/*
- * re-program LEDs to match meaning used on the Ariadne board
- */
- aer1->aer1_rap = 0x0500;
- aer1->aer1_idp = 0x9000;
- aer1->aer1_rap = 0x0600;
- aer1->aer1_idp = 0x8100;
- aer1->aer1_rap = 0x0700;
- aer1->aer1_idp = 0x8400;
-
-/*
- * you can `ifconfig (link0|-link0) ae0' to get the following
- * behaviour:
- * -link0 enable autoselect between 10Base-T (UTP) and 10Base2 (BNC)
- * if an active 10Base-T line is connected then 10Base-T
- * is used otherwise 10Base2.
- * this is the default behaviour, so there is no need to set
- * -link0 when you want autoselect.
- * link0 -link1 disable autoselect. enable BNC.
- * link0 link1 disable autoselect. enable UTP.
- */
- if (!(ifp->if_flags & IFF_LINK0)) {
- /* enable autoselect */
- aer1->aer1_rap = 0x0200;
- aer1->aer1_idp = 0x0200;
- } else {
- /* disable autoselect */
- aer1->aer1_rap = 0x0200;
- aer1->aer1_idp = 0x0000;
- if (!(ifp->if_flags & IFF_LINK1)) {
- /* enable BNC */
- sc->sc_r2->aer2_mode = 0x0000;
- } else {
- /* enable UTP */
- sc->sc_r2->aer2_mode = 0x8000;
- }
- }
-
- /* Try to initialize the LANCE. */
- delay(100);
- aer1->aer1_rap = AE_CSR0;
- aer1->aer1_rdp = AE_INIT;
-
- /* Wait for initialization to finish. */
- do {
- if (++timo == 10000) {
- printf("%s: card failed to initialize\n", sc->sc_dev.dv_xname);
- break;
- }
- } while ((aer1->aer1_rdp & AE_IDON) == 0);
-
- /* Start the LANCE. */
- aer1->aer1_rap = AE_CSR0;
- aer1->aer1_rdp = AE_STRT | AE_INEA | AE_IDON;
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
- ifp->if_timer = 0;
- aestart(ifp);
-}
-
-#define AENEXTTMP \
- if (++bix == AETBUF) bix = 0, tmd = sc->sc_r2->aer2_tmd; else ++tmd
-
-/*
- * Start output on interface. Get another datagram to send
- * off of the interface queue, and copy it to the interface
- * before starting the output.
- */
-void
-aestart(ifp)
- struct ifnet *ifp;
-{
- register struct ae_softc *sc = ifp->if_softc;
- register int bix;
- register struct aetmd *tmd;
- register struct mbuf *m;
- int len;
-
- if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
- return;
-
- bix = sc->sc_tmd;
- tmd = &sc->sc_r2->aer2_tmd[bix];
-
- for (;;) {
- if (sc->sc_no_td >= AETBUF) {
- ifp->if_flags |= IFF_OACTIVE;
- break;
- }
-
- IF_DEQUEUE(&ifp->if_snd, m);
- if (m == 0)
- break;
-
- ++sc->sc_no_td;
-
-#if NBPFILTER > 0
- if (ifp->if_bpf)
- bpf_mtap(ifp->if_bpf, m);
-#endif
-
- sc->sc_r1->aer1_rdp = AE_TINT | AE_INEA;
- len = aeput(sc->sc_r2->aer2_tbuf[bix], m);
-
-#ifdef AEDEBUG
- if (len > ETHER_MAX_LEN)
- printf("packet length %d\n", len);
-#endif
-
- ifp->if_timer = 5;
-
- tmd->tmd1 = AE_OWN | AE_STP | AE_ENP;
- tmd->tmd2 = SWAP(-len);
- tmd->tmd3 = 0;
-
- sc->sc_r1->aer1_rdp = AE_INEA | AE_TDMD;
-
- AENEXTTMP;
- }
-
- sc->sc_tmd = bix;
-}
-
-int
-aeintr(arg)
- void *arg;
-{
- register struct ae_softc *sc = arg;
- register struct aereg1 *aer1;
- register struct ifnet *ifp = &sc->sc_arpcom.ac_if;
- register u_int16_t stat;
-
- /* if not even initialized, don't do anything further.. */
- if (sc->sc_base == 0)
- return (0);
-
- aer1 = sc->sc_r1;
- stat = aer1->aer1_rdp;
-
- if ((stat & AE_INTR) == 0)
- return (0);
-
- aer1->aer1_rdp = (stat & (AE_INEA | AE_BABL | AE_MISS | AE_MERR |
- AE_RINT | AE_TINT | AE_IDON));
- if (stat & AE_SERR) {
- if (stat & AE_MERR) {
- printf("%s: memory error\n", sc->sc_dev.dv_xname);
- aereset(sc);
- return (1);
- }
- if (stat & AE_BABL) {
- printf("%s: babble\n", sc->sc_dev.dv_xname);
- ifp->if_oerrors++;
- }
-#if 0
- if (stat & AE_CERR) {
- printf("%s: collision error\n", sc->sc_dev.dv_xname);
- ifp->if_collisions++;
- }
-#endif
- if (stat & AE_MISS) {
- printf("%s: missed packet\n", sc->sc_dev.dv_xname);
- ifp->if_ierrors++;
- }
- aer1->aer1_rdp = AE_BABL | AE_CERR | AE_MISS | AE_INEA;
- }
- if ((stat & AE_RXON) == 0) {
- printf("%s: receiver disabled\n", sc->sc_dev.dv_xname);
- ifp->if_ierrors++;
- aereset(sc);
- return (1);
- }
- if ((stat & AE_TXON) == 0) {
- printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname);
- ifp->if_oerrors++;
- aereset(sc);
- return (1);
- }
- if (stat & AE_RINT) {
- /* Reset watchdog timer. */
- ifp->if_timer = 0;
- aerint(sc);
- }
- if (stat & AE_TINT) {
- /* Reset watchdog timer. */
- ifp->if_timer = 0;
- aetint(sc);
- }
-
- return (1);
-}
-
-/*
- * Ethernet interface transmitter interrupt.
- * Start another output if more data to send.
- */
-void
-aetint(sc)
- struct ae_softc *sc;
-{
- register int bix = (sc->sc_tmd - sc->sc_no_td + AETBUF) % AETBUF;
- struct aetmd *tmd = &sc->sc_r2->aer2_tmd[bix];
- struct ifnet *ifp = &sc->sc_arpcom.ac_if;
-
- if (tmd->tmd1 & AE_OWN) {
-#ifdef AEDEBUG
- printf("%s: extra tint\n", sc->sc_dev.dv_xname);
-#endif
- return;
- }
- ifp->if_flags &= ~IFF_OACTIVE;
-
- do {
- if (sc->sc_no_td <= 0)
- break;
- ifp->if_opackets++;
- --sc->sc_no_td;
-
- if (tmd->tmd1 & AE_ERR) {
- if (tmd->tmd3 & AE_TBUFF)
- printf("%s: transmit buffer error\n", sc->sc_dev.dv_xname);
- if (tmd->tmd3 & AE_UFLO)
- printf("%s: underflow\n", sc->sc_dev.dv_xname);
- if (tmd->tmd3 & (AE_TBUFF | AE_UFLO)) {
- aereset(sc);
- return;
- }
- if (tmd->tmd3 & AE_LCAR)
- printf("%s: lost carrier\n", sc->sc_dev.dv_xname);
- if (tmd->tmd3 & AE_LCOL) {
- printf("%s: late collision\n", sc->sc_dev.dv_xname);
- ifp->if_collisions++;
- }
- if (tmd->tmd3 & AE_RTRY) {
- printf("%s: excessive collisions, tdr %d\n",
- sc->sc_dev.dv_xname, tmd->tmd3 & AE_TDR_MASK);
- ifp->if_collisions += 16;
- }
- } else if (tmd->tmd1 & AE_ONE) {
- ifp->if_collisions++;
- }
- else if (tmd->tmd1 & AE_MORE) {
- /* Real number is unknown. */
- ifp->if_collisions += 2;
- }
- AENEXTTMP;
- } while ((tmd->tmd1 & AE_OWN) == 0);
-
- aestart(ifp);
- if (sc->sc_no_td == 0)
- ifp->if_timer = 0;
-}
-
-#define AENEXTRMP \
- if (++bix == AERBUF) bix = 0, rmd = sc->sc_r2->aer2_rmd; else ++rmd
-
-/*
- * Ethernet interface receiver interrupt.
- * If input error just drop packet.
- * Decapsulate packet based on type and pass to type specific
- * higher-level input routine.
- */
-void
-aerint(sc)
- struct ae_softc *sc;
-{
- struct ifnet *ifp = &sc->sc_arpcom.ac_if;
- register int bix = sc->sc_rmd;
- register struct aermd *rmd = &sc->sc_r2->aer2_rmd[bix];
-
- /*
- * Out of sync with hardware, should never happen?
- */
- if (rmd->rmd1 & AE_OWN) {
-#ifdef AEDEBUG
- printf("%s: extra rint\n", sc->sc_dev.dv_xname);
-#endif
- return;
- }
-
- /*
- * Process all buffers with valid data
- */
- do {
- sc->sc_r1->aer1_rdp = AE_RINT | AE_INEA;
- if (rmd->rmd1 & (AE_FRAM | AE_OFLO | AE_CRC | AE_RBUFF)) {
- ifp->if_ierrors++;
- if ((rmd->rmd1 & (AE_FRAM | AE_OFLO | AE_ENP)) == (AE_FRAM | AE_ENP))
- printf("%s: framing error\n", sc->sc_dev.dv_xname);
- if ((rmd->rmd1 & (AE_OFLO | AE_ENP)) == AE_OFLO)
- printf("%s: overflow\n", sc->sc_dev.dv_xname);
- if ((rmd->rmd1 & (AE_CRC | AE_OFLO | AE_ENP)) == (AE_CRC | AE_ENP))
- printf("%s: crc mismatch\n", sc->sc_dev.dv_xname);
- if (rmd->rmd1 & AE_RBUFF)
- printf("%s: receive buffer error\n", sc->sc_dev.dv_xname);
- } else if ((rmd->rmd1 & (AE_STP | AE_ENP)) != (AE_STP | AE_ENP)) {
- do {
- rmd->rmd3 = 0;
- rmd->rmd1 = AE_OWN;
- AENEXTRMP;
- } while ((rmd->rmd1 & (AE_OWN | AE_ERR | AE_STP | AE_ENP)) == 0);
-
- sc->sc_rmd = bix;
- printf("%s: chained buffer\n", sc->sc_dev.dv_xname);
- if ((rmd->rmd1 & (AE_OWN | AE_ERR | AE_STP | AE_ENP)) != AE_ENP) {
- aereset(sc);
- return;
- }
- } else
- aeread(sc, sc->sc_r2->aer2_rbuf[bix], SWAP(rmd->rmd3) - 4);
-
- rmd->rmd1 = AE_OWN;
- rmd->rmd2 = SWAP(-ETHER_MAX_LEN);
- rmd->rmd3 = 0;
-
- AENEXTRMP;
- } while ((rmd->rmd1 & AE_OWN) == 0);
-
- sc->sc_rmd = bix;
-}
-
-void
-aeread(sc, buf, len)
- register struct ae_softc *sc;
- u_char *buf;
- int len;
-{
- struct ifnet *ifp = &sc->sc_arpcom.ac_if;
- struct mbuf *m;
- struct ether_header *eh;
-
- if (len <= sizeof(struct ether_header) || len > ETHER_MAX_LEN) {
- printf("%s: invalid packet size %d; dropping\n",
- sc->sc_dev.dv_xname, len);
- ifp->if_ierrors++;
- return;
- }
-
- /* Pull packet off interface. */
- m = aeget(sc, buf, len);
- if (m == 0) {
- ifp->if_ierrors++;
- return;
- }
-
- ifp->if_ipackets++;
-
- /* We assume that the header fit entirely in one mbuf. */
- eh = mtod(m, struct ether_header *);
-
-#if NBPFILTER > 0
- /*
- * Check if there's a bpf filter listening on this interface.
- * If so, hand off the raw packet to bpf, which must deal with
- * trailers in its own way.
- */
- if (ifp->if_bpf) {
- bpf_mtap(ifp->if_bpf, m);
-
- /*
- * Note that the interface cannot be in promiscuous mode if
- * there are no bpf listeners. And if we are in promiscuous
- * mode, we have to check if this packet is really ours.
- */
- if ((ifp->if_flags & IFF_PROMISC) &&
- (eh->ether_dhost[0] & 1) == 0 && /* !mcast and !bcast */
- bcmp(eh->ether_dhost, sc->sc_arpcom.ac_enaddr,
- sizeof(eh->ether_dhost)) != 0) {
- m_freem(m);
- return;
- }
- }
-#endif
-
- /* We assume that the header fit entirely in one mbuf. */
- m_adj(m, sizeof(struct ether_header));
- ether_input(ifp, eh, m);
-}
-
-/*
- * Here come the two replacements for bcopy() and bzero() as
- * WORD-access for writing to the board is absolutely required!
- * They could use some tuning as this is time-critical (copying
- * packet-data) and should be processed as fast as possible.
- *
- * Thanks to Michael van Elst for pointing me to the problems
- * that kept the 1.3 code from running under NetBSD current
- * although it did mystically under 1.0 ...
- */
-
-#define isodd(p) (((size_t)(p)) & 1)
-#define align(p) ((ushort *)(((size_t)(p)) & ~1))
-
-/*
- * the first function copies WORD-aligned from the source to
- * an arbitrary destination. It assumes that the CPU can handle
- * mis-aligned writes to the destination itself.
- */
-static void
-wcopyfrom(a1, a2, length) /* bcopy() word-wise */
- char *a1, *a2;
- int length;
-{
- ushort i, *b1, *b2;
-
- if (length > 0 && isodd(a1)) {
- b1 = align(a1);
- *a2 = *b1 & 0x00ff; /* copy first byte with word access */
- ++a2;
- ++b1;
- --length;
- } else
- b1 = (ushort *)a1;
- b2 = (ushort *)a2;
-
- i = length / 2;
-
- while(i--) /* copy all words */
- *b2++ = *b1++;
-
- if (length & 0x0001) /* copy trailing byte */
- a2[length-1] = *b1 >> 8;
-}
-
-/*
- * the second function copies WORD-aligned from an arbitrary
- * source to the destination. It assumes that the CPU can handle
- * mis-aligned reads from the source itself.
- */
-static void
-wcopyto(a1, a2, length) /* bcopy() word-wise */
- char *a1, *a2;
- int length;
-{
- ushort i, *b1, *b2;
-
- if (length > 0 && isodd(a2)) {
- b2 = align(a2);
- i = (*b2 & 0xff00) | (*a1 & 0x00ff); /* copy first byte with word access */
- *b2 = i;
- ++a1;
- ++b2;
- --length;
- } else
- b2 = (ushort *)a2;
- b1 = (ushort *)a1;
-
- i = length / 2;
-
- while(i--) /* copy all words */
- *b2++ = *b1++;
-
- if (length & 0x0001) {
- i = (*b2 & 0x00ff) | (a1[length-1] & 0x00ff)<<8; /* copy trailing byte */
- *b2 = i;
- }
-}
-
-static void
-wzero(a1, length) /* bzero() word-wise */
- char *a1;
- int length;
-{
- ushort i, *b1;
-
- /*
- * Is the destination word-aligned?
- * If not, handle the leading byte...
- */
-
- if((length > 0) && ((size_t)a1 & 1)) {
- b1 = (ushort *)((size_t)a1 & ~1);
- *b1 &= 0xff00;
- --length;
- ++a1;
- }
-
- /*
- * Perform the main zeroing word-wise...
- */
-
- b1 = (ushort *)a1;
- i = length / 2;
- while(i--)
- *b1++ = 0;
-
- /*
- * Do we have to handle a trailing byte?
- */
-
- if (length & 0x0001)
- *b1 &= 0x00ff;
-}
-
-/*
- * Routine to copy from mbuf chain to transmit
- * buffer in board local memory.
- */
-int
-aeput(buffer, m)
- register char *buffer;
- register struct mbuf *m;
-{
- register struct mbuf *n;
- register int len = 0, tlen = 0;
-
- for (; m; m = n) {
- len = m->m_len;
- if (len == 0) {
- MFREE(m, n);
- continue;
- }
- wcopyto(mtod(m, char *), buffer, len);
- buffer += len;
- tlen += len;
- MFREE(m, n);
- }
-
- if (tlen < ETHER_MIN_LEN) {
- wzero(buffer, ETHER_MIN_LEN - tlen);
- tlen = ETHER_MIN_LEN;
- }
-
- return(tlen);
-}
-
-/*
- * Routine to copy from board local memory into mbufs.
- */
-struct mbuf *
-aeget(sc, buffer, totlen)
- struct ae_softc *sc;
- u_char *buffer;
- int totlen;
-{
- register struct mbuf *m;
- struct mbuf *top, **mp;
- int len;
-
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == 0)
- return (0);
- m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
- m->m_pkthdr.len = totlen;
- len = MHLEN;
- top = 0;
- mp = &top;
-
- while (totlen > 0) {
- if (top) {
- MGET(m, M_DONTWAIT, MT_DATA);
- if (m == 0) {
- m_freem(top);
- return (0);
- }
- len = MLEN;
- }
-
- if (totlen >= MINCLSIZE) {
- MCLGET(m, M_DONTWAIT);
- if (m->m_flags & M_EXT)
- len = MCLBYTES;
- }
- m->m_len = len = min(totlen, len);
- wcopyfrom((caddr_t)buffer, mtod(m, caddr_t), len);
- buffer += len;
- totlen -= len;
- *mp = m;
- mp = &m->m_next;
- }
-
- return (top);
-}
-
-/*
- * Process an ioctl request.
- */
-int
-aeioctl(ifp, cmd, data)
- register struct ifnet *ifp;
- u_long cmd;
- caddr_t data;
-{
- struct ae_softc *sc = ifp->if_softc;
- struct ifaddr *ifa = (struct ifaddr *)data;
- struct ifreq *ifr = (struct ifreq *)data;
- int s, error = 0;
-
- s = splnet();
-
- if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
- splx(s);
- return error;
- }
-
- switch (cmd) {
-
- case SIOCSIFADDR:
- ifp->if_flags |= IFF_UP;
-
- switch (ifa->ifa_addr->sa_family) {
-#ifdef INET
- case AF_INET:
- aeinit(sc);
- arp_ifinit(&sc->sc_arpcom, ifa);
- break;
-#endif
-#ifdef NS
- case AF_NS:
- {
- register struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
-
- if (ns_nullhost(*ina))
- ina->x_host =
- *(union ns_host *)(sc->sc_arpcom.ac_enaddr);
- else
- wcopyto(ina->x_host.c_host,
- sc->sc_arpcom.ac_enaddr,
- sizeof(sc->sc_arpcom.ac_enaddr));
- aeinit(sc); /* does ae_setaddr() */
- break;
- }
-#endif
- default:
- aeinit(sc);
- break;
- }
- break;
-
-#if defined(CCITT) && defined(LLC)
- case SIOCSIFCONF_X25:
- ifp->if_flags |= IFF_UP;
- ifa->ifa_rtrequest = cons_rtrequest; /* XXX */
- error = x25_llcglue(PRC_IFUP, ifa->ifa_addr);
- if (error == 0)
- aeinit(sc);
- break;
-#endif /* CCITT && LLC */
-
- case SIOCSIFFLAGS:
- if ((ifp->if_flags & IFF_UP) == 0 &&
- (ifp->if_flags & IFF_RUNNING) != 0) {
- /*
- * If interface is marked down and it is running, then
- * stop it.
- */
- aestop(sc);
- ifp->if_flags &= ~IFF_RUNNING;
- } else if ((ifp->if_flags & IFF_UP) != 0 &&
- (ifp->if_flags & IFF_RUNNING) == 0) {
- /*
- * If interface is marked up and it is stopped, then
- * start it.
- */
- aeinit(sc);
- } else {
- /*
- * Reset the interface to pick up changes in any other
- * flags that affect hardware registers.
- */
- aeinit(sc);
- }
- break;
-
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- error = (cmd == SIOCADDMULTI) ?
- ether_addmulti(ifr, &sc->sc_arpcom):
- ether_delmulti(ifr, &sc->sc_arpcom);
-
- if (error == ENETRESET) {
- /*
- * Multicast list has changed; set the hardware filter
- * accordingly.
- */
- aereset(sc);
- error = 0;
- }
- break;
-
- default:
- error = EINVAL;
- break;
- }
- splx(s);
- return (error);
-}
-
-/*
- * Set up the logical address filter.
- */
-void
-aesetladrf(ac, af)
- struct arpcom *ac;
- u_int16_t *af;
-{
- struct ifnet *ifp = &ac->ac_if;
- struct ether_multi *enm;
- register u_char *cp, c;
- register u_int32_t crc;
- register int i, len;
- struct ether_multistep step;
-
- /*
- * Set up multicast address filter by passing all multicast addresses
- * through a crc generator, and then using the high order 6 bits as an
- * index into the 64 bit logical address filter. The high order bit
- * selects the word, while the rest of the bits select the bit within
- * the word.
- */
-
- if (ifp->if_flags & IFF_PROMISC)
- goto allmulti;
-
- af[0] = af[1] = af[2] = af[3] = 0x0000;
- ETHER_FIRST_MULTI(step, ac, enm);
- while (enm != NULL) {
- if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
- sizeof(enm->enm_addrlo)) != 0) {
- /*
- * We must listen to a range of multicast addresses.
- * For now, just accept all multicasts, rather than
- * trying to set only those filter bits needed to match
- * the range. (At this time, the only use of address
- * ranges is for IP multicast routing, for which the
- * range is big enough to require all bits set.)
- */
- goto allmulti;
- }
-
- cp = enm->enm_addrlo;
- crc = 0xffffffff;
- for (len = sizeof(enm->enm_addrlo); --len >= 0;) {
- c = *cp++;
- for (i = 8; --i >= 0;) {
- if ((crc & 0x01) ^ (c & 0x01)) {
- crc >>= 1;
- crc ^= 0xedb88320;
- } else
- crc >>= 1;
- c >>= 1;
- }
- }
- /* Just want the 6 most significant bits. */
- crc >>= 26;
-
- /* Turn on the corresponding bit in the filter. */
- af[crc >> 4] |= 1 << SWAP(crc & 0x1f);
-
- ETHER_NEXT_MULTI(step, enm);
- }
- ifp->if_flags &= ~IFF_ALLMULTI;
- return;
-
-allmulti:
- ifp->if_flags |= IFF_ALLMULTI;
- af[0] = af[1] = af[2] = af[3] = 0xffff;
-}
-
-#endif /* NAE > 0 */
diff --git a/sys/arch/amiga/dev/if_aereg.h b/sys/arch/amiga/dev/if_aereg.h
deleted file mode 100644
index c08eede7d49..00000000000
--- a/sys/arch/amiga/dev/if_aereg.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/* $OpenBSD: if_aereg.h,v 1.2 1997/01/16 09:24:37 niklas Exp $ */
-/* $NetBSD: if_aereg.h,v 1.2 1995/08/18 15:53:32 chopps Exp $ */
-
-/*
- * Copyright (c) 1995 Bernd Ernesti and Klaus Burkert. All rights reserved.
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell and Rick Macklem.
- *
- * 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 Bernd Ernesti, by Klaus
- * Burkert, by Michael van Elst, and 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.
- *
- * @(#)if_lereg.h 8.1 (Berkeley) 6/10/93
- *
- * This is based on the original LANCE files, as the PCnet-ISA used on
- * the Ariadne is a LANCE-descendant optimized for the PC-ISA bus.
- * This causes some modifications, all data that is to go into registers
- * or to structures (buffer-descriptors, init-block) has to be
- * byte-swapped. In addition ALL write accesses to the board have to be
- * WORD or LONG, BYTE-access is prohibited!!
- */
-
-#define ETHER_MAX_LEN 1518
-#define ETHER_MIN_LEN 64
-
-#define AERBUF 16 /* 16 receive buffers */
-#define AERBUFLOG2 4
-#define AETBUF 4 /* 4 transmit buffers */
-#define AETBUFLOG2 2
-
-#define AE_RLEN (AERBUFLOG2 << 13)
-#define AE_TLEN (AETBUFLOG2 << 13)
-
-/*
- * PCnet-ISA registers.
- */
-
-struct aereg1 {
- u_int16_t aer1_rdp; /* data port */
- u_int16_t aer1_rap; /* register select port */
- u_int16_t aer1_reset; /* reading this resets the PCnet-ISA */
- u_int16_t aer1_idp; /* isa configuration port */
-};
-
-struct aereg2 {
- /* init block */
- u_int16_t aer2_mode; /* +0x0000 */
- u_int16_t aer2_padr[3]; /* +0x0002 */
- u_int16_t aer2_ladrf[4]; /* +0x0008 */
- u_int16_t aer2_rdra; /* +0x0010 */
- u_int16_t aer2_rlen; /* +0x0012 */
- u_int16_t aer2_tdra; /* +0x0014 */
- u_int16_t aer2_tlen; /* +0x0016 */
- /* receive message descriptors */
- struct aermd { /* +0x0018 */
- u_int16_t rmd0;
- u_int16_t rmd1;
- int16_t rmd2;
- u_int16_t rmd3;
- } aer2_rmd[AERBUF];
- /* transmit message descriptors */
- struct aetmd { /* +0x0058 */
- u_int16_t tmd0;
- u_int16_t tmd1;
- int16_t tmd2;
- u_int16_t tmd3;
- } aer2_tmd[AETBUF];
- char aer2_rbuf[AERBUF][ETHER_MAX_LEN]; /* +0x0060 */
- char aer2_tbuf[AETBUF][ETHER_MAX_LEN]; /* +0x2FD0 */
-};
-
-
-/*
- * Control and status bits -- aereg1
- */
-#define AE_CSR0 0x0000 /* Control and status register */
-#define AE_CSR1 0x0100 /* low address of init block */
-#define AE_CSR2 0x0200 /* high address of init block */
-#define AE_CSR3 0x0300 /* Bus master and control */
-
-/* Control and status register 0 (csr0) */
-#define AE_SERR 0x0080 /* error summary */
-#define AE_BABL 0x0040 /* transmitter timeout error */
-#define AE_CERR 0x0020 /* collision */
-#define AE_MISS 0x0010 /* missed a packet */
-#define AE_MERR 0x0008 /* memory error */
-#define AE_RINT 0x0004 /* receiver interrupt */
-#define AE_TINT 0x0002 /* transmitter interrupt */
-#define AE_IDON 0x0001 /* initalization done */
-#define AE_INTR 0x8000 /* interrupt condition */
-#define AE_INEA 0x4000 /* interrupt enable */
-#define AE_RXON 0x2000 /* receiver on */
-#define AE_TXON 0x1000 /* transmitter on */
-#define AE_TDMD 0x0800 /* transmit demand */
-#define AE_STOP 0x0400 /* disable all external activity */
-#define AE_STRT 0x0200 /* enable external activity */
-#define AE_INIT 0x0100 /* begin initalization */
-
-#define AE_PROM 0x0080 /* promiscuous mode */
-#define AE_MODE 0x0000
-
-/*
- * Control and status bits -- aereg2
- */
-#define AE_OWN 0x0080 /* LANCE owns the packet */
-#define AE_ERR 0x0040 /* error summary */
-#define AE_STP 0x0002 /* start of packet */
-#define AE_ENP 0x0001 /* end of packet */
-
-#define AE_MORE 0x0010 /* multiple collisions */
-#define AE_ONE 0x0008 /* single collision */
-#define AE_DEF 0x0004 /* defferred transmit */
-
-#define AE_FRAM 0x0020 /* framing error */
-#define AE_OFLO 0x0010 /* overflow error */
-#define AE_CRC 0x0008 /* CRC error */
-#define AE_RBUFF 0x0004 /* buffer error */
-
-/* Transmit message descriptor 3 (tmd3) */
-#define AE_TBUFF 0x0080 /* buffer error */
-#define AE_UFLO 0x0040 /* underflow error */
-#define AE_LCOL 0x0010 /* late collision */
-#define AE_LCAR 0x0008 /* loss of carrier */
-#define AE_RTRY 0x0004 /* retry error */
-#define AE_TDR_MASK 0xff03 /* time domain reflectometry counter */
-
-#define SWAP(x) (((x & 0xff) << 8 ) | (( x >> 8) & 0xff))
-
diff --git a/sys/arch/amiga/dev/if_bah.c b/sys/arch/amiga/dev/if_bah.c
index 82abd456f03..213a10ac44c 100644
--- a/sys/arch/amiga/dev/if_bah.c
+++ b/sys/arch/amiga/dev/if_bah.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_bah.c,v 1.7 1997/01/16 09:24:38 niklas Exp $ */
-/* $NetBSD: if_bah.c,v 1.25 1996/12/23 09:10:15 veego Exp $ */
+/* $OpenBSD: if_bah.c,v 1.8 1997/09/18 13:39:55 niklas Exp $ */
+/* $NetBSD: if_bah.c,v 1.30 1997/04/04 06:27:32 is Exp $ */
/*
* Copyright (c) 1994, 1995 Ignatios Souvatzis
@@ -1033,7 +1033,11 @@ bahintr(arg)
#endif
if (maskedisr & ARC_POR) {
- sc->sc_arccom.ac_anaddr = sc->sc_base->dipswitches;
+ /*
+ * XXX We should never see this. Don't bother to store
+ * the address.
+ * sc->sc_arccom.ac_anaddr = sc->sc_base->dipswitches;
+ */
sc->sc_base->command = ARC_CLR(CLR_POR);
log(LOG_WARNING, "%s: intr: got spurious power on reset int\n",
sc->sc_dev.dv_xname);
@@ -1048,8 +1052,8 @@ bahintr(arg)
sc->sc_arccom.ac_if.if_collisions++;
/*
-! * If less than 2 seconds per reconfig:
-! * If ARC_EXCESSIVE_RECONFIGS
+ * If less than 2 seconds per reconfig:
+ * If ARC_EXCESSIVE_RECONFIGS
* since last burst, complain and set treshold for
* warnings to ARC_EXCESSIVE_RECONS_REWARN.
*
diff --git a/sys/arch/amiga/dev/if_ed.c b/sys/arch/amiga/dev/if_ed.c
index e918ba94219..8244c5d7590 100644
--- a/sys/arch/amiga/dev/if_ed.c
+++ b/sys/arch/amiga/dev/if_ed.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_ed.c,v 1.10 1997/02/21 11:08:48 niklas Exp $ */
-/* $NetBSD: if_ed.c,v 1.24 1996/12/23 09:10:16 veego Exp $ */
+/* $OpenBSD: if_ed.c,v 1.11 1997/09/18 13:39:56 niklas Exp $ */
+/* $NetBSD: if_ed.c,v 1.26 1997/03/17 17:51:42 is Exp $ */
/*
* Device driver for National Semiconductor DS8390/WD83C690 based ethernet
diff --git a/sys/arch/amiga/dev/if_levar.h b/sys/arch/amiga/dev/if_levar.h
index 2a2676424ee..ffeb241b69a 100644
--- a/sys/arch/amiga/dev/if_levar.h
+++ b/sys/arch/amiga/dev/if_levar.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_levar.h,v 1.3 1996/05/09 22:40:01 niklas Exp $ */
-/* $NetBSD: if_levar.h,v 1.3 1996/05/07 00:46:45 thorpej Exp $ */
+/* $OpenBSD: if_levar.h,v 1.4 1997/09/18 13:39:56 niklas Exp $ */
+/* $NetBSD: if_levar.h,v 1.5 1997/03/27 21:15:14 veego Exp $ */
/*
* Copyright (c) 1982, 1990 The Regents of the University of California.
@@ -35,11 +35,16 @@
*/
/*
- * LANCE registers.
+ * LANCE and PCnet-ISA registers.
*/
struct lereg1 {
- u_short ler1_rdp; /* data port */
- u_short ler1_rap; /* register select port */
+ u_int16_t ler1_rdp; /* data port */
+ u_int16_t ler1_rap; /* register select port */
+ /*
+ * The next two registers are only available on PCnet-ISA cards.
+ */
+ u_int16_t ler1_reset; /* reading this resets the PCnet-ISA */
+ u_int16_t ler1_idp; /* isa configuration port */
};
/*
diff --git a/sys/arch/amiga/dev/if_qn.c b/sys/arch/amiga/dev/if_qn.c
index 46909ff8413..546bcd9e611 100644
--- a/sys/arch/amiga/dev/if_qn.c
+++ b/sys/arch/amiga/dev/if_qn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_qn.c,v 1.9 1997/01/16 09:24:47 niklas Exp $ */
+/* $OpenBSD: if_qn.c,v 1.10 1997/09/18 13:39:57 niklas Exp $ */
/* $NetBSD: if_qn.c,v 1.10 1996/12/23 09:10:19 veego Exp $ */
/*
@@ -490,10 +490,6 @@ word_copy_to_card(a, card, len)
/*
* Copy packet from mbuf to the board memory
- *
- * Uses an extra buffer/extra memory copy,
- * unless the whole packet fits in one mbuf.
- *
*/
u_short
qn_put(addr, m)
@@ -510,7 +506,6 @@ qn_put(addr, m)
for (; m != NULL; m = m->m_next) {
data = mtod(m, u_short *);
len = m->m_len;
- totlen += len;
if (len > 0) {
totlen += len;
diff --git a/sys/arch/amiga/dev/ite.c b/sys/arch/amiga/dev/ite.c
index 48d5142027a..58e0d9634d4 100644
--- a/sys/arch/amiga/dev/ite.c
+++ b/sys/arch/amiga/dev/ite.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ite.c,v 1.9 1997/01/16 09:24:50 niklas Exp $ */
+/* $OpenBSD: ite.c,v 1.10 1997/09/18 13:39:58 niklas Exp $ */
/* $NetBSD: ite.c,v 1.47 1996/12/23 09:10:20 veego Exp $ */
/*
@@ -59,7 +59,6 @@
#include <sys/proc.h>
#include <dev/cons.h>
#include <amiga/amiga/cc.h>
-#include <amiga/amiga/kdassert.h>
#include <amiga/amiga/color.h> /* DEBUG */
#include <amiga/amiga/custom.h> /* DEBUG */
#include <amiga/amiga/device.h>
diff --git a/sys/arch/amiga/dev/ite_et.c b/sys/arch/amiga/dev/ite_et.c
index 0942bb03fb1..2a45cd6bc43 100644
--- a/sys/arch/amiga/dev/ite_et.c
+++ b/sys/arch/amiga/dev/ite_et.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ite_et.c,v 1.3 1997/01/16 09:24:51 niklas Exp $ */
-/* $NetBSD: ite_et.c,v 1.2 1996/10/08 23:18:54 thorpej Exp $ */
+/* $OpenBSD: ite_et.c,v 1.4 1997/09/18 13:39:58 niklas Exp $ */
+/* $NetBSD: ite_et.c,v 1.3 1997/03/05 22:50:41 veego Exp $ */
/*
* Copyright (c) 1995 Ezra Story
@@ -130,7 +130,7 @@ et_cursor(ip, flag)
flag = ip->curx + ip->cury * ip->cols;
WCrt(ba, CRT_ID_CURSOR_LOC_LOW, flag & 0xff);
WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, (flag >> 8) & 0xff);
- WCrt(ba, CTR_ID_EXT_START, (flag >> (16-2)) & 0x0c);
+ WCrt(ba, CRT_ID_EXT_START, (flag >> (16-2)) & 0x0c);
ip->cursorx = ip->curx;
ip->cursory = ip->cury;
diff --git a/sys/arch/amiga/dev/rtc.h b/sys/arch/amiga/dev/rtc.h
index 417a8146192..53f33209c90 100644
--- a/sys/arch/amiga/dev/rtc.h
+++ b/sys/arch/amiga/dev/rtc.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rtc.h,v 1.2 1996/05/02 06:44:25 niklas Exp $ */
-/* $NetBSD: rtc.h,v 1.3 1996/04/21 21:12:19 veego Exp $ */
+/* $OpenBSD: rtc.h,v 1.3 1997/09/18 13:39:59 niklas Exp $ */
+/* $NetBSD: rtc.h,v 1.5 1997/07/17 23:29:28 is Exp $ */
/*
* Copyright (c) 1994 Christian E. Hopps
@@ -36,6 +36,12 @@
#ifndef _RTCVAR_H_
#define _RTCVAR_H_
+/* this is a hook set by a clock driver for the configured realtime clock,
+ returning plain current unix-time */
+
+time_t (*gettod) __P((void));
+int (*settod) __P((time_t));
+
struct rtclock2000 {
u_int :28, second2:4; /* lower digit */
u_int :28, second1:4; /* upper digit */
@@ -49,7 +55,7 @@ struct rtclock2000 {
u_int :28, month1:4; /* upper digit */
u_int :28, year2:4; /* lower digit */
u_int :28, year1:4; /* upper digit */
- u_int :28, week:4; /* week */
+ u_int :28, weekday:4; /* weekday */
u_int :28, control1:4; /* control-byte 1 */
u_int :28, control2:4; /* control-byte 2 */
u_int :28, control3:4; /* control-byte 3 */
@@ -92,15 +98,10 @@ struct rtclock3000 {
#define A3BBC_READ_REG 0xc3
#define A3NUM_BBC_REGS 12
-#define FEBRUARY 2
+/*
+ * Our clock starts at 1/1/1970, but counts the years from 1900.
+ */
#define STARTOFTIME 1970
-#define SECDAY 86400L
-#define SECYR (SECDAY * 365)
-
-
-#define leapyear(y) ((((y)%4)==0 && ((y)%100)!=0) || ((y)%400) == 0)
-#define range_test(n, l, h) ((n) < (l) || (n) > (h))
-#define days_in_year(a) (leapyear(a) ? 366 : 365)
-#define days_in_month(a) (month_days[(a) - 1])
+#define CLOCK_BASE_YEAR 1900
#endif /* _RTCVAR_H_ */
diff --git a/sys/arch/amiga/dev/ser.c b/sys/arch/amiga/dev/ser.c
index 8561cf2f0c2..afb7e0c1434 100644
--- a/sys/arch/amiga/dev/ser.c
+++ b/sys/arch/amiga/dev/ser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ser.c,v 1.6 1997/01/16 09:25:22 niklas Exp $ */
+/* $OpenBSD: ser.c,v 1.7 1997/09/18 13:39:59 niklas Exp $ */
/* $NetBSD: ser.c,v 1.39 1996/12/23 09:10:29 veego Exp $ */
/*
@@ -364,6 +364,7 @@ serclose(dev, flag, mode, p)
if (tp->t_cflag & HUPCL || tp->t_state & TS_WOPEN ||
(tp->t_state & TS_ISOPEN) == 0)
#endif
+ (void) sermctl(dev, 0, DMSET);
ttyclose(tp);
#if not_yet
if (tp != &ser_cons) {
diff --git a/sys/arch/amiga/dev/drcomvar.h b/sys/arch/amiga/dev/supio.h
index f6431d2a4b4..bcf214d8d9c 100644
--- a/sys/arch/amiga/dev/drcomvar.h
+++ b/sys/arch/amiga/dev/supio.h
@@ -1,8 +1,9 @@
-/* $OpenBSD: drcomvar.h,v 1.1 1997/01/16 09:23:56 niklas Exp $ */
-/* $NetBSD: drcomvar.h,v 1.1 1996/11/30 00:43:04 is Exp $ */
+/* $OpenBSD: supio.h,v 1.1 1997/09/18 13:40:00 niklas Exp $ */
+/* $NetBSD: supio.h,v 1.1 1997/08/27 19:32:52 is Exp $ */
/*
- * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
+ * Copyright (c) 1997 Ignatios Souvatzis
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -14,8 +15,8 @@
* 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 Christopher G. Demetriou
- * for the NetBSD Project.
+ * This product includes software developed by Ignatios Souvatzis
+ * for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
@@ -31,10 +32,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-int comintr __P((void *));
+/*
+ * DraCo multi-io chip bus space stuff definitions
+ */
-extern int comconsaddr;
-extern int comconsattached;
-extern bus_chipset_tag_t comconsbc;
-extern bus_io_handle_t comconsioh;
-extern tcflag_t comconscflag;
+struct supio_attach_args {
+ bus_space_tag_t supio_iot;
+ char *supio_name;
+ int supio_iobase;
+};