summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorasami <asami@FreeBSD.org>1996-10-30 22:41:46 +0000
committerasami <asami@FreeBSD.org>1996-10-30 22:41:46 +0000
commit95ac832055c11e8031e18bcc9759b2d12b654e9b (patch)
tree37f74d6fdf54e31c6c6d69a11d50e299cd0a1118
parente1b78916a4b8d96475ebaa0033860c706702fe49 (diff)
downloadFreeBSD-src-95ac832055c11e8031e18bcc9759b2d12b654e9b.zip
FreeBSD-src-95ac832055c11e8031e18bcc9759b2d12b654e9b.tar.gz
More merge and update.
(1) deleted #if 0 pc98/pc98/mse.c (2) hold per-unit I/O ports in ed_softc pc98/pc98/if_ed.c pc98/pc98/if_ed98.h (3) merge more files by segregating changes into headers. new file (moved from pc98/pc98): i386/isa/aic_98.h deleted: well, it's already in the commit message so I won't repeat the long list here ;) Submitted by: The FreeBSD(98) Development Team
-rw-r--r--sys/amd64/amd64/prof_machdep.c6
-rw-r--r--sys/amd64/amd64/vm_machdep.c18
-rw-r--r--sys/amd64/include/clock.h6
-rw-r--r--sys/amd64/isa/timerreg.h19
-rw-r--r--sys/amd64/isa/vector.S20
-rw-r--r--sys/amd64/isa/vector.s20
-rw-r--r--sys/amd64/pci/pci_bus.c6
-rw-r--r--sys/amd64/pci/pci_cfgreg.c6
-rw-r--r--sys/conf/files.pc9888
-rw-r--r--sys/conf/options.pc984
-rw-r--r--sys/dev/kbd/kbdtables.h143
-rw-r--r--sys/i386/i386/vm_machdep.c18
-rw-r--r--sys/i386/include/clock.h6
-rw-r--r--sys/i386/isa/aic6360.c27
-rw-r--r--sys/i386/isa/aic_98.h (renamed from sys/pc98/pc98/aic_98.h)0
-rw-r--r--sys/i386/isa/atapi.c28
-rw-r--r--sys/i386/isa/atapi.h13
-rw-r--r--sys/i386/isa/icu.s7
-rw-r--r--sys/i386/isa/kbdtables.h143
-rw-r--r--sys/i386/isa/matcd/creative.h9
-rw-r--r--sys/i386/isa/matcd/options.h11
-rw-r--r--sys/i386/isa/pcibus.c6
-rw-r--r--sys/i386/isa/prof_machdep.c6
-rw-r--r--sys/i386/isa/random_machdep.c6
-rw-r--r--sys/i386/isa/sound/dev_table.h10
-rw-r--r--sys/i386/isa/sound/local.h12
-rw-r--r--sys/i386/isa/sound/sound_calls.h6
-rw-r--r--sys/i386/isa/sound/sound_config.h24
-rw-r--r--sys/i386/isa/timerreg.h19
-rw-r--r--sys/i386/isa/vector.s20
-rw-r--r--sys/i386/pci/pci_bus.c6
-rw-r--r--sys/i386/pci/pci_cfgreg.c6
-rw-r--r--sys/i386/pci/pci_pir.c6
-rw-r--r--sys/isa/kbdtables.h143
-rw-r--r--sys/isa/timerreg.h19
-rw-r--r--sys/kern/kern_random.c6
-rw-r--r--sys/pc98/cbus/cbus.h4
-rw-r--r--sys/pc98/cbus/clock.c58
-rw-r--r--sys/pc98/cbus/pcrtc.c58
-rw-r--r--sys/pc98/conf/GENERIC5
-rw-r--r--sys/pc98/conf/GENERIC985
-rw-r--r--sys/pc98/conf/files.pc9888
-rw-r--r--sys/pc98/conf/options.pc984
-rw-r--r--sys/pc98/i386/exception.s279
-rw-r--r--sys/pc98/i386/microtime.s6
-rw-r--r--sys/pc98/i386/userconfig.c6
-rw-r--r--sys/pc98/i386/vm_machdep.c864
-rw-r--r--sys/pc98/pc98/aic6360.c2436
-rw-r--r--sys/pc98/pc98/atapi.c1074
-rw-r--r--sys/pc98/pc98/atapi.h13
-rw-r--r--sys/pc98/pc98/clock.c58
-rw-r--r--sys/pc98/pc98/icu.s357
-rw-r--r--sys/pc98/pc98/if_ed.c103
-rw-r--r--sys/pc98/pc98/if_ed98.h189
-rw-r--r--sys/pc98/pc98/if_fe.c6
-rw-r--r--sys/pc98/pc98/kbd.h12
-rw-r--r--sys/pc98/pc98/kbdtables.h1039
-rw-r--r--sys/pc98/pc98/matcd/TODO42
-rw-r--r--sys/pc98/pc98/matcd/creative.h142
-rw-r--r--sys/pc98/pc98/matcd/matcd.c2670
-rw-r--r--sys/pc98/pc98/matcd/options.h283
-rw-r--r--sys/pc98/pc98/mse.c12
-rw-r--r--sys/pc98/pc98/pc98.h4
-rw-r--r--sys/pc98/pc98/pcaudio.c34
-rw-r--r--sys/pc98/pc98/pcibus.c526
-rw-r--r--sys/pc98/pc98/prof_machdep.c163
-rw-r--r--sys/pc98/pc98/random_machdep.c520
-rw-r--r--sys/pc98/pc98/sound/CHANGELOG122
-rw-r--r--sys/pc98/pc98/sound/README86
-rw-r--r--sys/pc98/pc98/sound/Readme.aedsp166
-rw-r--r--sys/pc98/pc98/sound/Readme.modules87
-rw-r--r--sys/pc98/pc98/sound/Readme.v30142
-rw-r--r--sys/pc98/pc98/sound/adlib_card.c55
-rw-r--r--sys/pc98/pc98/sound/audio.c587
-rw-r--r--sys/pc98/pc98/sound/dev_table.c186
-rw-r--r--sys/pc98/pc98/sound/dev_table.h429
-rw-r--r--sys/pc98/pc98/sound/dmabuf.c1119
-rw-r--r--sys/pc98/pc98/sound/gus_card.c197
-rw-r--r--sys/pc98/pc98/sound/gus_midi.c312
-rw-r--r--sys/pc98/pc98/sound/gus_vol.c150
-rw-r--r--sys/pc98/pc98/sound/gus_wave.c3445
-rw-r--r--sys/pc98/pc98/sound/ics2101.c264
-rw-r--r--sys/pc98/pc98/sound/local.h128
-rw-r--r--sys/pc98/pc98/sound/midi_synth.c648
-rw-r--r--sys/pc98/pc98/sound/midibuf.c474
-rw-r--r--sys/pc98/pc98/sound/mpu401.c1777
-rw-r--r--sys/pc98/pc98/sound/opl3.c4
-rw-r--r--sys/pc98/pc98/sound/pas2_card.c420
-rw-r--r--sys/pc98/pc98/sound/pas2_midi.c341
-rw-r--r--sys/pc98/pc98/sound/pas2_mixer.c340
-rw-r--r--sys/pc98/pc98/sound/patmgr.c272
-rw-r--r--sys/pc98/pc98/sound/pcm86.c4
-rw-r--r--sys/pc98/pc98/sound/sb16_dsp.c4
-rw-r--r--sys/pc98/pc98/sound/sb16_midi.c4
-rw-r--r--sys/pc98/pc98/sound/sb_card.c65
-rw-r--r--sys/pc98/pc98/sound/sb_dsp.c4
-rw-r--r--sys/pc98/pc98/sound/sb_midi.c257
-rw-r--r--sys/pc98/pc98/sound/sb_mixer.c591
-rw-r--r--sys/pc98/pc98/sound/sequencer.c1992
-rw-r--r--sys/pc98/pc98/sound/sound.doc120
-rw-r--r--sys/pc98/pc98/sound/sound_calls.h272
-rw-r--r--sys/pc98/pc98/sound/sound_switch.c4
-rw-r--r--sys/pc98/pc98/sound/sound_timer.c406
-rw-r--r--sys/pc98/pc98/sound/soundcard.c10
-rw-r--r--sys/pc98/pc98/sound/sscape.c1120
-rw-r--r--sys/pc98/pc98/sound/sys_timer.c308
-rw-r--r--sys/pc98/pc98/sound/trix.c323
-rw-r--r--sys/pc98/pc98/sound/uart6850.c327
-rw-r--r--sys/pc98/pc98/sound/ulaw.h71
-rw-r--r--sys/pc98/pc98/spkr.c53
-rw-r--r--sys/pc98/pc98/syscons.c64
-rw-r--r--sys/pc98/pc98/syscons.h5
-rw-r--r--sys/pc98/pc98/timerreg.h93
-rw-r--r--sys/pc98/pc98/vector.s305
114 files changed, 1166 insertions, 28780 deletions
diff --git a/sys/amd64/amd64/prof_machdep.c b/sys/amd64/amd64/prof_machdep.c
index 62c8df5..a8603cb 100644
--- a/sys/amd64/amd64/prof_machdep.c
+++ b/sys/amd64/amd64/prof_machdep.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: prof_machdep.c,v 1.2 1996/04/08 16:41:06 wollman Exp $
+ * $Id: prof_machdep.c,v 1.3 1996/10/17 19:32:10 bde Exp $
*/
#ifdef GUPROF
@@ -40,7 +40,11 @@
#include <machine/profile.h>
#endif
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
#include <i386/isa/isa.h>
+#endif
#include <i386/isa/timerreg.h>
#ifdef GUPROF
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 44b799d..62ff784 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.69 1996/09/28 22:37:43 dyson Exp $
+ * $Id: vm_machdep.c,v 1.70 1996/10/15 03:16:33 dyson Exp $
*/
#include "npx.h"
@@ -66,7 +66,11 @@
#include <sys/user.h>
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
#include <i386/isa/isa.h>
+#endif
#ifdef BOUNCE_BUFFERS
static vm_offset_t
@@ -90,7 +94,11 @@ static int bounceallocarraysize;
static unsigned *bounceallocarray;
static int bouncefree;
+#if defined(PC98) && defined (EPSON_BOUNCEDMA)
+#define SIXTEENMEG (3840*4096) /* 15MB boundary */
+#else
#define SIXTEENMEG (4096*4096)
+#endif
#define MAXBKVA 1024
int maxbkva = MAXBKVA*PAGE_SIZE;
@@ -748,7 +756,7 @@ cpu_reset() {
* to do the reset here would then end up in no man's land.
*/
-#ifndef BROKEN_KEYBOARD_RESET
+#if !defined(BROKEN_KEYBOARD_RESET) && !defined(PC98)
outb(IO_KBD + 4, 0xFE);
DELAY(500000); /* wait 0.5 sec to see if that did it */
printf("Keyboard reset did not work, attempting CPU shutdown\n");
@@ -761,6 +769,12 @@ cpu_reset() {
/* "good night, sweet prince .... <THUNK!>" */
invltlb();
/* NOTREACHED */
+#ifdef PC98
+ asm(" cli ");
+ outb(0x37, 0x0f); /* SHUT 0 = 0 */
+ outb(0x37, 0x0b); /* SHUT 1 = 0 */
+ outb(0xf0, 0x00); /* reset port */
+#endif
while(1);
}
diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h
index f20902f..0f3427f 100644
--- a/sys/amd64/include/clock.h
+++ b/sys/amd64/include/clock.h
@@ -3,7 +3,7 @@
* Garrett Wollman, September 1994.
* This file is in the public domain.
*
- * $Id: clock.h,v 1.19 1996/10/17 17:31:25 bde Exp $
+ * $Id: clock.h,v 1.20 1996/10/25 13:01:08 bde Exp $
*/
#ifndef _MACHINE_CLOCK_H_
@@ -65,7 +65,11 @@ int sysbeep __P((int pitch, int period));
#ifdef CLOCK_HAIR
+#ifdef PC98
+#include <pc98/pc98/pc98.h> /* XXX */
+#else
#include <i386/isa/isa.h> /* XXX */
+#endif
#include <i386/isa/timerreg.h> /* XXX */
static __inline u_int
diff --git a/sys/amd64/isa/timerreg.h b/sys/amd64/isa/timerreg.h
index 5742f66..16fbc0b 100644
--- a/sys/amd64/isa/timerreg.h
+++ b/sys/amd64/isa/timerreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: Header: timerreg.h,v 1.2 93/02/28 15:08:58 mccanne Exp
- * $Id$
+ * $Id: timerreg.h,v 1.2 1993/10/16 13:46:26 rgrimes Exp $
*/
/*
@@ -59,6 +59,7 @@
* in undefined behavior (but hopefully not fry the chip).
* Reading in this manner has no side effects.
*
+ * [IBM-PC]
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
@@ -67,15 +68,31 @@
*
* Timer 0 is used to call hardclock.
* Timer 2 is used to generate console beeps.
+ *
+ * [PC-9801]
+ * The outputs of the three timers are connected as follows:
+ *
+ * timer 0 -> irq 0
+ * timer 1 -> speaker (via keyboard controller)
+ * timer 2 -> RS232C
+ *
+ * Timer 0 is used to call hardclock.
+ * Timer 1 is used to generate console beeps.
*/
/*
* Macros for specifying values to be written into a mode register.
*/
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
+#ifdef PC98
+#define TIMER_CNTR1 0x3fdb /* timer 1 counter port */
+#define TIMER_CNTR2 (IO_TIMER1 + 4) /* timer 2 counter port */
+#define TIMER_MODE (IO_TIMER1 + 6) /* timer mode port */
+#else
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
+#endif
#define TIMER_SEL0 0x00 /* select counter 0 */
#define TIMER_SEL1 0x40 /* select counter 1 */
#define TIMER_SEL2 0x80 /* select counter 2 */
diff --git a/sys/amd64/isa/vector.S b/sys/amd64/isa/vector.S
index 94691f5..0283c2a 100644
--- a/sys/amd64/isa/vector.S
+++ b/sys/amd64/isa/vector.S
@@ -1,12 +1,26 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
- * $Id: vector.s,v 1.19 1996/04/11 21:18:47 bde Exp $
+ * $Id: vector.s,v 1.20 1996/05/31 01:08:08 peter Exp $
+ */
+
+/*
+ * modified for PC98 by Kakefuda
*/
#include "opt_auto_eoi.h"
#include <i386/isa/icu.h>
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
#include <i386/isa/isa.h>
+#endif
+
+#ifdef PC98
+#define ICU_IMR_OFFSET 2 /* IO_ICU{1,2} + 2 */
+#else
+#define ICU_IMR_OFFSET 1 /* IO_ICU{1,2} + 1 */
+#endif
#define ICU_EOI 0x20 /* XXX - define elsewhere */
@@ -168,7 +182,7 @@ IDTVEC(vec_name) ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
orb $IRQ_BIT(irq_num),%al ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
- outb %al,$icu+1 ; \
+ outb %al,$icu+ICU_IMR_OFFSET ; \
enable_icus ; \
incl _cnt+V_INTR ; /* tally interrupts */ \
movl _cpl,%eax ; \
@@ -190,7 +204,7 @@ __CONCAT(Xresume,irq_num): ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
andb $~IRQ_BIT(irq_num),%al ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
- outb %al,$icu+1 ; \
+ outb %al,$icu+ICU_IMR_OFFSET ; \
sti ; /* XXX _doreti repeats the cli/sti */ \
MEXITCOUNT ; \
/* We could usually avoid the following jmp by inlining some of */ \
diff --git a/sys/amd64/isa/vector.s b/sys/amd64/isa/vector.s
index 94691f5..0283c2a 100644
--- a/sys/amd64/isa/vector.s
+++ b/sys/amd64/isa/vector.s
@@ -1,12 +1,26 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
- * $Id: vector.s,v 1.19 1996/04/11 21:18:47 bde Exp $
+ * $Id: vector.s,v 1.20 1996/05/31 01:08:08 peter Exp $
+ */
+
+/*
+ * modified for PC98 by Kakefuda
*/
#include "opt_auto_eoi.h"
#include <i386/isa/icu.h>
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
#include <i386/isa/isa.h>
+#endif
+
+#ifdef PC98
+#define ICU_IMR_OFFSET 2 /* IO_ICU{1,2} + 2 */
+#else
+#define ICU_IMR_OFFSET 1 /* IO_ICU{1,2} + 1 */
+#endif
#define ICU_EOI 0x20 /* XXX - define elsewhere */
@@ -168,7 +182,7 @@ IDTVEC(vec_name) ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
orb $IRQ_BIT(irq_num),%al ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
- outb %al,$icu+1 ; \
+ outb %al,$icu+ICU_IMR_OFFSET ; \
enable_icus ; \
incl _cnt+V_INTR ; /* tally interrupts */ \
movl _cpl,%eax ; \
@@ -190,7 +204,7 @@ __CONCAT(Xresume,irq_num): ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
andb $~IRQ_BIT(irq_num),%al ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
- outb %al,$icu+1 ; \
+ outb %al,$icu+ICU_IMR_OFFSET ; \
sti ; /* XXX _doreti repeats the cli/sti */ \
MEXITCOUNT ; \
/* We could usually avoid the following jmp by inlining some of */ \
diff --git a/sys/amd64/pci/pci_bus.c b/sys/amd64/pci/pci_bus.c
index 4232069..903214c 100644
--- a/sys/amd64/pci/pci_bus.c
+++ b/sys/amd64/pci/pci_bus.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
+** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
**
** pci bus subroutines for i386 architecture.
**
@@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
#define CONF1_ENABLE_RES1 0x80000000ul
#define CONF2_ENABLE_PORT 0x0cf8
+#ifdef PC98
+#define CONF2_FORWARD_PORT 0x0cf9
+#else
#define CONF2_FORWARD_PORT 0x0cfa
+#endif
#define CONF2_ENABLE_CHK 0x0e
#define CONF2_ENABLE_RES 0x0e
diff --git a/sys/amd64/pci/pci_cfgreg.c b/sys/amd64/pci/pci_cfgreg.c
index 4232069..903214c 100644
--- a/sys/amd64/pci/pci_cfgreg.c
+++ b/sys/amd64/pci/pci_cfgreg.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
+** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
**
** pci bus subroutines for i386 architecture.
**
@@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
#define CONF1_ENABLE_RES1 0x80000000ul
#define CONF2_ENABLE_PORT 0x0cf8
+#ifdef PC98
+#define CONF2_FORWARD_PORT 0x0cf9
+#else
#define CONF2_FORWARD_PORT 0x0cfa
+#endif
#define CONF2_ENABLE_CHK 0x0e
#define CONF2_ENABLE_RES 0x0e
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index fef4b97..08f74ae 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.pc98,v 1.7 1996/09/12 11:09:18 asami Exp $
+# $Id: files.pc98,v 1.8 1996/10/23 07:24:49 asami Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -43,7 +43,7 @@ i386/i386/db_disasm.c optional ddb
i386/i386/db_interface.c optional ddb
i386/i386/db_trace.c optional ddb
i386/i386/i386-gdbstub.c optional ddb
-pc98/i386/exception.s standard
+i386/i386/exception.s standard
i386/i386/identcpu.c standard
i386/i386/in_cksum.c optional inet
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
@@ -62,7 +62,7 @@ i386/i386/swtch.s standard
i386/i386/sys_machdep.c standard
pc98/i386/trap.c standard
pc98/i386/userconfig.c optional userconfig
-pc98/i386/vm_machdep.c standard
+i386/i386/vm_machdep.c standard
i386/ibcs2/ibcs2_fcntl.c optional ibcs2
i386/ibcs2/ibcs2_stat.c optional ibcs2
i386/ibcs2/ibcs2_ipc.c optional ibcs2
@@ -89,7 +89,7 @@ pc98/pc98/bs/bshw.c optional bs device-driver
pc98/pc98/bs/bsif.c optional bs device-driver
pc98/pc98/sbic55.c optional sbic device-driver
#i386/pc98/aha1542.c optional aha device-driver
-pc98/pc98/aic6360.c optional aic device-driver
+i386/isa/aic6360.c optional aic device-driver
pc98/pc98/b004.c optional bqu device-driver
i386/pc98/bt742a.c optional bt device-driver
i386/pc98/bt5xx-445.c optional bt device-driver
@@ -130,8 +130,8 @@ pc98/pc98/mse.c optional mse device-driver
pc98/isa/ncr5380.c optional nca device-driver
pc98/pc98/npx.c optional npx device-driver
pc98/pc98/pcaudio.c optional pca device-driver
-pc98/pc98/matcd/matcd.c optional matcd device-driver
-pc98/pc98/pcibus.c optional pci device-driver
+i386/isa/matcd/matcd.c optional matcd device-driver
+i386/isa/pcibus.c optional pci device-driver
i386/isa/pcicx.c optional ze device-driver
i386/isa/pcicx.c optional zp device-driver
pc98/isa/pcvt/pcvt_drv.c optional vt device-driver
@@ -140,11 +140,11 @@ pc98/isa/pcvt/pcvt_kbd.c optional vt device-driver
pc98/isa/pcvt/pcvt_out.c optional vt device-driver
pc98/isa/pcvt/pcvt_sup.c optional vt device-driver
pc98/isa/pcvt/pcvt_vtf.c optional vt device-driver
-pc98/pc98/prof_machdep.c optional profiling-routine
+i386/isa/prof_machdep.c optional profiling-routine
pc98/pc98/psm.c optional psm device-driver
pc98/isa/qcam.c optional qcam device-driver
pc98/isa/qcamio.c optional qcam device-driver
-pc98/pc98/random_machdep.c standard
+i386/isa/random_machdep.c standard
pc98/isa/rc.c optional rc device-driver
i386/isa/scd.c optional scd device-driver
pc98/isa/seagate.c optional sea device-driver
@@ -152,51 +152,51 @@ pc98/isa/si.c optional si device-driver
pc98/isa/si_code.c optional si device-driver
pc98/pc98/sio.c optional sio device-driver
pc98/pc98/sound/pcm86.c optional pcm device-driver
-pc98/pc98/sound/dev_table.c optional snd device-driver
+i386/isa/sound/dev_table.c optional snd device-driver
pc98/pc98/sound/soundcard.c optional snd device-driver
pc98/pc98/sound/sound_switch.c optional snd device-driver
-pc98/pc98/sound/audio.c optional snd device-driver
-pc98/pc98/sound/dmabuf.c optional snd device-driver
-pc98/pc98/sound/sys_timer.c optional snd device-driver
-pc98/pc98/sound/sequencer.c optional snd device-driver
-pc98/pc98/sound/patmgr.c optional snd device-driver
-pc98/pc98/sound/adlib_card.c optional opl device-driver
+i386/isa/sound/audio.c optional snd device-driver
+i386/isa/sound/dmabuf.c optional snd device-driver
+i386/isa/sound/sys_timer.c optional snd device-driver
+i386/isa/sound/sequencer.c optional snd device-driver
+i386/isa/sound/patmgr.c optional snd device-driver
+i386/isa/sound/adlib_card.c optional opl device-driver
pc98/pc98/sound/opl3.c optional opl device-driver
-pc98/pc98/sound/gus_card.c optional gus device-driver
-pc98/pc98/sound/gus_midi.c optional gus device-driver
-pc98/pc98/sound/gus_vol.c optional gus device-driver
-pc98/pc98/sound/gus_wave.c optional gus device-driver
-pc98/pc98/sound/ics2101.c optional gus device-driver
-pc98/pc98/sound/sound_timer.c optional gus device-driver
-pc98/pc98/sound/midi_synth.c optional gus device-driver
-pc98/pc98/sound/midibuf.c optional gus device-driver
+i386/isa/sound/gus_card.c optional gus device-driver
+i386/isa/sound/gus_midi.c optional gus device-driver
+i386/isa/sound/gus_vol.c optional gus device-driver
+i386/isa/sound/gus_wave.c optional gus device-driver
+i386/isa/sound/ics2101.c optional gus device-driver
+i386/isa/sound/sound_timer.c optional gus device-driver
+i386/isa/sound/midi_synth.c optional gus device-driver
+i386/isa/sound/midibuf.c optional gus device-driver
pc98/pc98/sound/ad1848.c optional gusxvi device-driver
pc98/pc98/sound/ad1848.c optional gus device-driver
pc98/pc98/sound/ad1848.c optional mss device-driver
-pc98/pc98/sound/midi_synth.c optional mss device-driver
-pc98/pc98/sound/midibuf.c optional mss device-driver
-pc98/pc98/sound/mpu401.c optional mpu device-driver
-pc98/pc98/sound/midi_synth.c optional mpu device-driver
-pc98/pc98/sound/midibuf.c optional mpu device-driver
-pc98/pc98/sound/pas2_card.c optional pas device-driver
-pc98/pc98/sound/pas2_midi.c optional pas device-driver
-pc98/pc98/sound/pas2_mixer.c optional pas device-driver
+i386/isa/sound/midi_synth.c optional mss device-driver
+i386/isa/sound/midibuf.c optional mss device-driver
+i386/isa/sound/mpu401.c optional mpu device-driver
+i386/isa/sound/midi_synth.c optional mpu device-driver
+i386/isa/sound/midibuf.c optional mpu device-driver
+i386/isa/sound/pas2_card.c optional pas device-driver
+i386/isa/sound/pas2_midi.c optional pas device-driver
+i386/isa/sound/pas2_mixer.c optional pas device-driver
pc98/pc98/sound/pas2_pcm.c optional pas device-driver
-pc98/pc98/sound/midi_synth.c optional pas device-driver
-pc98/pc98/sound/midibuf.c optional pas device-driver
-pc98/pc98/sound/sb_card.c optional sb device-driver
+i386/isa/sound/midi_synth.c optional pas device-driver
+i386/isa/sound/midibuf.c optional pas device-driver
+i386/isa/sound/sb_card.c optional sb device-driver
pc98/pc98/sound/sb_dsp.c optional sb device-driver
-pc98/pc98/sound/sb_midi.c optional sb device-driver
-pc98/pc98/sound/sb_mixer.c optional sb device-driver
-pc98/pc98/sound/midi_synth.c optional sb device-driver
-pc98/pc98/sound/midibuf.c optional sb device-driver
+i386/isa/sound/sb_midi.c optional sb device-driver
+i386/isa/sound/sb_mixer.c optional sb device-driver
+i386/isa/sound/midi_synth.c optional sb device-driver
+i386/isa/sound/midibuf.c optional sb device-driver
pc98/pc98/sound/sb16_dsp.c optional sbxvi device-driver
pc98/pc98/sound/sb16_midi.c optional sbmidi device-driver
-pc98/pc98/sound/uart6850.c optional uart device-driver
-pc98/pc98/sound/midi_synth.c optional uart device-driver
-pc98/pc98/sound/midibuf.c optional uart device-driver
-pc98/pc98/sound/trix.c optional trix device-driver
-pc98/pc98/sound/sscape.c optional sscape device-driver
+i386/isa/sound/uart6850.c optional uart device-driver
+i386/isa/sound/midi_synth.c optional uart device-driver
+i386/isa/sound/midibuf.c optional uart device-driver
+i386/isa/sound/trix.c optional trix device-driver
+i386/isa/sound/sscape.c optional sscape device-driver
pc98/isa/spigot.c optional spigot device-driver
pc98/pc98/spkr.c optional speaker device-driver
pc98/isa/stallion.c optional stl device-driver
@@ -205,7 +205,7 @@ pc98/isa/tw.c optional tw device-driver
pc98/isa/ultra14f.c optional uha device-driver
pc98/pc98/wd.c optional wdc device-driver
pc98/pc98/wd.c optional wd device-driver
-pc98/pc98/atapi.c optional atapi device-driver
+i386/isa/atapi.c optional atapi device-driver
pc98/pc98/wcd.c optional wcd device-driver
pc98/isa/wd7000.c optional wds device-driver
pc98/pc98/wt.c optional wt device-driver
diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98
index 3f3edc68..106083c 100644
--- a/sys/conf/options.pc98
+++ b/sys/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.6 1996/10/23 07:24:55 asami Exp $
+# $Id: options.pc98,v 1.7 1996/10/29 08:36:14 asami Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -29,6 +29,8 @@ XSERVER opt_pcvt.h
AHC_TAGENABLE opt_aic7xxx.h
AHC_SCBPAGING_ENABLE opt_aic7xxx.h
+AHC_FORCE_PIO opt_aic7xxx.h
+AHC_SHARE_SCBS opt_aic7xxx.h
CLK_CALIBRATION_LOOP opt_clock.h
CLK_USE_I8254_CALIBRATION opt_clock.h
diff --git a/sys/dev/kbd/kbdtables.h b/sys/dev/kbd/kbdtables.h
index 1c832cb..9f69ee4 100644
--- a/sys/dev/kbd/kbdtables.h
+++ b/sys/dev/kbd/kbdtables.h
@@ -25,11 +25,150 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: kbdtables.h,v 1.30 1995/12/10 13:38:53 phk Exp $
+ * $Id: kbdtables.h,v 1.31 1996/01/25 16:37:20 ache Exp $
*/
#define SET8 0x80 /* set eight bit on */
+#ifdef PC98
+/* PC-9801 keymap by kuribo@isl.melco.co.jp */
+static keymap_t key_map = { 0x80, /* PC98 keymap */
+/* alt
+ * scan cntrl alt alt cntrl
+ * code base shift cntrl shift alt shift cntrl shift spcl flgs
+ * ---------------------------------------------------------------------------
+ */
+/* sc=00 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
+/* sc=01 */ '1', '!', '!', '!', '1', '!', '!', '!', 0x00, 0x00,
+/* sc=02 */ '2', '\"', 0x1A, 0x1A, '2', '@', 0x00, 0x00, 0x00, 0x00,
+/* sc=03 */ '3', '#', 0x1B, 0x1B, '3', '#', 0x1B, 0x1B, 0x00, 0x00,
+/* sc=04 */ '4', '$', 0x1C, 0x1C, '4', '$', 0x1C, 0x1C, 0x00, 0x00,
+/* sc=05 */ '5', '%', 0x1D, 0x1D, '5', '%', 0x1D, 0x1D, 0x00, 0x00,
+/* sc=06 */ '6', '&', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00,
+/* sc=07 */ '7', '\'', 0x1F, 0x1F, '7', '&', '&', '&', 0x00, 0x00,
+/* sc=08 */ '8', '(', 0x7F, 0x7F, '8', '*', 0x08, 0x08, 0x00, 0x00,
+/* sc=09 */ '9', ')', '9', '9', '9', '(', '(', '(', 0x00, 0x00,
+/* sc=0a */ '0', NOP, '0', '0', '0', ')', ')', ')', 0x40, 0x00,
+/* sc=0b */ '-', '=', '-', '-', '-', '_', 0x1F, 0x1F, 0x00, 0x00,
+/* sc=0c */ '^', '`', 0x1E, 0x1E, '=', '+', '+', '+', 0x00, 0x00,
+/* sc=0d */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00,
+/* sc=0e */ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
+/* sc=0f */ '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', 0x00, 0x00,
+/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
+/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
+/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
+/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
+/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
+/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
+/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
+/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
+/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
+/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
+/* sc=1a */ '@', '~', 0x00, 0x00, '[', '{', 0x1B, 0x1B, 0x00, 0x00,
+/* sc=1b */ '[', '{', 0x1B, 0x1B, ']', '}', 0x1D, 0x1D, 0x00, 0x00,
+/* sc=1c */ '\r', '\r', '\n', '\n', '\r', '\r', '\n', '\n', 0x00, 0x00,
+/* sc=1d */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
+/* sc=1e */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
+/* sc=1f */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
+/* sc=20 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
+/* sc=21 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
+/* sc=22 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
+/* sc=23 */ 'j', 'J', '\n', '\n', 'j', 'J', '\n', '\n', 0x00, 0x01,
+/* sc=24 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
+/* sc=25 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
+/* sc=26 */ ';', '+', ';', ';', ';', ':', ';', ';', 0x00, 0x00,
+/* sc=27 */ ':', '*', ':', ':', '\'', '\"', '\'', '\'', 0x00, 0x00,
+/* sc=28 */ ']', '}', 0x1D, 0x1D, '`', '~', '~', '~', 0x00, 0x00,
+/* sc=29 */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
+/* sc=2a */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
+/* sc=2b */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
+/* sc=2c */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
+/* sc=2d */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
+/* sc=2e */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
+/* sc=2f */ 'm', 'M', '\r', '\r', 'm', 'M', '\r', '\r', 0x00, 0x01,
+/* sc=30 */ ',', '<', '<', '<', ',', '<', '<', '<', 0x00, 0x00,
+/* sc=31 */ '.', '>', '>', '>', '.', '>', '>', '>', 0x00, 0x00,
+/* sc=32 */ '/', '?', 0x7F, 0x7F, '/', '?', 0x7F, 0x7F, 0x00, 0x00,
+/* sc=33 */ NOP, '_', 0x1F, 0x1F, '\\', '|', 0x1C, 0x1C, 0x80, 0x00,
+/* sc=34 */ ' ', ' ', 0x00, 0x00, ' ', ' ', 0x00, 0x00, 0x00, 0x00,
+/* sc=35 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
+/* sc=36 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
+/* sc=37 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
+/* sc=38 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
+/* sc=39 */ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, RBT, RBT, 0x03, 0x02,
+/* sc=3a */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
+/* sc=3b */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
+/* sc=3c */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
+/* sc=3d */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
+/* sc=3e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
+/* sc=3f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=40 */ '-', '-', '-', '-', '-', '-', '-', '-', 0x00, 0x00,
+/* sc=41 */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00,
+/* sc=42 */ '7', '7', '7', '7', '7', '7', '7', '7', 0x00, 0x00,
+/* sc=43 */ '8', '8', '8', '8', '8', '8', '8', '8', 0x00, 0x00,
+/* sc=44 */ '9', '9', '9', '9', '9', '9', '9', '9', 0x00, 0x00,
+/* sc=45 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00,
+/* sc=46 */ '4', '4', '4', '4', '4', '4', '4', '4', 0x00, 0x00,
+/* sc=47 */ '5', '5', '5', '5', '5', '5', '5', '5', 0x00, 0x00,
+/* sc=48 */ '6', '6', '6', '6', '6', '6', '6', '6', 0x00, 0x00,
+/* sc=49 */ '+', '+', '+', '+', '+', '+', '+', '+', 0x00, 0x00,
+/* sc=4a */ '1', '1', '1', '1', '1', '1', '1', '1', 0x00, 0x00,
+/* sc=4b */ '2', '2', '2', '2', '2', '2', '2', '2', 0x00, 0x00,
+/* sc=4c */ '3', '3', '3', '3', '3', '3', '3', '3', 0x00, 0x00,
+/* sc=4d */ '=', '=', '=', '=', '=', '=', '=', '=', 0x00, 0x00,
+/* sc=4e */ '0', '0', '0', '0', '0', '0', '0', '0', 0x00, 0x00,
+/* sc=4f */ ',', ',', ',', ',', ',', ',', ',', ',', 0x00, 0x00,
+/* sc=50 */ '.', '.', '.', '.', '.', '.', '.', '.', 0x00, 0x00,
+/* sc=51 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
+/* sc=52 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
+/* sc=53 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
+/* sc=54 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
+/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=57 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=58 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=59 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=60 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
+/* sc=61 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=62 */ F( 1), F(13), F(25), F(37), S( 1), S( 1), S( 1), S( 1), 0xFF, 0x00,
+/* sc=63 */ F( 2), F(14), F(26), F(38), S( 2), S( 2), S( 2), S( 2), 0xFF, 0x00,
+/* sc=64 */ F( 3), F(15), F(27), F(39), S( 3), S( 3), S( 3), S( 3), 0xFF, 0x00,
+/* sc=65 */ F( 4), F(16), F(28), F(40), S( 4), S( 4), S( 4), S( 4), 0xFF, 0x00,
+/* sc=66 */ F( 5), F(17), F(29), F(41), S( 5), S( 5), S( 5), S( 5), 0xFF, 0x00,
+/* sc=67 */ F( 6), F(18), F(30), F(42), S( 6), S( 6), S( 6), S( 6), 0xFF, 0x00,
+/* sc=68 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
+/* sc=69 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
+/* sc=6a */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
+/* sc=6b */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
+/* sc=6c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=6d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=6e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=6f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=70 */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
+/* sc=71 */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
+/* sc=72 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
+/* sc=73 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
+/* sc=74 */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
+/* sc=75 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=76 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=77 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=78 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=79 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+};
+#endif
+
#ifdef DKKEYMAP
static keymap_t key_map = { 0x6C, /* DK iso8859 keymap */
/* alt
@@ -750,7 +889,7 @@ static keymap_t key_map = { 0xEC, /* keys number */
#endif
-#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP)
+#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP) && !defined(PC98)
static keymap_t key_map = { 0x6C, /* US iso8859 keymap */
/* alt
* scan cntrl alt alt cntrl
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 44b799d..62ff784 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.69 1996/09/28 22:37:43 dyson Exp $
+ * $Id: vm_machdep.c,v 1.70 1996/10/15 03:16:33 dyson Exp $
*/
#include "npx.h"
@@ -66,7 +66,11 @@
#include <sys/user.h>
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
#include <i386/isa/isa.h>
+#endif
#ifdef BOUNCE_BUFFERS
static vm_offset_t
@@ -90,7 +94,11 @@ static int bounceallocarraysize;
static unsigned *bounceallocarray;
static int bouncefree;
+#if defined(PC98) && defined (EPSON_BOUNCEDMA)
+#define SIXTEENMEG (3840*4096) /* 15MB boundary */
+#else
#define SIXTEENMEG (4096*4096)
+#endif
#define MAXBKVA 1024
int maxbkva = MAXBKVA*PAGE_SIZE;
@@ -748,7 +756,7 @@ cpu_reset() {
* to do the reset here would then end up in no man's land.
*/
-#ifndef BROKEN_KEYBOARD_RESET
+#if !defined(BROKEN_KEYBOARD_RESET) && !defined(PC98)
outb(IO_KBD + 4, 0xFE);
DELAY(500000); /* wait 0.5 sec to see if that did it */
printf("Keyboard reset did not work, attempting CPU shutdown\n");
@@ -761,6 +769,12 @@ cpu_reset() {
/* "good night, sweet prince .... <THUNK!>" */
invltlb();
/* NOTREACHED */
+#ifdef PC98
+ asm(" cli ");
+ outb(0x37, 0x0f); /* SHUT 0 = 0 */
+ outb(0x37, 0x0b); /* SHUT 1 = 0 */
+ outb(0xf0, 0x00); /* reset port */
+#endif
while(1);
}
diff --git a/sys/i386/include/clock.h b/sys/i386/include/clock.h
index f20902f..0f3427f 100644
--- a/sys/i386/include/clock.h
+++ b/sys/i386/include/clock.h
@@ -3,7 +3,7 @@
* Garrett Wollman, September 1994.
* This file is in the public domain.
*
- * $Id: clock.h,v 1.19 1996/10/17 17:31:25 bde Exp $
+ * $Id: clock.h,v 1.20 1996/10/25 13:01:08 bde Exp $
*/
#ifndef _MACHINE_CLOCK_H_
@@ -65,7 +65,11 @@ int sysbeep __P((int pitch, int period));
#ifdef CLOCK_HAIR
+#ifdef PC98
+#include <pc98/pc98/pc98.h> /* XXX */
+#else
#include <i386/isa/isa.h> /* XXX */
+#endif
#include <i386/isa/timerreg.h> /* XXX */
static __inline u_int
diff --git a/sys/i386/isa/aic6360.c b/sys/i386/isa/aic6360.c
index d9de4a6..46129e7 100644
--- a/sys/i386/isa/aic6360.c
+++ b/sys/i386/isa/aic6360.c
@@ -31,7 +31,7 @@
*/
/*
- * $Id: aic6360.c,v 1.22 1996/09/06 23:07:07 phk Exp $
+ * $Id: aic6360.c,v 1.23 1996/10/15 19:22:04 bde Exp $
*
* Acknowledgements: Many of the algorithms used in this driver are
* inspired by the work of Julian Elischer (julian@tfs.com) and
@@ -48,6 +48,10 @@
*/
/*
+ * PC-9801-100/AHA-1030P support by URATA S.
+ */
+
+/*
* A few customizable items:
*/
@@ -183,6 +187,9 @@
#define ST_MASK 0x3e /* bit 0,6,7 is reserved */
/* AIC6360 definitions */
+#ifdef PC98
+#include <i386/isa/aic_98.h>
+#else
#define SCSISEQ (iobase + 0x00) /* SCSI sequence control */
#define SXFRCTL0 (iobase + 0x01) /* SCSI transfer control 0 */
#define SXFRCTL1 (iobase + 0x02) /* SCSI transfer control 1 */
@@ -222,6 +229,7 @@
#define STACK (iobase + 0x1d) /* Stack */
#define TEST (iobase + 0x1e) /* Test register */
#define ID (iobase + 0x1f) /* ID register */
+#endif
#define IDSTRING "(C)1991ADAPTECAIC6360 "
@@ -609,6 +617,9 @@ static struct aic_data { /* One of these per adapter */
u_char imess[AIC_MAX_MSG_LEN + 1];
u_char *imp; /* Message pointer (for multibyte messages) */
u_char imlen;
+#ifdef PC98
+ int *aicport; /* I/O port information */
+#endif
} *aicdata[NAIC];
#define AIC_SHOWACBS 0x01
@@ -723,6 +734,15 @@ aicprobe(dev)
bzero(aic, sizeof(struct aic_data));
aicdata[unit] = aic;
aic->iobase = dev->id_iobase;
+#ifdef PC98
+ if (AIC_TYPE98(dev->id_flags) == AIC98_100) {
+ /* PC-9801-100 */
+ aic->aicport = aicport_100;
+ } else {
+ /* generic card */
+ aic->aicport = aicport_generic;
+ }
+#endif
if (aic_find(aic) != 0) {
aicdata[unit] = NULL;
@@ -730,6 +750,11 @@ aicprobe(dev)
return 0;
}
aicunit++;
+
+#ifdef PC98
+ if (AIC_TYPE98(dev->id_flags) == AIC98_100)
+ return 0x40;
+#endif
return 0x20;
}
diff --git a/sys/pc98/pc98/aic_98.h b/sys/i386/isa/aic_98.h
index 8a31101..8a31101 100644
--- a/sys/pc98/pc98/aic_98.h
+++ b/sys/i386/isa/aic_98.h
diff --git a/sys/i386/isa/atapi.c b/sys/i386/isa/atapi.c
index 8fde197..2445dcb 100644
--- a/sys/i386/isa/atapi.c
+++ b/sys/i386/isa/atapi.c
@@ -358,7 +358,12 @@ static struct atapi_params *atapi_probe (int port, int unit)
{
struct atapi_params *ap;
char tb [DEV_BSIZE];
+#ifdef PC98
+ int cnt;
+ outb(0x432,unit%2);
+ print(("unit = %d,select %d\n",unit,unit%2));
+#endif
/* Wait for controller not busy. */
outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
if (atapi_wait (port, 0) < 0) {
@@ -368,8 +373,20 @@ static struct atapi_params *atapi_probe (int port, int unit)
}
/* Issue ATAPI IDENTIFY command. */
+#ifdef PC98
+ outb (port + AR_DRIVE, unit/2 ? ARD_DRIVE1 : ARD_DRIVE0);
+
+ /* Wait for DRQ deassert. */
+ for (cnt=2000; cnt>0; --cnt)
+ if (! (inb (0x640 + AR_STATUS) & ARS_DRQ))
+ break;
+
+ outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
+ DELAY(500);
+#else
outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
+#endif
/* Check that device is present. */
if (inb (port + AR_STATUS) == 0xff) {
@@ -550,7 +567,13 @@ int atapi_start_cmd (struct atapi *ata, struct atapicmd *ac)
ac->result.error = 0;
ac->result.status = 0;
+#ifdef PC98
+ outb(0x432,(ac->unit)%2);
+ print(("(ac->unit) = %d,select %d (2) \n",(ac->unit),(ac->unit)%2));
+ outb (ata->port + AR_DRIVE, (ac->unit)/2 ? ARD_DRIVE1 : ARD_DRIVE0);
+#else
outb (ata->port + AR_DRIVE, ac->unit ? ARD_DRIVE1 : ARD_DRIVE0);
+#endif
if (atapi_wait (ata->port, 0) < 0) {
printf ("atapi%d.%d: controller not ready for cmd\n",
ata->ctrlr, ac->unit);
@@ -632,6 +655,11 @@ int atapi_intr (int ctrlr)
struct atapi *ata = atapitab + ctrlr;
struct atapicmd *ac = ata->queue;
+#ifdef PC98
+ outb(0x432,(ac->unit)%2);
+ print(("atapi_intr:(ac->unit)= %d,select %d\n",ac->unit,(ac->unit)%2));
+#endif
+
if (! ac) {
printf ("atapi%d: stray interrupt\n", ata->ctrlr);
return (0);
diff --git a/sys/i386/isa/atapi.h b/sys/i386/isa/atapi.h
index d43241b..5ff3d34 100644
--- a/sys/i386/isa/atapi.h
+++ b/sys/i386/isa/atapi.h
@@ -17,6 +17,18 @@
/*
* Disk Controller ATAPI register definitions.
*/
+#ifdef PC98
+#define AR_DATA 0x0 /* RW - data register (16 bits) */
+#define AR_ERROR 0x2 /* R - error register */
+#define AR_FEATURES 0x2 /* W - features */
+#define AR_IREASON 0x4 /* RW - interrupt reason */
+#define AR_TAG 0x6 /* - reserved for SAM TAG byte */
+#define AR_CNTLO 0x8 /* RW - byte count, low byte */
+#define AR_CNTHI 0xa /* RW - byte count, high byte */
+#define AR_DRIVE 0xc /* RW - drive select */
+#define AR_COMMAND 0xe /* W - command register */
+#define AR_STATUS 0xe /* R - immediate status */
+#else
#define AR_DATA 0x0 /* RW - data register (16 bits) */
#define AR_ERROR 0x1 /* R - error register */
#define AR_FEATURES 0x1 /* W - features */
@@ -27,6 +39,7 @@
#define AR_DRIVE 0x6 /* RW - drive select */
#define AR_COMMAND 0x7 /* W - command register */
#define AR_STATUS 0x7 /* R - immediate status */
+#endif
/*
* Status register bits
diff --git a/sys/i386/isa/icu.s b/sys/i386/isa/icu.s
index 1107c13..567daf1 100644
--- a/sys/i386/isa/icu.s
+++ b/sys/i386/isa/icu.s
@@ -36,7 +36,7 @@
*
* @(#)icu.s 7.2 (Berkeley) 5/21/91
*
- * $Id: icu.s,v 1.24 1996/03/12 05:44:25 nate Exp $
+ * $Id: icu.s,v 1.25 1996/05/31 01:08:07 peter Exp $
*/
/*
@@ -278,6 +278,7 @@ vec0:
MEXITCOUNT
jmp _Xintr0 /* XXX might need _Xfastintr0 */
+#ifndef PC98
ALIGN_TEXT
vec8:
popl %eax
@@ -287,6 +288,7 @@ vec8:
cli
MEXITCOUNT
jmp _Xintr8 /* XXX might need _Xfastintr8 */
+#endif
#define BUILD_VEC(irq_num) \
ALIGN_TEXT ; \
@@ -301,6 +303,9 @@ __CONCAT(vec,irq_num): ; \
BUILD_VEC(5)
BUILD_VEC(6)
BUILD_VEC(7)
+#ifdef PC98
+ BUILD_VEC(8)
+#endif
BUILD_VEC(9)
BUILD_VEC(10)
BUILD_VEC(11)
diff --git a/sys/i386/isa/kbdtables.h b/sys/i386/isa/kbdtables.h
index 1c832cb..9f69ee4 100644
--- a/sys/i386/isa/kbdtables.h
+++ b/sys/i386/isa/kbdtables.h
@@ -25,11 +25,150 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: kbdtables.h,v 1.30 1995/12/10 13:38:53 phk Exp $
+ * $Id: kbdtables.h,v 1.31 1996/01/25 16:37:20 ache Exp $
*/
#define SET8 0x80 /* set eight bit on */
+#ifdef PC98
+/* PC-9801 keymap by kuribo@isl.melco.co.jp */
+static keymap_t key_map = { 0x80, /* PC98 keymap */
+/* alt
+ * scan cntrl alt alt cntrl
+ * code base shift cntrl shift alt shift cntrl shift spcl flgs
+ * ---------------------------------------------------------------------------
+ */
+/* sc=00 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
+/* sc=01 */ '1', '!', '!', '!', '1', '!', '!', '!', 0x00, 0x00,
+/* sc=02 */ '2', '\"', 0x1A, 0x1A, '2', '@', 0x00, 0x00, 0x00, 0x00,
+/* sc=03 */ '3', '#', 0x1B, 0x1B, '3', '#', 0x1B, 0x1B, 0x00, 0x00,
+/* sc=04 */ '4', '$', 0x1C, 0x1C, '4', '$', 0x1C, 0x1C, 0x00, 0x00,
+/* sc=05 */ '5', '%', 0x1D, 0x1D, '5', '%', 0x1D, 0x1D, 0x00, 0x00,
+/* sc=06 */ '6', '&', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00,
+/* sc=07 */ '7', '\'', 0x1F, 0x1F, '7', '&', '&', '&', 0x00, 0x00,
+/* sc=08 */ '8', '(', 0x7F, 0x7F, '8', '*', 0x08, 0x08, 0x00, 0x00,
+/* sc=09 */ '9', ')', '9', '9', '9', '(', '(', '(', 0x00, 0x00,
+/* sc=0a */ '0', NOP, '0', '0', '0', ')', ')', ')', 0x40, 0x00,
+/* sc=0b */ '-', '=', '-', '-', '-', '_', 0x1F, 0x1F, 0x00, 0x00,
+/* sc=0c */ '^', '`', 0x1E, 0x1E, '=', '+', '+', '+', 0x00, 0x00,
+/* sc=0d */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00,
+/* sc=0e */ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
+/* sc=0f */ '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', 0x00, 0x00,
+/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
+/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
+/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
+/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
+/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
+/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
+/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
+/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
+/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
+/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
+/* sc=1a */ '@', '~', 0x00, 0x00, '[', '{', 0x1B, 0x1B, 0x00, 0x00,
+/* sc=1b */ '[', '{', 0x1B, 0x1B, ']', '}', 0x1D, 0x1D, 0x00, 0x00,
+/* sc=1c */ '\r', '\r', '\n', '\n', '\r', '\r', '\n', '\n', 0x00, 0x00,
+/* sc=1d */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
+/* sc=1e */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
+/* sc=1f */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
+/* sc=20 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
+/* sc=21 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
+/* sc=22 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
+/* sc=23 */ 'j', 'J', '\n', '\n', 'j', 'J', '\n', '\n', 0x00, 0x01,
+/* sc=24 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
+/* sc=25 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
+/* sc=26 */ ';', '+', ';', ';', ';', ':', ';', ';', 0x00, 0x00,
+/* sc=27 */ ':', '*', ':', ':', '\'', '\"', '\'', '\'', 0x00, 0x00,
+/* sc=28 */ ']', '}', 0x1D, 0x1D, '`', '~', '~', '~', 0x00, 0x00,
+/* sc=29 */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
+/* sc=2a */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
+/* sc=2b */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
+/* sc=2c */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
+/* sc=2d */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
+/* sc=2e */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
+/* sc=2f */ 'm', 'M', '\r', '\r', 'm', 'M', '\r', '\r', 0x00, 0x01,
+/* sc=30 */ ',', '<', '<', '<', ',', '<', '<', '<', 0x00, 0x00,
+/* sc=31 */ '.', '>', '>', '>', '.', '>', '>', '>', 0x00, 0x00,
+/* sc=32 */ '/', '?', 0x7F, 0x7F, '/', '?', 0x7F, 0x7F, 0x00, 0x00,
+/* sc=33 */ NOP, '_', 0x1F, 0x1F, '\\', '|', 0x1C, 0x1C, 0x80, 0x00,
+/* sc=34 */ ' ', ' ', 0x00, 0x00, ' ', ' ', 0x00, 0x00, 0x00, 0x00,
+/* sc=35 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
+/* sc=36 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
+/* sc=37 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
+/* sc=38 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
+/* sc=39 */ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, RBT, RBT, 0x03, 0x02,
+/* sc=3a */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
+/* sc=3b */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
+/* sc=3c */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
+/* sc=3d */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
+/* sc=3e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
+/* sc=3f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=40 */ '-', '-', '-', '-', '-', '-', '-', '-', 0x00, 0x00,
+/* sc=41 */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00,
+/* sc=42 */ '7', '7', '7', '7', '7', '7', '7', '7', 0x00, 0x00,
+/* sc=43 */ '8', '8', '8', '8', '8', '8', '8', '8', 0x00, 0x00,
+/* sc=44 */ '9', '9', '9', '9', '9', '9', '9', '9', 0x00, 0x00,
+/* sc=45 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00,
+/* sc=46 */ '4', '4', '4', '4', '4', '4', '4', '4', 0x00, 0x00,
+/* sc=47 */ '5', '5', '5', '5', '5', '5', '5', '5', 0x00, 0x00,
+/* sc=48 */ '6', '6', '6', '6', '6', '6', '6', '6', 0x00, 0x00,
+/* sc=49 */ '+', '+', '+', '+', '+', '+', '+', '+', 0x00, 0x00,
+/* sc=4a */ '1', '1', '1', '1', '1', '1', '1', '1', 0x00, 0x00,
+/* sc=4b */ '2', '2', '2', '2', '2', '2', '2', '2', 0x00, 0x00,
+/* sc=4c */ '3', '3', '3', '3', '3', '3', '3', '3', 0x00, 0x00,
+/* sc=4d */ '=', '=', '=', '=', '=', '=', '=', '=', 0x00, 0x00,
+/* sc=4e */ '0', '0', '0', '0', '0', '0', '0', '0', 0x00, 0x00,
+/* sc=4f */ ',', ',', ',', ',', ',', ',', ',', ',', 0x00, 0x00,
+/* sc=50 */ '.', '.', '.', '.', '.', '.', '.', '.', 0x00, 0x00,
+/* sc=51 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
+/* sc=52 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
+/* sc=53 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
+/* sc=54 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
+/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=57 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=58 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=59 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=60 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
+/* sc=61 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=62 */ F( 1), F(13), F(25), F(37), S( 1), S( 1), S( 1), S( 1), 0xFF, 0x00,
+/* sc=63 */ F( 2), F(14), F(26), F(38), S( 2), S( 2), S( 2), S( 2), 0xFF, 0x00,
+/* sc=64 */ F( 3), F(15), F(27), F(39), S( 3), S( 3), S( 3), S( 3), 0xFF, 0x00,
+/* sc=65 */ F( 4), F(16), F(28), F(40), S( 4), S( 4), S( 4), S( 4), 0xFF, 0x00,
+/* sc=66 */ F( 5), F(17), F(29), F(41), S( 5), S( 5), S( 5), S( 5), 0xFF, 0x00,
+/* sc=67 */ F( 6), F(18), F(30), F(42), S( 6), S( 6), S( 6), S( 6), 0xFF, 0x00,
+/* sc=68 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
+/* sc=69 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
+/* sc=6a */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
+/* sc=6b */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
+/* sc=6c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=6d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=6e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=6f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=70 */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
+/* sc=71 */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
+/* sc=72 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
+/* sc=73 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
+/* sc=74 */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
+/* sc=75 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=76 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=77 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=78 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=79 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+};
+#endif
+
#ifdef DKKEYMAP
static keymap_t key_map = { 0x6C, /* DK iso8859 keymap */
/* alt
@@ -750,7 +889,7 @@ static keymap_t key_map = { 0xEC, /* keys number */
#endif
-#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP)
+#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP) && !defined(PC98)
static keymap_t key_map = { 0x6C, /* US iso8859 keymap */
/* alt
* scan cntrl alt alt cntrl
diff --git a/sys/i386/isa/matcd/creative.h b/sys/i386/isa/matcd/creative.h
index 0877a78..72a12ad 100644
--- a/sys/i386/isa/matcd/creative.h
+++ b/sys/i386/isa/matcd/creative.h
@@ -98,13 +98,20 @@ See matcd.c for Edit History
#define CMD 0 /*Write - commands*/
#define DATA 0 /*Read - data/status from drive*/
+#ifdef PC98
+#define PHASE 0x100 /*Write - switch between data/status*/
+#define STATUS 0x100 /*Read - bus status */
+#define RESET 0x200 /*Write - reset all attached drives*/
+#define ALTDATA 0x200 /*<20>Read - data on non Creative bds.*/
+#define SELECT 0x300 /*Write - drive select*/
+#else /* !PC98 */
#define PHASE 1 /*Write - switch between data/status*/
#define STATUS 1 /*Read - bus status*/
#define RESET 2 /*Write - reset all attached drives*/
/*Any value written will reset*/
#define ALTDATA 2 /*<20>Read - data on non Creative bds.*/
#define SELECT 3 /*Write - drive select*/
-
+#endif /*PC98*/
/* Creative PHASE port bit assignments
*/
diff --git a/sys/i386/isa/matcd/options.h b/sys/i386/isa/matcd/options.h
index af0db68..3fde880 100644
--- a/sys/i386/isa/matcd/options.h
+++ b/sys/i386/isa/matcd/options.h
@@ -184,6 +184,16 @@
#ifdef AUTOHUNT
static int port_hints[]={
+#ifdef PC98
+ 0x30d2,
+ 0x30d0,
+ 0x30d4,
+ 0x30d6,
+ 0x30d8,
+ 0x30da,
+ 0x30dc,
+ 0x30de,
+#else /* IBM-PC */
0x230, /*SB Pro & SB16*/
0x240, /*SB Pro & SB16*/
0x250, /*Creative omniCD standalone boards*/
@@ -205,6 +215,7 @@ static int port_hints[]={
0x670, /*IBM*/
0x690, /*IBM*/
#endif /*0*/
+#endif /* PC98 */
-1}; /*use. Table MUST end with -1*/
#endif /*AUTOHUNT*/
diff --git a/sys/i386/isa/pcibus.c b/sys/i386/isa/pcibus.c
index 4232069..903214c 100644
--- a/sys/i386/isa/pcibus.c
+++ b/sys/i386/isa/pcibus.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
+** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
**
** pci bus subroutines for i386 architecture.
**
@@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
#define CONF1_ENABLE_RES1 0x80000000ul
#define CONF2_ENABLE_PORT 0x0cf8
+#ifdef PC98
+#define CONF2_FORWARD_PORT 0x0cf9
+#else
#define CONF2_FORWARD_PORT 0x0cfa
+#endif
#define CONF2_ENABLE_CHK 0x0e
#define CONF2_ENABLE_RES 0x0e
diff --git a/sys/i386/isa/prof_machdep.c b/sys/i386/isa/prof_machdep.c
index 62c8df5..a8603cb 100644
--- a/sys/i386/isa/prof_machdep.c
+++ b/sys/i386/isa/prof_machdep.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: prof_machdep.c,v 1.2 1996/04/08 16:41:06 wollman Exp $
+ * $Id: prof_machdep.c,v 1.3 1996/10/17 19:32:10 bde Exp $
*/
#ifdef GUPROF
@@ -40,7 +40,11 @@
#include <machine/profile.h>
#endif
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
#include <i386/isa/isa.h>
+#endif
#include <i386/isa/timerreg.h>
#ifdef GUPROF
diff --git a/sys/i386/isa/random_machdep.c b/sys/i386/isa/random_machdep.c
index 227b707..7a13baf 100644
--- a/sys/i386/isa/random_machdep.c
+++ b/sys/i386/isa/random_machdep.c
@@ -1,7 +1,7 @@
/*
* random_machdep.c -- A strong random number generator
*
- * $Id: random_machdep.c,v 1.11 1996/09/27 13:25:13 peter Exp $
+ * $Id: random_machdep.c,v 1.12 1996/10/09 19:47:32 bde Exp $
*
* Version 0.95, last modified 18-Oct-95
*
@@ -51,7 +51,11 @@
#include <machine/random.h>
#include <i386/isa/icu.h>
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
#include <i386/isa/isa.h>
+#endif
#include <i386/isa/timerreg.h>
#define MAX_BLKDEV 4
diff --git a/sys/i386/isa/sound/dev_table.h b/sys/i386/isa/sound/dev_table.h
index 402538c..5269f63 100644
--- a/sys/i386/isa/sound/dev_table.h
+++ b/sys/i386/isa/sound/dev_table.h
@@ -302,6 +302,11 @@ struct sound_timer_operations {
{SNDCARD_TRXPRO_SB, "AudioTriX (SB mode)", attach_trix_sb, probe_trix_sb},
{SNDCARD_TRXPRO_MPU, "AudioTriX MIDI", attach_trix_mpu, probe_trix_mpu},
#endif
+#ifdef PC98
+#ifndef EXCLUDE_PCM86
+ {SNDCARD_PCM86, "PC-9801-86/73", attach_pcm86, probe_pcm86},
+#endif
+#endif
{0, "*?*", NULL, NULL}
};
@@ -384,6 +389,11 @@ struct sound_timer_operations {
#ifndef EXCLUDE_YM3812
{SNDCARD_ADLIB, {FM_MONO, 0, 0}, SND_DEFAULT_ENABLE},
#endif
+#ifdef PC98
+#ifndef EXCLUDE_PCM86
+ {SNDCARD_PCM86, {0, 0, 0}, SND_DEFAULT_ENABLE},
+#endif
+#endif
{0, {0}, 0}
};
diff --git a/sys/i386/isa/sound/local.h b/sys/i386/isa/sound/local.h
index e80b780..c243e4b 100644
--- a/sys/i386/isa/sound/local.h
+++ b/sys/i386/isa/sound/local.h
@@ -92,6 +92,14 @@
#define EXCLUDE_UART6850
#endif
+#ifdef PC98
+#include "pcm.h"
+#if NPCM == 0 && !defined(EXCLUDE_PCM86)
+#define EXCLUDE_PCM86
+#endif
+#endif
+
+
/* nothing but a sequencer (Adlib/OPL) ? */
#if NGUS == 0 && NSB == 0 && NSBMIDI == 0 && NPAS == 0 && NMPU == 0 && \
NUART == 0 && NMSS == 0
@@ -99,9 +107,11 @@
#define EXCLUDE_MIDI
#endif
#ifndef EXCLUDE_AUDIO
+#if !defined(PC98) || defined(EXCLUDE_PCM86) && defined(EXCLUDE_MSS)
#define EXCLUDE_AUDIO
#endif
#endif
+#endif
/* nothing but a Midi (MPU/UART) ? */
#if NGUS == 0 && NSB == 0 && NSBMIDI == 0 && NPAS == 0 && NOPL == 0 && \
@@ -111,6 +121,8 @@
#define EXCLUDE_SEQUENCER
#endif
#ifndef EXCLUDE_AUDIO
+#if !defined(PC98) || defined(EXCLUDE_PCM86) && defined(EXCLUDE_MSS)
#define EXCLUDE_AUDIO
#endif
#endif
+#endif
diff --git a/sys/i386/isa/sound/sound_calls.h b/sys/i386/isa/sound/sound_calls.h
index bfe2f44..d52da0b 100644
--- a/sys/i386/isa/sound/sound_calls.h
+++ b/sys/i386/isa/sound/sound_calls.h
@@ -249,6 +249,12 @@ int pss_ioctl (int dev, struct fileinfo *file,
int pss_lseek (int dev, struct fileinfo *file, off_t offset, int orig);
long pss_init(long mem_start);
+#ifdef PC98
+/* From pcm86.c */
+int probe_pcm86(struct address_info *hw_config);
+long attach_pcm86(long mem_start, struct address_info *hw_config);
+#endif PC98
+
/* From aedsp16.c */
int InitAEDSP16_SBPRO(struct address_info *hw_config);
int InitAEDSP16_MSS(struct address_info *hw_config);
diff --git a/sys/i386/isa/sound/sound_config.h b/sys/i386/isa/sound/sound_config.h
index daafcbe..2330fa9 100644
--- a/sys/i386/isa/sound/sound_config.h
+++ b/sys/i386/isa/sound/sound_config.h
@@ -79,24 +79,44 @@ If your card has nonstandard I/O address or IRQ number, change defines
for the following settings in your kernel Makefile */
#ifndef SBC_BASE
+#ifdef PC98
+#define SBC_BASE 0x20d2 /* 0x20d2 is the factory default. */
+#else
#define SBC_BASE 0x220 /* 0x220 is the factory default. */
#endif
+#endif
#ifndef SBC_IRQ
+#ifdef PC98
+#define SBC_IRQ 10 /* IQR10 is not the factory default on PC9821. */
+#else
#define SBC_IRQ 7 /* IQR7 is the factory default. */
#endif
+#endif
#ifndef SBC_DMA
+#ifdef PC98
+#define SBC_DMA 3
+#else
#define SBC_DMA 1
#endif
+#endif
#ifndef SB16_DMA
+#ifdef PC98
+#define SB16_DMA 3
+#else
#define SB16_DMA 6
#endif
+#endif
#ifndef SB16MIDI_BASE
+#ifdef PC98
+#define SB16MIDI_BASE 0x80d2
+#else
#define SB16MIDI_BASE 0x300
#endif
+#endif
#ifndef PAS_BASE
#define PAS_BASE 0x388
@@ -248,7 +268,11 @@ If your card has nonstandard I/O address or IRQ number, change defines
#define DMA_AUTOINIT 0x10
+#ifdef PC98
+#define FM_MONO 0x28d2 /* This is the I/O address used by AdLib */
+#else
#define FM_MONO 0x388 /* This is the I/O address used by AdLib */
+#endif
/* SEQ_MAX_QUEUE is the maximum number of sequencer events buffered by the
driver. (There is no need to alter this) */
diff --git a/sys/i386/isa/timerreg.h b/sys/i386/isa/timerreg.h
index 5742f66..16fbc0b 100644
--- a/sys/i386/isa/timerreg.h
+++ b/sys/i386/isa/timerreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: Header: timerreg.h,v 1.2 93/02/28 15:08:58 mccanne Exp
- * $Id$
+ * $Id: timerreg.h,v 1.2 1993/10/16 13:46:26 rgrimes Exp $
*/
/*
@@ -59,6 +59,7 @@
* in undefined behavior (but hopefully not fry the chip).
* Reading in this manner has no side effects.
*
+ * [IBM-PC]
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
@@ -67,15 +68,31 @@
*
* Timer 0 is used to call hardclock.
* Timer 2 is used to generate console beeps.
+ *
+ * [PC-9801]
+ * The outputs of the three timers are connected as follows:
+ *
+ * timer 0 -> irq 0
+ * timer 1 -> speaker (via keyboard controller)
+ * timer 2 -> RS232C
+ *
+ * Timer 0 is used to call hardclock.
+ * Timer 1 is used to generate console beeps.
*/
/*
* Macros for specifying values to be written into a mode register.
*/
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
+#ifdef PC98
+#define TIMER_CNTR1 0x3fdb /* timer 1 counter port */
+#define TIMER_CNTR2 (IO_TIMER1 + 4) /* timer 2 counter port */
+#define TIMER_MODE (IO_TIMER1 + 6) /* timer mode port */
+#else
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
+#endif
#define TIMER_SEL0 0x00 /* select counter 0 */
#define TIMER_SEL1 0x40 /* select counter 1 */
#define TIMER_SEL2 0x80 /* select counter 2 */
diff --git a/sys/i386/isa/vector.s b/sys/i386/isa/vector.s
index 94691f5..0283c2a 100644
--- a/sys/i386/isa/vector.s
+++ b/sys/i386/isa/vector.s
@@ -1,12 +1,26 @@
/*
* from: vector.s, 386BSD 0.1 unknown origin
- * $Id: vector.s,v 1.19 1996/04/11 21:18:47 bde Exp $
+ * $Id: vector.s,v 1.20 1996/05/31 01:08:08 peter Exp $
+ */
+
+/*
+ * modified for PC98 by Kakefuda
*/
#include "opt_auto_eoi.h"
#include <i386/isa/icu.h>
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
#include <i386/isa/isa.h>
+#endif
+
+#ifdef PC98
+#define ICU_IMR_OFFSET 2 /* IO_ICU{1,2} + 2 */
+#else
+#define ICU_IMR_OFFSET 1 /* IO_ICU{1,2} + 1 */
+#endif
#define ICU_EOI 0x20 /* XXX - define elsewhere */
@@ -168,7 +182,7 @@ IDTVEC(vec_name) ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
orb $IRQ_BIT(irq_num),%al ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
- outb %al,$icu+1 ; \
+ outb %al,$icu+ICU_IMR_OFFSET ; \
enable_icus ; \
incl _cnt+V_INTR ; /* tally interrupts */ \
movl _cpl,%eax ; \
@@ -190,7 +204,7 @@ __CONCAT(Xresume,irq_num): ; \
movb _imen + IRQ_BYTE(irq_num),%al ; \
andb $~IRQ_BIT(irq_num),%al ; \
movb %al,_imen + IRQ_BYTE(irq_num) ; \
- outb %al,$icu+1 ; \
+ outb %al,$icu+ICU_IMR_OFFSET ; \
sti ; /* XXX _doreti repeats the cli/sti */ \
MEXITCOUNT ; \
/* We could usually avoid the following jmp by inlining some of */ \
diff --git a/sys/i386/pci/pci_bus.c b/sys/i386/pci/pci_bus.c
index 4232069..903214c 100644
--- a/sys/i386/pci/pci_bus.c
+++ b/sys/i386/pci/pci_bus.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
+** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
**
** pci bus subroutines for i386 architecture.
**
@@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
#define CONF1_ENABLE_RES1 0x80000000ul
#define CONF2_ENABLE_PORT 0x0cf8
+#ifdef PC98
+#define CONF2_FORWARD_PORT 0x0cf9
+#else
#define CONF2_FORWARD_PORT 0x0cfa
+#endif
#define CONF2_ENABLE_CHK 0x0e
#define CONF2_ENABLE_RES 0x0e
diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c
index 4232069..903214c 100644
--- a/sys/i386/pci/pci_cfgreg.c
+++ b/sys/i386/pci/pci_cfgreg.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
+** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
**
** pci bus subroutines for i386 architecture.
**
@@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
#define CONF1_ENABLE_RES1 0x80000000ul
#define CONF2_ENABLE_PORT 0x0cf8
+#ifdef PC98
+#define CONF2_FORWARD_PORT 0x0cf9
+#else
#define CONF2_FORWARD_PORT 0x0cfa
+#endif
#define CONF2_ENABLE_CHK 0x0e
#define CONF2_ENABLE_RES 0x0e
diff --git a/sys/i386/pci/pci_pir.c b/sys/i386/pci/pci_pir.c
index 4232069..903214c 100644
--- a/sys/i386/pci/pci_pir.c
+++ b/sys/i386/pci/pci_pir.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: pcibus.c,v 1.25 1996/06/13 21:50:41 se Exp $
+** $Id: pcibus.c,v 1.26 1996/06/18 01:22:28 bde Exp $
**
** pci bus subroutines for i386 architecture.
**
@@ -151,7 +151,11 @@ DATA_SET (pcibus_set, i386pci);
#define CONF1_ENABLE_RES1 0x80000000ul
#define CONF2_ENABLE_PORT 0x0cf8
+#ifdef PC98
+#define CONF2_FORWARD_PORT 0x0cf9
+#else
#define CONF2_FORWARD_PORT 0x0cfa
+#endif
#define CONF2_ENABLE_CHK 0x0e
#define CONF2_ENABLE_RES 0x0e
diff --git a/sys/isa/kbdtables.h b/sys/isa/kbdtables.h
index 1c832cb..9f69ee4 100644
--- a/sys/isa/kbdtables.h
+++ b/sys/isa/kbdtables.h
@@ -25,11 +25,150 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: kbdtables.h,v 1.30 1995/12/10 13:38:53 phk Exp $
+ * $Id: kbdtables.h,v 1.31 1996/01/25 16:37:20 ache Exp $
*/
#define SET8 0x80 /* set eight bit on */
+#ifdef PC98
+/* PC-9801 keymap by kuribo@isl.melco.co.jp */
+static keymap_t key_map = { 0x80, /* PC98 keymap */
+/* alt
+ * scan cntrl alt alt cntrl
+ * code base shift cntrl shift alt shift cntrl shift spcl flgs
+ * ---------------------------------------------------------------------------
+ */
+/* sc=00 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
+/* sc=01 */ '1', '!', '!', '!', '1', '!', '!', '!', 0x00, 0x00,
+/* sc=02 */ '2', '\"', 0x1A, 0x1A, '2', '@', 0x00, 0x00, 0x00, 0x00,
+/* sc=03 */ '3', '#', 0x1B, 0x1B, '3', '#', 0x1B, 0x1B, 0x00, 0x00,
+/* sc=04 */ '4', '$', 0x1C, 0x1C, '4', '$', 0x1C, 0x1C, 0x00, 0x00,
+/* sc=05 */ '5', '%', 0x1D, 0x1D, '5', '%', 0x1D, 0x1D, 0x00, 0x00,
+/* sc=06 */ '6', '&', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00,
+/* sc=07 */ '7', '\'', 0x1F, 0x1F, '7', '&', '&', '&', 0x00, 0x00,
+/* sc=08 */ '8', '(', 0x7F, 0x7F, '8', '*', 0x08, 0x08, 0x00, 0x00,
+/* sc=09 */ '9', ')', '9', '9', '9', '(', '(', '(', 0x00, 0x00,
+/* sc=0a */ '0', NOP, '0', '0', '0', ')', ')', ')', 0x40, 0x00,
+/* sc=0b */ '-', '=', '-', '-', '-', '_', 0x1F, 0x1F, 0x00, 0x00,
+/* sc=0c */ '^', '`', 0x1E, 0x1E, '=', '+', '+', '+', 0x00, 0x00,
+/* sc=0d */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00,
+/* sc=0e */ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
+/* sc=0f */ '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', 0x00, 0x00,
+/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
+/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
+/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
+/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
+/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
+/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
+/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
+/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
+/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
+/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
+/* sc=1a */ '@', '~', 0x00, 0x00, '[', '{', 0x1B, 0x1B, 0x00, 0x00,
+/* sc=1b */ '[', '{', 0x1B, 0x1B, ']', '}', 0x1D, 0x1D, 0x00, 0x00,
+/* sc=1c */ '\r', '\r', '\n', '\n', '\r', '\r', '\n', '\n', 0x00, 0x00,
+/* sc=1d */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
+/* sc=1e */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
+/* sc=1f */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
+/* sc=20 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
+/* sc=21 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
+/* sc=22 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
+/* sc=23 */ 'j', 'J', '\n', '\n', 'j', 'J', '\n', '\n', 0x00, 0x01,
+/* sc=24 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
+/* sc=25 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
+/* sc=26 */ ';', '+', ';', ';', ';', ':', ';', ';', 0x00, 0x00,
+/* sc=27 */ ':', '*', ':', ':', '\'', '\"', '\'', '\'', 0x00, 0x00,
+/* sc=28 */ ']', '}', 0x1D, 0x1D, '`', '~', '~', '~', 0x00, 0x00,
+/* sc=29 */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
+/* sc=2a */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
+/* sc=2b */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
+/* sc=2c */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
+/* sc=2d */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
+/* sc=2e */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
+/* sc=2f */ 'm', 'M', '\r', '\r', 'm', 'M', '\r', '\r', 0x00, 0x01,
+/* sc=30 */ ',', '<', '<', '<', ',', '<', '<', '<', 0x00, 0x00,
+/* sc=31 */ '.', '>', '>', '>', '.', '>', '>', '>', 0x00, 0x00,
+/* sc=32 */ '/', '?', 0x7F, 0x7F, '/', '?', 0x7F, 0x7F, 0x00, 0x00,
+/* sc=33 */ NOP, '_', 0x1F, 0x1F, '\\', '|', 0x1C, 0x1C, 0x80, 0x00,
+/* sc=34 */ ' ', ' ', 0x00, 0x00, ' ', ' ', 0x00, 0x00, 0x00, 0x00,
+/* sc=35 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
+/* sc=36 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
+/* sc=37 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
+/* sc=38 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
+/* sc=39 */ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, RBT, RBT, 0x03, 0x02,
+/* sc=3a */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
+/* sc=3b */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
+/* sc=3c */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
+/* sc=3d */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
+/* sc=3e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
+/* sc=3f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=40 */ '-', '-', '-', '-', '-', '-', '-', '-', 0x00, 0x00,
+/* sc=41 */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00,
+/* sc=42 */ '7', '7', '7', '7', '7', '7', '7', '7', 0x00, 0x00,
+/* sc=43 */ '8', '8', '8', '8', '8', '8', '8', '8', 0x00, 0x00,
+/* sc=44 */ '9', '9', '9', '9', '9', '9', '9', '9', 0x00, 0x00,
+/* sc=45 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00,
+/* sc=46 */ '4', '4', '4', '4', '4', '4', '4', '4', 0x00, 0x00,
+/* sc=47 */ '5', '5', '5', '5', '5', '5', '5', '5', 0x00, 0x00,
+/* sc=48 */ '6', '6', '6', '6', '6', '6', '6', '6', 0x00, 0x00,
+/* sc=49 */ '+', '+', '+', '+', '+', '+', '+', '+', 0x00, 0x00,
+/* sc=4a */ '1', '1', '1', '1', '1', '1', '1', '1', 0x00, 0x00,
+/* sc=4b */ '2', '2', '2', '2', '2', '2', '2', '2', 0x00, 0x00,
+/* sc=4c */ '3', '3', '3', '3', '3', '3', '3', '3', 0x00, 0x00,
+/* sc=4d */ '=', '=', '=', '=', '=', '=', '=', '=', 0x00, 0x00,
+/* sc=4e */ '0', '0', '0', '0', '0', '0', '0', '0', 0x00, 0x00,
+/* sc=4f */ ',', ',', ',', ',', ',', ',', ',', ',', 0x00, 0x00,
+/* sc=50 */ '.', '.', '.', '.', '.', '.', '.', '.', 0x00, 0x00,
+/* sc=51 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
+/* sc=52 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
+/* sc=53 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
+/* sc=54 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
+/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=57 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=58 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=59 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=5f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=60 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
+/* sc=61 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=62 */ F( 1), F(13), F(25), F(37), S( 1), S( 1), S( 1), S( 1), 0xFF, 0x00,
+/* sc=63 */ F( 2), F(14), F(26), F(38), S( 2), S( 2), S( 2), S( 2), 0xFF, 0x00,
+/* sc=64 */ F( 3), F(15), F(27), F(39), S( 3), S( 3), S( 3), S( 3), 0xFF, 0x00,
+/* sc=65 */ F( 4), F(16), F(28), F(40), S( 4), S( 4), S( 4), S( 4), 0xFF, 0x00,
+/* sc=66 */ F( 5), F(17), F(29), F(41), S( 5), S( 5), S( 5), S( 5), 0xFF, 0x00,
+/* sc=67 */ F( 6), F(18), F(30), F(42), S( 6), S( 6), S( 6), S( 6), 0xFF, 0x00,
+/* sc=68 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
+/* sc=69 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
+/* sc=6a */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
+/* sc=6b */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
+/* sc=6c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=6d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=6e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=6f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=70 */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
+/* sc=71 */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
+/* sc=72 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
+/* sc=73 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
+/* sc=74 */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
+/* sc=75 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=76 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=77 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=78 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=79 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+/* sc=7f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
+};
+#endif
+
#ifdef DKKEYMAP
static keymap_t key_map = { 0x6C, /* DK iso8859 keymap */
/* alt
@@ -750,7 +889,7 @@ static keymap_t key_map = { 0xEC, /* keys number */
#endif
-#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP)
+#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP) && !defined(PC98)
static keymap_t key_map = { 0x6C, /* US iso8859 keymap */
/* alt
* scan cntrl alt alt cntrl
diff --git a/sys/isa/timerreg.h b/sys/isa/timerreg.h
index 5742f66..16fbc0b 100644
--- a/sys/isa/timerreg.h
+++ b/sys/isa/timerreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: Header: timerreg.h,v 1.2 93/02/28 15:08:58 mccanne Exp
- * $Id$
+ * $Id: timerreg.h,v 1.2 1993/10/16 13:46:26 rgrimes Exp $
*/
/*
@@ -59,6 +59,7 @@
* in undefined behavior (but hopefully not fry the chip).
* Reading in this manner has no side effects.
*
+ * [IBM-PC]
* The outputs of the three timers are connected as follows:
*
* timer 0 -> irq 0
@@ -67,15 +68,31 @@
*
* Timer 0 is used to call hardclock.
* Timer 2 is used to generate console beeps.
+ *
+ * [PC-9801]
+ * The outputs of the three timers are connected as follows:
+ *
+ * timer 0 -> irq 0
+ * timer 1 -> speaker (via keyboard controller)
+ * timer 2 -> RS232C
+ *
+ * Timer 0 is used to call hardclock.
+ * Timer 1 is used to generate console beeps.
*/
/*
* Macros for specifying values to be written into a mode register.
*/
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
+#ifdef PC98
+#define TIMER_CNTR1 0x3fdb /* timer 1 counter port */
+#define TIMER_CNTR2 (IO_TIMER1 + 4) /* timer 2 counter port */
+#define TIMER_MODE (IO_TIMER1 + 6) /* timer mode port */
+#else
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
+#endif
#define TIMER_SEL0 0x00 /* select counter 0 */
#define TIMER_SEL1 0x40 /* select counter 1 */
#define TIMER_SEL2 0x80 /* select counter 2 */
diff --git a/sys/kern/kern_random.c b/sys/kern/kern_random.c
index 227b707..7a13baf 100644
--- a/sys/kern/kern_random.c
+++ b/sys/kern/kern_random.c
@@ -1,7 +1,7 @@
/*
* random_machdep.c -- A strong random number generator
*
- * $Id: random_machdep.c,v 1.11 1996/09/27 13:25:13 peter Exp $
+ * $Id: random_machdep.c,v 1.12 1996/10/09 19:47:32 bde Exp $
*
* Version 0.95, last modified 18-Oct-95
*
@@ -51,7 +51,11 @@
#include <machine/random.h>
#include <i386/isa/icu.h>
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
#include <i386/isa/isa.h>
+#endif
#include <i386/isa/timerreg.h>
#define MAX_BLKDEV 4
diff --git a/sys/pc98/cbus/cbus.h b/sys/pc98/cbus/cbus.h
index 84c77b4..6a369f7 100644
--- a/sys/pc98/cbus/cbus.h
+++ b/sys/pc98/cbus/cbus.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.h 5.7 (Berkeley) 5/9/91
- * $Id: pc98.h,v 1.5 1996/10/09 21:46:34 asami Exp $
+ * $Id: pc98.h,v 1.6 1996/10/23 07:25:22 asami Exp $
*/
#ifndef _PC98_PC98_PC98_H_
@@ -73,7 +73,7 @@
#define IO_NMI 0x050 /* NMI Control */
#define IO_WAIT 0x05F /* WAIT 0.6 us */
#define IO_GDC1 0x060 /* 7220 GDC Text Control */
-#define IO_TIMER 0x071 /* 8253C Timer */
+#define IO_TIMER1 0x071 /* 8253C Timer */
#define IO_SASI 0x080 /* SASI Hard Disk Controller */
#define IO_FD1 0x090 /* 765A 1MB FDC */
#define IO_GDC2 0x0a0 /* 7220 GDC Graphic Control */
diff --git a/sys/pc98/cbus/clock.c b/sys/pc98/cbus/clock.c
index 3e9faf9..0ba9a65 100644
--- a/sys/pc98/cbus/clock.c
+++ b/sys/pc98/cbus/clock.c
@@ -34,7 +34,11 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.8 1996/10/23 07:25:13 asami Exp $
+ * $Id: clock.c,v 1.9 1996/10/29 08:36:19 asami Exp $
+ */
+
+/*
+ * Routines to handle clock hardware.
*/
/*
@@ -48,10 +52,6 @@
* modified for PC98 by Kakefuda
*/
-/*
- * Primitive clock interrupt routines.
- */
-
#include "opt_clock.h"
#include "opt_cpu.h"
@@ -72,13 +72,12 @@
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <i386/isa/isa_device.h>
-#include <pc98/pc98/timerreg.h>
#else
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/rtc.h>
-#include <i386/isa/timerreg.h>
#endif
+#include <i386/isa/timerreg.h>
/*
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
@@ -109,52 +108,49 @@
int adjkerntz; /* local offset from GMT in seconds */
int disable_rtc_set; /* disable resettodr() if != 0 */
-int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
-
u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU)
-u_int i586_ctr_bias;
+u_int i586_ctr_bias;
u_int i586_ctr_comultiplier;
u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
-long long i586_last_tick;
-unsigned long i586_avg_tick;
#endif
int statclock_disable;
u_int stat_imask = SWI_CLOCK_MASK;
#ifdef TIMER_FREQ
-static u_int timer_freq = TIMER_FREQ;
+u_int timer_freq = TIMER_FREQ;
#else
#ifdef PC98
#ifndef AUTO_CLOCK
#ifndef PC98_8M
-static u_int timer_freq = 2457600;
+u_int timer_freq = 2457600;
#else /* !PC98_8M */
-static u_int timer_freq = 1996800;
+u_int timer_freq = 1996800;
#endif /* PC98_8M */
#else /* AUTO_CLOCK */
-static u_int timer_freq = 2457600;
+u_int timer_freq = 2457600;
#endif /* AUTO_CLOCK */
#else /* IBM-PC */
-static u_int timer_freq = 1193182;
+u_int timer_freq = 1193182;
#endif /* PC98 */
#endif
-int timer0_max_count;
-u_int timer0_overflow_threshold;
-u_int timer0_prescaler_count;
+int timer0_max_count;
+u_int timer0_overflow_threshold;
+u_int timer0_prescaler_count;
+int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
static int beeping = 0;
static u_int clk_imask = HWI_MASK | SWI_MASK;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
-static u_int hardclock_max_count;
+static u_int hardclock_max_count;
/*
* XXX new_function and timer_func should not handle clockframes, but
* timer_func currently needs to hold hardclock to handle the
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
* to switch between clkintr() and a slightly different timerintr().
*/
-static void (*new_function) __P((struct clockframe *frame));
-static u_int new_rate;
+static void (*new_function) __P((struct clockframe *frame));
+static u_int new_rate;
#ifndef PC98
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
@@ -171,7 +167,7 @@ static u_char timer0_state;
static u_char timer1_state;
#endif
static u_char timer2_state;
-static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
+static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
int rtc_inb __P((void));
#if defined(I586_CPU) || defined(I686_CPU)
@@ -437,7 +433,7 @@ getit(void)
disable_intr();
/* Select timer0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0);
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
@@ -625,7 +621,7 @@ calibrate_clocks(void)
u_int count, prev_count, tot_count;
int sec, start_sec, timeout;
- printf("Calibrating clock(s) relative to mc146818A clock...\n");
+ printf("Calibrating clock(s) relative to mc146818A clock ... ");
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
goto fail;
timeout = 100000000;
@@ -782,7 +778,7 @@ startrtclock()
if (delta < timer_freq / 100) {
#ifndef CLK_USE_I8254_CALIBRATION
if (bootverbose)
- printf(
+ printf(
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
freq = timer_freq;
#endif
@@ -802,7 +798,7 @@ startrtclock()
#ifndef CLK_USE_I586_CALIBRATION
if (i586_ctr_freq != 0) {
if (bootverbose)
- printf(
+ printf(
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
i586_ctr_freq = 0;
}
@@ -1114,10 +1110,8 @@ cpu_initclocks()
/*
* Finish setting up anti-jitter measures.
*/
- if (i586_ctr_freq != 0) {
- i586_last_tick = rdtsc();
- i586_ctr_bias = i586_last_tick;
- }
+ if (i586_ctr_freq != 0)
+ i586_ctr_bias = rdtsc();
#endif
#ifndef PC98
diff --git a/sys/pc98/cbus/pcrtc.c b/sys/pc98/cbus/pcrtc.c
index 3e9faf9..0ba9a65 100644
--- a/sys/pc98/cbus/pcrtc.c
+++ b/sys/pc98/cbus/pcrtc.c
@@ -34,7 +34,11 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.8 1996/10/23 07:25:13 asami Exp $
+ * $Id: clock.c,v 1.9 1996/10/29 08:36:19 asami Exp $
+ */
+
+/*
+ * Routines to handle clock hardware.
*/
/*
@@ -48,10 +52,6 @@
* modified for PC98 by Kakefuda
*/
-/*
- * Primitive clock interrupt routines.
- */
-
#include "opt_clock.h"
#include "opt_cpu.h"
@@ -72,13 +72,12 @@
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <i386/isa/isa_device.h>
-#include <pc98/pc98/timerreg.h>
#else
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/rtc.h>
-#include <i386/isa/timerreg.h>
#endif
+#include <i386/isa/timerreg.h>
/*
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
@@ -109,52 +108,49 @@
int adjkerntz; /* local offset from GMT in seconds */
int disable_rtc_set; /* disable resettodr() if != 0 */
-int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
-
u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU)
-u_int i586_ctr_bias;
+u_int i586_ctr_bias;
u_int i586_ctr_comultiplier;
u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
-long long i586_last_tick;
-unsigned long i586_avg_tick;
#endif
int statclock_disable;
u_int stat_imask = SWI_CLOCK_MASK;
#ifdef TIMER_FREQ
-static u_int timer_freq = TIMER_FREQ;
+u_int timer_freq = TIMER_FREQ;
#else
#ifdef PC98
#ifndef AUTO_CLOCK
#ifndef PC98_8M
-static u_int timer_freq = 2457600;
+u_int timer_freq = 2457600;
#else /* !PC98_8M */
-static u_int timer_freq = 1996800;
+u_int timer_freq = 1996800;
#endif /* PC98_8M */
#else /* AUTO_CLOCK */
-static u_int timer_freq = 2457600;
+u_int timer_freq = 2457600;
#endif /* AUTO_CLOCK */
#else /* IBM-PC */
-static u_int timer_freq = 1193182;
+u_int timer_freq = 1193182;
#endif /* PC98 */
#endif
-int timer0_max_count;
-u_int timer0_overflow_threshold;
-u_int timer0_prescaler_count;
+int timer0_max_count;
+u_int timer0_overflow_threshold;
+u_int timer0_prescaler_count;
+int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
static int beeping = 0;
static u_int clk_imask = HWI_MASK | SWI_MASK;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
-static u_int hardclock_max_count;
+static u_int hardclock_max_count;
/*
* XXX new_function and timer_func should not handle clockframes, but
* timer_func currently needs to hold hardclock to handle the
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
* to switch between clkintr() and a slightly different timerintr().
*/
-static void (*new_function) __P((struct clockframe *frame));
-static u_int new_rate;
+static void (*new_function) __P((struct clockframe *frame));
+static u_int new_rate;
#ifndef PC98
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
@@ -171,7 +167,7 @@ static u_char timer0_state;
static u_char timer1_state;
#endif
static u_char timer2_state;
-static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
+static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
int rtc_inb __P((void));
#if defined(I586_CPU) || defined(I686_CPU)
@@ -437,7 +433,7 @@ getit(void)
disable_intr();
/* Select timer0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0);
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
@@ -625,7 +621,7 @@ calibrate_clocks(void)
u_int count, prev_count, tot_count;
int sec, start_sec, timeout;
- printf("Calibrating clock(s) relative to mc146818A clock...\n");
+ printf("Calibrating clock(s) relative to mc146818A clock ... ");
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
goto fail;
timeout = 100000000;
@@ -782,7 +778,7 @@ startrtclock()
if (delta < timer_freq / 100) {
#ifndef CLK_USE_I8254_CALIBRATION
if (bootverbose)
- printf(
+ printf(
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
freq = timer_freq;
#endif
@@ -802,7 +798,7 @@ startrtclock()
#ifndef CLK_USE_I586_CALIBRATION
if (i586_ctr_freq != 0) {
if (bootverbose)
- printf(
+ printf(
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
i586_ctr_freq = 0;
}
@@ -1114,10 +1110,8 @@ cpu_initclocks()
/*
* Finish setting up anti-jitter measures.
*/
- if (i586_ctr_freq != 0) {
- i586_last_tick = rdtsc();
- i586_ctr_bias = i586_last_tick;
- }
+ if (i586_ctr_freq != 0)
+ i586_ctr_bias = rdtsc();
#endif
#ifndef PC98
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index 5bd1821..320aaa2 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
-# $Id: GENERIC98,v 1.6 1996/10/09 21:45:41 asami Exp $
+# $Id: GENERIC98,v 1.7 1996/10/23 07:24:45 asami Exp $
# GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
@@ -100,6 +100,9 @@ device wcd0 #IDE CD-ROM
# for any number of installed devices.
controller ncr0
controller ahc0
+options "AHC_FORCE_PIO" # Some motherboards choke on MemI/O,
+ # so use PIO in the ahc driver in the
+ # generic kernel.
controller sbic0 at isa? port "IO_SCSI" bio irq 5 drq 3 vector sbicintr
# sbic55.c.new
diff --git a/sys/pc98/conf/GENERIC98 b/sys/pc98/conf/GENERIC98
index 5bd1821..320aaa2 100644
--- a/sys/pc98/conf/GENERIC98
+++ b/sys/pc98/conf/GENERIC98
@@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
-# $Id: GENERIC98,v 1.6 1996/10/09 21:45:41 asami Exp $
+# $Id: GENERIC98,v 1.7 1996/10/23 07:24:45 asami Exp $
# GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
@@ -100,6 +100,9 @@ device wcd0 #IDE CD-ROM
# for any number of installed devices.
controller ncr0
controller ahc0
+options "AHC_FORCE_PIO" # Some motherboards choke on MemI/O,
+ # so use PIO in the ahc driver in the
+ # generic kernel.
controller sbic0 at isa? port "IO_SCSI" bio irq 5 drq 3 vector sbicintr
# sbic55.c.new
diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98
index fef4b97..08f74ae 100644
--- a/sys/pc98/conf/files.pc98
+++ b/sys/pc98/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.pc98,v 1.7 1996/09/12 11:09:18 asami Exp $
+# $Id: files.pc98,v 1.8 1996/10/23 07:24:49 asami Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -43,7 +43,7 @@ i386/i386/db_disasm.c optional ddb
i386/i386/db_interface.c optional ddb
i386/i386/db_trace.c optional ddb
i386/i386/i386-gdbstub.c optional ddb
-pc98/i386/exception.s standard
+i386/i386/exception.s standard
i386/i386/identcpu.c standard
i386/i386/in_cksum.c optional inet
# locore.s needs to be handled in Makefile to put it first. Otherwise it's
@@ -62,7 +62,7 @@ i386/i386/swtch.s standard
i386/i386/sys_machdep.c standard
pc98/i386/trap.c standard
pc98/i386/userconfig.c optional userconfig
-pc98/i386/vm_machdep.c standard
+i386/i386/vm_machdep.c standard
i386/ibcs2/ibcs2_fcntl.c optional ibcs2
i386/ibcs2/ibcs2_stat.c optional ibcs2
i386/ibcs2/ibcs2_ipc.c optional ibcs2
@@ -89,7 +89,7 @@ pc98/pc98/bs/bshw.c optional bs device-driver
pc98/pc98/bs/bsif.c optional bs device-driver
pc98/pc98/sbic55.c optional sbic device-driver
#i386/pc98/aha1542.c optional aha device-driver
-pc98/pc98/aic6360.c optional aic device-driver
+i386/isa/aic6360.c optional aic device-driver
pc98/pc98/b004.c optional bqu device-driver
i386/pc98/bt742a.c optional bt device-driver
i386/pc98/bt5xx-445.c optional bt device-driver
@@ -130,8 +130,8 @@ pc98/pc98/mse.c optional mse device-driver
pc98/isa/ncr5380.c optional nca device-driver
pc98/pc98/npx.c optional npx device-driver
pc98/pc98/pcaudio.c optional pca device-driver
-pc98/pc98/matcd/matcd.c optional matcd device-driver
-pc98/pc98/pcibus.c optional pci device-driver
+i386/isa/matcd/matcd.c optional matcd device-driver
+i386/isa/pcibus.c optional pci device-driver
i386/isa/pcicx.c optional ze device-driver
i386/isa/pcicx.c optional zp device-driver
pc98/isa/pcvt/pcvt_drv.c optional vt device-driver
@@ -140,11 +140,11 @@ pc98/isa/pcvt/pcvt_kbd.c optional vt device-driver
pc98/isa/pcvt/pcvt_out.c optional vt device-driver
pc98/isa/pcvt/pcvt_sup.c optional vt device-driver
pc98/isa/pcvt/pcvt_vtf.c optional vt device-driver
-pc98/pc98/prof_machdep.c optional profiling-routine
+i386/isa/prof_machdep.c optional profiling-routine
pc98/pc98/psm.c optional psm device-driver
pc98/isa/qcam.c optional qcam device-driver
pc98/isa/qcamio.c optional qcam device-driver
-pc98/pc98/random_machdep.c standard
+i386/isa/random_machdep.c standard
pc98/isa/rc.c optional rc device-driver
i386/isa/scd.c optional scd device-driver
pc98/isa/seagate.c optional sea device-driver
@@ -152,51 +152,51 @@ pc98/isa/si.c optional si device-driver
pc98/isa/si_code.c optional si device-driver
pc98/pc98/sio.c optional sio device-driver
pc98/pc98/sound/pcm86.c optional pcm device-driver
-pc98/pc98/sound/dev_table.c optional snd device-driver
+i386/isa/sound/dev_table.c optional snd device-driver
pc98/pc98/sound/soundcard.c optional snd device-driver
pc98/pc98/sound/sound_switch.c optional snd device-driver
-pc98/pc98/sound/audio.c optional snd device-driver
-pc98/pc98/sound/dmabuf.c optional snd device-driver
-pc98/pc98/sound/sys_timer.c optional snd device-driver
-pc98/pc98/sound/sequencer.c optional snd device-driver
-pc98/pc98/sound/patmgr.c optional snd device-driver
-pc98/pc98/sound/adlib_card.c optional opl device-driver
+i386/isa/sound/audio.c optional snd device-driver
+i386/isa/sound/dmabuf.c optional snd device-driver
+i386/isa/sound/sys_timer.c optional snd device-driver
+i386/isa/sound/sequencer.c optional snd device-driver
+i386/isa/sound/patmgr.c optional snd device-driver
+i386/isa/sound/adlib_card.c optional opl device-driver
pc98/pc98/sound/opl3.c optional opl device-driver
-pc98/pc98/sound/gus_card.c optional gus device-driver
-pc98/pc98/sound/gus_midi.c optional gus device-driver
-pc98/pc98/sound/gus_vol.c optional gus device-driver
-pc98/pc98/sound/gus_wave.c optional gus device-driver
-pc98/pc98/sound/ics2101.c optional gus device-driver
-pc98/pc98/sound/sound_timer.c optional gus device-driver
-pc98/pc98/sound/midi_synth.c optional gus device-driver
-pc98/pc98/sound/midibuf.c optional gus device-driver
+i386/isa/sound/gus_card.c optional gus device-driver
+i386/isa/sound/gus_midi.c optional gus device-driver
+i386/isa/sound/gus_vol.c optional gus device-driver
+i386/isa/sound/gus_wave.c optional gus device-driver
+i386/isa/sound/ics2101.c optional gus device-driver
+i386/isa/sound/sound_timer.c optional gus device-driver
+i386/isa/sound/midi_synth.c optional gus device-driver
+i386/isa/sound/midibuf.c optional gus device-driver
pc98/pc98/sound/ad1848.c optional gusxvi device-driver
pc98/pc98/sound/ad1848.c optional gus device-driver
pc98/pc98/sound/ad1848.c optional mss device-driver
-pc98/pc98/sound/midi_synth.c optional mss device-driver
-pc98/pc98/sound/midibuf.c optional mss device-driver
-pc98/pc98/sound/mpu401.c optional mpu device-driver
-pc98/pc98/sound/midi_synth.c optional mpu device-driver
-pc98/pc98/sound/midibuf.c optional mpu device-driver
-pc98/pc98/sound/pas2_card.c optional pas device-driver
-pc98/pc98/sound/pas2_midi.c optional pas device-driver
-pc98/pc98/sound/pas2_mixer.c optional pas device-driver
+i386/isa/sound/midi_synth.c optional mss device-driver
+i386/isa/sound/midibuf.c optional mss device-driver
+i386/isa/sound/mpu401.c optional mpu device-driver
+i386/isa/sound/midi_synth.c optional mpu device-driver
+i386/isa/sound/midibuf.c optional mpu device-driver
+i386/isa/sound/pas2_card.c optional pas device-driver
+i386/isa/sound/pas2_midi.c optional pas device-driver
+i386/isa/sound/pas2_mixer.c optional pas device-driver
pc98/pc98/sound/pas2_pcm.c optional pas device-driver
-pc98/pc98/sound/midi_synth.c optional pas device-driver
-pc98/pc98/sound/midibuf.c optional pas device-driver
-pc98/pc98/sound/sb_card.c optional sb device-driver
+i386/isa/sound/midi_synth.c optional pas device-driver
+i386/isa/sound/midibuf.c optional pas device-driver
+i386/isa/sound/sb_card.c optional sb device-driver
pc98/pc98/sound/sb_dsp.c optional sb device-driver
-pc98/pc98/sound/sb_midi.c optional sb device-driver
-pc98/pc98/sound/sb_mixer.c optional sb device-driver
-pc98/pc98/sound/midi_synth.c optional sb device-driver
-pc98/pc98/sound/midibuf.c optional sb device-driver
+i386/isa/sound/sb_midi.c optional sb device-driver
+i386/isa/sound/sb_mixer.c optional sb device-driver
+i386/isa/sound/midi_synth.c optional sb device-driver
+i386/isa/sound/midibuf.c optional sb device-driver
pc98/pc98/sound/sb16_dsp.c optional sbxvi device-driver
pc98/pc98/sound/sb16_midi.c optional sbmidi device-driver
-pc98/pc98/sound/uart6850.c optional uart device-driver
-pc98/pc98/sound/midi_synth.c optional uart device-driver
-pc98/pc98/sound/midibuf.c optional uart device-driver
-pc98/pc98/sound/trix.c optional trix device-driver
-pc98/pc98/sound/sscape.c optional sscape device-driver
+i386/isa/sound/uart6850.c optional uart device-driver
+i386/isa/sound/midi_synth.c optional uart device-driver
+i386/isa/sound/midibuf.c optional uart device-driver
+i386/isa/sound/trix.c optional trix device-driver
+i386/isa/sound/sscape.c optional sscape device-driver
pc98/isa/spigot.c optional spigot device-driver
pc98/pc98/spkr.c optional speaker device-driver
pc98/isa/stallion.c optional stl device-driver
@@ -205,7 +205,7 @@ pc98/isa/tw.c optional tw device-driver
pc98/isa/ultra14f.c optional uha device-driver
pc98/pc98/wd.c optional wdc device-driver
pc98/pc98/wd.c optional wd device-driver
-pc98/pc98/atapi.c optional atapi device-driver
+i386/isa/atapi.c optional atapi device-driver
pc98/pc98/wcd.c optional wcd device-driver
pc98/isa/wd7000.c optional wds device-driver
pc98/pc98/wt.c optional wt device-driver
diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98
index 3f3edc68..106083c 100644
--- a/sys/pc98/conf/options.pc98
+++ b/sys/pc98/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.6 1996/10/23 07:24:55 asami Exp $
+# $Id: options.pc98,v 1.7 1996/10/29 08:36:14 asami Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -29,6 +29,8 @@ XSERVER opt_pcvt.h
AHC_TAGENABLE opt_aic7xxx.h
AHC_SCBPAGING_ENABLE opt_aic7xxx.h
+AHC_FORCE_PIO opt_aic7xxx.h
+AHC_SHARE_SCBS opt_aic7xxx.h
CLK_CALIBRATION_LOOP opt_clock.h
CLK_USE_I8254_CALIBRATION opt_clock.h
diff --git a/sys/pc98/i386/exception.s b/sys/pc98/i386/exception.s
deleted file mode 100644
index b2bfa93..0000000
--- a/sys/pc98/i386/exception.s
+++ /dev/null
@@ -1,279 +0,0 @@
-/*-
- * Copyright (c) 1990 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.
- *
- * $Id: exception.s,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
- */
-
-#include "npx.h" /* NNPX */
-#include "assym.s" /* system defines */
-#include <sys/errno.h> /* error return codes */
-#include <machine/spl.h> /* SWI_AST_MASK ... */
-#include <machine/psl.h> /* PSL_I */
-#include <machine/trap.h> /* trap codes */
-#include <sys/syscall.h> /* syscall numbers */
-#include <machine/asmacros.h> /* miscellaneous macros */
-#include <sys/cdefs.h> /* CPP macros */
-
-#define KDSEL 0x10 /* kernel data selector */
-#define SEL_RPL_MASK 0x0003
-#define TRAPF_CS_OFF (13 * 4)
-
- .text
-
-/*****************************************************************************/
-/* Trap handling */
-/*****************************************************************************/
-/*
- * Trap and fault vector routines
- */
-#define IDTVEC(name) ALIGN_TEXT; .globl __CONCAT(_X,name); __CONCAT(_X,name):
-#define TRAP(a) pushl $(a) ; jmp _alltraps
-
-/*
- * XXX - debugger traps are now interrupt gates so at least bdb doesn't lose
- * control. The sti's give the standard losing behaviour for ddb and kgdb.
- */
-#ifdef BDE_DEBUGGER
-#define BDBTRAP(name) \
- ss ; \
- cmpb $0,_bdb_exists ; \
- je 1f ; \
- testb $SEL_RPL_MASK,4(%esp) ; \
- jne 1f ; \
- ss ; \
- .globl __CONCAT(__CONCAT(bdb_,name),_ljmp); \
-__CONCAT(__CONCAT(bdb_,name),_ljmp): \
- ljmp $0,$0 ; \
-1:
-#else
-#define BDBTRAP(name)
-#endif
-
-#define BPTTRAP(a) testl $PSL_I,4+8(%esp) ; je 1f ; sti ; 1: ; TRAP(a)
-
-MCOUNT_LABEL(user)
-MCOUNT_LABEL(btrap)
-
-IDTVEC(div)
- pushl $0; TRAP(T_DIVIDE)
-IDTVEC(dbg)
- BDBTRAP(dbg)
- pushl $0; BPTTRAP(T_TRCTRAP)
-IDTVEC(nmi)
- pushl $0; TRAP(T_NMI)
-IDTVEC(bpt)
- BDBTRAP(bpt)
- pushl $0; BPTTRAP(T_BPTFLT)
-IDTVEC(ofl)
- pushl $0; TRAP(T_OFLOW)
-IDTVEC(bnd)
- pushl $0; TRAP(T_BOUND)
-IDTVEC(ill)
- pushl $0; TRAP(T_PRIVINFLT)
-IDTVEC(dna)
- pushl $0; TRAP(T_DNA)
-IDTVEC(fpusegm)
- pushl $0; TRAP(T_FPOPFLT)
-IDTVEC(tss)
- TRAP(T_TSSFLT)
-IDTVEC(missing)
- TRAP(T_SEGNPFLT)
-IDTVEC(stk)
- TRAP(T_STKFLT)
-IDTVEC(prot)
- TRAP(T_PROTFLT)
-IDTVEC(page)
- TRAP(T_PAGEFLT)
-IDTVEC(mchk)
- pushl $0; TRAP(T_MCHK)
-IDTVEC(rsvd)
- pushl $0; TRAP(T_RESERVED)
-IDTVEC(fpu)
-#if NNPX > 0
- /*
- * Handle like an interrupt (except for accounting) so that we can
- * call npxintr to clear the error. It would be better to handle
- * npx interrupts as traps. This used to be difficult for nested
- * interrupts, but now it is fairly easy - mask nested ones the
- * same as SWI_AST's.
- */
- pushl $0 /* dummy error code */
- pushl $0 /* dummy trap type */
- pushal
- pushl %ds
- pushl %es /* now the stack frame is a trap frame */
- movl $KDSEL,%eax
- movl %ax,%ds
- movl %ax,%es
- FAKE_MCOUNT(12*4(%esp))
- movl _cpl,%eax
- pushl %eax
- pushl $0 /* dummy unit to finish building intr frame */
- incl _cnt+V_TRAP
- orl $SWI_AST_MASK,%eax
- movl %eax,_cpl
- call _npxintr
- incb _intr_nesting_level
- MEXITCOUNT
- jmp _doreti
-#else /* NNPX > 0 */
- pushl $0; TRAP(T_ARITHTRAP)
-#endif /* NNPX > 0 */
-IDTVEC(align)
- TRAP(T_ALIGNFLT)
-
- SUPERALIGN_TEXT
- .globl _alltraps
-_alltraps:
- pushal
- pushl %ds
- pushl %es
-alltraps_with_regs_pushed:
- movl $KDSEL,%eax
- movl %ax,%ds
- movl %ax,%es
- FAKE_MCOUNT(12*4(%esp))
-calltrap:
- FAKE_MCOUNT(_btrap) /* init "from" _btrap -> calltrap */
- incl _cnt+V_TRAP
- orl $SWI_AST_MASK,_cpl
- call _trap
-
- /*
- * There was no place to save the cpl so we have to recover it
- * indirectly. For traps from user mode it was 0, and for traps
- * from kernel mode Oring SWI_AST_MASK into it didn't change it.
- */
- subl %eax,%eax
- testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
- jne 1f
- movl _cpl,%eax
-1:
- /*
- * Return via _doreti to handle ASTs. Have to change trap frame
- * to interrupt frame.
- */
- pushl %eax
- subl $4,%esp
- incb _intr_nesting_level
- MEXITCOUNT
- jmp _doreti
-
-/*
- * Call gate entry for syscall.
- * The intersegment call has been set up to specify one dummy parameter.
- * This leaves a place to put eflags so that the call frame can be
- * converted to a trap frame. Note that the eflags is (semi-)bogusly
- * pushed into (what will be) tf_err and then copied later into the
- * final spot. It has to be done this way because esp can't be just
- * temporarily altered for the pushfl - an interrupt might come in
- * and clobber the saved cs/eip.
- */
- SUPERALIGN_TEXT
-IDTVEC(syscall)
- pushfl /* save eflags in tf_err for now */
- subl $4,%esp /* skip over tf_trapno */
- pushal
- pushl %ds
- pushl %es
- movl $KDSEL,%eax /* switch to kernel segments */
- movl %ax,%ds
- movl %ax,%es
- movl TF_ERR(%esp),%eax /* copy saved eflags to final spot */
- movl %eax,TF_EFLAGS(%esp)
- movl $7,TF_ERR(%esp) /* sizeof "lcall 7,0" */
- FAKE_MCOUNT(12*4(%esp))
- incl _cnt+V_SYSCALL
- movl $SWI_AST_MASK,_cpl
- call _syscall
- /*
- * Return via _doreti to handle ASTs.
- */
- pushl $0 /* cpl to restore */
- subl $4,%esp
- movb $1,_intr_nesting_level
- MEXITCOUNT
- jmp _doreti
-
-/*
- * Call gate entry for Linux/NetBSD syscall (int 0x80)
- */
- SUPERALIGN_TEXT
-IDTVEC(int0x80_syscall)
- subl $8,%esp /* skip over tf_trapno and tf_err */
- pushal
- pushl %ds
- pushl %es
- movl $KDSEL,%eax /* switch to kernel segments */
- movl %ax,%ds
- movl %ax,%es
- movl $2,TF_ERR(%esp) /* sizeof "int 0x80" */
- FAKE_MCOUNT(12*4(%esp))
- incl _cnt+V_SYSCALL
- movl $SWI_AST_MASK,_cpl
- call _syscall
- /*
- * Return via _doreti to handle ASTs.
- */
- pushl $0 /* cpl to restore */
- subl $4,%esp
- movb $1,_intr_nesting_level
- MEXITCOUNT
- jmp _doreti
-
-/*
- * Include what was once config+isa-dependent code.
- * XXX it should be in a stand-alone file. It's still icu-dependent and
- * belongs in i386/isa.
- */
-#ifdef PC98
-#include "pc98/pc98/vector.s"
-#else
-#include "i386/isa/vector.s"
-#endif
-
-/*
- * Include what was once icu-dependent code.
- * XXX it should be merged into this file (also move the definition of
- * imen to vector.s or isa.c).
- * Before including it, set up a normal asm environment so that vector.s
- * doesn't have to know that stuff is included after it.
- */
- .data
- ALIGN_DATA
- .text
- SUPERALIGN_TEXT
-#ifdef PC98
-#include "pc98/pc98/icu.s"
-#else
-#include "i386/isa/icu.s"
-#endif
diff --git a/sys/pc98/i386/microtime.s b/sys/pc98/i386/microtime.s
index 8cd7f44..146f748 100644
--- a/sys/pc98/i386/microtime.s
+++ b/sys/pc98/i386/microtime.s
@@ -32,22 +32,20 @@
* SUCH DAMAGE.
*
* from: Steve McCanne's microtime code
- * $Id: microtime.s,v 1.4 1996/09/07 02:13:34 asami Exp $
+ * $Id: microtime.s,v 1.5 1996/10/09 19:47:38 bde Exp $
*/
#include "opt_cpu.h"
#include <machine/asmacros.h>
-#include <machine/clock.h>
#include <i386/isa/icu.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/timerreg.h>
#else
#include <i386/isa/isa.h>
-#include <i386/isa/timerreg.h>
#endif
+#include <i386/isa/timerreg.h>
ENTRY(microtime)
diff --git a/sys/pc98/i386/userconfig.c b/sys/pc98/i386/userconfig.c
index ba5da41..55ead7a 100644
--- a/sys/pc98/i386/userconfig.c
+++ b/sys/pc98/i386/userconfig.c
@@ -46,7 +46,7 @@
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
- ** $Id: userconfig.c,v 1.8 1996/10/23 07:25:04 asami Exp $
+ ** $Id: userconfig.c,v 1.9 1996/10/29 08:36:17 asami Exp $
**/
/**
@@ -244,7 +244,7 @@ static DEV_INFO device_info[] = {
{"aha", "Adaptec 154x SCSI controller", 0, CLS_STORAGE},
{"uha", "Ultrastor 14F/24F/34F SCSI controller",0, CLS_STORAGE},
{"aic", "Adaptec 152x SCSI and compatible sound cards", 0, CLS_STORAGE},
-{"nca", "ProAudio Spectrum SCSI and comaptibles", 0, CLS_STORAGE},
+{"nca", "ProAudio Spectrum SCSI and compatibles", 0, CLS_STORAGE},
{"sea", "Seagate ST01/ST02 SCSI and compatibles", 0, CLS_STORAGE},
{"wds", "Western Digitial WD7000 SCSI controller", 0, CLS_STORAGE},
{"ncr", "NCR 53C810 SCSI controller", FLG_FIXED, CLS_STORAGE},
@@ -2247,7 +2247,7 @@ visuserconfig(void)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: userconfig.c,v 1.8 1996/10/23 07:25:04 asami Exp $
+ * $Id: userconfig.c,v 1.9 1996/10/29 08:36:17 asami Exp $
*/
#include "scbus.h"
diff --git a/sys/pc98/i386/vm_machdep.c b/sys/pc98/i386/vm_machdep.c
deleted file mode 100644
index 4e1581c..0000000
--- a/sys/pc98/i386/vm_machdep.c
+++ /dev/null
@@ -1,864 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986 The Regents of the University of California.
- * Copyright (c) 1989, 1990 William Jolitz
- * Copyright (c) 1994 John Dyson
- * 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, and William Jolitz.
- *
- * 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: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
- * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.5 1996/10/09 21:46:03 asami Exp $
- */
-
-#include "npx.h"
-#include "opt_bounce.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/malloc.h>
-#include <sys/buf.h>
-#include <sys/vnode.h>
-#include <sys/vmmeter.h>
-
-#include <machine/clock.h>
-#include <machine/md_var.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_prot.h>
-#include <vm/lock.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-#include <vm/vm_map.h>
-#include <vm/vm_extern.h>
-
-#include <sys/user.h>
-
-#ifdef PC98
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/epsonio.h>
-#else
-#include <i386/isa/isa.h>
-#endif
-
-#ifdef BOUNCE_BUFFERS
-static vm_offset_t
- vm_bounce_kva __P((int size, int waitok));
-static void vm_bounce_kva_free __P((vm_offset_t addr, vm_offset_t size,
- int now));
-static vm_offset_t
- vm_bounce_page_find __P((int count));
-static void vm_bounce_page_free __P((vm_offset_t pa, int count));
-
-static volatile int kvasfreecnt;
-
-caddr_t bouncememory;
-int bouncepages;
-static int bpwait;
-static vm_offset_t *bouncepa;
-static int bmwait, bmfreeing;
-
-#define BITS_IN_UNSIGNED (8*sizeof(unsigned))
-static int bounceallocarraysize;
-static unsigned *bounceallocarray;
-static int bouncefree;
-
-#if defined(PC98) && defined (EPSON_BOUNCEDMA)
-#define SIXTEENMEG (3840*4096) /* 15MB boundary */
-#else
-#define SIXTEENMEG (4096*4096)
-#endif
-#define MAXBKVA 1024
-int maxbkva = MAXBKVA*PAGE_SIZE;
-
-/* special list that can be used at interrupt time for eventual kva free */
-static struct kvasfree {
- vm_offset_t addr;
- vm_offset_t size;
-} kvaf[MAXBKVA];
-
-/*
- * get bounce buffer pages (count physically contiguous)
- * (only 1 inplemented now)
- */
-static vm_offset_t
-vm_bounce_page_find(count)
- int count;
-{
- int bit;
- int s,i;
-
- if (count != 1)
- panic("vm_bounce_page_find -- no support for > 1 page yet!!!");
-
- s = splbio();
-retry:
- for (i = 0; i < bounceallocarraysize; i++) {
- if (bounceallocarray[i] != 0xffffffff) {
- bit = ffs(~bounceallocarray[i]);
- if (bit) {
- bounceallocarray[i] |= 1 << (bit - 1) ;
- bouncefree -= count;
- splx(s);
- return bouncepa[(i * BITS_IN_UNSIGNED + (bit - 1))];
- }
- }
- }
- bpwait = 1;
- tsleep((caddr_t) &bounceallocarray, PRIBIO, "bncwai", 0);
- goto retry;
-}
-
-static void
-vm_bounce_kva_free(addr, size, now)
- vm_offset_t addr;
- vm_offset_t size;
- int now;
-{
- int s = splbio();
- kvaf[kvasfreecnt].addr = addr;
- kvaf[kvasfreecnt].size = size;
- ++kvasfreecnt;
- if( now) {
- /*
- * this will do wakeups
- */
- vm_bounce_kva(0,0);
- } else {
- if (bmwait) {
- /*
- * if anyone is waiting on the bounce-map, then wakeup
- */
- wakeup((caddr_t) io_map);
- bmwait = 0;
- }
- }
- splx(s);
-}
-
-/*
- * free count bounce buffer pages
- */
-static void
-vm_bounce_page_free(pa, count)
- vm_offset_t pa;
- int count;
-{
- int allocindex;
- int index;
- int bit;
-
- if (count != 1)
- panic("vm_bounce_page_free -- no support for > 1 page yet!!!");
-
- for(index=0;index<bouncepages;index++) {
- if( pa == bouncepa[index])
- break;
- }
-
- if( index == bouncepages)
- panic("vm_bounce_page_free: invalid bounce buffer");
-
- allocindex = index / BITS_IN_UNSIGNED;
- bit = index % BITS_IN_UNSIGNED;
-
- bounceallocarray[allocindex] &= ~(1 << bit);
-
- bouncefree += count;
- if (bpwait) {
- bpwait = 0;
- wakeup((caddr_t) &bounceallocarray);
- }
-}
-
-/*
- * allocate count bounce buffer kva pages
- */
-static vm_offset_t
-vm_bounce_kva(size, waitok)
- int size;
- int waitok;
-{
- int i;
- vm_offset_t kva = 0;
- vm_offset_t off;
- int s = splbio();
-more:
- if (!bmfreeing && kvasfreecnt) {
- bmfreeing = 1;
- for (i = 0; i < kvasfreecnt; i++) {
- for(off=0;off<kvaf[i].size;off+=PAGE_SIZE) {
- pmap_kremove( kvaf[i].addr + off);
- }
- kmem_free_wakeup(io_map, kvaf[i].addr,
- kvaf[i].size);
- }
- kvasfreecnt = 0;
- bmfreeing = 0;
- if( bmwait) {
- bmwait = 0;
- wakeup( (caddr_t) io_map);
- }
- }
-
- if( size == 0) {
- splx(s);
- return 0;
- }
-
- if ((kva = kmem_alloc_pageable(io_map, size)) == 0) {
- if( !waitok) {
- splx(s);
- return 0;
- }
- bmwait = 1;
- tsleep((caddr_t) io_map, PRIBIO, "bmwait", 0);
- goto more;
- }
- splx(s);
- return kva;
-}
-
-/*
- * same as vm_bounce_kva -- but really allocate (but takes pages as arg)
- */
-vm_offset_t
-vm_bounce_kva_alloc(count)
-int count;
-{
- int i;
- vm_offset_t kva;
- vm_offset_t pa;
- if( bouncepages == 0) {
- kva = (vm_offset_t) malloc(count*PAGE_SIZE, M_TEMP, M_WAITOK);
- return kva;
- }
- kva = vm_bounce_kva(count*PAGE_SIZE, 1);
- for(i=0;i<count;i++) {
- pa = vm_bounce_page_find(1);
- pmap_kenter(kva + i * PAGE_SIZE, pa);
- }
- return kva;
-}
-
-/*
- * same as vm_bounce_kva_free -- but really free
- */
-void
-vm_bounce_kva_alloc_free(kva, count)
- vm_offset_t kva;
- int count;
-{
- int i;
- vm_offset_t pa;
- if( bouncepages == 0) {
- free((caddr_t) kva, M_TEMP);
- return;
- }
- for(i = 0; i < count; i++) {
- pa = pmap_kextract(kva + i * PAGE_SIZE);
- vm_bounce_page_free(pa, 1);
- }
- vm_bounce_kva_free(kva, count*PAGE_SIZE, 0);
-}
-
-/*
- * do the things necessary to the struct buf to implement
- * bounce buffers... inserted before the disk sort
- */
-void
-vm_bounce_alloc(bp)
- struct buf *bp;
-{
- int countvmpg;
- vm_offset_t vastart, vaend;
- vm_offset_t vapstart, vapend;
- vm_offset_t va, kva;
- vm_offset_t pa;
- int dobounceflag = 0;
- int i;
-
- if (bouncepages == 0)
- return;
-
- if (bp->b_flags & B_BOUNCE) {
- printf("vm_bounce_alloc: called recursively???\n");
- return;
- }
-
- if (bp->b_bufsize < bp->b_bcount) {
- printf(
- "vm_bounce_alloc: b_bufsize(0x%lx) < b_bcount(0x%lx) !!\n",
- bp->b_bufsize, bp->b_bcount);
- panic("vm_bounce_alloc");
- }
-
-/*
- * This is not really necessary
- * if( bp->b_bufsize != bp->b_bcount) {
- * printf("size: %d, count: %d\n", bp->b_bufsize, bp->b_bcount);
- * }
- */
-
-
- vastart = (vm_offset_t) bp->b_data;
- vaend = (vm_offset_t) bp->b_data + bp->b_bufsize;
-
- vapstart = trunc_page(vastart);
- vapend = round_page(vaend);
- countvmpg = (vapend - vapstart) / PAGE_SIZE;
-
-/*
- * if any page is above 16MB, then go into bounce-buffer mode
- */
- va = vapstart;
- for (i = 0; i < countvmpg; i++) {
- pa = pmap_kextract(va);
- if (pa >= SIXTEENMEG)
- ++dobounceflag;
- if( pa == 0)
- panic("vm_bounce_alloc: Unmapped page");
- va += PAGE_SIZE;
- }
- if (dobounceflag == 0)
- return;
-
- if (bouncepages < dobounceflag)
- panic("Not enough bounce buffers!!!");
-
-/*
- * allocate a replacement kva for b_addr
- */
- kva = vm_bounce_kva(countvmpg*PAGE_SIZE, 1);
-#if 0
- printf("%s: vapstart: %x, vapend: %x, countvmpg: %d, kva: %x ",
- (bp->b_flags & B_READ) ? "read":"write",
- vapstart, vapend, countvmpg, kva);
-#endif
- va = vapstart;
- for (i = 0; i < countvmpg; i++) {
- pa = pmap_kextract(va);
- if (pa >= SIXTEENMEG) {
- /*
- * allocate a replacement page
- */
- vm_offset_t bpa = vm_bounce_page_find(1);
- pmap_kenter(kva + (PAGE_SIZE * i), bpa);
-#if 0
- printf("r(%d): (%x,%x,%x) ", i, va, pa, bpa);
-#endif
- /*
- * if we are writing, the copy the data into the page
- */
- if ((bp->b_flags & B_READ) == 0) {
- bcopy((caddr_t) va, (caddr_t) kva + (PAGE_SIZE * i), PAGE_SIZE);
- }
- } else {
- /*
- * use original page
- */
- pmap_kenter(kva + (PAGE_SIZE * i), pa);
- }
- va += PAGE_SIZE;
- }
-
-/*
- * flag the buffer as being bounced
- */
- bp->b_flags |= B_BOUNCE;
-/*
- * save the original buffer kva
- */
- bp->b_savekva = bp->b_data;
-/*
- * put our new kva into the buffer (offset by original offset)
- */
- bp->b_data = (caddr_t) (((vm_offset_t) kva) |
- ((vm_offset_t) bp->b_savekva & PAGE_MASK));
-#if 0
- printf("b_savekva: %x, newva: %x\n", bp->b_savekva, bp->b_data);
-#endif
- return;
-}
-
-/*
- * hook into biodone to free bounce buffer
- */
-void
-vm_bounce_free(bp)
- struct buf *bp;
-{
- int i;
- vm_offset_t origkva, bouncekva, bouncekvaend;
-
-/*
- * if this isn't a bounced buffer, then just return
- */
- if ((bp->b_flags & B_BOUNCE) == 0)
- return;
-
-/*
- * This check is not necessary
- * if (bp->b_bufsize != bp->b_bcount) {
- * printf("vm_bounce_free: b_bufsize=%d, b_bcount=%d\n",
- * bp->b_bufsize, bp->b_bcount);
- * }
- */
-
- origkva = (vm_offset_t) bp->b_savekva;
- bouncekva = (vm_offset_t) bp->b_data;
-/*
- printf("free: %d ", bp->b_bufsize);
-*/
-
-/*
- * check every page in the kva space for b_addr
- */
- for (i = 0; i < bp->b_bufsize; ) {
- vm_offset_t mybouncepa;
- vm_offset_t copycount;
-
- copycount = round_page(bouncekva + 1) - bouncekva;
- mybouncepa = pmap_kextract(trunc_page(bouncekva));
-
-/*
- * if this is a bounced pa, then process as one
- */
- if ( mybouncepa != pmap_kextract( trunc_page( origkva))) {
- vm_offset_t tocopy = copycount;
- if (i + tocopy > bp->b_bufsize)
- tocopy = bp->b_bufsize - i;
-/*
- * if this is a read, then copy from bounce buffer into original buffer
- */
- if (bp->b_flags & B_READ)
- bcopy((caddr_t) bouncekva, (caddr_t) origkva, tocopy);
-/*
- * free the bounce allocation
- */
-
-/*
- printf("(kva: %x, pa: %x)", bouncekva, mybouncepa);
-*/
- vm_bounce_page_free(mybouncepa, 1);
- }
-
- origkva += copycount;
- bouncekva += copycount;
- i += copycount;
- }
-
-/*
- printf("\n");
-*/
-/*
- * add the old kva into the "to free" list
- */
-
- bouncekva= trunc_page((vm_offset_t) bp->b_data);
- bouncekvaend= round_page((vm_offset_t)bp->b_data + bp->b_bufsize);
-
-/*
- printf("freeva: %d\n", (bouncekvaend - bouncekva) / PAGE_SIZE);
-*/
- vm_bounce_kva_free( bouncekva, (bouncekvaend - bouncekva), 0);
- bp->b_data = bp->b_savekva;
- bp->b_savekva = 0;
- bp->b_flags &= ~B_BOUNCE;
-
- return;
-}
-
-
-/*
- * init the bounce buffer system
- */
-void
-vm_bounce_init()
-{
- int i;
-
- kvasfreecnt = 0;
-
- if (bouncepages == 0)
- return;
-
- bounceallocarraysize = (bouncepages + BITS_IN_UNSIGNED - 1) / BITS_IN_UNSIGNED;
- bounceallocarray = malloc(bounceallocarraysize * sizeof(unsigned), M_TEMP, M_NOWAIT);
-
- if (!bounceallocarray)
- panic("Cannot allocate bounce resource array");
-
- bouncepa = malloc(bouncepages * sizeof(vm_offset_t), M_TEMP, M_NOWAIT);
- if (!bouncepa)
- panic("Cannot allocate physical memory array");
-
- for(i=0;i<bounceallocarraysize;i++) {
- bounceallocarray[i] = 0xffffffff;
- }
-
- for(i=0;i<bouncepages;i++) {
- vm_offset_t pa;
- if( (pa = pmap_kextract((vm_offset_t) bouncememory + i * PAGE_SIZE)) >= SIXTEENMEG)
- panic("bounce memory out of range");
- if( pa == 0)
- panic("bounce memory not resident");
- bouncepa[i] = pa;
- bounceallocarray[i/(8*sizeof(int))] &= ~(1<<(i%(8*sizeof(int))));
- }
- bouncefree = bouncepages;
-
-}
-#endif /* BOUNCE_BUFFERS */
-
-/*
- * quick version of vm_fault
- */
-void
-vm_fault_quick(v, prot)
- caddr_t v;
- int prot;
-{
- if (prot & VM_PROT_WRITE)
- subyte(v, fubyte(v));
- else
- fubyte(v);
-}
-
-/*
- * Finish a fork operation, with process p2 nearly set up.
- * Copy and update the kernel stack and pcb, making the child
- * ready to run, and marking it so that it can return differently
- * than the parent. Returns 1 in the child process, 0 in the parent.
- * We currently double-map the user area so that the stack is at the same
- * address in each process; in the future we will probably relocate
- * the frame pointers on the stack after copying.
- */
-int
-cpu_fork(p1, p2)
- register struct proc *p1, *p2;
-{
- struct pcb *pcb2 = &p2->p_addr->u_pcb;
- int sp, offset;
- volatile int retval;
-
- /*
- * Copy pcb and stack from proc p1 to p2.
- * We do this as cheaply as possible, copying only the active
- * part of the stack. The stack and pcb need to agree;
- * this is tricky, as the final pcb is constructed by savectx,
- * but its frame isn't yet on the stack when the stack is copied.
- * This should be done differently, with a single call
- * that copies and updates the pcb+stack,
- * replacing the bcopy and savectx.
- */
-
- __asm __volatile("movl %%esp,%0" : "=r" (sp));
- offset = sp - (int)kstack;
-
- retval = 1; /* return 1 in child */
- bcopy((caddr_t)kstack + offset, (caddr_t)p2->p_addr + offset,
- (unsigned) ctob(UPAGES) - offset);
- p2->p_md.md_regs = p1->p_md.md_regs;
-
- *pcb2 = p1->p_addr->u_pcb;
- pcb2->pcb_cr3 = vtophys(p2->p_vmspace->vm_pmap.pm_pdir);
-
- retval = 0; /* return 0 in parent */
- savectx(pcb2);
- return (retval);
-}
-
-void
-cpu_exit(p)
- register struct proc *p;
-{
-#ifdef USER_LDT
- struct pcb *pcb;
-#endif
-
-#if NNPX > 0
- npxexit(p);
-#endif /* NNPX */
-#ifdef USER_LDT
- pcb = &p->p_addr->u_pcb;
- if (pcb->pcb_ldt != 0) {
- if (pcb == curpcb)
- lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
- kmem_free(kernel_map, (vm_offset_t)pcb->pcb_ldt,
- pcb->pcb_ldt_len * sizeof(union descriptor));
- pcb->pcb_ldt_len = (int)pcb->pcb_ldt = 0;
- }
-#endif
- cnt.v_swtch++;
- cpu_switch(p);
- panic("cpu_exit");
-}
-
-void
-cpu_wait(p)
- struct proc *p;
-{
- /* drop per-process resources */
- pmap_dispose_proc(p);
- vmspace_free(p->p_vmspace);
-}
-
-/*
- * Dump the machine specific header information at the start of a core dump.
- */
-int
-cpu_coredump(p, vp, cred)
- struct proc *p;
- struct vnode *vp;
- struct ucred *cred;
-{
-
- return (vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES),
- (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)NULL,
- p));
-}
-
-#ifdef notyet
-static void
-setredzone(pte, vaddr)
- u_short *pte;
- caddr_t vaddr;
-{
-/* eventually do this by setting up an expand-down stack segment
- for ss0: selector, allowing stack access down to top of u.
- this means though that protection violations need to be handled
- thru a double fault exception that must do an integral task
- switch to a known good context, within which a dump can be
- taken. a sensible scheme might be to save the initial context
- used by sched (that has physical memory mapped 1:1 at bottom)
- and take the dump while still in mapped mode */
-}
-#endif
-
-/*
- * Convert kernel VA to physical address
- */
-u_long
-kvtop(void *addr)
-{
- vm_offset_t va;
-
- va = pmap_kextract((vm_offset_t)addr);
- if (va == 0)
- panic("kvtop: zero page frame");
- return((int)va);
-}
-
-/*
- * Map an IO request into kernel virtual address space.
- *
- * All requests are (re)mapped into kernel VA space.
- * Notice that we use b_bufsize for the size of the buffer
- * to be mapped. b_bcount might be modified by the driver.
- */
-void
-vmapbuf(bp)
- register struct buf *bp;
-{
- register caddr_t addr, v, kva;
- vm_offset_t pa;
-
- if ((bp->b_flags & B_PHYS) == 0)
- panic("vmapbuf");
-
- for (v = bp->b_saveaddr, addr = (caddr_t)trunc_page(bp->b_data);
- addr < bp->b_data + bp->b_bufsize;
- addr += PAGE_SIZE, v += PAGE_SIZE) {
- /*
- * Do the vm_fault if needed; do the copy-on-write thing
- * when reading stuff off device into memory.
- */
- vm_fault_quick(addr,
- (bp->b_flags&B_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ);
- pa = trunc_page(pmap_kextract((vm_offset_t) addr));
- if (pa == 0)
- panic("vmapbuf: page not present");
- vm_page_hold(PHYS_TO_VM_PAGE(pa));
- pmap_kenter((vm_offset_t) v, pa);
- }
-
- kva = bp->b_saveaddr;
- bp->b_saveaddr = bp->b_data;
- bp->b_data = kva + (((vm_offset_t) bp->b_data) & PAGE_MASK);
-}
-
-/*
- * Free the io map PTEs associated with this IO operation.
- * We also invalidate the TLB entries and restore the original b_addr.
- */
-void
-vunmapbuf(bp)
- register struct buf *bp;
-{
- register caddr_t addr;
- vm_offset_t pa;
-
- if ((bp->b_flags & B_PHYS) == 0)
- panic("vunmapbuf");
-
- for (addr = (caddr_t)trunc_page(bp->b_data);
- addr < bp->b_data + bp->b_bufsize;
- addr += PAGE_SIZE) {
- pa = trunc_page(pmap_kextract((vm_offset_t) addr));
- pmap_kremove((vm_offset_t) addr);
- vm_page_unhold(PHYS_TO_VM_PAGE(pa));
- }
-
- bp->b_data = bp->b_saveaddr;
-}
-
-/*
- * Force reset the processor by invalidating the entire address space!
- */
-void
-cpu_reset() {
-#ifdef PC98
- asm(" cli ");
- outb(0x37, 0x0f); /* SHUT 0 = 0 */
- outb(0x37, 0x0b); /* SHUT 1 = 0 */
- if ((pc98_machine_type & M_EPSON_PC98)
- && (epson_machine_id == 0x20 /*note A*/)) {
- epson_outb(0xc17, epson_inb(0xc17) | 0x40);
- /* reset port for NOTE_A */
- }
- outb(0xf0, 0x00); /* reset port */
-#else /* IBM-PC */
-
- /*
- * Attempt to do a CPU reset via the keyboard controller,
- * do not turn of the GateA20, as any machine that fails
- * to do the reset here would then end up in no man's land.
- */
-
-#ifndef BROKEN_KEYBOARD_RESET
- outb(IO_KBD + 4, 0xFE);
- DELAY(500000); /* wait 0.5 sec to see if that did it */
- printf("Keyboard reset did not work, attempting CPU shutdown\n");
- DELAY(1000000); /* wait 1 sec for printf to complete */
-#endif
-
- /* force a shutdown by unmapping entire address space ! */
- bzero((caddr_t) PTD, PAGE_SIZE);
-
- /* "good night, sweet prince .... <THUNK!>" */
- invltlb();
-#endif
- /* NOTREACHED */
- while(1);
-}
-
-/*
- * Grow the user stack to allow for 'sp'. This version grows the stack in
- * chunks of SGROWSIZ.
- */
-int
-grow(p, sp)
- struct proc *p;
- u_int sp;
-{
- unsigned int nss;
- caddr_t v;
- struct vmspace *vm = p->p_vmspace;
-
- if ((caddr_t)sp <= vm->vm_maxsaddr || (unsigned)sp >= (unsigned)USRSTACK)
- return (1);
-
- nss = roundup(USRSTACK - (unsigned)sp, PAGE_SIZE);
-
- if (nss > p->p_rlimit[RLIMIT_STACK].rlim_cur)
- return (0);
-
- if (vm->vm_ssize && roundup(vm->vm_ssize << PAGE_SHIFT,
- SGROWSIZ) < nss) {
- int grow_amount;
- /*
- * If necessary, grow the VM that the stack occupies
- * to allow for the rlimit. This allows us to not have
- * to allocate all of the VM up-front in execve (which
- * is expensive).
- * Grow the VM by the amount requested rounded up to
- * the nearest SGROWSIZ to provide for some hysteresis.
- */
- grow_amount = roundup((nss - (vm->vm_ssize << PAGE_SHIFT)), SGROWSIZ);
- v = (char *)USRSTACK - roundup(vm->vm_ssize << PAGE_SHIFT,
- SGROWSIZ) - grow_amount;
- /*
- * If there isn't enough room to extend by SGROWSIZ, then
- * just extend to the maximum size
- */
- if (v < vm->vm_maxsaddr) {
- v = vm->vm_maxsaddr;
- grow_amount = MAXSSIZ - (vm->vm_ssize << PAGE_SHIFT);
- }
- if ((grow_amount == 0) || (vm_map_find(&vm->vm_map, NULL, 0, (vm_offset_t *)&v,
- grow_amount, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0) != KERN_SUCCESS)) {
- return (0);
- }
- vm->vm_ssize += grow_amount >> PAGE_SHIFT;
- }
-
- return (1);
-}
-
-/*
- * prototype routine to implement the pre-zeroed page mechanism
- * this routine is called from the idle loop.
- */
-int
-vm_page_zero_idle() {
- vm_page_t m;
- static int free_rover = 0;
- if ((cnt.v_free_count > cnt.v_interrupt_free_min) &&
- (m = vm_page_list_find(PQ_FREE, free_rover))) {
- --(*vm_page_queues[m->queue].lcnt);
- TAILQ_REMOVE(vm_page_queues[m->queue].pl, m, pageq);
- enable_intr();
- pmap_zero_page(VM_PAGE_TO_PHYS(m));
- disable_intr();
- m->queue = PQ_ZERO + m->pc;
- ++(*vm_page_queues[m->queue].lcnt);
- TAILQ_INSERT_HEAD(vm_page_queues[m->queue].pl, m, pageq);
- free_rover = (free_rover + PQ_PRIME3) & PQ_L2_MASK;
- ++vm_page_zero_count;
- return 1;
- }
- return 0;
-}
diff --git a/sys/pc98/pc98/aic6360.c b/sys/pc98/pc98/aic6360.c
deleted file mode 100644
index cbec0c0..0000000
--- a/sys/pc98/pc98/aic6360.c
+++ /dev/null
@@ -1,2436 +0,0 @@
-/*
- * Copyright (c) 1994 Charles Hannum.
- * Copyright (c) 1994 Jarle Greipsland
- * 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 Jarle Greipsland
- * 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.
- */
-
-/*
- * $Id: aic6360.c,v 1.4 1996/09/10 09:37:43 asami Exp $
- *
- * Acknowledgements: Many of the algorithms used in this driver are
- * inspired by the work of Julian Elischer (julian@tfs.com) and
- * Charles Hannum (mycroft@duality.gnu.ai.mit.edu). Thanks a million!
- *
- * Converted from NetBSD to FreeBSD by Jim Babb
- */
-
-/* TODO list:
- * 1) Get the DMA stuff working.
- * 2) Get the iov/uio stuff working. Is this a good thing ???
- * 3) Get the synch stuff working.
- * 4) Rewrite it to use malloc for the acb structs instead of static alloc.?
- */
-
-/*
- * PC-9801-100/AHA-1030P support by URATA S.
- */
-
-/*
- * A few customizable items:
- */
-
-/* The SCSI ID of the host adapter/computer */
-#ifndef AIC_SCSI_HOSTID
-#define AIC_SCSI_HOSTID 7
-#endif
-
-/* Use doubleword transfers to/from SCSI chip. Note: This requires
- * motherboard support. Basicly, some motherboard chipsets are able to
- * split a 32 bit I/O operation into two 16 bit I/O operations,
- * transparently to the processor. This speeds up some things, notably long
- * data transfers.
- */
-#define AIC_USE_DWORDS 0
-
-/* Allow disconnects? Was mainly used in an early phase of the driver when
- * the message system was very flaky. Should go away soon.
- */
-#define AIC_ALLOW_DISCONNECT 1
-
-/* Synchronous data transfers? (does not work yet!) XXX */
-#define AIC_USE_SYNCHRONOUS 0 /* Enable/disable (1/0) */
-#define AIC_SYNC_PERIOD 200
-#define AIC_SYNC_REQ_ACK_OFS 8
-
-/* Max attempts made to transmit a message */
-#define AIC_MSG_MAX_ATTEMPT 3 /* Not used now XXX */
-
-/* Use DMA (else we do programmed I/O using string instructions) (not yet!)*/
-#define AIC_USE_EISA_DMA 0
-#define AIC_USE_ISA_DMA 0
-
-/* How to behave on the (E)ISA bus when/if DMAing (on<<4) + off in us */
-#define EISA_BRST_TIM ((15<<4) + 1) /* 15us on, 1us off */
-
-/* Some spin loop parameters (essentially how long to wait some places)
- * The problem(?) is that sometimes we expect either to be able to transmit a
- * byte or to get a new one from the SCSI bus pretty soon. In order to avoid
- * returning from the interrupt just to get yanked back for the next byte we
- * may spin in the interrupt routine waiting for this byte to come. How long?
- * This is really (SCSI) device and processor dependent. Tuneable, I guess.
- */
-#define AIC_MSGI_SPIN 1 /* Will spinwait upto ?ms for a new msg byte */
-#define AIC_MSGO_SPIN 1
-
-/* Include debug functions? At the end of this file there are a bunch of
- * functions that will print out various information regarding queued SCSI
- * commands, driver state and chip contents. You can call them from the
- * kernel debugger. If you set AIC_DEBUG to 0 they are not included (the
- * kernel uses less memory) but you lose the debugging facilities.
- */
-#define AIC_DEBUG 0
-
-/* End of customizable parameters */
-
-#if AIC_USE_EISA_DMA || AIC_USE_ISA_DMA
-#error "I said not yet! Start paying attention... grumble"
-#endif
-
-#include "opt_ddb.h"
-#include "aic.h"
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/errno.h>
-#include <sys/ioctl.h>
-#include <sys/malloc.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <scsi/scsi_all.h>
-#include <scsi/scsiconf.h>
-
-#include <machine/clock.h>
-#include <i386/isa/isa_device.h>
-
-#include <sys/kernel.h>
-
-/* Definitions, most of them has turned out to be unneccesary, but here they
- * are anyway.
- */
-
-/*
- * Generic SCSI messages. For now we reject most of them.
- */
-/* Messages (1 byte) */ /* I/T M(andatory) or (O)ptional */
-#define MSG_CMDCOMPLETE 0x00 /* M/M */
-#define MSG_EXTENDED 0x01 /* O/O */
-#define MSG_SAVEDATAPOINTER 0x02 /* O/O */
-#define MSG_RESTOREPOINTERS 0x03 /* O/O */
-#define MSG_DISCONNECT 0x04 /* O/O */
-#define MSG_INITIATOR_DET_ERR 0x05 /* M/M */
-#define MSG_ABORT 0x06 /* O/M */
-#define MSG_MESSAGE_REJECT 0x07 /* M/M */
-#define MSG_NOOP 0x08 /* M/M */
-#define MSG_PARITY_ERR 0x09 /* M/M */
-#define MSG_LINK_CMD_COMPLETE 0x0a /* O/O */
-#define MSG_LINK_CMD_COMPLETEF 0x0b /* O/O */
-#define MSG_BUS_DEV_RESET 0x0c /* O/M */
-#define MSG_ABORT_TAG 0x0d /* O/O */
-#define MSG_CLEAR_QUEUE 0x0e /* O/O */
-#define MSG_INIT_RECOVERY 0x0f /* O/O */
-#define MSG_REL_RECOVERY 0x10 /* O/O */
-#define MSG_TERM_IO_PROC 0x11 /* O/O */
-
-/* Messages (2 byte) */
-#define MSG_SIMPLE_Q_TAG 0x20 /* O/O */
-#define MSG_HEAD_OF_Q_TAG 0x21 /* O/O */
-#define MSG_ORDERED_Q_TAG 0x22 /* O/O */
-#define MSG_IGN_WIDE_RESIDUE 0x23 /* O/O */
-
-/* Identify message */
-#define MSG_IDENTIFY(lun) ((AIC_ALLOW_DISCONNECT ? 0xc0 : 0x80)|((lun) & 0x7))
-#define MSG_ISIDENT(m) ((m) & 0x80)
-
-/* Extended messages (opcode) */
-#define MSG_EXT_SDTR 0x01
-
-/* SCSI Status codes */
-#define ST_GOOD 0x00
-#define ST_CHKCOND 0x02
-#define ST_CONDMET 0x04
-#define ST_BUSY 0x08
-#define ST_INTERMED 0x10
-#define ST_INTERMED_CONDMET 0x14
-#define ST_RESERVATION_CONFLICT 0x18
-#define ST_CMD_TERM 0x22
-#define ST_QUEUE_FULL 0x28
-
-#define ST_MASK 0x3e /* bit 0,6,7 is reserved */
-
-/* AIC6360 definitions */
-#ifdef PC98
-#include <pc98/pc98/aic_98.h>
-#else
-#define SCSISEQ (iobase + 0x00) /* SCSI sequence control */
-#define SXFRCTL0 (iobase + 0x01) /* SCSI transfer control 0 */
-#define SXFRCTL1 (iobase + 0x02) /* SCSI transfer control 1 */
-#define SCSISIGI (iobase + 0x03) /* SCSI signal in */
-#define SCSISIGO (iobase + 0x03) /* SCSI signal out */
-#define SCSIRATE (iobase + 0x04) /* SCSI rate control */
-#define SCSIID (iobase + 0x05) /* SCSI ID */
-#define SELID (iobase + 0x05) /* Selection/Reselection ID */
-#define SCSIDAT (iobase + 0x06) /* SCSI Latched Data */
-#define SCSIBUS (iobase + 0x07) /* SCSI Data Bus*/
-#define STCNT0 (iobase + 0x08) /* SCSI transfer count */
-#define STCNT1 (iobase + 0x09)
-#define STCNT2 (iobase + 0x0a)
-#define CLRSINT0 (iobase + 0x0b) /* Clear SCSI interrupts 0 */
-#define SSTAT0 (iobase + 0x0b) /* SCSI interrupt status 0 */
-#define CLRSINT1 (iobase + 0x0c) /* Clear SCSI interrupts 1 */
-#define SSTAT1 (iobase + 0x0c) /* SCSI status 1 */
-#define SSTAT2 (iobase + 0x0d) /* SCSI status 2 */
-#define SCSITEST (iobase + 0x0e) /* SCSI test control */
-#define SSTAT3 (iobase + 0x0e) /* SCSI status 3 */
-#define CLRSERR (iobase + 0x0f) /* Clear SCSI errors */
-#define SSTAT4 (iobase + 0x0f) /* SCSI status 4 */
-#define SIMODE0 (iobase + 0x10) /* SCSI interrupt mode 0 */
-#define SIMODE1 (iobase + 0x11) /* SCSI interrupt mode 1 */
-#define DMACNTRL0 (iobase + 0x12) /* DMA control 0 */
-#define DMACNTRL1 (iobase + 0x13) /* DMA control 1 */
-#define DMASTAT (iobase + 0x14) /* DMA status */
-#define FIFOSTAT (iobase + 0x15) /* FIFO status */
-#define DMADATA (iobase + 0x16) /* DMA data */
-#define DMADATAL (iobase + 0x16) /* DMA data low byte */
-#define DMADATAH (iobase + 0x17) /* DMA data high byte */
-#define BRSTCNTRL (iobase + 0x18) /* Burst Control */
-#define DMADATALONG (iobase + 0x18)
-#define PORTA (iobase + 0x1a) /* Port A */
-#define PORTB (iobase + 0x1b) /* Port B */
-#define REV (iobase + 0x1c) /* Revision (001 for 6360) */
-#define STACK (iobase + 0x1d) /* Stack */
-#define TEST (iobase + 0x1e) /* Test register */
-#define ID (iobase + 0x1f) /* ID register */
-#endif
-
-#define IDSTRING "(C)1991ADAPTECAIC6360 "
-
-/* What all the bits do */
-
-/* SCSISEQ */
-#define TEMODEO 0x80
-#define ENSELO 0x40
-#define ENSELI 0x20
-#define ENRESELI 0x10
-#define ENAUTOATNO 0x08
-#define ENAUTOATNI 0x04
-#define ENAUTOATNP 0x02
-#define SCSIRSTO 0x01
-
-/* SXFRCTL0 */
-#define SCSIEN 0x80
-#define DMAEN 0x40
-#define CHEN 0x20
-#define CLRSTCNT 0x10
-#define SPIOEN 0x08
-#define CLRCH 0x02
-
-/* SXFRCTL1 */
-#define BITBUCKET 0x80
-#define SWRAPEN 0x40
-#define ENSPCHK 0x20
-#define STIMESEL1 0x10
-#define STIMESEL0 0x08
-#define STIMO_256ms 0x00
-#define STIMO_128ms 0x08
-#define STIMO_64ms 0x10
-#define STIMO_32ms 0x18
-#define ENSTIMER 0x04
-#define BYTEALIGN 0x02
-
-/* SCSISIGI */
-#define CDI 0x80
-#define IOI 0x40
-#define MSGI 0x20
-#define ATNI 0x10
-#define SELI 0x08
-#define BSYI 0x04
-#define REQI 0x02
-#define ACKI 0x01
-
-/* Important! The 3 most significant bits of this register, in initiator mode,
- * represents the "expected" SCSI bus phase and can be used to trigger phase
- * mismatch and phase change interrupts. But more important: If there is a
- * phase mismatch the chip will not transfer any data! This is actually a nice
- * feature as it gives us a bit more control over what is happening when we are
- * bursting data (in) through the FIFOs and the phase suddenly changes from
- * DATA IN to STATUS or MESSAGE IN. The transfer will stop and wait for the
- * proper phase to be set in this register instead of dumping the bits into the
- * FIFOs.
- */
-/* SCSISIGO */
-#define CDO 0x80
-#define CDEXP (CDO)
-#define IOO 0x40
-#define IOEXP (IOO)
-#define MSGO 0x20
-#define MSGEXP (MSGO)
-#define ATNO 0x10
-#define SELO 0x08
-#define BSYO 0x04
-#define REQO 0x02
-#define ACKO 0x01
-
-/* Information transfer phases */
-#define PH_DOUT (0)
-#define PH_DIN (IOI)
-#define PH_CMD (CDI)
-#define PH_STAT (CDI|IOI)
-#define PH_MSGO (MSGI|CDI)
-#define PH_MSGI (MSGI|CDI|IOI)
-
-#define PH_MASK 0xe0
-
-/* Some pseudo phases for getphase()*/
-#define PH_BUSFREE 0x100 /* (Re)Selection no longer valid */
-#define PH_INVALID 0x101 /* (Re)Selection valid, but no REQ yet */
-#define PH_PSBIT 0x100 /* "pseudo" bit */
-
-/* SCSIRATE */
-#define SXFR2 0x40
-#define SXFR1 0x20
-#define SXFR0 0x10
-#define SOFS3 0x08
-#define SOFS2 0x04
-#define SOFS1 0x02
-#define SOFS0 0x01
-
-/* SCSI ID */
-#define OID2 0x40
-#define OID1 0x20
-#define OID0 0x10
-#define OID_S 4 /* shift value */
-#define TID2 0x04
-#define TID1 0x02
-#define TID0 0x01
-#define SCSI_ID_MASK 0x7
-
-/* SCSI selection/reselection ID (both target *and* initiator) */
-#define SELID7 0x80
-#define SELID6 0x40
-#define SELID5 0x20
-#define SELID4 0x10
-#define SELID3 0x08
-#define SELID2 0x04
-#define SELID1 0x02
-#define SELID0 0x01
-
-/* CLRSINT0 Clears what? (interrupt and/or status bit) */
-#define SETSDONE 0x80
-#define CLRSELDO 0x40 /* I */
-#define CLRSELDI 0x20 /* I+ */
-#define CLRSELINGO 0x10 /* I */
-#define CLRSWRAP 0x08 /* I+S */
-#define CLRSDONE 0x04 /* I+S */
-#define CLRSPIORDY 0x02 /* I */
-#define CLRDMADONE 0x01 /* I */
-
-/* SSTAT0 Howto clear */
-#define TARGET 0x80
-#define SELDO 0x40 /* Selfclearing */
-#define SELDI 0x20 /* Selfclearing when CLRSELDI is set */
-#define SELINGO 0x10 /* Selfclearing */
-#define SWRAP 0x08 /* CLRSWAP */
-#define SDONE 0x04 /* Not used in initiator mode */
-#define SPIORDY 0x02 /* Selfclearing (op on SCSIDAT) */
-#define DMADONE 0x01 /* Selfclearing (all FIFOs empty & T/C */
-
-/* CLRSINT1 Clears what? */
-#define CLRSELTIMO 0x80 /* I+S */
-#define CLRATNO 0x40
-#define CLRSCSIRSTI 0x20 /* I+S */
-#define CLRBUSFREE 0x08 /* I+S */
-#define CLRSCSIPERR 0x04 /* I+S */
-#define CLRPHASECHG 0x02 /* I+S */
-#define CLRREQINIT 0x01 /* I+S */
-
-/* SSTAT1 How to clear? When set?*/
-#define SELTO 0x80 /* C select out timeout */
-#define ATNTARG 0x40 /* Not used in initiator mode */
-#define SCSIRSTI 0x20 /* C RST asserted */
-#define PHASEMIS 0x10 /* Selfclearing */
-#define BUSFREE 0x08 /* C bus free condition */
-#define SCSIPERR 0x04 /* C parity error on inbound data */
-#define PHASECHG 0x02 /* C phase in SCSISIGI doesn't match */
-#define REQINIT 0x01 /* C or ACK asserting edge of REQ */
-
-/* SSTAT2 */
-#define SOFFSET 0x20
-#define SEMPTY 0x10
-#define SFULL 0x08
-#define SFCNT2 0x04
-#define SFCNT1 0x02
-#define SFCNT0 0x01
-
-/* SCSITEST */
-#define SCTESTU 0x08
-#define SCTESTD 0x04
-#define STCTEST 0x01
-
-/* SSTAT3 */
-#define SCSICNT3 0x80
-#define SCSICNT2 0x40
-#define SCSICNT1 0x20
-#define SCSICNT0 0x10
-#define OFFCNT3 0x08
-#define OFFCNT2 0x04
-#define OFFCNT1 0x02
-#define OFFCNT0 0x01
-
-/* CLRSERR */
-#define CLRSYNCERR 0x04
-#define CLRFWERR 0x02
-#define CLRFRERR 0x01
-
-/* SSTAT4 */
-#define SYNCERR 0x04
-#define FWERR 0x02
-#define FRERR 0x01
-
-/* SIMODE0 */
-#define ENSELDO 0x40
-#define ENSELDI 0x20
-#define ENSELINGO 0x10
-#define ENSWRAP 0x08
-#define ENSDONE 0x04
-#define ENSPIORDY 0x02
-#define ENDMADONE 0x01
-
-/* SIMODE1 */
-#define ENSELTIMO 0x80
-#define ENATNTARG 0x40
-#define ENSCSIRST 0x20
-#define ENPHASEMIS 0x10
-#define ENBUSFREE 0x08
-#define ENSCSIPERR 0x04
-#define ENPHASECHG 0x02
-#define ENREQINIT 0x01
-
-/* DMACNTRL0 */
-#define ENDMA 0x80
-#define B8MODE 0x40
-#define DMA 0x20
-#define DWORDPIO 0x10
-#define WRITE 0x08
-#define INTEN 0x04
-#define RSTFIFO 0x02
-#define SWINT 0x01
-
-/* DMACNTRL1 */
-#define PWRDWN 0x80
-#define ENSTK32 0x40
-#define STK4 0x10
-#define STK3 0x08
-#define STK2 0x04
-#define STK1 0x02
-#define STK0 0x01
-
-/* DMASTAT */
-#define ATDONE 0x80
-#define WORDRDY 0x40
-#define INTSTAT 0x20
-#define DFIFOFULL 0x10
-#define DFIFOEMP 0x08
-#define DFIFOHF 0x04
-#define DWORDRDY 0x02
-
-/* BRSTCNTRL */
-#define BON3 0x80
-#define BON2 0x40
-#define BON1 0x20
-#define BON0 0x10
-#define BOFF3 0x08
-#define BOFF2 0x04
-#define BOFF1 0x02
-#define BOFF0 0x01
-
-/* TEST */
-#define BOFFTMR 0x40
-#define BONTMR 0x20
-#define STCNTH 0x10
-#define STCNTM 0x08
-#define STCNTL 0x04
-#define SCSIBLK 0x02
-#define DMABLK 0x01
-
-
-#define orreg(reg, val) outb((reg), inb(reg)| (val))
-#define andreg(reg, val) outb((reg), inb(reg)& (val))
-#define nandreg(reg, val) outb((reg), inb(reg)&~(val))
-
-
-
-#ifdef DDB
-#define fatal_if_no_DDB()
-#else
-#define fatal_if_no_DDB() panic("panic for historical reasons")
-#endif
-
-typedef u_long physaddr;
-
-struct aic_dma_seg {
- physaddr addr;
- long len;
-};
-
-#define DELAYCOUNT 16
-
-#define FUDGE(X) ((X)>>1) /* get 1 ms spincount */
-#define MINIFUDGE(X) ((X)>>4) /* get (approx) 125us spincount */
-#define AIC_NSEG 16
-#define NUM_CONCURRENT 7 /* Only one per target for now */
-
-/*
- * ACB. Holds additional information for each SCSI command Comments: We
- * need a separate scsi command block because we may need to overwrite it
- * with a request sense command. Basicly, we refrain from fiddling with
- * the scsi_xfer struct (except do the expected updating of return values).
- * We'll generally update: xs->{flags,resid,error,sense,status} and
- * occasionally xs->retries.
- */
-
-struct acb {
- TAILQ_ENTRY(acb) chain;
- struct scsi_xfer *xs; /* SCSI xfer ctrl block from above */
- int flags; /* Status */
-#define ACB_FREE 0x00
-#define ACB_ACTIVE 0x01
-#define ACB_DONE 0x04
-#define ACB_CHKSENSE 0x08
-/* struct aic_dma_seg dma[AIC_NSEG]; */ /* Physical addresses+len */
- struct scsi_generic cmd; /* SCSI command block */
- int clen;
- char *daddr; /* Saved data pointer */
- int dleft; /* Residue */
- int stat; /* SCSI status byte */
-};
-
-/*
- * Some info about each (possible) target on the SCSI bus. This should
- * probably have been a "per target+lunit" structure, but we'll leave it at
- * this for now. Is there a way to reliably hook it up to sc->fordriver??
- */
-struct aic_tinfo {
- int cmds; /* #commands processed */
- int dconns; /* #disconnects */
- int touts; /* #timeouts */
- int perrs; /* #parity errors */
- int senses; /* #request sense commands sent */
- ushort lubusy; /* What local units/subr. are busy? */
- u_char flags;
-#define NEED_TO_RESET 0x01 /* Should send a BUS_DEV_RESET */
-#define DO_NEGOTIATE 0x02 /* (Re)Negotiate synchronous options */
-#define TARGET_BUSY 0x04 /* Target is busy, i.e. cmd in progress */
- u_char persgst; /* Period suggestion */
- u_char offsgst; /* Offset suggestion */
- u_char syncdata; /* True negotiated synch parameters */
-};
-
-/* Register a linenumber (for debugging) */
-#if AIC_DEBUG
-#define LOGLINE(p) \
- do { \
- p->history[p->hp] = __LINE__; \
- p->hp = ++p->hp % AIC_HSIZE; \
- } while (0)
-#else
-#define LOGLINE(p)
-#endif
-
-static struct aic_data { /* One of these per adapter */
- u_short iobase; /* Base I/O port */
- struct scsi_link sc_link; /* prototype for subdevs */
- int aic_int; /* IRQ on the EISA bus */
- int aic_dma; /* DRQ on the EISA bus */
- /* Lists of command blocks */
- TAILQ_HEAD(acb_list, acb) free_list, ready_list, nexus_list;
- struct acb *nexus; /* current command */
- /* Command blocks and target info */
- struct acb acb[NUM_CONCURRENT];
- struct aic_tinfo tinfo[8];
- /* Data about the current nexus (updated for every cmd switch) */
- u_char *dp; /* Current data pointer */
- int dleft; /* Data left to transfer */
- /* Adapter state */
- short phase; /* Copy of what bus phase we are in */
- short prevphase; /* Copy of what bus phase we were in */
- short state; /* State applicable to the adapter */
-#define AIC_IDLE 0x01
-#define AIC_TMP_UNAVAIL 0x02 /* Don't accept SCSI commands */
-#define AIC_SELECTING 0x03 /* SCSI command is arbiting */
-#define AIC_RESELECTED 0x04 /* Has been reselected */
-#define AIC_HASNEXUS 0x05 /* Actively using the SCSI bus */
-#define AIC_CLEANING 0x06
- short flags;
-#define AIC_DROP_MSGI 0x01 /* Discard all msgs (parity err detected) */
-#define AIC_DOINGDMA 0x02 /* The FIFO data path is active! */
-#define AIC_BUSFREE_OK 0x04 /* Bus free phase is OK. */
-#define AIC_SYNCHNEGO 0x08 /* Synch negotiation in progress. */
-#define AIC_BLOCKED 0x10 /* Don't schedule new scsi bus operations */
- /* Debugging stuff */
-#define AIC_HSIZE 8
- short history[AIC_HSIZE]; /* Store line numbers here. */
- short hp;
- u_char progress; /* Set if interrupt has achieved progress */
- /* Message stuff */
- u_char msgpriq; /* One or more messages to send (encoded) */
- u_char msgout; /* What message is on its way out? */
-#define SEND_DEV_RESET 0x01
-#define SEND_PARITY_ERROR 0x02
-#define SEND_ABORT 0x04
-#define SEND_REJECT 0x08
-#define SEND_INIT_DET_ERR 0x10
-#define SEND_IDENTIFY 0x20
-#define SEND_SDTR 0x40
-#define AIC_MAX_MSG_LEN 8
- u_char omess[AIC_MAX_MSG_LEN]; /* Scratch area for messages */
- u_char *omp; /* Message pointer (for multibyte messages) */
- u_char omlen;
- u_char imess[AIC_MAX_MSG_LEN + 1];
- u_char *imp; /* Message pointer (for multibyte messages) */
- u_char imlen;
-#ifdef PC98
- int *aicport; /* I/O port information */
-#endif
-} *aicdata[NAIC];
-
-#define AIC_SHOWACBS 0x01
-#define AIC_SHOWINTS 0x02
-#define AIC_SHOWCMDS 0x04
-#define AIC_SHOWMISC 0x08
-#define AIC_SHOWTRAC 0x10
-#define AIC_SHOWSTART 0x20
-static int aic_debug = 0; /* AIC_SHOWSTART|AIC_SHOWMISC|AIC_SHOWTRAC; */
-
-#if AIC_DEBUG
-#define AIC_ACBS(str) do {if (aic_debug & AIC_SHOWACBS) printf str;} while (0)
-#define AIC_MISC(str) do {if (aic_debug & AIC_SHOWMISC) printf str;} while (0)
-#define AIC_INTS(str) do {if (aic_debug & AIC_SHOWINTS) printf str;} while (0)
-#define AIC_TRACE(str) do {if (aic_debug & AIC_SHOWTRAC) printf str;} while (0)
-#define AIC_CMDS(str) do {if (aic_debug & AIC_SHOWCMDS) printf str;} while (0)
-#define AIC_START(str) do {if (aic_debug & AIC_SHOWSTART) printf str;}while (0)
-#else
-#define AIC_ACBS(str)
-#define AIC_MISC(str)
-#define AIC_INTS(str)
-#define AIC_TRACE(str)
-#define AIC_CMDS(str)
-#define AIC_START(str)
-#endif
-
-static int aicprobe __P((struct isa_device *));
-static int aicattach __P((struct isa_device *));
-static void aic_minphys __P((struct buf *));
-static u_int32_t aic_adapter_info __P((int));
-static void aic_init __P((struct aic_data *));
-static int aic_find __P((struct aic_data *));
-static void aic_done __P((struct acb *));
-static void aic_dataout __P((struct aic_data *aic));
-static void aic_datain __P((struct aic_data *aic));
-static int32_t aic_scsi_cmd __P((struct scsi_xfer *));
-static int aic_poll __P((struct aic_data *aic, struct acb *));
-void aic_add_timeout __P((struct acb *, int));
-void aic_remove_timeout __P((struct acb *));
-static void aic6360_reset __P((struct aic_data *aic));
-static u_short aicphase __P((struct aic_data *aic));
-static void aic_msgin __P((struct aic_data *aic));
-static void aic_msgout __P((struct aic_data *aic));
-static timeout_t aic_timeout;
-static void aic_sched __P((struct aic_data *));
-static void aic_scsi_reset __P((struct aic_data *));
-#if AIC_DEBUG
-void aic_print_active_acb __P((void));
-void aic_dump6360 __P((void));
-void aic_dump_driver __P((void));
-#endif
-
-/* Linkup to the rest of the kernel */
-struct isa_driver aicdriver = {
- aicprobe, aicattach, "aic"
-};
-
-static int aicunit = 0;
-
-static struct scsi_adapter aic_switch = {
- aic_scsi_cmd,
- aic_minphys,
- 0,
- 0,
- aic_adapter_info,
- "aic"
- ,0 , 0
-};
-
-static struct scsi_device aic_dev = {
- NULL, /* Use default error handler */
- NULL, /* have a queue, served by this */
- NULL, /* have no async handler */
- NULL, /* Use default 'done' routine */
- "aic",
- 0
-};
-
-
-/*
- * INITIALIZATION ROUTINES (probe, attach ++)
- */
-
-/*
- * aicprobe: probe for AIC6360 SCSI-controller
- * returns non-zero value if a controller is found.
- */
-static int
-aicprobe(dev)
- struct isa_device *dev;
-{
- int unit = aicunit;
- struct aic_data *aic;
-
- if (unit >= NAIC) {
- printf("aic%d: unit number too high\n", unit);
- return 0;
- }
- dev->id_unit = unit;
- /*
- * Allocate a storage area for us
- */
- if (aicdata[unit]) {
- printf("aic%d: memory already allocated\n", unit);
- return 0;
- }
- aic = malloc(sizeof(struct aic_data), M_TEMP, M_NOWAIT);
- if (!aic) {
- printf("aic%d: cannot malloc!\n", unit);
- return 0;
- }
- bzero(aic, sizeof(struct aic_data));
- aicdata[unit] = aic;
- aic->iobase = dev->id_iobase;
-#ifdef PC98
- if (AIC_TYPE98(dev->id_flags) == AIC98_100) {
- /* PC-9801-100 */
- aic->aicport = aicport_100;
- } else {
- /* generic card */
- aic->aicport = aicport_generic;
- }
-#endif
-
- if (aic_find(aic) != 0) {
- aicdata[unit] = NULL;
- free(aic, M_TEMP);
- return 0;
- }
- aicunit++;
-#ifdef PC98
- return 0x40;
-#else
- return 0x20;
-#endif
-}
-
-/* Do the real search-for-device.
- * Prerequisite: aic->iobase should be set to the proper value
- */
-static int
-aic_find(aic)
- struct aic_data *aic;
-{
- u_short iobase = aic->iobase;
- char chip_id[sizeof(IDSTRING)]; /* For chips that support it */
- int i;
-
- /* Remove aic6360 from possible powerdown mode */
- outb(DMACNTRL0, 0);
-
- /* Thanks to mark@aggregate.com for the new method for detecting
- * whether the chip is present or not. Bonus: may also work for
- * the AIC-6260!
- */
- AIC_TRACE(("aic: probing for aic-chip at port 0x%x\n",(int)iobase));
- /*
- * Linux also init's the stack to 1-16 and then clears it,
- * 6260's don't appear to have an ID reg - mpg
- */
- /* Push the sequence 0,1,..,15 on the stack */
-#define STSIZE 16
- outb(DMACNTRL1, 0); /* Reset stack pointer */
- for (i = 0; i < STSIZE; i++)
- outb(STACK, i);
-
- /* See if we can pull out the same sequence */
- outb(DMACNTRL1, 0);
- for (i = 0; i < STSIZE && inb(STACK) == i; i++)
- ;
- if (i != STSIZE) {
- AIC_START(("STACK futzed at %d.\n", i));
- return ENXIO;
- }
-
- /* See if we can pull the id string out of the ID register,
- * now only used for informational purposes.
- */
- bzero(chip_id, sizeof(chip_id));
- insb(ID, chip_id, sizeof(IDSTRING)-1);
- AIC_START(("AIC found at 0x%x ", (int)aic->iobase));
- AIC_START(("ID: %s ",chip_id));
- AIC_START(("chip revision %d\n",(int)inb(REV)));
- return 0;
-}
-
-
-/*
- * Attach the AIC6360, fill out some high and low level data structures
- */
-static int
-aicattach(dev)
- struct isa_device *dev;
-{
- int unit = dev->id_unit;
- struct aic_data *aic = aicdata[unit];
- struct scsibus_data *scbus;
-
- AIC_TRACE(("aicattach\n"));
- aic->state = 0;
- aic_scsi_reset(aic);
- aic_init(aic); /* Init chip and driver */
-
- /*
- * Fill in the prototype scsi_link
- */
- aic->sc_link.adapter_unit = unit;
- aic->sc_link.adapter_targ = AIC_SCSI_HOSTID;
- aic->sc_link.adapter_softc = aic;
- aic->sc_link.adapter = &aic_switch;
- aic->sc_link.device = &aic_dev;
-
- /*
- * Prepare the scsibus_data area for the upperlevel
- * scsi code.
- */
- scbus = scsi_alloc_bus();
- if(!scbus)
- return 0;
- scbus->adapter_link = &aic->sc_link;
-
- /*
- * ask the adapter what subunits are present
- */
- scsi_attachdevs(scbus);
-
- return 1;
-}
-
-
-/* Initialize AIC6360 chip itself
- * The following conditions should hold:
- * aicprobe should have succeeded, i.e. the iobase address in aic_data must
- * be valid.
- */
-static void
-aic6360_reset(aic)
- struct aic_data *aic;
-{
- u_short iobase = aic->iobase;
-
- outb(SCSITEST, 0); /* Doc. recommends to clear these two */
- outb(TEST, 0); /* registers before operations commence */
-
- /* Reset SCSI-FIFO and abort any transfers */
- outb(SXFRCTL0, CHEN|CLRCH|CLRSTCNT);
-
- /* Reset DMA-FIFO */
- outb(DMACNTRL0, RSTFIFO);
- outb(DMACNTRL1, 0);
-
- outb(SCSISEQ, 0); /* Disable all selection features */
- outb(SXFRCTL1, 0);
-
- outb(SIMODE0, 0x00); /* Disable some interrupts */
- outb(CLRSINT0, 0x7f); /* Clear a slew of interrupts */
-
- outb(SIMODE1, 0x00); /* Disable some more interrupts */
- outb(CLRSINT1, 0xef); /* Clear another slew of interrupts */
-
- outb(SCSIRATE, 0); /* Disable synchronous transfers */
-
- outb(CLRSERR, 0x07); /* Haven't seen ant errors (yet) */
-
- outb(SCSIID, AIC_SCSI_HOSTID << OID_S); /* Set our SCSI-ID */
- outb(BRSTCNTRL, EISA_BRST_TIM);
-}
-
-/* Pull the SCSI RST line for 500 us */
-static void
-aic_scsi_reset(aic)
- struct aic_data *aic;
-{
- u_short iobase = aic->iobase;
-
- outb(SCSISEQ, SCSIRSTO);
- DELAY(500);
- outb(SCSISEQ, 0);
- DELAY(50);
-}
-
-/*
- * Initialize aic SCSI driver, also (conditonally) reset the SCSI bus.
- * The reinitialization is still buggy (e.g. on SCSI resets).
- */
-static void
-aic_init(aic)
- struct aic_data *aic;
-{
- u_short iobase = aic->iobase;
- struct acb *acb;
- int r;
-
- /* Reset the SCSI-bus itself */
- aic_scsi_reset(aic);
-
- aic6360_reset(aic); /* Clean up our own hardware */
-
-/*XXX*/ /* If not the first time (probably a reset condition),
- * we should clean queues with active commands
- */
- if (aic->state == 0) { /* First time through */
- TAILQ_INIT(&aic->ready_list);
- TAILQ_INIT(&aic->nexus_list);
- TAILQ_INIT(&aic->free_list);
- aic->nexus = 0;
- acb = aic->acb;
- bzero(acb, sizeof(aic->acb));
- for (r = 0; r < sizeof(aic->acb) / sizeof(*acb); r++) {
- TAILQ_INSERT_TAIL(&aic->free_list, acb, chain);
- acb++;
- }
- bzero(&aic->tinfo, sizeof(aic->tinfo));
- } else {
- aic->state = AIC_CLEANING;
- if (aic->nexus != NULL) {
- aic->nexus->xs->error = XS_DRIVER_STUFFUP;
- untimeout(aic_timeout, (caddr_t)aic->nexus);
- aic_done(aic->nexus);
- }
- aic->nexus = NULL;
- while (acb = aic->nexus_list.tqh_first) {
- acb->xs->error = XS_DRIVER_STUFFUP;
- untimeout(aic_timeout, (caddr_t)acb);
- aic_done(acb);
- }
- }
-
- aic->phase = aic->prevphase = PH_INVALID;
- aic->hp = 0;
- for (r = 0; r < 7; r++) {
- struct aic_tinfo *tp = &aic->tinfo[r];
- tp->flags = AIC_USE_SYNCHRONOUS ? DO_NEGOTIATE : 0;
- tp->flags |= NEED_TO_RESET;
- tp->persgst = AIC_SYNC_PERIOD;
- tp->offsgst = AIC_SYNC_REQ_ACK_OFS;
- tp->syncdata = 0;
- }
- aic->state = AIC_IDLE;
- outb(DMACNTRL0, INTEN);
- return;
-}
-
-/*
- * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
- */
-
-/*
- * Expected sequence:
- * 1) Command inserted into ready list
- * 2) Command selected for execution
- * 3) Command won arbitration and has selected target device
- * 4) Send message out (identify message, eventually also sync.negotiations)
- * 5) Send command
- * 5a) Receive disconnect message, disconnect.
- * 5b) Reselected by target
- * 5c) Receive identify message from target.
- * 6) Send or receive data
- * 7) Receive status
- * 8) Receive message (command complete etc.)
- * 9) If status == SCSI_CHECK construct a synthetic request sense SCSI cmd.
- * Repeat 2-8 (no disconnects please...)
- */
-
-/*
- * Start a SCSI-command
- * This function is called by the higher level SCSI-driver to queue/run
- * SCSI-commands.
- */
-static int32_t
-aic_scsi_cmd(xs)
- struct scsi_xfer *xs;
-{
- struct scsi_link *sc = xs->sc_link;
- struct aic_data *aic;
- struct acb *acb;
- int s = 0;
- int flags;
-
- aic = (struct aic_data *)sc->adapter_softc;
- SC_DEBUG(sc, SDEV_DB2, ("aic_scsi_cmd\n"));
- AIC_TRACE(("aic_scsi_cmd\n"));
- AIC_MISC(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
- sc->target));
-
- flags = xs->flags;
-
- /* Get a aic command block */
- if (!(flags & SCSI_NOMASK)) {
- /* Critical region */
- s = splbio();
- acb = aic->free_list.tqh_first;
- if (acb) {
- TAILQ_REMOVE(&aic->free_list, acb, chain);
- }
- splx(s);
- } else {
- acb = aic->free_list.tqh_first;
- if (acb) {
- TAILQ_REMOVE(&aic->free_list, acb, chain);
- }
- }
-
- if (acb == NULL) {
- xs->error = XS_DRIVER_STUFFUP;
- AIC_MISC(("TRY_AGAIN_LATER"));
- return TRY_AGAIN_LATER;
- }
-
- /* Initialize acb */
- acb->flags = ACB_ACTIVE;
- acb->xs = xs;
- bcopy(xs->cmd, &acb->cmd, xs->cmdlen);
- acb->clen = xs->cmdlen;
- acb->daddr = xs->data;
- acb->dleft = xs->datalen;
- acb->stat = 0;
-
- if (!(flags & SCSI_NOMASK))
- s = splbio();
-
- TAILQ_INSERT_TAIL(&aic->ready_list, acb, chain);
- timeout(aic_timeout, (caddr_t)acb, (xs->timeout*hz)/1000);
-
- if (aic->state == AIC_IDLE)
- aic_sched(aic);
-
- if (!(flags & SCSI_NOMASK)) { /* Almost done. Wait outside */
- splx(s);
- AIC_MISC(("SUCCESSFULLY_QUEUED"));
- return SUCCESSFULLY_QUEUED;
- }
-
- /* Not allowed to use interrupts, use polling instead */
- return aic_poll(aic, acb);
-}
-
-/*
- * Adjust transfer size in buffer structure
- */
-static void
-aic_minphys(bp)
- struct buf *bp;
-{
-
- AIC_TRACE(("aic_minphys\n"));
- if (bp->b_bcount > (AIC_NSEG << PAGE_SHIFT))
- bp->b_bcount = (AIC_NSEG << PAGE_SHIFT);
-}
-
-
-static u_int32_t
-aic_adapter_info(unit)
- int unit;
-{
-
- AIC_TRACE(("aic_adapter_info\n"));
- return (2); /* One outstanding command per target */
-}
-
-/*
- * Used when interrupt driven I/O isn't allowed, e.g. during boot.
- */
-static int
-aic_poll(aic, acb)
- struct aic_data *aic;
- struct acb *acb;
-{
- register u_short iobase = aic->iobase;
- struct scsi_xfer *xs = acb->xs;
- int count = xs->timeout * 10;
-
- AIC_TRACE(("aic_poll\n"));
- while (count) {
- if (inb(DMASTAT) & INTSTAT)
- aicintr(xs->sc_link->adapter_unit);
- if (xs->flags & ITSDONE)
- break;
- DELAY(100);
- count--;
- }
- if (count == 0) {
- AIC_MISC(("aic_poll: timeout"));
- aic_timeout((caddr_t)acb);
- }
- if (xs->error)
- return HAD_ERROR;
- return COMPLETE;
-}
-
-/* LOW LEVEL SCSI UTILITIES */
-
-/* Determine the SCSI bus phase, return either a real SCSI bus phase or some
- * pseudo phase we use to detect certain exceptions. This one is a bit tricky.
- * The bits we peek at:
- * CDI, MSGI and DI is the 3 SCSI signals determining the bus phase.
- * These should be qualified by REQI high and ACKI low.
- * Also peek at SSTAT0[SELDO|SELDI] to detect a passing BUSFREE condition.
- * No longer detect SCSI RESET or PERR here. They are tested for separately
- * in the interrupt handler.
- * Note: If an exception occur at some critical time during the phase
- * determination we'll most likely return something wildly erronous....
- */
-static inline u_short
-aicphase(aic)
- struct aic_data *aic;
-{
- register u_short iobase = aic->iobase;
- register u_char sstat0, sstat1, scsisig;
-
- sstat1 = inb(SSTAT1); /* Look for REQINIT (REQ asserted) */
- scsisig = inb(SCSISIGI); /* Get the SCSI bus signals */
- sstat0 = inb(SSTAT0); /* Get the selection valid status bits */
-
- if (!(inb(SSTAT0) & (SELDO|SELDI))) /* Selection became invalid? */
- return PH_BUSFREE;
-
- /* Selection is still valid */
- if (!(sstat1 & REQINIT)) /* REQ not asserted ? */
- return PH_INVALID;
-
- /* REQ is asserted, (and ACK is not) */
- return scsisig & PH_MASK;
-}
-
-
-/* Schedule a scsi operation. This has now been pulled out of the interrupt
- * handler so that we may call it from aic_scsi_cmd and aic_done. This may
- * save us an unecessary interrupt just to get things going. Should only be
- * called when state == AIC_IDLE and at bio pl.
- */
-static void
-aic_sched(aic)
- register struct aic_data *aic;
-{
- struct scsi_link *sc;
- struct acb *acb;
- u_short iobase = aic->iobase;
- int t;
- u_char simode0, simode1, scsiseq;
-
- AIC_TRACE(("aic_sched\n"));
- simode0 = ENSELDI;
- simode1 = ENSCSIRST|ENSCSIPERR|ENREQINIT;
- scsiseq = ENRESELI;
- /*
- * Find first acb in rdy queue that is for a target/lunit
- * combinations that is not busy.
- */
- outb(CLRSINT1, CLRSELTIMO|CLRBUSFREE|CLRSCSIPERR);
- for (acb = aic->ready_list.tqh_first; acb; acb = acb->chain.tqe_next) {
- sc = acb->xs->sc_link;
- t = sc->target;
- if (!(aic->tinfo[t].lubusy & (1 << sc->lun))) {
- TAILQ_REMOVE(&aic->ready_list, acb, chain);
- aic->nexus = acb;
- aic->state = AIC_SELECTING;
- /*
- * Start selection process. Always enable
- * reselections. Note: we don't have a nexus yet, so
- * cannot set aic->state = AIC_HASNEXUS.
- */
- simode0 = ENSELDI|ENSELDO;
- simode1 = ENSCSIRST|ENSCSIPERR|
- ENREQINIT|ENSELTIMO;
- scsiseq = ENRESELI|ENSELO|ENAUTOATNO;
- outb(SCSIID, AIC_SCSI_HOSTID << OID_S | t);
- outb(SXFRCTL1, STIMO_256ms|ENSTIMER);
- outb(CLRSINT0, CLRSELDO);
- break;
- }
-#if AIC_DEBUG
- else
- AIC_MISC(("%d:%d busy\n", t, sc->lun));
-#endif
- }
- AIC_MISC(("%sselecting\n",scsiseq&ENSELO?"":"re"));
- outb(SIMODE0, simode0);
- outb(SIMODE1, simode1);
- outb(SCSISEQ, scsiseq);
-}
-
-
-/*
- * POST PROCESSING OF SCSI_CMD (usually current)
- */
-static void
-aic_done(acb)
- struct acb *acb;
-{
- struct scsi_xfer *xs = acb->xs;
- struct scsi_link *sc = xs->sc_link;
- struct aic_data *aic = (struct aic_data *)sc->adapter_softc;
-
- AIC_TRACE(("aic_done "));
-
- /*
- * Now, if we've come here with no error code, i.e. we've kept the
- * initial XS_NOERROR, and the status code signals that we should
- * check sense, we'll need to set up a request sense cmd block and
- * push the command back into the ready queue *before* any other
- * commands for this target/lunit, else we lose the sense info.
- * We don't support chk sense conditions for the request sense cmd.
- */
- if (xs->error == XS_NOERROR && !(acb->flags & ACB_CHKSENSE)) {
- if ((acb->stat & ST_MASK)==SCSI_CHECK) {
- struct scsi_sense *ss = (void *)&acb->cmd;
- AIC_MISC(("requesting sense "));
- /* First, save the return values */
- xs->resid = acb->dleft;
- xs->status = acb->stat;
- /* Next, setup a request sense command block */
- bzero(ss, sizeof(*ss));
- ss->op_code = REQUEST_SENSE;
- ss->byte2 = sc->lun << 5;
- ss->length = sizeof(struct scsi_sense_data);
- acb->clen = sizeof(*ss);
- acb->daddr = (char *)&xs->sense;
- acb->dleft = sizeof(struct scsi_sense_data);
- acb->flags = ACB_ACTIVE|ACB_CHKSENSE;
- TAILQ_INSERT_HEAD(&aic->ready_list, acb, chain);
- aic->tinfo[sc->target].lubusy &= ~(1<<sc->lun);
- aic->tinfo[sc->target].senses++;
- if (aic->nexus == acb) {
- aic->nexus = NULL;
- aic->state = AIC_IDLE;
- aic_sched(aic);
- }
- return;
- }
- }
-
- if (xs->flags & SCSI_ERR_OK) {
- xs->resid = 0;
- xs->error = XS_NOERROR;
- } else if (xs->error == XS_NOERROR && (acb->flags & ACB_CHKSENSE)) {
- xs->error = XS_SENSE;
- } else {
- xs->resid = acb->dleft;
- }
- xs->flags |= ITSDONE;
-
-#if AIC_DEBUG
- if (aic_debug & AIC_SHOWMISC) {
- printf("err=0x%02x ",xs->error);
- if (xs->error == XS_SENSE)
- printf("sense=%2x\n", xs->sense.error_code);
- }
- if ((xs->resid || xs->error > XS_SENSE) && aic_debug & AIC_SHOWMISC) {
- if (xs->resid)
- printf("aic_done: resid=%d\n", xs->resid);
- if (xs->error)
- printf("aic_done: error=%d\n", xs->error);
- }
-#endif
-
- /*
- * Remove the ACB from whatever queue it's on. We have to do a bit of
- * a hack to figure out which queue it's on. Note that it is *not*
- * necessary to cdr down the ready queue, but we must cdr down the
- * nexus queue and see if it's there, so we can mark the unit as no
- * longer busy. This code is sickening, but it works.
- */
- if (acb == aic->nexus) {
- aic->state = AIC_IDLE;
- aic->tinfo[sc->target].lubusy &= ~(1<<sc->lun);
- aic_sched(aic);
- } else if (aic->ready_list.tqh_last == &acb->chain.tqe_next) {
- TAILQ_REMOVE(&aic->ready_list, acb, chain);
- } else {
- register struct acb *acb2;
- for (acb2 = aic->nexus_list.tqh_first; acb2;
- acb2 = acb2->chain.tqe_next)
- if (acb2 == acb) {
- TAILQ_REMOVE(&aic->nexus_list, acb, chain);
- aic->tinfo[sc->target].lubusy &= ~(1<<sc->lun);
- /* XXXX Should we call aic_sched() here? */
- break;
- }
- if (acb2)
- ;
- else if (acb->chain.tqe_next) {
- TAILQ_REMOVE(&aic->ready_list, acb, chain);
- } else {
- printf("aic%d: can't find matching acb\n",
- xs->sc_link->adapter_unit);
- Debugger("aic6360");
- fatal_if_no_DDB();
- }
- }
- /* Put it on the free list. */
- acb->flags = ACB_FREE;
- TAILQ_INSERT_HEAD(&aic->free_list, acb, chain);
-
- aic->tinfo[sc->target].cmds++;
- scsi_done(xs);
- return;
-}
-
-/*
- * INTERRUPT/PROTOCOL ENGINE
- */
-
-/* The message system:
- * This is a revamped message system that now should easier accomodate new
- * messages, if necessary.
- * Currently we accept these messages:
- * IDENTIFY (when reselecting)
- * COMMAND COMPLETE # (expect bus free after messages marked #)
- * NOOP
- * MESSAGE REJECT
- * SYNCHRONOUS DATA TRANSFER REQUEST
- * SAVE DATA POINTER
- * RESTORE POINTERS
- * DISCONNECT #
- *
- * We may send these messages in prioritized order:
- * BUS DEVICE RESET # if SCSI_RESET & xs->flags (or in weird sits.)
- * MESSAGE PARITY ERROR par. err. during MSGI
- * MESSAGE REJECT If we get a message we don't know how to handle
- * ABORT # send on errors
- * INITIATOR DETECTED ERROR also on errors (SCSI2) (during info xfer)
- * IDENTIFY At the start of each transfer
- * SYNCHRONOUS DATA TRANSFER REQUEST if appropriate
- * NOOP if nothing else fits the bill ...
- */
-
-#define aic_sched_msgout(m) \
- do { \
- orreg(SCSISIGO, ATNO); \
- aic->msgpriq |= (m); \
- } while (0)
-
-#define IS1BYTEMSG(m) (((m) != 1 && (m) < 0x20) || (m) >= 0x80)
-#define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
-#define ISEXTMSG(m) ((m) == 1)
-/* Precondition:
- * The SCSI bus is already in the MSGI phase and there is a message byte
- * on the bus, along with an asserted REQ signal.
- */
-static void
-aic_msgin(aic)
- register struct aic_data *aic;
-{
- register u_short iobase = aic->iobase;
- int spincount, extlen;
- u_char sstat1;
-
- AIC_TRACE(("aic_msgin "));
- outb(SCSISIGO, PH_MSGI);
- /* Prepare for a new message. A message should (according to the SCSI
- * standard) be transmitted in one single message_in phase.
- * If we have been in some other phase, then this is a new message.
- */
- if (aic->prevphase != PH_MSGI) {
- aic->flags &= ~AIC_DROP_MSGI;
- aic->imlen = 0;
- }
- /*
- * Read a whole message but the last byte. If we shall reject the
- * message, we shall have to do it, by asserting ATNO, during the
- * message transfer phase itself.
- */
- for (;;) {
- sstat1 = inb(SSTAT1);
- /* If parity errors just dump everything on the floor, also
- * a parity error automatically sets ATNO
- */
- if (sstat1 & SCSIPERR) {
- aic_sched_msgout(SEND_PARITY_ERROR);
- aic->flags |= AIC_DROP_MSGI;
- }
- /*
- * If we're going to reject the message, don't bother storing
- * the incoming bytes. But still, we need to ACK them.
- */
- if (!(aic->flags & AIC_DROP_MSGI)) {
- /* Get next message byte */
- aic->imess[aic->imlen] = inb(SCSIDAT);
- /*
- * This testing is suboptimal, but most messages will
- * be of the one byte variety, so it should not effect
- * performance significantly.
- */
- if (IS1BYTEMSG(aic->imess[0]))
- break;
- if (IS2BYTEMSG(aic->imess[0]) && aic->imlen == 1)
- break;
- if (ISEXTMSG(aic->imess[0]) && aic->imlen > 0) {
- if (aic->imlen == AIC_MAX_MSG_LEN) {
- aic->flags |= AIC_DROP_MSGI;
- aic_sched_msgout(SEND_REJECT);
- }
- extlen = aic->imess[1] ? aic->imess[1] : 256;
- if (aic->imlen == extlen + 2)
- break; /* Got it all */
- }
- }
- /* If we reach this spot we're either:
- * a) in the middle of a multi-byte message or
- * b) we're dropping bytes
- */
- outb(SXFRCTL0, CHEN|SPIOEN);
- inb(SCSIDAT); /* Really read it (ACK it, that is) */
- outb(SXFRCTL0, CHEN);
- aic->imlen++;
-
- /*
- * We expect the bytes in a multibyte message to arrive
- * relatively close in time, a few microseconds apart.
- * Therefore we will spinwait for some small amount of time
- * waiting for the next byte.
- */
- spincount = DELAYCOUNT * AIC_MSGI_SPIN;
- LOGLINE(aic);
- while (spincount-- && !((sstat1 = inb(SSTAT1)) & REQINIT))
- ;
- if (spincount == -1 || sstat1 & (PHASEMIS|BUSFREE))
- return;
- }
- /* Now we should have a complete message (1 byte, 2 byte and moderately
- * long extended messages). We only handle extended messages which
- * total length is shorter than AIC_MAX_MSG_LEN. Longer messages will
- * be amputated. (Return XS_BOBBITT ?)
- */
- if (aic->state == AIC_HASNEXUS) {
- struct acb *acb = aic->nexus;
- struct aic_tinfo *ti = &aic->tinfo[acb->xs->sc_link->target];
- int offs, per, rate;
-
- outb(SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE|ENSCSIPERR);
- switch (aic->imess[0]) {
- case MSG_CMDCOMPLETE:
- if (!acb) {
- aic_sched_msgout(SEND_ABORT);
- printf("aic: CMDCOMPLETE but no command?\n");
- break;
- }
- if (aic->dleft < 0) {
- struct scsi_link *sc = acb->xs->sc_link;
- printf("aic: %d extra bytes from %d:%d\n",
- -aic->dleft, sc->target, sc->lun);
- acb->dleft = 0;
- }
- acb->xs->resid = acb->dleft = aic->dleft;
- aic->flags |= AIC_BUSFREE_OK;
- untimeout(aic_timeout, (caddr_t)acb);
- aic_done(acb);
- break;
- case MSG_MESSAGE_REJECT:
- if (aic_debug & AIC_SHOWMISC)
- printf("aic: our msg rejected by target\n");
- if (aic->flags & AIC_SYNCHNEGO) {
- ti->syncdata = 0;
- ti->persgst = ti->offsgst = 0;
- aic->flags &= ~AIC_SYNCHNEGO;
- ti->flags &= ~DO_NEGOTIATE;
- }
- /* Not all targets understand INITIATOR_DETECTED_ERR */
- if (aic->msgout == SEND_INIT_DET_ERR)
- aic_sched_msgout(SEND_ABORT);
- break;
- case MSG_NOOP: /* Will do! Immediately, sir!*/
- break; /* Hah, that was easy! */
- case MSG_DISCONNECT:
- if (!acb) {
- aic_sched_msgout(SEND_ABORT);
- printf("aic: nothing to DISCONNECT\n");
- break;
- }
- ti->dconns++;
- TAILQ_INSERT_HEAD(&aic->nexus_list, acb, chain);
- acb = aic->nexus = NULL;
- aic->state = AIC_IDLE;
- aic->flags |= AIC_BUSFREE_OK;
- break;
- case MSG_SAVEDATAPOINTER:
- if (!acb) {
- aic_sched_msgout(SEND_ABORT);
- printf("aic: no DATAPOINTERs to save\n");
- break;
- }
- acb->dleft = aic->dleft;
- acb->daddr = aic->dp;
- break;
- case MSG_RESTOREPOINTERS:
- if (!acb) {
- aic_sched_msgout(SEND_ABORT);
- printf("aic: no DATAPOINTERs to restore\n");
- break;
- }
- aic->dp = acb->daddr;
- aic->dleft = acb->dleft;
- break;
- case MSG_EXTENDED:
- switch (aic->imess[2]) {
- case MSG_EXT_SDTR:
- per = aic->imess[3] * 4;
- rate = (per + 49 - 100)/50;
- offs = aic->imess[4];
- if (offs == 0)
- ti->syncdata = 0;
- else if (rate > 7) {
- /* Too slow for aic6360. Do asynch
- * instead. Renegotiate the deal.
- */
- ti->persgst = 0;
- ti->offsgst = 0;
- aic_sched_msgout(SEND_SDTR);
- } else {
- rate = rate<<4 | offs;
- ti->syncdata = rate;
- }
- break;
- default: /* Extended messages we don't handle */
- aic_sched_msgout(SEND_REJECT);
- break;
- }
- break;
- default:
- aic_sched_msgout(SEND_REJECT);
- break;
- }
- } else if (aic->state == AIC_RESELECTED) {
- struct scsi_link *sc;
- struct acb *acb;
- u_char selid, lunit;
- /*
- * Which target is reselecting us? (The ID bit really)
- */
- selid = inb(SELID) & ~(1<<AIC_SCSI_HOSTID);
- if (MSG_ISIDENT(aic->imess[0])) { /* Identify? */
- AIC_MISC(("searching "));
- /* Search wait queue for disconnected cmd
- * The list should be short, so I haven't bothered with
- * any more sophisticated structures than a simple
- * singly linked list.
- */
- lunit = aic->imess[0] & 0x07;
- for (acb = aic->nexus_list.tqh_first; acb;
- acb = acb->chain.tqe_next) {
- sc = acb->xs->sc_link;
- if (sc->lun == lunit &&
- selid == (1<<sc->target)) {
- TAILQ_REMOVE(&aic->nexus_list, acb,
- chain);
- break;
- }
- }
- if (!acb) { /* Invalid reselection! */
- aic_sched_msgout(SEND_ABORT);
- printf("aic: invalid reselect (idbit=0x%2x)\n",
- selid);
- } else { /* Reestablish nexus */
- /* Setup driver data structures and
- * do an implicit RESTORE POINTERS
- */
- aic->nexus = acb;
- aic->dp = acb->daddr;
- aic->dleft = acb->dleft;
- aic->tinfo[sc->target].lubusy |= (1<<sc->lun);
- outb(SCSIRATE,aic->tinfo[sc->target].syncdata);
- AIC_MISC(("... found acb"));
- aic->state = AIC_HASNEXUS;
- }
- } else {
- printf("aic: bogus reselect (no IDENTIFY) %0x2x\n",
- selid);
- aic_sched_msgout(SEND_DEV_RESET);
- }
- } else { /* Neither AIC_HASNEXUS nor AIC_RESELECTED! */
- printf("aic: unexpected message in; will send DEV_RESET\n");
- aic_sched_msgout(SEND_DEV_RESET);
- }
- /* Must not forget to ACK the last message byte ... */
- outb(SXFRCTL0, CHEN|SPIOEN);
- inb(SCSIDAT);
- outb(SXFRCTL0, CHEN);
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|ENSCSIPERR|ENREQINIT);
-}
-
-
-/* The message out (and in) stuff is a bit complicated:
- * If the target requests another message (sequence) without
- * having changed phase in between it really asks for a
- * retransmit, probably due to parity error(s).
- * The following messages can be sent:
- * IDENTIFY @ These 3 stems from scsi command activity
- * BUS_DEV_RESET @
- * IDENTIFY + SDTR @
- * MESSAGE_REJECT if MSGI doesn't make sense
- * MESSAGE_PARITY_ERROR if MSGI spots a parity error
- * NOOP if asked for a message and there's nothing to send
- */
-static void
-aic_msgout(aic)
- register struct aic_data *aic;
-{
- register u_short iobase = aic->iobase;
- struct aic_tinfo *ti;
- struct acb *acb;
-
- /* First determine what to send. If we haven't seen a
- * phasechange this is a retransmission request.
- */
- outb(SCSISIGO, PH_MSGO);
- if (aic->prevphase != PH_MSGO) { /* NOT a retransmit */
- /* Pick up highest priority message */
- aic->msgout = aic->msgpriq & -aic->msgpriq; /* What message? */
- aic->omlen = 1; /* "Default" message len */
- switch (aic->msgout) {
- case SEND_SDTR: /* Also implies an IDENTIFY message */
- acb = aic->nexus;
- ti = &aic->tinfo[acb->xs->sc_link->target];
- aic->omess[1] = MSG_EXTENDED;
- aic->omess[2] = 3;
- aic->omess[3] = MSG_EXT_SDTR;
- aic->omess[4] = ti->persgst >> 2;
- aic->omess[5] = ti->offsgst;
- aic->omlen = 6;
- /* Fallthrough! */
- case SEND_IDENTIFY:
- if (aic->state != AIC_HASNEXUS) {
- printf("aic at line %d: no nexus", __LINE__);
- Debugger("aic6360");
- fatal_if_no_DDB();
- }
- acb = aic->nexus;
- aic->omess[0] = MSG_IDENTIFY(acb->xs->sc_link->lun);
- break;
- case SEND_DEV_RESET:
- aic->omess[0] = MSG_BUS_DEV_RESET;
- aic->flags |= AIC_BUSFREE_OK;
- break;
- case SEND_PARITY_ERROR:
- aic->omess[0] = MSG_PARITY_ERR;
- break;
- case SEND_ABORT:
- aic->omess[0] = MSG_ABORT;
- aic->flags |= AIC_BUSFREE_OK;
- break;
- case SEND_INIT_DET_ERR:
- aic->omess[0] = MSG_INITIATOR_DET_ERR;
- break;
- case SEND_REJECT:
- aic->omess[0] = MSG_MESSAGE_REJECT;
- break;
- default:
- aic->omess[0] = MSG_NOOP;
- break;
- }
- aic->omp = aic->omess;
- } else if (aic->omp == &aic->omess[aic->omlen]) {
- /* Have sent the message at least once, this is a retransmit.
- */
- AIC_MISC(("retransmitting "));
- if (aic->omlen > 1)
- outb(SCSISIGO, PH_MSGO|ATNO);
- }
- /* else, we're in the middle of a multi-byte message */
- outb(SXFRCTL0, CHEN|SPIOEN);
- outb(DMACNTRL0, INTEN|RSTFIFO);
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|ENSCSIPERR|ENREQINIT);
- do {
- LOGLINE(aic);
- do {
- aic->phase = aicphase(aic);
- } while (aic->phase == PH_INVALID);
- if (aic->phase != PH_MSGO)
- /* Target left MSGO, possibly to reject our
- * message
- */
- break;
- /* Clear ATN before last byte */
- if (aic->omp == &aic->omess[aic->omlen-1])
- outb(CLRSINT1, CLRATNO);
- outb(SCSIDAT, *aic->omp++); /* Send MSG */
- LOGLINE(aic);
- while (inb(SCSISIGI) & ACKO)
- ;
- } while (aic->omp != &aic->omess[aic->omlen]);
- aic->progress = aic->omp != aic->omess;
- /* We get here in two ways:
- * a) phase != MSGO. Target is probably going to reject our message
- * b) aic->omp == &aic->omess[aic->omlen], i.e. the message has been
- * transmitted correctly and accepted by the target.
- */
- if (aic->phase == PH_MSGO) { /* Message accepted by target! */
- aic->msgpriq &= ~aic->msgout;
- aic->msgout = 0;
- }
- outb(SXFRCTL0, CHEN); /* Disable SPIO */
- outb(SIMODE0, 0); /* Setup interrupts before leaving */
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|ENSCSIPERR|ENREQINIT);
- /* Enabled ints: SCSIPERR, SCSIRSTI (unexpected)
- * REQINIT (expected) BUSFREE (possibly expected)
- */
-}
-
-/* aic_dataout: perform a data transfer using the FIFO datapath in the aic6360
- * Precondition: The SCSI bus should be in the DOUT phase, with REQ asserted
- * and ACK deasserted (i.e. waiting for a data byte)
- * This new revision has been optimized (I tried) to make the common case fast,
- * and the rarer cases (as a result) somewhat more comlex
- */
-static void
-aic_dataout(aic)
- register struct aic_data *aic;
-{
- register u_short iobase = aic->iobase;
- register u_char dmastat;
- int amount, olddleft = aic->dleft;
-#define DOUTAMOUNT 128 /* Full FIFO */
-
- /* Enable DATA OUT transfers */
- outb(SCSISIGO, PH_DOUT);
- outb(CLRSINT1, CLRPHASECHG);
- /* Clear FIFOs and counters */
- outb(SXFRCTL0, CHEN|CLRSTCNT|CLRCH);
- outb(DMACNTRL0, WRITE|INTEN|RSTFIFO);
- /* Enable FIFOs */
- outb(SXFRCTL0, SCSIEN|DMAEN|CHEN);
- outb(DMACNTRL0, ENDMA|DWORDPIO|WRITE|INTEN);
-
- /* Setup to detect:
- * PHASEMIS & PHASECHG: target has left the DOUT phase
- * SCSIRST: something just pulled the RST line.
- * BUSFREE: target has unexpectedly left the DOUT phase
- */
- outb(SIMODE1, ENPHASEMIS|ENSCSIRST|ENBUSFREE|ENPHASECHG);
-
- /* I have tried to make the main loop as tight as possible. This
- * means that some of the code following the loop is a bit more
- * complex than otherwise.
- */
- while (aic->dleft) {
- int xfer;
-
- LOGLINE(aic);
-
- for (;;) {
- dmastat = inb(DMASTAT);
- if (dmastat & DFIFOEMP)
- break;
- if (dmastat & INTSTAT)
- goto phasechange;
- }
-
- xfer = min(DOUTAMOUNT, aic->dleft);
-
-#if AIC_USE_DWORDS
- if (xfer >= 12) {
- outsl(DMADATALONG, aic->dp, xfer/4);
- aic->dleft -= xfer & ~3;
- aic->dp += xfer & ~3;
- xfer &= 3;
- }
-#else
- if (xfer >= 8) {
- outsw(DMADATA, aic->dp, xfer/2);
- aic->dleft -= xfer & ~1;
- aic->dp += xfer & ~1;
- xfer &= 1;
- }
-#endif
-
- if (xfer) {
- outb(DMACNTRL0, ENDMA|B8MODE|INTEN);
- outsb(DMADATA, aic->dp, xfer);
- aic->dleft -= xfer;
- aic->dp += xfer;
- outb(DMACNTRL0, ENDMA|DWORDPIO|INTEN);
- }
- }
-
- /* See the bytes off chip */
- for (;;) {
- dmastat = inb(DMASTAT);
- if ((dmastat & DFIFOEMP) && (inb(SSTAT2) & SEMPTY))
- break;
- if (dmastat & INTSTAT)
- goto phasechange;
- }
-
-phasechange:
- /* We now have the data off chip. */
- outb(SXFRCTL0, CHEN);
-
- if (dmastat & INTSTAT) { /* Some sort of phasechange */
- register u_char sstat2;
- /* Stop transfers, do some accounting */
- amount = inb(FIFOSTAT);
- sstat2 = inb(SSTAT2);
- if ((sstat2 & 7) == 0)
- amount += sstat2 & SFULL ? 8 : 0;
- else
- amount += sstat2 & 7;
- aic->dleft += amount;
- aic->dp -= amount;
- AIC_MISC(("+%d ", amount));
- }
-
- outb(DMACNTRL0, RSTFIFO|INTEN);
- LOGLINE(aic);
- while (inb(SXFRCTL0) & SCSIEN)
- ;
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|ENSCSIPERR|ENREQINIT);
- /* Enabled ints: BUSFREE, SCSIPERR, SCSIRSTI (unexpected)
- * REQINIT (expected)
- */
- aic->progress = olddleft != aic->dleft;
- return;
-}
-
-/* aic_datain: perform data transfers using the FIFO datapath in the aic6360
- * Precondition: The SCSI bus should be in the DIN phase, with REQ asserted
- * and ACK deasserted (i.e. at least one byte is ready).
- * For now, uses a pretty dumb algorithm, hangs around until all data has been
- * transferred. This, is OK for fast targets, but not so smart for slow
- * targets which don't disconnect or for huge transfers.
- */
-static void
-aic_datain(aic)
- register struct aic_data *aic;
-{
- register u_short iobase = aic->iobase;
- register u_char dmastat;
- int olddleft = aic->dleft;
-#define DINAMOUNT 128 /* Default amount of data to transfer */
-
- /* Enable DATA IN transfers */
- outb(SCSISIGO, PH_DIN);
- outb(CLRSINT1, CLRPHASECHG);
- /* Clear FIFOs and counters */
- outb(SXFRCTL0, CHEN|CLRSTCNT|CLRCH);
- outb(DMACNTRL0, INTEN|RSTFIFO);
- /* Enable FIFOs */
- outb(SXFRCTL0, SCSIEN|DMAEN|CHEN);
- outb(DMACNTRL0, ENDMA|DWORDPIO|INTEN);
-
- outb(SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE|ENPHASECHG);
-
- /* We leave this loop if one or more of the following is true:
- * a) phase != PH_DIN && FIFOs are empty
- * b) SCSIRSTI is set (a reset has occurred) or busfree is detected.
- */
- while (aic->dleft) {
- int done = 0;
- int xfer;
-
- LOGLINE(aic);
-
- /* Wait for fifo half full or phase mismatch */
- for (;;) {
- dmastat = inb(DMASTAT);
- if (dmastat & (DFIFOFULL|INTSTAT))
- break;
- }
-
- if (dmastat & DFIFOFULL)
- xfer = DINAMOUNT;
- else {
- while ((inb(SSTAT2) & SEMPTY) == 0)
- ;
- xfer = inb(FIFOSTAT);
- done = 1;
- }
-
- xfer = min(xfer, aic->dleft);
-
-#if AIC_USE_DWORDS
- if (xfer >= 12) {
- insl(DMADATALONG, aic->dp, xfer/4);
- aic->dleft -= xfer & ~3;
- aic->dp += xfer & ~3;
- xfer &= 3;
- }
-#else
- if (xfer >= 8) {
- insw(DMADATA, aic->dp, xfer/2);
- aic->dleft -= xfer & ~1;
- aic->dp += xfer & ~1;
- xfer &= 1;
- }
-#endif
-
- if (xfer) {
- outb(DMACNTRL0, ENDMA|B8MODE|INTEN);
- insb(DMADATA, aic->dp, xfer);
- aic->dleft -= xfer;
- aic->dp += xfer;
- outb(DMACNTRL0, ENDMA|DWORDPIO|INTEN);
- }
-
- if (done)
- break;
- }
-
-#if 0
- if (aic->dleft)
- printf("residual of %d\n", aic->dleft);
-#endif
-
- aic->progress = olddleft != aic->dleft;
- /* Some SCSI-devices are rude enough to transfer more data than what
- * was requested, e.g. 2048 bytes from a CD-ROM instead of the
- * requested 512. Test for progress, i.e. real transfers. If no real
- * transfers have been performed (acb->dleft is probably already zero)
- * and the FIFO is not empty, waste some bytes....
- */
- if (!aic->progress) {
- int extra = 0;
- LOGLINE(aic);
-
- for (;;) {
- dmastat = inb(DMASTAT);
- if (dmastat & DFIFOEMP)
- break;
- (void) inb(DMADATA); /* Throw it away */
- extra++;
- }
-
- AIC_MISC(("aic: %d extra bytes from %d:%d\n", extra,
- acb->xs->sc_link->target, acb->xs->sc_link->lun));
- aic->progress = extra;
- }
-
- /* Stop the FIFO data path */
- outb(SXFRCTL0, CHEN);
-
- outb(DMACNTRL0, RSTFIFO|INTEN);
- /* Come back when REQ is set again */
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|ENSCSIPERR|ENREQINIT);
- LOGLINE(aic);
-}
-
-
-/*
- * This is the workhorse routine of the driver.
- * Deficiencies (for now):
- * 1) always uses programmed I/O
- * 2) doesn't support synchronous transfers properly (yet)
- */
-
-void
-aicintr(int unit)
-{
- struct aic_data *aic = aicdata[unit];
- register struct acb *acb;
- register struct scsi_link *sc;
- register u_short iobase = aic->iobase;
- struct aic_tinfo *ti;
- u_char sstat0, sstat1, sstat2, sxfrctl0;
-
-
- LOGLINE(aic);
- /* Clear INTEN. This is important if we're running with edge
- * triggered interrupts as we don't guarantee that all interrupts will
- * be served during one single invocation of this routine, i.e. we may
- * need another edge.
- */
- outb(DMACNTRL0, 0);
- AIC_TRACE(("aicintr\n"));
-
- /*
- * 1st check for abnormal conditions, such as reset or parity errors
- */
- sstat1 = inb(SSTAT1);
- AIC_MISC(("s1:0x%02x ", sstat1));
- if (sstat1 & (SCSIRSTI|SCSIPERR)) {
- if (sstat1 & SCSIRSTI) {
- printf("aic: reset in -- reinitializing....\n");
- aic_init(aic); /* Restart everything */
- LOGLINE(aic);
- outb(DMACNTRL0, INTEN);
- return;
- } else {
- printf("aic: SCSI bus parity error\n");
- outb(CLRSINT1, CLRSCSIPERR);
- if (aic->prevphase == PH_MSGI)
- aic_sched_msgout(SEND_PARITY_ERROR);
- else
- aic_sched_msgout(SEND_INIT_DET_ERR);
- }
- }
-
- /*
- * If we're not already busy doing something test for the following
- * conditions:
- * 1) We have been reselected by something
- * 2) We have selected something successfully
- * 3) Our selection process has timed out
- * 4) This is really a bus free interrupt just to get a new command
- * going?
- * 5) Spurious interrupt?
- */
- sstat0 = inb(SSTAT0);
- AIC_MISC(("s0:0x%02x ", sstat0));
- if (aic->state != AIC_HASNEXUS) { /* No nexus yet */
- if (sstat0 & SELDI) {
- LOGLINE(aic);
- /* We have been reselected. Things to do:
- * a) If we're trying to select something ourselves
- * back off the current command.
- * b) "Wait" for a message in phase (IDENTIFY)
- * c) Call aic_msgin() to get the identify message and
- * retrieve the disconnected command from the wait
- * queue.
- */
- AIC_MISC(("reselect "));
- /* If we're trying to select a target ourselves,
- * push our command back into the rdy list.
- */
- if (aic->state == AIC_SELECTING) {
- AIC_MISC(("backoff selector "));
- TAILQ_INSERT_HEAD(&aic->ready_list, aic->nexus,
- chain);
- aic->nexus = NULL;
- }
- aic->state = AIC_RESELECTED;
- /* Clear interrupts, disable future selection stuff
- * including select interrupts and timeouts
- */
- outb(CLRSINT0, CLRSELDI);
- outb(SCSISEQ, 0);
- outb(SIMODE0, 0);
- /* Setup chip so we may detect spurious busfree
- * conditions later.
- */
- outb(CLRSINT1, CLRBUSFREE);
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|
- ENSCSIPERR|ENREQINIT);
- /* Now, we're expecting an IDENTIFY message. */
- aic->phase = aicphase(aic);
- if (aic->phase & PH_PSBIT) {
- LOGLINE(aic);
- outb(DMACNTRL0, INTEN);
- return; /* Come back when REQ is set */
- }
- if (aic->phase == PH_MSGI)
- aic_msgin(aic); /* Handle identify message */
- else {
- /* Things are seriously fucked up.
- * Pull the brakes, i.e. RST
- */
- printf("aic at line %d: target didn't identify\n", __LINE__);
- Debugger("aic6360");
- fatal_if_no_DDB();
- aic_init(aic);
- return;
- }
- if (aic->state != AIC_HASNEXUS) {/* IDENTIFY fail?! */
- printf("aic at line %d: identify failed\n",
- __LINE__);
- aic_init(aic);
- return;
- } else {
- outb(SIMODE1,
- ENSCSIRST|ENBUSFREE|ENSCSIPERR|ENREQINIT);
- /* Fallthrough to HASNEXUS part of aicintr */
- }
- } else if (sstat0 & SELDO) {
- LOGLINE(aic);
- /* We have selected a target. Things to do:
- * a) Determine what message(s) to send.
- * b) Verify that we're still selecting the target.
- * c) Mark device as busy.
- */
- acb = aic->nexus;
- if (!acb) {
- printf("aic at line %d: missing acb", __LINE__);
- Debugger("aic6360");
- fatal_if_no_DDB();
- }
- sc = acb->xs->sc_link;
- ti = &aic->tinfo[sc->target];
- if (acb->xs->flags & SCSI_RESET)
- aic->msgpriq = SEND_DEV_RESET;
- else if (ti->flags & DO_NEGOTIATE)
- aic->msgpriq = SEND_IDENTIFY|SEND_SDTR;
- else
- aic->msgpriq = SEND_IDENTIFY;
- /* Setup chip to enable later testing for busfree
- * conditions
- */
- outb(CLRSINT1, CLRBUSFREE);
- outb(SCSISEQ, 0); /* Stop selection stuff */
- nandreg(SIMODE0, ENSELDO); /* No more selectout ints */
- sstat0 = inb(SSTAT0);
- if (sstat0 & SELDO) { /* Still selected!? */
- outb(SIMODE0, 0);
- outb(SIMODE1, ENSCSIRST|ENSCSIPERR|
- ENBUSFREE|ENREQINIT);
- aic->state = AIC_HASNEXUS;
- aic->flags = 0;
- aic->prevphase = PH_INVALID;
- aic->dp = acb->daddr;
- aic->dleft = acb->dleft;
- ti->lubusy |= (1<<sc->lun);
- AIC_MISC(("select ok "));
- } else {
- /* Has seen busfree since selection, i.e.
- * a "spurious" selection. Shouldn't happen.
- */
- printf("aic: unexpected busfree\n");
- acb->xs->error = XS_DRIVER_STUFFUP;
- untimeout(aic_timeout, (caddr_t)acb);
- aic_done(acb);
- }
- LOGLINE(aic);
- outb(DMACNTRL0, INTEN);
- return;
- } else if (sstat1 & SELTO) {
- /* Selection timed out. What to do:
- * Disable selections out and fail the command with
- * code XS_TIMEOUT.
- */
- acb = aic->nexus;
- if (!acb) {
- printf("aic at line %d: missing acb", __LINE__);
- Debugger("aic6360");
- fatal_if_no_DDB();
- }
- outb(SCSISEQ, ENRESELI|ENAUTOATNP);
- outb(SXFRCTL1, 0);
- outb(CLRSINT1, CLRSELTIMO);
- aic->state = AIC_IDLE;
- acb->xs->error = XS_TIMEOUT;
- untimeout(aic_timeout, (caddr_t)acb);
- aic_done(acb);
- LOGLINE(aic);
- outb(DMACNTRL0, INTEN);
- return;
- } else {
- /* Assume a bus free interrupt. What to do:
- * Start selecting.
- */
- if (aic->state == AIC_IDLE)
- aic_sched(aic);
-#if AIC_DEBUG
- else
- AIC_MISC(("Extra aic6360 interrupt."));
-#endif
- LOGLINE(aic);
- outb(DMACNTRL0, INTEN);
- return;
- }
- }
- /* Driver is now in state AIC_HASNEXUS, i.e. we have a current command
- * working the SCSI bus.
- */
- acb = aic->nexus;
- if (aic->state != AIC_HASNEXUS || acb == NULL) {
- printf("aic: no nexus!!\n");
- Debugger("aic6360");
- fatal_if_no_DDB();
- }
-
- /* What sort of transfer does the bus signal? */
- aic->phase = aicphase(aic);
- if (!(aic->phase & PH_PSBIT)) /* not a pseudo phase */
- outb(SCSISIGO, aic->phase);
- outb(CLRSINT1, CLRPHASECHG);
- /* These interrupts are enabled by default:
- * SCSIRSTI, SCSIPERR, BUSFREE, REQINIT
- */
- switch (aic->phase) {
- case PH_MSGO:
- LOGLINE(aic);
- if (aic_debug & AIC_SHOWMISC)
- printf("PH_MSGO ");
- aic_msgout(aic);
- aic->prevphase = PH_MSGO;
- /* Setup interrupts before leaving */
- outb(SIMODE0, 0);
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|ENSCSIPERR|ENREQINIT);
- /* Enabled ints: SCSIPERR, SCSIRSTI (unexpected)
- * REQINIT (expected) BUSFREE (possibly expected)
- */
- break;
- case PH_CMD: /* CMD phase & REQ asserted */
- LOGLINE(aic);
- if (aic_debug & AIC_SHOWMISC)
- printf("PH_CMD 0x%02x (%d) ",
- acb->cmd.opcode, acb->clen);
- outb(SCSISIGO, PH_CMD);
- /* Use FIFO for CMDs. Assumes that no cmd > 128 bytes. OK? */
- /* Clear hostFIFO and enable EISA-hostFIFO transfers */
- outb(DMACNTRL0, WRITE|RSTFIFO|INTEN); /* 3(4) */
- /* Clear scsiFIFO and enable SCSI-interface
- & hostFIFO-scsiFIFO transfers */
- outb(SXFRCTL0, CHEN|CLRCH|CLRSTCNT); /* 4 */
- outb(SXFRCTL0, SCSIEN|DMAEN|CHEN); /* 5 */
- outb(DMACNTRL0, ENDMA|WRITE|INTEN); /* 3+6 */
- /* What (polled) interrupts to enable */
- outb(SIMODE1, ENPHASEMIS|ENSCSIRST|ENBUSFREE|ENSCSIPERR);
- /* DFIFOEMP is set, FIFO (128 byte) is always big enough */
- outsw(DMADATA, (short *)&acb->cmd, acb->clen>>1);
-
- /* Wait for SCSI FIFO to drain */
- LOGLINE(aic);
- do {
- sstat2 = inb(SSTAT2);
- } while (!(sstat2 & SEMPTY) && !(inb(DMASTAT) & INTSTAT));
- if (!(inb(SSTAT2) & SEMPTY)) {
- printf("aic at line %d: SCSI-FIFO didn't drain\n",
- __LINE__);
- Debugger("aic6360");
- fatal_if_no_DDB();
- acb->xs->error = XS_DRIVER_STUFFUP;
- untimeout(aic_timeout, (caddr_t)acb);
- aic_done(acb);
- aic_init(aic);
- return;
- }
- outb(SXFRCTL0, CHEN); /* Clear SCSIEN & DMAEN */
- outb(SIMODE0, 0);
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|ENSCSIPERR);
- LOGLINE(aic);
- do {
- sxfrctl0 = inb(SXFRCTL0);
- } while (sxfrctl0 & SCSIEN && !(inb(DMASTAT) & INTSTAT));
- if (sxfrctl0 & SCSIEN) {
- printf("aic at line %d: scsi xfer never finished\n",
- __LINE__);
- Debugger("aic6360");
- fatal_if_no_DDB();
- acb->xs->error = XS_DRIVER_STUFFUP;
- untimeout(aic_timeout, (caddr_t)acb);
- aic_done(acb);
- aic_init(aic);
- return;
- }
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|ENSCSIPERR|ENREQINIT);
- /* Enabled ints: BUSFREE, SCSIPERR, SCSIRSTI (unexpected)
- * REQINIT (expected)
- */
- aic->prevphase = PH_CMD;
- break;
- case PH_DOUT:
- LOGLINE(aic);
- AIC_MISC(("PH_DOUT [%d] ",aic->dleft));
- aic_dataout(aic);
- aic->prevphase = PH_DOUT;
- break;
- case PH_MSGI:
- LOGLINE(aic);
- if (aic_debug & AIC_SHOWMISC)
- printf("PH_MSGI ");
- aic_msgin(aic);
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|ENSCSIPERR|ENREQINIT);
- aic->prevphase = PH_MSGI;
- break;
- case PH_DIN:
- LOGLINE(aic);
- if (aic_debug & AIC_SHOWMISC)
- printf("PH_DIN ");
- aic_datain(aic);
- aic->prevphase = PH_DIN;
- break;
- case PH_STAT:
- LOGLINE(aic);
- if (aic_debug & AIC_SHOWMISC)
- printf("PH_STAT ");
- outb(SCSISIGO, PH_STAT);
- outb(SXFRCTL0, CHEN|SPIOEN);
- outb(DMACNTRL0, RSTFIFO|INTEN);
- outb(SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE|ENSCSIPERR);
- acb->stat = inb(SCSIDAT);
- outb(SXFRCTL0, CHEN);
- if (aic_debug & AIC_SHOWMISC)
- printf("0x%02x ", acb->stat);
- outb(SIMODE1, ENSCSIRST|ENBUSFREE|ENSCSIPERR|ENREQINIT);
- aic->prevphase = PH_STAT;
- break;
- case PH_INVALID:
- LOGLINE(aic);
- break;
- case PH_BUSFREE:
- LOGLINE(aic);
- if (aic->flags & AIC_BUSFREE_OK) { /*It's fun the 1st time.. */
- aic->flags &= ~AIC_BUSFREE_OK;
- } else {
- printf("aic at line %d: unexpected busfree phase\n",
- __LINE__);
- Debugger("aic6360");
- fatal_if_no_DDB();
- }
- break;
- default:
- printf("aic at line %d: bogus bus phase\n", __LINE__);
- Debugger("aic6360");
- fatal_if_no_DDB();
- break;
- }
- LOGLINE(aic);
- outb(DMACNTRL0, INTEN);
- return;
-}
-
-static void
-aic_timeout(void *arg1) {
- int s = splbio();
- struct acb *acb = (struct acb *)arg1;
- int unit;
- struct aic_data *aic;
-
- unit = acb->xs->sc_link->adapter_unit;
- aic = aicdata[unit];
- sc_print_addr(acb->xs->sc_link);
- acb->xs->error = XS_TIMEOUT;
- printf("timed out\n");
-
- aic_done(acb);
- splx(s);
-}
-
-#if AIC_DEBUG
-/*
- * The following functions are mostly used for debugging purposes, either
- * directly called from the driver or from the kernel debugger.
- */
-
-void
-aic_show_scsi_cmd(acb)
- struct acb *acb;
-{
- u_char *b = (u_char *)&acb->cmd;
- struct scsi_link *sc = acb->xs->sc_link;
- int i;
-
- sc_print_addr(sc);
- if (!(acb->xs->flags & SCSI_RESET)) {
- for (i = 0; i < acb->clen; i++) {
- if (i)
- printf(",");
- printf("%x", b[i]);
- }
- printf("\n");
- } else
- printf("RESET\n");
-}
-
-void
-aic_print_acb(acb)
- struct acb *acb;
-{
-
- printf("acb@%x xs=%x flags=%x", acb, acb->xs, acb->flags);
- printf(" daddr=%x dleft=%d stat=%x\n",
- (long)acb->daddr, acb->dleft, acb->stat);
- aic_show_scsi_cmd(acb);
-}
-
-void
-aic_print_active_acb()
-{
- struct acb *acb;
- struct aic_data *aic = aicdata[0];
-
- printf("ready list:\n");
- for (acb = aic->ready_list.tqh_first; acb; acb = acb->chain.tqe_next)
- aic_print_acb(acb);
- printf("nexus:\n");
- if (aic->nexus)
- aic_print_acb(aic->nexus);
- printf("nexus list:\n");
- for (acb = aic->nexus_list.tqh_first; acb; acb = acb->chain.tqe_next)
- aic_print_acb(acb);
-}
-
-void
-aic_dump6360()
-{
- u_short iobase = 0x340;
-
- printf("aic6360: SCSISEQ=%x SXFRCTL0=%x SXFRCTL1=%x SCSISIGI=%x\n",
- inb(SCSISEQ), inb(SXFRCTL0), inb(SXFRCTL1), inb(SCSISIGI));
- printf(" SSTAT0=%x SSTAT1=%x SSTAT2=%x SSTAT3=%x SSTAT4=%x\n",
- inb(SSTAT0), inb(SSTAT1), inb(SSTAT2), inb(SSTAT3), inb(SSTAT4));
- printf(" SIMODE0=%x SIMODE1=%x DMACNTRL0=%x DMACNTRL1=%x DMASTAT=%x\n",
- inb(SIMODE0), inb(SIMODE1), inb(DMACNTRL0), inb(DMACNTRL1),
- inb(DMASTAT));
- printf(" FIFOSTAT=%d SCSIBUS=0x%x\n",
- inb(FIFOSTAT), inb(SCSIBUS));
-}
-
-void
-aic_dump_driver()
-{
- struct aic_data *aic = aicdata[0];
- struct aic_tinfo *ti;
- int i;
-
- printf("nexus=%x phase=%x prevphase=%x\n", aic->nexus, aic->phase,
- aic->prevphase);
- printf("state=%x msgin=%x msgpriq=%x msgout=%x imlen=%d omlen=%d\n",
- aic->state, aic->imess[0], aic->msgpriq, aic->msgout, aic->imlen,
- aic->omlen);
- printf("history:");
- i = aic->hp;
- do {
- printf(" %d", aic->history[i]);
- i = (i + 1) % AIC_HSIZE;
- } while (i != aic->hp);
- printf("*\n");
- for (i = 0; i < 7; i++) {
- ti = &aic->tinfo[i];
- printf("tinfo%d: %d cmds %d disconnects %d timeouts",
- i, ti->cmds, ti->dconns, ti->touts);
- printf(" %d senses flags=%x\n", ti->senses, ti->flags);
- }
-}
-#endif
diff --git a/sys/pc98/pc98/atapi.c b/sys/pc98/pc98/atapi.c
deleted file mode 100644
index dc5e1c7..0000000
--- a/sys/pc98/pc98/atapi.c
+++ /dev/null
@@ -1,1074 +0,0 @@
-/*
- * Device-independent level for ATAPI drivers.
- *
- * Copyright (C) 1995 Cronyx Ltd.
- * Author Serge Vakulenko, <vak@cronyx.ru>
- *
- * This software is distributed with NO WARRANTIES, not even the implied
- * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Authors grant any other persons or organisations permission to use
- * or modify this software as long as this message is kept with the software,
- * all derivative works or modified versions.
- *
- * Version 1.9, Mon Oct 9 22:34:47 MSK 1995
- */
-
-/*
- * The ATAPI level is implemented as a machine-dependent layer
- * between the device driver and the IDE controller.
- * All the machine- and controller dependency is isolated inside
- * the ATAPI level, while all the device dependency is located
- * in the device subdriver.
- *
- * It seems that an ATAPI bus will became popular for medium-speed
- * storage devices such as CD-ROMs, magneto-optical disks, tape streamers etc.
- *
- * To ease the development of new ATAPI drivers, the subdriver
- * interface was designed to be as simple as possible.
- *
- * Three routines are available for the subdriver to access the device:
- *
- * struct atapires atapi_request_wait (ata, unit, cmd, a1, a2, a3, a4, a5,
- * a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, addr, count);
- * struct atapi *ata; -- atapi controller descriptor
- * int unit; -- device unit number on the IDE bus
- * u_char cmd; -- ATAPI command code
- * u_char a1..a15; -- ATAPI command arguments
- * char *addr; -- address of the data buffer for i/o
- * int count; -- data length, >0 for read ops, <0 for write ops
- *
- * The atapi_request_wait() function puts the op in the queue of ATAPI
- * commands for the IDE controller, starts the controller, the waits for
- * operation to be completed (using tsleep).
- * The function should be called from the user phase only (open(), close(),
- * ioctl() etc).
- * Ata and unit args are the values which the subdriver gets from the ATAPI
- * level via attach() call.
- * Buffer pointed to by *addr should be placed in core memory, static
- * or dynamic, but not in stack.
- * The function returns the error code structure, which consists of:
- * - atapi driver code value
- * - controller status port value
- * - controller error port value
- *
- * struct atapires atapi_request_immediate (ata, unit, cmd, a1, a2, a3,
- * a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
- * addr, count);
- *
- * The atapi_request_immediate() function is similar to atapi_request_wait(),
- * but it does not use interrupts for performing the request.
- * It should be used during an attach phase to get parameters from the device.
- *
- * void atapi_request_callback (ata, unit, cmd, a1, a2, a3, a4, a5,
- * a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
- * addr, count, done, x, y);
- * struct atapi *ata; -- atapi controller descriptor
- * int unit; -- device unit number on the IDE bus
- * u_char cmd; -- ATAPI command code
- * u_char a1..a15; -- ATAPI command arguments
- * char *addr; -- address of the data buffer for i/o
- * int count; -- data length, >0 for read ops, <0 for write ops
- * void (*done)(); -- function to call when op finished
- * void *x, *y; -- arguments for done() function
- *
- * The atapi_request_callback() function puts the op in the queue of ATAPI
- * commands for the IDE controller, starts the controller, then returns.
- * When the operation finishes, then the callback function done()
- * will be called on the interrupt level.
- * The function is designed to be callable from the interrupt phase.
- * The done() functions is called with the following arguments:
- * (void) (*done) (x, y, count, errcode)
- * void *x, *y; -- arguments from the atapi_request_callback()
- * int count; -- the data residual count
- * struct atapires errcode; -- error code structure, see above
- *
- * The new driver could be added in three steps:
- * 1. Add entries for the new driver to bdevsw and cdevsw tables in conf.c.
- * You will need to make at least three routines: open(), close(),
- * strategy() and possibly ioctl().
- * 2. Make attach() routine, which should allocate all the needed data
- * structures and print the device description string (see wcdattach()).
- * 3. Add an appropriate case to the switch in atapi_attach() routine,
- * call attach() routine of the new driver here. Add the appropriate
- * #include line at the top of attach.c.
- * That's all!
- *
- * Use #define DEBUG in atapi.c to enable tracing of all i/o operations
- * on the IDE bus.
- */
-#undef DEBUG
-
-#include "wdc.h"
-#include "opt_atapi.h"
-
-#ifndef ATAPI_MODULE
-# include "wcd.h"
-/* # include "wmt.h" -- add your driver here */
-/* # include "wmd.h" -- add your driver here */
-#endif
-
-#if NWDC > 0 && defined (ATAPI)
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/malloc.h>
-
-#include <machine/clock.h>
-#include <machine/cpufunc.h>
-
-#ifdef ATAPI_MODULE
-# define ATAPI_STATIC
-#endif
-
-#ifdef PC98
-#include <pc98/pc98/atapi.h>
-#else
-#include <i386/isa/atapi.h>
-#endif
-
-#ifndef ATAPI_STATIC
-/* this code is compiled as part of the kernel if options ATAPI */
-/*
- * In the case of loadable ATAPI driver we need to store
- * the probe info for delayed attaching.
- */
-struct atapidrv atapi_drvtab[4];
-int atapi_ndrv;
-struct atapi *atapi_tab;
-
-int atapi_attach (int ctlr, int unit, int port)
-{
- atapi_drvtab[atapi_ndrv].ctlr = ctlr;
- atapi_drvtab[atapi_ndrv].unit = unit;
- atapi_drvtab[atapi_ndrv].port = port;
- atapi_drvtab[atapi_ndrv].attached = 0;
- ++atapi_ndrv;
- return (1);
-}
-#else /* ATAPI_STATIC */
-/* this code is compiled part of the module */
-
-#ifdef DEBUG
-# define print(s) printf s
-#else
-# define print(s) {/*void*/}
-#endif
-
-/*
- * ATAPI packet command phase.
- */
-#define PHASE_CMDOUT (ARS_DRQ | ARI_CMD)
-#define PHASE_DATAIN (ARS_DRQ | ARI_IN)
-#define PHASE_DATAOUT ARS_DRQ
-#define PHASE_COMPLETED (ARI_IN | ARI_CMD)
-#define PHASE_ABORTED 0 /* nonstandard - for NEC 260 */
-
-struct atapi atapitab[NWDC];
-
-static struct atapi_params *atapi_probe (int port, int unit);
-static int atapi_wait (int port, u_char bits_wanted);
-static void atapi_send_cmd (struct atapi *ata, struct atapicmd *ac);
-static int atapi_io (struct atapi *ata, struct atapicmd *ac);
-static int atapi_start_cmd (struct atapi *ata, struct atapicmd *ac);
-static int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac);
-
-extern int wdstart (int ctrlr);
-extern int wcdattach(struct atapi*, int, struct atapi_params*, int);
-
-/*
- * Probe the ATAPI device at IDE controller `ctlr', drive `unit'.
- * Called at splbio().
- */
-#ifdef ATAPI_MODULE
-static
-#endif
-int atapi_attach (int ctlr, int unit, int port)
-{
- struct atapi *ata = atapitab + ctlr;
- struct atapi_params *ap;
- char buf [sizeof(ap->model) + 1];
- char revbuf [sizeof(ap->revision) + 1];
- struct atapicmd *ac;
-
- print (("atapi%d.%d at 0x%x: attach called\n", ctlr, unit, port));
- ap = atapi_probe (port, unit);
- if (! ap)
- return (0);
-
- bcopy (ap->model, buf, sizeof(buf)-1);
- buf[sizeof(buf)-1] = 0;
-
- bcopy (ap->revision, revbuf, sizeof(revbuf)-1);
- revbuf[sizeof(revbuf)-1] = 0;
-
- printf ("wdc%d: unit %d (atapi): <%s/%s>", ctlr, unit, buf, revbuf);
-
- /* device is removable */
- if (ap->removable)
- printf (", removable");
-
- /* packet command size */
- switch (ap->cmdsz) {
- case AT_PSIZE_12: break;
- case AT_PSIZE_16: printf (", cmd16"); ata->cmd16 = 1; break;
- default: printf (", cmd%d", ap->cmdsz);
- }
-
- /* DRQ type */
- switch (ap->drqtype) {
- case AT_DRQT_MPROC: ata->slow = 1; break;
- case AT_DRQT_INTR: printf (", intr"); ata->intrcmd = 1; break;
- case AT_DRQT_ACCEL: printf (", accel"); break;
- default: printf (", drq%d", ap->drqtype);
- }
-
- /* overlap operation supported */
- if (ap->ovlapflag)
- printf (", ovlap");
-
- /* interleaved DMA supported */
- if (ap->idmaflag)
- printf (", idma");
- /* DMA supported */
- else if (ap->dmaflag)
- printf (", dma");
-
- /* IORDY can be disabled */
- if (ap->iordydis)
- printf (", iordis");
- /* IORDY supported */
- else if (ap->iordyflag)
- printf (", iordy");
-
- printf ("\n");
-
- ata->port = port;
- ata->ctrlr = ctlr;
- ata->attached[unit] = 0;
-#ifdef DEBUG
- ata->debug = 1;
-#else
- ata->debug = 0;
-#endif
- /* Initialize free queue. */
- ata->cmdrq[15].next = 0;
- for (ac = ata->cmdrq+14; ac >= ata->cmdrq; --ac)
- ac->next = ac+1;
- ata->free = ata->cmdrq;
-
- if (ap->proto != AT_PROTO_ATAPI) {
- printf ("wdc%d: unit %d: unknown ATAPI protocol=%d\n",
- ctlr, unit, ap->proto);
- free (ap, M_TEMP);
- return (0);
- }
-#ifdef ATAPI_MODULE
- ata->params[unit] = ap;
- return (1);
-#else
- switch (ap->devtype) {
- default:
- /* unknown ATAPI device */
- printf ("wdc%d: unit %d: unknown ATAPI type=%d\n",
- ctlr, unit, ap->devtype);
- break;
-
- case AT_TYPE_DIRECT: /* direct-access */
- case AT_TYPE_CDROM: /* CD-ROM device */
-#if NWCD > 0
- /* ATAPI CD-ROM */
- if (wcdattach (ata, unit, ap, ata->debug) < 0)
- break;
- /* Device attached successfully. */
- ata->attached[unit] = 1;
- return (1);
-#else
- printf ("wdc%d: ATAPI CD-ROMs not configured\n", ctlr);
- break;
-#endif
-
- case AT_TYPE_TAPE: /* streaming tape (QIC-121 model) */
-#if NWMT > 0
- /* Add your driver here */
-#else
- printf ("wdc%d: ATAPI streaming tapes not supported yet\n", ctlr);
-#endif
- break;
-
- case AT_TYPE_OPTICAL: /* optical disk */
-#if NWMD > 0
- /* Add your driver here */
-#else
- printf ("wdc%d: ATAPI optical disks not supported yet\n", ctlr);
-#endif
- break;
- }
- /* Attach failed. */
- free (ap, M_TEMP);
- return (0);
-#endif /* ATAPI_MODULE */
-}
-
-static char *cmdname (u_char cmd)
-{
- static char buf[8];
-
- switch (cmd) {
- case 0x00: return ("TEST_UNIT_READY");
- case 0x03: return ("REQUEST_SENSE");
- case 0x1b: return ("START_STOP");
- case 0x1e: return ("PREVENT_ALLOW");
- case 0x25: return ("READ_CAPACITY");
- case 0x28: return ("READ_BIG");
- case 0x43: return ("READ_TOC");
- case 0x42: return ("READ_SUBCHANNEL");
- case 0x55: return ("MODE_SELECT_BIG");
- case 0x5a: return ("MODE_SENSE");
- case 0xb4: return ("PLAY_CD");
- case 0x47: return ("PLAY_MSF");
- case 0x4b: return ("PAUSE");
- case 0x48: return ("PLAY_TRACK");
- case 0xa5: return ("PLAY_BIG");
- }
- sprintf (buf, "[0x%x]", cmd);
- return (buf);
-}
-
-static void bswap (char *buf, int len)
-{
- u_short *p = (u_short*) (buf + len);
- while (--p >= (u_short*) buf)
- *p = ntohs (*p);
-}
-
-static void btrim (char *buf, int len)
-{
- char *p;
-
- /* Remove the trailing spaces. */
- for (p=buf; p<buf+len; ++p)
- if (! *p)
- *p = ' ';
- for (p=buf+len-1; p>=buf && *p==' '; --p)
- *p = 0;
-}
-
-/*
- * Issue IDENTIFY command to ATAPI drive to ask it what it is.
- */
-static struct atapi_params *atapi_probe (int port, int unit)
-{
- struct atapi_params *ap;
- char tb [DEV_BSIZE];
- int cnt;
-
-#ifdef PC98
- outb(0x432,unit%2);
- print(("unit = %d,select %d\n",unit,unit%2));
-#endif
- /* Wait for controller not busy. */
- outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
- if (atapi_wait (port, 0) < 0) {
- print (("atapiX.%d at 0x%x: controller busy, status=%b\n",
- unit, port, inb (port + AR_STATUS), ARS_BITS));
- return (0);
- }
-
- /* Issue ATAPI IDENTIFY command. */
-#ifdef PC98
- outb (port + AR_DRIVE, unit/2 ? ARD_DRIVE1 : ARD_DRIVE0);
-
- /* Wait for DRQ deassert. */
- for (cnt=2000; cnt>0; --cnt)
- if (! (inb (0x640 + AR_STATUS) & ARS_DRQ))
- break;
-
- outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
- DELAY(500);
-#else
- outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0);
- outb (port + AR_COMMAND, ATAPIC_IDENTIFY);
-#endif
-
- /* Check that device is present. */
- if (inb (port + AR_STATUS) == 0xff) {
- print (("atapiX.%d at 0x%x: no device\n", unit, port));
- if (unit == 1)
- /* Select unit 0. */
- outb (port + AR_DRIVE, ARD_DRIVE0);
- return (0);
- }
-
- /* Wait for data ready. */
- if (atapi_wait (port, ARS_DRQ) != 0) {
- print (("atapiX.%d at 0x%x: identify not ready, status=%b\n",
- unit, port, inb (port + AR_STATUS), ARS_BITS));
- if (unit == 1)
- /* Select unit 0. */
- outb (port + AR_DRIVE, ARD_DRIVE0);
- return (0);
- }
-
- /* Obtain parameters. */
- insw (port + AR_DATA, tb, sizeof(tb) / sizeof(short));
-
- ap = malloc (sizeof *ap, M_TEMP, M_NOWAIT);
- if (! ap)
- return (0);
- bcopy (tb, ap, sizeof *ap);
-
- /*
- * Shuffle string byte order.
- * Mitsumi and NEC drives don't need this.
- */
- if (! ((ap->model[0] == 'N' && ap->model[1] == 'E') ||
- (ap->model[0] == 'F' && ap->model[1] == 'X')))
- bswap (ap->model, sizeof(ap->model));
- bswap (ap->serial, sizeof(ap->serial));
- bswap (ap->revision, sizeof(ap->revision));
-
- /* Clean up the model name, serial and revision numbers. */
- btrim (ap->model, sizeof(ap->model));
- btrim (ap->serial, sizeof(ap->serial));
- btrim (ap->revision, sizeof(ap->revision));
- return (ap);
-}
-
-/*
- * Wait uninterruptibly until controller is not busy and certain
- * status bits are set.
- * The wait is usually short unless it is for the controller to process
- * an entire critical command.
- * Return 1 for (possibly stale) controller errors, -1 for timeout errors,
- * or 0 for no errors.
- */
-static int atapi_wait (int port, u_char bits_wanted)
-{
- int cnt;
- u_char s;
-
- /* Wait 5 sec for BUSY deassert. */
- for (cnt=500000; cnt>0; --cnt) {
- s = inb (port + AR_STATUS);
- if (! (s & ARS_BSY))
- break;
- DELAY (10);
- }
- if (cnt <= 0)
- return (-1);
- if (! bits_wanted)
- return (s & ARS_CHECK);
-
- /* Wait 50 msec for bits wanted. */
- for (cnt=5000; cnt>0; --cnt) {
- s = inb (port + AR_STATUS);
- if ((s & bits_wanted) == bits_wanted)
- return (s & ARS_CHECK);
- DELAY (10);
- }
- return (-1);
-}
-
-void atapi_debug (struct atapi *ata, int on)
-{
- ata->debug = on;
-}
-
-static struct atapicmd *atapi_alloc (struct atapi *ata)
-{
- struct atapicmd *ac;
-
- while (! ata->free)
- tsleep ((caddr_t)ata, PRIBIO, "atacmd", 0);
- ac = ata->free;
- ata->free = ac->next;
- ac->busy = 1;
- return (ac);
-}
-
-static void atapi_free (struct atapi *ata, struct atapicmd *ac)
-{
- if (! ata->free)
- wakeup ((caddr_t)&ata);
- ac->busy = 0;
- ac->next = ata->free;
- ata->free = ac;
-}
-
-/*
- * Add new command request to the end of the queue.
- */
-static void atapi_enqueue (struct atapi *ata, struct atapicmd *ac)
-{
- ac->next = 0;
- if (ata->tail)
- ata->tail->next = ac;
- else
- ata->queue = ac;
- ata->tail = ac;
-}
-
-static void atapi_done (struct atapi *ata)
-{
- struct atapicmd *ac = ata->queue;
-
- if (! ac)
- return; /* cannot happen */
-
- ata->queue = ac->next;
- if (! ata->queue)
- ata->tail = 0;
-
- if (ac->callback) {
- (*ac->callback) (ac->cbarg1, ac->cbarg2, ac->count, ac->result);
- atapi_free (ata, ac);
- } else
- wakeup ((caddr_t)ac);
-}
-
-/*
- * Start new packet op. Called from wdstart().
- * Return 1 if op started, and we are waiting for interrupt.
- * Return 0 when idle.
- */
-int atapi_start (int ctrlr)
-{
- struct atapi *ata = atapitab + ctrlr;
- struct atapicmd *ac;
-again:
- ac = ata->queue;
- if (! ac)
- return (0);
-
- /* Start packet command. */
- if (atapi_start_cmd (ata, ac) < 0) {
- atapi_done (ata);
- goto again;
- }
-
- if (ata->intrcmd)
- /* Wait for interrupt before sending packet command */
- return (1);
-
- /* Wait for DRQ. */
- if (atapi_wait_cmd (ata, ac) < 0) {
- atapi_done (ata);
- goto again;
- }
-
- /* Send packet command. */
- atapi_send_cmd (ata, ac);
- return (1);
-}
-
-/*
- * Start new packet op. Returns -1 on errors.
- */
-int atapi_start_cmd (struct atapi *ata, struct atapicmd *ac)
-{
- ac->result.error = 0;
- ac->result.status = 0;
-
-#ifdef PC98
- outb(0x432,(ac->unit)%2);
- print(("(ac->unit) = %d,select %d (2) \n",(ac->unit),(ac->unit)%2));
- outb (ata->port + AR_DRIVE, (ac->unit)/2 ? ARD_DRIVE1 : ARD_DRIVE0);
-#else
- outb (ata->port + AR_DRIVE, ac->unit ? ARD_DRIVE1 : ARD_DRIVE0);
-#endif
- if (atapi_wait (ata->port, 0) < 0) {
- printf ("atapi%d.%d: controller not ready for cmd\n",
- ata->ctrlr, ac->unit);
- ac->result.code = RES_NOTRDY;
- return (-1);
- }
-
- /* Set up the controller registers. */
- outb (ata->port + AR_FEATURES, 0);
- outb (ata->port + AR_IREASON, 0);
- outb (ata->port + AR_TAG, 0);
- outb (ata->port + AR_CNTLO, ac->count & 0xff);
- outb (ata->port + AR_CNTHI, ac->count >> 8);
- outb (ata->port + AR_COMMAND, ATAPIC_PACKET);
-
- if (ata->debug)
- printf ("atapi%d.%d: start\n", ata->ctrlr, ac->unit);
- return (0);
-}
-
-/*
- * Wait for DRQ before sending packet cmd. Returns -1 on errors.
- */
-int atapi_wait_cmd (struct atapi *ata, struct atapicmd *ac)
-{
- /* Wait for DRQ from 50 usec to 3 msec for slow devices */
- int cnt = ata->intrcmd ? 10000 : ata->slow ? 3000 : 50;
- int ireason = 0, phase = 0;
-
- /* Wait for command phase. */
- for (; cnt>0; cnt-=10) {
- ireason = inb (ata->port + AR_IREASON);
- ac->result.status = inb (ata->port + AR_STATUS);
- phase = (ireason & (ARI_CMD | ARI_IN)) |
- (ac->result.status & ARS_DRQ);
- if (phase == PHASE_CMDOUT)
- break;
- DELAY (10);
- }
-
- if (phase != PHASE_CMDOUT) {
- ac->result.code = RES_NODRQ;
- ac->result.error = inb (ata->port + AR_ERROR);
- printf ("atapi%d.%d: invalid command phase, ireason=0x%x, status=%b, error=%b\n",
- ata->ctrlr, ac->unit, ireason,
- ac->result.status, ARS_BITS,
- ac->result.error, AER_BITS);
- return (-1);
- }
- return (0);
-}
-
-/*
- * Send packet cmd.
- */
-void atapi_send_cmd (struct atapi *ata, struct atapicmd *ac)
-{
- outsw (ata->port + AR_DATA, ac->cmd, ata->cmd16 ? 8 : 6);
- if (ata->debug)
- printf ("atapi%d.%d: send cmd %s %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x\n",
- ata->ctrlr, ac->unit, cmdname (ac->cmd[0]), ac->cmd[0],
- ac->cmd[1], ac->cmd[2], ac->cmd[3], ac->cmd[4],
- ac->cmd[5], ac->cmd[6], ac->cmd[7], ac->cmd[8],
- ac->cmd[9], ac->cmd[10], ac->cmd[11], ac->cmd[12],
- ac->cmd[13], ac->cmd[14], ac->cmd[15]);
-}
-
-/*
- * Interrupt routine for the controller. Called from wdintr().
- * Finish the started op, wakeup wait-type commands,
- * run callbacks for callback-type commands, then return.
- * Do not start new op here, it will be done by wdstart,
- * which is called just after us.
- * Return 1 if op continues, and we are waiting for new interrupt.
- * Return 0 when idle.
- */
-int atapi_intr (int ctrlr)
-{
- struct atapi *ata = atapitab + ctrlr;
- struct atapicmd *ac = ata->queue;
-
-#ifdef PC98
- outb(0x432,(ac->unit)%2);
- print(("atapi_intr:(ac->unit)= %d,select %d\n",ac->unit,(ac->unit)%2));
-#endif
-
- if (! ac) {
- printf ("atapi%d: stray interrupt\n", ata->ctrlr);
- return (0);
- }
- if (atapi_io (ata, ac) > 0)
- return (1);
- atapi_done (ata);
- return (0);
-}
-
-/*
- * Process the i/o phase, transferring the command/data to/from the device.
- * Return 1 if op continues, and we are waiting for new interrupt.
- * Return 0 when idle.
- */
-int atapi_io (struct atapi *ata, struct atapicmd *ac)
-{
- u_char ireason;
- u_short len, i;
-
- if (atapi_wait (ata->port, 0) < 0) {
- ac->result.status = inb (ata->port + AR_STATUS);
- ac->result.error = inb (ata->port + AR_ERROR);
- ac->result.code = RES_NOTRDY;
- printf ("atapi%d.%d: controller not ready, status=%b, error=%b\n",
- ata->ctrlr, ac->unit, ac->result.status, ARS_BITS,
- ac->result.error, AER_BITS);
- return (0);
- }
-
- ac->result.status = inb (ata->port + AR_STATUS);
- ac->result.error = inb (ata->port + AR_ERROR);
- len = inb (ata->port + AR_CNTLO);
- len |= inb (ata->port + AR_CNTHI) << 8;
- ireason = inb (ata->port + AR_IREASON);
-
- if (ata->debug) {
- printf ("atapi%d.%d: intr ireason=0x%x, len=%d, status=%b, error=%b\n",
- ata->ctrlr, ac->unit, ireason, len,
- ac->result.status, ARS_BITS,
- ac->result.error, AER_BITS);
- }
- switch ((ireason & (ARI_CMD | ARI_IN)) | (ac->result.status & ARS_DRQ)) {
- default:
- printf ("atapi%d.%d: unknown phase\n", ata->ctrlr, ac->unit);
- ac->result.code = RES_ERR;
- break;
-
- case PHASE_CMDOUT:
- /* Send packet command. */
- if (! (ac->result.status & ARS_DRQ)) {
- printf ("atapi%d.%d: no cmd drq\n",
- ata->ctrlr, ac->unit);
- ac->result.code = RES_NODRQ;
- break;
- }
- atapi_send_cmd (ata, ac);
- return (1);
-
- case PHASE_DATAOUT:
- /* Write data */
- if (ac->count > 0) {
- printf ("atapi%d.%d: invalid data direction\n",
- ata->ctrlr, ac->unit);
- ac->result.code = RES_INVDIR;
- break;
- }
- if (-ac->count < len) {
- print (("atapi%d.%d: send data underrun, %d bytes left\n",
- ata->ctrlr, ac->unit, -ac->count));
- ac->result.code = RES_UNDERRUN;
- outsw (ata->port + AR_DATA, ac->addr,
- -ac->count / sizeof(short));
- for (i= -ac->count; i<len; i+=sizeof(short))
- outw (ata->port + AR_DATA, 0);
- } else
- outsw (ata->port + AR_DATA, ac->addr,
- len / sizeof(short));
- ac->addr += len;
- ac->count += len;
- return (1);
-
- case PHASE_DATAIN:
- /* Read data */
- if (ac->count < 0) {
- printf ("atapi%d.%d: invalid data direction\n",
- ata->ctrlr, ac->unit);
- ac->result.code = RES_INVDIR;
- break;
- }
- if (ac->count < len) {
- print (("atapi%d.%d: recv data overrun, %d bytes left\n",
- ata->ctrlr, ac->unit, ac->count));
- ac->result.code = RES_OVERRUN;
- insw (ata->port + AR_DATA, ac->addr,
- ac->count / sizeof(short));
- for (i=ac->count; i<len; i+=sizeof(short))
- inw (ata->port + AR_DATA);
- } else
- insw (ata->port + AR_DATA, ac->addr,
- len / sizeof(short));
- ac->addr += len;
- ac->count -= len;
- return (1);
-
- case PHASE_ABORTED:
- case PHASE_COMPLETED:
- if (ac->result.status & (ARS_CHECK | ARS_DF))
- ac->result.code = RES_ERR;
- else if (ac->count < 0) {
- print (("atapi%d.%d: send data overrun, %d bytes left\n",
- ata->ctrlr, ac->unit, -ac->count));
- ac->result.code = RES_OVERRUN;
- } else if (ac->count > 0) {
- print (("atapi%d.%d: recv data underrun, %d bytes left\n",
- ata->ctrlr, ac->unit, ac->count));
- ac->result.code = RES_UNDERRUN;
- bzero (ac->addr, ac->count);
- } else
- ac->result.code = RES_OK;
- break;
- }
- return (0);
-}
-
-/*
- * Queue new packet request, then call wdstart().
- * Called on splbio().
- */
-void atapi_request_callback (struct atapi *ata, int unit,
- u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
- u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
- u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
- char *addr, int count, atapi_callback_t *done, void *x, void *y)
-{
- struct atapicmd *ac;
-
- ac = atapi_alloc (ata);
- ac->cmd[0] = cmd; ac->cmd[1] = a1;
- ac->cmd[2] = a2; ac->cmd[3] = a3;
- ac->cmd[4] = a4; ac->cmd[5] = a5;
- ac->cmd[6] = a6; ac->cmd[7] = a7;
- ac->cmd[8] = a8; ac->cmd[9] = a9;
- ac->cmd[10] = a10; ac->cmd[11] = a11;
- ac->cmd[12] = a12; ac->cmd[13] = a13;
- ac->cmd[14] = a14; ac->cmd[15] = a15;
- ac->unit = unit;
- ac->addr = addr;
- ac->count = count;
- ac->callback = done;
- ac->cbarg1 = x;
- ac->cbarg2 = y;
-
- if (ata->debug)
- printf ("atapi%d.%d: req cb %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x len=%d\n",
- ata->ctrlr, ac->unit, ac->cmd[0], ac->cmd[1],
- ac->cmd[2], ac->cmd[3], ac->cmd[4], ac->cmd[5],
- ac->cmd[6], ac->cmd[7], ac->cmd[8], ac->cmd[9],
- ac->cmd[10], ac->cmd[11], ac->cmd[12],
- ac->cmd[13], ac->cmd[14], ac->cmd[15], count);
- atapi_enqueue (ata, ac);
- wdstart (ata->ctrlr);
-}
-
-/*
- * Queue new packet request, then call wdstart().
- * Wait until the request is finished.
- * Called on spl0().
- * Return atapi error.
- * Buffer pointed to by *addr should be placed in core memory, not in stack!
- */
-struct atapires atapi_request_wait (struct atapi *ata, int unit,
- u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
- u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
- u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
- char *addr, int count)
-{
- struct atapicmd *ac;
- int x = splbio ();
- struct atapires result;
-
- ac = atapi_alloc (ata);
- ac->cmd[0] = cmd; ac->cmd[1] = a1;
- ac->cmd[2] = a2; ac->cmd[3] = a3;
- ac->cmd[4] = a4; ac->cmd[5] = a5;
- ac->cmd[6] = a6; ac->cmd[7] = a7;
- ac->cmd[8] = a8; ac->cmd[9] = a9;
- ac->cmd[10] = a10; ac->cmd[11] = a11;
- ac->cmd[12] = a12; ac->cmd[13] = a13;
- ac->cmd[14] = a14; ac->cmd[15] = a15;
- ac->unit = unit;
- ac->addr = addr;
- ac->count = count;
- ac->callback = 0;
- ac->cbarg1 = 0;
- ac->cbarg2 = 0;
-
- if (ata->debug)
- printf ("atapi%d.%d: req w %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x len=%d\n",
- ata->ctrlr, ac->unit, ac->cmd[0], ac->cmd[1],
- ac->cmd[2], ac->cmd[3], ac->cmd[4], ac->cmd[5],
- ac->cmd[6], ac->cmd[7], ac->cmd[8], ac->cmd[9],
- ac->cmd[10], ac->cmd[11], ac->cmd[12],
- ac->cmd[13], ac->cmd[14], ac->cmd[15], count);
- atapi_enqueue (ata, ac);
- wdstart (ata->ctrlr);
- tsleep ((caddr_t)ac, PRIBIO, "atareq", 0);
-
- result = ac->result;
- atapi_free (ata, ac);
- splx (x);
- return (result);
-}
-
-/*
- * Perform a packet command on the device.
- * Should be called on splbio().
- * Return atapi error.
- */
-struct atapires atapi_request_immediate (struct atapi *ata, int unit,
- u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
- u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
- u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
- char *addr, int count)
-{
- struct atapicmd cmdbuf, *ac = &cmdbuf;
- int cnt;
-
- ac->cmd[0] = cmd; ac->cmd[1] = a1;
- ac->cmd[2] = a2; ac->cmd[3] = a3;
- ac->cmd[4] = a4; ac->cmd[5] = a5;
- ac->cmd[6] = a6; ac->cmd[7] = a7;
- ac->cmd[8] = a8; ac->cmd[9] = a9;
- ac->cmd[10] = a10; ac->cmd[11] = a11;
- ac->cmd[12] = a12; ac->cmd[13] = a13;
- ac->cmd[14] = a14; ac->cmd[15] = a15;
- ac->unit = unit;
- ac->addr = addr;
- ac->count = count;
- ac->callback = 0;
- ac->cbarg1 = 0;
- ac->cbarg2 = 0;
-
- if (ata->debug)
- printf ("atapi%d.%d: req im %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x len=%d\n",
- ata->ctrlr, ac->unit, ac->cmd[0], ac->cmd[1],
- ac->cmd[2], ac->cmd[3], ac->cmd[4], ac->cmd[5],
- ac->cmd[6], ac->cmd[7], ac->cmd[8], ac->cmd[9],
- ac->cmd[10], ac->cmd[11], ac->cmd[12],
- ac->cmd[13], ac->cmd[14], ac->cmd[15], count);
-
- /* Start packet command, wait for DRQ. */
- if (atapi_start_cmd (ata, ac) >= 0 && atapi_wait_cmd (ata, ac) >= 0) {
- /* Send packet command. */
- atapi_send_cmd (ata, ac);
-
- /* Wait for data i/o phase. */
- for (cnt=20000; cnt>0; --cnt)
- if (((inb (ata->port + AR_IREASON) & (ARI_CMD | ARI_IN)) |
- (inb (ata->port + AR_STATUS) & ARS_DRQ)) != PHASE_CMDOUT)
- break;
-
- /* Do all needed i/o. */
- while (atapi_io (ata, ac))
- /* Wait for DRQ deassert. */
- for (cnt=2000; cnt>0; --cnt)
- if (! (inb (ata->port + AR_STATUS) & ARS_DRQ))
- break;
- }
- return (ac->result);
-}
-#endif /* ATAPI_STATIC */
-
-#if defined (ATAPI_MODULE) || !defined(ATAPI_STATIC)
-int (*atapi_start_ptr) (int ctrlr);
-int (*atapi_intr_ptr) (int ctrlr);
-void (*atapi_debug_ptr) (struct atapi *ata, int on);
-struct atapires (*atapi_request_wait_ptr) (struct atapi *ata, int unit,
- u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
- u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
- u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
- char *addr, int count);
-void (*atapi_request_callback_ptr) (struct atapi *ata, int unit,
- u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
- u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
- u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
- char *addr, int count, atapi_callback_t *done, void *x, void *y);
-struct atapires (*atapi_request_immediate_ptr) (struct atapi *ata, int unit,
- u_char cmd, u_char a1, u_char a2, u_char a3, u_char a4,
- u_char a5, u_char a6, u_char a7, u_char a8, u_char a9,
- u_char a10, u_char a11, u_char a12, u_char a13, u_char a14, u_char a15,
- char *addr, int count);
-#endif
-
-#ifdef ATAPI_MODULE
-/*
- * ATAPI loadable driver stubs.
- */
-#include <sys/exec.h>
-#include <sys/conf.h>
-#include <sys/sysent.h>
-#include <sys/lkm.h>
-
-extern int atapi_lock (int ctlr);
-/*
- * XXX "ioconf.h" is not included by <sys/conf.h> for lkms, so we need this
- * misplaced declaration.
- */
-extern void wdintr (int);
-
-/*
- * Construct lkm_misc structure (see lkm.h).
- */
-MOD_MISC(atapi);
-
-int atapi_locked;
-
-int atapi_lock (int ctlr)
-{
- atapi_locked = 1;
- wakeup (&atapi_locked);
- return (1);
-}
-
-/*
- * Function called when loading the driver.
- */
-static int atapi_load (struct lkm_table *lkmtp, int cmd)
-{
- struct atapidrv *d;
- int n, x;
-
- /*
- * Probe all free IDE units, searching for ATAPI drives.
- */
- n = 0;
- for (d=atapi_drvtab; d<atapi_drvtab+atapi_ndrv && d->port; ++d) {
- /* Lock the controller. */
- x = splbio ();
- atapi_locked = 0;
- atapi_start_ptr = atapi_lock;
- wdstart (d->ctlr);
- while (! atapi_locked)
- tsleep (&atapi_locked, PRIBIO, "atach", 0);
-
- /* Probe the drive. */
- if (atapi_attach (d->ctlr, d->unit, d->port)) {
- d->attached = 1;
- ++n;
- }
-
- /* Unlock the controller. */
- atapi_start_ptr = 0;
- wdintr (d->ctlr);
- splx (x);
- }
- if (! n)
- return ENXIO;
- atapi_start_ptr = atapi_start;
- atapi_intr_ptr = atapi_intr;
- atapi_debug_ptr = atapi_debug;
- atapi_request_wait_ptr = atapi_request_wait;
- atapi_request_callback_ptr = atapi_request_callback;
- atapi_request_immediate_ptr = atapi_request_immediate;
- atapi_tab = atapitab;
- return 0;
-}
-
-/*
- * Function called when unloading the driver.
- */
-static int atapi_unload (struct lkm_table *lkmtp, int cmd)
-{
- struct atapi *ata;
- int u;
-
- for (ata=atapi_tab; ata<atapi_tab+2; ++ata)
- if (ata->port)
- for (u=0; u<2; ++u)
- if (ata->attached[u])
- return EBUSY;
- for (ata=atapi_tab; ata<atapi_tab+2; ++ata)
- if (ata->port)
- for (u=0; u<2; ++u)
- if (ata->params[u]) {
- free (ata->params[u], M_TEMP);
- ata->params[u] = 0;
- }
- atapi_start_ptr = 0;
- atapi_intr_ptr = 0;
- atapi_debug_ptr = 0;
- atapi_request_wait_ptr = 0;
- atapi_request_callback_ptr = 0;
- atapi_request_immediate_ptr = 0;
- atapi_tab = 0;
- return 0;
-}
-
-/*
- * Dispatcher function for the module (load/unload/stat).
- */
-int atapi_mod (struct lkm_table *lkmtp, int cmd, int ver)
-{
- DISPATCH (lkmtp, cmd, ver, atapi_load, atapi_unload, lkm_nullcmd);
-}
-#endif /* ATAPI_MODULE */
-
-#endif /* NWDC && ATAPI */
diff --git a/sys/pc98/pc98/atapi.h b/sys/pc98/pc98/atapi.h
index d43241b..5ff3d34 100644
--- a/sys/pc98/pc98/atapi.h
+++ b/sys/pc98/pc98/atapi.h
@@ -17,6 +17,18 @@
/*
* Disk Controller ATAPI register definitions.
*/
+#ifdef PC98
+#define AR_DATA 0x0 /* RW - data register (16 bits) */
+#define AR_ERROR 0x2 /* R - error register */
+#define AR_FEATURES 0x2 /* W - features */
+#define AR_IREASON 0x4 /* RW - interrupt reason */
+#define AR_TAG 0x6 /* - reserved for SAM TAG byte */
+#define AR_CNTLO 0x8 /* RW - byte count, low byte */
+#define AR_CNTHI 0xa /* RW - byte count, high byte */
+#define AR_DRIVE 0xc /* RW - drive select */
+#define AR_COMMAND 0xe /* W - command register */
+#define AR_STATUS 0xe /* R - immediate status */
+#else
#define AR_DATA 0x0 /* RW - data register (16 bits) */
#define AR_ERROR 0x1 /* R - error register */
#define AR_FEATURES 0x1 /* W - features */
@@ -27,6 +39,7 @@
#define AR_DRIVE 0x6 /* RW - drive select */
#define AR_COMMAND 0x7 /* W - command register */
#define AR_STATUS 0x7 /* R - immediate status */
+#endif
/*
* Status register bits
diff --git a/sys/pc98/pc98/clock.c b/sys/pc98/pc98/clock.c
index 3e9faf9..0ba9a65 100644
--- a/sys/pc98/pc98/clock.c
+++ b/sys/pc98/pc98/clock.c
@@ -34,7 +34,11 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.8 1996/10/23 07:25:13 asami Exp $
+ * $Id: clock.c,v 1.9 1996/10/29 08:36:19 asami Exp $
+ */
+
+/*
+ * Routines to handle clock hardware.
*/
/*
@@ -48,10 +52,6 @@
* modified for PC98 by Kakefuda
*/
-/*
- * Primitive clock interrupt routines.
- */
-
#include "opt_clock.h"
#include "opt_cpu.h"
@@ -72,13 +72,12 @@
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <i386/isa/isa_device.h>
-#include <pc98/pc98/timerreg.h>
#else
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/rtc.h>
-#include <i386/isa/timerreg.h>
#endif
+#include <i386/isa/timerreg.h>
/*
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
@@ -109,52 +108,49 @@
int adjkerntz; /* local offset from GMT in seconds */
int disable_rtc_set; /* disable resettodr() if != 0 */
-int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
-
u_int idelayed;
#if defined(I586_CPU) || defined(I686_CPU)
-u_int i586_ctr_bias;
+u_int i586_ctr_bias;
u_int i586_ctr_comultiplier;
u_int i586_ctr_freq;
u_int i586_ctr_multiplier;
-long long i586_last_tick;
-unsigned long i586_avg_tick;
#endif
int statclock_disable;
u_int stat_imask = SWI_CLOCK_MASK;
#ifdef TIMER_FREQ
-static u_int timer_freq = TIMER_FREQ;
+u_int timer_freq = TIMER_FREQ;
#else
#ifdef PC98
#ifndef AUTO_CLOCK
#ifndef PC98_8M
-static u_int timer_freq = 2457600;
+u_int timer_freq = 2457600;
#else /* !PC98_8M */
-static u_int timer_freq = 1996800;
+u_int timer_freq = 1996800;
#endif /* PC98_8M */
#else /* AUTO_CLOCK */
-static u_int timer_freq = 2457600;
+u_int timer_freq = 2457600;
#endif /* AUTO_CLOCK */
#else /* IBM-PC */
-static u_int timer_freq = 1193182;
+u_int timer_freq = 1193182;
#endif /* PC98 */
#endif
-int timer0_max_count;
-u_int timer0_overflow_threshold;
-u_int timer0_prescaler_count;
+int timer0_max_count;
+u_int timer0_overflow_threshold;
+u_int timer0_prescaler_count;
+int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
static int beeping = 0;
static u_int clk_imask = HWI_MASK | SWI_MASK;
static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
-static u_int hardclock_max_count;
+static u_int hardclock_max_count;
/*
* XXX new_function and timer_func should not handle clockframes, but
* timer_func currently needs to hold hardclock to handle the
* timer0_state == 0 case. We should use register_intr()/unregister_intr()
* to switch between clkintr() and a slightly different timerintr().
*/
-static void (*new_function) __P((struct clockframe *frame));
-static u_int new_rate;
+static void (*new_function) __P((struct clockframe *frame));
+static u_int new_rate;
#ifndef PC98
static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
@@ -171,7 +167,7 @@ static u_char timer0_state;
static u_char timer1_state;
#endif
static u_char timer2_state;
-static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
+static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
int rtc_inb __P((void));
#if defined(I586_CPU) || defined(I686_CPU)
@@ -437,7 +433,7 @@ getit(void)
disable_intr();
/* Select timer0 and latch counter value. */
- outb(TIMER_MODE, TIMER_SEL0);
+ outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
low = inb(TIMER_CNTR0);
high = inb(TIMER_CNTR0);
@@ -625,7 +621,7 @@ calibrate_clocks(void)
u_int count, prev_count, tot_count;
int sec, start_sec, timeout;
- printf("Calibrating clock(s) relative to mc146818A clock...\n");
+ printf("Calibrating clock(s) relative to mc146818A clock ... ");
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
goto fail;
timeout = 100000000;
@@ -782,7 +778,7 @@ startrtclock()
if (delta < timer_freq / 100) {
#ifndef CLK_USE_I8254_CALIBRATION
if (bootverbose)
- printf(
+ printf(
"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
freq = timer_freq;
#endif
@@ -802,7 +798,7 @@ startrtclock()
#ifndef CLK_USE_I586_CALIBRATION
if (i586_ctr_freq != 0) {
if (bootverbose)
- printf(
+ printf(
"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
i586_ctr_freq = 0;
}
@@ -1114,10 +1110,8 @@ cpu_initclocks()
/*
* Finish setting up anti-jitter measures.
*/
- if (i586_ctr_freq != 0) {
- i586_last_tick = rdtsc();
- i586_ctr_bias = i586_last_tick;
- }
+ if (i586_ctr_freq != 0)
+ i586_ctr_bias = rdtsc();
#endif
#ifndef PC98
diff --git a/sys/pc98/pc98/icu.s b/sys/pc98/pc98/icu.s
deleted file mode 100644
index 567daf1..0000000
--- a/sys/pc98/pc98/icu.s
+++ /dev/null
@@ -1,357 +0,0 @@
-/*-
- * Copyright (c) 1989, 1990 William F. Jolitz.
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * 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.
- *
- * @(#)icu.s 7.2 (Berkeley) 5/21/91
- *
- * $Id: icu.s,v 1.25 1996/05/31 01:08:07 peter Exp $
- */
-
-/*
- * AT/386
- * Vector interrupt control section
- */
-
-/*
- * XXX this file should be named ipl.s. All spls are now soft and the
- * only thing related to the hardware icu is that the h/w interrupt
- * numbers are used without translation in the masks.
- */
-
- .data
- .globl _cpl
-_cpl: .long HWI_MASK | SWI_MASK /* current priority (all off) */
- .globl _imen
-_imen: .long HWI_MASK /* interrupt mask enable (all h/w off) */
- .globl _tty_imask
-_tty_imask: .long 0
- .globl _bio_imask
-_bio_imask: .long 0
- .globl _net_imask
-_net_imask: .long 0
- .globl _ipending
-_ipending: .long 0
- .globl _netisr
-_netisr: .long 0 /* set with bits for which queue to service */
- .globl _netisrs
-_netisrs:
- .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
- .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
- .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
- .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
- .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
- .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
- .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
- .long dummynetisr, dummynetisr, dummynetisr, dummynetisr
-vec:
- .long vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7
- .long vec8, vec9, vec10, vec11, vec12, vec13, vec14, vec15
-
- .text
-
-/*
- * Handle return from interrupts, traps and syscalls.
- */
- SUPERALIGN_TEXT
-_doreti:
- FAKE_MCOUNT(_bintr) /* init "from" _bintr -> _doreti */
- addl $4,%esp /* discard unit number */
- popl %eax /* cpl to restore */
-doreti_next:
- /*
- * Check for pending HWIs and SWIs atomically with restoring cpl
- * and exiting. The check has to be atomic with exiting to stop
- * (ipending & ~cpl) changing from zero to nonzero while we're
- * looking at it (this wouldn't be fatal but it would increase
- * interrupt latency). Restoring cpl has to be atomic with exiting
- * so that the stack cannot pile up (the nesting level of interrupt
- * handlers is limited by the number of bits in cpl).
- */
- movl %eax,%ecx
- notl %ecx
- cli
- andl _ipending,%ecx
- jne doreti_unpend
-doreti_exit:
- movl %eax,_cpl
- decb _intr_nesting_level
- MEXITCOUNT
- .globl doreti_popl_es
-doreti_popl_es:
- popl %es
- .globl doreti_popl_ds
-doreti_popl_ds:
- popl %ds
- popal
- addl $8,%esp
- .globl doreti_iret
-doreti_iret:
- iret
-
- ALIGN_TEXT
- .globl doreti_iret_fault
-doreti_iret_fault:
- subl $8,%esp
- pushal
- pushl %ds
- .globl doreti_popl_ds_fault
-doreti_popl_ds_fault:
- pushl %es
- .globl doreti_popl_es_fault
-doreti_popl_es_fault:
- movl $0,4+4+32+4(%esp) /* XXX should be the error code */
- movl $T_PROTFLT,4+4+32+0(%esp)
- jmp alltraps_with_regs_pushed
-
- ALIGN_TEXT
-doreti_unpend:
- /*
- * Enabling interrupts is safe because we haven't restored cpl yet.
- * The locking from the "btrl" test is probably no longer necessary.
- * We won't miss any new pending interrupts because we will check
- * for them again.
- */
- sti
- bsfl %ecx,%ecx /* slow, but not worth optimizing */
- btrl %ecx,_ipending
- jnc doreti_next /* some intr cleared memory copy */
- movl ihandlers(,%ecx,4),%edx
- testl %edx,%edx
- je doreti_next /* "can't happen" */
- cmpl $NHWI,%ecx
- jae doreti_swi
- cli
- movl %eax,_cpl
- MEXITCOUNT
- jmp %edx
-
- ALIGN_TEXT
-doreti_swi:
- pushl %eax
- /*
- * The SWI_AST handler has to run at cpl = SWI_AST_MASK and the
- * SWI_CLOCK handler at cpl = SWI_CLOCK_MASK, so we have to restore
- * all the h/w bits in cpl now and have to worry about stack growth.
- * The worst case is currently (30 Jan 1994) 2 SWI handlers nested
- * in dying interrupt frames and about 12 HWIs nested in active
- * interrupt frames. There are only 4 different SWIs and the HWI
- * and SWI masks limit the nesting further.
- */
- orl imasks(,%ecx,4),%eax
- movl %eax,_cpl
- call %edx
- popl %eax
- jmp doreti_next
-
- ALIGN_TEXT
-swi_ast:
- addl $8,%esp /* discard raddr & cpl to get trap frame */
- testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
- je swi_ast_phantom
- movl $T_ASTFLT,(2+8+0)*4(%esp)
- call _trap
- subl %eax,%eax /* recover cpl */
- jmp doreti_next
-
- ALIGN_TEXT
-swi_ast_phantom:
- /*
- * These happen when there is an interrupt in a trap handler before
- * ASTs can be masked or in an lcall handler before they can be
- * masked or after they are unmasked. They could be avoided for
- * trap entries by using interrupt gates, and for lcall exits by
- * using by using cli, but they are unavoidable for lcall entries.
- */
- cli
- orl $SWI_AST_PENDING,_ipending
- subl %eax,%eax
- jmp doreti_exit /* SWI_AST is highest so we must be done */
-
-/*
- * Interrupt priority mechanism
- * -- soft splXX masks with group mechanism (cpl)
- * -- h/w masks for currently active or unused interrupts (imen)
- * -- ipending = active interrupts currently masked by cpl
- */
-
-ENTRY(splz)
- /*
- * The caller has restored cpl and checked that (ipending & ~cpl)
- * is nonzero. We have to repeat the check since if there is an
- * interrupt while we're looking, _doreti processing for the
- * interrupt will handle all the unmasked pending interrupts
- * because we restored early. We're repeating the calculation
- * of (ipending & ~cpl) anyway so that the caller doesn't have
- * to pass it, so this only costs one "jne". "bsfl %ecx,%ecx"
- * is undefined when %ecx is 0 so we can't rely on the secondary
- * btrl tests.
- */
- movl _cpl,%eax
-splz_next:
- /*
- * We don't need any locking here. (ipending & ~cpl) cannot grow
- * while we're looking at it - any interrupt will shrink it to 0.
- */
- movl %eax,%ecx
- notl %ecx
- andl _ipending,%ecx
- jne splz_unpend
- ret
-
- ALIGN_TEXT
-splz_unpend:
- bsfl %ecx,%ecx
- btrl %ecx,_ipending
- jnc splz_next
- movl ihandlers(,%ecx,4),%edx
- testl %edx,%edx
- je splz_next /* "can't happen" */
- cmpl $NHWI,%ecx
- jae splz_swi
- /*
- * We would prefer to call the intr handler directly here but that
- * doesn't work for badly behaved handlers that want the interrupt
- * frame. Also, there's a problem determining the unit number.
- * We should change the interface so that the unit number is not
- * determined at config time.
- */
- jmp *vec(,%ecx,4)
-
- ALIGN_TEXT
-splz_swi:
- cmpl $SWI_AST,%ecx
- je splz_next /* "can't happen" */
- pushl %eax
- orl imasks(,%ecx,4),%eax
- movl %eax,_cpl
- call %edx
- popl %eax
- movl %eax,_cpl
- jmp splz_next
-
-/*
- * Fake clock interrupt(s) so that they appear to come from our caller instead
- * of from here, so that system profiling works.
- * XXX do this more generally (for all vectors; look up the C entry point).
- * XXX frame bogusness stops us from just jumping to the C entry point.
- */
- ALIGN_TEXT
-vec0:
- popl %eax /* return address */
- pushfl
-#define KCSEL 8
- pushl $KCSEL
- pushl %eax
- cli
- MEXITCOUNT
- jmp _Xintr0 /* XXX might need _Xfastintr0 */
-
-#ifndef PC98
- ALIGN_TEXT
-vec8:
- popl %eax
- pushfl
- pushl $KCSEL
- pushl %eax
- cli
- MEXITCOUNT
- jmp _Xintr8 /* XXX might need _Xfastintr8 */
-#endif
-
-#define BUILD_VEC(irq_num) \
- ALIGN_TEXT ; \
-__CONCAT(vec,irq_num): ; \
- int $ICU_OFFSET + (irq_num) ; \
- ret
-
- BUILD_VEC(1)
- BUILD_VEC(2)
- BUILD_VEC(3)
- BUILD_VEC(4)
- BUILD_VEC(5)
- BUILD_VEC(6)
- BUILD_VEC(7)
-#ifdef PC98
- BUILD_VEC(8)
-#endif
- BUILD_VEC(9)
- BUILD_VEC(10)
- BUILD_VEC(11)
- BUILD_VEC(12)
- BUILD_VEC(13)
- BUILD_VEC(14)
- BUILD_VEC(15)
-
- ALIGN_TEXT
-swi_net:
- MCOUNT
- bsfl _netisr,%eax
- je swi_net_done
-swi_net_more:
- btrl %eax,_netisr
- jnc swi_net_next
- call *_netisrs(,%eax,4)
-swi_net_next:
- bsfl _netisr,%eax
- jne swi_net_more
-swi_net_done:
- ret
-
- ALIGN_TEXT
-dummynetisr:
- MCOUNT
- ret
-
-/*
- * XXX there should be a registration function to put the handler for the
- * attached driver directly in ihandlers. Then this function will go away.
- */
- ALIGN_TEXT
-swi_tty:
- MCOUNT
-#include "cy.h"
-#if NCY > 0
- call _cypoll
-#endif
-#include "rc.h"
-#if NRC > 0
- call _rcpoll
-#endif
-#include "sio.h"
-#if NSIO > 0
- jmp _siopoll
-#else
- ret
-#endif
diff --git a/sys/pc98/pc98/if_ed.c b/sys/pc98/pc98/if_ed.c
index 6b7bf2f..9e1d45b 100644
--- a/sys/pc98/pc98/if_ed.c
+++ b/sys/pc98/pc98/if_ed.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_ed.c,v 1.9 1996/10/23 07:25:17 asami Exp $
+ * $Id: if_ed.c,v 1.10 1996/10/29 08:36:20 asami Exp $
*/
/*
@@ -106,7 +106,17 @@
#include <i386/isa/if_edreg.h>
#ifdef PC98
-#include <pc98/pc98/if_ed98.h>
+/* register offsets */
+struct pc98_edregister {
+ u_int *port;
+ u_int ioskip;
+ u_int nic_offset;
+ u_int asic_offset;
+ u_int data;
+ u_int reset;
+ u_int pc_misc;
+ u_int pc_reset;
+};
#endif
/*
@@ -160,12 +170,16 @@ struct ed_softc {
u_char next_packet; /* pointer to next unread RX packet */
struct ifmib_iso_8802_3 mibdata; /* stuff for network mgmt */
#ifdef PC98
- int unit;
+ struct pc98_edregister edreg; /* I/O port register offset info */
#endif
};
static struct ed_softc ed_softc[NED];
+#ifdef PC98
+#include <pc98/pc98/if_ed98.h>
+#endif
+
static int ed_attach __P((struct ed_softc *, int, int));
static int ed_attach_isa __P((struct isa_device *));
@@ -421,10 +435,6 @@ ed_probe(isa_dev)
{
int nports;
-#ifdef PC98
- ed_softc[isa_dev->id_unit].unit = isa_dev->id_unit;
-#endif
-
#if NCRD > 0
/*
* If PC-Card probe required, then register driver with
@@ -443,7 +453,7 @@ ed_probe(isa_dev)
if ((ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_GENERIC) ||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_LPC)) {
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LPC;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LPC);
+ pc98_set_register(isa_dev, ED_TYPE98_LPC);
nports = ed_probe_Novell(isa_dev);
if (nports)
return (nports);
@@ -454,7 +464,7 @@ ed_probe(isa_dev)
* Allied Telesis CenterCom LA-98-T
*/
ed_softc[isa_dev->id_unit].type = ED_TYPE98_GENERIC;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_GENERIC);
+ pc98_set_register(isa_dev, ED_TYPE98_GENERIC);
if (ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_GENERIC) {
#endif
@@ -478,7 +488,7 @@ ed_probe(isa_dev)
if ((ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_GENERIC) ||
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_SIC)) {
ed_softc[isa_dev->id_unit].type = ED_TYPE98_SIC;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_SIC);
+ pc98_set_register(isa_dev, ED_TYPE98_SIC);
nports = ed_probe_SIC98(isa_dev);
if (nports)
return (nports);
@@ -492,7 +502,7 @@ ed_probe(isa_dev)
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_BDN)) {
/* LD-BDN */
ed_softc[isa_dev->id_unit].type = ED_TYPE98_BDN;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_BDN);
+ pc98_set_register(isa_dev, ED_TYPE98_BDN);
nports = ed_probe_Novell(isa_dev);
if (nports)
return (nports);
@@ -506,7 +516,7 @@ ed_probe(isa_dev)
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_LGY)) {
/* LGY-98 */
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LGY;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LGY);
+ pc98_set_register(isa_dev, ED_TYPE98_LGY);
nports = ed_probe_Novell(isa_dev);
if (nports)
return (nports);
@@ -520,7 +530,7 @@ ed_probe(isa_dev)
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_ICM)) {
/* ICM */
ed_softc[isa_dev->id_unit].type = ED_TYPE98_ICM;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_ICM);
+ pc98_set_register(isa_dev, ED_TYPE98_ICM);
nports = ed_probe_Novell(isa_dev);
if (nports)
return (nports);
@@ -534,7 +544,7 @@ ed_probe(isa_dev)
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_EGY)) {
/* EGY-98 */
ed_softc[isa_dev->id_unit].type = ED_TYPE98_EGY;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_EGY);
+ pc98_set_register(isa_dev, ED_TYPE98_EGY);
nports = ed_probe_Novell(isa_dev);
if (nports)
return (nports);
@@ -547,7 +557,7 @@ ed_probe(isa_dev)
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_LA98)) {
/* LA-98 */
ed_softc[isa_dev->id_unit].type = ED_TYPE98_LA98;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_LA98);
+ pc98_set_register(isa_dev, ED_TYPE98_LA98);
nports = ed_probe_Novell(isa_dev);
if (nports)
return (nports);
@@ -560,7 +570,7 @@ ed_probe(isa_dev)
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_108)) {
/* PC-9801-108 */
ed_softc[isa_dev->id_unit].type = ED_TYPE98_108;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_108);
+ pc98_set_register(isa_dev, ED_TYPE98_108);
nports = ed_probe_Novell(isa_dev);
if (nports)
return (nports);
@@ -573,7 +583,7 @@ ed_probe(isa_dev)
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_CNET98EL)) {
/* C-NET(98)E/L */
ed_softc[isa_dev->id_unit].type = ED_TYPE98_CNET98EL;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_CNET98EL);
+ pc98_set_register(isa_dev, ED_TYPE98_CNET98EL);
nports = ed_probe_CNET98EL(isa_dev);
if (nports)
return (nports);
@@ -586,7 +596,7 @@ ed_probe(isa_dev)
(ED_TYPE98(isa_dev->id_flags) == ED_TYPE98_CNET98)) {
/* C-NET(98) */
ed_softc[isa_dev->id_unit].type = ED_TYPE98_CNET98;
- pc98_set_register(isa_dev, isa_dev->id_unit, ED_TYPE98_CNET98);
+ pc98_set_register(isa_dev, ED_TYPE98_CNET98);
nports = ed_probe_CNET98(isa_dev);
if (nports)
return (nports);
@@ -628,10 +638,6 @@ ed_probe_generic8390(sc)
struct ed_softc *sc;
{
#ifdef PC98
- int unit = sc->unit;
-#endif
-
-#ifdef PC98
if (sc->type == ED_TYPE98_LPC) {
if ((inb(sc->nic_addr + ED_P0_CR) &
(ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
@@ -1036,9 +1042,6 @@ ed_probe_3Com(isa_dev)
int i;
u_int memsize;
u_char isa16bit;
-#ifdef PC98
- int unit = isa_dev->id_unit;
-#endif
sc->asic_addr = isa_dev->id_iobase + ED_3COM_ASIC_OFFSET;
sc->nic_addr = isa_dev->id_iobase + ED_3COM_NIC_OFFSET;
@@ -1359,7 +1362,6 @@ ed_probe_Novell_generic(sc, port, unit, flags)
if (sc->type == ED_TYPE98_LPC)
LPCT_1d0_OFF();
#endif
-
DELAY(5000);
/*
@@ -1592,7 +1594,7 @@ ed_probe_Novell(isa_dev)
}
#if NCRD > 0
-
+
/*
* Probe framework for pccards. Replicates the standard framework,
* minus the pccard driver registration and ignores the ether address
@@ -1653,9 +1655,7 @@ ed_probe_HP_pclanp(isa_dev)
u_char irq; /* board configured IRQ */
char test_pattern[ED_HPP_TEST_SIZE]; /* read/write areas for */
char test_buffer[ED_HPP_TEST_SIZE]; /* probing card */
-#ifdef PC98
- int unit = isa_dev->id_unit;
-#endif
+
/* Fill in basic information */
sc->asic_addr = isa_dev->id_iobase + ED_HPP_ASIC_OFFSET;
@@ -2503,9 +2503,6 @@ ed_stop(sc)
struct ed_softc *sc;
{
int n = 5000;
-#ifdef PC98
- int unit = sc->unit;
-#endif
if (sc->gone)
return;
@@ -2550,9 +2547,6 @@ ed_init(xsc)
struct ed_softc *sc = xsc;
struct ifnet *ifp = &sc->arpcom.ac_if;
int i, s;
-#ifdef PC98
- int unit = sc->unit;
-#endif
if (sc->gone)
return;
@@ -2655,7 +2649,7 @@ ed_init(xsc)
*/
#ifdef PC98
for (i = 0; i < ETHER_ADDR_LEN; ++i)
- outb(sc->nic_addr + ED_P1_PAR0 + i * pc98_io_skip[unit],
+ outb(sc->nic_addr + ED_P1_PAR0 + i * sc->edreg.ioskip,
sc->arpcom.ac_enaddr[i]);
#else
for (i = 0; i < ETHER_ADDR_LEN; ++i)
@@ -2713,9 +2707,6 @@ ed_xmit(sc)
{
struct ifnet *ifp = (struct ifnet *)sc;
unsigned short len;
-#ifdef PC98
- int unit = sc->unit;
-#endif
if (sc->gone)
return;
@@ -2930,9 +2921,6 @@ ed_rint(sc)
u_short len;
struct ed_ring packet_hdr;
char *packet_ptr;
-#ifdef PC98
- int unit = sc->unit;
-#endif
if (sc->gone)
return;
@@ -3056,9 +3044,6 @@ edintr_sc(sc)
{
struct ifnet *ifp = (struct ifnet *)sc;
u_char isr;
-#ifdef PC98
- int unit = sc->unit;
-#endif
if (sc->gone)
return;
@@ -3548,10 +3533,6 @@ ed_pio_readmem(sc, src, dst, amount)
unsigned char *dst;
unsigned short amount;
{
-#ifdef PC98
- int unit = sc->unit;
-#endif
-
/* HP cards need special handling */
if (sc->vendor == ED_VENDOR_HP && sc->type == ED_TYPE_HP_PCLANPLUS) {
ed_hpp_readmem(sc, src, dst, amount);
@@ -3603,9 +3584,6 @@ ed_pio_writemem(sc, src, dst, len)
unsigned short len;
{
int maxwait = 200; /* about 240us */
-#ifdef PC98
- int unit = sc->unit;
-#endif
if (sc->vendor == ED_VENDOR_NOVELL) {
@@ -3711,9 +3689,6 @@ ed_pio_write_mbufs(sc, m, dst)
unsigned short total_len, dma_len;
struct mbuf *mp;
int maxwait = 200; /* about 240us */
-#ifdef PC98
- int unit = sc->unit;
-#endif
/* HP PC Lan+ cards need special handling */
if ((sc->vendor == ED_VENDOR_HP) &&
@@ -3977,9 +3952,6 @@ ed_hpp_write_mbufs(struct ed_softc *sc, struct mbuf *m, int dst)
volatile u_short * const d =
(volatile u_short *) sc->hpp_mem_start;
int use_32bit_accesses = !(sc->hpp_id & ED_HPP_ID_16_BIT_ACCESS);
-#ifdef PC98
- int unit = sc->unit;
-#endif
/* select page 0 registers */
outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_STA);
@@ -4095,9 +4067,6 @@ ed_setrcr(sc)
{
struct ifnet *ifp = (struct ifnet *)sc;
int i;
-#ifdef PC98
- int unit = sc->unit;
-#endif
/* set page 1 registers */
outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
@@ -4109,7 +4078,7 @@ ed_setrcr(sc)
*/
#ifdef PC98
for (i = 0; i < 8; i++)
- outb(sc->nic_addr + ED_P1_MAR0 + i * pc98_io_skip[unit], 0xff);
+ outb(sc->nic_addr + ED_P1_MAR0 + i * sc->edreg.ioskip, 0xff);
#else
for (i = 0; i < 8; i++)
outb(sc->nic_addr + ED_P1_MAR0 + i, 0xff);
@@ -4139,7 +4108,7 @@ ed_setrcr(sc)
*/
#ifdef PC98
for (i = 0; i < 8; i++)
- outb(sc->nic_addr + ED_P1_MAR0 + i * pc98_io_skip[unit],
+ outb(sc->nic_addr + ED_P1_MAR0 + i * sc->edreg.ioskip,
((u_char *) mcaf)[i]);
#else
for (i = 0; i < 8; i++)
@@ -4155,12 +4124,12 @@ ed_setrcr(sc)
* Initialize multicast address hashing registers to
* not accept multicasts.
*/
-#ifndef PC98
+#ifdef PC98
for (i = 0; i < 8; ++i)
- outb(sc->nic_addr + ED_P1_MAR0 + i, 0x00);
+ outb(sc->nic_addr + ED_P1_MAR0 + i * sc->edreg.ioskip, 0x00);
#else
for (i = 0; i < 8; ++i)
- outb(sc->nic_addr + ED_P1_MAR0 + i * pc98_io_skip[unit], 0x00);
+ outb(sc->nic_addr + ED_P1_MAR0 + i, 0x00);
#endif
/* Set page 0 registers */
diff --git a/sys/pc98/pc98/if_ed98.h b/sys/pc98/pc98/if_ed98.h
index 9924e36..476d574 100644
--- a/sys/pc98/pc98/if_ed98.h
+++ b/sys/pc98/pc98/if_ed98.h
@@ -36,8 +36,7 @@
#error Why you include if_ed98.h?
#endif
-static void pc98_set_register __P((struct isa_device *dev,
- int unit, int type));
+static void pc98_set_register __P((struct isa_device *dev, int type));
/*
* Vendor types
@@ -50,11 +49,11 @@ static void pc98_set_register __P((struct isa_device *dev,
#ifdef ED_NOVELL_NIC_OFFSET
#undef ED_NOVELL_NIC_OFFSET
#endif
-#define ED_NOVELL_NIC_OFFSET ed_novell_nic_offset[unit]
+#define ED_NOVELL_NIC_OFFSET sc->edreg.nic_offset
#ifdef ED_NOVELL_ASIC_OFFSET
#undef ED_NOVELL_ASIC_OFFSET
#endif
-#define ED_NOVELL_ASIC_OFFSET ed_novell_asic_offset[unit]
+#define ED_NOVELL_ASIC_OFFSET sc->edreg.asic_offset
/*
* Remote DMA data register; for reading or writing to the NIC mem
@@ -63,7 +62,7 @@ static void pc98_set_register __P((struct isa_device *dev,
#ifdef ED_NOVELL_DATA
#undef ED_NOVELL_DATA
#endif
-#define ED_NOVELL_DATA ed_novell_data[unit]
+#define ED_NOVELL_DATA sc->edreg.data
/*
* Reset register; reading from this register causes a board reset
@@ -71,7 +70,7 @@ static void pc98_set_register __P((struct isa_device *dev,
#ifdef ED_NOVELL_RESET
#undef ED_NOVELL_RESET
#endif
-#define ED_NOVELL_RESET ed_novell_reset[unit]
+#define ED_NOVELL_RESET sc->edreg.reset
/*
* Card type
@@ -113,152 +112,152 @@ static void pc98_set_register __P((struct isa_device *dev,
* Page 0 register offsets
*/
#undef ED_P0_CR
-#define ED_P0_CR edp[unit][0x00]
+#define ED_P0_CR sc->edreg.port[0x00]
#undef ED_P0_CLDA0
-#define ED_P0_CLDA0 edp[unit][0x01]
+#define ED_P0_CLDA0 sc->edreg.port[0x01]
#undef ED_P0_PSTART
-#define ED_P0_PSTART edp[unit][0x01]
+#define ED_P0_PSTART sc->edreg.port[0x01]
#undef ED_P0_CLDA1
-#define ED_P0_CLDA1 edp[unit][0x02]
+#define ED_P0_CLDA1 sc->edreg.port[0x02]
#undef ED_P0_PSTOP
-#define ED_P0_PSTOP edp[unit][0x02]
+#define ED_P0_PSTOP sc->edreg.port[0x02]
#undef ED_P0_BNRY
-#define ED_P0_BNRY edp[unit][0x03]
+#define ED_P0_BNRY sc->edreg.port[0x03]
#undef ED_P0_TSR
-#define ED_P0_TSR edp[unit][0x04]
+#define ED_P0_TSR sc->edreg.port[0x04]
#undef ED_P0_TPSR
-#define ED_P0_TPSR edp[unit][0x04]
+#define ED_P0_TPSR sc->edreg.port[0x04]
#undef ED_P0_NCR
-#define ED_P0_NCR edp[unit][0x05]
+#define ED_P0_NCR sc->edreg.port[0x05]
#undef ED_P0_TBCR0
-#define ED_P0_TBCR0 edp[unit][0x05]
+#define ED_P0_TBCR0 sc->edreg.port[0x05]
#undef ED_P0_FIFO
-#define ED_P0_FIFO edp[unit][0x06]
+#define ED_P0_FIFO sc->edreg.port[0x06]
#undef ED_P0_TBCR1
-#define ED_P0_TBCR1 edp[unit][0x06]
+#define ED_P0_TBCR1 sc->edreg.port[0x06]
#undef ED_P0_ISR
-#define ED_P0_ISR edp[unit][0x07]
+#define ED_P0_ISR sc->edreg.port[0x07]
#undef ED_P0_CRDA0
-#define ED_P0_CRDA0 edp[unit][0x08]
+#define ED_P0_CRDA0 sc->edreg.port[0x08]
#undef ED_P0_RSAR0
-#define ED_P0_RSAR0 edp[unit][0x08]
+#define ED_P0_RSAR0 sc->edreg.port[0x08]
#undef ED_P0_CRDA1
-#define ED_P0_CRDA1 edp[unit][0x09]
+#define ED_P0_CRDA1 sc->edreg.port[0x09]
#undef ED_P0_RSAR1
-#define ED_P0_RSAR1 edp[unit][0x09]
+#define ED_P0_RSAR1 sc->edreg.port[0x09]
#undef ED_P0_RBCR0
-#define ED_P0_RBCR0 edp[unit][0x0a]
+#define ED_P0_RBCR0 sc->edreg.port[0x0a]
#undef ED_P0_RBCR1
-#define ED_P0_RBCR1 edp[unit][0x0b]
+#define ED_P0_RBCR1 sc->edreg.port[0x0b]
#undef ED_P0_RSR
-#define ED_P0_RSR edp[unit][0x0c]
+#define ED_P0_RSR sc->edreg.port[0x0c]
#undef ED_P0_RCR
-#define ED_P0_RCR edp[unit][0x0c]
+#define ED_P0_RCR sc->edreg.port[0x0c]
#undef ED_P0_CNTR0
-#define ED_P0_CNTR0 edp[unit][0x0d]
+#define ED_P0_CNTR0 sc->edreg.port[0x0d]
#undef ED_P0_TCR
-#define ED_P0_TCR edp[unit][0x0d]
+#define ED_P0_TCR sc->edreg.port[0x0d]
#undef ED_P0_CNTR1
-#define ED_P0_CNTR1 edp[unit][0x0e]
+#define ED_P0_CNTR1 sc->edreg.port[0x0e]
#undef ED_P0_DCR
-#define ED_P0_DCR edp[unit][0x0e]
+#define ED_P0_DCR sc->edreg.port[0x0e]
#undef ED_P0_CNTR2
-#define ED_P0_CNTR2 edp[unit][0x0f]
+#define ED_P0_CNTR2 sc->edreg.port[0x0f]
#undef ED_P0_IMR
-#define ED_P0_IMR edp[unit][0x0f]
+#define ED_P0_IMR sc->edreg.port[0x0f]
/*
* Page 1 register offsets
*/
#undef ED_P1_CR
-#define ED_P1_CR edp[unit][0x00]
+#define ED_P1_CR sc->edreg.port[0x00]
#undef ED_P1_PAR0
-#define ED_P1_PAR0 edp[unit][0x01]
+#define ED_P1_PAR0 sc->edreg.port[0x01]
#undef ED_P1_PAR1
-#define ED_P1_PAR1 edp[unit][0x02]
+#define ED_P1_PAR1 sc->edreg.port[0x02]
#undef ED_P1_PAR2
-#define ED_P1_PAR2 edp[unit][0x03]
+#define ED_P1_PAR2 sc->edreg.port[0x03]
#undef ED_P1_PAR3
-#define ED_P1_PAR3 edp[unit][0x04]
+#define ED_P1_PAR3 sc->edreg.port[0x04]
#undef ED_P1_PAR4
-#define ED_P1_PAR4 edp[unit][0x05]
+#define ED_P1_PAR4 sc->edreg.port[0x05]
#undef ED_P1_PAR5
-#define ED_P1_PAR5 edp[unit][0x06]
+#define ED_P1_PAR5 sc->edreg.port[0x06]
#undef ED_P1_CURR
-#define ED_P1_CURR edp[unit][0x07]
+#define ED_P1_CURR sc->edreg.port[0x07]
#undef ED_P1_MAR0
-#define ED_P1_MAR0 edp[unit][0x08]
+#define ED_P1_MAR0 sc->edreg.port[0x08]
#undef ED_P1_MAR1
-#define ED_P1_MAR1 edp[unit][0x09]
+#define ED_P1_MAR1 sc->edreg.port[0x09]
#undef ED_P1_MAR2
-#define ED_P1_MAR2 edp[unit][0x0a]
+#define ED_P1_MAR2 sc->edreg.port[0x0a]
#undef ED_P1_MAR3
-#define ED_P1_MAR3 edp[unit][0x0b]
+#define ED_P1_MAR3 sc->edreg.port[0x0b]
#undef ED_P1_MAR4
-#define ED_P1_MAR4 edp[unit][0x0c]
+#define ED_P1_MAR4 sc->edreg.port[0x0c]
#undef ED_P1_MAR5
-#define ED_P1_MAR5 edp[unit][0x0d]
+#define ED_P1_MAR5 sc->edreg.port[0x0d]
#undef ED_P1_MAR6
-#define ED_P1_MAR6 edp[unit][0x0e]
+#define ED_P1_MAR6 sc->edreg.port[0x0e]
#undef ED_P1_MAR7
-#define ED_P1_MAR7 edp[unit][0x0f]
+#define ED_P1_MAR7 sc->edreg.port[0x0f]
/*
* Page 2 register offsets
*/
#undef ED_P2_CR
-#define ED_P2_CR edp[unit][0x00]
+#define ED_P2_CR sc->edreg.port[0x00]
#undef ED_P2_PSTART
-#define ED_P2_PSTART edp[unit][0x01]
+#define ED_P2_PSTART sc->edreg.port[0x01]
#undef ED_P2_CLDA0
-#define ED_P2_CLDA0 edp[unit][0x01]
+#define ED_P2_CLDA0 sc->edreg.port[0x01]
#undef ED_P2_PSTOP
-#define ED_P2_PSTOP edp[unit][0x02]
+#define ED_P2_PSTOP sc->edreg.port[0x02]
#undef ED_P2_CLDA1
-#define ED_P2_CLDA1 edp[unit][0x02]
+#define ED_P2_CLDA1 sc->edreg.port[0x02]
#undef ED_P2_RNPP
-#define ED_P2_RNPP edp[unit][0x03]
+#define ED_P2_RNPP sc->edreg.port[0x03]
#undef ED_P2_TPSR
-#define ED_P2_TPSR edp[unit][0x04]
+#define ED_P2_TPSR sc->edreg.port[0x04]
#undef ED_P2_LNPP
-#define ED_P2_LNPP edp[unit][0x05]
+#define ED_P2_LNPP sc->edreg.port[0x05]
#undef ED_P2_ACU
-#define ED_P2_ACU edp[unit][0x06]
+#define ED_P2_ACU sc->edreg.port[0x06]
#undef ED_P2_ACL
-#define ED_P2_ACL edp[unit][0x07]
+#define ED_P2_ACL sc->edreg.port[0x07]
#undef ED_P2_RCR
-#define ED_P2_RCR edp[unit][0x0c]
+#define ED_P2_RCR sc->edreg.port[0x0c]
#undef ED_P2_TCR
-#define ED_P2_TCR edp[unit][0x0d]
+#define ED_P2_TCR sc->edreg.port[0x0d]
#undef ED_P2_DCR
-#define ED_P2_DCR edp[unit][0x0e]
+#define ED_P2_DCR sc->edreg.port[0x0e]
#undef ED_P2_IMR
-#define ED_P2_IMR edp[unit][0x0f]
+#define ED_P2_IMR sc->edreg.port[0x0f]
/* PCCARD */
#ifdef ED_PC_MISC
#undef ED_PC_MISC
#endif
-#define ED_PC_MISC ed_pc_misc[unit]
+#define ED_PC_MISC sc->edreg.pc_misc
#ifdef ED_PC_RESET
#undef ED_PC_RESET
#endif
-#define ED_PC_RESET ed_pc_reset[unit]
+#define ED_PC_RESET sc->edreg.pc_reset
/* LPC-T support */
#define LPCT_1d0_ON() \
@@ -336,19 +335,6 @@ static void pc98_set_register __P((struct isa_device *dev,
*/
#define ED_CNET98EL_ISR 0x05
-
-
-/* register offsets */
-static unsigned int *edp[NED];
-static unsigned int pc98_io_skip[NED];
-static int ed_novell_nic_offset[NED];
-static int ed_novell_asic_offset[NED];
-static int ed_novell_data[NED];
-static int ed_novell_reset[NED];
-static int ed_pc_misc[NED];
-static int ed_pc_reset[NED];
-
-
/* NE2000, LGY-98, ICM, LPC-T, C-NET(98)E/L */
static unsigned int edp_generic[16] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
@@ -391,14 +377,15 @@ static unsigned int edp_cnet98[16] = {
};
-static void pc98_set_register(struct isa_device *dev, int unit, int type)
+static void pc98_set_register(struct isa_device *dev, int type)
{
+ struct ed_softc *sc = &ed_softc[dev->id_unit];
int adj;
switch (type) {
case ED_TYPE98_GENERIC:
- edp[unit] = edp_generic;
- pc98_io_skip[unit] = 1;
+ sc->edreg.port = edp_generic;
+ sc->edreg.ioskip = 1;
ED_NOVELL_NIC_OFFSET = 0x0000;
ED_NOVELL_ASIC_OFFSET = 0x0010;
ED_NOVELL_DATA = 0x0000;
@@ -408,8 +395,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
break;
case ED_TYPE98_LGY:
- edp[unit] = edp_generic;
- pc98_io_skip[unit] = 1;
+ sc->edreg.port = edp_generic;
+ sc->edreg.ioskip = 1;
ED_NOVELL_NIC_OFFSET = 0x0000;
ED_NOVELL_ASIC_OFFSET = 0x0200;
ED_NOVELL_DATA = 0x0000;
@@ -419,8 +406,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
break;
case ED_TYPE98_EGY:
- edp[unit] = edp_egy98;
- pc98_io_skip[unit] = 2;
+ sc->edreg.port = edp_egy98;
+ sc->edreg.ioskip = 2;
ED_NOVELL_NIC_OFFSET = 0;
ED_NOVELL_ASIC_OFFSET = 0x0200;
ED_NOVELL_DATA = 0x0000;
@@ -430,8 +417,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
break;
case ED_TYPE98_ICM:
- edp[unit] = edp_generic;
- pc98_io_skip[unit] = 1;
+ sc->edreg.port = edp_generic;
+ sc->edreg.ioskip = 1;
ED_NOVELL_NIC_OFFSET = 0;
ED_NOVELL_ASIC_OFFSET = 0x0100;
ED_NOVELL_DATA = 0x0000;
@@ -441,8 +428,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
break;
case ED_TYPE98_BDN:
- edp[unit] = edp_bdn98;
- pc98_io_skip[unit] = 0x1000;
+ sc->edreg.port = edp_bdn98;
+ sc->edreg.ioskip = 0x1000;
ED_NOVELL_NIC_OFFSET = 0x0000;
ED_NOVELL_ASIC_OFFSET = 0x0100;
ED_NOVELL_DATA = 0;
@@ -452,8 +439,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
break;
case ED_TYPE98_SIC:
- edp[unit] = edp_sic98;
- pc98_io_skip[unit] = 0x200;
+ sc->edreg.port = edp_sic98;
+ sc->edreg.ioskip = 0x200;
ED_NOVELL_NIC_OFFSET = 0x0000;
ED_NOVELL_ASIC_OFFSET = 0x2000;
ED_NOVELL_DATA = 0x00; /* dummy */
@@ -463,8 +450,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
break;
case ED_TYPE98_LPC:
- edp[unit] = edp_generic;
- pc98_io_skip[unit] = 0x1;
+ sc->edreg.port = edp_generic;
+ sc->edreg.ioskip = 0x1;
ED_NOVELL_NIC_OFFSET = 0x0000;
ED_NOVELL_ASIC_OFFSET = 0x0100;
ED_NOVELL_DATA = 0x0000;
@@ -474,8 +461,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
break;
case ED_TYPE98_108:
- edp[unit] = edp_nec108;
- pc98_io_skip[unit] = 2;
+ sc->edreg.port = edp_nec108;
+ sc->edreg.ioskip = 2;
adj = (dev->id_iobase & 0xf000) / 2;
ED_NOVELL_NIC_OFFSET = 0;
ED_NOVELL_ASIC_OFFSET = (0x888 | adj) - dev->id_iobase;
@@ -486,8 +473,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
break;
case ED_TYPE98_LA98:
- edp[unit] = edp_la98;
- pc98_io_skip[unit] = 0x1000;
+ sc->edreg.port = edp_la98;
+ sc->edreg.ioskip = 0x1000;
ED_NOVELL_NIC_OFFSET = 0;
ED_NOVELL_ASIC_OFFSET = 0x100;
ED_NOVELL_DATA = 0x0000;
@@ -497,8 +484,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
break;
case ED_TYPE98_CNET98EL:
- edp[unit] = edp_generic;
- pc98_io_skip[unit] = 1;
+ sc->edreg.port = edp_generic;
+ sc->edreg.ioskip = 1;
ED_NOVELL_NIC_OFFSET = 0;
ED_NOVELL_ASIC_OFFSET = 0x0400;
ED_NOVELL_DATA = 0x000e;
@@ -507,8 +494,8 @@ static void pc98_set_register(struct isa_device *dev, int unit, int type)
break;
case ED_TYPE98_CNET98:
- edp[unit] = edp_cnet98;
- pc98_io_skip[unit] = 2;
+ sc->edreg.port = edp_cnet98;
+ sc->edreg.ioskip = 2;
ED_NOVELL_NIC_OFFSET = 0;
ED_NOVELL_ASIC_OFFSET = 0x0400;
ED_NOVELL_DATA = 0x000e;
diff --git a/sys/pc98/pc98/if_fe.c b/sys/pc98/pc98/if_fe.c
index 856b1c5..bfc8229 100644
--- a/sys/pc98/pc98/if_fe.c
+++ b/sys/pc98/pc98/if_fe.c
@@ -21,7 +21,7 @@
*/
/*
- * $Id: if_fe.c,v 1.8 1996/09/12 11:09:48 asami Exp $
+ * $Id: if_fe.c,v 1.9 1996/10/09 21:46:25 asami Exp $
*
* Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards.
* To be used with FreeBSD 2.x
@@ -242,8 +242,8 @@ static struct fe_softc {
#define sc_enaddr arpcom.ac_enaddr
/* Standard driver entry points. These can be static. */
-static int fe_probe ( DEVICE * );
-static int fe_attach ( DEVICE * );
+static int fe_probe ( struct isa_device * );
+static int fe_attach ( struct isa_device * );
static void fe_init ( int );
static int fe_ioctl ( struct ifnet *, int, caddr_t );
static void fe_start ( struct ifnet * );
diff --git a/sys/pc98/pc98/kbd.h b/sys/pc98/pc98/kbd.h
index 8a963e4..a4fcc74 100644
--- a/sys/pc98/pc98/kbd.h
+++ b/sys/pc98/pc98/kbd.h
@@ -1,9 +1,15 @@
/*
* Keyboard definitions
+ * from: unknown origin, 386BSD 0.1
+ * $Id: kbd.h,v 1.4 1995/05/30 08:02:38 rgrimes Exp $
*/
-#ifndef _PC98_PC98_KBD_H_
-#define _PC98_PC98_KBD_H_ 1
+#ifndef _I386_ISA_KBD_H_
+#define _I386_ISA_KBD_H_ 1
+
+/* Reference: IBM AT Technical Reference Manual,
+ * pp. 1-38 to 1-43, 4-3 to 4-22
+ */
/* commands and responses */
#define KBC_RESET 0xFF /* Reset the keyboard */
@@ -12,4 +18,4 @@
#define KBR_RESEND 0xFE /* Keyboard needs resend of command */
#define KBR_ACK 0xFA /* Keyboard did receive command */
#define KBR_RSTDONE 0xAA /* Keyboard reset complete */
-#endif /* _PC98_PC98_KBD_H_ */
+#endif /* _I386_ISA_KBD_H_ */
diff --git a/sys/pc98/pc98/kbdtables.h b/sys/pc98/pc98/kbdtables.h
deleted file mode 100644
index 4a822a9..0000000
--- a/sys/pc98/pc98/kbdtables.h
+++ /dev/null
@@ -1,1039 +0,0 @@
-/*-
- * Copyright (c) 1992-1994 Sen Schmidt
- * 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
- * in this position and unchanged.
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough 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.
- *
- * $Id: kbdtables.h,v 1.1.1.1 1996/06/14 10:04:44 asami Exp $
- */
-
-#define SET8 0x80 /* set eight bit on */
-
-/*
- * modified for PC98 by kuribo@isl.melco.co.jp
- */
-
-#ifdef PC98 /* PC98 keyboard truetype by kuribo */
-static keymap_t key_map = { 0x80, /* PC98 keymap */
-/* alt
- * scan cntrl alt alt cntrl
- * code base shift cntrl shift alt shift cntrl shift spcl flgs
- * ---------------------------------------------------------------------------
- */
-/* sc=00 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
-/* sc=01 */ '1', '!', '!', '!', '1', '!', '!', '!', 0x00, 0x00,
-/* sc=02 */ '2', '\"', 0x1A, 0x1A, '2', '@', 0x00, 0x00, 0x00, 0x00,
-/* sc=03 */ '3', '#', 0x1B, 0x1B, '3', '#', 0x1B, 0x1B, 0x00, 0x00,
-/* sc=04 */ '4', '$', 0x1C, 0x1C, '4', '$', 0x1C, 0x1C, 0x00, 0x00,
-/* sc=05 */ '5', '%', 0x1D, 0x1D, '5', '%', 0x1D, 0x1D, 0x00, 0x00,
-/* sc=06 */ '6', '&', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00,
-/* sc=07 */ '7', '\'', 0x1F, 0x1F, '7', '&', '&', '&', 0x00, 0x00,
-/* sc=08 */ '8', '(', 0x7F, 0x7F, '8', '*', 0x08, 0x08, 0x00, 0x00,
-/* sc=09 */ '9', ')', '9', '9', '9', '(', '(', '(', 0x00, 0x00,
-/* sc=0a */ '0', NOP, '0', '0', '0', ')', ')', ')', 0x40, 0x00,
-/* sc=0b */ '-', '=', '-', '-', '-', '_', 0x1F, 0x1F, 0x00, 0x00,
-/* sc=0c */ '^', '`', 0x1E, 0x1E, '=', '+', '+', '+', 0x00, 0x00,
-/* sc=0d */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00,
-/* sc=0e */ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-/* sc=0f */ '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t', 0x00, 0x00,
-/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
-/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
-/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
-/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
-/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
-/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
-/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
-/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
-/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
-/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
-/* sc=1a */ '@', '~', 0x00, 0x00, '[', '{', 0x1B, 0x1B, 0x00, 0x00,
-/* sc=1b */ '[', '{', 0x1B, 0x1B, ']', '}', 0x1D, 0x1D, 0x00, 0x00,
-/* sc=1c */ '\r', '\r', '\n', '\n', '\r', '\r', '\n', '\n', 0x00, 0x00,
-/* sc=1d */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
-/* sc=1e */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
-/* sc=1f */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
-/* sc=20 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
-/* sc=21 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
-/* sc=22 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
-/* sc=23 */ 'j', 'J', '\n', '\n', 'j', 'J', '\n', '\n', 0x00, 0x01,
-/* sc=24 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
-/* sc=25 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
-/* sc=26 */ ';', '+', ';', ';', ';', ':', ';', ';', 0x00, 0x00,
-/* sc=27 */ ':', '*', ':', ':', '\'', '\"', '\'', '\'', 0x00, 0x00,
-/* sc=28 */ ']', '}', 0x1D, 0x1D, '`', '~', '~', '~', 0x00, 0x00,
-/* sc=29 */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
-/* sc=2a */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
-/* sc=2b */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
-/* sc=2c */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
-/* sc=2d */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
-/* sc=2e */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
-/* sc=2f */ 'm', 'M', '\r', '\r', 'm', 'M', '\r', '\r', 0x00, 0x01,
-/* sc=30 */ ',', '<', '<', '<', ',', '<', '<', '<', 0x00, 0x00,
-/* sc=31 */ '.', '>', '>', '>', '.', '>', '>', '>', 0x00, 0x00,
-/* sc=32 */ '/', '?', 0x7F, 0x7F, '/', '?', 0x7F, 0x7F, 0x00, 0x00,
-/* sc=33 */ NOP, '_', 0x1F, 0x1F, '\\', '|', 0x1C, 0x1C, 0x80, 0x00,
-/* sc=34 */ ' ', ' ', 0x00, 0x00, ' ', ' ', 0x00, 0x00, 0x00, 0x00,
-/* sc=35 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
-/* sc=36 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
-/* sc=37 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
-/* sc=38 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
-/* sc=39 */ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, RBT, RBT, 0x00, 0x00,
-/* sc=3a */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
-/* sc=3b */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
-/* sc=3c */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
-/* sc=3d */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
-/* sc=3e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
-/* sc=3f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=40 */ '-', '-', '-', '-', '-', '-', '-', '-', 0x00, 0x00,
-/* sc=41 */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00,
-/* sc=42 */ '7', '7', '7', '7', '7', '7', '7', '7', 0x00, 0x00,
-/* sc=43 */ '8', '8', '8', '8', '8', '8', '8', '8', 0x00, 0x00,
-/* sc=44 */ '9', '9', '9', '9', '9', '9', '9', '9', 0x00, 0x00,
-/* sc=45 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00,
-/* sc=46 */ '4', '4', '4', '4', '4', '4', '4', '4', 0x00, 0x00,
-/* sc=47 */ '5', '5', '5', '5', '5', '5', '5', '5', 0x00, 0x00,
-/* sc=48 */ '6', '6', '6', '6', '6', '6', '6', '6', 0x00, 0x00,
-/* sc=49 */ '+', '+', '+', '+', '+', '+', '+', '+', 0x00, 0x00,
-/* sc=4a */ '1', '1', '1', '1', '1', '1', '1', '1', 0x00, 0x00,
-/* sc=4b */ '2', '2', '2', '2', '2', '2', '2', '2', 0x00, 0x00,
-/* sc=4c */ '3', '3', '3', '3', '3', '3', '3', '3', 0x00, 0x00,
-/* sc=4d */ '=', '=', '=', '=', '=', '=', '=', '=', 0x00, 0x00,
-/* sc=4e */ '0', '0', '0', '0', '0', '0', '0', '0', 0x00, 0x00,
-/* sc=4f */ ',', ',', ',', ',', ',', ',', ',', ',', 0x00, 0x00,
-/* sc=50 */ '.', '.', '.', '.', '.', '.', '.', '.', 0x00, 0x00,
-/* sc=51 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
-/* sc=52 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
-/* sc=53 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
-/* sc=54 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=57 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=58 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=59 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=60 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
-/* sc=61 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=62 */ F( 1), F(13), F(25), F(37), S( 1), S( 1), S( 1), S( 1), 0xFF, 0x00,
-/* sc=63 */ F( 2), F(14), F(26), F(38), S( 2), S( 2), S( 2), S( 2), 0xFF, 0x00,
-/* sc=64 */ F( 3), F(15), F(27), F(39), S( 3), S( 3), S( 3), S( 3), 0xFF, 0x00,
-/* sc=65 */ F( 4), F(16), F(28), F(40), S( 4), S( 4), S( 4), S( 4), 0xFF, 0x00,
-/* sc=66 */ F( 5), F(17), F(29), F(41), S( 5), S( 5), S( 5), S( 5), 0xFF, 0x00,
-/* sc=67 */ F( 6), F(18), F(30), F(42), S( 6), S( 6), S( 6), S( 6), 0xFF, 0x00,
-/* sc=68 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
-/* sc=69 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
-/* sc=6a */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
-/* sc=6b */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
-/* sc=6c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=6d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=6e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=6f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=70 */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
-/* sc=71 */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
-/* sc=72 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
-/* sc=73 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
-/* sc=74 */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
-/* sc=75 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=76 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=77 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=78 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=79 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-};
-#endif
-
-#ifdef DKKEYMAP
-static keymap_t key_map = { 0x6C, /* DK iso8859 keymap */
-/* alt
- * scan cntrl alt alt cntrl
- * code base shift cntrl shift alt shift cntrl shift spcl flgs
- * ---------------------------------------------------------------------------
- */
-/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=01 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
-/* sc=02 */ '1', '!', NOP, NOP, '1', '!', NOP, NOP, 0x33, 0x00,
-/* sc=03 */ '2', '"', 0x00, 0x00, '@', '@', 0x00, 0x00, 0x00, 0x00,
-/* sc=04 */ '3', '#', NOP, NOP, 0x9E, '#', NOP, NOP, 0x33, 0x00,
-/* sc=05 */ '4', 0xA4, NOP, NOP, '$', 0xA4, NOP, NOP, 0x33, 0x00,
-/* sc=06 */ '5', '%', NOP, NOP, '5', '%', NOP, NOP, 0x33, 0x00,
-/* sc=07 */ '6', '&', NOP, NOP, '6', '&', NOP, NOP, 0x33, 0x00,
-/* sc=08 */ '7', '/', NOP, NOP, '{', '/', NOP, NOP, 0x33, 0x00,
-/* sc=09 */ '8', '(', 0x1B, 0x1B, '[', '(', 0x1B, 0x1B, 0x00, 0x00,
-/* sc=0a */ '9', ')', 0x1D, 0x1D, ']', ')', 0x1D, 0x1D, 0x00, 0x00,
-/* sc=0b */ '0', '=', NOP, NOP, '}', '=', NOP, NOP, 0x33, 0x00,
-/* sc=0c */ '+', '?', NOP, NOP, '+', '?', NOP, NOP, 0x33, 0x00,
-/* sc=0d */ '\'', '`', NOP, NOP, '|', '`', NOP, NOP, 0x33, 0x00,
-/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00,
-/* sc=0f */ 0x09, BTAB, NOP, NOP, 0x09, BTAB, NOP, NOP, 0x77, 0x00,
-/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
-/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
-/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
-/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
-/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
-/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
-/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
-/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
-/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
-/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
-/* sc=1a */ 0xE5, 0xC5, NOP, NOP, 0x86, 0x8F, NOP, NOP, 0x33, 0x01,
-/* sc=1b */ '"', '^', 0x1E, 0x1E, '~', '^', 0x1E, 0x1E, 0x00, 0x00,
-/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00,
-/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
-/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
-/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
-/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
-/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
-/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
-/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
-/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01,
-/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
-/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
-/* sc=27 */ 0xE6, 0xC6, NOP, NOP, 0x91, 0x92, NOP, NOP, 0x33, 0x01,
-/* sc=28 */ 0xF8, 0xD8, NOP, NOP, 0x9B, 0x9D, NOP, NOP, 0x33, 0x01,
-/* sc=29 */ 0xBD, 0xA7, NOP, NOP, 0xBD, 0xA7, NOP, NOP, 0x33, 0x00,
-/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
-/* sc=2b */ '\'', '*', NOP, NOP, '\'', '*', NOP, NOP, 0x33, 0x00,
-/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
-/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
-/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
-/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
-/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
-/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
-/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01,
-/* sc=33 */ ',', ';', NOP, NOP, ',', ';', NOP, NOP, 0x33, 0x00,
-/* sc=34 */ '.', ':', NOP, NOP, '.', ':', NOP, NOP, 0x33, 0x00,
-/* sc=35 */ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, 0x00, 0x00,
-/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00,
-/* sc=37 */ '*', '*', '*', '*', '*', '*', '*', '*', 0x00, 0x00,
-/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
-/* sc=39 */ ' ', ' ', 0x00, ' ', ' ', ' ', SUSP, ' ', 0x02, 0x00,
-/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
-/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00,
-/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00,
-/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00,
-/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00,
-/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00,
-/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00,
-/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
-/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
-/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
-/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
-/* sc=45 */ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, 0xFF, 0x00,
-/* sc=46 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02,
-/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02,
-/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02,
-/* sc=4a */ F(52), '-', '-', '-', '-', '-', '-', '-', 0x80, 0x02,
-/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02,
-/* sc=4c */ F(54), '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02,
-/* sc=4d */ F(55), '6', '6', '6', '6', '6', '6', '6', 0x80, 0x02,
-/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02,
-/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02,
-/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02,
-/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02,
-/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02,
-/* sc=53 */ 0x7F, '.', '.', '.', '.', '.', RBT, RBT, 0x03, 0x02,
-/* sc=54 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=56 */ '<', '>', 0x1C, 0x1C, '\\', '>', 0x1C, 0x1C, 0x00, 0x00,
-/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
-/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
-/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x02,
-/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00,
-/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00,
-/* sc=5c */ NEXT, NOP, DBG, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00,
-/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
-/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
-/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
-/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
-/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
-/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
-/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
-/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
-/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
-/* sc=67 */ F(61), F(61), F(61), F(61), F(61), F(61), RBT, F(61), 0xFF, 0x00,
-/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=69 */ F(62), F(62), F(62), F(62), F(62), F(62), F(62), F(62), 0xFF, 0x00,
-/* sc=6a */ F(63), F(63), F(63), F(63), F(63), F(63), F(63), F(63), 0xFF, 0x00,
-/* sc=6b */ F(64), F(64), F(64), F(64), F(64), F(64), F(64), F(64), 0xFF, 0x00,
-};
-#endif
-
-#ifdef UKKEYMAP
-static keymap_t key_map = { 0x6C, /* uk iso8859 keymap */
-/* alt
- * scan cntrl alt alt cntrl
- * code base shift cntrl shift alt shift cntrl shift spcl flgs
- * ---------------------------------------------------------------------------
- */
-/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=01 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
-/* sc=02 */ '1', '!', NOP, NOP, '`', '`', NOP, NOP, 0x33, 0x00,
-/* sc=03 */ '2', '"', 0x00, 0x00, '@', '@', 0x00, 0x00, 0x00, 0x00,
-/* sc=04 */ '3', 0xA3, NOP, NOP, '#', '#', NOP, NOP, 0x33, 0x00,
-/* sc=05 */ '4', '$', NOP, NOP, '4', '$', NOP, NOP, 0x33, 0x00,
-/* sc=06 */ '5', '%', NOP, NOP, '5', '%', NOP, NOP, 0x33, 0x00,
-/* sc=07 */ '6', '^', 0x1E, 0x1E, '^', '^', 0x1E, 0x1E, 0x00, 0x00,
-/* sc=08 */ '7', '&', NOP, NOP, '[', '[', 0x1B, 0x1B, 0x30, 0x00,
-/* sc=09 */ '8', '*', NOP, NOP, '8', '*', NOP, NOP, 0x33, 0x00,
-/* sc=0a */ '9', '(', NOP, NOP, ']', ']', 0x1D, 0x1D, 0x30, 0x00,
-/* sc=0b */ '0', ')', NOP, NOP, '{', '{', NOP, NOP, 0x33, 0x00,
-/* sc=0c */ '-', '_', 0x1F, 0x1F, '|', '|', 0x1F, 0x1F, 0x00, 0x00,
-/* sc=0d */ '=', '+', NOP, NOP, '}', '}', NOP, NOP, 0x33, 0x00,
-/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00,
-/* sc=0f */ 0x09, BTAB, NOP, NOP, 0x09, BTAB, NOP, NOP, 0x77, 0x00,
-/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
-/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
-/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
-/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
-/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
-/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
-/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
-/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
-/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
-/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
-/* sc=1a */ '[', '{', 0x1B, 0x1B, '[', '{', 0x1B, 0x1B, 0x00, 0x00,
-/* sc=1b */ ']', '}', 0x1D, 0x1D, ']', '}', 0x1D, 0x1D, 0x00, 0x00,
-/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00,
-/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
-/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
-/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
-/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
-/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
-/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
-/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
-/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01,
-/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
-/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
-/* sc=27 */ ';', ':', NOP, NOP, ';', ':', NOP, NOP, 0x33, 0x00,
-/* sc=28 */ '\'', '@', 0x00, 0x00, '\'', '@', 0x00, 0x00, 0x00, 0x00,
-/* sc=29 */ '\\', '|', 0x1C, 0x1C, '\\', '\\', 0x1C, 0x1C, 0x00, 0x00,
-/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
-/* sc=2b */ '#', '~', NOP, NOP, '~', '~', NOP, NOP, 0x33, 0x00,
-/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
-/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
-/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
-/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
-/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
-/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
-/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01,
-/* sc=33 */ ',', '<', NOP, NOP, ',', '<', NOP, NOP, 0x33, 0x00,
-/* sc=34 */ '.', '>', NOP, NOP, '.', '>', NOP, NOP, 0x33, 0x00,
-/* sc=35 */ '/', '?', NOP, NOP, '/', '?', NOP, NOP, 0x33, 0x00,
-/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00,
-/* sc=37 */ '*', '*', 0x0A, 0x0A, '*', '*', 0x0A, 0x0A, 0x33, 0x00,
-/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
-/* sc=39 */ ' ', ' ', 0x00, ' ', ' ', ' ', SUSP, ' ', 0x02, 0x00,
-/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
-/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00,
-/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00,
-/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00,
-/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00,
-/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00,
-/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00,
-/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
-/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
-/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
-/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
-/* sc=45 */ NLK, NLK, 0x13, 0x13, NLK, NLK, 0x13, 0x13, 0xCC, 0x00,
-/* sc=46 */ SLK, SLK, 0x7F, 0x7F, SLK, SLK, 0x7F, 0x7F, 0xCC, 0x00,
-/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02,
-/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02,
-/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02,
-/* sc=4a */ F(52), '-', 0x1F, 0x1F, '-', '-', '-', '-', 0x80, 0x02,
-/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02,
-/* sc=4c */ F(54), '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02,
-/* sc=4d */ F(55), '6', 0x1E, 0x1E, '6', '6', '6', '6', 0x80, 0x02,
-/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02,
-/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02,
-/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02,
-/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02,
-/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02,
-/* sc=53 */ 0x7F, '.', '.', '.', '.', '.', RBT, RBT, 0x03, 0x02,
-/* sc=54 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=56 */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00,
-/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
-/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
-/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0xFF, 0x02,
-/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00,
-/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x02,
-/* sc=5c */ NEXT, NOP, DBG, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00,
-/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
-/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
-/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
-/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
-/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
-/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
-/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
-/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
-/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
-/* sc=67 */ F(61), F(61), F(61), F(61), F(61), F(61), RBT, F(61), 0xFF, 0x00,
-/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=69 */ F(62), F(62), F(62), F(62), F(62), F(62), F(62), F(62), 0xFF, 0x00,
-/* sc=6a */ F(63), F(63), F(63), F(63), F(63), F(63), F(63), F(63), 0xFF, 0x00,
-/* sc=6b */ F(64), F(64), F(64), F(64), F(64), F(64), F(64), F(64), 0xFF, 0x00,
-};
-#endif
-
-#ifdef GRKEYMAP
-static keymap_t key_map = { 0x6C, /* german iso8859 keymap */
-/* alt
- * scan cntrl alt alt cntrl
- * code base shift cntrl shift alt shift cntrl shift spcl flgs
- * ---------------------------------------------------------------------------
- */
-/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=01 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
-/* sc=02 */ '1', '!', NOP, NOP, '`', '`', NOP, NOP, 0x33, 0x00,
-/* sc=03 */ '2', '"', 0x00, 0x00, '@', '@', 0x00, 0x00, 0x00, 0x00,
-/* sc=04 */ '3', 0xA7, NOP, NOP, '#', '#', NOP, NOP, 0x33, 0x00,
-/* sc=05 */ '4', '$', NOP, NOP, '4', '$', NOP, NOP, 0x33, 0x00,
-/* sc=06 */ '5', '%', NOP, NOP, '5', '%', NOP, NOP, 0x33, 0x00,
-/* sc=07 */ '6', '&', 0x1E, 0x1E, '^', '^', 0x1E, 0x1E, 0x00, 0x00,
-/* sc=08 */ '7', '/', 0x1B, 0x1B, '[', '[', 0x1B, 0x1B, 0x00, 0x00,
-/* sc=09 */ '8', '(', NOP, NOP, '8', '(', NOP, NOP, 0x33, 0x00,
-/* sc=0a */ '9', ')', 0x1D, 0x1D, ']', ']', 0x1D, 0x1D, 0x00, 0x00,
-/* sc=0b */ '0', '=', NOP, NOP, '{', '{', NOP, NOP, 0x33, 0x00,
-/* sc=0c */ 0xDF, '?', NOP, NOP, '|', '|', NOP, NOP, 0x33, 0x00,
-/* sc=0d */ 0x92, 0x93, NOP, NOP, '\'', '`', NOP, NOP, 0x33, 0x00,
-/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00,
-/* sc=0f */ 0x09, BTAB, NOP, NOP, 0x09, BTAB, NOP, NOP, 0x77, 0x00,
-/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
-/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
-/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
-/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
-/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
-/* sc=15 */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
-/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
-/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
-/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
-/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
-/* sc=1a */ 0xFC, 0xDC, 0x1B, 0x1B, '[', '{', 0x1B, 0x1B, 0x00, 0x01,
-/* sc=1b */ '+', '*', 0x1D, 0x1D, ']', '}', 0x1D, 0x1D, 0x00, 0x00,
-/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00,
-/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
-/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
-/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
-/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
-/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
-/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
-/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
-/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01,
-/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
-/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
-/* sc=27 */ 0xF6, 0xD6, NOP, NOP, 0xF6, 0xD6, NOP, NOP, 0x33, 0x01,
-/* sc=28 */ 0xE4, 0xC4, NOP, NOP, 0xE4, 0xC4, NOP, NOP, 0x33, 0x01,
-/* sc=29 */ '<', '>', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00,
-/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
-/* sc=2b */ '#', '^', 0x1E, 0x1E, '`', '~', 0x1E, 0x1E, 0x00, 0x00,
-/* sc=2c */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
-/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
-/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
-/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
-/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
-/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
-/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01,
-/* sc=33 */ ',', ';', NOP, NOP, ',', ';', NOP, NOP, 0x33, 0x00,
-/* sc=34 */ '.', ':', NOP, NOP, '.', ':', NOP, NOP, 0x33, 0x00,
-/* sc=35 */ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, 0x00, 0x00,
-/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00,
-/* sc=37 */ '*', '*', 0x0A, 0x0A, '*', '*', 0x0A, 0x0A, 0x33, 0x00,
-/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
-/* sc=39 */ ' ', ' ', 0x00, ' ', ' ', ' ', SUSP, ' ', 0x02, 0x00,
-/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
-/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00,
-/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00,
-/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00,
-/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00,
-/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00,
-/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00,
-/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
-/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
-/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
-/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
-/* sc=45 */ NLK, NLK, 0x13, 0x13, NLK, NLK, 0x13, 0x13, 0xCC, 0x00,
-/* sc=46 */ SLK, SLK, 0x7F, 0x7F, SLK, SLK, 0x7F, 0x7F, 0xCC, 0x00,
-/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02,
-/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02,
-/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02,
-/* sc=4a */ F(52), '-', 0x1F, 0x1F, '-', '-', '-', '-', 0x80, 0x02,
-/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02,
-/* sc=4c */ F(54), '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02,
-/* sc=4d */ F(55), '6', 0x1E, 0x1E, '6', '6', '6', '6', 0x80, 0x02,
-/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02,
-/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02,
-/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02,
-/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02,
-/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02,
-/* sc=53 */ 0x7F, '.', '.', '.', '.', '.', RBT, RBT, 0x03, 0x02,
-/* sc=54 */ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00,
-/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
-/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
-/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0xFF, 0x02,
-/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00,
-/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x02,
-/* sc=5c */ NEXT, NOP, DBG, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00,
-/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
-/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
-/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
-/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
-/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
-/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
-/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
-/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
-/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
-/* sc=67 */ F(61), F(61), F(61), F(61), F(61), F(61), RBT, F(61), 0xFF, 0x00,
-/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=69 */ F(62), F(62), F(62), F(62), F(62), F(62), F(62), F(62), 0xFF, 0x00,
-/* sc=6a */ F(63), F(63), F(63), F(63), F(63), F(63), F(63), F(63), 0xFF, 0x00,
-/* sc=6b */ F(64), F(64), F(64), F(64), F(64), F(64), F(64), F(64), 0xFF, 0x00,
-};
-#endif
-
-#ifdef SWKEYMAP
-static keymap_t key_map = { 0x6C, /* swedish iso8859 keymap */
-/* alt
- * scan cntrl alt alt cntrl
- * code base shift cntrl shift alt shift cntrl shift spcl flgs
- * ---------------------------------------------------------------------------
- */
-/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=01 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
-/* sc=02 */ '1', '!', NOP, NOP, NOP, NOP, NOP, NOP, 0x3F, 0x00,
-/* sc=03 */ '2', '"', 0x00, 0x00, '@', '@', 0x00, 0x00, 0x00, 0x00,
-/* sc=04 */ '3', '#', NOP, NOP, 0xA3, NOP, NOP, NOP, 0x37, 0x00,
-/* sc=05 */ '4', '$', NOP, NOP, 0xA4, NOP, NOP, NOP, 0x37, 0x00,
-/* sc=06 */ '5', '%', NOP, NOP, NOP, NOP, NOP, NOP, 0x3F, 0x00,
-/* sc=07 */ '6', '&', NOP, NOP, NOP, NOP, NOP, NOP, 0x3F, 0x00,
-/* sc=08 */ '7', '/', NOP, NOP, '{', NOP, NOP, NOP, 0x37, 0x00,
-/* sc=09 */ '8', '(', NOP, NOP, '[', NOP, NOP, NOP, 0x37, 0x00,
-/* sc=0a */ '9', ')', NOP, NOP, ']', NOP, NOP, NOP, 0x37, 0x00,
-/* sc=0b */ '0', '=', NOP, NOP, '}', NOP, NOP, NOP, 0x37, 0x00,
-/* sc=0c */ '+', '?', NOP, NOP, '\\', NOP, 0x1C, NOP, 0x35, 0x00,
-/* sc=0d */ 0x180, '`', NOP, NOP, NOP, NOP, NOP, NOP, 0x3F, 0x00,
-/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00,
-/* sc=0f */ 0x09, BTAB, NOP, NOP, 0x09, BTAB, NOP, NOP, 0x77, 0x00,
-/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
-/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
-/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
-/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
-/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
-/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
-/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
-/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
-/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
-/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
-/* sc=1a */ 0xE5, 0xC5, NOP, NOP, '}', ']', NOP, NOP, 0x33, 0x01,
-/* sc=1b */ 0xA8, '^', NOP, NOP, '~', NOP, NOP, NOP, 0x37, 0x00,
-/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00,
-/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
-/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
-/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
-/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
-/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
-/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
-/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
-/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01,
-/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
-/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
-/* sc=27 */ 0xF6, 0xD6, NOP, NOP, '|', '\\', NOP, NOP, 0x33, 0x01,
-/* sc=28 */ 0xE4, 0xC4, NOP, NOP, '{', '[', NOP, NOP, 0x33, 0x01,
-/* sc=29 */ 0xA7, 0xBD, NOP, NOP, '\\', '|', NOP, NOP, 0x33, 0x00,
-/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
-/* sc=2b */ '\'', '*', NOP, NOP, NOP, NOP, NOP, NOP, 0x3F, 0x00,
-/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
-/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
-/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
-/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
-/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
-/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
-/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01,
-/* sc=33 */ ',', ';', NOP, NOP, NOP, '<', NOP, NOP, 0x3B, 0x00,
-/* sc=34 */ '.', ':', NOP, NOP, NOP, '>', NOP, NOP, 0x3B, 0x00,
-/* sc=35 */ '-', '_', 0x1F, NOP, '/', '?', NOP, NOP, 0x13, 0x00,
-/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00,
-/* sc=37 */ '*', '*', 0x0A, 0x0A, '*', '*', 0x0A, 0x0A, 0x33, 0x00,
-/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
-/* sc=39 */ ' ', ' ', 0x00, ' ', ' ', ' ', SUSP, ' ', 0x02, 0x00,
-/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
-/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00,
-/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00,
-/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00,
-/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00,
-/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00,
-/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00,
-/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
-/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
-/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
-/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
-/* sc=45 */ NLK, NLK, 0x13, 0x13, NLK, NLK, 0x13, 0x13, 0xCC, 0x00,
-/* sc=46 */ SLK, SLK, 0x7F, 0x7F, SLK, SLK, 0x7F, 0x7F, 0xCC, 0x00,
-/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02,
-/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02,
-/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02,
-/* sc=4a */ F(52), '-', 0x1F, 0x1F, '-', '-', '-', '-', 0x80, 0x02,
-/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02,
-/* sc=4c */ F(54), '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02,
-/* sc=4d */ F(55), '6', 0x1E, 0x1E, '6', '6', '6', '6', 0x80, 0x02,
-/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02,
-/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02,
-/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02,
-/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02,
-/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02,
-/* sc=53 */ 0x7F, '.', '.', '.', '.', '.', RBT, RBT, 0x03, 0x02,
-/* sc=54 */ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00,
-/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=56 */ '<', '>', NOP, NOP, '|', NOP, NOP, NOP, 0x37, 0x00,
-/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
-/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
-/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0xFF, 0x02,
-/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00,
-/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x02,
-/* sc=5c */ NEXT, NOP, DBG, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00,
-/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
-/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
-/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
-/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
-/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
-/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
-/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
-/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
-/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
-/* sc=67 */ F(61), F(61), F(61), F(61), F(61), F(61), RBT, F(61), 0xFF, 0x00,
-/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=69 */ F(62), F(62), F(62), F(62), F(62), F(62), F(62), F(62), 0xFF, 0x00,
-/* sc=6a */ F(63), F(63), F(63), F(63), F(63), F(63), F(63), F(63), 0xFF, 0x00,
-/* sc=6b */ F(64), F(64), F(64), F(64), F(64), F(64), F(64), F(64), 0xFF, 0x00,
-};
-#endif
-
-#ifdef RUKEYMAP
-static keymap_t key_map = { 0xEC, /* keys number */
-/* alt
- * scan cntrl alt alt cntrl
- * code base shift cntrl shift alt shift cntrl shift spcl flgs
- * -------------------------------------------------------------------------------------------
- */
-/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=01 */ 0x1B, 0x1B, NOP, NOP, SET8|0x1B, SET8|0x1B, DBG, NOP, 0x33, 0x00,
-/* sc=02 */ '1', '!', NOP, NOP, SET8|'1', SET8|'!', NOP, NOP, 0x33, 0x00,
-/* sc=03 */ '2', '@', 0x00, 0x00, SET8|'2', SET8|'@', SET8|0x00, SET8|0x00, 0x00, 0x00,
-/* sc=04 */ '3', '#', NOP, NOP, SET8|'3', SET8|'#', NOP, NOP, 0x33, 0x00,
-/* sc=05 */ '4', '$', NOP, NOP, SET8|'4', SET8|'$', NOP, NOP, 0x33, 0x00,
-/* sc=06 */ '5', '%', NOP, NOP, SET8|'5', SET8|'%', NOP, NOP, 0x33, 0x00,
-/* sc=07 */ '6', '^', 0x1E, 0x1E, SET8|'6', SET8|'^', SET8|0x1E, SET8|0x1E, 0x00, 0x00,
-/* sc=08 */ '7', '&', NOP, NOP, SET8|'7', SET8|'&', NOP, NOP, 0x33, 0x00,
-/* sc=09 */ '8', '*', NOP, NOP, SET8|'8', SET8|'*', NOP, NOP, 0x33, 0x00,
-/* sc=0a */ '9', '(', NOP, NOP, SET8|'9', SET8|'(', NOP, NOP, 0x33, 0x00,
-/* sc=0b */ '0', ')', NOP, NOP, SET8|'0', SET8|')', NOP, NOP, 0x33, 0x00,
-/* sc=0c */ '-', '_', 0x1F, 0x1F, SET8|'-', SET8|'_', SET8|0x1F, SET8|0x1F, 0x00, 0x00,
-/* sc=0d */ '=', '+', NOP, NOP, SET8|'=', SET8|'+', NOP, NOP, 0x33, 0x00,
-/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, SET8|0x08, SET8|0x08, SET8|0x7F, SET8|0x7F, 0x00, 0x00,
-/* sc=0f */ 0x09, BTAB, NOP, NOP, SET8|0x09, BTAB, NOP, NOP, 0x77, 0x00,
-/* sc=10 */ 'q', 'Q', 0x11, 0x11, SET8|'q', SET8|'Q', SET8|0x11, SET8|0x11, 0x00, 0x01,
-/* sc=11 */ 'w', 'W', 0x17, 0x17, SET8|'w', SET8|'W', SET8|0x17, SET8|0x17, 0x00, 0x01,
-/* sc=12 */ 'e', 'E', 0x05, 0x05, SET8|'e', SET8|'E', SET8|0x05, SET8|0x05, 0x00, 0x01,
-/* sc=13 */ 'r', 'R', 0x12, 0x12, SET8|'r', SET8|'R', SET8|0x12, SET8|0x12, 0x00, 0x01,
-/* sc=14 */ 't', 'T', 0x14, 0x14, SET8|'t', SET8|'T', SET8|0x14, SET8|0x14, 0x00, 0x01,
-/* sc=15 */ 'y', 'Y', 0x19, 0x19, SET8|'y', SET8|'Y', SET8|0x19, SET8|0x19, 0x00, 0x01,
-/* sc=16 */ 'u', 'U', 0x15, 0x15, SET8|'u', SET8|'U', SET8|0x15, SET8|0x15, 0x00, 0x01,
-/* sc=17 */ 'i', 'I', 0x09, 0x09, SET8|'i', SET8|'I', SET8|0x09, SET8|0x09, 0x00, 0x01,
-/* sc=18 */ 'o', 'O', 0x0F, 0x0F, SET8|'o', SET8|'O', SET8|0x0F, SET8|0x0F, 0x00, 0x01,
-/* sc=19 */ 'p', 'P', 0x10, 0x10, SET8|'p', SET8|'P', SET8|0x10, SET8|0x10, 0x00, 0x01,
-/* sc=1a */ '[', '{', 0x1B, 0x1B, SET8|'[', SET8|'{', SET8|0x1B, SET8|0x1B, 0x00, 0x00,
-/* sc=1b */ ']', '}', 0x1D, 0x1D, SET8|']', SET8|'}', SET8|0x1D, SET8|0x1D, 0x00, 0x00,
-/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, SET8|0x0D, SET8|0x0D, SET8|0x0A, SET8|0x0A, 0x00, 0x00,
-/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
-/* sc=1e */ 'a', 'A', 0x01, 0x01, SET8|'a', SET8|'A', SET8|0x01, SET8|0x01, 0x00, 0x01,
-/* sc=1f */ 's', 'S', 0x13, 0x13, SET8|'s', SET8|'S', SET8|0x13, SET8|0x13, 0x00, 0x01,
-/* sc=20 */ 'd', 'D', 0x04, 0x04, SET8|'d', SET8|'D', SET8|0x04, SET8|0x04, 0x00, 0x01,
-/* sc=21 */ 'f', 'F', 0x06, 0x06, SET8|'f', SET8|'F', SET8|0x06, SET8|0x06, 0x00, 0x01,
-/* sc=22 */ 'g', 'G', 0x07, 0x07, SET8|'g', SET8|'G', SET8|0x07, SET8|0x07, 0x00, 0x01,
-/* sc=23 */ 'h', 'H', 0x08, 0x08, SET8|'h', SET8|'H', SET8|0x08, SET8|0x08, 0x00, 0x01,
-/* sc=24 */ 'j', 'J', 0x0A, 0x0A, SET8|'j', SET8|'J', SET8|0x0A, SET8|0x0A, 0x00, 0x01,
-/* sc=25 */ 'k', 'K', 0x0B, 0x0B, SET8|'k', SET8|'K', SET8|0x0B, SET8|0x0B, 0x00, 0x01,
-/* sc=26 */ 'l', 'L', 0x0C, 0x0C, SET8|'l', SET8|'L', SET8|0x0C, SET8|0x0C, 0x00, 0x01,
-/* sc=27 */ ';', ':', NOP, NOP, SET8|';', SET8|':', NOP, NOP, 0x33, 0x00,
-/* sc=28 */ '\'', '"', NOP, NOP, SET8|'\'', SET8|'"', NOP, NOP, 0x33, 0x00,
-/* sc=29 */ '`', '~', NOP, NOP, SET8|'`', SET8|'~', NOP, NOP, 0x33, 0x00,
-/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
-/* sc=2b */ '\\', '|', 0x1C, 0x1C, SET8|'\\', SET8|'|', SET8|0x1C, SET8|0x1C, 0x00, 0x00,
-/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, SET8|'z', SET8|'Z', SET8|0x1A, SET8|0x1A, 0x00, 0x01,
-/* sc=2d */ 'x', 'X', 0x18, 0x18, SET8|'x', SET8|'X', SET8|0x18, SET8|0x18, 0x00, 0x01,
-/* sc=2e */ 'c', 'C', 0x03, 0x03, SET8|'c', SET8|'C', SET8|0x03, SET8|0x03, 0x00, 0x01,
-/* sc=2f */ 'v', 'V', 0x16, 0x16, SET8|'v', SET8|'V', SET8|0x16, SET8|0x16, 0x00, 0x01,
-/* sc=30 */ 'b', 'B', 0x02, 0x02, SET8|'b', SET8|'B', SET8|0x02, SET8|0x02, 0x00, 0x01,
-/* sc=31 */ 'n', 'N', 0x0E, 0x0E, SET8|'n', SET8|'N', SET8|0x0E, SET8|0x0E, 0x00, 0x01,
-/* sc=32 */ 'm', 'M', 0x0D, 0x0D, SET8|'m', SET8|'M', SET8|0x0D, SET8|0x0D, 0x00, 0x01,
-/* sc=33 */ ',', '<', NOP, NOP, SET8|',', SET8|'<', NOP, NOP, 0x33, 0x00,
-/* sc=34 */ '.', '>', NOP, NOP, SET8|'.', SET8|'>', NOP, NOP, 0x33, 0x00,
-/* sc=35 */ '/', '?', NOP, NOP, SET8|'/', SET8|'?', NOP, NOP, 0x33, 0x00,
-/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00,
-/* sc=37 */ '*', '*', 0x0A, 0x0A, SET8|'*', SET8|'*', SET8|0x0A, SET8|0x0A, 0x00, 0x00,
-/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
-/* sc=39 */ ' ', ' ', 0x00, ' ', SET8|' ', SET8|' ', SET8|' ', SET8|' ', 0x00, 0x00,
-/* sc=3a */ ALK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
-/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00,
-/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00,
-/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00,
-/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00,
-/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00,
-/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00,
-/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
-/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
-/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
-/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
-/* sc=45 */ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, 0xFF, 0x00,
-/* sc=46 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=47 */ F(49), '7', '7', '7', SET8|'7', SET8|'7', SET8|'7', SET8|'7', 0x80, 0x02,
-/* sc=48 */ F(50), '8', '8', '8', SET8|'8', SET8|'8', SET8|'8', SET8|'8', 0x80, 0x02,
-/* sc=49 */ F(51), '9', '9', '9', SET8|'9', SET8|'9', SET8|'9', SET8|'9', 0x80, 0x02,
-/* sc=4a */ F(52), '-', '-', '-', SET8|'-', SET8|'-', SET8|'-', SET8|'-', 0x80, 0x02,
-/* sc=4b */ F(53), '4', '4', '4', SET8|'4', SET8|'4', SET8|'4', SET8|'4', 0x80, 0x02,
-/* sc=4c */ F(54), '5', '5', '5', SET8|'5', SET8|'5', SET8|'5', SET8|'5', 0x80, 0x02,
-/* sc=4d */ F(55), '6', '6', '6', SET8|'6', SET8|'6', SET8|'6', SET8|'6', 0x80, 0x02,
-/* sc=4e */ F(56), '+', '+', '+', SET8|'+', SET8|'+', SET8|'+', SET8|'+', 0x80, 0x02,
-/* sc=4f */ F(57), '1', '1', '1', SET8|'1', SET8|'1', SET8|'1', SET8|'1', 0x80, 0x02,
-/* sc=50 */ F(58), '2', '2', '2', SET8|'2', SET8|'2', SET8|'2', SET8|'2', 0x80, 0x02,
-/* sc=51 */ F(59), '3', '3', '3', SET8|'3', SET8|'3', SET8|'3', SET8|'3', 0x80, 0x02,
-/* sc=52 */ F(60), '0', '0', '0', SET8|'0', SET8|'0', SET8|'0', SET8|'0', 0x80, 0x02,
-/* sc=53 */ 0x7F, '.', '.', '.', SET8|'.', SET8|'.', RBT, RBT, 0x03, 0x02,
-/* sc=54 */ ALK, ALK, ALK, ALK, ALK, ALK, ALK, ALK, 0xFF, 0x00,
-/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
-/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
-/* sc=59 */ 0x0D, 0x0D, 0x0A, 0x0A, SET8|0x0D, SET8|0x0D, SET8|0x0A, SET8|0x0A, 0x00, 0x00,
-/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00,
-/* sc=5b */ '/', '/', NOP, NOP, SET8|'/', SET8|'/', NOP, NOP, 0x33, 0x00,
-/* sc=5c */ NEXT, NOP, DBG, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00,
-/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
-/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
-/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
-/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
-/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
-/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
-/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
-/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
-/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
-/* sc=67 */ F(61), F(61), F(61), F(61), F(61), F(61), RBT, F(61), 0xFF, 0x00,
-/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=69 */ F(62), F(62), F(62), F(62), F(62), F(62), F(62), F(62), 0xFF, 0x00,
-/* sc=6a */ F(63), F(63), F(63), F(63), F(63), F(63), F(63), F(63), 0xFF, 0x00,
-/* sc=6b */ F(64), F(64), F(64), F(64), F(64), F(64), F(64), F(64), 0xFF, 0x00,
-/* sc=6c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=6d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=6e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=6f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=70 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=71 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=72 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=73 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=74 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=75 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=76 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=77 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=78 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=79 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7a */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7b */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7c */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7d */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7e */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=7f */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* extended (ALTGR LOCK keys) */
-/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=01 */ 0x1B, 0x1B, NOP, NOP, SET8|0x1B, SET8|0x1B, DBG, NOP, 0x33, 0x00,
-/* sc=02 */ '!', '1', NOP, NOP, SET8|'1', SET8|'!', NOP, NOP, 0x33, 0x00,
-/* sc=03 */ '"', '2', 0x00, 0x00, SET8|'2', SET8|'@', SET8|0x00, SET8|0x00, 0x00, 0x00,
-/* sc=04 */ '\'', '3', NOP, NOP, SET8|'3', SET8|'#', NOP, NOP, 0x33, 0x00,
-/* sc=05 */ '*', '4', NOP, NOP, SET8|'4', SET8|'$', NOP, NOP, 0x33, 0x00,
-/* sc=06 */ ':', '5', NOP, NOP, SET8|'5', SET8|'%', NOP, NOP, 0x33, 0x00,
-/* sc=07 */ ',', '6', 0x1E, 0x1E, SET8|'6', SET8|'^', SET8|0x1E, SET8|0x1E, 0x00, 0x00,
-/* sc=08 */ '.', '7', NOP, NOP, SET8|'7', SET8|'&', NOP, NOP, 0x33, 0x00,
-/* sc=09 */ ';', '8', NOP, NOP, SET8|'8', SET8|'*', NOP, NOP, 0x33, 0x00,
-/* sc=0a */ '(', '9', NOP, NOP, SET8|'9', SET8|'(', NOP, NOP, 0x33, 0x00,
-/* sc=0b */ ')', '0', NOP, NOP, SET8|'0', SET8|')', NOP, NOP, 0x33, 0x00,
-/* sc=0c */ '-', '_', 0x1F, 0x1F, SET8|'-', SET8|'_', SET8|0x1F, SET8|0x1F, 0x00, 0x00,
-/* sc=0d */ '=', '+', NOP, NOP, SET8|'=', SET8|'+', NOP, NOP, 0x33, 0x00,
-/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, SET8|0x08, SET8|0x08, SET8|0x7F, SET8|0x7F, 0x00, 0x00,
-/* sc=0f */ 0x09, BTAB, NOP, NOP, SET8|0x09, BTAB, NOP, NOP, 0x77, 0x00,
-/* sc=10 */ 0xca, 0xea, 0x11, 0x11, SET8|'q', SET8|'Q', SET8|0x11, SET8|0x11, 0x00, 0x01,
-/* sc=11 */ 0xc3, 0xe3, 0x17, 0x17, SET8|'w', SET8|'W', SET8|0x17, SET8|0x17, 0x00, 0x01,
-/* sc=12 */ 0xd5, 0xf5, 0x05, 0x05, SET8|'e', SET8|'E', SET8|0x05, SET8|0x05, 0x00, 0x01,
-/* sc=13 */ 0xcb, 0xeb, 0x12, 0x12, SET8|'r', SET8|'R', SET8|0x12, SET8|0x12, 0x00, 0x01,
-/* sc=14 */ 0xc5, 0xe5, 0x14, 0x14, SET8|'t', SET8|'T', SET8|0x14, SET8|0x14, 0x00, 0x01,
-/* sc=15 */ 0xce, 0xee, 0x19, 0x19, SET8|'y', SET8|'Y', SET8|0x19, SET8|0x19, 0x00, 0x01,
-/* sc=16 */ 0xc7, 0xe7, 0x15, 0x15, SET8|'u', SET8|'U', SET8|0x15, SET8|0x15, 0x00, 0x01,
-/* sc=17 */ 0xdb, 0xfb, 0x09, 0x09, SET8|'i', SET8|'I', SET8|0x09, SET8|0x09, 0x00, 0x01,
-/* sc=18 */ 0xdd, 0xfd, 0x0F, 0x0F, SET8|'o', SET8|'O', SET8|0x0F, SET8|0x0F, 0x00, 0x01,
-/* sc=19 */ 0xda, 0xfa, 0x10, 0x10, SET8|'p', SET8|'P', SET8|0x10, SET8|0x10, 0x00, 0x01,
-/* sc=1a */ 0xc8, 0xe8, 0x1B, 0x1B, SET8|'[', SET8|'{', SET8|0x1B, SET8|0x1B, 0x00, 0x01,
-/* sc=1b */ 0xdf, 0xff, 0x1D, 0x1D, SET8|']', SET8|'}', SET8|0x1D, SET8|0x1D, 0x00, 0x01,
-/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, SET8|0x0D, SET8|0x0D, SET8|0x0A, SET8|0x0A, 0x00, 0x00,
-/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
-/* sc=1e */ 0xc6, 0xe6, 0x01, 0x01, SET8|'a', SET8|'A', SET8|0x01, SET8|0x01, 0x00, 0x01,
-/* sc=1f */ 0xd9, 0xf9, 0x13, 0x13, SET8|'s', SET8|'S', SET8|0x13, SET8|0x13, 0x00, 0x01,
-/* sc=20 */ 0xd7, 0xf7, 0x04, 0x04, SET8|'d', SET8|'D', SET8|0x04, SET8|0x04, 0x00, 0x01,
-/* sc=21 */ 0xc1, 0xe1, 0x06, 0x06, SET8|'f', SET8|'F', SET8|0x06, SET8|0x06, 0x00, 0x01,
-/* sc=22 */ 0xd0, 0xf0, 0x07, 0x07, SET8|'g', SET8|'G', SET8|0x07, SET8|0x07, 0x00, 0x01,
-/* sc=23 */ 0xd2, 0xf2, 0x08, 0x08, SET8|'h', SET8|'H', SET8|0x08, SET8|0x08, 0x00, 0x01,
-/* sc=24 */ 0xcf, 0xef, 0x0A, 0x0A, SET8|'j', SET8|'J', SET8|0x0A, SET8|0x0A, 0x00, 0x01,
-/* sc=25 */ 0xcc, 0xec, 0x0B, 0x0B, SET8|'k', SET8|'K', SET8|0x0B, SET8|0x0B, 0x00, 0x01,
-/* sc=26 */ 0xc4, 0xe4, 0x0C, 0x0C, SET8|'l', SET8|'L', SET8|0x0C, SET8|0x0C, 0x00, 0x01,
-/* sc=27 */ 0xd6, 0xf6, NOP, NOP, SET8|';', SET8|':', NOP, NOP, 0x33, 0x01,
-/* sc=28 */ 0xdc, 0xfc, NOP, NOP, SET8|'\'', SET8|'"', NOP, NOP, 0x33, 0x01,
-/* sc=29 */ 0xa3, 0xb3, NOP, NOP, SET8|'`', SET8|'~', NOP, NOP, 0x33, 0x01,
-/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
-/* sc=2b */ '\\', '|', 0x1C, 0x1C, SET8|'\\', SET8|'|', SET8|0x1C, SET8|0x1C, 0x00, 0x00,
-/* sc=2c */ 0xd1, 0xf1, 0x1A, 0x1A, SET8|'z', SET8|'Z', SET8|0x1A, SET8|0x1A, 0x00, 0x01,
-/* sc=2d */ 0xde, 0xfe, 0x18, 0x18, SET8|'x', SET8|'X', SET8|0x18, SET8|0x18, 0x00, 0x01,
-/* sc=2e */ 0xd3, 0xf3, 0x03, 0x03, SET8|'c', SET8|'C', SET8|0x03, SET8|0x03, 0x00, 0x01,
-/* sc=2f */ 0xcd, 0xed, 0x16, 0x16, SET8|'v', SET8|'V', SET8|0x16, SET8|0x16, 0x00, 0x01,
-/* sc=30 */ 0xc9, 0xe9, 0x02, 0x02, SET8|'b', SET8|'B', SET8|0x02, SET8|0x02, 0x00, 0x01,
-/* sc=31 */ 0xd4, 0xf4, 0x0E, 0x0E, SET8|'n', SET8|'N', SET8|0x0E, SET8|0x0E, 0x00, 0x01,
-/* sc=32 */ 0xd8, 0xf8, 0x0D, 0x0D, SET8|'m', SET8|'M', SET8|0x0D, SET8|0x0D, 0x00, 0x01,
-/* sc=33 */ 0xc2, 0xe2, NOP, NOP, SET8|',', SET8|'<', NOP, NOP, 0x33, 0x01,
-/* sc=34 */ 0xc0, 0xe0, NOP, NOP, SET8|'.', SET8|'>', NOP, NOP, 0x33, 0x01,
-/* sc=35 */ '/', '?', NOP, NOP, SET8|'/', SET8|'?', NOP, NOP, 0x33, 0x00,
-/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00,
-/* sc=37 */ '*', '*', 0x0A, 0x0A, SET8|'*', SET8|'*', SET8|0x0A, SET8|0x0A, 0x00, 0x00,
-/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
-/* sc=39 */ ' ', ' ', 0x00, ' ', SET8|' ', SET8|' ', SET8|' ', SET8|' ', 0x00, 0x00,
-/* sc=3a */ ALK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
-/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00,
-/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00,
-/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00,
-/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00,
-/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00,
-/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00,
-/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
-/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
-/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
-/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
-/* sc=45 */ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, 0xFF, 0x00,
-/* sc=46 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=47 */ F(49), '7', '7', '7', SET8|'7', SET8|'7', SET8|'7', SET8|'7', 0x80, 0x02,
-/* sc=48 */ F(50), '8', '8', '8', SET8|'8', SET8|'8', SET8|'8', SET8|'8', 0x80, 0x02,
-/* sc=49 */ F(51), '9', '9', '9', SET8|'9', SET8|'9', SET8|'9', SET8|'9', 0x80, 0x02,
-/* sc=4a */ F(52), '-', '-', '-', SET8|'-', SET8|'-', SET8|'-', SET8|'-', 0x80, 0x02,
-/* sc=4b */ F(53), '4', '4', '4', SET8|'4', SET8|'4', SET8|'4', SET8|'4', 0x80, 0x02,
-/* sc=4c */ F(54), '5', '5', '5', SET8|'5', SET8|'5', SET8|'5', SET8|'5', 0x80, 0x02,
-/* sc=4d */ F(55), '6', '6', '6', SET8|'6', SET8|'6', SET8|'6', SET8|'6', 0x80, 0x02,
-/* sc=4e */ F(56), '+', '+', '+', SET8|'+', SET8|'+', SET8|'+', SET8|'+', 0x80, 0x02,
-/* sc=4f */ F(57), '1', '1', '1', SET8|'1', SET8|'1', SET8|'1', SET8|'1', 0x80, 0x02,
-/* sc=50 */ F(58), '2', '2', '2', SET8|'2', SET8|'2', SET8|'2', SET8|'2', 0x80, 0x02,
-/* sc=51 */ F(59), '3', '3', '3', SET8|'3', SET8|'3', SET8|'3', SET8|'3', 0x80, 0x02,
-/* sc=52 */ F(60), '0', '0', '0', SET8|'0', SET8|'0', SET8|'0', SET8|'0', 0x80, 0x02,
-/* sc=53 */ 0x7F, '.', '.', '.', SET8|'.', SET8|'.', RBT, RBT, 0x03, 0x02,
-/* sc=54 */ ALK, ALK, ALK, ALK, ALK, ALK, ALK, ALK, 0xFF, 0x00,
-/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
-/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
-/* sc=59 */ 0x0D, 0x0D, 0x0A, 0x0A, SET8|0x0D, SET8|0x0D, SET8|0x0A, SET8|0x0A, 0x00, 0x00,
-/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00,
-/* sc=5b */ '/', '/', NOP, NOP, SET8|'/', SET8|'/', NOP, NOP, 0x33, 0x00,
-/* sc=5c */ NEXT, NOP, DBG, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00,
-/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
-/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
-/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
-/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
-/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
-/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
-/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
-/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
-/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
-/* sc=67 */ F(61), F(61), F(61), F(61), F(61), F(61), RBT, F(61), 0xFF, 0x00,
-/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=69 */ F(62), F(62), F(62), F(62), F(62), F(62), F(62), F(62), 0xFF, 0x00,
-/* sc=6a */ F(63), F(63), F(63), F(63), F(63), F(63), F(63), F(63), 0xFF, 0x00,
-/* sc=6b */ F(64), F(64), F(64), F(64), F(64), F(64), F(64), F(64), 0xFF, 0x00,
-};
-
-#endif
-
-#if !defined(DKKEYMAP) && !defined(UKKEYMAP) && !defined(GRKEYMAP) && !defined(SWKEYMAP) && !defined(RUKEYMAP) && !defined(PC98)
-static keymap_t key_map = { 0x6C, /* US iso8859 keymap */
-/* alt
- * scan cntrl alt alt cntrl
- * code base shift cntrl shift alt shift cntrl shift spcl flgs
- * ---------------------------------------------------------------------------
- */
-/* sc=00 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=01 */ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B, 0x02, 0x00,
-/* sc=02 */ '1', '!', NOP, NOP, '1', '!', NOP, NOP, 0x33, 0x00,
-/* sc=03 */ '2', '@', 0x00, 0x00, '2', '@', 0x00, 0x00, 0x00, 0x00,
-/* sc=04 */ '3', '#', NOP, NOP, '3', '#', NOP, NOP, 0x33, 0x00,
-/* sc=05 */ '4', '$', NOP, NOP, '4', '$', NOP, NOP, 0x33, 0x00,
-/* sc=06 */ '5', '%', NOP, NOP, '5', '%', NOP, NOP, 0x33, 0x00,
-/* sc=07 */ '6', '^', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E, 0x00, 0x00,
-/* sc=08 */ '7', '&', NOP, NOP, '7', '&', NOP, NOP, 0x33, 0x00,
-/* sc=09 */ '8', '*', NOP, NOP, '8', '*', NOP, NOP, 0x33, 0x00,
-/* sc=0a */ '9', '(', NOP, NOP, '9', '(', NOP, NOP, 0x33, 0x00,
-/* sc=0b */ '0', ')', NOP, NOP, '0', ')', NOP, NOP, 0x33, 0x00,
-/* sc=0c */ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, 0x00, 0x00,
-/* sc=0d */ '=', '+', NOP, NOP, '=', '+', NOP, NOP, 0x33, 0x00,
-/* sc=0e */ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00,
-/* sc=0f */ 0x09, BTAB, NOP, NOP, 0x09, BTAB, NOP, NOP, 0x77, 0x00,
-/* sc=10 */ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, 0x00, 0x01,
-/* sc=11 */ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, 0x00, 0x01,
-/* sc=12 */ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, 0x00, 0x01,
-/* sc=13 */ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, 0x00, 0x01,
-/* sc=14 */ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, 0x00, 0x01,
-/* sc=15 */ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, 0x00, 0x01,
-/* sc=16 */ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, 0x00, 0x01,
-/* sc=17 */ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, 0x00, 0x01,
-/* sc=18 */ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, 0x00, 0x01,
-/* sc=19 */ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, 0x00, 0x01,
-/* sc=1a */ '[', '{', 0x1B, 0x1B, '[', '{', 0x1B, 0x1B, 0x00, 0x00,
-/* sc=1b */ ']', '}', 0x1D, 0x1D, ']', '}', 0x1D, 0x1D, 0x00, 0x00,
-/* sc=1c */ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, 0x00, 0x00,
-/* sc=1d */ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, 0xFF, 0x00,
-/* sc=1e */ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, 0x00, 0x01,
-/* sc=1f */ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, 0x00, 0x01,
-/* sc=20 */ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, 0x00, 0x01,
-/* sc=21 */ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, 0x00, 0x01,
-/* sc=22 */ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, 0x00, 0x01,
-/* sc=23 */ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, 0x00, 0x01,
-/* sc=24 */ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, 0x00, 0x01,
-/* sc=25 */ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, 0x00, 0x01,
-/* sc=26 */ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, 0x00, 0x01,
-/* sc=27 */ ';', ':', NOP, NOP, ';', ':', NOP, NOP, 0x33, 0x00,
-/* sc=28 */ '\'', '"', NOP, NOP, '\'', '"', NOP, NOP, 0x33, 0x00,
-/* sc=29 */ '`', '~', NOP, NOP, '`', '~', NOP, NOP, 0x33, 0x00,
-/* sc=2a */ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, 0xFF, 0x00,
-/* sc=2b */ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, 0x00, 0x00,
-/* sc=2c */ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, 0x00, 0x01,
-/* sc=2d */ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, 0x00, 0x01,
-/* sc=2e */ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, 0x00, 0x01,
-/* sc=2f */ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, 0x00, 0x01,
-/* sc=30 */ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, 0x00, 0x01,
-/* sc=31 */ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, 0x00, 0x01,
-/* sc=32 */ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, 0x00, 0x01,
-/* sc=33 */ ',', '<', NOP, NOP, ',', '<', NOP, NOP, 0x33, 0x00,
-/* sc=34 */ '.', '>', NOP, NOP, '.', '>', NOP, NOP, 0x33, 0x00,
-/* sc=35 */ '/', '?', NOP, NOP, '/', '?', NOP, NOP, 0x33, 0x00,
-/* sc=36 */ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, 0xFF, 0x00,
-/* sc=37 */ '*', '*', 0x0A, 0x0A, '*', '*', 0x0A, 0x0A, 0x33, 0x00,
-/* sc=38 */ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, 0xFF, 0x00,
-/* sc=39 */ ' ', ' ', 0x00, ' ', ' ', ' ', SUSP, ' ', 0x02, 0x00,
-/* sc=3a */ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, 0xFF, 0x00,
-/* sc=3b */ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11), 0xFF, 0x00,
-/* sc=3c */ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12), 0xFF, 0x00,
-/* sc=3d */ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13), 0xFF, 0x00,
-/* sc=3e */ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14), 0xFF, 0x00,
-/* sc=3f */ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15), 0xFF, 0x00,
-/* sc=40 */ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16), 0xFF, 0x00,
-/* sc=41 */ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7), 0xFF, 0x00,
-/* sc=42 */ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8), 0xFF, 0x00,
-/* sc=43 */ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9), 0xFF, 0x00,
-/* sc=44 */ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10), 0xFF, 0x00,
-/* sc=45 */ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, 0xFF, 0x00,
-/* sc=46 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=47 */ F(49), '7', '7', '7', '7', '7', '7', '7', 0x80, 0x02,
-/* sc=48 */ F(50), '8', '8', '8', '8', '8', '8', '8', 0x80, 0x02,
-/* sc=49 */ F(51), '9', '9', '9', '9', '9', '9', '9', 0x80, 0x02,
-/* sc=4a */ F(52), '-', '-', '-', '-', '-', '-', '-', 0x80, 0x02,
-/* sc=4b */ F(53), '4', '4', '4', '4', '4', '4', '4', 0x80, 0x02,
-/* sc=4c */ F(54), '5', '5', '5', '5', '5', '5', '5', 0x80, 0x02,
-/* sc=4d */ F(55), '6', '6', '6', '6', '6', '6', '6', 0x80, 0x02,
-/* sc=4e */ F(56), '+', '+', '+', '+', '+', '+', '+', 0x80, 0x02,
-/* sc=4f */ F(57), '1', '1', '1', '1', '1', '1', '1', 0x80, 0x02,
-/* sc=50 */ F(58), '2', '2', '2', '2', '2', '2', '2', 0x80, 0x02,
-/* sc=51 */ F(59), '3', '3', '3', '3', '3', '3', '3', 0x80, 0x02,
-/* sc=52 */ F(60), '0', '0', '0', '0', '0', '0', '0', 0x80, 0x02,
-/* sc=53 */ 0x7F, '.', '.', '.', '.', '.', RBT, RBT, 0x03, 0x02,
-/* sc=54 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=55 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=56 */ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=57 */ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11), 0xFF, 0x00,
-/* sc=58 */ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12), 0xFF, 0x00,
-/* sc=59 */ 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00,
-/* sc=5a */ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, 0xFF, 0x00,
-/* sc=5b */ '/', '/', '/', '/', '/', '/', '/', '/', 0x00, 0x00,
-/* sc=5c */ NEXT, NOP, DBG, NOP, NOP, NOP, NOP, NOP, 0xFF, 0x00,
-/* sc=5d */ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, 0xFF, 0x00,
-/* sc=5e */ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49), 0xFF, 0x00,
-/* sc=5f */ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50), 0xFF, 0x00,
-/* sc=60 */ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51), 0xFF, 0x00,
-/* sc=61 */ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53), 0xFF, 0x00,
-/* sc=62 */ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55), 0xFF, 0x00,
-/* sc=63 */ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57), 0xFF, 0x00,
-/* sc=64 */ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58), 0xFF, 0x00,
-/* sc=65 */ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59), 0xFF, 0x00,
-/* sc=66 */ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60), 0xFF, 0x00,
-/* sc=67 */ F(61), F(61), F(61), F(61), F(61), F(61), RBT, F(61), 0xFF, 0x00,
-/* sc=68 */ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, 0xFF, 0x00,
-/* sc=69 */ F(62), F(62), F(62), F(62), F(62), F(62), F(62), F(62), 0xFF, 0x00,
-/* sc=6a */ F(63), F(63), F(63), F(63), F(63), F(63), F(63), F(63), 0xFF, 0x00,
-/* sc=6b */ F(64), F(64), F(64), F(64), F(64), F(64), F(64), F(64), 0xFF, 0x00,
-};
-
-#endif
-
-static fkeytab_t fkey_tab[96] = {
-/* 01-04 */ {"\033[M", 3}, {"\033[N", 3}, {"\033[O", 3}, {"\033[P", 3},
-/* 05-08 */ {"\033[Q", 3}, {"\033[R", 3}, {"\033[S", 3}, {"\033[T", 3},
-/* 09-12 */ {"\033[U", 3}, {"\033[V", 3}, {"\033[W", 3}, {"\033[X", 3},
-/* 13-16 */ {"\033[Y", 3}, {"\033[Z", 3}, {"\033[a", 3}, {"\033[b", 3},
-/* 17-20 */ {"\033[c", 3}, {"\033[d", 3}, {"\033[e", 3}, {"\033[f", 3},
-/* 21-24 */ {"\033[g", 3}, {"\033[h", 3}, {"\033[i", 3}, {"\033[j", 3},
-/* 25-28 */ {"\033[k", 3}, {"\033[l", 3}, {"\033[m", 3}, {"\033[n", 3},
-/* 29-32 */ {"\033[o", 3}, {"\033[p", 3}, {"\033[q", 3}, {"\033[r", 3},
-/* 33-36 */ {"\033[s", 3}, {"\033[t", 3}, {"\033[u", 3}, {"\033[v", 3},
-/* 37-40 */ {"\033[w", 3}, {"\033[x", 3}, {"\033[y", 3}, {"\033[z", 3},
-/* 41-44 */ {"\033[@", 3}, {"\033[[", 3}, {"\033[\\",3}, {"\033[]", 3},
-/* 45-48 */ {"\033[^", 3}, {"\033[_", 3}, {"\033[`", 3}, {"\033[{", 3},
-/* 49-52 */ {"\033[H", 3}, {"\033[A", 3}, {"\033[I", 3}, {"-" , 1},
-/* 53-56 */ {"\033[D", 3}, {"\033[E", 3}, {"\033[C", 3}, {"+" , 1},
-/* 57-60 */ {"\033[F", 3}, {"\033[B", 3}, {"\033[G", 3}, {"\033[L", 3},
-/* 61-64 */ {"\177", 1}, {"\033[J", 3}, {"\033[~", 3}, {"\033[}", 3},
-/* 65-68 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
-/* 69-72 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
-/* 73-76 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
-/* 77-80 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
-/* 81-84 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
-/* 85-88 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
-/* 89-92 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} ,
-/* 93-96 */ {"", 0} , {"", 0} , {"", 0} , {"", 0}
-};
diff --git a/sys/pc98/pc98/matcd/TODO b/sys/pc98/pc98/matcd/TODO
deleted file mode 100644
index 138f470..0000000
--- a/sys/pc98/pc98/matcd/TODO
+++ /dev/null
@@ -1,42 +0,0 @@
-Things to do for the matcd driver 4-Jul-95
-
-1. Someone wants to switch all drivers from disklabel and
- its assorted mechanisms over to disk slicing and its mechanisms,
- but I was unable to find any useful documentation on how to
- implement the changes for a read-only, single-partition,
- removable (ie, partition can change size) device.
- So this will have to wait until after 2.1.
-
-2. Support for reading R-W subcodes while playing audio. This would be
- useful if you have any CD+G or CD+MIDI discs, but the demand for this
- is pretty low, unless you like Karaoke. Someone will also have to
- write a CD+G viewer for X. The code for the driver to add this is
- pretty minor but there aren't any precedents on how to handle the
- data transfer to the application.
-
-3. Support for reading the ISBN and UPC labels. The ioctl structures
- for these appear to be defined but no other driver seems to do this.
-
-4. Multi-session support. There are two forms of this; what
- Philips defined and what Kodak uses. This will be quite
- complicated and will probably require changes in the filesystem
- layer. The drive support for Kodak multi-session is known to work.
-
-5. Multiple data tracks. My vision here was to add an ioctl
- that caused a track offset to be inserted into block requests,
- effectively shifting the base to the specified track. Very
- easy to add but not a big deal since I have only two discs
- in my collection that have multiple data tracks and I mastered
- one of them.
-
-6. A curses-based CD-Player app (ie, not X). I will probably do this
- mainly for its value as a debugging tool. It was pretty annoying
- not finding a single application that actually issued all the
- defined ioctls, let alone any new ones.
-
-If you feel the urge to work on one or more of these remaining items,
-please contact the author first at bsdmail@nemesis.lonestar.org
-to make sure the work hasn't already been done or started.
-
- Frank Durda IV
-
diff --git a/sys/pc98/pc98/matcd/creative.h b/sys/pc98/pc98/matcd/creative.h
deleted file mode 100644
index 72a12ad..0000000
--- a/sys/pc98/pc98/matcd/creative.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*creative.h-------------------------------------------------------------------
-
- Matsushita(Panasonic) / Creative CD-ROM Driver (matcd)
- Authored by Frank Durda IV
-
- Copyright 1994, 1995 Frank Durda IV. All rights reserved.
- "FDIV" is a trademark of Frank Durda IV.
-
-
- 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 positioned at the very beginning of this file without
- modification, all copyright strings, all related programming
- codes that display the copyright strings, this list of
- conditions and the following disclaimer.
- 2. Redistributions in binary form must contain all copyright strings
- and related programming code that display the copyright strings.
- 3. 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.
- 4. All advertising materials mentioning features or use of this
- software must display the following acknowledgement:
- "The Matsushita/Panasonic CD-ROM driver was developed
- by Frank Durda IV for use with "FreeBSD" and similar
- operating systems."
- "Similar operating systems" includes mainly non-profit oriented
- systems for research and education, including but not restricted
- to "NetBSD", "386BSD", and "Mach" (by CMU). The wording of the
- acknowledgement (in electronic form or printed text) may not be
- changed without permission from the author.
- 5. Absolutely no warranty of function, fitness or purpose is made
- by the author Frank Durda IV.
- 6. Neither the name of the author nor the name "FreeBSD" may
- be used to endorse or promote products derived from this software
- without specific prior written permission.
- (The author can be reached at bsdmail@nemesis.lonestar.org)
- 7. The product containing this software must meet all of these
- conditions even if it is unsupported, not a complete system
- and/or does not contain compiled code.
- 8. These conditions will be in force for the full life of the
- copyright.
- 9. If all the above conditions are met, modifications to other
- parts of this file may be freely made, although any person
- or persons making changes do not receive the right to add their
- name or names to the copyright strings and notices in this
- software. Persons making changes are encouraged to insert edit
- history in matcd.c and to put your name and details of the
- change there.
- 10. You must have prior written permission from the author to
- deviate from these terms.
-
- Vendors who produce product(s) containing this code are encouraged
- (but not required) to provide copies of the finished product(s) to
- the author and to correspond with the author about development
- activity relating to this code. Donations of development hardware
- and/or software are also welcome. (This is one of the faster ways
- to get a driver developed for a device.)
-
- THIS SOFTWARE IS PROVIDED BY THE DEVELOPER(S) ``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 DEVELOPER(S) 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.
-
-
------No changes are allowed above this line------------------------------------
-
-See matcd.c for Edit History
-
- These are the I/O port mapping offsets and bit assignments used
- by Creative Labs in their implementation of the host interface for
- the Matsushita CD-ROM drive. These may be different in the adapter
- cards (including sound cards) made by other vendors.
- It is unknown if the Creative interface is based on a reference design
- provided by Matsushita (other interface vendors would similar or
- identical if this was the case).
-
- The drive is actually capable of some things that the Creative
- interface doesn't implement, such as DMA and interrupts.
-
- See matcd.h for defines related to the Matsushita drive itself.
-*/
-
-
-/* Creative Labs (and compatible) I/O port mapping offsets
-*/
-
-#define NUMPORTS 4 /*Four ports are decoded by the i/f*/
-
-#define CMD 0 /*Write - commands*/
-#define DATA 0 /*Read - data/status from drive*/
-#ifdef PC98
-#define PHASE 0x100 /*Write - switch between data/status*/
-#define STATUS 0x100 /*Read - bus status */
-#define RESET 0x200 /*Write - reset all attached drives*/
-#define ALTDATA 0x200 /*<20>Read - data on non Creative bds.*/
-#define SELECT 0x300 /*Write - drive select*/
-#else /* !PC98 */
-#define PHASE 1 /*Write - switch between data/status*/
-#define STATUS 1 /*Read - bus status*/
-#define RESET 2 /*Write - reset all attached drives*/
- /*Any value written will reset*/
-#define ALTDATA 2 /*<20>Read - data on non Creative bds.*/
-#define SELECT 3 /*Write - drive select*/
-#endif /*PC98*/
-
-/* Creative PHASE port bit assignments
-*/
-
-#define PHASENA 1 /*Access data bytes instead of status*/
-
-
-/* Creative STATUS port register bits
-*/
-
-#define DTEN 2 /*When low, in data xfer phase*/
-#define STEN 4 /*When low, in status phase*/
-#define TEST 1 /*Function is unknown*/
-
-
-/* Creative drive SELECT port bit assignments
- Note that in the Creative interface, DS0==Bit 1 and
- DS1==Bit 0 (DS is Drive Select).
-*/
-
-#define CRDRIVE0 0x00
-#define CRDRIVE1 0x02
-#define CRDRIVE2 0x01
-#define CRDRIVE3 0x03
-
-/*End of creative.h*/
-
-
diff --git a/sys/pc98/pc98/matcd/matcd.c b/sys/pc98/pc98/matcd/matcd.c
deleted file mode 100644
index a8b1eb4..0000000
--- a/sys/pc98/pc98/matcd/matcd.c
+++ /dev/null
@@ -1,2670 +0,0 @@
-/*matcd.c--------------------------------------------------------------------
-
- Matsushita(Panasonic) / Creative CD-ROM Driver (matcd)
- Authored by Frank Durda IV
-
- Copyright 1994, 1995 Frank Durda IV. All rights reserved.
- "FDIV" is a trademark of Frank Durda IV.
-
-
- 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 positioned at the very beginning of this file without
- modification, all copyright strings, all related programming
- codes that display the copyright strings, this list of
- conditions and the following disclaimer.
- 2. Redistributions in binary form must contain all copyright strings
- and related programming code that display the copyright strings.
- 3. 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.
- 4. All advertising materials mentioning features or use of this
- software must display the following acknowledgement:
- "The Matsushita/Panasonic CD-ROM driver was developed
- by Frank Durda IV for use with "FreeBSD" and similar
- operating systems."
- "Similar operating systems" includes mainly non-profit oriented
- systems for research and education, including but not restricted
- to "NetBSD", "386BSD", and "Mach" (by CMU). The wording of the
- acknowledgement (in electronic form or printed text) may not be
- changed without permission from the author.
- 5. Absolutely no warranty of function, fitness or purpose is made
- by the author Frank Durda IV.
- 6. Neither the name of the author nor the name "FreeBSD" may
- be used to endorse or promote products derived from this software
- without specific prior written permission.
- (The author can be reached at bsdmail@nemesis.lonestar.org)
- 7. The product containing this software must meet all of these
- conditions even if it is unsupported, not a complete system
- and/or does not contain compiled code.
- 8. These conditions will be in force for the full life of the
- copyright.
- 9. If all the above conditions are met, modifications to other
- parts of this file may be freely made, although any person
- or persons making changes do not receive the right to add their
- name or names to the copyright strings and notices in this
- software. Persons making changes are encouraged to insert edit
- history in matcd.c and to put your name and details of the
- change there.
- 10. You must have prior written permission from the author to
- deviate from these terms.
-
- Vendors who produce product(s) containing this code are encouraged
- (but not required) to provide copies of the finished product(s) to
- the author and to correspond with the author about development
- activity relating to this code. Donations of development hardware
- and/or software are also welcome. (This is one of the faster ways
- to get a driver developed for a device.)
-
- THIS SOFTWARE IS PROVIDED BY THE DEVELOPER(S) ``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 DEVELOPER(S) 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.
-
-
------------------------------------------------------------------------------
-Dedicated to: My family, my Grandfather,
- and Max, my Golden Retriever
-
-Thanks to: Jordon Hubbard (jkh) for getting me ramped-up to 2.x system
- quickly enough to make the 2.1 release. He put up with
- plenty of silly questions and might get the post of
- ambassador some day.
-
-and The people who donated equipment and other material to make
- development of this driver possible. Donations and
- sponsors for projects are appreciated.
-
-
------No changes are allowed above this line------------------------------------
-
-Edit History - (should be in sync with any source control log entries)
-
- Never seen one of these before? Ok, here is how it works.
- Every time you change the code, you increment the edit number,
- that number over there in the <%d> and in the (%d) in the
- version string. You never set this number lower than it is.
- Near, or preferably on lines that change, insert the edit
- number. If there is a number there already, you can replace it
- with a newer one. This makes searches for code changes very fast.
-
- In the edit history, start with the edit number, and a good
- description of what changes were made. Then follow it with
- the date, your name and an EMAIL address where you can be reached.
-
- Please follow this practice; it helps leave understandable code in
- your wake.
-
- FYI, you have major and minor release codes. Major releases numbered
- 1 thru n. Major feature additions should get a new major release
- number. Minor releases start with a null and then letters
- A thru Z. So 3A(456) is Major release 3, Minor release 1,
- Edit 456 (in Microsoft-ese that would be 03.01.456), and 5(731)
- is Major release 5, Minor release 0, Edit 731. Typically only the
- author will change the major and minor release codes in small
- projects.
-
- EDIT edit Edit HISTORY history History
-
-<1> This initial version is to get basic filesystem I/O working
- using the SoundBlaster 16 interface. The stand-alone adapter
- card doesn't work yet.
- December 1994 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<2> Corrections to resolve a race condition when multiple drives
- on the same controller was active. Fixed drive 1 & 2 swap
- problem. See selectdrive().
- 21-Jan-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<3> Added automatic probing and support for all Creative Labs sound
- cards with the Creative/Panasonic interface and the stand-alone
- interface adapters. See AUTOHUNT and FULLCONFIG conditionals
- for more information.
- 21-Jan-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<4> Rebundled debug conditionals.
- 14-Feb-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<5> Changes needed to work on FreeBSD 2.1. Also added draincmd
- since some conditions cause the drive to produce surprise data.
- See setmode and draincmd
- 19-Feb-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<6> Got rid of some redundant error code by creating chk_error().
- Also built a nice generic bus-lock function.
- 20-Feb-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<7> Improved comments, general structuring.
- Fixed a problem with disc eject not working if LOCKDRIVE was set.
- Apparently the drive will reject an EJECT command if the drive
- is LOCKED.
- 21-Feb-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-Edit number code marking begins here - earlier edits were during development.
-
-<8> Final device name selected and actually made to compile under
- >2.0. For newer systems, it is "matcd", for older it is "mat".
- 24-Feb-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<9> Added some additional disk-related ioctl functions that didn't
- make it into earlier versions.
- 26-Feb-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<10> Updated some conditionals so the code will compile under
- 1.1.5.1, although this is not the supported platform.
- Also found that some other devices probe code was changing the
- settings for the port 0x302 debug board, so added code to set it
- to a sane state before we use it.
- 26-Feb-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<11> The Copyright and Use statement has been replaced in all files
- with a new version.
- 1-Mar-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<12> Added ioctls having to do with audio volume, routing and playback
- speed. Also added some code I think is for dynamic loading.
- 12-Mar-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<13> Added ioctls to return TOC headers and entries.
- 19-Mar-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<14> More ioctls to finish out general audio support and some clean-up.
- Also fixed a bug in open where CD label information would not
- always be cleared after a disc change.
-
- Added a check to block attempts to resume audio if already playing.
- The resulting sound is a cross between Kryten and Max Headroom.
- But, if you *want* this "feature", enable #define KRYTEN
- in options.h.
-
- So it is not BSD-ish enough, eh? What, too many comments? :-)
- 21-Mar-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<15> LOCKDRIVE has been modified so that a new series of minor
- numbers are created. When these are opened, the selected
- drive will have its door locked and the device must be completely
- closed to unlock the media. The EJECT ioctl will be refused
- when the drive is locked this way. This is useful for
- servers and other places where the media needs to remain in the
- drive. Bit 7 of the minor number controls locking.
-
- As of this edit, the code compiles with no warnings with -Wall set.
- 22-Mar-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<16> Added a new check in the probe code that looks for the drive
- interface being in an idle state after issuing a reset. If this
- isn't the case, then the device at this location isn't a
- Matsushita CD-ROM drive. This will prevent hangs in draincmd later.
- Added the tray close ioctl. This required modifications to open
- to allow the character devices to be "partially" opened so that
- the close ioctl could be issued when the open would otherwise fail.
- Close also delays slightly after completing because the drive
- doesn't update its disc and media status instantly.
- Also created the capability ioctl that lets an application find out
- up front what things a drive can do.
- Fixed a global spelling error.
- Changed matcddriver structure to simply say "matcd". The original
- string "matcd interface " broke the kernel -c boot mechanism.
- Updated the #includes in response to a complaint in first release.
- Updated and tested conditionals so that driver will still compile
- under FreeBSD 1.1.5.1 as well as 2.0 and early 2.1.
- 4-Apr-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<17> The function matcd_toc_entries which is executed in response to
- the CDIOREADTOCENTRYS ioctl didn't cope with programs that only
- requested part of the TOC. This change is based on code submitted
- by Doug Robson (dfr@render.com).
- (This change was introduced out of order and exists in FreeBSD
- 2.0.5 without the version stamp being updated. I.N.M.F.)
- 1-Jun-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<18> While working on the TEAC CD-ROM driver (teaccd) that is reusing
- chunks of code from this driver, I discovered several functions,
- arrays and other things that should have been declared 'static'.
- These changes are necessary if the TEAC CD-ROM driver is to be
- present at the same time as matcd.
- Also fixed the residual buss vs bus symbols and strings.
- There are no functional code changes in this edit.
- 2-May-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<19> Creative has changed the Status port slightly in their
- sound boards based on the Vibra-16 (and probably the Vibra-16S)
- chipset. This change masks some unused bits that were formally
- on all the time and are doing different things in this design.
- The changes are transparent to all other supported boards.
- 20-Jun-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<20> Code was added to detect non-Creative (SoundBlaster) host
- interfaces, and the driver will switch to code compatible with the
- detected host interface. This should add support for MediaVision,
- IBM, Reveal, and other compatible adapters with split
- data/status-ports. This code allows a mix of SoundBlaster (Type 0)
- and non-SoundBlaster (Type 1) boards in the same system with no
- special configuration.
-
- I also updated the attach code to display the interface type and
- changed the host interface probe messages to reflect the "c" for
- controller in controller-specific messages as the existing messages
- were confusing when a second card was in place . The kernel -c
- tables have been updated accordingly, so you now have a matcdc%d
- controller to change settings on.
- 24-Jun-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<21> Added interface handling code in two of those "this should not
- happen" routines, draincmd and get_stat. Since these routines are
- called by functions during probing that may not know what type
- interface is out there, the code assumes that a given adapter is
- both a type 0 and a type 1 adapter at the same time. Plus,
- this code gets executed once in a very long time so the cost of
- assuming both host adapter types is not significant.
- 4-Jul-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<22> Four external interface prototypes were altered by someone else.
- I believe these changes are for making GCC and/or the linker shut-up
- when building some other part of the system since matcd already
- compiles -Wall with no warnings...
- 8-Sep-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<23> This change implements the ioctls for preventing media removal
- and allowing media removal.
- Currently, these calls will work according to the following rules:
- No "l" devs opened Any "l" dev open
- CDALLOW accepted always rejected always
- CDPREVENT accepted always accepted always
-
- One refinement might be to allow CDALLOW/CDPREVENT to always
- work if UID 0 issued the ioctl, but that will wait for later.
-
- I also made a change to the information that the toc_entry code
- returns so that xcdplayer won't malfunction. (It would not play
- the last track on a non-mixed mode audio CD.) Unlike cdplayer,
- xcdplayer asks for track information one track at a time, and
- calls for information on the lead-out track by its official
- number (0xaa), rather than referring to the "after last" (n+1) track
- as cdplayer does. Anyway, this change should make both players
- happy.
- 16-Sep-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<24> In Edit 15 when the extra devs were created for selective locking,
- the door locking was broken if a non-locking dev on the drive is
- closed. The problem was caused by not tracking locked devs and
- non-locking devs as being different partitions. The change is to
- simply use the locking dev bit to flag a set of shadow partitions
- when it comes to lock operations. All other operations treat the
- locked and unlocked partitions as being identical.
- 18-Sep-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<25> During work on Edit 23, I noted that on slow and very busy systems,
- sometimes the driver would go to sleep forever. The problem appears
- to have been a race condition caused by doing separate timeout/sleep
- calls without using SPL first. The change here is to use tsleep
- which provides the equivalent of timeout/sleep timeout/tsleep if the
- last paremeter is tsleep is set to the time value that would have been
- given to timeout.
- I also fixed some duplicate location strings in the tsleep calls.
- 24-Sep-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<26> Moved a function declaration that generated two warnings with
- the FULLCONFIG/FULLDRIVER conditionals disabled.
- Updated the igot function so that it correctly reports limited
- functions when a sub-set driver is compiled.
- Eliminated FULLCONFIG conditional and now set controller counts
- based on the NMATCD #define produced by the config process.
- Also, disable the audio-related ioctls based on the BOOTMFS
- conditional to help make the boot floppy kernel smaller.
- 18-Oct-95 Frank Durda IV bsdmail@nemesis.lonestar.org
-
-<27> Incorporated changes needed to move the cdevsw and bdevsw
- entries into the drivers (including this one). Also
- include a quick first pass cut at DEVFS suppport.
-
----------------------------------------------------------------------------*/
-
-/*Match this format: Version_dc(d)__dd-mmm-yy */
-static char MATCDVERSION[]="Version 1(26) 18-Oct-95";
-
-/* The following strings may not be changed*/
-static char MATCDCOPYRIGHT[] = "Matsushita CD-ROM driver, Copr. 1994,1995 Frank Durda IV";
-/* The proceeding strings may not be changed*/
-
-/* $Id: matcd.c,v 1.4 1996/09/03 10:24:08 asami Exp $ */
-
-/*---------------------------------------------------------------------------
- Include declarations
----------------------------------------------------------------------------*/
-
-#include "matcd.h"
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <sys/buf.h>
-#include <sys/dkbad.h>
-#include <sys/cdio.h>
-#include <sys/disklabel.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/proc.h>
-
-#ifdef PC98
-#include "pc98/pc98/matcd/options.h" /*Conditional compile options
- and probe port hints*/
-#include "i386/isa/matcd/matcddrv.h" /*Drive-related defs & strings*/
-#include "pc98/pc98/matcd/creative.h" /*Host interface related defs*/
-#else
-#include "i386/isa/matcd/options.h" /*Conditional compile options
- and probe port hints*/
-#include "i386/isa/matcd/matcddrv.h" /*Drive-related defs & strings*/
-#include "i386/isa/matcd/creative.h" /*Host interface related defs*/
-#endif
-
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#ifdef DEVFS
-#include <sys/devfsext.h>
-#endif /*DEVFS*/
-
-/*---------------------------------------------------------------------------
- Defines and structures
----------------------------------------------------------------------------*/
-
-#define DRIVESPERC 4 /*This is a constant*/
-#define TOTALDRIVES NUMCTRLRS*DRIVESPERC /*Max possible drives*/
-
-#define TICKRES 10 /*Our coarse timer resolution*/
-#define ISABUSKHZ 8330 /*Number of IN/OUT ISA/sec*/
-#define MAXTRKS 101 /*Maximum possible tracks*/
-
-#define RAW_DEVICE 46 /*<16>Dev number for raw device*/
-
-
-#define MATCDBLK 2048 /*Standard block size*/
-#define MATCDRBLK 2352 /*Raw and/or DA block size*/
-#define MATCD_RETRYS 5 /*Number of retries for read ops*/
-#define MATCD_READ_1 0x80 /*Read state machine defines*/
-#define MATCD_READ_2 0x90 /*Read state machine defines*/
-
-struct matcd_volinfo {
- unsigned char type; /*00 CD-DA or CD-ROM
- 10 CD-I
- 20 XA */
- unsigned char trk_low; /*Normally 1*/
- unsigned char trk_high; /*Highest track number*/
- unsigned char vol_msf[3]; /*Size of disc in min/sec/frame*/
-};
-
-
-struct matcd_mbx {
- short controller;
- short ldrive;
- short partition;
- short port;
- short iftype; /*<20>Host interface type*/
- short retry;
- short nblk;
- int sz;
- u_long skip;
- struct buf *bp;
- int p_offset;
- short count;
-};
-
-static struct matcd_data {
- short drivemode; /*Last state drive was set to*/
- short flags;
- short status; /*Last audio-related function*/
- int blksize;
- u_long disksize;
- short iobase;
- short iftype; /*<20>Host interface type*/
- struct disklabel dlabel;
- unsigned int partflags[MAXPARTITIONS];
- unsigned int openflags;
- struct matcd_volinfo volinfo;
- struct matcd_mbx mbx;
- u_char patch[2]; /*<12>Last known audio routing*/
- u_char volume[2]; /*<12>Last known volume setting*/
-#ifdef DEVFS
- void *ra_devfs_token; /* handle for devfs entry */
- void *rc_devfs_token;
- void *a_devfs_token;
- void *c_devfs_token;
- void *rla_devfs_token;
- void *rlc_devfs_token;
- void *la_devfs_token;
- void *lc_devfs_token;
-#endif DEVFS
-} matcd_data[TOTALDRIVES];
-
-
-/* Bit equates for matcd_data.flags*/
-
-#define MATCDINIT 0x0001 /*Probe ran on host adapter*/
-#define MATCDLABEL 0x0004 /*Valid TOC exists*/
-#define MATCDLOCK 0x0008 /*<15>Drive door is locked*/
-#define MATCDWARN 0x0020 /*Have reported an open disc change*/
-
-
-/* Bit equates for matcd_data.partflags*/
-
-#define MATCDOPEN 0x0001
-#define MATCDREADRAW 0x0002
-
-
-/* Error classes returned by chk_error()*/
-
-#define ERR_RETRY 1 /*A retry might recover this*/
-#define ERR_INIT 2 /*A retry certainly will get this*/
-#define ERR_FATAL 3 /*This cannot be recovered from*/
-
-
-static struct buf_queue_head request_head[NUMCTRLRS]; /*<18>A queue for each host interface*/
-static int nextcontroller=0; /*<18>Number of interface units found*/
-static int drivepresent=0; /*<18>Don't change this - see license*/
-static int iftype; /*<20>Probe/Attach i.f. type relay*/
-
-static unsigned char if_state[4]={0,0,0,0}; /*<18>State of the host I/F and bus*/
-
-/* Flags in the if_state array
-*/
-
-#define BUSBUSY 0x01 /*<18>Bus is already busy*/
-
-
-struct matcd_read2 {
- unsigned char start_msf[3];
- unsigned char end_msf[3];
-};
-
-
-/* This mystery structure is supposed to make dynamic driver
- loading possible.
-*/
-
-
-/*---------------------------------------------------------------------------
- These macros take apart the minor number and yield the
- partition, drive on controller, and controller.
- This must match the settings in /dev/MAKEDEV.
----------------------------------------------------------------------------*/
-
-#define matcd_partition(dev) ((minor(dev)) & 0x07)
-#define matcd_ldrive(dev) (((minor(dev)) & 0x78) >> 3)
-#define matcd_cdrive(dev) (((minor(dev)) & 0x18) >> 3)
-#define matcd_controller(dev) (((minor(dev)) & 0x60) >> 5)
-#ifdef LOCKDRIVE
-#define matcd_lockable(dev) (((minor(dev)) & 0x80) >> 5)
-#endif /*LOCKDRIVE*/
-
-
-
-
-/*---------------------------------------------------------------------------
- Entry points and other connections to/from kernel - see also conf.h
- --- not any more :)
----------------------------------------------------------------------------*/
-
-static int matcd_probe(struct isa_device *dev);
-static int matcd_attach(struct isa_device *dev);
-struct isa_driver matcddriver={matcd_probe, matcd_attach,
- "matcdc"};
-
-
-static d_open_t matcdopen;
-static d_close_t matcdclose;
-static d_ioctl_t matcdioctl;
-static d_psize_t matcdsize;
-static d_strategy_t matcdstrategy;
-
-#define CDEV_MAJOR 46
-#define BDEV_MAJOR 17
-
-static struct cdevsw matcd_cdevsw;
-static struct bdevsw matcd_bdevsw =
- { matcdopen, matcdclose, matcdstrategy, matcdioctl, /*17*/
- nodump, matcdsize, 0, "matcd",
- &matcd_cdevsw, -1 };
-
-/*---------------------------------------------------------------------------
- Internal function declarations
----------------------------------------------------------------------------*/
-
-static void matcd_drvinit(void *unused);
-static void matcd_start(int controller);
-static void zero_cmd(char *);
-static void matcd_pread(int port, int count, unsigned char * data);
-static int matcd_fastcmd(int port,int ldrive,int cdrive,
- unsigned char * cp);
-static void matcd_slowcmd(int port,int ldrive,int cdrive,
- unsigned char * cp);
-static void matcd_blockread(int state);
-static void selectdrive(int port,int drive);
-static void doreset(int port,int cdrive);
-static int doprobe(int port,int cdrive);
-static void lockbus(int controller, int ldrive);
-static void unlockbus(int controller, int ldrive);
-static int matcd_volinfo(int ldrive);
-static void draincmd(int port,int cdrive,int ldrive);
-static int get_error(int port, int ldrive, int cdrive);
-static int chk_error(int errnum);
-static int msf_to_blk(unsigned char * cd);
-#ifdef FULLDRIVER
-static int matcd_playtracks(int ldrive, int cdrive, int controller,
- struct ioc_play_track *pt);
-static int matcd_playmsf(int ldrive, int cdrive, int controller,
- struct ioc_play_msf *pt);
-static int matcd_pause(int ldrive, int cdrive, int controller,
- int action);
-static int matcd_stop(int ldrive, int cdrive, int controller);
-static int matcd_level(int ldrive, int cdrive, int controller,
- struct ioc_vol * volume, int action);
-static int matcd_patch(int ldrive, int cdrive, int controller,
- struct ioc_patch * routing);
-static int matcd_route(int ldrive, int cdrive, int controller,
- int command);
-static int matcd_pitch(int ldrive, int cdrive, int controller,
- struct ioc_pitch * speed);
-#endif /*FULLDRIVER*/
-static int matcd_toc_header(int ldrive, int cdrive, int controller,
- struct ioc_toc_header * toc);
-static int matcd_toc_entries(int ldrive, int cdrive,
- int controller,
- struct ioc_read_toc_entry *ioc_entry);
-static int matcd_read_subq(int ldrive, int cdrive, int controller,
- struct ioc_read_subchannel * sqp);
-static int matcd_igot(struct ioc_capability * sqp);
-static int waitforit(int timelimit, int state, int port,
- char * where);
-static int get_stat(int port, int ldrive);
-static int media_chk(struct matcd_data *cd,int errnum,
- int ldrive,int test);
-static int matcd_eject(int ldrive, int cdrive, int controller);
-static int matcd_doorclose(int ldrive, int cdrive, int controller);
-static int matcd_dlock(int ldrive, int cdrive,
- int controller, int action);
-static int docmd(char * cmd, int ldrive, int cdrive,
- int controller, int port);
-
-
-/*---------------------------------------------------------------------------
- matcdopen - Open the device
-
- This routine actually gets called every time anybody opens
- any partition on a drive. But the first call is the one that
- does all the work.
-
-<15> If LOCKDRIVE is enabled, additional minor number devices allow
-<15> the drive to be locked while being accessed.
----------------------------------------------------------------------------*/
-int matcdopen(dev_t dev, int flags, int fmt,
- struct proc *p)
-{
- int cdrive,ldrive,partition,controller,lock;
- struct matcd_data *cd;
- int i,z,port;
- unsigned char cmd[MAXCMDSIZ];
-
- ldrive=matcd_ldrive(dev);
- cdrive=matcd_cdrive(dev);
- partition=matcd_partition(dev);
- controller=matcd_controller(dev);
- lock=matcd_lockable(dev);
- cd= &matcd_data[ldrive];
- port=cd->iobase; /*and port#*/
-
- if (ldrive >= TOTALDRIVES) return(ENXIO);
-
-
-#ifdef DEBUGOPEN
- printf("matcd%d: Open: dev %x partition %x controller %x flags %x cdrive %x\n",
- ldrive,(int)dev,partition,controller,cd->flags,
- matcd_cdrive(dev));
-#endif /*DEBUGOPEN*/
-
- if (!(cd->flags & MATCDINIT)) { /*Did probe find this drive*/
- return(ENXIO);
- }
-
- if (!(cd->flags & MATCDLABEL) &&
- cd->openflags) { /*Has drive completely closed?*/
- return(ENXIO); /*No, all partitions must close*/
- }
-
-
-/* Now, test to see if the media is ready
-*/
-
- lockbus(controller,ldrive);
- zero_cmd(cmd);
- cmd[0]=NOP; /*Test drive*/
- matcd_slowcmd(port,ldrive,cdrive,cmd);
- i=waitforit(10*TICKRES,DTEN,port,"matopen");
- z=get_stat(port,ldrive); /*Read status byte*/
-#ifdef DEBUGOPEN
- printf("matcd%d Result of NOP is %x %x\n",ldrive,i,z);
-#endif /*DEBUGOPEN*/
- if ((z & MATCD_ST_DSKIN)==0) { /*Is there a disc in the drive?*/
-#ifdef DEBUGOPEN
- printf("matcd%d: No Disc in open\n",ldrive);
-#endif /*DEBUGOPEN*/
- unlockbus(controller, ldrive); /*Release bus lock*/
- cd->flags &= ~MATCDLABEL; /*<16>Mark label as invalid*/
- if (major(dev)==RAW_DEVICE) { /*<16>Is the char device?*/
- return(0); /*<16>Allow Semi open*/
- }
- else {
- return(ENXIO); /*<16>Normally blow off*/
- }
- }
- if (z & MATCD_ST_ERROR) { /*Was there an error*/
- i=get_error(port,ldrive,cdrive);/*Find out what it was*/
-#ifdef DEBUGOPEN
- printf("matcd%d NOP Error was %x\n",ldrive,i);
-#endif /*DEBUGOPEN*/
- if (cd->openflags) { /*Any parts open?*/
- if (media_chk(cd,i,ldrive,0)) { /*<14>Was it a disc chg?*/
-#ifdef DEBUGOPEN
- printf("matcd%d: Disc change detected i %x z %x\n",
- ldrive,i,z);
-#endif /*DEBUGOPEN*/
- unlockbus(controller, ldrive); /*Release bus lock*/
- return(ENOTTY);
- }
-
- } else {
- media_chk(cd,i,ldrive,1);/*<14>Was it a disc chg?*/
- /*<14>Clear volume info*/
- }
- }
- unlockbus(controller, ldrive); /*Release bus lock*/
-
-/* Here we fill in the disklabel structure although most is
- hardcoded.
-*/
-
- if ((cd->flags & MATCDLABEL)==0) {
- bzero(&cd->dlabel,sizeof(struct disklabel));
-
-
-/* Now we query the drive for the actual size of the media.
- This is where we find out of there is any media or if the
- media isn't a Mode 1 or Mode 2/XA disc.
- See version information about Mode 2/XA support.
-*/
- lockbus(controller,ldrive);
- i=matcdsize(dev);
- unlockbus(controller, ldrive); /*Release bus lock*/
-#ifdef DEBUGOPEN
- printf("matcd%d: Bus unlocked in open\n",ldrive);
-#endif /*DEBUGOPEN*/
- if (i < 0) {
- printf("matcd%d: Could not read the disc size\n",ldrive);
- return(ENXIO);
- } /*matcdsize filled in rest of dlabel*/
-
-/* Based on the results, fill in the variable entries in the disklabel
-*/
- cd->dlabel.d_secsize=cd->blksize;
- cd->dlabel.d_ncylinders=(cd->disksize/100)+1;
- cd->dlabel.d_secperunit=cd->disksize;
- cd->dlabel.d_partitions[0].p_size=cd->disksize;
- cd->dlabel.d_checksum=dkcksum(&cd->dlabel);
-
-
-/* Now fill in the hardcoded section
-*/
- /*123456789012345678*/
- strncpy(cd->dlabel.d_typename,"Matsushita CDR ",16);
- strncpy(cd->dlabel.d_packname,"(c) 1994, fdiv ",16);
- cd->dlabel.d_magic=DISKMAGIC;
- cd->dlabel.d_magic2=DISKMAGIC;
- cd->dlabel.d_nsectors=100;
- cd->dlabel.d_secpercyl=100;
- cd->dlabel.d_ntracks=1;
- cd->dlabel.d_interleave=1;
- cd->dlabel.d_rpm=300;
- cd->dlabel.d_npartitions=1; /*See note below*/
- cd->dlabel.d_partitions[0].p_offset=0;
- cd->dlabel.d_partitions[0].p_fstype=9;
- cd->dlabel.d_flags=D_REMOVABLE;
-
-/* I originally considered allowing the partition match tracks or
- sessions on the media, but since you are allowed up to 99
- tracks in the RedBook world, this would not fit in with the
- BSD fixed partition count scheme. So ioctls will be used to shift
- the track to be accessed into partition 1.
-*/
-
- cd->flags |= MATCDLABEL; /*Mark drive as having TOC*/
- }
-
-#ifdef DEBUGOPEN
- printf("matcd%d open2: partition=%d disksize=%d blksize=%x flags=%x\n",
- ldrive,partition,(int)cd->disksize,cd->blksize,cd->flags);
-#endif /*DEBUGOPEN*/
-
-#ifdef LOCKDRIVE
- if (cd->openflags==0 && lock) {
- zero_cmd(cmd);
- cmd[0]=LOCK; /*Lock drive*/
- cmd[1]=1;
- docmd(cmd,ldrive,cdrive,controller,port);/*<15>Issue cmd*/
- cd->flags |= MATCDLOCK; /*<15>Drive is now locked*/
- }
-#endif /*LOCKDRIVE*/
- cd->openflags |= (1<<(partition+lock));/*<24>Mark partition open*/
-
- if (partition==RAW_PART ||
- (partition < cd->dlabel.d_npartitions &&
- cd->dlabel.d_partitions[partition].p_fstype != FS_UNUSED)) {
- cd->partflags[partition] |= MATCDOPEN;
- if (partition == RAW_PART) {
- cd->partflags[partition] |= MATCDREADRAW;
- }
-#ifdef DEBUGOPEN
- printf("matcd%d: Open is complete - openflags %x\n",
- ldrive,cd->openflags);
-#endif /*DEBUGOPEN*/
- return(0);
- }
-#ifdef DEBUGOPEN
- printf("matcd%d: Open FAILED\n",ldrive);
-#endif /*DEBUGOPEN*/
- return(ENXIO);
-}
-
-
-/*---------------------------------------------------------------------------
- matcdclose - Close the device
-
- Close may not do much other than clear some driver settings.
- Note that audio playback will continue.
-
-<15> If you define LOCKDRIVE, and the drive has been opened using
-<15> one of the locking minor numbers, code in close will unlock
-<15> the drive.
----------------------------------------------------------------------------*/
-
-int matcdclose(dev_t dev, int flags, int fmt,
- struct proc *p)
-{
- int ldrive,cdrive,port,partition,controller,lock;
- struct matcd_data *cd;
-#ifdef LOCKDRIVE
- unsigned char cmd[MAXCMDSIZ];
-#endif /*LOCKDRIVE*/
-
- ldrive=matcd_ldrive(dev);
- cdrive=matcd_cdrive(dev);
- lock=matcd_lockable(dev);
- cd=matcd_data+ldrive;
- port=cd->iobase; /*and port#*/
-
- if (ldrive >= TOTALDRIVES)
- return(ENXIO);
-
- partition = matcd_partition(dev);
- controller=matcd_controller(dev);
-#ifdef DEBUGOPEN
- printf("matcd%d: Close partition=%d flags %x openflags %x partflags %x\n",
- ldrive,partition,cd->flags,cd->openflags,
- cd->partflags[partition]);
-#endif /*DEBUGOPEN*/
-
- if (!(cd->flags & MATCDINIT))
- return(ENXIO);
-
- cd->partflags[partition] &= ~(MATCDOPEN|MATCDREADRAW);
- cd->openflags &= ~(1<<(partition+lock));
- if (cd->openflags==0) { /*<24>Really last close?*/
-#ifdef LOCKDRIVE
- if (cd->flags & MATCDLOCK) { /*<24>Was drive locked?*/
- zero_cmd(cmd); /*Yes, so unlock it*/
- cmd[0]=LOCK; /*Unlock drive*/
- docmd(cmd,ldrive,cdrive,controller,port);
- }
-#endif /*LOCKDRIVE*/
- cd->flags &= ~(MATCDWARN|MATCDLOCK);
- /*<15>Clear warning flag*/
- }
- return(0);
-}
-
-
-/*---------------------------------------------------------------------------
- matcdstrategy - Accepts I/O requests from kernel for processing
-
- This routine accepts a read request block pointer (historically
- but somewhat inaccurately called *bp for buffer pointer).
- Various sanity checks are performed on the request.
- When we are happy with the request and the state of the device,
- the request is added to the queue of requests for the interface
- that the drive is connected to. We support multiple interfaces
- so there are multiple queues. Once the request is added, we
- call the matcd_start routine to start the device in case it isn't
- doing something already. All I/O including ioctl requests
- rely on the current request starting the next one before exiting.
----------------------------------------------------------------------------*/
-
-void matcdstrategy(struct buf *bp)
-{
- struct matcd_data *cd;
- int s;
- int ldrive,controller;
-
- ldrive=matcd_ldrive(bp->b_dev);
- controller=matcd_controller(bp->b_dev);
- cd= &matcd_data[ldrive];
-
-#ifdef DEBUGIO
- printf("matcd%d: Strategy: buf=0x%lx, block#=%ld bcount=%ld\n",
- ldrive,(unsigned long)bp,bp->b_blkno,bp->b_bcount);
-#endif /*DEBUGIO*/
-
-
- if (ldrive >= TOTALDRIVES || bp->b_blkno < 0) {
- printf("matcd%d: Bogus parameters received - kernel may be corrupted\n",ldrive);
- bp->b_error=EINVAL;
- goto bad;
- }
-
- if (!(cd->flags & MATCDLABEL)) {
- bp->b_error = EIO;
- goto bad;
- }
-
- if (!(bp->b_flags & B_READ)) {
- bp->b_error = EROFS;
- goto bad;
- }
-
- if (bp->b_bcount==0) /*Request is zero-length - all done*/
- goto done;
-
- if (matcd_partition(bp->b_dev) != RAW_PART) {
- if (bounds_check_with_label(bp,&cd->dlabel,1) <= 0) {
- goto done;
- }
- } else {
- bp->b_pblkno=bp->b_blkno;
- bp->b_resid=0;
- }
-
- s=splbio(); /*Make sure we don't get intr'ed*/
- tqdisksort(&request_head[controller], bp);/*Add new request (bp) to queue (dp
- and sort the requests in a way that
- may not be ideal for CD-ROM media*/
-
-
- matcd_start(controller); /*Ok, with our newly sorted queue,
- see if we can start an I/O operation
- right now*/
- splx(s); /*Return priorities to normal*/
- return; /*All done*/
-
-bad: bp->b_flags |= B_ERROR; /*Request bad in some way*/
-done: bp->b_resid = bp->b_bcount; /*Show amount of data un read*/
- biodone(bp); /*Signal we have done all we plan to*/
- return;
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_start - Pull a request from the queue and consider doing it.
----------------------------------------------------------------------------*/
-
-static void matcd_start(int controller)
-{
- struct matcd_data *cd;
- struct buf *bp;
- struct partition *p;
- int part,ldrive;
-
- bp = TAILQ_FIRST(&request_head[controller]);
- if (bp == NULL) { /*Nothing on read queue to do?*/
- wakeup((caddr_t)&matcd_data->status); /*Wakeup any blocked*/
- return; /* opens, ioctls, etc*/
- }
-
- ldrive=matcd_ldrive(bp->b_dev); /*Get logical drive#*/
- cd=&matcd_data[ldrive]; /*Get pointer to data for this drive*/
-#ifdef DEBUGIO
- printf("matcd%d: In start controller %d\n",ldrive,controller);
-#endif /*DEBUGIO*/
-
- if (if_state[controller] & BUSBUSY) {
-#ifdef DEBUGIO
- printf("matcd%d: Dropping thread in start, controller %d\n",
- ldrive,controller);
-#endif /*DEBUGIO*/
- return;
- }
-
-/* Ok, the controller is idle (not necessarily the drive) and so
- get the command to do and issue it
-*/
-
- TAILQ_REMOVE(&request_head[controller], bp, b_act);
-
- part=matcd_partition(bp->b_dev);
- p=cd->dlabel.d_partitions + part;
-
- if_state[controller] |= BUSBUSY;/*<18>Mark bus as busy*/
- cd->mbx.ldrive=ldrive; /*Save current logical drive*/
- cd->mbx.controller=controller; /*and controller*/
- cd->mbx.partition=part; /*and partition (2048 vs 2532)*/
- cd->mbx.port=cd->iobase; /*and port#*/
- cd->mbx.iftype=cd->iftype; /*<20>interface type*/
- cd->mbx.retry=MATCD_RETRYS; /*and the retry count*/
- cd->mbx.bp=bp; /*and the bp*/
- cd->mbx.p_offset=p->p_offset; /*and where the data will go*/
- matcd_blockread(MATCD_READ_1+ldrive); /*Actually start the read*/
- return; /*Dropping thread. matcd_blockread
- must have scheduled a timeout or
- we will go to sleep forever*/
-}
-
-
-/*---------------------------------------------------------------------------
- matcdioctl - Process things that aren't block reads
-
- In this driver, ioctls are used mainly to change
- the mode the drive is running in, play audio and other
- things that don't fit into the block read scheme of things.
----------------------------------------------------------------------------*/
-
-int matcdioctl(dev_t dev, int command, caddr_t addr,
- int flags, struct proc *p)
-{
- struct matcd_data *cd;
- int ldrive,cdrive,partition;
- int port, controller;
-#ifdef DEBUGIOCTL
- int i;
-#endif /*DEBUGIOCTL*/
-
- ldrive=matcd_ldrive(dev);
- cdrive=matcd_cdrive(dev);
- partition=matcd_partition(dev);
- controller=ldrive>>2;
- cd = &matcd_data[ldrive];
- port=cd->iobase;
-
-#ifdef DEBUGIOCTL
- printf("matcd%d: ioctl %x cdrive %x parms ",ldrive,command,cdrive);
- for (i=0;i<10;i++) {
- printf("%02x ",(unsigned int)addr[i]);
- }
- printf(" flags %x\n",cd->flags);
-#endif /*DEBUGIOCTL*/
-
- if (command==CDIOCCLOSE) /*<16>Allow close if door open*/
- return(matcd_doorclose(ldrive, cdrive, controller));
-
- if (!(cd->flags & MATCDLABEL)) /*Did we read TOC OK?*/
- return(EIO); /*<16>then drive really isn't ready*/
-
- switch(command) {
- case DIOCSBAD:
- return(EINVAL);
-
- case DIOCGDINFO:
- *(struct disklabel *) addr = cd->dlabel;
- return(0);
-
- case DIOCGPART:
- ((struct partinfo *) addr)->disklab=&cd->dlabel;
- ((struct partinfo *) addr)->part=
- &cd->dlabel.d_partitions[matcd_partition(dev)];
- return(0);
-
- case DIOCWDINFO:
- case DIOCSDINFO:
- if ((flags & FWRITE) == 0) {
- return(EBADF);
- }
- else {
- return setdisklabel(&cd->dlabel,
- (struct disklabel *) addr, 0);
- }
- case DIOCWLABEL:
- return(EBADF);
-
- case CDIOCEJECT:
- return(matcd_eject(ldrive, cdrive, controller));
-
- case CDIOCALLOW:
- return(matcd_dlock(ldrive, cdrive,
- controller,0));
-
- case CDIOCPREVENT:
- return(matcd_dlock(ldrive, cdrive,
- controller, MATCDLOCK));
-
-#ifdef FULLDRIVER
- case CDIOCPLAYTRACKS:
- return(matcd_playtracks(ldrive, cdrive, controller,
- (struct ioc_play_track *) addr));
-
- case CDIOCPLAYMSF:
- return(matcd_playmsf(ldrive, cdrive, controller,
- (struct ioc_play_msf *) addr));
-
- case CDIOCRESUME:
- return(matcd_pause(ldrive, cdrive, controller,RESUME));
-
- case CDIOCPAUSE:
- return(matcd_pause(ldrive, cdrive, controller,0));
-
- case CDIOCSTOP:
- return(matcd_stop(ldrive, cdrive, controller));
-
- case CDIOCGETVOL:
- case CDIOCSETVOL:
- return(matcd_level(ldrive, cdrive, controller,
- (struct ioc_vol *) addr, command));
-
- case CDIOCSETMONO: /*<12>This drive can't do mono*/
- return(EINVAL); /*<12>but it looks like it should*/
-
- /*<12>SRC OUT SRC OUT*/
- case CDIOCSETSTEREO: /*<12>0 -> L 1 -> R*/
- case CDIOCSETMUTE: /*<12>0 -> NULL 1 -> NULL*/
- case CDIOCSETLEFT: /*<12>0 -> L&R 1 -> NULL*/
- case CDIOCSETRIGHT: /*<12>0 -> NULL 1 -> L&R*/
- /*<12>Adjust audio routing*/
- return(matcd_route(ldrive, cdrive, controller,
- command));
-
- case CDIOCSETPATCH: /*<12>Allow precise routing*/
- return(matcd_patch(ldrive, cdrive, controller,
- (struct ioc_patch *) addr));
-
- case CDIOCPITCH: /*<12>Adjust playback speed*/
- return(matcd_pitch(ldrive, cdrive, controller,
- (struct ioc_pitch *) addr));
-
- case CDIOCSTART: /*<12>Only reason this isn't*/
- return(EINVAL); /*<12>implemented is I can't find out*/
- /*<12>what it should do!*/
-#endif /*FULLDRIVER*/
-
- case CDIOREADTOCHEADER:
- return(matcd_toc_header(ldrive, cdrive, controller,
- (struct ioc_toc_header *) addr));
-
- case CDIOREADTOCENTRYS:
- return(matcd_toc_entries(ldrive, cdrive, controller,
- (struct ioc_read_toc_entry *) addr));
-
- case CDIOCREADSUBCHANNEL:
- return(matcd_read_subq(ldrive, cdrive, controller,
- (struct ioc_read_subchannel *) addr));
-
- case CDIOCCAPABILITY: /*<16>Request drive/driver capability*/
- return(matcd_igot((struct ioc_capability *) addr));
-
- case CDIOCRESET: /*<12>There is no way to hard reset*/
- return(EINVAL); /*<12>just one drive*/
-
- default:
- return(ENOTTY);
- }
-}
-
-/*---------------------------------------------------------------------------
- matcdsize - Reports how many blocks exist on the disc.
----------------------------------------------------------------------------*/
-
-int matcdsize(dev_t dev)
-{
- int size,blksize;
- int ldrive,part;
- struct matcd_data *cd;
-
- ldrive=matcd_ldrive(dev);
- part=matcd_partition(dev);
- if (part==RAW_PART)
- blksize=MATCDRBLK; /*2352*/
- else
- blksize=MATCDBLK; /*2048*/
-
- cd = &matcd_data[ldrive];
-
- if (matcd_volinfo(ldrive) >= 0) {
- cd->blksize=blksize;
- size=msf_to_blk((char * )&cd->volinfo.vol_msf);
-
- cd->disksize=size*(blksize/DEV_BSIZE);
-#ifdef DEBUGOPEN
- printf("matcd%d: Media size %d\n",ldrive,size);
-#endif /*DEBUGOPEN*/
- return(0);
- }
- return(-1);
-}
-
-/*---------------------------------------------------------------------------
- matcd_probe - Search for host interface/adapters
-
- The probe routine hunts for the first drive on the interface since
- there is no way to locate just the adapter. It also resets the
- entire drive chain while it is there. matcd_attach() takes care of
- the rest of the initialization.
-
- The probe routine can be compiled two ways. In AUTOHUNT mode,
- the kernel config file can say "port?" and we will check all ports
- listed in the port_hint array (see above).
-
- Without AUTOHUNT set, the config file must list a specific port
- address to check.
-
- Note that specifying the explicit addresses makes boot-up a lot
- faster.
-
- The probe will locate Panasonic/Creative interface on the following
- Creative adapter boards:
- #1330A Sound Blaster PRO
- #1730 Sound Blaster 16
- #1740 Sound Blaster 16 (cost reduced)
- #2230 Sound Blaster 16 (cost reduced)
- #2770 Sound Blaster 16 Value (cost reduced)
- #1810 omniCD upgrade kit adapter card (stand-alone CD)
- #3100 PhoneBlaster SB16 + Sierra 14.4K modem combo
- Creative releases a newer and cheaper-to-make Sound Blaster
- board every few months, so by the original release date of this
- software, there are probably 8 different board models called
- Sound Blaster 16. These include "Vibra", "Value", etc.
-
- Please report additional part numbers and board descriptions
- and new port numbers that work to the author.
-
----------------------------------------------------------------------------*/
-
-static int
-matcd_probe(struct isa_device *dev)
-{
- int i,cdrive;
- unsigned char y;
- int port = dev->id_iobase; /*Take port hint from config file*/
-
- cdrive=nextcontroller; /*Controller defined by pass for now*/
- if (nextcontroller==NUMCTRLRS) {
- printf("matcdc%d: - Too many interfaces specified in config\n",
- nextcontroller);
- return(0);
- }
- if (nextcontroller==0) { /*Very first time to be called*/
- for (i=0; i<TOTALDRIVES; i++) {
- matcd_data[i].drivemode=MODE_UNKNOWN;
- matcd_data[i].flags=0;
- }
- }
-
- i=nextcontroller*DRIVESPERC; /*Precompute controller offset*/
- for (y=0; y<DRIVESPERC; y++) {
- matcd_data[i+y].flags=0;
- }
-
-#ifdef DEBUGPROBE
- printf("matcdc%d: In probe i %d y %d port %x\n",
- nextcontroller,i,y,port);
-#endif /*DEBUGPROBE*/
-#ifdef AUTOHUNT
-#ifdef DEBUGPROBE
- printf("matcd%d: size of port_hints %d\n",
- nextcontroller,sizeof(port_hints));
-#endif /*DEBUGPROBE*/
- if (port==-1) {
- for(i=0;i<(sizeof(port_hints)/sizeof(short));i++) {
- port=port_hints[i];
-#ifdef DEBUGPROBE
- printf("matcdc%d: Port hint %x\n",nextcontroller,port);
-#endif /*DEBUGPROBE*/
- if (port==-1) {
- dev->id_iobase=-1; /*Put port ? back*/
- return(0);/*Nothing left to try*/
- }
- if (port!=0) { /*Untested port found*/
- dev->id_iobase=port;
- port_hints[i]=0;/*Don't use that port again*/
- if (doprobe(port,cdrive)==0) return(NUMPORTS);
- }
- }
- dev->id_iobase=-1; /*Put port ? back as it was*/
- return(0); /*Interface not found*/
-
- } else { /*Config specified a port*/
- i=0; /*so eliminate it from the hint list*/
- for(i=0;;i++) { /*or we might try to assign it again*/
- if (port_hints[i]== -1) break; /*End of list*/
- if (port_hints[i]==port) {
- port_hints[i]=0; /*Clear duplicate*/
- break;
- }
- }
- if (doprobe(port,cdrive)==0) return(NUMPORTS);
- else return(0);
- }
-#else /*AUTOHUNT*/
- if (port==-1) {
- printf("matcdc%d: AUTOHUNT disabled but port? specified in config\n",
- nextcontroller);
- return(0);
- }
- if (doprobe(port,cdrive)==0) return(NUMPORTS);
- else return(0);
-#endif /*AUTOHUNT*/
-}
-
-/*---------------------------------------------------------------------------
- doprobe - Common probe code that actually checks the ports we
- have decided to test.
-
-<20> Edit 20 changes adds code to determine if the host interface
- is one that behaves like the Creative SoundBlaster cards,
- or whether the host interface like those used by some boards
- made by Media Vision and a version known as Lasermate.
----------------------------------------------------------------------------*/
-
-int doprobe(int port,int cdrive)
-{
- unsigned char cmd[MAXCMDSIZ];
- int i;
-
-#ifdef RESETONBOOT
- doreset(port,cdrive); /*Reset what might be our device*/
-#endif /*RESETONBOOT*/
- outb(port+PHASE,0); /*<16>Guarantee status phase*/
- zero_cmd(cmd);
- cmd[0]=NOP; /*A reasonably harmless command.
- This command will fail after
- power-up or after reset. That's OK*/
-#ifdef RESETONBOOT
- if (((inb(port+STATUS) & (DTEN|STEN)) != (DTEN|STEN)) ||
- (inb(port+DATA) != 0xff))
- return(-1); /*<20>Something detected but it isn't
- the device we wanted*/
-#endif /*RESETONBOOT*/
- if (matcd_fastcmd(port,0,0,cmd)==0) {/*Issue command*/
- outb(port+PHASE,1); /*<20>Switch to Creative Data phase*/
- i=inb(port+CMD); /*<20>Read a byte in data phase*/
- outb(port+PHASE,0); /*<20>Switch to Creative Status phase*/
- if ((inb(port+STATUS) & (DTEN|STEN))
- == (DTEN|STEN)) { /*<20>Drive went idle*/
- iftype=1; /*<20>It is not a Creative interface.*/
- } else { /*<20>Status byte still available*/
- iftype=0;
- inb(port+CMD); /*<20>Read status byte*/
- }
-#ifdef DEBUGPROBE
- printf("matcdc%d: Probe found something\n",nextcontroller);
-#endif /*DEBUGPROBE*/
-/*------Don't change anything below this line - see license -----------------*/
- if (drivepresent==0) { /*Don't change*/
- printf("matcd - Matsushita (Panasonic) CD-ROM Driver by FDIV, %s\n",
- /*Don't change*/
- MATCDVERSION); /*Don't change*/
- drivepresent++; /*Don't change*/
- if (drivepresent==0) /*Don't change - make LINT happy*/
- printf("%s\n",MATCDCOPYRIGHT); /*Don't change*/
- } /*Don't change*/
-/*------Don't change anything above this line - see license -----------------*/
- return(0); /*Drive 0 detected*/
- }
-#ifdef DEBUGPROBE
- printf("matcdc%d: Probe DID NOT find something\n",nextcontroller);
-#endif /*DEBUGPROBE*/
- return(1);
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_attach - Locates drives on the adapters that were located.
- If we got here, we located an interface and at least one
- drive. Now we figure out how many drives are under that
- interface. The Panasonic interface is too simple to call
- it a controller, but in the existing PDP model, that is
- what it would be.
----------------------------------------------------------------------------*/
-
-static int
-matcd_attach(struct isa_device *dev)
-{
- int i;
- unsigned int z,cdrive;
- unsigned char cmd[MAXCMDSIZ];
- unsigned char data[12];
- struct matcd_data *cd;
- int port = dev->id_iobase; /*Take port ID selected in probe()*/
-
-#ifdef DEBUGPROBE
- printf("matcdc: Attach dev %x id_unit %d\n",
- (unsigned int)dev,dev->id_unit);
-#endif /*DEBUGPROBE*/
- printf("matcdc%d Host interface type %d\n",
- nextcontroller,iftype);
- TAILQ_INIT(&request_head[nextcontroller]);
- for (cdrive=0; cdrive<4; cdrive++) { /*We're hunting drives...*/
- zero_cmd(cmd);
- cmd[0]=NOP; /*A reasonably harmless command.
- This command will fail after
- power-up or after reset. It's OK*/
- i=cdrive+(DRIVESPERC*nextcontroller);
- if (matcd_fastcmd(port,i,cdrive,cmd)==0) { /*Issue cmd*/
- z=get_stat(port,cdrive);/*Read status byte*/
- if ((z & MATCD_ST_ERROR)) { /*If there was an error,
- we must ask for error info
- or subsequent cmds fail*/
- zero_cmd(cmd);
- cmd[0]=READERROR; /*Inquire*/
- matcd_fastcmd(port,i,cdrive,cmd);
- matcd_pread(port,8,data);/*Read data returned*/
- z=get_stat(port,i);/*Read status byte*/
-#ifdef DEBUGPROBE
- printf("matcd%d: Status byte %x ",i,z);
-#endif /*DEBUGPROBE*/
- }
- zero_cmd(cmd);
- cmd[0]=READID; /*Get drive ID*/
- matcd_fastcmd(port,i,cdrive,cmd);
- matcd_pread(port,10,data);/*Read Drive Parm*/
- get_stat(port,i); /*Read and toss status byte*/
- data[10]=0; /*Build ASCIZ string*/
- printf("matcd%d: [%s] ",i,data);
- cd=&matcd_data[i];
- cd->flags |= MATCDINIT;
- cd->iobase=dev->id_iobase;
- cd->iftype=iftype;
- cd->openflags=0;
- cd->volume[0]=cd->volume[1]=DEFVOL;
- /*<12>Match volume drive resets to*/
- cd->patch[0]=0x01; /*<12>Channel 0 to Left*/
- cd->patch[1]=0x02; /*<12>Channel 1 to Right*/
- cd->status=CD_AS_NO_STATUS;
- for (i=0; i<MAXPARTITIONS; i++) {
- cd->partflags[i]=0;
- }
-#ifdef DEVFS
- cd->ra_devfs_token = devfs_add_devswf(&matcd_cdevsw,
- dkmakeminor(i, 0, 0), DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640, "rmatcd%da", i);
- cd->rc_devfs_token = devfs_add_devswf(&matcd_cdevsw,
- dkmakeminor(i, 0, RAW_PART), DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640, "rmatcd%dc", i);
- cd->a_devfs_token = devfs_add_devswf(&matcd_bdevsw,
- dkmakeminor(i, 0, 0), DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640, "matcd%da", i);
- cd->c_devfs_token = devfs_add_devswf(&matcd_bdevsw,
- dkmakeminor(i, 0, RAW_PART), DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640, "matcd%dc", i);
- cd->rla_devfs_token = devfs_add_devswf(&matcd_cdevsw,
- 0x80 | dkmakeminor(i, 0, 0), DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640, "rmatcd%dla", i);
- cd->rlc_devfs_token = devfs_add_devswf(&matcd_cdevsw,
- 0x80 | dkmakeminor(i, 0, RAW_PART), DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640, "rmatcd%dc", i);
- cd->la_devfs_token = devfs_add_devswf(&matcd_bdevsw,
- 0x80 | dkmakeminor(i, 0, 0), DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640, "matcd%dla", i);
- cd->lc_devfs_token = devfs_add_devswf(&matcd_bdevsw,
- 0x80 | dkmakeminor(i, 0, RAW_PART), DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640, "matcd%dlc", i);
-#endif
- }
- }
- nextcontroller++; /*Bump ctlr assign to next number*/
- printf("\n"); /*End line of drive reports*/
-
- return(1);
-}
-
-
-/*---------------------------------------------------------------------------
- zero_cmd - Initialize command buffer
----------------------------------------------------------------------------*/
-
-void zero_cmd(char * lcmd)
-{
- int i;
-
- for (i=0; i<MAXCMDSIZ; lcmd[i++]=0);
- return;
-}
-
-
-/*---------------------------------------------------------------------------
- doreset - Resets all the drives connected to a interface
----------------------------------------------------------------------------*/
-
-void doreset(int port,int cdrive)
-{
- register int i,z;
- outb(port+RESET,0); /*Reset what might be our device*/
- /*Although this ensures a known
- state, it does close the drive
- door (if open) and aborts any
- audio playback in progress. */
- for (i=0;i<(125*ISABUSKHZ);i++){/*DELAY 500msec minimum. Worst
- case is door open and none or
- unreadable media */
- z=inb(port+CMD); /*This makes the loop run at a
- known speed. This value is ok
- for 8.33MHz bus*/
- }
- for (i=0;i<4;i++) {
- matcd_data[(cdrive*4)+i].drivemode=MODE_UNKNOWN;
- }
- return;
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_fastcmd - Send a command to a drive
-
- This routine executed commands that return instantly (or reasonably
- quick), such as RESET, NOP, READ ERROR, etc. The only difference
- between it and handling for slower commands, is the slower commands
- will invoke a timeout/sleep if they don't get an instant response.
-
- Fastcmd is mainly used in probe(), attach() and error related
- functions. Every attempt should be made to NOT use this
- function for any command that might be executed when the system
- is up.
----------------------------------------------------------------------------*/
-
-int matcd_fastcmd(int port,int ldrive,int cdrive,unsigned char * cp)
-{
- unsigned int i;
- unsigned char z;
- int level;
-#ifdef DEBUGCMD
- unsigned char *cx;
-#endif /*DEBUGCMD*/
-
-
-
- draincmd(port,cdrive,ldrive); /*Make sure bus is really idle*/
-#ifdef DEBUGCMD
- cx=cp;
- printf("matcd%d: Fast Send port %x sel %d command %x %x %x %x %x %x %x\n",
- ldrive,port,cdrive,cx[0],cx[1],cx[2],cx[3],cx[4],cx[5],cx[6]);
-#endif /*DEBUGCMD*/
- selectdrive(port,cdrive); /*Enable the desired target drive*/
- level=splhigh(); /*----------------------------------------*/
- for (i=0; i<7; i++) { /*The seven bytes of the command*/
- outb(port+CMD,*cp++); /*must be sent within 10msec or*/
- } /*the drive will ignore the cmd*/
- splx(level); /*------------------------------------------------*/
-
-/* Now we wait a maximum of 240msec for a response.
- Only in a few rare cases does it take this long.
- If it is longer, the command should probably be slept on
- rather than increasing the timing value
-*/
-
- for (i=0; i<(60*ISABUSKHZ); i++) {
- z = (inb(port+STATUS)) & (DTEN|STEN);
- if (z != (DTEN|STEN)) break;
- }
-
-/* We are now either in a data or status phase, OR we timed-out.*/
-
- if (z == (DTEN|STEN)) {
-#ifdef DEBUGCMD
- printf("matcd%d: Command time-out\n",ldrive);
-#endif /*DEBUGCMD*/
- return(-1);
- }
- if (z != DTEN) {
- return(1);
- }
- return(0);
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_slowcmd - Issue a command to the drive
-
- This routine is for commands that might take a long time, such
- as a read or seek. The caller must determine if the command
- completes instantly or schedule a poll later on.
----------------------------------------------------------------------------*/
-
-void matcd_slowcmd(int port,int ldrive,int cdrive,unsigned char * cp)
-{
- unsigned int i;
- int level,size;
-#ifdef DEBUGCMD
- unsigned char *cx;
-#endif /*DEBUGCMD*/
-
-
- draincmd(port,cdrive,ldrive); /*Make sure bus is really idle*/
-
-#ifdef DEBUGCMD
- cx=cp;
- printf("matcd%d: Slow Send port %x sel %d command %x %x %x %x %x %x %x\n",
- ldrive,port,cdrive,cx[0],cx[1],cx[2],cx[3],cx[4],cx[5],cx[6]);
-#endif /*DEBUGCMD*/
- selectdrive(port,cdrive); /*Enable the desired target drive*/
- if (*cp==ABORT) size=1;
- else size=7;
- level=splhigh(); /*----------------------------------------*/
- for (i=0; i<size; i++) { /*The seven bytes of the command*/
- outb(port+CMD,*cp++); /*must be sent within 10msec or*/
- } /*the drive will ignore the cmd*/
- splx(level); /*------------------------------------------------*/
- return;
-}
-
-
-/*---------------------------------------------------------------------------
- draincmd - Makes certain the bus is idle and throws away
- any residual data from the drive if there is any.
- Called as preface to most commands.
- Added in Edit 5.
-
- This was added because switching drive modes causes
- the drive to emit buffers that were meant to be sent
- to the D-to-A to be sent to the host. See setmode.
----------------------------------------------------------------------------*/
-void draincmd(int port,int cdrive,int ldrive)
-{
- int i,z;
-
- i=inb(port+STATUS);
- if ((i & (DTEN|STEN)) == (DTEN|STEN)) return;
-
- printf("matcd%d: in draincmd: bus not idle %x - trying to fix\n",
- ldrive,inb(port+STATUS));
- if ((i & (DTEN|STEN)) == STEN) {
-#ifdef DEBUGCMD
- printf("matcd%d: Data present READING - ",ldrive);
-#endif /*DEBUGCMD*/
- i=0;
- outb(port+PHASE,1); /*<16>Enable data read*/
- while ((inb(port+STATUS) & (DTEN|STEN)) == STEN) {
- inb(port+DATA); /*<21>Ok for Creative*/
- inb(port+ALTDATA); /*<21>Ok for others*/
- i++;
- }
- outb(port+PHASE,0);
-#ifdef DEBUGCMD
- printf("%d bytes read\n",i);
-#endif /*DEBUGCMD*/
- }
-#ifdef DEBUGCMD
- printf("matcd%d: Now read status: ",ldrive);
-#endif /*DEBUGCMD*/
- i=get_stat(port,ldrive); /*Read status byte*/
- z=inb(port+STATUS); /*Read bus status*/
-#ifdef DEBUGCMD
- printf("Data byte %x and status is now %x\n",i,z);
-#endif /*DEBUGCMD*/
- if ((z & (DTEN|STEN)) != (DTEN|STEN)) {
- printf("matcd%d: Bus not idle %x - resetting\n",
- cdrive,inb(port+STATUS));
- doreset(port,cdrive);
- }
- return;
-}
-
-
-/*---------------------------------------------------------------------------
- selectdrive - Swaps drive select bits
-
- On Creative SB/SB16/stand-alone adapters, possibly to make them
- hard to reverse engineer, the drive select signals are swapped.
----------------------------------------------------------------------------*/
-
-void selectdrive(int port,int drive)
-{
- switch(drive) {
- case 0: /*0x00 -> 0x00*/
- outb(port+SELECT,CRDRIVE0);
- break;
- case 1: /*0x01 -> 0x02*/
- outb(port+SELECT,CRDRIVE1);
- break;
- case 2: /*0x02 -> 0x01*/
- outb(port+SELECT,CRDRIVE2);
- break;
- case 3: /*0x03 -> 0x03*/
- outb(port+SELECT,CRDRIVE3);
- break;
- }
- return;
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_pread - Read small blocks of control data from a drive
----------------------------------------------------------------------------*/
-
-void matcd_pread(int port, int count, unsigned char * data)
-{
- int i;
-
- for (i=0; i<count; i++) {
- *data++ = inb(port+CMD);
- }
- return;
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_setmode - Configures disc to run in the desired data mode
-
- This routine assumes the drive is already idle.
-
-NOTE - Undocumented action of hardware: If you change (or reaffirm) data
- modes with MODESELECT + BLOCKPARAM immediately after a command was
- issued that aborted a DA play operation, the drive will unexpectedly
- return 2532 bytes of data in a data phase on the first or second
- subsequent command.
-
- Original Symptom: drive will refuse to go idle after reading data
- and status expected for a command. State mechanics for this are
- not fully understood.
----------------------------------------------------------------------------*/
-
-static int
-matcd_setmode(int ldrive, int mode)
-{
- struct matcd_data *cd;
- int retries;
- int i,port,cdrive;
- unsigned char cmd[MAXCMDSIZ];
-
- cd = matcd_data + ldrive;
- retries=3;
- cdrive=ldrive&0x03;
- port=cd->iobase;
- if (cd->drivemode==mode) {
- return(0); /*Drive already set*/
- }
-
-/* The drive is not in the right mode, so we need to set it.
-*/
-
- zero_cmd(cmd);
- cmd[0]=MODESELECT; /*Set drive transfer modes*/
-/* cmd[1]=BLOCKPARAM; BLOCKPARAM==0*/
- cmd[2]=mode;
- switch(mode) {
- case MODE_DATA:
- cmd[3]=0x08; /*2048 bytes*/
- break;
- case MODE_USER:
- cmd[3]=0x09; /*2352 bytes*/
- cmd[4]=0x30;
- break;
- case MODE_DA:
- cmd[3]=0x09; /*2352 bytes*/
- cmd[4]=0x30;
- break;
- }
- i=0;
- while(retries-- > 0) {
- i=matcd_fastcmd(port,ldrive,cdrive,cmd);
- get_stat(port,ldrive); /*Read and toss status byte*/
- if (i==0) {
- cd->drivemode=mode; /*Set new mode*/
- return(i);
- }
- get_error(port,ldrive,cdrive);
- }
- cd->drivemode=MODE_UNKNOWN; /*We failed*/
- return(i);
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_volinfo - Read information from disc Table of Contents
----------------------------------------------------------------------------*/
-
-static int matcd_volinfo(int ldrive)
-{
- struct matcd_data *cd;
- int port,i;
- int z,cdrive;
- int retry;
- unsigned char cmd[MAXCMDSIZ];
- unsigned char data[12];
-
- retry=10; /*<16>This may take a long time*/
- cd = &matcd_data[ldrive];
- cdrive=ldrive&0x03;
- port=cd->iobase;
-
-#ifdef DEBUGOPEN
- printf("matcd%d: In volinfo, port %x\n",ldrive,port);
-#endif /*DEBUGOPEN*/
-
- while(retry>0) {
- zero_cmd(cmd);
- cmd[0]=READDINFO; /*Read Disc Info*/
- matcd_slowcmd(port,ldrive,cdrive,cmd);
- i=waitforit(10*TICKRES,DTEN,port,"matvinf");
- if (i) { /*THIS SHOULD NOT HAPPEN*/
- z=get_stat(port,ldrive);/*Read status byte*/
- printf("matcd%d: command failed, status %x\n",
- ldrive,z);
- return(-1);
- }
- matcd_pread(port, 6, data); /*Read data returned*/
- z=get_stat(port,ldrive);/*Read status byte*/
-#ifdef DEBUGOPEN
- printf("matcd%d: Data got was %x %x %x %x %x %x ",ldrive,
- data[0],data[1],data[2], data[3],data[4],data[5]);
- printf("status byte %x\n",z);
-#endif /*DEBUGOPEN*/
- if ((z & MATCD_ST_ERROR)==0)
- break; /*No Error*/
-
-/* If media change or other error, you have to read error data or
- the drive will reject subsequent commands.
-*/
-
- if (chk_error(get_error(port, ldrive, cdrive))==ERR_FATAL) {
-#ifdef DEBUGOPEN
- printf("matcd%d: command failed, status %x\n",
- ldrive,z);
-#endif /*DEBUGOPEN*/
- return(-1);
- }
- tsleep((caddr_t)&nextcontroller, PRIBIO, "matvi2", hz);
- if ((--retry)==0) return(-1);
-#ifdef DEBUGOPEN
- printf("matcd%d: Retrying",ldrive);
-#endif /*DEBUGOPEN*/
- }
-#ifdef DEBUGOPEN
- printf("matcd%d: Status port %x \n",ldrive,inb(port+STATUS));
-#endif /*DEBUGOPEN*/
-
- cd->volinfo.type=data[0];
- cd->volinfo.trk_high=data[2];
- cd->volinfo.trk_low=data[1];
- cd->volinfo.vol_msf[0]=data[3];
- cd->volinfo.vol_msf[1]=data[4];
- cd->volinfo.vol_msf[2]=data[5];
-
- if (cd->volinfo.trk_low + cd->volinfo.trk_high) {
- cd->flags |= MATCDLABEL;
- return(0);
- }
- return(-1);
-}
-
-
-/*---------------------------------------------------------------------------
- blk_to_msf - Convert block numbers into CD disk block ids
----------------------------------------------------------------------------*/
-
-static void blk_to_msf(int blk, unsigned char *msf)
-{
- blk=blk+150; /*2 seconds skip required to
- reach ISO data*/
- msf[0]=blk/4500;
- blk=blk%4500;
- msf[1]=blk/75;
- msf[2]=blk%75;
- return;
-}
-
-
-/*---------------------------------------------------------------------------
- msf_to_blk - Convert CD disk block ids into block numbers
----------------------------------------------------------------------------*/
-
-static int msf_to_blk(unsigned char * cd)
-{
- return(((cd[0]*60) /*Convert MSF to*/
- +cd[1])*75 /*Blocks minus 2*/
- +cd[2]-150); /*seconds*/
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_blockread - Performs actual background disc I/O operations
-
- This routine is handed the block number to read, issues the
- command to the drive, waits for it to complete, reads the
- data or error, retries if needed, and returns the results
- to the host.
----------------------------------------------------------------------------*/
-
-static void matcd_blockread(int state)
-{
- struct matcd_mbx *mbx;
- int ldrive,cdrive;
- int port, controller;
- short iftype;
- struct buf *bp;
- struct matcd_data *cd;
- int i;
- struct matcd_read2 rbuf;
- int blknum;
- caddr_t addr;
- int status;
- int errtyp;
- int phase;
- unsigned char cmd[MAXCMDSIZ];
-
- mbx = &matcd_data[state & 0x0f].mbx;
- ldrive=mbx->ldrive; /*ldrive is logical drive #*/
- cdrive=ldrive & 0x03; /*cdrive is drive # on a controller*/
- port=mbx->port; /*port is base port for i/f*/
- iftype=mbx->iftype;
- bp= mbx->bp;
- cd=&matcd_data[ldrive];
- controller = cd->mbx.controller;
-
-#ifdef DEBUGIO
- printf("matcd%d: Show state %x cdrive %d partition %d\n",
- ldrive,state,cdrive,mbx->partition);
-#endif /*DEBUGIO*/
-
-loop:
-#ifdef DEBUGIO
- printf("matcd%d: Top dp %x\n",ldrive,(unsigned int)dp);
-#endif /*DEBUGIO*/
- switch (state & 0xf0) {
- case MATCD_READ_1:
-#ifdef DEBUGIO
- printf("matcd%d: State 1 cd->flags %x\n",ldrive,cd->flags);
-#endif /*DEBUGIO*/
- /* to check for raw/cooked mode */
- if (cd->partflags[mbx->partition] & MATCDREADRAW) {
- mbx->sz = MATCDRBLK;
- i=matcd_setmode(ldrive, MODE_DA);
-#ifdef DEBUGIO
- printf("matcd%d: Set MODE_DA result %d\n",ldrive,i);
-#endif /*DEBUGIO*/
- } else {
- mbx->sz = cd->blksize;
- i=matcd_setmode(ldrive, MODE_DATA);
-#ifdef DEBUGIO
- printf("matcd%d: Set MODE_DATA result %d\n",ldrive,i);
-#endif /*DEBUGIO*/
- }
- /*for first block*/
-#ifdef DEBUGIO
- printf("matcd%d: A mbx %x bp %x b_bcount %x sz %x\n",
- ldrive,(unsigned int)mbx,(unsigned int)bp,
- (unsigned int)bp->b_bcount,mbx->sz);
-#endif /*DEBUGIO*/
- mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz;
- mbx->skip=0;
-nextblock:
-#ifdef DEBUGIO
- printf("matcd%d: at Nextblock b_blkno %d\n",
- ldrive,(unsigned int)bp->b_blkno);
-#endif /*DEBUGIO*/
-
- blknum=(bp->b_blkno / (mbx->sz/DEV_BSIZE))
- + mbx->p_offset + mbx->skip/mbx->sz;
-
- blk_to_msf(blknum,rbuf.start_msf);
-
- zero_cmd(cmd);
- cmd[0]=READ; /*Get drive ID*/
- cmd[1]=rbuf.start_msf[0];
- cmd[2]=rbuf.start_msf[1];
- cmd[3]=rbuf.start_msf[2];
- cmd[6]=1; /*Xfer only one block*/
- matcd_slowcmd(port,ldrive,cdrive,cmd);
-
-/* Now that we have issued the command, check immediately to
- see if data is ready. The drive has read-ahead caching, so
- it is possible the data is already in the drive buffer.
-
- If the data is not ready, schedule a wakeup and later on this
- code will run again to see if the data is ready then.
-*/
-
- case MATCD_READ_2:
- state=MATCD_READ_2+ldrive;
- phase = (inb(port+STATUS)) & (DTEN|STEN);
-#ifdef DEBUGIO
- printf("matcd%d: In state 2 status %x ",ldrive,phase);
-#endif /*DEBUGIO*/
- switch(phase) {
- case (DTEN|STEN): /*DTEN==H STEN==H*/
-#ifdef DEBUGIO
- printf("matcd%d: Sleeping\n",ldrive);
-#endif /*DEBUGIO*/
- timeout((timeout_func_t)matcd_blockread,
- (caddr_t)MATCD_READ_2+ldrive,hz/100);
- return;
-
-
- case STEN: /*DTEN=L STEN=H*/
- case 0: /*DTEN=L STEN=L*/
-#ifdef DEBUGIO
- printf("matcd%d: Data Phase\n",ldrive);
-#endif /*DEBUGIO*/
- addr=bp->b_un.b_addr + mbx->skip;
-#ifdef DEBUGIO
- printf("matcd%d: Xfer Addr %x size %x",
- ldrive,(unsigned int)addr,mbx->sz);
- i=0; /*<20>Reset read count*/
-#endif /*DEBUGIO*/
- if (iftype==0) { /*<20>Creative host I/F*/
- outb(port+PHASE,1); /*Enable data read*/
- while((inb(port+STATUS) &
- (DTEN|STEN))==STEN) {
- *addr++=inb(port+DATA);
-#ifdef DEBUGIO
- i++;
-#endif /*DEBUGIO*/
- }
- outb(port+PHASE,0); /*Disable read*/
- } else { /*<20>Not Creative interface*/
- while((inb(port+STATUS) &
- (DTEN|STEN))==STEN) {
- *addr++=inb(port+ALTDATA);
-#ifdef DEBUGIO
- i++;
-#endif /*DEBUGIO*/
- }
- }
-#ifdef DEBUGIO
- printf("matcd%d: Read %d bytes\n",ldrive,i);
-#endif /*DEBUGIO*/
-
-
-/* Now, wait for the Status phase to arrive. This will also
- tell us if any went wrong with the request.
-*/
- while((inb(port+STATUS)&(DTEN|STEN)) != DTEN);
- status=get_stat(port,ldrive); /*Read status byte*/
-#ifdef DEBUGIO
- printf("matcd%d: Status port %x byte %x ",
- ldrive,i,status);
-#endif /*DEBUGIO*/
- if (status & MATCD_ST_ERROR) {
- i=get_error(port,ldrive,cdrive);
- printf("matcd%d: %s while reading block %d [Soft]\n",
- ldrive,matcderrors[i],(int)bp->b_blkno);
- media_chk(cd,i,ldrive,0);/*<14>was wrong place*/
- }
-
- if (--mbx->nblk > 0) {
- mbx->skip += mbx->sz;
- goto nextblock; /*Oooooh, you flunk the course*/
- }
- bp->b_resid=0;
- biodone(bp); /*Signal transfer complete*/
-
- unlockbus(ldrive>>2, ldrive); /*Release bus lock*/
- matcd_start(controller);/*See if other drives have work*/
- return;
-
-/* Here we skipped the data phase and went directly to status.
- This indicates a hard error.
-*/
-
- case DTEN: /*DTEN=H STEN=L*/
- status=get_stat(port,ldrive); /*Read status byte*/
-#ifdef DEBUGIO
- printf("matcd%d: error, status was %x\n",
- ldrive,status);
-#endif /*DEBUGIO*/
-
-/* Ok, we need more details, so read error. This is needed to issue
- any further commands anyway
-*/
-
- errtyp=get_error(port,ldrive,cdrive);
- printf("matcd%d: %s while reading block %d\n",
- ldrive,matcderrors[errtyp],(int)bp->b_blkno);
-
- if (media_chk(cd,errtyp,ldrive,0)==0) {
- errtyp=chk_error(errtyp);
- if (errtyp==ERR_RETRY) {/*<14>We can retry*/
- /*<14>this error but the drive*/
- /*<14>probably has already*/
- if (mbx->retry-- > 0 ) {
- state=MATCD_READ_1+ldrive;
-#ifdef DEBUGIO
- printf("matcd%d: Attempting retry\n",
- ldrive);
-#endif /*DEBUGIO*/
- goto loop;
- }
- }
- }
-/*<14> The other error types are either something very bad or the media
-<14> has been removed by the user. In both cases there is no retry
-<14> for this call. We will invalidate the label in both cases.
-*/
- bp->b_flags |= B_ERROR;
- bp->b_resid = bp->b_bcount;
- biodone(bp);
- unlockbus(ldrive>>2, ldrive);
- matcd_start(controller);
- return;
- }
- }
-}
-
-
-/*---------------------------------------------------------------------------
- docmd - Get the bus, do the command, wait for completion,
- attempt retries, give up the bus.
- For commands that do not return data.
----------------------------------------------------------------------------*/
-
-int docmd(char * cmd, int ldrive, int cdrive, int controller, int port)
-{
- int retries,i,z;
-
- lockbus(controller, ldrive); /*Request bus*/
- retries=3;
- while(retries-- > 0) {
- matcd_slowcmd(port,ldrive,cdrive,cmd);
- i=waitforit(80*TICKRES,DTEN,port,"matcmd");
- z=get_stat(port,ldrive);/*Read status byte*/
- if ((z & MATCD_ST_ERROR)==0) break;
- i=chk_error(get_error(port,ldrive,cdrive));
- if (i!=ERR_INIT) {
- unlockbus(controller, ldrive); /*Release bus*/
- return(EFAULT);
- }
- }
- unlockbus(controller, ldrive); /*Release bus*/
- return(i);
-}
-
-
-/*---------------------------------------------------------------------------
- get_error - Read the error that aborted a command.
- Created in Edit 6
----------------------------------------------------------------------------*/
-
-int get_error(int port, int ldrive, int cdrive)
-{
- int status,errnum;
- unsigned char cmd1[MAXCMDSIZ];
- unsigned char data[12];
-
- zero_cmd(cmd1);
- cmd1[0]=READERROR; /*Enquire*/
- matcd_fastcmd(port,ldrive,cdrive,cmd1);
- matcd_pread(port, 8, data); /*Read data returned*/
- errnum=data[2]; /*Caller wants it classified*/
- status=get_stat(port,ldrive); /*Read status byte*/
-
-#ifdef DEBUGCMD
- printf("matcd%d: Chkerror found %x on command %x addrval %x statusdata %x statusport %x\n",
- ldrive,errnum,data[1],data[0],status,inb(port+STATUS));
-#endif /*DEBUGCMD*/
- return(errnum);
-}
-
-
-/*---------------------------------------------------------------------------
- chk_error - Classify the error that the drive reported
- Created in Edit 6
----------------------------------------------------------------------------*/
-
-int chk_error(int errnum)
-{
- switch(errnum) {
-/* These are errors we can attempt a retry for, although the drive
- has already done so.
-*/
- case UNRECV_ERROR:
- case SEEK_ERROR:
- case TRACK_ERROR:
- case FOCUS_ERROR:
- case CLV_ERROR:
- case DATA_ERROR:
- case MODE_ERROR: /*<16>Make this retryable*/
- return(ERR_RETRY);
-
-/* These errors usually indicate the user took the media from the
- drive while the dev was open. We will invalidate the unit
- until it closes when we see this.
-*/
- case NOT_READY:
- case MEDIA_CHANGED:
- case DISC_OUT:
- case HARD_RESET:
- return (ERR_INIT);
-
-/* These errors indicate the system is confused about the drive
- or media, and point to bugs in the driver or OS. These errors
- cannot be retried since you will always get the same error.
-*/
-
- case RAM_ERROR:
- case DIAG_ERROR:
- case CDB_ERROR:
- case END_ADDRESS:
- case ILLEGAL_REQ:
- case ADDRESS_ERROR:
- default:
- return (ERR_FATAL);
- }
-}
-
-
-/*---------------------------------------------------------------------------
- get_stat - Reads status byte
-
- This routine should be totally unnecessary, performing the
- task with a single line of in-line code. However in special
- cases, the drives return blocks of data that are not associated
- with the command in question. This appears to be at least one
- firmware error and the rest of the driver makes an effort to avoid
- triggering the fault. However, reading and throwing this
- bogus data is faster and less destructive than resetting all
- the drives on a given controller, plus it leaves the other drives
- unaffected.
----------------------------------------------------------------------------*/
-
-int get_stat(int port,int ldrive)
-{
- int status,busstat;
-
- status=inb(port+DATA); /*Read status byte, last step of cmd*/
- busstat=inb(port+STATUS); /*<16>Get bus status - should be 0xff*/
- while ((busstat & (DTEN|STEN)) != (DTEN|STEN)) {
- printf("matcd%d: get_stat: After reading status byte, bus didn't go idle %x %x %x\n",ldrive,status,busstat,port);
- if (( busstat & (DTEN|STEN)) == STEN) {
- int k;
- k=0;
-#ifdef DEBUGCMD
- printf("matcd%d: DATA PRESENT!!!! DISCARDING\n",ldrive);
-#endif /*DEBUGCMD*/
- outb(port+PHASE,1); /*Enable data read*/
- while ((inb(port+STATUS) & (DTEN|STEN)) == STEN) {
- inb(port+DATA);
- inb(port+ALTDATA);
-/* printf("%2x ",inb(port+DATA));*/
- k++;
- }
- outb(port+PHASE,0);
-#ifdef DEBUGCMD
- printf("\nmatcd%d: BYTES READ IN DATA was %d\n",
- ldrive,k);
-#endif /*DEBUGCMD*/
- }
- status=inb(port+DATA); /*Read the status byte again*/
-#ifdef DEBUGCMD
- printf("matcd%d: Next status byte is %x\n",ldrive,status);
-#endif /*DEBUGCMD*/
- busstat=inb(port+STATUS);
- }
- return(status);
-}
-
-
-/*---------------------------------------------------------------------------
- waitforit - Waits for a command started by slowcmd to complete.
----------------------------------------------------------------------------*/
-
-int waitforit(int timelimit, int state, int port, char * where)
-{
- int i,j;
-
- j=i=0;
-#ifdef DEBUGCMD
- printf("matcd: waitforit port %x timelimit %x hz %x\n",
- port,timelimit,hz);
-#endif /*DEBUGCMD*/
- while (i<timelimit) {
- j=inb(port+STATUS) & (STEN|DTEN); /*Read status*/
- if (j!=(STEN|DTEN)) break;
- tsleep((caddr_t)&nextcontroller, PRIBIO, where, hz/100);
- i++;
- }
-#ifdef DEBUGCMD
- printf("matcd: Count was %d\n",i);
-#endif /*DEBUGCMD*/
- if (j==state) return(0); /*Command complete*/
-#ifdef DEBUGCMD
- printf("matcd: Timeout!");
-#endif /*DEBUGCMD*/
- return(1); /*Timeout occurred*/
-}
-
-
-/*---------------------------------------------------------------------------
- lockbus - Wait for the bus on the requested driver interface
- to go idle and acquire it.
- Created in Edit 6
----------------------------------------------------------------------------*/
-
-void lockbus(int controller, int ldrive)
-{
- while ((if_state[controller] & BUSBUSY)) {
-#ifdef DEBUGSLEEP
- printf("matcd%d: Can't do it now - going to sleep\n",
- ldrive);
-#endif /*DEBUGSLEEP*/
- tsleep((caddr_t)&matcd_data->status, PRIBIO,
- "matlck", 0);
- }
- if_state[controller] |= BUSBUSY; /*<18>It's ours NOW*/
-#ifdef DEBUGSLEEP
- printf("matcd%d: BUS locked in lockbus\n",ldrive);
-#endif /*DEBUGSLEEP*/
-}
-
-
-/*---------------------------------------------------------------------------
- unlockbus - Release the host interface bus we already have so
- someone else can use it.
- Created in Edit 6
----------------------------------------------------------------------------*/
-
-void unlockbus(int controller, int ldrive)
-{
- if_state[controller] &= ~BUSBUSY;
-#ifdef DEBUGSLEEP
- printf("matcd%d: bus unlocked\n",ldrive);
-#endif /*DEBUGSLEEP*/
- wakeup((caddr_t)&matcd_data->status); /*Wakeup other users*/
- matcd_start(controller); /*Wake up any block I/O*/
-}
-
-
-/*---------------------------------------------------------------------------
- media_chk - Checks error for types related to media
- changes.
----------------------------------------------------------------------------*/
-
-int media_chk(struct matcd_data *cd,int errnum,int ldrive,int test)
-{
- if (errnum==NOT_READY ||
- errnum==MEDIA_CHANGED ||
- errnum==HARD_RESET ||
- errnum==DISC_OUT) {
- cd->flags &= ~MATCDLABEL; /*Mark label as invalid*/
- if (test==0) { /*<14>Do warn by default*/
-
- if ((cd->flags & MATCDWARN)==0) {/*<14>Msg already?*/
- printf("matcd%d: Media changed - Further I/O aborted until device closed\n",ldrive);
- cd->flags |= MATCDWARN;
- }
- }
- return(1);
- }
- if (errnum==MODE_ERROR) /*<16>Maybe the setting is*/
- cd->drivemode=MODE_UNKNOWN; /*<16>wrong so force a reset*/
- return(0);
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_eject - Open drive tray
----------------------------------------------------------------------------*/
-
-int matcd_eject(int ldrive, int cdrive, int controller)
-{
- int i,port;
- struct matcd_data *cd;
- unsigned char cmd[MAXCMDSIZ];
-
- cd=&matcd_data[ldrive];
- port=cd->iobase; /*Get I/O port base*/
-
-#ifdef LOCKDRIVE
- if (cd->flags & MATCDLOCK) { /*<15>Drive was locked via open*/
- return(EINVAL); /*<15>so don't allow the eject*/
- }
-#endif /*LOCKDRIVE*/
- zero_cmd(cmd); /*Initialize command buffer*/
- cmd[0]=LOCK; /*Unlock drive*/
- i=docmd(cmd,ldrive,cdrive,controller,port); /*Issue command*/
- cmd[0]=DOOROPEN; /*Open Door*/
- i=docmd(cmd,ldrive,cdrive,controller,port); /*Issue command*/
- cd->flags &= ~(MATCDLABEL|MATCDLOCK); /*<15>Mark vol info invalid*/
- return(i); /*Return result we got*/
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_doorclose - Close drive tray
-<16> Added in Edit 16
----------------------------------------------------------------------------*/
-
-int matcd_doorclose(int ldrive, int cdrive, int controller)
-{
- int i,port;
- struct matcd_data *cd;
- unsigned char cmd[MAXCMDSIZ];
-
- cd=&matcd_data[ldrive];
- port=cd->iobase; /*Get I/O port base*/
-
- zero_cmd(cmd); /*Initialize command buffer*/
- cmd[0]=DOORCLOSE; /*Open Door*/
- i=docmd(cmd,ldrive,cdrive,controller,port); /*Issue command*/
- cd->flags &= ~(MATCDLABEL|MATCDLOCK); /*Mark vol info invalid*/
- tsleep((caddr_t)&nextcontroller, PRIBIO, "matclos", hz);
- return(i); /*Return result we got*/
-}
-
-
-/*---------------------------------------------------------------------------
-<23> matcd_dlock - Honor/Reject drive tray requests
----------------------------------------------------------------------------*/
-
-int matcd_dlock(int ldrive, int cdrive, int controller, int action)
-{
- int i,port;
- struct matcd_data *cd;
- unsigned char cmd[MAXCMDSIZ];
-
- cd=&matcd_data[ldrive];
- port=cd->iobase; /*<23>Get I/O port base*/
-
- zero_cmd(cmd); /*<23>Initialize command buffer*/
- cmd[0]=LOCK; /*<23>Unlock drive*/
-
- if (action) { /*<23>They want to lock the door?*/
- cd->flags |= MATCDLOCK; /*<23>Remember we did this*/
- cmd[1]=1; /*<23>Lock Door command*/
- } else {
- cd->flags &= ~MATCDLOCK;/*<23>Remember we did this*/
- /*<23>Unlock Door command*/
- }
- i=docmd(cmd,ldrive,cdrive,controller,port); /*<23>Issue command*/
- return(i); /*<23>Return result we got*/
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_toc_header - Return Table of Contents header to caller
-<13> New for Edit 13
----------------------------------------------------------------------------*/
-
-static int matcd_toc_header(int ldrive, int cdrive, int controller,
- struct ioc_toc_header * toc)
-{
- struct matcd_data *cd;
-
- cd=&matcd_data[ldrive];
- if ((cd->flags & MATCDLABEL)==0)
- return(EIO); /*Refuse after chg error*/
-
- toc->len=msf_to_blk(cd->volinfo.vol_msf); /*In frames*/
- toc->starting_track=cd->volinfo.trk_low; /*1*/
- toc->ending_track=cd->volinfo.trk_high; /*Last track*/
-
- return(0);
-
-}
-
-
-/*---------------------------------------------------------------------------
- matcd_toc_entries - Read all of the TOC entries
-
- These entries are cached by the drive, but it might be worth
- the space investment to have the driver cache these as well.
- For a disc with 40 tracks, it means 41 command calls to get
- this information from the drive.
-<13> New for Edit 13
----------------------------------------------------------------------------*/
-
-static int matcd_toc_entries(int ldrive, int cdrive, int controller,
- struct ioc_read_toc_entry * ioc_entry)
-{
- struct matcd_data *cd;
- struct cd_toc_entry entries[MAXTRKS];
- struct cd_toc_entry *from;
- struct cd_toc_entry *to;
- int len,trk,i,z,port;
- unsigned char cmd[MAXCMDSIZ];
- unsigned char data[5];
-
- cd=&matcd_data[ldrive];
- port=cd->iobase;
-
- if ((cd->flags & MATCDLABEL)==0)
- return(EIO); /*Refuse after chg error*/
-
- zero_cmd(cmd);
- cmd[0]=READTOC;
-
- for(trk=cd->volinfo.trk_low-1; trk<cd->volinfo.trk_high; trk++) {
- cmd[2]=trk+1;
- lockbus(controller, ldrive); /*Request bus*/
- matcd_slowcmd(port,ldrive,cdrive,cmd);
- i=waitforit(10*TICKRES,DTEN,port,"mats1");
- matcd_pread(port, 8, data); /*Read data returned*/
- z=get_stat(port,ldrive); /*Read status byte*/
- if ((z & MATCD_ST_ERROR)) { /*Something went wrong*/
- i=get_error(port, ldrive, cdrive);
- unlockbus(controller, ldrive); /*Release bus*/
- return(EIO);
- }
- unlockbus(controller, ldrive); /*Release bus*/
-
-#ifdef DEBUGIOCTL
- printf("Track %d addr/ctrl %x m %x s %x f %x\n",data[2],
- data[1],data[4],data[5],data[6]);
-#endif /*DEBUGIOCTL*/
-
- entries[trk].control=data[1]; /*Track type*/
- entries[trk].addr_type=ioc_entry->address_format;/*Type*/
- entries[trk].track=data[2]; /*Track #, can be Out of Order*/
- if (ioc_entry->address_format == CD_MSF_FORMAT) {
- entries[trk].addr.msf.unused=0;
- entries[trk].addr.msf.minute=data[4]; /*Min*/
- entries[trk].addr.msf.second=data[5]; /*Sec*/
- entries[trk].addr.msf.frame=data[6]; /*Frame*/
- }
- }
- entries[trk].control=data[2]; /*Copy from last valid track*/
- entries[trk].track=0xaa; /*<23>Lead-out*/
- entries[trk].addr.msf.unused=0; /*Fill*/
- entries[trk].addr.msf.minute=cd->volinfo.vol_msf[0];
- entries[trk].addr.msf.second=cd->volinfo.vol_msf[1];
- entries[trk].addr.msf.frame=cd->volinfo.vol_msf[2];
- trk++; /*Bump to include leadout track*/
-
-
-/* Now that we have read all the data from the drive, copy the
- array from the kernel address space into the user address space
-*/
-
- len=ioc_entry->data_len;
- i=ioc_entry->starting_track; /*<23>What did they want?*/
- if (i==0xaa) i=trk-1; /*<23>Give them lead-out info*/
- else i=ioc_entry->starting_track - 1; /*<23>start where they asked*/
- from = &entries[i];
- to = ioc_entry->data;
-
- while (i < trk && len >= sizeof(struct cd_toc_entry)) {
- if (copyout(from,to,sizeof(struct cd_toc_entry))
- != 0) {
- return (EFAULT);
- }
- i++;
- len -= sizeof(struct cd_toc_entry);
- from++;
- to++;
- }
- return(0);
-
-}
-
-/*---------------------------------------------------------------------------
- matcd_subq - Read the Sub-Q packet - (where are we?)
-
- This call gives a snapshot state of where the optical
- pick-up is when the command is issued.
-<14> New for Edit 14
----------------------------------------------------------------------------*/
-
-static int matcd_read_subq(int ldrive, int cdrive, int controller,
- struct ioc_read_subchannel * sqp)
-{
- struct matcd_data *cd;
- int i,z,port;
- unsigned char cmd[MAXCMDSIZ];
- unsigned char data[12];
- struct cd_sub_channel_info subq; /*Build result here*/
-
- cd=&matcd_data[ldrive];
- port=cd->iobase;
-
- if ((cd->flags & MATCDLABEL)==0)
- return(EIO); /*Refuse after chg error*/
-
-/* We only support the ioctl functions we could get information
- on, so test for the things we can do
-*/
-
- if (sqp->data_format!=CD_CURRENT_POSITION ||
- sqp->address_format!=CD_MSF_FORMAT) {
- return(EINVAL);
- }
-
- zero_cmd(cmd);
- cmd[0]=READSUBQ;
- lockbus(controller, ldrive); /*Request bus*/
- matcd_slowcmd(port,ldrive,cdrive,cmd);
-
-/* While we wait, fill in the hard-coded entries of the table*/
-
- subq.what.position.data_format=CD_MSF_FORMAT;
- subq.what.position.absaddr.msf.unused=0;
- subq.what.position.reladdr.msf.unused=0;
-
- i=waitforit(10*TICKRES,DTEN,port,"mats2");
- matcd_pread(port, 11, data); /*Read data returned*/
- z=get_stat(port,ldrive); /*Read status byte*/
- if ((z & MATCD_ST_ERROR)) { /*Something went wrong*/
- i=get_error(port, ldrive, cdrive);
- unlockbus(controller, ldrive); /*Release bus*/
- return(EIO);
- }
- unlockbus(controller, ldrive); /*Release bus*/
-
-#ifdef DEBUGIOCTL
- printf("Subq track %d index %d adr/ctl %x abs %d:%2d:%2d rel %d:%2d:%2d UPC %x\n",
- data[2],data[3],data[1],data[4],data[5],data[6],
- data[7],data[8],data[9],data[10]);
-#endif /*DEBUGIOCTL*/
-
- if (z & MATCD_ST_AUDIOBSY) { /*Drive playing or paused*/
- if (cd->status==CD_AS_PLAY_PAUSED) { /*Have we issued*/
- i=cd->status; /*a pause command?*/
- } else {
- i=CD_AS_PLAY_IN_PROGRESS;/*No, we really are playing*/
- }
- } else {
- if (cd->status==CD_AS_PLAY_IN_PROGRESS) {/*It was playing*/
- i=CD_AS_PLAY_COMPLETED; /*so it finished*/
- } else { /*Any other status reported*/
- i=cd->status; /*as we get it*/
- }
- }
-
- subq.header.audio_status=cd->status=i; /*Store status we selected*/
-
- subq.what.position.track_number=data[2];
- subq.what.position.index_number=data[3];
-
- subq.what.position.absaddr.msf.minute=data[4];
- subq.what.position.absaddr.msf.second=data[5];
- subq.what.position.absaddr.msf.frame=data[6];
-
- subq.what.position.reladdr.msf.minute=data[7];
- subq.what.position.reladdr.msf.second=data[8];
- subq.what.position.reladdr.msf.frame=data[9];
-
-/* Ok, now copy our nicely-built structure from the kernel address
- space into the user address space (we hope)
-*/
-
- if (copyout(&subq, sqp->data,
- min(sizeof(struct cd_sub_channel_info), sqp->data_len))!=0) {
- return(EFAULT);
- }
- return(0);
-}
-
-/*---------------------------------------------------------------------------
- matcd_igot - Like the song, report the capabilities that the
- drive/driver has available.
-
- This call returns a structure of flags indicating what
- functions are available so that the application can offer
- only the functions the drive is actually capable of.
-<16> New for Edit 16
----------------------------------------------------------------------------*/
-
-static int matcd_igot(struct ioc_capability * sqp)
-{
-
-#ifdef FULLDRIVER
- sqp->play_function=(CDDOPLAYTRK | /*Can play trks/indx*/
- CDDOPLAYMSF | /*Can play msf to msf*/
- CDDOPAUSE | /*Can pause playback*/
- CDDORESUME | /*Can resume playback*/
- CDDOSTOP | /*Can stop playback*/
- CDDOPITCH); /*Can change play pitch*/
-
- sqp->routing_function=(CDREADVOLUME | /*Can read volume*/
- CDSETVOLUME | /*Can set volume*/
- CDSETSTEREO | /*Can select stereo play*/
- CDSETLEFT | /*Can select left-only*/
- CDSETRIGHT | /*Can select right-only*/
- CDSETMUTE | /*Can mute audio*/
- CDSETPATCH); /*Direct patch settings*/
-#else /*FULLDRIVER*/
- sqp->play_function=0; /*No audio capability*/
- sqp->routing_function=0; /*No audio capability*/
-#endif /*FULLDRIVER*/
-
- sqp->special_function=(CDDOEJECT | /*Door can be opened*/
- CDDOCLOSE | /*Door can be closed*/
- CDDOLOCK | /*Door can be locked*/
- CDREADSUBQ | /*Can read subchannel*/
- CDREADENTRIES | /*Can read TOC entries*/
- CDREADHEADER); /*Can read TOC*/
- return(0);
-}
-
-
-#ifdef FULLDRIVER
-#include "i386/isa/matcd/audio.c" /*<15>ioctls related to
- audio are here*/
-#endif /*FULLDRIVER*/
-
-
-static matcd_devsw_installed = 0;
-
-static void
-matcd_drvinit(void *unused)
-{
-
- if( ! matcd_devsw_installed ) {
- bdevsw_add_generic(BDEV_MAJOR,CDEV_MAJOR, &matcd_bdevsw);
- matcd_devsw_installed = 1;
- }
-}
-
-SYSINIT(matcddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,matcd_drvinit,NULL)
-
-
-/*End of matcd.c*/
-
diff --git a/sys/pc98/pc98/matcd/options.h b/sys/pc98/pc98/matcd/options.h
deleted file mode 100644
index 62d2e2b..0000000
--- a/sys/pc98/pc98/matcd/options.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*options.h--------------------------------------------------------------------
-
- Matsushita(Panasonic) / Creative CD-ROM Driver (matcd)
- Authored by Frank Durda IV
-
- Copyright 1994, 1995 Frank Durda IV. All rights reserved.
- "FDIV" is a trademark of Frank Durda IV.
-
-
- 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 positioned at the very beginning of this file without
- modification, all copyright strings, all related programming
- codes that display the copyright strings, this list of
- conditions and the following disclaimer.
- 2. Redistributions in binary form must contain all copyright strings
- and related programming code that display the copyright strings.
- 3. 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.
- 4. All advertising materials mentioning features or use of this
- software must display the following acknowledgement:
- "The Matsushita/Panasonic CD-ROM driver was developed
- by Frank Durda IV for use with "FreeBSD" and similar
- operating systems."
- "Similar operating systems" includes mainly non-profit oriented
- systems for research and education, including but not restricted
- to "NetBSD", "386BSD", and "Mach" (by CMU). The wording of the
- acknowledgement (in electronic form or printed text) may not be
- changed without permission from the author.
- 5. Absolutely no warranty of function, fitness or purpose is made
- by the author Frank Durda IV.
- 6. Neither the name of the author nor the name "FreeBSD" may
- be used to endorse or promote products derived from this software
- without specific prior written permission.
- (The author can be reached at bsdmail@nemesis.lonestar.org)
- 7. The product containing this software must meet all of these
- conditions even if it is unsupported, not a complete system
- and/or does not contain compiled code.
- 8. These conditions will be in force for the full life of the
- copyright.
- 9. If all the above conditions are met, modifications to other
- parts of this file may be freely made, although any person
- or persons making changes do not receive the right to add their
- name or names to the copyright strings and notices in this
- software. Persons making changes are encouraged to insert edit
- history in matcd.c and to put your name and details of the
- change there.
- 10. You must have prior written permission from the author to
- deviate from these terms.
-
- Vendors who produce product(s) containing this code are encouraged
- (but not required) to provide copies of the finished product(s) to
- the author and to correspond with the author about development
- activity relating to this code. Donations of development hardware
- and/or software are also welcome. (This is one of the faster ways
- to get a driver developed for a device.)
-
- THIS SOFTWARE IS PROVIDED BY THE DEVELOPER(S) ``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 DEVELOPER(S) 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.
-
-
------No changes are allowed above this line------------------------------------
------------------------------------------------------------------------------
- Conditional compilation flags - change to suit your system
----------------------------------------------------------------------------*/
-
-/* AUTOHUNT Adds extra code that allows the driver to search
- for interface cards rather than having to hard-code
- the locations in the kernel conf file.
- Leaving AUTOHUNT enabled is the recommended setting.
-*/
-
-#define AUTOHUNT
-
-
-/* NUMCTRLRS Configures support for between one and four
- host interfaces, for up to 16 drives.
- The number of entries in the kernel config
- file is used by default, but this may be changed
- to a specific value if desired.
-
- Leaving NUMCTRLRS based on NMATCD is the
- recommended setting.
-*/
-
-#if NMATCD >= 4
-#define NUMCTRLRS 4 /*Limit driver to four host interfaces*/
-#else /*NMATCD*/
-#define NUMCTRLRS NMATCD
-#endif /*NMATCD*/
-
-
-/* FULLDRIVER If not set, the audio, non-data functions and
- some error recovery functions are eliminated from
- the compiled driver. The resulting driver will be
- smaller and may help a kernel fit on a boot floppy.
- Leaving FULLDRIVER enabled is the recommended setting.
-*/
-
-#ifndef BOOTMFS
-#define FULLDRIVER
-#endif /*BOOTMFS*/
-
-
-/* RESETONBOOT causes the driver to reset the drive(s) to be
- reset during probing. This causes any audio
- playback to be aborted and the drives will close
- their trays if they are open.
- Leaving RESETONBOOT enabled is the recommended setting.
-*/
-
-#define RESETONBOOT
-
-
-/*<15> LOCKDRIVE If enabled, when a drive is opened using a
-<15> minor number greater than 127, the drive door is
-<15> locked. The drive door remains locked until all
-<23> partitions on the drive are closed. The EJECT,
-<23> ALLOW and PREVENT ioctls are refused when this locking
-<23> mechanism is active.
-<15> The additional code size is small so enabling
-<15> LOCKDRIVE is the recommended setting.
-*/
-
-#define LOCKDRIVE
-
-
-/*<14> KRYTEN This enables a bug that someone might consider
-<14> to be a feature. If KRYTEN is enabled and you are
-<14> playing audio and you issue the resume-play ioctl,
-<14> the audio will stutter, playing the same quarter
-<14> of a second or so of audio several times before
-<14> resuming normally. Resuming from a pause acts
-<14> normally regardless of the setting of this flag.
-<14> Leaving KRYTEN disabled is the recommended setting.
-<14>*/
-
-/*#define KRYTEN*/
-
-
-/*---------------------------------------------------------------------------
- This structure contains the hints for where we should look for the
- host adapter. If you want to change where we search or reduce the
- places we search to avoid confusing some other device, either
- specify explicit addresses in the kernel config file (preferred)
- or change this array.
-
- If the kernel config file has multiple ? entries, the probe routines
- will use this table multiple times and will eliminate each failed
- entry that probe tries.
-
- WARNING: The number of controller entries for this driver in config
- must be less than or equal to the number of hints if hints are used.
-
- If you add entries to the table, add them immediately before
- the -1 end-of-table marker. The values already present are
- the ones used by Creative Labs boards and those of a few
- other vendors.
-
- Each additional entry increases the boot time by four seconds,
- and can increase the chance of accessing some other device.
- Therefore, the list should be kept to a minimum. Once the
- devices have been correctly located, the kernel should be
- configured so that it looks only at the correct location from
- that point on.
-
- Be sure to search devices located below 0x3ff BEFORE scanning
- higher locations. Some boards don't decode all I/O address lines,
- so 0x230 and 0x630 appear identical.
----------------------------------------------------------------------------*/
-
-#ifdef AUTOHUNT
-static int port_hints[]={
-#ifdef PC98
- 0x30d2,
- 0x30d0,
- 0x30d4,
- 0x30d6,
- 0x30d8,
- 0x30da,
- 0x30dc,
- 0x30de,
-#else
- 0x230, /*SB Pro & SB16*/
- 0x240, /*SB Pro & SB16*/
- 0x250, /*Creative omniCD standalone boards*/
- 0x260, /*Creative omniCD standalone boards*/
- 0x340, /*Laser Mate*/
- 0x360, /*Laser Mate*/
- 0x630, /*IBM*/
-#if 0
-/* These locations are alternate settings for LaserMate and IBM
- boards, but they usually conflict with network and SCSI cards.
- I recommend against probing these randomly.
-*/
- 0x310, /*Laser Mate*/
- 0x320, /*Laser Mate*/
- 0x330, /*Laser Mate*/
- 0x350, /*Laser Mate*/
- 0x370, /*Laser Mate*/
- 0x650, /*IBM*/
- 0x670, /*IBM*/
- 0x690, /*IBM*/
-#endif /*0*/
-#endif
- -1}; /*use. Table MUST end with -1*/
-#endif /*AUTOHUNT*/
-
-
-/*---------------------------------------------------------------------------
- Debugging flags - Turn these on only if you are looking at a
- problem.
----------------------------------------------------------------------------*/
-
-/* DEBUGOPEN If enabled, debug messages for open and close
- operations.
-*/
-
-/*#define DEBUGOPEN*/
-
-
-/* DEBUGIO If enabled, reports on calls to strategy, start
- and other I/O related functions.
-*/
-
-/*#define DEBUGIO*/
-
-
-/* DEBUGQUEUE If enabled, shows activity on disk request queues.
- Warning - This debug is VERY VERY NOISY and will
- loop endlessly if queues are not null terminated
- as they should be.
-*/
-
-/*#define DEBUGQUEUE*/
-
-
-/* DEBUGCMD If enabled, shows the actual commands being issued
- to the CD-ROM drives.
-*/
-
-/*#define DEBUGCMD*/
-
-
-/* DEBUGSLEEP If enabled, reports on timeouts, wakeups, dropped
- threads, etc.
-*/
-
-/*#define DEBUGSLEEP*/
-
-
-/* DEBUGIOCTL If enabled, reports on the various ioctl-related
- calls and operations. You might have to enable
- DEBUGCMD as well to get enough debugging information.
-*/
-
-/*#define DEBUGIOCTL*/
-
-
-/* DEBUGPROBE If enabled, reports on the process of locating
- adapters and drives. The debugging in matcdprobe()
- and matcdattach() routines is enabled with this
- flag.
-*/
-
-/*#define DEBUGPROBE*/
-
-
-/*End of options.h*/
-
diff --git a/sys/pc98/pc98/mse.c b/sys/pc98/pc98/mse.c
index 871a564..9ffaafc 100644
--- a/sys/pc98/pc98/mse.c
+++ b/sys/pc98/pc98/mse.c
@@ -11,7 +11,7 @@
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
- * $Id: mse.c,v 1.4 1996/09/07 02:13:57 asami Exp $
+ * $Id: mse.c,v 1.5 1996/09/10 09:38:15 asami Exp $
*/
/*
* Driver for the Logitech and ATI Inport Bus mice for use with 386bsd and
@@ -662,17 +662,7 @@ mse_probe98m(idp)
/* initialize */
outb(msport + INT, INT_DISABLE); /* INT disable */
outb(msport + HC, HC_NO_CLEAR); /* HC = 0 */
-#if 0
- if (inb(msport + PORT_C) & 0x80 != 0) {
- return (0);
- }
-#endif
outb(msport + HC, HC_CLEAR); /* HC = 1 */
-#if 0
- if (inb(msport + PORT_C) & 0x80 == 0) {
- return (0);
- }
-#endif
return (1);
}
diff --git a/sys/pc98/pc98/pc98.h b/sys/pc98/pc98/pc98.h
index 84c77b4..6a369f7 100644
--- a/sys/pc98/pc98/pc98.h
+++ b/sys/pc98/pc98/pc98.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.h 5.7 (Berkeley) 5/9/91
- * $Id: pc98.h,v 1.5 1996/10/09 21:46:34 asami Exp $
+ * $Id: pc98.h,v 1.6 1996/10/23 07:25:22 asami Exp $
*/
#ifndef _PC98_PC98_PC98_H_
@@ -73,7 +73,7 @@
#define IO_NMI 0x050 /* NMI Control */
#define IO_WAIT 0x05F /* WAIT 0.6 us */
#define IO_GDC1 0x060 /* 7220 GDC Text Control */
-#define IO_TIMER 0x071 /* 8253C Timer */
+#define IO_TIMER1 0x071 /* 8253C Timer */
#define IO_SASI 0x080 /* SASI Hard Disk Controller */
#define IO_FD1 0x090 /* 765A 1MB FDC */
#define IO_GDC2 0x0a0 /* 7220 GDC Graphic Control */
diff --git a/sys/pc98/pc98/pcaudio.c b/sys/pc98/pc98/pcaudio.c
index 10d5232..2b5c4c7 100644
--- a/sys/pc98/pc98/pcaudio.c
+++ b/sys/pc98/pc98/pcaudio.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pcaudio.c,v 1.5 1996/09/10 09:38:24 asami Exp $
+ * $Id: pcaudio.c,v 1.6 1996/10/09 21:46:40 asami Exp $
*/
#include "pca.h"
@@ -35,8 +35,7 @@
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/uio.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
+#include <sys/fcntl.h>
#include <sys/proc.h>
#include <sys/kernel.h>
@@ -45,18 +44,14 @@
#ifdef PC98
#include <pc98/pc98/pc98.h>
-#include <i386/isa/isa_device.h>
-#include <pc98/pc98/timerreg.h>
-
-#include <pc98/pc98/sound/ulaw.h>
#else
#include <i386/isa/isa.h>
+#endif
#include <i386/isa/isa_device.h>
#include <i386/isa/timerreg.h>
#define DSP_ULAW_NOT_WANTED
#include <i386/isa/sound/ulaw.h>
-#endif
#ifdef DEVFS
#include <sys/devfsext.h>
@@ -97,7 +92,7 @@ static void *pcac_devfs_token;
static int pca_sleep = 0;
static int pca_initialized = 0;
-void pcaintr(struct clockframe *frame);
+static void pcaintr(struct clockframe *frame);
static int pcaprobe(struct isa_device *dvp);
static int pcaattach(struct isa_device *dvp);
@@ -121,7 +116,8 @@ static void pca_continue __P((void));
static void pca_init __P((void));
static void pca_pause __P((void));
-static inline void conv(const void *table, void *buff, unsigned long n)
+static inline void
+conv(const void *table, void *buff, unsigned long n)
{
__asm__("1:\tmovb (%2), %3\n"
"\txlatb\n"
@@ -152,7 +148,7 @@ pca_volume(int volume)
static void
-pca_init()
+pca_init(void)
{
pca_status.open = 0;
pca_status.queries = 0;
@@ -233,7 +229,7 @@ pca_stop(void)
static void
-pca_pause()
+pca_pause(void)
{
int x = splhigh();
@@ -249,7 +245,7 @@ pca_pause()
static void
-pca_continue()
+pca_continue(void)
{
int x = splhigh();
@@ -313,7 +309,7 @@ pcaattach(struct isa_device *dvp)
}
-static int
+static int
pcaopen(dev_t dev, int flags, int fmt, struct proc *p)
{
/* audioctl device can always be opened */
@@ -341,7 +337,7 @@ pcaopen(dev_t dev, int flags, int fmt, struct proc *p)
}
-static int
+static int
pcaclose(dev_t dev, int flags, int fmt, struct proc *p)
{
/* audioctl device can always be closed */
@@ -357,7 +353,7 @@ pcaclose(dev_t dev, int flags, int fmt, struct proc *p)
}
-static int
+static int
pcawrite(dev_t dev, struct uio *uio, int flag)
{
int count, error, which, x;
@@ -403,7 +399,7 @@ pcawrite(dev_t dev, struct uio *uio, int flag)
}
-static int
+static int
pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
{
audio_info_t *auptr;
@@ -467,7 +463,7 @@ pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
}
-void
+static void
pcaintr(struct clockframe *frame)
{
if (pca_status.index < pca_status.in_use[pca_status.current]) {
@@ -510,7 +506,7 @@ pcaintr(struct clockframe *frame)
}
-int
+static int
pcaselect(dev_t dev, int rw, struct proc *p)
{
int s = spltty();
diff --git a/sys/pc98/pc98/pcibus.c b/sys/pc98/pc98/pcibus.c
deleted file mode 100644
index 2e922e9..0000000
--- a/sys/pc98/pc98/pcibus.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/**************************************************************************
-**
-** $Id: pcibus.c,v 1.3 1996/09/03 10:23:51 asami Exp $
-**
-** pci bus subroutines for i386 architecture.
-**
-** FreeBSD
-**
-**-------------------------------------------------------------------------
-**
-** Copyright (c) 1994 Wolfgang Stanglmeier. 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. 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 "vector.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-
-#include <i386/isa/icu.h>
-#include <i386/isa/isa_device.h>
-
-#include <pci/pcivar.h>
-#include <pci/pcireg.h>
-#include <pci/pcibus.h>
-
-/*-----------------------------------------------------------------
-**
-** The following functions are provided by the pci bios.
-** They are used only by the pci configuration.
-**
-** pcibus_setup():
-** Probes for a pci system.
-** Sets pci_maxdevice and pci_mechanism.
-**
-** pcibus_tag():
-** Creates a handle for pci configuration space access.
-** This handle is given to the read/write functions.
-**
-** pcibus_ftag():
-** Creates a modified handle.
-**
-** pcibus_read():
-** Read a long word from the pci configuration space.
-** Requires a tag (from pcitag) and the register
-** number (should be a long word alligned one).
-**
-** pcibus_write():
-** Writes a long word to the pci configuration space.
-** Requires a tag (from pcitag), the register number
-** (should be a long word alligned one), and a value.
-**
-** pcibus_regirq():
-** Register an interupt handler for a pci device.
-** Requires a tag (from pcitag), the register number
-** (should be a long word alligned one), and a value.
-**
-**-----------------------------------------------------------------
-*/
-
-static int
-pcibus_check (void);
-
-static void
-pcibus_setup (void);
-
-static pcici_t
-pcibus_tag (u_char bus, u_char device, u_char func);
-
-static pcici_t
-pcibus_ftag (pcici_t tag, u_char func);
-
-static u_long
-pcibus_read (pcici_t tag, u_long reg);
-
-static void
-pcibus_write (pcici_t tag, u_long reg, u_long data);
-
-static int
-pcibus_ihandler_attach (int irq, inthand2_t *func, int arg, unsigned* maskptr);
-
-static int
-pcibus_ihandler_detach (int irq, inthand2_t *func);
-
-static int
-pcibus_imask_include (int irq, unsigned* maskptr);
-
-static int
-pcibus_imask_exclude (int irq, unsigned* maskptr);
-
-static struct pcibus i386pci = {
- "pci",
- pcibus_setup,
- pcibus_tag,
- pcibus_ftag,
- pcibus_read,
- pcibus_write,
- ICU_LEN,
- pcibus_ihandler_attach,
- pcibus_ihandler_detach,
- pcibus_imask_include,
- pcibus_imask_exclude,
-};
-
-/*
-** Announce structure to generic driver
-*/
-
-DATA_SET (pcibus_set, i386pci);
-
-/*--------------------------------------------------------------------
-**
-** Determine configuration mode
-**
-**--------------------------------------------------------------------
-*/
-
-
-#define CONF1_ADDR_PORT 0x0cf8
-#define CONF1_DATA_PORT 0x0cfc
-
-#define CONF1_ENABLE 0x80000000ul
-#define CONF1_ENABLE_CHK 0x80000000ul
-#define CONF1_ENABLE_MSK 0x7ff00000ul
-#define CONF1_ENABLE_CHK1 0xff000001ul
-#define CONF1_ENABLE_MSK1 0x80000001ul
-#define CONF1_ENABLE_RES1 0x80000000ul
-
-#define CONF2_ENABLE_PORT 0x0cf8
-#ifdef PC98
-#define CONF2_FORWARD_PORT 0x0cf9
-#else
-#define CONF2_FORWARD_PORT 0x0cfa
-#endif
-
-#define CONF2_ENABLE_CHK 0x0e
-#define CONF2_ENABLE_RES 0x0e
-
-static int
-pcibus_check (void)
-{
- u_char device;
-
- if (bootverbose) printf ("pcibus_check:\tdevice ");
-
- for (device = 0; device < pci_maxdevice; device++) {
- unsigned long id;
- if (bootverbose)
- printf ("%d ", device);
- id = pcibus_read (pcibus_tag (0,device,0), 0);
- if (id && id != 0xfffffffful) {
- if (bootverbose) printf ("is there (id=%08lx)\n", id);
- return 1;
- }
- }
- if (bootverbose)
- printf ("-- nothing found\n");
- return 0;
-}
-
-static void
-pcibus_setup (void)
-{
- unsigned long mode1res,oldval1;
- unsigned char mode2res,oldval2;
-
- oldval1 = inl (CONF1_ADDR_PORT);
-
- if (bootverbose) {
- printf ("pcibus_setup(1):\tmode 1 addr port (0x0cf8) is 0x%08lx\n", oldval1);
- }
-
- /*---------------------------------------
- ** Assume configuration mechanism 1 for now ...
- **---------------------------------------
- */
-
- if ((oldval1 & CONF1_ENABLE_MSK) == 0) {
-
- pci_mechanism = 1;
- pci_maxdevice = 32;
-
- outl (CONF1_ADDR_PORT, CONF1_ENABLE_CHK);
- outb (CONF1_ADDR_PORT +3, 0);
- mode1res = inl (CONF1_ADDR_PORT);
- outl (CONF1_ADDR_PORT, oldval1);
-
- if (bootverbose)
- printf ("pcibus_setup(1a):\tmode1res=0x%08lx (0x%08lx)\n",
- mode1res, CONF1_ENABLE_CHK);
-
- if (mode1res) {
- if (pcibus_check())
- return;
- };
-
- outl (CONF1_ADDR_PORT, CONF1_ENABLE_CHK1);
- mode1res = inl(CONF1_ADDR_PORT);
- outl (CONF1_ADDR_PORT, oldval1);
-
- if (bootverbose)
- printf ("pcibus_setup(1b):\tmode1res=0x%08lx (0x%08lx)\n",
- mode1res, CONF1_ENABLE_CHK1);
-
- if ((mode1res & CONF1_ENABLE_MSK1) == CONF1_ENABLE_RES1) {
- if (pcibus_check())
- return;
- };
- }
-
- /*---------------------------------------
- ** Try configuration mechanism 2 ...
- **---------------------------------------
- */
-
- oldval2 = inb (CONF2_ENABLE_PORT);
-
- if (bootverbose) {
- printf ("pcibus_setup(2):\tmode 2 enable port (0x0cf8) is 0x%02x\n", oldval2);
- }
-
- if ((oldval2 & 0xf0) == 0) {
-
- pci_mechanism = 2;
- pci_maxdevice = 16;
-
- outb (CONF2_ENABLE_PORT, CONF2_ENABLE_CHK);
- mode2res = inb(CONF2_ENABLE_PORT);
- outb (CONF2_ENABLE_PORT, oldval2);
-
- if (bootverbose)
- printf ("pcibus_setup(2a):\tmode2res=0x%02x (0x%02x)\n",
- mode2res, CONF2_ENABLE_CHK);
-
- if (mode2res == CONF2_ENABLE_RES) {
- if (bootverbose)
- printf ("pcibus_setup(2a):\tnow trying mechanism 2\n");
-
- if (pcibus_check())
- return;
- }
- }
-
- /*---------------------------------------
- ** No PCI bus host bridge found
- **---------------------------------------
- */
-
- pci_mechanism = 0;
- pci_maxdevice = 0;
-}
-
-/*--------------------------------------------------------------------
-**
-** Build a pcitag from bus, device and function number
-**
-**--------------------------------------------------------------------
-*/
-
-static pcici_t
-pcibus_tag (unsigned char bus, unsigned char device, unsigned char func)
-{
- pcici_t tag;
-
- tag.cfg1 = 0;
- if (func >= 8) return tag;
-
- switch (pci_mechanism) {
-
- case 1:
- if (device < 32) {
- tag.cfg1 = CONF1_ENABLE
- | (((u_long) bus ) << 16ul)
- | (((u_long) device) << 11ul)
- | (((u_long) func ) << 8ul);
- }
- break;
- case 2:
- if (device < 16) {
- tag.cfg2.port = 0xc000 | (device << 8ul);
- tag.cfg2.enable = 0xf0 | (func << 1ul);
- tag.cfg2.forward = bus;
- }
- break;
- };
- return tag;
-}
-
-static pcici_t
-pcibus_ftag (pcici_t tag, u_char func)
-{
- switch (pci_mechanism) {
-
- case 1:
- tag.cfg1 &= ~0x700ul;
- tag.cfg1 |= (((u_long) func) << 8ul);
- break;
- case 2:
- tag.cfg2.enable = 0xf0 | (func << 1ul);
- break;
- };
- return tag;
-}
-
-/*--------------------------------------------------------------------
-**
-** Read register from configuration space.
-**
-**--------------------------------------------------------------------
-*/
-
-static u_long
-pcibus_read (pcici_t tag, u_long reg)
-{
- u_long addr, data = 0;
-
- if (!tag.cfg1) return (0xfffffffful);
-
- switch (pci_mechanism) {
-
- case 1:
- addr = tag.cfg1 | (reg & 0xfc);
-#ifdef PCI_DEBUG
- printf ("pci_conf_read(1): addr=%x ", addr);
-#endif
- outl (CONF1_ADDR_PORT, addr);
- data = inl (CONF1_DATA_PORT);
- outl (CONF1_ADDR_PORT, 0 );
- break;
-
- case 2:
- addr = tag.cfg2.port | (reg & 0xfc);
-#ifdef PCI_DEBUG
- printf ("pci_conf_read(2): addr=%x ", addr);
-#endif
- outb (CONF2_ENABLE_PORT , tag.cfg2.enable );
- outb (CONF2_FORWARD_PORT, tag.cfg2.forward);
-
- data = inl ((u_short) addr);
-
- outb (CONF2_ENABLE_PORT, 0);
- outb (CONF2_FORWARD_PORT, 0);
- break;
- };
-
-#ifdef PCI_DEBUG
- printf ("data=%x\n", data);
-#endif
-
- return (data);
-}
-
-/*--------------------------------------------------------------------
-**
-** Write register into configuration space.
-**
-**--------------------------------------------------------------------
-*/
-
-static void
-pcibus_write (pcici_t tag, u_long reg, u_long data)
-{
- u_long addr;
-
- if (!tag.cfg1) return;
-
- switch (pci_mechanism) {
-
- case 1:
- addr = tag.cfg1 | (reg & 0xfc);
-#ifdef PCI_DEBUG
- printf ("pci_conf_write(1): addr=%x data=%x\n",
- addr, data);
-#endif
- outl (CONF1_ADDR_PORT, addr);
- outl (CONF1_DATA_PORT, data);
- outl (CONF1_ADDR_PORT, 0 );
- break;
-
- case 2:
- addr = tag.cfg2.port | (reg & 0xfc);
-#ifdef PCI_DEBUG
- printf ("pci_conf_write(2): addr=%x data=%x\n",
- addr, data);
-#endif
- outb (CONF2_ENABLE_PORT, tag.cfg2.enable);
- outb (CONF2_FORWARD_PORT, tag.cfg2.forward);
-
- outl ((u_short) addr, data);
-
- outb (CONF2_ENABLE_PORT, 0);
- outb (CONF2_FORWARD_PORT, 0);
- break;
- };
-}
-
-/*-----------------------------------------------------------------------
-**
-** Register an interupt handler for a pci device.
-**
-**-----------------------------------------------------------------------
-*/
-
-static int
-pcibus_ihandler_attach (int irq, inthand2_t *func, int arg, unsigned * maskptr)
-{
- char buf[16];
- char *cp;
- int free_id, id, result;
-
- sprintf(buf, "pci irq%d", irq);
- for (cp = intrnames, free_id = 0, id = 0; id < NR_DEVICES; id++) {
- if (strcmp(cp, buf) == 0)
- break;
- if (free_id <= 0 && strcmp(cp, "pci irqnn") == 0)
- free_id = id;
- while (*cp++ != '\0')
- ;
- }
- if (id == NR_DEVICES) {
- id = free_id;
- if (id == 0) {
- /*
- * All pci irq counters are in use, perhaps because
- * config is old so there aren't any. Abuse the
- * clk0 counter.
- */
- printf (
- "pcibus_ihandler_attach: counting pci irq%d's as clk0 irqs\n",
- irq);
- }
- }
- result = register_intr(
- irq, /* isa irq */
- id, /* device id */
- 0, /* flags? */
- func, /* handler */
- maskptr, /* mask pointer */
- arg); /* handler arg */
-
- if (result) {
- printf ("@@@ pcibus_ihandler_attach: result=%d\n", result);
- return (result);
- };
- update_intr_masks();
-
- INTREN ((1ul<<irq));
- return (0);
-}
-
-static int
-pcibus_ihandler_detach (int irq, inthand2_t *func)
-{
- int result;
-
- INTRDIS ((1ul<<irq));
-
- result = unregister_intr (irq, func);
-
- if (result)
- printf ("@@@ pcibus_ihandler_detach: result=%d\n", result);
-
- update_intr_masks();
-
- return (result);
-}
-
-static int
-pcibus_imask_include (int irq, unsigned* maskptr)
-{
- unsigned mask;
-
- if (!maskptr) return (0);
-
- mask = 1ul << irq;
-
- if (*maskptr & mask)
- return (-1);
-
- INTRMASK (*maskptr, mask);
- update_intr_masks();
-
- return (0);
-}
-
-static int
-pcibus_imask_exclude (int irq, unsigned* maskptr)
-{
- unsigned mask;
-
- if (!maskptr) return (0);
-
- mask = 1ul << irq;
-
- if (! (*maskptr & mask))
- return (-1);
-
- *maskptr &= ~mask;
- update_intr_masks();
-
- return (0);
-}
diff --git a/sys/pc98/pc98/prof_machdep.c b/sys/pc98/pc98/prof_machdep.c
deleted file mode 100644
index 50e7c3b..0000000
--- a/sys/pc98/pc98/prof_machdep.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * NEED A COPYRIGHT NOPTICE HERE
- *
- * $Id: prof_machdep.c,v 1.2 1996/04/08 16:41:06 wollman Exp $
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <machine/clock.h>
-#ifdef PC98
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/timerreg.h>
-#else
-#include <i386/isa/isa.h>
-#include <i386/isa/timerreg.h>
-#endif
-
-#ifdef GUPROF
-extern u_int cputime __P((void));
-#endif
-
-#ifdef __GNUC__
-asm("
-GM_STATE = 0
-GMON_PROF_OFF = 3
-
- .text
- .align 4,0x90
- .globl __mcount
-__mcount:
- #
- # Check that we are profiling. Do it early for speed.
- #
- cmpl $GMON_PROF_OFF,__gmonparam+GM_STATE
- je Lmcount_exit
- #
- # __mcount is the same as mcount except the caller hasn't changed
- # the stack except to call here, so the caller's raddr is above
- # our raddr.
- #
- movl 4(%esp),%edx
- jmp Lgot_frompc
-
- .align 4,0x90
- .globl mcount
-mcount:
- cmpl $GMON_PROF_OFF,__gmonparam+GM_STATE
- je Lmcount_exit
- #
- # The caller's stack frame has already been built, so %ebp is
- # the caller's frame pointer. The caller's raddr is in the
- # caller's frame following the caller's caller's frame pointer.
- #
- movl 4(%ebp),%edx
-Lgot_frompc:
- #
- # Our raddr is the caller's pc.
- #
- movl (%esp),%eax
-
- pushf
- pushl %eax
- pushl %edx
- cli
- call _mcount
- addl $8,%esp
- popf
-Lmcount_exit:
- ret
-");
-#else /* !__GNUC__ */
-#error
-#endif /* __GNUC__ */
-
-#ifdef GUPROF
-/*
- * mexitcount saves the return register(s), loads selfpc and calls
- * mexitcount(selfpc) to do the work. Someday it should be in a machine
- * dependent file together with cputime(), __mcount and mcount. cputime()
- * can't just be put in machdep.c because it has to be compiled without -pg.
- */
-#ifdef __GNUC__
-asm("
- .text
-#
-# Dummy label to be seen when gprof -u hides mexitcount.
-#
- .align 4,0x90
- .globl __mexitcount
-__mexitcount:
- nop
-
-GMON_PROF_HIRES = 4
-
- .align 4,0x90
- .globl mexitcount
-mexitcount:
- cmpl $GMON_PROF_HIRES,__gmonparam+GM_STATE
- jne Lmexitcount_exit
- pushl %edx
- pushl %eax
- movl 8(%esp),%eax
- pushf
- pushl %eax
- cli
- call _mexitcount
- addl $4,%esp
- popf
- popl %eax
- popl %edx
-Lmexitcount_exit:
- ret
-");
-#else /* !__GNUC__ */
-#error
-#endif /* __GNUC__ */
-
-/*
- * Return the time elapsed since the last call. The units are machine-
- * dependent.
- */
-u_int
-cputime()
-{
- u_int count;
- u_int delta;
- u_char low;
- static u_int prev_count;
-
- /*
- * Read the current value of the 8254 timer counter 0.
- */
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
- low = inb(TIMER_CNTR0);
- count = low | (inb(TIMER_CNTR0) << 8);
-
- /*
- * The timer counts down from TIMER_CNTR0_MAX to 0 and then resets.
- * While profiling is enabled, this routine is called at least twice
- * per timer reset (for mcounting and mexitcounting hardclock()),
- * so at most one reset has occurred since the last call, and one
- * has occurred iff the current count is larger than the previous
- * count. This allows counter underflow to be detected faster
- * than in microtime().
- */
- delta = prev_count - count;
- prev_count = count;
- if ((int) delta <= 0)
- return (delta + timer0_max_count);
- return (delta);
-}
-#else /* not GUPROF */
-#ifdef __GNUC__
-asm("
- .text
- .align 4,0x90
- .globl mexitcount
-mexitcount:
- ret
-");
-#else /* !__GNUC__ */
-#error
-#endif /* __GNUC__ */
-#endif /* GUPROF */
diff --git a/sys/pc98/pc98/random_machdep.c b/sys/pc98/pc98/random_machdep.c
deleted file mode 100644
index 13ced6f..0000000
--- a/sys/pc98/pc98/random_machdep.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * random_machdep.c -- A strong random number generator
- *
- * $Id: random_machdep.c,v 1.7 1996/10/09 21:46:41 asami Exp $
- *
- * Version 0.95, last modified 18-Oct-95
- *
- * Copyright Theodore Ts'o, 1994, 1995. 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, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 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. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * ALTERNATIVELY, this product may be distributed under the terms of
- * the GNU Public License, in which case the provisions of the GPL are
- * required INSTEAD OF the above restrictions. (This clause is
- * necessary due to a potential bad interaction between the GPL and
- * the restrictions contained in a BSD-style copyright.)
- *
- * THIS SOFTWARE IS PROVIDED ``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.
- */
-
-/*
- * modified for PC-9801 by KATO T. of Nagoya University
- */
-
-#include "opt_cpu.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/select.h>
-#include <sys/fcntl.h>
-
-#include <machine/clock.h>
-#include <machine/random.h>
-
-#include <i386/isa/icu.h>
-#ifdef PC98
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/timerreg.h>
-#else
-#include <i386/isa/isa.h>
-#include <i386/isa/timerreg.h>
-#endif
-
-#define MAX_BLKDEV 4
-
-/*
- * The pool is stirred with a primitive polynomial of degree 128
- * over GF(2), namely x^128 + x^99 + x^59 + x^31 + x^9 + x^7 + 1.
- * For a pool of size 64, try x^64+x^62+x^38+x^10+x^6+x+1.
- */
-#define POOLWORDS 128 /* Power of 2 - note that this is 32-bit words */
-#define POOLBITS (POOLWORDS*32)
-
-#if POOLWORDS == 128
-#define TAP1 99 /* The polynomial taps */
-#define TAP2 59
-#define TAP3 31
-#define TAP4 9
-#define TAP5 7
-#elif POOLWORDS == 64
-#define TAP1 62 /* The polynomial taps */
-#define TAP2 38
-#define TAP3 10
-#define TAP4 6
-#define TAP5 1
-#else
-#error No primitive polynomial available for chosen POOLWORDS
-#endif
-
-#define WRITEBUFFER 512 /* size in bytes */
-
-/* There is actually only one of these, globally. */
-struct random_bucket {
- u_int add_ptr;
- u_int entropy_count;
- int input_rotate;
- u_int32_t *pool;
- struct selinfo rsel;
-};
-
-/* There is one of these per entropy source */
-struct timer_rand_state {
- u_long last_time;
- int last_delta;
- int nbits;
-};
-
-static struct random_bucket random_state;
-static u_int32_t random_pool[POOLWORDS];
-static struct timer_rand_state keyboard_timer_state;
-static struct timer_rand_state extract_timer_state;
-static struct timer_rand_state irq_timer_state[ICU_LEN];
-#ifdef notyet
-static struct timer_rand_state blkdev_timer_state[MAX_BLKDEV];
-#endif
-static struct wait_queue *random_wait;
-
-inthand2_t *sec_intr_handler[ICU_LEN];
-int sec_intr_unit[ICU_LEN];
-
-#ifndef MIN
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
-void
-rand_initialize(void)
-{
- random_state.add_ptr = 0;
- random_state.entropy_count = 0;
- random_state.pool = random_pool;
- random_wait = NULL;
- random_state.rsel.si_flags = 0;
- random_state.rsel.si_pid = 0;
-}
-
-/*
- * This function adds an int into the entropy "pool". It does not
- * update the entropy estimate. The caller must do this if appropriate.
- *
- * The pool is stirred with a primitive polynomial of degree 128
- * over GF(2), namely x^128 + x^99 + x^59 + x^31 + x^9 + x^7 + 1.
- * For a pool of size 64, try x^64+x^62+x^38+x^10+x^6+x+1.
- *
- * We rotate the input word by a changing number of bits, to help
- * assure that all bits in the entropy get toggled. Otherwise, if we
- * consistently feed the entropy pool small numbers (like ticks and
- * scancodes, for example), the upper bits of the entropy pool don't
- * get affected. --- TYT, 10/11/95
- */
-static inline void
-add_entropy_word(struct random_bucket *r, const u_int32_t input)
-{
- u_int i;
- u_int32_t w;
-
- w = (input << r->input_rotate) | (input >> (32 - r->input_rotate));
- i = r->add_ptr = (r->add_ptr - 1) & (POOLWORDS-1);
- if (i)
- r->input_rotate = (r->input_rotate + 7) & 31;
- else
- /*
- * At the beginning of the pool, add an extra 7 bits
- * rotation, so that successive passes spread the
- * input bits across the pool evenly.
- */
- r->input_rotate = (r->input_rotate + 14) & 31;
-
- /* XOR in the various taps */
- w ^= r->pool[(i+TAP1)&(POOLWORDS-1)];
- w ^= r->pool[(i+TAP2)&(POOLWORDS-1)];
- w ^= r->pool[(i+TAP3)&(POOLWORDS-1)];
- w ^= r->pool[(i+TAP4)&(POOLWORDS-1)];
- w ^= r->pool[(i+TAP5)&(POOLWORDS-1)];
- w ^= r->pool[i];
- /* Rotate w left 1 bit (stolen from SHA) and store */
- r->pool[i] = (w << 1) | (w >> 31);
-}
-
-/*
- * This function adds entropy to the entropy "pool" by using timing
- * delays. It uses the timer_rand_state structure to make an estimate
- * of how any bits of entropy this call has added to the pool.
- *
- * The number "num" is also added to the pool - it should somehow describe
- * the type of event which just happened. This is currently 0-255 for
- * keyboard scan codes, and 256 upwards for interrupts.
- * On the i386, this is assumed to be at most 16 bits, and the high bits
- * are used for a high-resolution timer.
- */
-static void
-add_timer_randomness(struct random_bucket *r, struct timer_rand_state *state,
- u_int num)
-{
- int delta, delta2;
- u_int nbits;
- u_int32_t time;
-
-#if defined(I586_CPU) || defined(I686_CPU)
- if (i586_ctr_freq != 0) {
- num ^= (u_int32_t) rdtsc() << 16;
- r->entropy_count += 2;
- } else {
-#endif
- disable_intr();
- outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
- num ^= inb(TIMER_CNTR0) << 16;
- num ^= inb(TIMER_CNTR0) << 24;
- enable_intr();
- r->entropy_count += 2;
-#if defined(I586_CPU) || defined(I686_CPU)
- }
-#endif
-
- time = ticks;
-
- add_entropy_word(r, (u_int32_t) num);
- add_entropy_word(r, time);
-
- /*
- * Calculate number of bits of randomness we probably
- * added. We take into account the first and second order
- * deltas in order to make our estimate.
- */
- delta = time - state->last_time;
- state->last_time = time;
-
- delta2 = delta - state->last_delta;
- state->last_delta = delta;
-
- if (delta < 0) delta = -delta;
- if (delta2 < 0) delta2 = -delta2;
- delta = MIN(delta, delta2) >> 1;
- for (nbits = 0; delta; nbits++)
- delta >>= 1;
-
- r->entropy_count += nbits;
-
- /* Prevent overflow */
- if (r->entropy_count > POOLBITS)
- r->entropy_count = POOLBITS;
-
- if (r->entropy_count >= 8)
- selwakeup(&random_state.rsel);
-}
-
-void
-add_keyboard_randomness(u_char scancode)
-{
- add_timer_randomness(&random_state, &keyboard_timer_state, scancode);
-}
-
-void
-add_interrupt_randomness(int irq)
-{
- (sec_intr_handler[irq])(sec_intr_unit[irq]);
- add_timer_randomness(&random_state, &irq_timer_state[irq], irq);
-}
-
-#ifdef notused
-void
-add_blkdev_randomness(int major)
-{
- if (major >= MAX_BLKDEV)
- return;
-
- add_timer_randomness(&random_state, &blkdev_timer_state[major],
- 0x200+major);
-}
-#endif /* notused */
-
-/*
- * MD5 transform algorithm, taken from code written by Colin Plumb,
- * and put into the public domain
- *
- * QUESTION: Replace this with SHA, which as generally received better
- * reviews from the cryptographic community?
- */
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
- ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data. MD5Update blocks
- * the data and converts bytes into longwords for this routine.
- */
-static void
-MD5Transform(u_int32_t buf[4],
- u_int32_t const in[16])
-{
- u_int32_t a, b, c, d;
-
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
-
- MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
-
- MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
-
- MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
-}
-
-#undef F1
-#undef F2
-#undef F3
-#undef F4
-#undef MD5STEP
-
-
-#if POOLWORDS % 16
-#error extract_entropy() assumes that POOLWORDS is a multiple of 16 words.
-#endif
-/*
- * This function extracts randomness from the "entropy pool", and
- * returns it in a buffer. This function computes how many remaining
- * bits of entropy are left in the pool, but it does not restrict the
- * number of bytes that are actually obtained.
- */
-static inline int
-extract_entropy(struct random_bucket *r, char *buf, int nbytes)
-{
- int ret, i;
- u_int32_t tmp[4];
-
- add_timer_randomness(r, &extract_timer_state, nbytes);
-
- /* Redundant, but just in case... */
- if (r->entropy_count > POOLBITS)
- r->entropy_count = POOLBITS;
- /* Why is this here? Left in from Ted Ts'o. Perhaps to limit time. */
- if (nbytes > 32768)
- nbytes = 32768;
-
- ret = nbytes;
- if (r->entropy_count / 8 >= nbytes)
- r->entropy_count -= nbytes*8;
- else
- r->entropy_count = 0;
-
- while (nbytes) {
- /* Hash the pool to get the output */
- tmp[0] = 0x67452301;
- tmp[1] = 0xefcdab89;
- tmp[2] = 0x98badcfe;
- tmp[3] = 0x10325476;
- for (i = 0; i < POOLWORDS; i += 16)
- MD5Transform(tmp, r->pool+i);
- /* Modify pool so next hash will produce different results */
- add_entropy_word(r, tmp[0]);
- add_entropy_word(r, tmp[1]);
- add_entropy_word(r, tmp[2]);
- add_entropy_word(r, tmp[3]);
- /*
- * Run the MD5 Transform one more time, since we want
- * to add at least minimal obscuring of the inputs to
- * add_entropy_word(). --- TYT
- */
- MD5Transform(tmp, r->pool);
-
- /* Copy data to destination buffer */
- i = MIN(nbytes, 16);
- bcopy(tmp, buf, i);
- nbytes -= i;
- buf += i;
- }
-
- /* Wipe data from memory */
- bzero(tmp, sizeof(tmp));
-
- return ret;
-}
-
-#ifdef notused /* XXX NOT the exported kernel interface */
-/*
- * This function is the exported kernel interface. It returns some
- * number of good random numbers, suitable for seeding TCP sequence
- * numbers, etc.
- */
-void
-get_random_bytes(void *buf, u_int nbytes)
-{
- extract_entropy(&random_state, (char *) buf, nbytes);
-}
-#endif /* notused */
-
-u_int
-read_random(char *buf, u_int nbytes)
-{
- if ((nbytes * 8) > random_state.entropy_count)
- nbytes = random_state.entropy_count / 8;
-
- return extract_entropy(&random_state, buf, nbytes);
-}
-
-u_int
-read_random_unlimited(char *buf, u_int nbytes)
-{
- return extract_entropy(&random_state, buf, nbytes);
-}
-
-#ifdef notused
-u_int
-write_random(const char *buf, u_int nbytes)
-{
- u_int i;
- u_int32_t word, *p;
-
- for (i = nbytes, p = (u_int32_t *)buf;
- i >= sizeof(u_int32_t);
- i-= sizeof(u_int32_t), p++)
- add_entropy_word(&random_state, *p);
- if (i) {
- word = 0;
- bcopy(p, &word, i);
- add_entropy_word(&random_state, word);
- }
- return nbytes;
-}
-#endif /* notused */
-
-int
-random_select(dev_t dev, int rw, struct proc *p)
-{
- int s, ret;
-
- if (rw == FWRITE)
- return 1; /* heh. */
-
- s = splhigh();
- if (random_state.entropy_count >= 8)
- ret = 1;
- else {
- selrecord(p, &random_state.rsel);
- ret = 0;
- }
- splx(s);
-
- return ret;
-}
-
diff --git a/sys/pc98/pc98/sound/CHANGELOG b/sys/pc98/pc98/sound/CHANGELOG
deleted file mode 100644
index e21dfaa..0000000
--- a/sys/pc98/pc98/sound/CHANGELOG
+++ /dev/null
@@ -1,122 +0,0 @@
-Changelog for version 3.0-950506
-------------------------------------
-
-Since 3.0-94xxxx
-- Too many changes
-
-Since 3.0-940818
-- Fixes for Linux 1.1.4x.
-- Disables Disney Sound System with SG NX Pro 16 (less noise).
-
-Since 2.90-2
-- Fixes to soundcard.h
-- Non blocking mode to /dev/sequencer
-- Experimental detection code for Ensoniq Soundscape.
-
-Since 2.90
-- Minor and major bug fixes
-
-Since pre-3.0-940712
-- GUS MAX support
-- Partially working MSS/WSS support (could work with some cards).
-- Hardware u-Law and A-Law support with AD1848/CS4248 and CS4231 codecs
- (GUS MAX, GUS16, WSS etc). Hardware ADPCM is possible with GUS16 and
- GUS MAX, but it doesn't work yet.
-Since pre-3.0-940426
-- AD1848/CS4248/CS4231 codec support (MSS, GUS MAX, Aztec, Orchid etc).
-This codec chip is used in various soundcards. This version is developed
-for the 16 bit daughtercard of GUS. It should work with other cards also
-if the following requirements are met:
- - The I/O, IRQ and DMA settings are jumper selectable or
- the card is initialized by booting DOS before booting Linux (etc.).
- - You add the IO, IRQ and DMA settings manually to the local.h.
- (Just define GUS16_BASE, GUS16_IRQ and GUS16_DMA). Note that
- the base address bust be the base address of the codec chip not the
- card itself. For the GUS16 these are the same but most MSS compatible
- cards have the codec located at card_base+4.
-- Some minor changes
-
-Since 2.5 (******* MAJOR REWRITE ***********)
-
-This version is based on v2.3. I have tried to maintain two versions
-together so that this one should have the same features than v2.5.
-Something may still be missing. If you notice such things, please let me
-know.
-
-The Readme.v30 contains more details.
-
-- /dev/midi## devices.
-- /dev/sequencer2
-
-Since 2.5-beta2
-- Some fine tuning to the GUS v3.7 mixer code.
-- Fixed speed limits for the plain SB (1.0 to 2.0).
-
-Since 2.5-beta
-- Fixed OPL-3 detection with SB. Caused problems with PAS16.
-- GUS v3.7 mixer support.
-
-Since 2.4
-- Mixer support for Sound Galaxy NX Pro (define __SGNXPRO__ on your local.h).
-- Fixed truncated sound on /dev/dsp when the device is closed.
-- Linear volume mode for GUS
-- Pitch bends larger than +/- 2 octaves.
-- MIDI recording for SB and SB Pro. (Untested).
-- Some other fixes.
-- SB16 MIDI and DSP drivers only initialized if SB16 actually installed.
-- Implemented better detection for OPL-3. This should be useful if you
- have an old SB Pro (the non-OPL-3 one) or a SB 2.0 clone which has a OPL-3.
-- SVR4.2 support by Ian Hartas. Initial ALPHA TEST version (untested).
-
-Since 2.3b
-- Fixed bug which made it impossible to make long recordings to disk.
- Recording was not restarted after a buffer overflow situation.
-- Limited mixer support for GUS.
-- Numerous improvements to the GUS driver by Andrew Robinson. Including
- some click removal etc.
-
-Since 2.3
-- Fixed some minor bugs in the SB16 driver.
-
-Since 2.2b
-- Full SB16 DSP support. 8/16 bit, mono/stereo
-- The SCO and FreeBSD versions should be in sync now. There are some
- problems with SB16 and GUS in the freebsd versions.
- The DMA buffer allocation of the SCO version has been polished but
- there could still be some problems. At least it hogs memory.
- The DMA channel
- configuration method used in the sco/System is a hack.
-- Support for the MPU emulation of the SB16.
-- Some big arrays are now allocated boot time. This makes the bss segment
- smaller which makes it possible to use the full driver with
- NetBSD. These arrays are not allocated if no suitable soundcard is available.
-- Fixed a bug in the compute_and_set_volume in gus_wave.c
-- Fixed the too fast mono playback problem of SB Pro and PAS16.
-
-Since 2.2
-- Stereo recording for SB Pro. Somehow it was missing and nobody
- had noticed it earlier.
-- Minor polishing.
-- Interpreting of boot time arguments (sound=) for Linux.
-- Breakup of sb_dsp.c. Parts of the code has been moved to
- sb_mixer.c and sb_midi.c
-
-Since 2.1
-- Preliminary support for SB16.
- - The SB16 mixer is supported in it's native mode.
- - Digitized voice capability up to 44.1 kHz/8 bit/mono
- (16 bit and stereo support coming in the next release).
-- Fixed some bugs in the digitized voice driver for PAS16.
-- Proper initialization of the SB emulation of latest PAS16 models.
-
-- Significantly improved /dev/dsp and /dev/audio support.
- - Now supports half duplex mode. It's now possible to record and
- playback without closing and reopening the device.
- - It's possible to use smaller buffers than earlier. There is a new
- ioctl(fd, SNDCTL_DSP_SUBDIVIDE, &n) where n should be 1, 2 or 4.
- This call instructs the driver to use smaller buffers. The default
- buffer size (0.5 to 1.0 seconds) is divided by n. Should be called
- immediately after opening the device.
-
-Since 2.0
-Just cosmetic changes.
diff --git a/sys/pc98/pc98/sound/README b/sys/pc98/pc98/sound/README
deleted file mode 100644
index 1c31ac6..0000000
--- a/sys/pc98/pc98/sound/README
+++ /dev/null
@@ -1,86 +0,0 @@
-VoxWare v2.90 release notes
---------------------------
-
-
- This version includes some hidden features which
- are described in the file experimental.txt
- Some of these features are not enabled by default. Look at
- experimental.txt for more info.
-
- I just decided to release this version with some
- incompletely implemented features disabled since
- there are some new features required by a popular
- application. In addition there is also support
- for the GUS MAX and the 16 bit sampling option of GUS.
-
- The MSS/WSS support works now. At least with SG NX Pro 16.
-
-********* IMPORTANT *****************************************
-Linux 1.0 or later is required to by this driver version.
-
-Don't distribute binaries which use /dev/sequencer and are
-compiled with the soundcard.h of this version. They will
-not work with version 2.x of the driver.
-*************************************************************
-
-
-You will need the snd-util-2.5.tar.gz and snd-data-0.1.tar.Z
-packages to use this driver. They should be in the same
-ftp site or BBS from where you got this driver. For
-example at nic.funet.fi:pub/OS/Linux/*.
-
-If you are looking for the installation instructions, please
-look at linux/Readme.
-
-Compatibility with the earlier versions
----------------------------------------
-
-This version is backward compatible with the version 2.X. All programs
-compiled with sys/soundcard.h of v2.X should work without problems.
-PROGRAMS COMPILED WITH THE sys/soundcard.h OF THIS VERSION WILL NOT
-WORK WITH v2.X DRIVER. BE CAREFUL WHEN DISTRIBUTING BINARIES COMPILED
-FOR THIS VERSION.
-
-Contributors
-------------
-
-This driver contains code by several contributors. In addition several other
-persons have given useful suggestions. The following is a list of major
-contributors. (I could have forgotten some names.)
-
- Craig Metz 1/2 of the PAS16 Mixer and PCM support
- Rob Hooft Volume computation algorithm for the FM synth.
- Mika Liljeberg uLaw encoding and decoding routines
- Greg Lee Volume computation algorithm for the GUS and
- lot's of valuable suggestions.
- Andy Warner ISC port
- Jim Lowe FreeBSD port
- Anders Baekgaard Bughunting and valuable suggestions.
- Joerg Schubert SB16 DSP support.
- Andrew Robinson Improvements to the GUS driver
- Megens SA MIDI recording for SB and SB Pro.
- Mikael Nordqvist Linear volume support for GUS.
- Mikael Nordqvist Linear volume support for GUS.
- Ian Hartas SVR4.2 port
- Markus Aroharju and
- Risto Kankkunen Major contributions to the mixer support
- of GUS v3.7.
- Hunyue Yau Mixer support for SG NX Pro.
- Marc Hoffman PSS support.
-
-Regards,
-
-Hannu Savolainen
-hannu@voxware.pp.fi
-
-Snail mail: Hannu Savolainen
- Hiekkalaiturintie 3 A 8
- 00980 Helsinki
- Finland
-FAX: +358 0 341 6272 (answers if I have my machine (mgetty) on).
-
-NOTE! I probably don't answer to Snail mail or FAX messages. Sending answer
- to each of them is simply too expensive and time consuming. However I
- try to reply every email message I get (within a week). If you don't
- get response, please check how your address is written in the message
- header. I can't answer if I don't have a valid reply address.
diff --git a/sys/pc98/pc98/sound/Readme.aedsp16 b/sys/pc98/pc98/sound/Readme.aedsp16
deleted file mode 100644
index b205a9d..0000000
--- a/sys/pc98/pc98/sound/Readme.aedsp16
+++ /dev/null
@@ -1,6 +0,0 @@
-Informations about Audio Excel DSP 16 can be found in the source
-file aedsp16.c
-Please, read the head of the source before using it. It contain useful
-informations.
-
- Riccardo
diff --git a/sys/pc98/pc98/sound/Readme.modules b/sys/pc98/pc98/sound/Readme.modules
deleted file mode 100644
index 315540f..0000000
--- a/sys/pc98/pc98/sound/Readme.modules
+++ /dev/null
@@ -1,87 +0,0 @@
- Linux sound-driver module
- (c) Peter Trattler
- License: GPL (Gnu Public License)
-
-
-Idea:
-
-I've modified the sources for the sound driver to allow simply insert and
-remove the sound driver from the kernel by calling (only available for Linux)
-
- insmod /usr/src/linux/modules/sound.o
-
-and
-
- rmmod sound
-
-This may be useful if you are doing one of the following things:
-
-1) Debugging the sound driver
-2) Creating a new device within the sound-driver
-3) You do not the sound driver all the time (as it wastes quite a lot of
-memory for its buffers)
-
-
-Compilation:
-
-Go to /usr/src/linux and make the following steps:
-
-a) configure the sound driver: To do that call "make config" and enable the
-sound-driver -- you will be asked different questions about your
-sound-hardware (remember not to use a too big DMA-Buffer size; you
-should use 16kB, if you have 16Bit devices, otherwise you can use 32kB)
-
-b) disable the sound driver in the kernel: call make config again but answer
-'N' to "Sound card support"
-
-c) run "make modules"; the sound-driver sound.o should end up in
-/usr/src/linux/modules
-
-
-If memory is tight:
-
-I've allocated at about 70kB for the sound-drivers internal tables. If this
-is too much, 'insmod sound.o' will generate the following warning
-...
-use 'insmod memsize=xxxx'
-...
-You can only use this command, if you have (I think) at least
-modules-1.1.87 or up. You can also switch debugging on by running the command
-
-insmod sound.o debugmem=1
-
-
-Files I changed:
-
-I've only changed the files soundcard.c(most changes) and some changes within
-the Makefile, sound_config.h and the Makefile in /usr/src/linux/drivers
-
-
-Bugs:
-
-a) As the kmalloc (..., GFP_DMA) caused some unexpected errors (I don't know if
-it is my fault), I created some code, which is (by default) enabled by
-
-#define KMALLOC_DMA_BROKEN 1 (within soundcard.c).
-
-It trys to allocate a large enough region, so that the complete dma-buffer
-can be occupied in this space. If it does not fit within this region it
-doubles the size of it. But this can cause problems, if the sound-buffer is
-too big (as kmalloc can only handle regions at up to circa 100kB).
-
-So take care to use for 8Bit devices a sound-DMA-buffer of 32kB (maximum)
-and for 16Bit devices a maximum of 16kB. Otherwise the allocation scheme
-might fail.
-
-b) Buffers allocated by the different sound devices via calls to kmalloc are
-not freed, if the sound driver is removed again (these buffers tend to be
-quite small -- so it does not harm a lot)
-
-c) If there is not enough (kernel-) memory available, the installation of
-the sound-driver fails. (This happens quite often, if you did not install the
-driver right after booting -- [PS: I've only got 5MB of Ram, so this might
-be the source for this problem])
-
-
-Author:
- Peter Trattler (peter@sbox.tu-graz.ac.at)
diff --git a/sys/pc98/pc98/sound/Readme.v30 b/sys/pc98/pc98/sound/Readme.v30
deleted file mode 100644
index 8884ad8..0000000
--- a/sys/pc98/pc98/sound/Readme.v30
+++ /dev/null
@@ -1,142 +0,0 @@
-VoxWare v3.0
-------------
-
-This is a late alpha/early beta of the VoxWare v3.0 to be relased May/June 95.
-
-All features of v2.90-2 should work as earlier. There could be some
-omissions but they are unintentional. I started this version thread
-after v2.3 so all features implemented before it are there.
-
-New features
-============
-
-There are now two new device interfaces. The /dev/midi## is a raw
-tty like interface to MIDI ports. There is a device file for each MIDI
-port on your system. They are named (/dev/midi00 to /dev/midiNN).
-The second addition is the /dev/music which is higher level interface
-than the old /dev/sequencer. It's intended for writing device independent
-applications like sequencers.
-
-/dev/midi##
------------
-
-This interface should be usefull for applications like MIDI sysex librarians.
-There are (currently) no timing features so making music could be impossible.
-
-There are as many /dev/midi## devices as there are MIDI ports in the system.
-The /dev/midi00 is connected to the first one, /dev/midi01 to the second etc.
-
-These devices work like tty devices in raw mode. Everything written to them is
-sent out to the MIDI port. There is currently an extra delay of at most
-1/100th of sec but it will be removed later.
-
-The reading algorithm is little bit more complicated. There are two different
-cases:
-
-1) There is at least one byte in the input buffer.
-
-The read returns as many bytes as it can without waiting for more bytes.
-For example when a process reads 100 bytes and there are 10 bytes in the
-buffer, the read returns just 10 bytes.
-
-2) The input buffer is empty when the process calls read.
-
-The read waits for the first byte and then continues as in case 1. By
-default it waits infinitely but there is an ioctl for setting a timeout
-for this. The ioctl(fd, SNDCTL_MIDI_PRETIME, &time) changes the timeout.
-The time is given in 1/10th of seconds (10 means one second).
-
-Other ioctl calls:
-
-ioctl(fd, SNDCTL_MIDI_MPUMODE, &mode) is available for full MPU-401
-compatible devices such as MPU-IPC-T, MQ PC Midi Card or MQX-32.
-It's not available for the so called MPU UART ports of some soundcards
-(PAS16, SB16 etc). By default the MIDI port is in UART mode after open.
-If this ioctl is called with mode=1, the interface is put to the intelligent
-(coprocessor) mode. NOTE! The MIDI port will be reset when this ioctl is called.
-It could have some strange effects if not called immediately after open. This
-vall returns EINVAL if the midi port doesn't support the MPU-401 intelligent
-mode.
-
-ioctl(fd, SNDCTL_MIDI_MPUCMD, &cmdstruct) is valid only if the MIDI port
-is put to the coprocessor mode using ioctl(SNDCTL_MIDI_MPUMODE). It's used to
-send commands to a MPU-401 compatible MIDI cards. Please refer to the
-MPU-401 Technical Reference Manual (or Music Quest Technical Reference
-Manual) for descriptions of the commands.
-
-The argument of SNDCTL_MIDI_MPUCOMMAND is of type mpu_command_rec. It
-has the following fields:
-
-typedef struct {
- unsigned char cmd;
-
- char nr_args, nr_returns;
- unsigned char data[30];
- } mpu_command_rec;
-
-where:
- cmd Contains the command number.
- nr_args Number of arguments of the command.
- MUST BE INITIALIZED BEFORE CALL
- nr_returns Number of bytes returned by the command.
- MUST BE INITIALIZED BEFORE CALL
- data Buffer for the command arguments and returned
- data.
-
-Be extremely carefull with the nr_args and nr_returns fields. They
-must match the command. An incorrect value will put the card and
-the driver out of sync. Refer to the MPU-401/MQX-32M documentation for further
-datails.
-
-
-
-/dev/music (/dev/sequencer2)
-----------------------------
-
-This device file works much like the /dev/sequencer which has been present
-since the beginning. The main differences are the following:
-
-- /dev/sequencer makes the MIDI ports to look like the synth devices. In fact
-the result is somewhere between the MIDI specification and the synth devices of
-/dev/sequencer. Both kind of devices are accessed using the SEQ_START_NOTE()
-like macros. The voice number parameters of the API macros have been redefined
-to denote MIDI channels. This means that the driver allocates voices for
-the channels automaticly (this is a responsibility/right of an application
-with /dev/sequencer). The result is that a SEQ_START_NOTE() macro has
-similar effects for a synth channel than on a MIDI port. This kind of
-solution provides better device independence than the /dev/sequencer. The
-drawback is that the new interface doesn't permit so low level access to the
-device as the /dev/sequencer does. An application developer must choose between
-these two interfaces. I think the old /dev/sequencer is better for applications
-like module players while the new one is better for making generic sequencer
-programs.
-
-- There are no separate MIDI devices with the /dev/sequencer2. The
-ioctl(SNDCTL_SEQ_NRMIDIS) returns always zero. Instead the MIDI ports are
-shown as synth devices. ioctl(SNDCTL_SEQ_NRSYNTHS) on /dev/sequencer2 will
-return sum of internal synthesizers (GUS, OPL3) and MIDI ports in the systems.
-
-- The new interface is used much like the ordinary /dev/sequencer. The
-event format is new so you have to use the API macros defined in the
-sys/soundcard.h. The interface is will propably change before the final 3.0
-release but using the API macros should ensure compatibility in source level.
-The new event format is not recognized by version 2.X so don't try to
-distribute binaries compiled with soundcard.h of v3.X.
-
-- The basic API useage is similar to the current one. There are some new
-macros but the older ones should work as earlier. The most important
-incompatibility is that the /dev/sequencer2 driver allocates voices itself.
-The other one is that the application must send SEQ_START_TIMER() as it's
-first event. Otherwise the timer is not started and the application waits
-infinitely.
-
-
-There are several new features but I don't document them here. There are
-some info in the soundcard.h (near the end). I have also included some
-sample code in the directory v30. Full documentation will
-appear in the Hacker's Guide later.
-
-Don't hesitate to contact me in case you have questions or comments.
-
-Hannu Savolainen
-hannu@voxware.pp.fi
diff --git a/sys/pc98/pc98/sound/adlib_card.c b/sys/pc98/pc98/sound/adlib_card.c
deleted file mode 100644
index 4ec55b9..0000000
--- a/sys/pc98/pc98/sound/adlib_card.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * sound/adlib_card.c
- *
- * Detection routine for the AdLib card.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_YM3812)
-
-long
-attach_adlib_card (long mem_start, struct address_info *hw_config)
-{
-
- if (opl3_detect (FM_MONO))
- {
- mem_start = opl3_init (mem_start);
- }
- return mem_start;
-}
-
-int
-probe_adlib (struct address_info *hw_config)
-{
- return opl3_detect (FM_MONO);
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/audio.c b/sys/pc98/pc98/sound/audio.c
deleted file mode 100644
index 51e983d..0000000
--- a/sys/pc98/pc98/sound/audio.c
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * sound/audio.c
- *
- * Device file manager for /dev/audio
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-#ifdef CONFIGURE_SOUNDCARD
-#ifndef EXCLUDE_AUDIO
-
-#include <i386/isa/sound/ulaw.h>
-#include <i386/isa/sound/coproc.h>
-
-#define ON 1
-#define OFF 0
-
-static int wr_buff_no[MAX_AUDIO_DEV]; /*
-
- * != -1, if there is
- * a incomplete output
- * block in the queue.
- */
-static int wr_buff_size[MAX_AUDIO_DEV], wr_buff_ptr[MAX_AUDIO_DEV];
-
-static int audio_mode[MAX_AUDIO_DEV];
-static int dev_nblock[MAX_AUDIO_DEV]; /* 1 if in noblocking mode */
-
-#define AM_NONE 0
-#define AM_WRITE 1
-#define AM_READ 2
-
-static char *wr_dma_buf[MAX_AUDIO_DEV];
-static int audio_format[MAX_AUDIO_DEV];
-static int local_conversion[MAX_AUDIO_DEV];
-
-static int
-set_format (int dev, int fmt)
-{
- if (fmt != AFMT_QUERY)
- {
-
- local_conversion[dev] = 0;
-
- if (!(audio_devs[dev]->format_mask & fmt)) /* Not supported */
- if (fmt == AFMT_MU_LAW)
- {
- fmt = AFMT_U8;
- local_conversion[dev] = AFMT_MU_LAW;
- }
- else
- fmt = AFMT_U8; /* This is always supported */
-
- audio_format[dev] = DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, fmt, 1);
- }
-
- if (local_conversion[dev]) /* This shadows the HW format */
- return local_conversion[dev];
-
- return audio_format[dev];
-}
-
-int
-audio_open (int dev, struct fileinfo *file)
-{
- int ret;
- int bits;
- int dev_type = dev & 0x0f;
- int mode = file->mode & O_ACCMODE;
-
- dev = dev >> 4;
-
- if (dev_type == SND_DEV_DSP16)
- bits = 16;
- else
- bits = 8;
-
- if ((ret = DMAbuf_open (dev, mode)) < 0)
- return ret;
-
- if (audio_devs[dev]->coproc)
- if ((ret = audio_devs[dev]->coproc->
- open (audio_devs[dev]->coproc->devc, COPR_PCM)) < 0)
- {
- audio_release (dev, file);
- printk ("Sound: Can't access coprocessor device\n");
-
- return ret;
- }
-
- local_conversion[dev] = 0;
-
- if (DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, bits, 1) != bits)
- {
- audio_release (dev, file);
- return RET_ERROR (ENXIO);
- }
-
- if (dev_type == SND_DEV_AUDIO)
- {
- set_format (dev, AFMT_MU_LAW);
- }
- else
- set_format (dev, bits);
-
- wr_buff_no[dev] = -1;
- audio_mode[dev] = AM_NONE;
- wr_buff_size[dev] = wr_buff_ptr[dev] = 0;
- dev_nblock[dev] = 0;
-
- return ret;
-}
-
-void
-audio_release (int dev, struct fileinfo *file)
-{
- int mode;
-
- dev = dev >> 4;
- mode = file->mode & O_ACCMODE;
-
- if (wr_buff_no[dev] >= 0)
- {
- DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
-
- wr_buff_no[dev] = -1;
- }
-
- if (audio_devs[dev]->coproc)
- audio_devs[dev]->coproc->close (audio_devs[dev]->coproc->devc, COPR_PCM);
- DMAbuf_release (dev, mode);
-}
-
-#ifdef NO_INLINE_ASM
-static void
-translate_bytes (const unsigned char *table, unsigned char *buff, unsigned long n)
-{
- unsigned long i;
-
- for (i = 0; i < n; ++i)
- buff[i] = table[buff[i]];
-}
-
-#else
-static inline void
-translate_bytes (const void *table, void *buff, unsigned long n)
-{
- __asm__ ("cld\n"
- "1:\tlodsb\n\t"
- "xlatb\n\t"
- "stosb\n\t"
-"loop 1b\n\t":
-: "b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
-: "bx", "cx", "di", "si", "ax");
-}
-
-#endif
-
-int
-audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- int c, p, l;
- int err;
-
- dev = dev >> 4;
-
- p = 0;
- c = count;
-
- if (audio_mode[dev] == AM_READ) /*
- * Direction changed
- */
- {
- wr_buff_no[dev] = -1;
- }
-
- audio_mode[dev] = AM_WRITE;
-
- if (!count) /*
- * Flush output
- */
- {
- if (wr_buff_no[dev] >= 0)
- {
- DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
-
- wr_buff_no[dev] = -1;
- }
- return 0;
- }
-
- while (c)
- { /*
- * Perform output blocking
- */
- if (wr_buff_no[dev] < 0) /*
- * There is no incomplete buffers
- */
- {
- if ((wr_buff_no[dev] = DMAbuf_getwrbuffer (dev, &wr_dma_buf[dev],
- &wr_buff_size[dev],
- dev_nblock[dev])) < 0)
- {
- /* Handle nonblocking mode */
-#if defined(__FreeBSD__)
- if (dev_nblock[dev] && wr_buff_no[dev] == RET_ERROR (EWOULDBLOCK))
- return wr_buff_no[dev]; /*
- * XXX Return error, write() will
- * supply # of accepted bytes.
- * In fact, in FreeBSD the check
- * above should not be needed
- */
-#else
- if (dev_nblock[dev] && wr_buff_no[dev] == RET_ERROR (EAGAIN))
- return p; /* No more space. Return # of accepted bytes */
-#endif
- return wr_buff_no[dev];
- }
- wr_buff_ptr[dev] = 0;
- }
-
- l = c;
- if (l > (wr_buff_size[dev] - wr_buff_ptr[dev]))
- l = (wr_buff_size[dev] - wr_buff_ptr[dev]);
-
- if (!audio_devs[dev]->copy_from_user)
- { /*
- * No device specific copy routine
- */
- COPY_FROM_USER (&wr_dma_buf[dev][wr_buff_ptr[dev]], buf, p, l);
- }
- else
- audio_devs[dev]->copy_from_user (dev,
- wr_dma_buf[dev], wr_buff_ptr[dev], buf, p, l);
-
-
- /*
- * Insert local processing here
- */
-
- if (local_conversion[dev] == AFMT_MU_LAW)
- {
-#ifdef linux
- /*
- * This just allows interrupts while the conversion is running
- */
- __asm__ ("sti");
-#endif
- translate_bytes (ulaw_dsp, (unsigned char *) &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
- }
-
- c -= l;
- p += l;
- wr_buff_ptr[dev] += l;
-
- if (wr_buff_ptr[dev] >= wr_buff_size[dev])
- {
- if ((err = DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev])) < 0)
- {
- return err;
- }
-
- wr_buff_no[dev] = -1;
- }
-
- }
-
- return count;
-}
-
-int
-audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- int c, p, l;
- char *dmabuf;
- int buff_no;
-
- dev = dev >> 4;
- p = 0;
- c = count;
-
- if (audio_mode[dev] == AM_WRITE)
- {
- if (wr_buff_no[dev] >= 0)
- {
- DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
-
- wr_buff_no[dev] = -1;
- }
- }
-
- audio_mode[dev] = AM_READ;
-
- while (c)
- {
- if ((buff_no = DMAbuf_getrdbuffer (dev, &dmabuf, &l,
- dev_nblock[dev])) < 0)
- {
- /* Nonblocking mode handling. Return current # of bytes */
-
-#if defined(__FreeBSD__)
- if (dev_nblock[dev] && buff_no == RET_ERROR (EWOULDBLOCK))
- return buff_no; /*
- * XXX Return error, read() will supply
- * # of bytes actually read. In fact,
- * in FreeBSD the check above should not
- * be needed
- */
-#else
- if (dev_nblock[dev] && buff_no == RET_ERROR (EAGAIN))
- return p;
-#endif
-
- return buff_no;
- }
-
- if (l > c)
- l = c;
-
- /*
- * Insert any local processing here.
- */
-
- if (local_conversion[dev] == AFMT_MU_LAW)
- {
-#ifdef linux
- /*
- * This just allows interrupts while the conversion is running
- */
- __asm__ ("sti");
-#endif
-
- translate_bytes (dsp_ulaw, (unsigned char *) dmabuf, l);
- }
-
- COPY_TO_USER (buf, p, dmabuf, l);
-
- DMAbuf_rmchars (dev, buff_no, l);
-
- p += l;
- c -= l;
- }
-
- return count - c;
-}
-
-int
-audio_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned int arg)
-{
-
- dev = dev >> 4;
-
- if (((cmd >> 8) & 0xff) == 'C')
- {
- if (audio_devs[dev]->coproc) /* Coprocessor ioctl */
- return audio_devs[dev]->coproc->ioctl (audio_devs[dev]->coproc->devc, cmd, arg, 0);
- else
- printk ("/dev/dsp%d: No coprocessor for this device\n", dev);
-
- return RET_ERROR (EREMOTEIO);
- }
- else
- switch (cmd)
- {
- case SNDCTL_DSP_SYNC:
- if (wr_buff_no[dev] >= 0)
- {
- DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
-
- wr_buff_no[dev] = -1;
- }
- return DMAbuf_ioctl (dev, cmd, arg, 0);
- break;
-
- case SNDCTL_DSP_POST:
- if (wr_buff_no[dev] >= 0)
- {
- DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
-
- wr_buff_no[dev] = -1;
- }
- return 0;
- break;
-
- case SNDCTL_DSP_RESET:
- wr_buff_no[dev] = -1;
- return DMAbuf_ioctl (dev, cmd, arg, 0);
- break;
-
- case SNDCTL_DSP_GETFMTS:
- return IOCTL_OUT (arg, audio_devs[dev]->format_mask);
- break;
-
- case SNDCTL_DSP_SETFMT:
- return IOCTL_OUT (arg, set_format (dev, IOCTL_IN (arg)));
-
- case SNDCTL_DSP_GETISPACE:
- if (audio_mode[dev] == AM_WRITE)
- return RET_ERROR (EBUSY);
-
- {
- audio_buf_info info;
-
- int err = DMAbuf_ioctl (dev, cmd, (unsigned long) &info, 1);
-
- if (err < 0)
- return err;
-
- if (wr_buff_no[dev] != -1)
- info.bytes += wr_buff_ptr[dev];
-
- IOCTL_TO_USER ((char *) arg, 0, (char *) &info, sizeof (info));
- return 0;
- }
-
- case SNDCTL_DSP_GETOSPACE:
- if (audio_mode[dev] == AM_READ)
- return RET_ERROR (EBUSY);
-
- {
- audio_buf_info info;
-
- int err = DMAbuf_ioctl (dev, cmd, (unsigned long) &info, 1);
-
- if (err < 0)
- return err;
-
- if (wr_buff_no[dev] != -1)
- info.bytes += wr_buff_size[dev] - wr_buff_ptr[dev];
-
- IOCTL_TO_USER ((char *) arg, 0, (char *) &info, sizeof (info));
- return 0;
- }
-
- case SNDCTL_DSP_NONBLOCK:
- dev_nblock[dev] = 1;
- return 0;
- break;
-
-#ifdef __FreeBSD__
- case FIONBIO: /* XXX Is this the same in Linux? */
- if (*(int *)arg)
- dev_nblock[dev] = 1;
- else
- dev_nblock[dev] = 0;
- return 0;
- break;
-
- case FIOASYNC:
- return 0; /* XXX Useful for ampling input notification? */
- break;
-#endif
-
- default:
- return DMAbuf_ioctl (dev, cmd, arg, 0);
- }
-}
-
-long
-audio_init (long mem_start)
-{
- /*
- * NOTE! This routine could be called several times during boot.
- */
- return mem_start;
-}
-
-#ifdef ALLOW_SELECT
-int
-audio_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
-{
- int l;
- char *dmabuf;
-
- dev = dev >> 4;
-
- switch (sel_type)
- {
- case SEL_IN:
- if (audio_mode[dev] != AM_READ && /* Wrong direction */
- audio_mode[dev] != AM_NONE)
- return 0;
-
- if (DMAbuf_getrdbuffer (dev, &dmabuf, &l,
- 1 /* Don't block */ ) >= 0)
- return 1; /* We have data */
-
- return DMAbuf_select (dev, file, sel_type, wait);
- break;
-
- case SEL_OUT:
- if (audio_mode[dev] != AM_WRITE && /* Wrong direction */
- audio_mode[dev] != AM_NONE)
- return 0;
-
- if (wr_buff_no[dev] != -1)
- return 1; /* There is space in the current buffer */
-
- return DMAbuf_select (dev, file, sel_type, wait);
- break;
-
- case SEL_EX:
- return 0;
- }
-
- return 0;
-}
-
-#endif /* ALLOW_SELECT */
-
-#else /* EXCLUDE_AUDIO */
-/*
- * Stub versions
- */
-
-int
-audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- return RET_ERROR (EIO);
-}
-
-int
-audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- return RET_ERROR (EIO);
-}
-
-int
-audio_open (int dev, struct fileinfo *file)
-{
- return RET_ERROR (ENXIO);
-}
-
-void
-audio_release (int dev, struct fileinfo *file)
-{
-};
-int
-audio_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned int arg)
-{
- return RET_ERROR (EIO);
-}
-
-int
-audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
-{
- return RET_ERROR (EIO);
-}
-
-long
-audio_init (long mem_start)
-{
- return mem_start;
-}
-
-#endif
-
-#endif
diff --git a/sys/pc98/pc98/sound/dev_table.c b/sys/pc98/pc98/sound/dev_table.c
deleted file mode 100644
index 2b6142b..0000000
--- a/sys/pc98/pc98/sound/dev_table.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * sound/dev_table.c
- *
- * Device call tables.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#define _DEV_TABLE_C_
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-#ifdef CONFIGURE_SOUNDCARD
-
-int
-snd_find_driver (int type)
-{
- int i, n = sizeof (sound_drivers) / sizeof (struct driver_info);
-
- for (i = 0; i < (n - 1); i++)
- if (sound_drivers[i].card_type == type)
- return i;
-
- return -1; /*
- * Not found
- */
-}
-
-static long
-sndtable_init (long mem_start)
-{
- int i, n = sizeof (snd_installed_cards) / sizeof (struct card_info);
- int drv;
-
- printk ("Sound initialization started\n");
-
- for (i = 0; i < (n - 1); i++)
- if (snd_installed_cards[i].enabled)
- if ((drv = snd_find_driver (snd_installed_cards[i].card_type)) == -1)
- snd_installed_cards[i].enabled = 0; /*
- * Mark as not detected
- */
- else if (sound_drivers[drv].probe (&snd_installed_cards[i].config))
- {
-#ifndef SHORT_BANNERS
- printk ("snd%d",
- snd_installed_cards[i].card_type);
-#endif
-
- mem_start = sound_drivers[drv].attach (mem_start, &snd_installed_cards[i].config);
-#ifndef SHORT_BANNERS
- printk (" at 0x%x irq %d drq %d\n",
- snd_installed_cards[i].config.io_base,
- snd_installed_cards[i].config.irq,
- snd_installed_cards[i].config.dma);
-#endif
- }
- else
- snd_installed_cards[i].enabled = 0; /*
- * Mark as not detected
- */
- printk ("Sound initialization complete\n");
- return mem_start;
-}
-
-int
-sndtable_probe (int unit, struct address_info *hw_config)
-{
- int i, n = sizeof (snd_installed_cards) / sizeof (struct card_info);
-
- if (!unit)
- return TRUE;
-
- for (i = 0; i < (n - 1); i++)
- if (snd_installed_cards[i].enabled)
- if (snd_installed_cards[i].card_type == unit)
- {
- int drv;
-
- snd_installed_cards[i].config.io_base = hw_config->io_base;
- snd_installed_cards[i].config.irq = hw_config->irq;
- snd_installed_cards[i].config.dma = hw_config->dma;
- if ((drv = snd_find_driver (snd_installed_cards[i].card_type)) == -1)
- snd_installed_cards[i].enabled = 0; /*
- * Mark as not
- * detected
- */
- else if (sound_drivers[drv].probe (hw_config))
- return 1;
- snd_installed_cards[i].enabled = 0; /*
- * Mark as not detected
- */
- return 0;
- }
-
- return FALSE;
-}
-
-int
-sndtable_init_card (int unit, struct address_info *hw_config)
-{
- int i, n = sizeof (snd_installed_cards) / sizeof (struct card_info);
-
- if (!unit)
- {
- if (sndtable_init (0) != 0)
- panic ("snd: Invalid memory allocation\n");
- return TRUE;
- }
-
- for (i = 0; i < (n - 1); i++)
- if (snd_installed_cards[i].card_type == unit)
- {
- int drv;
-
- snd_installed_cards[i].config.io_base = hw_config->io_base;
- snd_installed_cards[i].config.irq = hw_config->irq;
- snd_installed_cards[i].config.dma = hw_config->dma;
-
- if ((drv = snd_find_driver (snd_installed_cards[i].card_type)) == -1)
- snd_installed_cards[i].enabled = 0; /*
- * Mark as not detected
- */
- else if (sound_drivers[drv].attach (0, hw_config) != 0)
- panic ("snd#: Invalid memory allocation\n");
- return TRUE;
- }
-
- return FALSE;
-}
-
-int
-sndtable_get_cardcount (void)
-{
- return num_audiodevs + num_mixers + num_synths + num_midis;
-}
-
-struct address_info *
-sound_getconf (int card_type)
-{
- int j, ptr;
- int n = sizeof (snd_installed_cards) / sizeof (struct card_info);
-
- ptr = -1;
- for (j = 0; j < n && ptr == -1; j++)
- if (snd_installed_cards[j].card_type == card_type)
- ptr = j;
-
- if (ptr == -1)
- return (struct address_info *) NULL;
-
- return &snd_installed_cards[ptr].config;
-}
-
-#else
-
-void
-sound_setup (char *str, int *ints)
-{
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/dev_table.h b/sys/pc98/pc98/sound/dev_table.h
deleted file mode 100644
index 5269f63..0000000
--- a/sys/pc98/pc98/sound/dev_table.h
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * dev_table.h
- *
- * Global definitions for device call tables
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 _DEV_TABLE_H_
-#define _DEV_TABLE_H_
-
-/*
- * NOTE! NOTE! NOTE! NOTE!
- *
- * If you modify this file, please check the dev_table.c also.
- *
- * NOTE! NOTE! NOTE! NOTE!
- */
-
-struct driver_info {
- int card_type; /* From soundcard.h */
- char *name;
- long (*attach) (long mem_start, struct address_info *hw_config);
- int (*probe) (struct address_info *hw_config);
-};
-
-struct card_info {
- int card_type; /* Link (search key) to the driver list */
- struct address_info config;
- int enabled;
-};
-
-/*
- * Device specific parameters (used only by dmabuf.c)
- */
-#define MAX_SUB_BUFFERS (32*MAX_REALTIME_FACTOR)
-
-#define DMODE_NONE 0
-#define DMODE_OUTPUT 1
-#define DMODE_INPUT 2
-
-struct dma_buffparms {
- int dma_mode; /* DMODE_INPUT, DMODE_OUTPUT or DMODE_NONE */
-
- /*
- * Pointers to raw buffers
- */
-
- char *raw_buf[DSP_BUFFCOUNT];
- unsigned long raw_buf_phys[DSP_BUFFCOUNT];
- int raw_count;
-
- /*
- * Device state tables
- */
-
- unsigned long flags;
-#define DMA_BUSY 0x00000001
-#define DMA_RESTART 0x00000002
-#define DMA_ACTIVE 0x00000004
-#define DMA_STARTED 0x00000008
-#define DMA_ALLOC_DONE 0x00000020
-
- int open_mode;
-
- /*
- * Queue parameters.
- */
- int qlen;
- int qhead;
- int qtail;
-
- int nbufs;
- int counts[MAX_SUB_BUFFERS];
- int subdivision;
- char *buf[MAX_SUB_BUFFERS];
- unsigned long buf_phys[MAX_SUB_BUFFERS];
-
- int fragment_size;
- int max_fragments;
-
- int bytes_in_use;
-
- int underrun_count;
-};
-
-/*
- * Structure for use with various microcontrollers and DSP processors
- * in the recent soundcards.
- */
-typedef struct coproc_operations {
- char name[32];
- int (*open) (void *devc, int sub_device);
- void (*close) (void *devc, int sub_device);
- int (*ioctl) (void *devc, unsigned int cmd, unsigned int arg, int local);
- void (*reset) (void *devc);
-
- void *devc; /* Driver specific info */
- } coproc_operations;
-
-struct audio_operations {
- char name[32];
- int flags;
-#define NOTHING_SPECIAL 0
-#define NEEDS_RESTART 1
-#define DMA_AUTOMODE 2
- int format_mask; /* Bitmask for supported audio formats */
- void *devc; /* Driver specific info */
- int (*open) (int dev, int mode);
- void (*close) (int dev);
- void (*output_block) (int dev, unsigned long buf,
- int count, int intrflag, int dma_restart);
- void (*start_input) (int dev, unsigned long buf,
- int count, int intrflag, int dma_restart);
- int (*ioctl) (int dev, unsigned int cmd, unsigned int arg, int local);
- int (*prepare_for_input) (int dev, int bufsize, int nbufs);
- int (*prepare_for_output) (int dev, int bufsize, int nbufs);
- void (*reset) (int dev);
- void (*halt_xfer) (int dev);
- int (*local_qlen)(int dev);
- void (*copy_from_user)(int dev, char *localbuf, int localoffs,
- snd_rw_buf *userbuf, int useroffs, int len);
- int buffcount;
- long buffsize;
- int dmachan;
- struct dma_buffparms *dmap;
- struct coproc_operations *coproc;
- int mixer_dev;
-};
-
-struct mixer_operations {
- char name[32];
- int (*ioctl) (int dev, unsigned int cmd, unsigned int arg);
-};
-
-struct synth_operations {
- struct synth_info *info;
- int midi_dev;
- int synth_type;
- int synth_subtype;
-
- int (*open) (int dev, int mode);
- void (*close) (int dev);
- int (*ioctl) (int dev, unsigned int cmd, unsigned int arg);
- int (*kill_note) (int dev, int voice, int note, int velocity);
- int (*start_note) (int dev, int voice, int note, int velocity);
- int (*set_instr) (int dev, int voice, int instr);
- void (*reset) (int dev);
- void (*hw_control) (int dev, unsigned char *event);
- int (*load_patch) (int dev, int format, snd_rw_buf *addr,
- int offs, int count, int pmgr_flag);
- void (*aftertouch) (int dev, int voice, int pressure);
- void (*controller) (int dev, int voice, int ctrl_num, int value);
- void (*panning) (int dev, int voice, int value);
- void (*volume_method) (int dev, int mode);
- int (*pmgr_interface) (int dev, struct patmgr_info *info);
- void (*bender) (int dev, int chn, int value);
- int (*alloc_voice) (int dev, int chn, int note, struct voice_alloc_info *alloc);
- void (*setup_voice) (int dev, int voice, int chn);
-
- struct voice_alloc_info alloc;
- struct channel_info chn_info[16];
-};
-
-struct midi_input_info { /* MIDI input scanner variables */
-#define MI_MAX 10
- int m_busy;
- unsigned char m_buf[MI_MAX];
- unsigned char m_prev_status; /* For running status */
- int m_ptr;
-#define MST_INIT 0
-#define MST_DATA 1
-#define MST_SYSEX 2
- int m_state;
- int m_left;
- };
-
-struct midi_operations {
- struct midi_info info;
- struct synth_operations *converter;
- struct midi_input_info in_info;
- int (*open) (int dev, int mode,
- void (*inputintr)(int dev, unsigned char data),
- void (*outputintr)(int dev)
- );
- void (*close) (int dev);
- int (*ioctl) (int dev, unsigned int cmd, unsigned int arg);
- int (*putc) (int dev, unsigned char data);
- int (*start_read) (int dev);
- int (*end_read) (int dev);
- void (*kick)(int dev);
- int (*command) (int dev, unsigned char *data);
- int (*buffer_status) (int dev);
- int (*prefix_cmd) (int dev, unsigned char status);
- struct coproc_operations *coproc;
-};
-
-struct sound_timer_operations {
- struct sound_timer_info info;
- int priority;
- int devlink;
- int (*open)(int dev, int mode);
- void (*close)(int dev);
- int (*event)(int dev, unsigned char *ev);
- unsigned long (*get_time)(int dev);
- int (*ioctl) (int dev, unsigned int cmd, unsigned int arg);
- void (*arm_timer)(int dev, long time);
-};
-
-#ifdef _DEV_TABLE_C_
- struct audio_operations *audio_devs[MAX_AUDIO_DEV] = {NULL}; int num_audiodevs = 0;
- struct mixer_operations *mixer_devs[MAX_MIXER_DEV] = {NULL}; int num_mixers = 0;
- struct synth_operations *synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV] = {NULL}; int num_synths = 0;
- struct midi_operations *midi_devs[MAX_MIDI_DEV] = {NULL}; int num_midis = 0;
-
-#ifndef EXCLUDE_SEQUENCER
- extern struct sound_timer_operations default_sound_timer;
- struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] =
- {&default_sound_timer, NULL};
- int num_sound_timers = 1;
-#else
- struct sound_timer_operations *sound_timer_devs[MAX_TIMER_DEV] =
- {NULL};
- int num_sound_timers = 0;
-#endif
-
-/*
- * List of low level drivers compiled into the kernel.
- */
-
- struct driver_info sound_drivers[] = {
-#ifndef EXCLUDE_PSS
- {SNDCARD_PSS, "Echo Personal Sound System PSS (ESC614)", attach_pss, probe_pss},
-# ifdef PSS_MPU_BASE
- {SNDCARD_PSS_MPU, "PSS-MPU", attach_pss_mpu, probe_pss_mpu},
-# endif
-# ifdef PSS_MSS_BASE
- {SNDCARD_PSS_MSS, "PSS-MSS", attach_pss_mss, probe_pss_mss},
-# endif
-#endif
-#ifndef EXCLUDE_YM3812
- {SNDCARD_ADLIB, "OPL-2/OPL-3 FM", attach_adlib_card, probe_adlib},
-#endif
-#ifndef EXCLUDE_PAS
- {SNDCARD_PAS, "ProAudioSpectrum", attach_pas_card, probe_pas},
-#endif
-#if !defined(EXCLUDE_MPU401) && !defined(EXCLUDE_MIDI)
- {SNDCARD_MPU401,"Roland MPU-401", attach_mpu401, probe_mpu401},
-#endif
-#if !defined(EXCLUDE_UART6850) && !defined(EXCLUDE_MIDI)
- {SNDCARD_UART6850,"6860 UART Midi", attach_uart6850, probe_uart6850},
-#endif
-#ifndef EXCLUDE_SB
- {SNDCARD_SB, "SoundBlaster", attach_sb_card, probe_sb},
-#endif
-#if !defined(EXCLUDE_SB) && !defined(EXCLUDE_SB16)
-#ifndef EXCLUDE_AUDIO
- {SNDCARD_SB16, "SoundBlaster16", sb16_dsp_init, sb16_dsp_detect},
-#endif
-#ifndef EXCLUDE_MIDI
- {SNDCARD_SB16MIDI,"SB16 MIDI", attach_sb16midi, probe_sb16midi},
-#endif
-#endif
-#ifndef EXCLUDE_GUS16
- {SNDCARD_GUS16, "Ultrasound 16-bit opt.", attach_gus_db16, probe_gus_db16},
-#endif
-#ifndef EXCLUDE_MSS
- {SNDCARD_MSS, "MS Sound System", attach_ms_sound, probe_ms_sound},
-#endif
-#ifndef EXCLUDE_GUS
- {SNDCARD_GUS, "Gravis Ultrasound", attach_gus_card, probe_gus},
-#endif
-#ifndef EXCLUDE_SSCAPE
- {SNDCARD_SSCAPE, "Ensoniq Soundscape", attach_sscape, probe_sscape},
- {SNDCARD_SSCAPE_MSS, "MS Sound System (SoundScape)", attach_ss_ms_sound, probe_ss_ms_sound},
-#endif
-#ifndef EXCLUDE_TRIX
- {SNDCARD_TRXPRO, "MediaTriX AudioTriX Pro", attach_trix_wss, probe_trix_wss},
- {SNDCARD_TRXPRO_SB, "AudioTriX (SB mode)", attach_trix_sb, probe_trix_sb},
- {SNDCARD_TRXPRO_MPU, "AudioTriX MIDI", attach_trix_mpu, probe_trix_mpu},
-#endif
-#ifdef PC98
-#ifndef EXCLUDE_PCM86
- {SNDCARD_PCM86, "PC-9801-86/73", attach_pcm86, probe_pcm86},
-#endif
-#endif
- {0, "*?*", NULL, NULL}
- };
-
-#if defined(linux) || defined(__FreeBSD__)
-/*
- * List of devices actually configured in the system.
- *
- * Note! The detection order is significant. Don't change it.
- */
-
- struct card_info snd_installed_cards[] = {
-#ifndef EXCLUDE_PSS
- {SNDCARD_PSS, {PSS_BASE, PSS_IRQ, PSS_DMA}, SND_DEFAULT_ENABLE},
-# ifdef PSS_MPU_BASE
- {SNDCARD_PSS_MPU, {PSS_MPU_BASE, PSS_MPU_IRQ, 0}, SND_DEFAULT_ENABLE},
-# endif
-# ifdef PSS_MSS_BASE
- {SNDCARD_PSS_MSS, {PSS_MSS_BASE, PSS_MSS_IRQ, PSS_MSS_DMA}, SND_DEFAULT_ENABLE},
-# endif
-#endif
-#ifndef EXCLUDE_TRIX
- {SNDCARD_TRXPRO, {TRIX_BASE, TRIX_IRQ, TRIX_DMA}, SND_DEFAULT_ENABLE},
-# ifdef TRIX_SB_BASE
- {SNDCARD_TRXPRO_SB, {TRIX_SB_BASE, TRIX_SB_IRQ, TRIX_SB_DMA}, SND_DEFAULT_ENABLE},
-# endif
-# ifdef TRIX_MPU_BASE
- {SNDCARD_TRXPRO_MPU, {TRIX_MPU_BASE, TRIX_MPU_IRQ, 0}, SND_DEFAULT_ENABLE},
-# endif
-#endif
-#ifndef EXCLUDE_SSCAPE
- {SNDCARD_SSCAPE, {SSCAPE_BASE, SSCAPE_IRQ, SSCAPE_DMA}, SND_DEFAULT_ENABLE},
- {SNDCARD_SSCAPE_MSS, {SSCAPE_MSS_BASE, SSCAPE_MSS_IRQ, SSCAPE_MSS_DMA}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifndef EXCLUDE_MSS
- {SNDCARD_MSS, {MSS_BASE, MSS_IRQ, MSS_DMA}, SND_DEFAULT_ENABLE},
-# ifdef MSS2_BASE
- {SNDCARD_MSS, {MSS2_BASE, MSS2_IRQ, MSS2_DMA}, SND_DEFAULT_ENABLE},
-# endif
-#endif
-
-#ifndef EXCLUDE_PAS
- {SNDCARD_PAS, {PAS_BASE, PAS_IRQ, PAS_DMA}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifndef EXCLUDE_SB
- {SNDCARD_SB, {SBC_BASE, SBC_IRQ, SBC_DMA}, SND_DEFAULT_ENABLE},
-#endif
-
-#if !defined(EXCLUDE_MPU401) && !defined(EXCLUDE_MIDI)
- {SNDCARD_MPU401, {MPU_BASE, MPU_IRQ, 0}, SND_DEFAULT_ENABLE},
-#ifdef MPU2_BASE
- {SNDCARD_MPU401, {MPU2_BASE, MPU2_IRQ, 0}, SND_DEFAULT_ENABLE},
-#endif
-#ifdef MPU3_BASE
- {SNDCARD_MPU401, {MPU3_BASE, MPU2_IRQ, 0}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#if !defined(EXCLUDE_UART6850) && !defined(EXCLUDE_MIDI)
- {SNDCARD_UART6850, {U6850_BASE, U6850_IRQ, 0}, SND_DEFAULT_ENABLE},
-#endif
-
-#if !defined(EXCLUDE_SB) && !defined(EXCLUDE_SB16)
-#ifndef EXCLUDE_AUDIO
- {SNDCARD_SB16, {SBC_BASE, SBC_IRQ, SB16_DMA}, SND_DEFAULT_ENABLE},
-#endif
-#ifndef EXCLUDE_MIDI
- {SNDCARD_SB16MIDI,{SB16MIDI_BASE, SBC_IRQ, 0}, SND_DEFAULT_ENABLE},
-#endif
-#endif
-
-#ifndef EXCLUDE_GUS
-#ifndef EXCLUDE_GUS16
- {SNDCARD_GUS16, {GUS16_BASE, GUS16_IRQ, GUS16_DMA, GUS_DMA_READ}, SND_DEFAULT_ENABLE},
-#endif
- {SNDCARD_GUS, {GUS_BASE, GUS_IRQ, GUS_DMA, GUS_DMA_READ}, SND_DEFAULT_ENABLE},
-#endif
-
-#ifndef EXCLUDE_YM3812
- {SNDCARD_ADLIB, {FM_MONO, 0, 0}, SND_DEFAULT_ENABLE},
-#endif
-#ifdef PC98
-#ifndef EXCLUDE_PCM86
- {SNDCARD_PCM86, {0, 0, 0}, SND_DEFAULT_ENABLE},
-#endif
-#endif
- {0, {0}, 0}
- };
-
- int num_sound_cards =
- sizeof(snd_installed_cards) / sizeof (struct card_info);
-
-#else
- int num_sound_cards = 0;
-#endif /* linux */
-
- int num_sound_drivers =
- sizeof(sound_drivers) / sizeof (struct driver_info);
-
-#else
- extern struct audio_operations * audio_devs[MAX_AUDIO_DEV]; extern int num_audiodevs;
- extern struct mixer_operations * mixer_devs[MAX_MIXER_DEV]; extern int num_mixers;
- extern struct synth_operations * synth_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV]; extern int num_synths;
- extern struct midi_operations * midi_devs[MAX_MIDI_DEV]; extern int num_midis;
- extern struct sound_timer_operations * sound_timer_devs[MAX_SYNTH_DEV+MAX_MIDI_DEV]; extern int num_sound_timers;
-
- extern struct driver_info sound_drivers[];
- extern int num_sound_drivers;
- extern struct card_info snd_installed_cards[];
- extern int num_sound_cards;
-#endif /* _DEV_TABLE_C_ */
-
-int sndtable_probe(int unit, struct address_info *hw_config);
-int sndtable_init_card(int unit, struct address_info *hw_config);
-int sndtable_get_cardcount (void);
-struct address_info *sound_getconf(int card_type);
-int snd_find_driver(int type);
-
-#endif /* _DEV_TABLE_H_ */
diff --git a/sys/pc98/pc98/sound/dmabuf.c b/sys/pc98/pc98/sound/dmabuf.c
deleted file mode 100644
index 90673af..0000000
--- a/sys/pc98/pc98/sound/dmabuf.c
+++ /dev/null
@@ -1,1119 +0,0 @@
-/*
- * sound/dmabuf.c
- *
- * The DMA buffer manager for digitized voice applications
- *
- * Copyright by Hannu Savolainen 1993, 1994, 1995
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-#ifdef CONFIGURE_SOUNDCARD
-
-#if !defined(EXCLUDE_AUDIO) || !defined(EXCLUDE_GUS)
-
-DEFINE_WAIT_QUEUES (dev_sleeper[MAX_AUDIO_DEV], dev_sleep_flag[MAX_AUDIO_DEV]);
-
-static struct dma_buffparms dmaps[MAX_AUDIO_DEV] =
-{
- {0}}; /*
-
- * Primitive way to allocate
- * such a large array.
- * Needs dynamic run-time alloction.
- */
-
-static void
-reorganize_buffers (int dev)
-{
- /*
- * This routine breaks the physical device buffers to logical ones.
- */
-
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
- struct audio_operations *dsp_dev = audio_devs[dev];
-
- unsigned i, p, n;
- unsigned sr, nc, sz, bsz;
-
- if (dmap->fragment_size == 0)
- { /* Compute the fragment size using the default algorithm */
-
- sr = dsp_dev->ioctl (dev, SOUND_PCM_READ_RATE, 0, 1);
- nc = dsp_dev->ioctl (dev, SOUND_PCM_READ_CHANNELS, 0, 1);
- sz = dsp_dev->ioctl (dev, SOUND_PCM_READ_BITS, 0, 1);
-
- if (sr < 1 || nc < 1 || sz < 1)
- {
- printk ("Warning: Invalid PCM parameters[%d] sr=%d, nc=%d, sz=%d\n",
- dev, sr, nc, sz);
- sr = DSP_DEFAULT_SPEED;
- nc = 1;
- sz = 8;
- }
-
- sz = sr * nc * sz;
-
- sz /= 8; /* #bits -> #bytes */
-
- /*
- * Compute a buffer size for time not exeeding 1 second.
- * Usually this algorithm gives a buffer size for 0.5 to 1.0 seconds
- * of sound (using the current speed, sample size and #channels).
- */
-
- bsz = dsp_dev->buffsize;
- while (bsz > sz)
- bsz /= 2;
-
- if (dsp_dev->buffcount == 1 && bsz == dsp_dev->buffsize)
- bsz /= 2; /* Needs at least 2 buffers */
-
- if (dmap->subdivision == 0) /* Not already set */
- dmap->subdivision = 1; /* Init to default value */
- else
- bsz /= dmap->subdivision;
-
- if (bsz < 16)
- bsz = 16; /* Just a sanity check */
-
- while ((dsp_dev->buffsize * dsp_dev->buffcount) / bsz > MAX_SUB_BUFFERS)
- bsz *= 2;
-
- dmap->fragment_size = bsz;
- }
- else
- {
- /*
- * The process has specified the buffer sice with SNDCTL_DSP_SETFRAGMENT or
- * the buffer sice computation has already been done.
- */
- if (dmap->fragment_size > (audio_devs[dev]->buffsize / 2))
- dmap->fragment_size = (audio_devs[dev]->buffsize / 2);
- bsz = dmap->fragment_size;
- }
-
- bsz &= ~0x03; /* Force size which is multiple of 4 bytes */
-
- /*
- * Now computing addresses for the logical buffers
- */
-
- n = 0;
- for (i = 0; i < dmap->raw_count &&
- n < dmap->max_fragments &&
- n < MAX_SUB_BUFFERS; i++)
- {
- p = 0;
-
- while ((p + bsz) <= dsp_dev->buffsize &&
- n < dmap->max_fragments &&
- n < MAX_SUB_BUFFERS)
- {
- dmap->buf[n] = dmap->raw_buf[i] + p;
- dmap->buf_phys[n] = dmap->raw_buf_phys[i] + p;
- p += bsz;
- n++;
- }
- }
-
- dmap->nbufs = n;
- dmap->bytes_in_use = n * bsz;
-
- for (i = 0; i < dmap->nbufs; i++)
- {
- dmap->counts[i] = 0;
- }
-
- dmap->flags |= DMA_ALLOC_DONE;
-}
-
-static void
-dma_init_buffers (int dev)
-{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap = &dmaps[dev];
-
- RESET_WAIT_QUEUE (dev_sleeper[dev], dev_sleep_flag[dev]);
-
- dmap->flags = DMA_BUSY; /* Other flags off */
- dmap->qlen = dmap->qhead = dmap->qtail = 0;
- dmap->nbufs = 1;
- dmap->bytes_in_use = audio_devs[dev]->buffsize;
-
- dmap->dma_mode = DMODE_NONE;
-}
-
-int
-DMAbuf_open (int dev, int mode)
-{
- int retval;
- struct dma_buffparms *dmap = NULL;
-
- if (dev >= num_audiodevs)
- {
- printk ("PCM device %d not installed.\n", dev);
- return RET_ERROR (ENXIO);
- }
-
- if (!audio_devs[dev])
- {
- printk ("PCM device %d not initialized\n", dev);
- return RET_ERROR (ENXIO);
- }
-
- dmap = audio_devs[dev]->dmap = &dmaps[dev];
-
- if (dmap->flags & DMA_BUSY)
- return RET_ERROR (EBUSY);
-
-#ifdef USE_RUNTIME_DMAMEM
- dmap->raw_buf[0] = NULL;
- sound_dma_malloc (dev);
-#endif
-
- if (dmap->raw_buf[0] == NULL)
- return RET_ERROR (ENOSPC); /* Memory allocation failed during boot */
-
- if ((retval = audio_devs[dev]->open (dev, mode)) < 0)
- return retval;
-
- dmap->open_mode = mode;
- dmap->subdivision = dmap->underrun_count = 0;
- dmap->fragment_size = 0;
- dmap->max_fragments = 65536; /* Just a large value */
-
- dma_init_buffers (dev);
- audio_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_BITS, 8, 1);
- audio_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_CHANNELS, 1, 1);
- audio_devs[dev]->ioctl (dev, SOUND_PCM_WRITE_RATE, DSP_DEFAULT_SPEED, 1);
-
- return 0;
-}
-
-static void
-dma_reset (int dev)
-{
- int retval;
- unsigned long flags;
-
- DISABLE_INTR (flags);
-
- audio_devs[dev]->reset (dev);
- audio_devs[dev]->close (dev);
-
- if ((retval = audio_devs[dev]->open (dev, audio_devs[dev]->dmap->open_mode)) < 0)
- printk ("Sound: Reset failed - Can't reopen device\n");
- RESTORE_INTR (flags);
-
- dma_init_buffers (dev);
- reorganize_buffers (dev);
-}
-
-static int
-dma_sync (int dev)
-{
- unsigned long flags;
-
- if (audio_devs[dev]->dmap->dma_mode == DMODE_OUTPUT)
- {
- DISABLE_INTR (flags);
-
- while (!PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev])
- && audio_devs[dev]->dmap->qlen)
- {
- DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 10 * HZ);
- if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))
- {
- RESTORE_INTR (flags);
- return audio_devs[dev]->dmap->qlen;
- }
- }
- RESTORE_INTR (flags);
-
- /*
- * Some devices such as GUS have huge amount of on board RAM for the
- * audio data. We have to wait until the device has finished playing.
- */
-
- DISABLE_INTR (flags);
- if (audio_devs[dev]->local_qlen) /* Device has hidden buffers */
- {
- while (!(PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]))
- && audio_devs[dev]->local_qlen (dev))
- {
- DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], HZ);
- }
- }
- RESTORE_INTR (flags);
- }
- return audio_devs[dev]->dmap->qlen;
-}
-
-int
-DMAbuf_release (int dev, int mode)
-{
- unsigned long flags;
-
- if (!(PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]))
- && (audio_devs[dev]->dmap->dma_mode == DMODE_OUTPUT))
- {
- dma_sync (dev);
- }
-
-#ifdef USE_RUNTIME_DMAMEM
- sound_dma_free (dev);
-#endif
-
- DISABLE_INTR (flags);
- audio_devs[dev]->reset (dev);
-
- audio_devs[dev]->close (dev);
-
- audio_devs[dev]->dmap->dma_mode = DMODE_NONE;
- audio_devs[dev]->dmap->flags &= ~DMA_BUSY;
- RESTORE_INTR (flags);
-
- return 0;
-}
-
-int
-DMAbuf_getrdbuffer (int dev, char **buf, int *len, int dontblock)
-{
- unsigned long flags;
- int err = EIO;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
-
- DISABLE_INTR (flags);
- if (!dmap->qlen)
- {
- if (dmap->flags & DMA_RESTART)
- {
- dma_reset (dev);
- dmap->flags &= ~DMA_RESTART;
- }
-
- if (dmap->dma_mode == DMODE_OUTPUT) /* Direction change */
- {
- dma_sync (dev);
- dma_reset (dev);
- dmap->dma_mode = DMODE_NONE;
- }
-
- if (!(dmap->flags & DMA_ALLOC_DONE))
- reorganize_buffers (dev);
-
- if (!dmap->dma_mode)
- {
- int err;
-
- if ((err = audio_devs[dev]->prepare_for_input (dev,
- dmap->fragment_size, dmap->nbufs)) < 0)
- {
- RESTORE_INTR (flags);
- return err;
- }
- dmap->dma_mode = DMODE_INPUT;
- }
-
- if (!(dmap->flags & DMA_ACTIVE))
- {
- audio_devs[dev]->start_input (dev, dmap->buf_phys[dmap->qtail],
- dmap->fragment_size, 0,
- !(audio_devs[dev]->flags & DMA_AUTOMODE) ||
- !(dmap->flags & DMA_STARTED));
- dmap->flags |= DMA_ACTIVE | DMA_STARTED;
- }
-
- if (dontblock)
- {
- RESTORE_INTR (flags);
-#if defined(__FreeBSD__)
- return RET_ERROR (EWOULDBLOCK);
-#else
- return RET_ERROR (EAGAIN);
-#endif
- }
-
- /* Wait for the next block */
-
- DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 2 * HZ);
- if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))
- {
- printk ("Sound: DMA timed out - IRQ/DRQ config error?\n");
- dma_reset (dev);
- err = EIO;
- SET_ABORT_FLAG (dev_sleeper[dev], dev_sleep_flag[dev]);
- }
- else
- err = EINTR;
- }
- RESTORE_INTR (flags);
-
- if (!dmap->qlen)
- return RET_ERROR (err);
-
- *buf = &dmap->buf[dmap->qhead][dmap->counts[dmap->qhead]];
- *len = dmap->fragment_size - dmap->counts[dmap->qhead];
-
- return dmap->qhead;
-}
-
-int
-DMAbuf_rmchars (int dev, int buff_no, int c)
-{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
-
- int p = dmap->counts[dmap->qhead] + c;
-
- if (p >= dmap->fragment_size)
- { /* This buffer is completely empty */
- dmap->counts[dmap->qhead] = 0;
- if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
- printk ("\nSound: Audio queue1 corrupted for dev%d (%d/%d)\n",
- dev, dmap->qlen, dmap->nbufs);
- dmap->qlen--;
- dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
- }
- else
- dmap->counts[dmap->qhead] = p;
-
- return 0;
-}
-
-int
-DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
-{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
-
- switch (cmd)
- {
- case SNDCTL_DSP_RESET:
- dma_reset (dev);
- return 0;
- break;
-
- case SNDCTL_DSP_SYNC:
- dma_sync (dev);
- dma_reset (dev);
- return 0;
- break;
-
- case SNDCTL_DSP_GETBLKSIZE:
- if (!(dmap->flags & DMA_ALLOC_DONE))
- reorganize_buffers (dev);
-
- return IOCTL_OUT (arg, dmap->fragment_size);
- break;
-
- case SNDCTL_DSP_SETBLKSIZE:
- {
- int size = IOCTL_IN(arg);
-
- if(!(dmap->flags & DMA_ALLOC_DONE) && size)
- {
- dmap->fragment_size = size;
- return 0;
- }
- else
- return RET_ERROR (EINVAL); /* Too late to change */
- }
- break;
-
- case SNDCTL_DSP_SUBDIVIDE:
- {
- int fact = IOCTL_IN (arg);
-
- if (fact == 0)
- {
- fact = dmap->subdivision;
- if (fact == 0)
- fact = 1;
- return IOCTL_OUT (arg, fact);
- }
-
- if (dmap->subdivision != 0 ||
- dmap->fragment_size) /* Loo late to change */
- return RET_ERROR (EINVAL);
-
- if (fact > MAX_REALTIME_FACTOR)
- return RET_ERROR (EINVAL);
-
- if (fact != 1 && fact != 2 && fact != 4 && fact != 8 && fact != 16)
- return RET_ERROR (EINVAL);
-
- dmap->subdivision = fact;
- return IOCTL_OUT (arg, fact);
- }
- break;
-
- case SNDCTL_DSP_SETFRAGMENT:
- {
- int fact = IOCTL_IN (arg);
- int bytes, count;
-
- if (fact == 0)
- return RET_ERROR (EIO);
-
- if (dmap->subdivision != 0 ||
- dmap->fragment_size) /* Loo late to change */
- return RET_ERROR (EINVAL);
-
- bytes = fact & 0xffff;
- count = (fact >> 16) & 0xffff;
-
- if (count == 0)
- count = MAX_SUB_BUFFERS;
-
- if (bytes < 7 || bytes > 17) /* <64 || > 128k */
- return RET_ERROR (EINVAL);
-
- if (count < 2)
- return RET_ERROR (EINVAL);
-
- dmap->fragment_size = (1 << bytes);
- dmap->max_fragments = count;
-
- if (dmap->fragment_size > audio_devs[dev]->buffsize)
- dmap->fragment_size = audio_devs[dev]->buffsize;
-
- if (dmap->fragment_size == audio_devs[dev]->buffsize &&
- audio_devs[dev]->flags & DMA_AUTOMODE)
- dmap->fragment_size /= 2; /* Needs at least 2 buffers */
-
- dmap->subdivision = 1; /* Disable SNDCTL_DSP_SUBDIVIDE */
- return IOCTL_OUT (arg, bytes | (count << 16));
- }
- break;
-
- case SNDCTL_DSP_GETISPACE:
- case SNDCTL_DSP_GETOSPACE:
- if (!local)
- return RET_ERROR (EINVAL);
-
- {
- audio_buf_info *info = (audio_buf_info *) arg;
-
- info->fragments = dmap->qlen;
- info->fragsize = dmap->fragment_size;
- info->bytes = dmap->qlen * dmap->fragment_size;
- }
- return 0;
-
- default:
- return audio_devs[dev]->ioctl (dev, cmd, arg, local);
- }
-
-}
-
-static int
-space_in_queue (int dev)
-{
- int len, max, tmp;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
-
- if (dmap->qlen >= dmap->nbufs) /* No space at all */
- return 0;
-
- /*
- * Verify that there are no more pending buffers than the limit
- * defined by the process.
- */
-
- max = dmap->max_fragments;
- len = dmap->qlen;
-
- if (audio_devs[dev]->local_qlen)
- {
- tmp = audio_devs[dev]->local_qlen (dev);
- if (tmp & len)
- tmp--; /*
- * This buffer has been counted twice
- */
- len += tmp;
- }
-
- if (len >= max)
- return 0;
- return 1;
-}
-
-int
-DMAbuf_getwrbuffer (int dev, char **buf, int *size, int dontblock)
-{
- unsigned long flags;
- int abort, err = EIO;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
-
- if (dmap->dma_mode == DMODE_INPUT) /* Direction change */
- {
- dma_reset (dev);
- dmap->dma_mode = DMODE_NONE;
- }
- else if (dmap->flags & DMA_RESTART) /* Restart buffering */
- {
- dma_sync (dev);
- dma_reset (dev);
- }
-
- dmap->flags &= ~DMA_RESTART;
-
- if (!(dmap->flags & DMA_ALLOC_DONE))
- reorganize_buffers (dev);
-
- if (!dmap->dma_mode)
- {
- int err;
-
- dmap->dma_mode = DMODE_OUTPUT;
- if ((err = audio_devs[dev]->prepare_for_output (dev,
- dmap->fragment_size, dmap->nbufs)) < 0)
- return err;
- }
-
- DISABLE_INTR (flags);
-
- abort = 0;
- while (!space_in_queue (dev) &&
- !abort)
- {
-
- if (dontblock)
- {
- RESTORE_INTR (flags);
- return RET_ERROR (EAGAIN);
- }
-
- /*
- * Wait for free space
- */
- DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 2 * HZ);
- if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))
- {
- printk ("Sound: DMA timed out - IRQ/DRQ config error?\n");
- dma_reset (dev);
- err = EIO;
- abort = 1;
- SET_ABORT_FLAG (dev_sleeper[dev], dev_sleep_flag[dev]);
- }
- else if (PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]))
- {
- err = EINTR;
- abort = 1;
- }
- }
- RESTORE_INTR (flags);
-
- if (!space_in_queue (dev))
- {
- return RET_ERROR (err); /* Caught a signal ? */
- }
-
- *buf = dmap->buf[dmap->qtail];
- *size = dmap->fragment_size;
- dmap->counts[dmap->qtail] = 0;
-
- return dmap->qtail;
-}
-
-int
-DMAbuf_start_output (int dev, int buff_no, int l)
-{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
-
- if (buff_no != dmap->qtail)
- printk ("Sound warning: DMA buffers out of sync %d != %d\n", buff_no, dmap->qtail);
-
- dmap->qlen++;
- if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
- printk ("\nSound: Audio queue2 corrupted for dev%d (%d/%d)\n",
- dev, dmap->qlen, dmap->nbufs);
-
- dmap->counts[dmap->qtail] = l;
-
- if ((l != dmap->fragment_size) &&
- ((audio_devs[dev]->flags & DMA_AUTOMODE) &&
- audio_devs[dev]->flags & NEEDS_RESTART))
- dmap->flags |= DMA_RESTART;
- else
- dmap->flags &= ~DMA_RESTART;
-
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
-
- if (!(dmap->flags & DMA_ACTIVE))
- {
- dmap->flags |= DMA_ACTIVE;
- audio_devs[dev]->output_block (dev, dmap->buf_phys[dmap->qhead],
- dmap->counts[dmap->qhead], 0,
- !(audio_devs[dev]->flags & DMA_AUTOMODE) ||
- !(dmap->flags & DMA_STARTED));
- dmap->flags |= DMA_STARTED;
- }
-
- return 0;
-}
-
-int
-DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
-{
- int chan = audio_devs[dev]->dmachan;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
-#ifdef linux
- unsigned long flags;
-#endif
- /*
- * This function is not as portable as it should be.
- */
-
- /*
- * The count must be one less than the actual size. This is handled by
- * set_dma_addr()
- */
-
- if (audio_devs[dev]->flags & DMA_AUTOMODE)
- { /*
- * Auto restart mode. Transfer the whole *
- * buffer
- */
-#ifdef linux
- DISABLE_INTR (flags);
- disable_dma (chan);
- clear_dma_ff (chan);
- set_dma_mode (chan, dma_mode | DMA_AUTOINIT);
- set_dma_addr (chan, dmap->raw_buf_phys[0]);
- set_dma_count (chan, dmap->bytes_in_use);
- enable_dma (chan);
- RESTORE_INTR (flags);
-#else
-
-#if defined(__FreeBSD__)
-
- isa_dmastart (B_RAW | ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE),
- (caddr_t)dmap->raw_buf_phys[0],
- dmap->bytes_in_use,
- chan);
-#else /* else __FreeBSD__ */
-#if defined(GENERIC_SYSV)
-#ifndef DMAMODE_AUTO
- printk ("sound: Invalid DMA mode for device %d\n", dev);
-#endif
-#if defined(SVR42)
-
- /*
- ** send full count to snd_dma_prog, it will take care of subtracting
- ** one if it is required.
- */
- snd_dma_prog (chan, dmap->raw_buf_phys[0], dmap->bytes_in_use,
- dma_mode, TRUE);
-
-#else /* !SVR42 */
- dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode)
-#ifdef DMAMODE_AUTO
- | DMAMODE_AUTO
-#endif
- ,
- dmap->raw_buf_phys[0], dmap->bytes_in_use - 1);
- dma_enable (chan);
-#endif /* ! SVR42 */
-#else
-#error This routine is not valid for this OS.
-#endif
-#endif
-
-#endif
- }
- else
- {
-#ifdef linux
- DISABLE_INTR (flags);
- disable_dma (chan);
- clear_dma_ff (chan);
- set_dma_mode (chan, dma_mode);
- set_dma_addr (chan, physaddr);
- set_dma_count (chan, count);
- enable_dma (chan);
- RESTORE_INTR (flags);
-#else
-#if defined(__FreeBSD__)
- isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,
- (caddr_t)physaddr,
- count,
- chan);
-#else /* FreeBSD */
-
-#if defined(GENERIC_SYSV)
-#if defined(SVR42)
-
- snd_dma_prog (chan, physaddr, count, dma_mode, FALSE);
-
-#else /* ! SVR42 */
- dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode),
- physaddr, count);
- dma_enable (chan);
-#endif /* SVR42 */
-#else
-#error This routine is not valid for this OS.
-#endif /* GENERIC_SYSV */
-#endif
-
-#endif
- }
-
- return count;
-}
-
-long
-DMAbuf_init (long mem_start)
-{
- int dev;
-
-#if defined(SVR42)
- snd_dma_init ();
-#endif /* SVR42 */
-
- /*
- * NOTE! This routine could be called several times.
- */
-
- for (dev = 0; dev < num_audiodevs; dev++)
- audio_devs[dev]->dmap = &dmaps[dev];
- return mem_start;
-}
-
-void
-DMAbuf_outputintr (int dev, int event_type)
-{
- /*
- * Event types:
- * 0 = DMA transfer done. Device still has more data in the local
- * buffer.
- * 1 = DMA transfer done. Device doesn't have local buffer or it's
- * empty now.
- * 2 = No DMA transfer but the device has now more space in it's local
- * buffer.
- */
-
- unsigned long flags;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
-
-#if defined(SVR42)
- snd_dma_intr (audio_devs[dev]->dmachan);
-#endif /* SVR42 */
-
- if (event_type != 2)
- {
- if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
- {
- printk ("\nSound: Audio queue3 corrupted for dev%d (%d/%d)\n",
- dev, dmap->qlen, dmap->nbufs);
- return;
- }
-
- dmap->qlen--;
- dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
- dmap->flags &= ~DMA_ACTIVE;
-
-#ifdef __FreeBSD__
- isa_dmadone(0, 0, 0, audio_devs[dev]->dmachan);
-#endif
-
- if (dmap->qlen)
- {
- audio_devs[dev]->output_block (dev, dmap->buf_phys[dmap->qhead],
- dmap->counts[dmap->qhead], 1,
- !(audio_devs[dev]->flags & DMA_AUTOMODE));
- dmap->flags |= DMA_ACTIVE;
- }
- else if (event_type == 1)
- {
- dmap->underrun_count++;
- audio_devs[dev]->halt_xfer (dev);
- if ((audio_devs[dev]->flags & DMA_AUTOMODE) &&
- audio_devs[dev]->flags & NEEDS_RESTART)
- dmap->flags |= DMA_RESTART;
- else
- dmap->flags &= ~DMA_RESTART;
- }
- } /* event_type != 2 */
-
- DISABLE_INTR (flags);
- if (SOMEONE_WAITING (dev_sleeper[dev], dev_sleep_flag[dev]))
- {
- WAKE_UP (dev_sleeper[dev], dev_sleep_flag[dev]);
- }
- RESTORE_INTR (flags);
-#if defined(__FreeBSD__)
- if(selinfo[dev].si_pid)
- selwakeup(&selinfo[dev]);
-#endif
-}
-
-void
-DMAbuf_inputintr (int dev)
-{
- unsigned long flags;
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
-
-#if defined(SVR42)
- snd_dma_intr (audio_devs[dev]->dmachan);
-#endif /* SVR42 */
-
-#ifdef __FreeBSD__
- isa_dmadone(0, 0, 0, audio_devs[dev]->dmachan);
-#endif
-
- if (dmap->qlen == (dmap->nbufs - 1))
- {
-#if !defined(__FreeBSD__) /* ignore console message. */
- printk ("Sound: Recording overrun\n");
-#endif
- dmap->underrun_count++;
- audio_devs[dev]->halt_xfer (dev);
- dmap->flags &= ~DMA_ACTIVE;
- if (audio_devs[dev]->flags & DMA_AUTOMODE)
- dmap->flags |= DMA_RESTART;
- else
- dmap->flags &= ~DMA_RESTART;
- }
- else
- {
- dmap->qlen++;
- if (dmap->qlen <= 0 || dmap->qlen > dmap->nbufs)
- printk ("\nSound: Audio queue4 corrupted for dev%d (%d/%d)\n",
- dev, dmap->qlen, dmap->nbufs);
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
-
- audio_devs[dev]->start_input (dev, dmap->buf_phys[dmap->qtail],
- dmap->fragment_size, 1,
- !(audio_devs[dev]->flags & DMA_AUTOMODE));
- dmap->flags |= DMA_ACTIVE;
- }
-
- DISABLE_INTR (flags);
- if (SOMEONE_WAITING (dev_sleeper[dev], dev_sleep_flag[dev]))
- {
- WAKE_UP (dev_sleeper[dev], dev_sleep_flag[dev]);
- }
- RESTORE_INTR (flags);
-#if defined(__FreeBSD__)
- if(selinfo[dev].si_pid)
- selwakeup(&selinfo[dev]);
-#endif
-}
-
-int
-DMAbuf_open_dma (int dev)
-{
- unsigned long flags;
- int chan = audio_devs[dev]->dmachan;
-
- if (ALLOC_DMA_CHN (chan, audio_devs[dev]->name))
- {
-#if 0
- /* Enough already! This error is reported twice elsewhere */
- printk ("Unable to grab DMA%d for the audio driver\n", chan);
-#endif
- return RET_ERROR (EBUSY);
- }
-
- DISABLE_INTR (flags);
-#ifdef linux
- disable_dma (chan);
- clear_dma_ff (chan);
-#endif
- RESTORE_INTR (flags);
-
- return 0;
-}
-
-void
-DMAbuf_close_dma (int dev)
-{
- int chan = audio_devs[dev]->dmachan;
-
- DMAbuf_reset_dma (dev);
- RELEASE_DMA_CHN (chan);
-}
-
-void
-DMAbuf_reset_dma (int dev)
-{
-}
-
-#ifdef ALLOW_SELECT
-int
-DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
-{
- struct dma_buffparms *dmap = audio_devs[dev]->dmap;
- unsigned long flags;
-
- switch (sel_type)
- {
- case SEL_IN:
- if (dmap->dma_mode != DMODE_INPUT)
- return 0;
-
- DISABLE_INTR (flags);
- if (!dmap->qlen)
- {
-#if defined(__FreeBSD__)
- selrecord(wait, &selinfo[dev]);
-#else
- dev_sleep_flag[dev].mode = WK_SLEEP;
- select_wait (&dev_sleeper[dev], wait);
-#endif
- RESTORE_INTR (flags);
- return 0;
- }
- RESTORE_INTR (flags);
- return 1;
- break;
-
- case SEL_OUT:
- if (dmap->dma_mode == DMODE_INPUT)
- return 0;
-
- if (dmap->dma_mode == DMODE_NONE)
- return 1;
-
- DISABLE_INTR (flags);
- if (!space_in_queue (dev))
- {
-#if defined(__FreeBSD__)
- selrecord(wait, &selinfo[dev]);
-#else
- dev_sleep_flag[dev].mode = WK_SLEEP;
- select_wait (&dev_sleeper[dev], wait);
-#endif
- RESTORE_INTR (flags);
- return 0;
- }
- RESTORE_INTR (flags);
- return 1;
- break;
-
- case SEL_EX:
- return 0;
- }
-
- return 0;
-}
-
-#endif /* ALLOW_SELECT */
-
-#else /* EXCLUDE_AUDIO */
-/*
- * Stub versions if audio services not included
- */
-
-int
-DMAbuf_open (int dev, int mode)
-{
- return RET_ERROR (ENXIO);
-}
-
-int
-DMAbuf_release (int dev, int mode)
-{
- return 0;
-}
-
-int
-DMAbuf_getwrbuffer (int dev, char **buf, int *size, int dontblock)
-{
- return RET_ERROR (EIO);
-}
-
-int
-DMAbuf_getrdbuffer (int dev, char **buf, int *len, int dontblock)
-{
- return RET_ERROR (EIO);
-}
-
-int
-DMAbuf_rmchars (int dev, int buff_no, int c)
-{
- return RET_ERROR (EIO);
-}
-
-int
-DMAbuf_start_output (int dev, int buff_no, int l)
-{
- return RET_ERROR (EIO);
-}
-
-int
-DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
-{
- return RET_ERROR (EIO);
-}
-
-long
-DMAbuf_init (long mem_start)
-{
- return mem_start;
-}
-
-int
-DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
-{
- return RET_ERROR (EIO);
-}
-
-int
-DMAbuf_open_dma (int dev)
-{
- return RET_ERROR (ENXIO);
-}
-
-void
-DMAbuf_close_dma (int dev)
-{
- return;
-}
-
-void
-DMAbuf_reset_dma (int dev)
-{
- return;
-}
-
-void
-DMAbuf_inputintr (int dev)
-{
- return;
-}
-
-void
-DMAbuf_outputintr (int dev, int underrun_flag)
-{
- return;
-}
-
-#endif
-
-#endif
diff --git a/sys/pc98/pc98/sound/gus_card.c b/sys/pc98/pc98/sound/gus_card.c
deleted file mode 100644
index 0e96df1..0000000
--- a/sys/pc98/pc98/sound/gus_card.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * sound/gus_card.c
- *
- * Detection routine for the Gravis Ultrasound.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
-
-#include <i386/isa/sound/gus_hw.h>
-
-int gus_base, gus_irq, gus_dma;
-extern int gus_wave_volume;
-extern int gus_pcm_volume;
-extern int have_gus_max;
-
-long
-attach_gus_card (long mem_start, struct address_info *hw_config)
-{
- int io_addr;
-
- snd_set_irq_handler (hw_config->irq, gusintr, "Gravis Ultrasound");
-
- if (gus_wave_detect (hw_config->io_base)) /*
- * Try first the default
- */
- {
- mem_start = gus_wave_init (mem_start, hw_config->irq, hw_config->dma,
- hw_config->dma_read);
-#ifndef EXCLUDE_MIDI
- mem_start = gus_midi_init (mem_start);
-#endif
-#ifndef EXCLUDE_SEQUENCER
- sound_timer_init (hw_config->io_base + 8);
-#endif
- return mem_start;
- }
-
-#ifndef EXCLUDE_GUS_IODETECT
-
- /*
- * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
- */
-
- for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
- if (io_addr != hw_config->io_base) /*
- * Already tested
- */
- if (gus_wave_detect (io_addr))
- {
- printk (" WARNING! GUS found at %x, config was %x ", io_addr, hw_config->io_base);
- mem_start = gus_wave_init (mem_start, hw_config->irq, hw_config->dma,
- hw_config->dma_read);
-#ifndef EXCLUDE_MIDI
- mem_start = gus_midi_init (mem_start);
-#endif
-#ifndef EXCLUDE_SEQUENCER
- sound_timer_init (io_addr + 8);
-#endif
- return mem_start;
- }
-
-#endif
-
- return mem_start; /*
- * Not detected
- */
-}
-
-int
-probe_gus (struct address_info *hw_config)
-{
- int io_addr;
-
- if (gus_wave_detect (hw_config->io_base))
- return 1;
-
-#ifndef EXCLUDE_GUS_IODETECT
-
- /*
- * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)
- */
-
- for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)
- if (io_addr != hw_config->io_base) /*
- * Already tested
- */
- if (gus_wave_detect (io_addr))
- return 1;
-
-#endif
-
- return 0;
-}
-
-void
-gusintr (INT_HANDLER_PARMS (irq, dummy))
-{
- unsigned char src;
-
-#ifdef linux
- sti ();
-#endif
-
-#ifndef EXCLUDE_GUSMAX
- if (have_gus_max)
-# if defined(__FreeBSD__)
- ad1848_interrupt (INT_HANDLER_CALL (gus_irq));
-# else
- ad1848_interrupt (INT_HANDLER_CALL (irq));
-# endif
-#endif
-
- while (1)
- {
- if (!(src = INB (u_IrqStatus)))
- return;
-
- if (src & DMA_TC_IRQ)
- {
- guswave_dma_irq ();
- }
-
- if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))
- {
-#ifndef EXCLUDE_MIDI
- gus_midi_interrupt (0);
-#endif
- }
-
- if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))
- {
-#ifndef EXCLUDE_SEQUENCER
- sound_timer_interrupt ();
-#else
- gus_write8 (0x45, 0); /* Stop timers */
-#endif
- }
-
- if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))
- {
- gus_voice_irq ();
- }
- }
-}
-
-#endif
-
-/*
- * Some extra code for the 16 bit sampling option
- */
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS16)
-
-int
-probe_gus_db16 (struct address_info *hw_config)
-{
- return ad1848_detect (hw_config->io_base);
-}
-
-long
-attach_gus_db16 (long mem_start, struct address_info *hw_config)
-{
- gus_pcm_volume = 100;
- gus_wave_volume = 90;
-
- ad1848_init ("GUS 16 bit sampling", hw_config->io_base,
- hw_config->irq,
- hw_config->dma,
- hw_config->dma);
- return mem_start;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/gus_midi.c b/sys/pc98/pc98/sound/gus_midi.c
deleted file mode 100644
index 876c665..0000000
--- a/sys/pc98/pc98/sound/gus_midi.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * sound/gus2_midi.c
- *
- * The low level driver for the GUS Midi Interface.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#ifdef CONFIGURE_SOUNDCARD
-
-#include <i386/isa/sound/gus_hw.h>
-
-#if !defined(EXCLUDE_GUS) && !defined(EXCLUDE_MIDI)
-
-static int midi_busy = 0, input_opened = 0;
-static int my_dev;
-static int output_used = 0;
-static volatile unsigned char gus_midi_control;
-
-static void (*midi_input_intr) (int dev, unsigned char data);
-
-static unsigned char tmp_queue[256];
-static volatile int qlen;
-static volatile unsigned char qhead, qtail;
-extern int gus_base, gus_irq, gus_dma;
-
-#define GUS_MIDI_STATUS() INB(u_MidiStatus)
-
-static int
-gus_midi_open (int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
-
- if (midi_busy)
- {
- printk ("GUS: Midi busy\n");
- return RET_ERROR (EBUSY);
- }
-
- OUTB (MIDI_RESET, u_MidiControl);
- gus_delay ();
-
- gus_midi_control = 0;
- input_opened = 0;
-
- if (mode == OPEN_READ || mode == OPEN_READWRITE)
- {
- gus_midi_control |= MIDI_ENABLE_RCV;
- input_opened = 1;
- }
-
- if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
- {
- gus_midi_control |= MIDI_ENABLE_XMIT;
- }
-
- OUTB (gus_midi_control, u_MidiControl); /*
- * Enable
- */
-
- midi_busy = 1;
- qlen = qhead = qtail = output_used = 0;
- midi_input_intr = input;
-
- return 0;
-}
-
-static int
-dump_to_midi (unsigned char midi_byte)
-{
- unsigned long flags;
- int ok = 0;
-
- output_used = 1;
-
- DISABLE_INTR (flags);
-
- if (GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY)
- {
- ok = 1;
- OUTB (midi_byte, u_MidiData);
- }
- else
- {
- /*
- * Enable Midi xmit interrupts (again)
- */
- gus_midi_control |= MIDI_ENABLE_XMIT;
- OUTB (gus_midi_control, u_MidiControl);
- }
-
- RESTORE_INTR (flags);
- return ok;
-}
-
-static void
-gus_midi_close (int dev)
-{
- /*
- * Reset FIFO pointers, disable intrs
- */
-
- OUTB (MIDI_RESET, u_MidiControl);
- midi_busy = 0;
-}
-
-static int
-gus_midi_out (int dev, unsigned char midi_byte)
-{
-
- unsigned long flags;
-
- /*
- * Drain the local queue first
- */
-
- DISABLE_INTR (flags);
-
- while (qlen && dump_to_midi (tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
-
- RESTORE_INTR (flags);
-
- /*
- * Output the byte if the local queue is empty.
- */
-
- if (!qlen)
- if (dump_to_midi (midi_byte))
- return 1; /*
- * OK
- */
-
- /*
- * Put to the local queue
- */
-
- if (qlen >= 256)
- return 0; /*
- * Local queue full
- */
-
- DISABLE_INTR (flags);
-
- tmp_queue[qtail] = midi_byte;
- qlen++;
- qtail++;
-
- RESTORE_INTR (flags);
-
- return 1;
-}
-
-static int
-gus_midi_start_read (int dev)
-{
- return 0;
-}
-
-static int
-gus_midi_end_read (int dev)
-{
- return 0;
-}
-
-static int
-gus_midi_ioctl (int dev, unsigned cmd, unsigned arg)
-{
- return RET_ERROR (EINVAL);
-}
-
-static void
-gus_midi_kick (int dev)
-{
-}
-
-static int
-gus_midi_buffer_status (int dev)
-{
- unsigned long flags;
-
- if (!output_used)
- return 0;
-
- DISABLE_INTR (flags);
-
- if (qlen && dump_to_midi (tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
-
- RESTORE_INTR (flags);
-
- return (qlen > 0) | !(GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY);
-}
-
-#define MIDI_SYNTH_NAME "Gravis Ultrasound Midi"
-#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
-#include <i386/isa/sound/midi_synth.h>
-
-static struct midi_operations gus_midi_operations =
-{
- {"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
- &std_midi_synth,
- {0},
- gus_midi_open,
- gus_midi_close,
- gus_midi_ioctl,
- gus_midi_out,
- gus_midi_start_read,
- gus_midi_end_read,
- gus_midi_kick,
- NULL, /*
- * command
- */
- gus_midi_buffer_status,
- NULL
-};
-
-long
-gus_midi_init (long mem_start)
-{
- if (num_midis >= MAX_MIDI_DEV)
- {
- printk ("Sound: Too many midi devices detected\n");
- return mem_start;
- }
-
- OUTB (MIDI_RESET, u_MidiControl);
-
- std_midi_synth.midi_dev = my_dev = num_midis;
- midi_devs[num_midis++] = &gus_midi_operations;
- return mem_start;
-}
-
-void
-gus_midi_interrupt (int dummy)
-{
- unsigned char stat, data;
- unsigned long flags;
-
- DISABLE_INTR (flags);
-
- stat = GUS_MIDI_STATUS ();
-
- if (stat & MIDI_RCV_FULL)
- {
- data = INB (u_MidiData);
- if (input_opened)
- midi_input_intr (my_dev, data);
- }
-
- if (stat & MIDI_XMIT_EMPTY)
- {
- while (qlen && dump_to_midi (tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
-
- if (!qlen)
- {
- /*
- * Disable Midi output interrupts, since no data in the buffer
- */
- gus_midi_control &= ~MIDI_ENABLE_XMIT;
- OUTB (gus_midi_control, u_MidiControl);
- }
- }
-
-#if 0
- if (stat & MIDI_FRAME_ERR)
- printk ("GUS: Midi framing error\n");
- if (stat & MIDI_OVERRUN && input_opened)
- printk ("GUS: Midi input overrun\n");
-#endif
-
- RESTORE_INTR (flags);
-}
-
-#endif
-
-#endif
diff --git a/sys/pc98/pc98/sound/gus_vol.c b/sys/pc98/pc98/sound/gus_vol.c
deleted file mode 100644
index a8f1121..0000000
--- a/sys/pc98/pc98/sound/gus_vol.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * gus_vol.c - Compute volume for GUS.
- *
- * Greg Lee 1993.
- */
-#include <i386/isa/sound/sound_config.h>
-#ifndef EXCLUDE_GUS
-#include <i386/isa/sound/gus_linearvol.h>
-
-extern unsigned short gus_adagio_vol (int vel, int mainv, int xpn, int voicev);
-extern unsigned short gus_linear_vol (int vol, int mainvol);
-
-#define GUS_VOLUME gus_wave_volume
-
-
-extern int gus_wave_volume;
-
-/*
- * Calculate gus volume from note velocity, main volume, expression, and
- * intrinsic patch volume given in patch library. Expression is multiplied
- * in, so it emphasizes differences in note velocity, while main volume is
- * added in -- I don't know whether this is right, but it seems reasonable to
- * me. (In the previous stage, main volume controller messages were changed
- * to expression controller messages, if they were found to be used for
- * dynamic volume adjustments, so here, main volume can be assumed to be
- * constant throughout a song.)
- *
- * Intrinsic patch volume is added in, but if over 64 is also multiplied in, so
- * we can give a big boost to very weak voices like nylon guitar and the
- * basses. The normal value is 64. Strings are assigned lower values.
- */
-unsigned short
-gus_adagio_vol (int vel, int mainv, int xpn, int voicev)
-{
- int i, m, n, x;
-
-
- /*
- * A voice volume of 64 is considered neutral, so adjust the main volume if
- * something other than this neutral value was assigned in the patch
- * library.
- */
- x = 256 + 6 * (voicev - 64);
-
- /*
- * Boost expression by voice volume above neutral.
- */
- if (voicev > 65)
- xpn += voicev - 64;
- xpn += (voicev - 64) / 2;
-
- /*
- * Combine multiplicative and level components.
- */
- x = vel * xpn * 6 + (voicev / 4) * x;
-
-#ifdef GUS_VOLUME
- /*
- * Further adjustment by installation-specific master volume control
- * (default 60).
- */
- x = (x * GUS_VOLUME * GUS_VOLUME) / 10000;
-#endif
-
-#ifdef GUS_USE_CHN_MAIN_VOLUME
- /*
- * Experimental support for the channel main volume
- */
-
- mainv = (mainv / 2) + 64; /* Scale to 64 to 127 */
- x = (x * mainv * mainv) / 16384;
-#endif
-
- if (x < 2)
- return (0);
- else if (x >= 65535)
- return ((15 << 8) | 255);
-
- /*
- * Convert to gus's logarithmic form with 4 bit exponent i and 8 bit
- * mantissa m.
- */
- n = x;
- i = 7;
- if (n < 128)
- {
- while (i > 0 && n < (1 << i))
- i--;
- }
- else
- while (n > 255)
- {
- n >>= 1;
- i++;
- }
- /*
- * Mantissa is part of linear volume not expressed in exponent. (This is
- * not quite like real logs -- I wonder if it's right.)
- */
- m = x - (1 << i);
-
- /*
- * Adjust mantissa to 8 bits.
- */
- if (m > 0)
- {
- if (i > 8)
- m >>= i - 8;
- else if (i < 8)
- m <<= 8 - i;
- }
-
- return ((i << 8) + m);
-}
-
-/*
- * Volume-values are interpreted as linear values. Volume is based on the
- * value supplied with SEQ_START_NOTE(), channel main volume (if compiled in)
- * and the volume set by the mixer-device (default 60%).
- */
-
-unsigned short
-gus_linear_vol (int vol, int mainvol)
-{
- int mixer_mainvol;
-
- if (vol <= 0)
- vol = 0;
- else if (vol >= 127)
- vol = 127;
-
-#ifdef GUS_VOLUME
- mixer_mainvol = GUS_VOLUME;
-#else
- mixer_mainvol = 100;
-#endif
-
-#ifdef GUS_USE_CHN_MAIN_VOLUME
- if (mainvol <= 0)
- mainvol = 0;
- else if (mainvol >= 127)
- mainvol = 127;
-#else
- mainvol = 128;
-#endif
-
- return gus_linearvol[(((vol * mainvol) / 128) * mixer_mainvol) / 100];
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/gus_wave.c b/sys/pc98/pc98/sound/gus_wave.c
deleted file mode 100644
index e0f946d6..0000000
--- a/sys/pc98/pc98/sound/gus_wave.c
+++ /dev/null
@@ -1,3445 +0,0 @@
-/*
- * sound/gus_wave.c
- *
- * Driver for the Gravis UltraSound wave table synth.
- *
- * Copyright by Hannu Savolainen 1993, 1994
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-#include <machine/ultrasound.h>
-#include <i386/isa/sound/gus_hw.h>
-
-static unsigned char gus_look8 __P((int reg));
-static unsigned short gus_read16 __P((int reg));
-static void gus_write_addr __P((int reg, unsigned long address, int is16bit));
-static void gus_write16 __P((int reg, unsigned int data));
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
-
-#define MAX_SAMPLE 150
-#define MAX_PATCH 256
-
-struct voice_info
- {
- unsigned long orig_freq;
- unsigned long current_freq;
- unsigned long mode;
- int bender;
- int bender_range;
- int panning;
- int midi_volume;
- unsigned int initial_volume;
- unsigned int current_volume;
- int loop_irq_mode, loop_irq_parm;
-#define LMODE_FINISH 1
-#define LMODE_PCM 2
-#define LMODE_PCM_STOP 3
- int volume_irq_mode, volume_irq_parm;
-#define VMODE_HALT 1
-#define VMODE_ENVELOPE 2
-#define VMODE_START_NOTE 3
-
- int env_phase;
- unsigned char env_rate[6];
- unsigned char env_offset[6];
-
- /*
- * Volume computation parameters for gus_adagio_vol()
- */
- int main_vol, expression_vol, patch_vol;
-
- /* Variables for "Ultraclick" removal */
- int dev_pending, note_pending, volume_pending, sample_pending;
- char kill_pending;
- long offset_pending;
-
- };
-
-static struct voice_alloc_info *voice_alloc;
-
-extern int gus_base;
-extern int gus_irq, gus_dma;
-static long gus_mem_size = 0;
-static long free_mem_ptr = 0;
-static int gus_busy[MAX_AUDIO_DEV], gus_dspnum=0;
-static int gus_dma_read=0;
-static int nr_voices = 0;
-static int gus_devnum = 0;
-static int volume_base, volume_scale, volume_method;
-static int gus_recmask = SOUND_MASK_MIC;
-static int recording_active = 0;
-static int only_read_access = 0;
-
-int gus_wave_volume = 60;
-static int gus_pcm_volume = 80;
-int have_gus_max = 0;
-static int gus_line_vol = 100, gus_mic_vol = 0;
-static unsigned char mix_image = 0x00;
-
-/*
- * Current version of this driver doesn't allow synth and PCM functions
- * at the same time. The active_device specifies the active driver
- */
-static int active_device = 0;
-
-#define GUS_DEV_WAVE 1 /* Wave table synth */
-#define GUS_DEV_PCM_DONE 2 /* PCM device, transfer done */
-#define GUS_DEV_PCM_CONTINUE 3 /* PCM device, transfer done ch. 1/2 */
-
-static int gus_sampling_speed;
-static int gus_sampling_channels;
-static int gus_sampling_bits;
-
-DEFINE_WAIT_QUEUE (dram_sleeper, dram_sleep_flag);
-
-/*
- * Variables and buffers for PCM output
- */
-#define MAX_PCM_BUFFERS (32*MAX_REALTIME_FACTOR) /* Don't change */
-
-static int pcm_bsize, pcm_nblk, pcm_banksize;
-static int pcm_datasize[MAX_PCM_BUFFERS];
-static volatile int pcm_head, pcm_tail, pcm_qlen;
-static volatile int pcm_active;
-static volatile int dma_active;
-static int pcm_opened = 0;
-static int pcm_current_dev;
-static int pcm_current_block;
-static unsigned long pcm_current_buf;
-static int pcm_current_count;
-static int pcm_current_intrflag;
-
-#if defined(__FreeBSD__)
-static char *gus_copy_buf;
-#endif
-
-static struct voice_info voices[32];
-
-static int freq_div_table[] =
-{
- 44100, /* 14 */
- 41160, /* 15 */
- 38587, /* 16 */
- 36317, /* 17 */
- 34300, /* 18 */
- 32494, /* 19 */
- 30870, /* 20 */
- 29400, /* 21 */
- 28063, /* 22 */
- 26843, /* 23 */
- 25725, /* 24 */
- 24696, /* 25 */
- 23746, /* 26 */
- 22866, /* 27 */
- 22050, /* 28 */
- 21289, /* 29 */
- 20580, /* 30 */
- 19916, /* 31 */
- 19293 /* 32 */
-};
-
-static struct patch_info *samples;
-static long sample_ptrs[MAX_SAMPLE + 1];
-static int sample_map[32];
-static int free_sample;
-
-
-static int patch_table[MAX_PATCH];
-static int patch_map[32];
-
-static struct synth_info gus_info =
-{"Gravis UltraSound", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 0, 16, 0, MAX_PATCH};
-
-static void gus_poke (long addr, unsigned char data);
-static void compute_and_set_volume (int voice, int volume, int ramp_time);
-extern unsigned short gus_adagio_vol (int vel, int mainv, int xpn, int voicev);
-extern unsigned short gus_linear_vol (int vol, int mainvol);
-static void compute_volume (int voice, int volume);
-static void do_volume_irq (int voice);
-static void set_input_volumes (void);
-
-#define INSTANT_RAMP -1 /* Instant change. No ramping */
-#define FAST_RAMP 0 /* Fastest possible ramp */
-
-static void
-reset_sample_memory (void)
-{
- int i;
-
- for (i = 0; i <= MAX_SAMPLE; i++)
- sample_ptrs[i] = -1;
- for (i = 0; i < 32; i++)
- sample_map[i] = -1;
- for (i = 0; i < 32; i++)
- patch_map[i] = -1;
-
- gus_poke (0, 0); /* Put a silent sample to the beginning */
- gus_poke (1, 0);
- free_mem_ptr = 2;
-
- free_sample = 0;
-
- for (i = 0; i < MAX_PATCH; i++)
- patch_table[i] = -1;
-}
-
-void
-gus_delay (void)
-{
- int i;
-
- for (i = 0; i < 7; i++)
- INB (u_DRAMIO);
-}
-
-static void
-gus_poke (long addr, unsigned char data)
-{ /* Writes a byte to the DRAM */
- unsigned long flags;
-
- DISABLE_INTR (flags);
- OUTB (0x43, u_Command);
- OUTB (addr & 0xff, u_DataLo);
- OUTB ((addr >> 8) & 0xff, u_DataHi);
-
- OUTB (0x44, u_Command);
- OUTB ((addr >> 16) & 0xff, u_DataHi);
- OUTB (data, u_DRAMIO);
- RESTORE_INTR (flags);
-}
-
-static unsigned char
-gus_peek (long addr)
-{ /* Reads a byte from the DRAM */
- unsigned long flags;
- unsigned char tmp;
-
- DISABLE_INTR (flags);
- OUTB (0x43, u_Command);
- OUTB (addr & 0xff, u_DataLo);
- OUTB ((addr >> 8) & 0xff, u_DataHi);
-
- OUTB (0x44, u_Command);
- OUTB ((addr >> 16) & 0xff, u_DataHi);
- tmp = INB (u_DRAMIO);
- RESTORE_INTR (flags);
-
- return tmp;
-}
-
-void
-gus_write8 (int reg, unsigned int data)
-{ /* Writes to an indirect register (8 bit) */
- unsigned long flags;
-
- DISABLE_INTR (flags);
-
- OUTB (reg, u_Command);
- OUTB ((unsigned char) (data & 0xff), u_DataHi);
-
- RESTORE_INTR (flags);
-}
-
-static unsigned char
-gus_read8 (int reg)
-{ /* Reads from an indirect register (8 bit). Offset 0x80. */
- unsigned long flags;
- unsigned char val;
-
- DISABLE_INTR (flags);
- OUTB (reg | 0x80, u_Command);
- val = INB (u_DataHi);
- RESTORE_INTR (flags);
-
- return val;
-}
-
-static unsigned char
-gus_look8 (int reg)
-{ /* Reads from an indirect register (8 bit). No additional offset. */
- unsigned long flags;
- unsigned char val;
-
- DISABLE_INTR (flags);
- OUTB (reg, u_Command);
- val = INB (u_DataHi);
- RESTORE_INTR (flags);
-
- return val;
-}
-
-static void
-gus_write16 (int reg, unsigned int data)
-{ /* Writes to an indirect register (16 bit) */
- unsigned long flags;
-
- DISABLE_INTR (flags);
-
- OUTB (reg, u_Command);
-
- OUTB ((unsigned char) (data & 0xff), u_DataLo);
- OUTB ((unsigned char) ((data >> 8) & 0xff), u_DataHi);
-
- RESTORE_INTR (flags);
-}
-
-static unsigned short
-gus_read16 (int reg)
-{ /* Reads from an indirect register (16 bit). Offset 0x80. */
- unsigned long flags;
- unsigned char hi, lo;
-
- DISABLE_INTR (flags);
-
- OUTB (reg | 0x80, u_Command);
-
- lo = INB (u_DataLo);
- hi = INB (u_DataHi);
-
- RESTORE_INTR (flags);
-
- return ((hi << 8) & 0xff00) | lo;
-}
-
-static void
-gus_write_addr (int reg, unsigned long address, int is16bit)
-{ /* Writes an 24 bit memory address */
- unsigned long hold_address;
- unsigned long flags;
-
- DISABLE_INTR (flags);
- if (is16bit)
- {
- /*
- * Special processing required for 16 bit patches
- */
-
- hold_address = address;
- address = address >> 1;
- address &= 0x0001ffffL;
- address |= (hold_address & 0x000c0000L);
- }
-
- gus_write16 (reg, (unsigned short) ((address >> 7) & 0xffff));
- gus_write16 (reg + 1, (unsigned short) ((address << 9) & 0xffff));
- /* Could writing twice fix problems with GUS_VOICE_POS() ? Lets try... */
- gus_delay ();
- gus_write16 (reg, (unsigned short) ((address >> 7) & 0xffff));
- gus_write16 (reg + 1, (unsigned short) ((address << 9) & 0xffff));
- RESTORE_INTR (flags);
-}
-
-static void
-gus_select_voice (int voice)
-{
- if (voice < 0 || voice > 31)
- return;
-
- OUTB (voice, u_Voice);
-}
-
-static void
-gus_select_max_voices (int nvoices)
-{
- if (nvoices < 14)
- nvoices = 14;
- if (nvoices > 32)
- nvoices = 32;
-
- voice_alloc->max_voice = nr_voices = nvoices;
-
- gus_write8 (0x0e, (nvoices - 1) | 0xc0);
-}
-
-static void
-gus_voice_on (unsigned int mode)
-{
- gus_write8 (0x00, (unsigned char) (mode & 0xfc));
- gus_delay ();
- gus_write8 (0x00, (unsigned char) (mode & 0xfc));
-}
-
-static void
-gus_voice_off (void)
-{
- gus_write8 (0x00, gus_read8 (0x00) | 0x03);
-}
-
-static void
-gus_voice_mode (unsigned int m)
-{
- unsigned char mode = (unsigned char) (m & 0xff);
-
- gus_write8 (0x00, (gus_read8 (0x00) & 0x03) |
- (mode & 0xfc)); /* Don't touch last two bits */
- gus_delay ();
- gus_write8 (0x00, (gus_read8 (0x00) & 0x03) | (mode & 0xfc));
-}
-
-static void
-gus_voice_freq (unsigned long freq)
-{
- unsigned long divisor = freq_div_table[nr_voices - 14];
- unsigned short fc;
-
- fc = (unsigned short) (((freq << 9) + (divisor >> 1)) / divisor);
- fc = fc << 1;
-
- gus_write16 (0x01, fc);
-}
-
-static void
-gus_voice_volume (unsigned int vol)
-{
- gus_write8 (0x0d, 0x03); /* Stop ramp before setting volume */
- gus_write16 (0x09, (unsigned short) (vol << 4));
-}
-
-static void
-gus_voice_balance (unsigned int balance)
-{
- gus_write8 (0x0c, (unsigned char) (balance & 0xff));
-}
-
-static void
-gus_ramp_range (unsigned int low, unsigned int high)
-{
- gus_write8 (0x07, (unsigned char) ((low >> 4) & 0xff));
- gus_write8 (0x08, (unsigned char) ((high >> 4) & 0xff));
-}
-
-static void
-gus_ramp_rate (unsigned int scale, unsigned int rate)
-{
- gus_write8 (0x06, (unsigned char) (((scale & 0x03) << 6) | (rate & 0x3f)));
-}
-
-static void
-gus_rampon (unsigned int m)
-{
- unsigned char mode = (unsigned char) (m & 0xff);
-
- gus_write8 (0x0d, mode & 0xfc);
- gus_delay ();
- gus_write8 (0x0d, mode & 0xfc);
-}
-
-static void
-gus_ramp_mode (unsigned int m)
-{
- unsigned char mode = (unsigned char) (m & 0xff);
-
- gus_write8 (0x0d, (gus_read8 (0x0d) & 0x03) |
- (mode & 0xfc)); /* Leave the last 2 bits alone */
- gus_delay ();
- gus_write8 (0x0d, (gus_read8 (0x0d) & 0x03) | (mode & 0xfc));
-}
-
-static void
-gus_rampoff (void)
-{
- gus_write8 (0x0d, 0x03);
-}
-
-static void
-gus_set_voice_pos (int voice, long position)
-{
- int sample_no;
-
- if ((sample_no = sample_map[voice]) != -1)
- if (position < samples[sample_no].len)
- if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- voices[voice].offset_pending = position;
- else
- gus_write_addr (0x0a, sample_ptrs[sample_no] + position,
- samples[sample_no].mode & WAVE_16_BITS);
-}
-
-static void
-gus_voice_init (int voice)
-{
- unsigned long flags;
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_voice_volume (0);
- gus_voice_off ();
- gus_write_addr (0x0a, 0, 0); /* Set current position to 0 */
- gus_write8 (0x00, 0x03); /* Voice off */
- gus_write8 (0x0d, 0x03); /* Ramping off */
- voice_alloc->map[voice] = 0;
- voice_alloc->alloc_times[voice] = 0;
- RESTORE_INTR (flags);
-
-}
-
-static void
-gus_voice_init2 (int voice)
-{
- voices[voice].panning = 0;
- voices[voice].mode = 0;
- voices[voice].orig_freq = 20000;
- voices[voice].current_freq = 20000;
- voices[voice].bender = 0;
- voices[voice].bender_range = 200;
- voices[voice].initial_volume = 0;
- voices[voice].current_volume = 0;
- voices[voice].loop_irq_mode = 0;
- voices[voice].loop_irq_parm = 0;
- voices[voice].volume_irq_mode = 0;
- voices[voice].volume_irq_parm = 0;
- voices[voice].env_phase = 0;
- voices[voice].main_vol = 127;
- voices[voice].patch_vol = 127;
- voices[voice].expression_vol = 127;
- voices[voice].sample_pending = -1;
-}
-
-static void
-step_envelope (int voice)
-{
- unsigned vol, prev_vol, phase;
- unsigned char rate;
- long int flags;
-
- if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
- {
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_rampoff ();
- RESTORE_INTR (flags);
- return;
- /*
- * Sustain phase begins. Continue envelope after receiving note off.
- */
- }
-
- if (voices[voice].env_phase >= 5)
- { /* Envelope finished. Shoot the voice down */
- gus_voice_init (voice);
- return;
- }
-
- prev_vol = voices[voice].current_volume;
- phase = ++voices[voice].env_phase;
- compute_volume (voice, voices[voice].midi_volume);
- vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255;
- rate = voices[voice].env_rate[phase];
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
-
- gus_voice_volume (prev_vol);
-
-
- gus_write8 (0x06, rate); /* Ramping rate */
-
- voices[voice].volume_irq_mode = VMODE_ENVELOPE;
-
- if (((vol - prev_vol) / 64) == 0) /* No significant volume change */
- {
- RESTORE_INTR (flags);
- step_envelope (voice); /* Continue the envelope on the next step */
- return;
- }
-
- if (vol > prev_vol)
- {
- if (vol >= (4096 - 64))
- vol = 4096 - 65;
- gus_ramp_range (0, vol);
- gus_rampon (0x20); /* Increasing volume, with IRQ */
- }
- else
- {
- if (vol <= 64)
- vol = 65;
- gus_ramp_range (vol, 4030);
- gus_rampon (0x60); /* Decreasing volume, with IRQ */
- }
- voices[voice].current_volume = vol;
- RESTORE_INTR (flags);
-}
-
-static void
-init_envelope (int voice)
-{
- voices[voice].env_phase = -1;
- voices[voice].current_volume = 64;
-
- step_envelope (voice);
-}
-
-static void
-start_release (int voice, long int flags)
-{
- if (gus_read8 (0x00) & 0x03)
- return; /* Voice already stopped */
-
- voices[voice].env_phase = 2; /* Will be incremented by step_envelope */
-
- voices[voice].current_volume =
- voices[voice].initial_volume =
- gus_read16 (0x09) >> 4; /* Get current volume */
-
- voices[voice].mode &= ~WAVE_SUSTAIN_ON;
- gus_rampoff ();
- RESTORE_INTR (flags);
- step_envelope (voice);
-}
-
-static void
-gus_voice_fade (int voice)
-{
- int instr_no = sample_map[voice], is16bits;
- long int flags;
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
-
- if (instr_no < 0 || instr_no > MAX_SAMPLE)
- {
- gus_write8 (0x00, 0x03); /* Hard stop */
- voice_alloc->map[voice] = 0;
- RESTORE_INTR (flags);
- return;
- }
-
- is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /* 8 or 16 bits */
-
- if (voices[voice].mode & WAVE_ENVELOPES)
- {
- start_release (voice, flags);
- return;
- }
-
- /*
- * Ramp the volume down but not too quickly.
- */
- if ((int) (gus_read16 (0x09) >> 4) < 100) /* Get current volume */
- {
- gus_voice_off ();
- gus_rampoff ();
- gus_voice_init (voice);
- return;
- }
-
- gus_ramp_range (65, 4030);
- gus_ramp_rate (2, 4);
- gus_rampon (0x40 | 0x20); /* Down, once, with IRQ */
- voices[voice].volume_irq_mode = VMODE_HALT;
- RESTORE_INTR (flags);
-}
-
-static void
-gus_reset (void)
-{
- int i;
-
- gus_select_max_voices (24);
- volume_base = 3071;
- volume_scale = 4;
- volume_method = VOL_METHOD_ADAGIO;
-
- for (i = 0; i < 32; i++)
- {
- gus_voice_init (i); /* Turn voice off */
- gus_voice_init2 (i);
- }
-
- INB (u_Status); /* Touch the status register */
-
- gus_look8 (0x41); /* Clear any pending DMA IRQs */
- gus_look8 (0x49); /* Clear any pending sample IRQs */
-
- gus_read8 (0x0f); /* Clear pending IRQs */
-
-}
-
-static void
-gus_initialize (void)
-{
- unsigned long flags;
- unsigned char dma_image, irq_image, tmp;
-
- static unsigned char gus_irq_map[16] =
- {0, 0, 0, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7};
-
- static unsigned char gus_dma_map[8] =
- {0, 1, 0, 2, 0, 3, 4, 5};
-
- DISABLE_INTR (flags);
- gus_write8 (0x4c, 0); /* Reset GF1 */
- gus_delay ();
- gus_delay ();
-
- gus_write8 (0x4c, 1); /* Release Reset */
- gus_delay ();
- gus_delay ();
-
- /*
- * Clear all interrupts
- */
-
- gus_write8 (0x41, 0); /* DMA control */
- gus_write8 (0x45, 0); /* Timer control */
- gus_write8 (0x49, 0); /* Sample control */
-
- gus_select_max_voices (24);
-
- INB (u_Status); /* Touch the status register */
-
- gus_look8 (0x41); /* Clear any pending DMA IRQs */
- gus_look8 (0x49); /* Clear any pending sample IRQs */
- gus_read8 (0x0f); /* Clear pending IRQs */
-
- gus_reset (); /* Resets all voices */
-
- gus_look8 (0x41); /* Clear any pending DMA IRQs */
- gus_look8 (0x49); /* Clear any pending sample IRQs */
- gus_read8 (0x0f); /* Clear pending IRQs */
-
- gus_write8 (0x4c, 7); /* Master reset | DAC enable | IRQ enable */
-
- /*
- * Set up for Digital ASIC
- */
-
- OUTB (0x05, gus_base + 0x0f);
-
- mix_image |= 0x02; /* Disable line out */
- OUTB (mix_image, u_Mixer);
-
- OUTB (0x00, u_IRQDMAControl);
-
- OUTB (0x00, gus_base + 0x0f);
-
- /*
- * Now set up the DMA and IRQ interface
- *
- * The GUS supports two IRQs and two DMAs.
- *
- * Just one DMA channel is used. This prevents simultaneous ADC and DAC.
- * Adding this support requires significant changes to the dmabuf.c, dsp.c
- * and audio.c also.
- */
-
- irq_image = 0;
- tmp = gus_irq_map[gus_irq];
- if (!tmp)
- printk ("Warning! GUS IRQ not selected\n");
- irq_image |= tmp;
- irq_image |= 0x40; /* Combine IRQ1 (GF1) and IRQ2 (Midi) */
-
- dma_image = gus_dma_map[gus_dma_read] << 3;
- if(!dma_image)
- printk ("Warning! GUS DMA read channel not selected.\n");
- if(gus_dma_read == gus_dma)
- {
- dma_image = 0x40; /* dual dma inhibited
- Combine DMA1 (DRAM) and IRQ2 (ADC) */
- }
- tmp = gus_dma_map[gus_dma];
- if (!tmp)
- printk ("Warning! GUS DMA not selected\n");
- dma_image |= tmp;
-
- /*
- * For some reason the IRQ and DMA addresses must be written twice
- */
-
- /*
- * Doing it first time
- */
-
- OUTB (mix_image, u_Mixer); /* Select DMA control */
- OUTB (dma_image | 0x80, u_IRQDMAControl); /* Set DMA address */
-
- OUTB (mix_image | 0x40, u_Mixer); /* Select IRQ control */
- OUTB (irq_image, u_IRQDMAControl); /* Set IRQ address */
-
- /*
- * Doing it second time
- */
-
- OUTB (mix_image, u_Mixer); /* Select DMA control */
- OUTB (dma_image, u_IRQDMAControl); /* Set DMA address */
-
- OUTB (mix_image | 0x40, u_Mixer); /* Select IRQ control */
- OUTB (irq_image, u_IRQDMAControl); /* Set IRQ address */
-
- gus_select_voice (0); /* This disables writes to IRQ/DMA reg */
-
- mix_image &= ~0x02; /* Enable line out */
- mix_image |= 0x08; /* Enable IRQ */
- OUTB (mix_image, u_Mixer); /*
- * Turn mixer channels on
- * Note! Mic in is left off.
- */
-
- gus_select_voice (0); /* This disables writes to IRQ/DMA reg */
-
- gusintr (INT_HANDLER_CALL (0)); /* Serve pending interrupts */
- RESTORE_INTR (flags);
-}
-
-int
-gus_wave_detect (int baseaddr)
-{
- unsigned long i;
- unsigned long loc;
-
- gus_base = baseaddr;
-
- gus_write8 (0x4c, 0); /* Reset GF1 */
- gus_delay ();
- gus_delay ();
-
- gus_write8 (0x4c, 1); /* Release Reset */
- gus_delay ();
- gus_delay ();
-
- /* See if there is first block there.... */
- gus_poke (0L, 0xaa);
- if (gus_peek (0L) != 0xaa)
- return (0);
-
- /* Now zero it out so that I can check for mirroring .. */
- gus_poke (0L, 0x00);
- for (i = 1L; i < 1024L; i++)
- {
- int n, failed;
-
- /* check for mirroring ... */
- if (gus_peek (0L) != 0)
- break;
- loc = i << 10;
-
- for (n = loc - 1, failed = 0; n <= loc; n++)
- {
- gus_poke (loc, 0xaa);
- if (gus_peek (loc) != 0xaa)
- failed = 1;
-
- gus_poke (loc, 0x55);
- if (gus_peek (loc) != 0x55)
- failed = 1;
- }
-
- if (failed)
- break;
- }
- gus_mem_size = i << 10;
- return 1;
-}
-
-static int
-guswave_ioctl (int dev,
- unsigned int cmd, unsigned int arg)
-{
-
- switch (cmd)
- {
- case SNDCTL_SYNTH_INFO:
- gus_info.nr_voices = nr_voices;
- IOCTL_TO_USER ((char *) arg, 0, &gus_info, sizeof (gus_info));
- return 0;
- break;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- reset_sample_memory ();
- return 0;
- break;
-
- case SNDCTL_SEQ_PERCMODE:
- return 0;
- break;
-
- case SNDCTL_SYNTH_MEMAVL:
- return gus_mem_size - free_mem_ptr - 32;
-
- default:
- return RET_ERROR (EINVAL);
- }
-}
-
-static int
-guswave_set_instr (int dev, int voice, int instr_no)
-{
- int sample_no;
-
- if (instr_no < 0 || instr_no > MAX_PATCH)
- return RET_ERROR (EINVAL);
-
- if (voice < 0 || voice > 31)
- return RET_ERROR (EINVAL);
-
- if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- {
- voices[voice].sample_pending = instr_no;
- return 0;
- }
-
- sample_no = patch_table[instr_no];
- patch_map[voice] = -1;
-
- if (sample_no < 0)
- {
- printk ("GUS: Undefined patch %d for voice %d\n", instr_no, voice);
- return RET_ERROR (EINVAL); /* Patch not defined */
- }
-
- if (sample_ptrs[sample_no] == -1) /* Sample not loaded */
- {
- printk ("GUS: Sample #%d not loaded for patch %d (voice %d)\n",
- sample_no, instr_no, voice);
- return RET_ERROR (EINVAL);
- }
-
- sample_map[voice] = sample_no;
- patch_map[voice] = instr_no;
- return 0;
-}
-
-static int
-guswave_kill_note (int dev, int voice, int note, int velocity)
-{
- unsigned long flags;
-
- DISABLE_INTR (flags);
- /* voice_alloc->map[voice] = 0xffff; */
- if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- {
- voices[voice].kill_pending = 1;
- RESTORE_INTR (flags);
- }
- else
- {
- RESTORE_INTR (flags);
- gus_voice_fade (voice);
- }
-
- RESTORE_INTR (flags);
- return 0;
-}
-
-static void
-guswave_aftertouch (int dev, int voice, int pressure)
-{
-#if 0
- short lo_limit, hi_limit;
- unsigned long flags;
-
- if (voice < 0 || voice > 31)
- return;
-
- if (voices[voice].mode & WAVE_ENVELOPES && voices[voice].env_phase != 2)
- return; /* Don't mix with envelopes */
-
- if (pressure < 32)
- {
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_rampoff ();
- compute_and_set_volume (voice, 255, 0); /* Back to original volume */
- RESTORE_INTR (flags);
- return;
- }
-
- hi_limit = voices[voice].current_volume;
- lo_limit = hi_limit * 99 / 100;
- if (lo_limit < 65)
- lo_limit = 65;
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- if (hi_limit > (4095 - 65))
- {
- hi_limit = 4095 - 65;
- gus_voice_volume (hi_limit);
- }
- gus_ramp_range (lo_limit, hi_limit);
- gus_ramp_rate (3, 8);
- gus_rampon (0x58); /* Bidirectional, dow, loop */
- RESTORE_INTR (flags);
-#endif /* 0 */
-}
-
-static void
-guswave_panning (int dev, int voice, int value)
-{
- if (voice >= 0 || voice < 32)
- voices[voice].panning = value;
-}
-
-static void
-guswave_volume_method (int dev, int mode)
-{
- if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO)
- volume_method = mode;
-}
-
-static void
-compute_volume (int voice, int volume)
-{
- if (volume < 128)
- voices[voice].midi_volume = volume;
-
- switch (volume_method)
- {
- case VOL_METHOD_ADAGIO:
- voices[voice].initial_volume =
- gus_adagio_vol (voices[voice].midi_volume, voices[voice].main_vol,
- voices[voice].expression_vol,
- voices[voice].patch_vol);
- break;
-
- case VOL_METHOD_LINEAR: /* Totally ignores patch-volume and expression */
- voices[voice].initial_volume =
- gus_linear_vol (volume, voices[voice].main_vol);
- break;
-
- default:
- voices[voice].initial_volume = volume_base +
- (voices[voice].midi_volume * volume_scale);
- }
-
- if (voices[voice].initial_volume > 4030)
- voices[voice].initial_volume = 4030;
-}
-
-static void
-compute_and_set_volume (int voice, int volume, int ramp_time)
-{
- int current, target, rate;
- unsigned long flags;
-
- compute_volume (voice, volume);
- voices[voice].current_volume = voices[voice].initial_volume;
-
- DISABLE_INTR (flags);
- /*
- * CAUTION! Interrupts disabled. Enable them before returning
- */
-
- gus_select_voice (voice);
-
- current = gus_read16 (0x09) >> 4;
- target = voices[voice].initial_volume;
-
- if (ramp_time == INSTANT_RAMP)
- {
- gus_rampoff ();
- gus_voice_volume (target);
- RESTORE_INTR (flags);
- return;
- }
-
- if (ramp_time == FAST_RAMP)
- rate = 63;
- else
- rate = 16;
- gus_ramp_rate (0, rate);
-
- if ((target - current) / 64 == 0) /* Close enough to target. */
- {
- gus_rampoff ();
- gus_voice_volume (target);
- RESTORE_INTR (flags);
- return;
- }
-
- if (target > current)
- {
- if (target > (4095 - 65))
- target = 4095 - 65;
- gus_ramp_range (current, target);
- gus_rampon (0x00); /* Ramp up, once, no IRQ */
- }
- else
- {
- if (target < 65)
- target = 65;
-
- gus_ramp_range (target, current);
- gus_rampon (0x40); /* Ramp down, once, no irq */
- }
- RESTORE_INTR (flags);
-}
-
-static void
-dynamic_volume_change (int voice)
-{
- unsigned char status;
- unsigned long flags;
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- status = gus_read8 (0x00); /* Get voice status */
- RESTORE_INTR (flags);
-
- if (status & 0x03)
- return; /* Voice was not running */
-
- if (!(voices[voice].mode & WAVE_ENVELOPES))
- {
- compute_and_set_volume (voice, voices[voice].midi_volume, 1);
- return;
- }
-
- /*
- * Voice is running and has envelopes.
- */
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- status = gus_read8 (0x0d); /* Ramping status */
- RESTORE_INTR (flags);
-
- if (status & 0x03) /* Sustain phase? */
- {
- compute_and_set_volume (voice, voices[voice].midi_volume, 1);
- return;
- }
-
- if (voices[voice].env_phase < 0)
- return;
-
- compute_volume (voice, voices[voice].midi_volume);
-
-}
-
-static void
-guswave_controller (int dev, int voice, int ctrl_num, int value)
-{
- unsigned long flags;
- unsigned long freq;
-
- if (voice < 0 || voice > 31)
- return;
-
- switch (ctrl_num)
- {
- case CTRL_PITCH_BENDER:
- voices[voice].bender = value;
-
- if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
- {
- freq = compute_finetune (voices[voice].orig_freq, value,
- voices[voice].bender_range);
- voices[voice].current_freq = freq;
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_voice_freq (freq);
- RESTORE_INTR (flags);
- }
- break;
-
- case CTRL_PITCH_BENDER_RANGE:
- voices[voice].bender_range = value;
- break;
- case CTL_EXPRESSION:
- value /= 128;
- case CTRL_EXPRESSION:
- if (volume_method == VOL_METHOD_ADAGIO)
- {
- voices[voice].expression_vol = value;
- if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
- dynamic_volume_change (voice);
- }
- break;
-
- case CTL_PAN:
- voices[voice].panning = (value * 2) - 128;
- break;
-
- case CTL_MAIN_VOLUME:
- value = (value * 100) / 16383;
-
- case CTRL_MAIN_VOLUME:
- voices[voice].main_vol = value;
- if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
- dynamic_volume_change (voice);
- break;
-
- default:
- break;
- }
-}
-
-static int
-guswave_start_note2 (int dev, int voice, int note_num, int volume)
-{
- int sample, best_sample, best_delta, delta_freq;
- int is16bits, samplep, patch, pan;
- unsigned long note_freq, base_note, freq, flags;
- unsigned char mode = 0;
-
- if (voice < 0 || voice > 31)
- {
- printk ("GUS: Invalid voice\n");
- return RET_ERROR (EINVAL);
- }
-
- if (note_num == 255)
- {
- if (voices[voice].mode & WAVE_ENVELOPES)
- {
- voices[voice].midi_volume = volume;
- dynamic_volume_change (voice);
- return 0;
- }
-
- compute_and_set_volume (voice, volume, 1);
- return 0;
- }
-
- if ((patch = patch_map[voice]) == -1)
- {
- return RET_ERROR (EINVAL);
- }
-
- if ((samplep = patch_table[patch]) == -1)
- {
- return RET_ERROR (EINVAL);
- }
-
- note_freq = note_to_freq (note_num);
-
- /*
- * Find a sample within a patch so that the note_freq is between low_note
- * and high_note.
- */
- sample = -1;
-
- best_sample = samplep;
- best_delta = 1000000;
- while (samplep >= 0 && sample == -1)
- {
- delta_freq = note_freq - samples[samplep].base_note;
- if (delta_freq < 0)
- delta_freq = -delta_freq;
- if (delta_freq < best_delta)
- {
- best_sample = samplep;
- best_delta = delta_freq;
- }
- if (samples[samplep].low_note <= note_freq &&
- note_freq <= samples[samplep].high_note)
- sample = samplep;
- else
- samplep = samples[samplep].key; /*
- * Follow link
- */
- }
- if (sample == -1)
- sample = best_sample;
-
- if (sample == -1)
- {
- printk ("GUS: Patch %d not defined for note %d\n", patch, note_num);
- return 0; /* Should play default patch ??? */
- }
-
- is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0;
- voices[voice].mode = samples[sample].mode;
- voices[voice].patch_vol = samples[sample].volume;
-
- if (voices[voice].mode & WAVE_ENVELOPES)
- {
- int i;
-
- for (i = 0; i < 6; i++)
- {
- voices[voice].env_rate[i] = samples[sample].env_rate[i];
- voices[voice].env_offset[i] = samples[sample].env_offset[i];
- }
- }
-
- sample_map[voice] = sample;
-
- base_note = samples[sample].base_note / 100; /* Try to avoid overflows */
- note_freq /= 100;
-
- freq = samples[sample].base_freq * note_freq / base_note;
-
- voices[voice].orig_freq = freq;
-
- /*
- * Since the pitch bender may have been set before playing the note, we
- * have to calculate the bending now.
- */
-
- freq = compute_finetune (voices[voice].orig_freq, voices[voice].bender,
- voices[voice].bender_range);
- voices[voice].current_freq = freq;
-
- pan = (samples[sample].panning + voices[voice].panning) / 32;
- pan += 7;
- if (pan < 0)
- pan = 0;
- if (pan > 15)
- pan = 15;
-
- if (samples[sample].mode & WAVE_16_BITS)
- {
- mode |= 0x04; /* 16 bits */
- if ((sample_ptrs[sample] >> 18) !=
- ((sample_ptrs[sample] + samples[sample].len) >> 18))
- printk ("GUS: Sample address error\n");
- }
-
- /*************************************************************************
- * CAUTION! Interrupts disabled. Don't return before enabling
- *************************************************************************/
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_voice_off ();
- gus_rampoff ();
-
- RESTORE_INTR (flags);
-
- if (voices[voice].mode & WAVE_ENVELOPES)
- {
- compute_volume (voice, volume);
- init_envelope (voice);
- }
- else
- compute_and_set_volume (voice, volume, 0);
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
-
- if (samples[sample].mode & WAVE_LOOP_BACK)
- gus_write_addr (0x0a, sample_ptrs[sample] + samples[sample].len -
- voices[voice].offset_pending, is16bits); /* start=end */
- else
- gus_write_addr (0x0a, sample_ptrs[sample] + voices[voice].offset_pending,
- is16bits); /* Sample start=begin */
-
- if (samples[sample].mode & WAVE_LOOPING)
- {
- mode |= 0x08;
-
- if (samples[sample].mode & WAVE_BIDIR_LOOP)
- mode |= 0x10;
-
- if (samples[sample].mode & WAVE_LOOP_BACK)
- {
- gus_write_addr (0x0a,
- sample_ptrs[sample] + samples[sample].loop_end -
- voices[voice].offset_pending, is16bits);
- mode |= 0x40;
- }
-
- gus_write_addr (0x02, sample_ptrs[sample] + samples[sample].loop_start,
- is16bits); /* Loop start location */
- gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].loop_end,
- is16bits); /* Loop end location */
- }
- else
- {
- mode |= 0x20; /* Loop IRQ at the end */
- voices[voice].loop_irq_mode = LMODE_FINISH; /* Ramp down at the end */
- voices[voice].loop_irq_parm = 1;
- gus_write_addr (0x02, sample_ptrs[sample],
- is16bits); /* Loop start location */
- gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].len - 1,
- is16bits); /* Loop end location */
- }
- gus_voice_freq (freq);
- gus_voice_balance (pan);
- gus_voice_on (mode);
- RESTORE_INTR (flags);
-
- return 0;
-}
-
-/*
- * New guswave_start_note by Andrew J. Robinson attempts to minimize clicking
- * when the note playing on the voice is changed. It uses volume
- * ramping.
- */
-
-static int
-guswave_start_note (int dev, int voice, int note_num, int volume)
-{
- long int flags;
- int mode;
- int ret_val = 0;
-
- DISABLE_INTR (flags);
- if (note_num == 255)
- {
- if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- voices[voice].volume_pending = volume;
- else
- {
- ret_val = guswave_start_note2 (gus_devnum, voice, note_num, volume);
- }
- }
- else
- {
- gus_select_voice (voice);
- mode = gus_read8 (0x00);
- if (mode & 0x20)
- gus_write8 (0x00, mode & 0xdf); /* No interrupt! */
-
- voices[voice].offset_pending = 0;
- voices[voice].kill_pending = 0;
- voices[voice].volume_irq_mode = 0;
- voices[voice].loop_irq_mode = 0;
-
- if (voices[voice].sample_pending >= 0)
- {
- RESTORE_INTR (flags); /* Run temporarily with interrupts enabled */
- guswave_set_instr (voices[voice].dev_pending, voice,
- voices[voice].sample_pending);
- voices[voice].sample_pending = -1;
- DISABLE_INTR (flags);
- gus_select_voice (voice); /* Reselect the voice (just to be sure) */
- }
-
- if ((mode & 0x01) || (int) ((gus_read16 (0x09) >> 4) < 2065))
- {
- ret_val = guswave_start_note2 (gus_devnum, voice, note_num, volume);
- }
- else
- {
- voices[voice].dev_pending = gus_devnum;
- voices[voice].note_pending = note_num;
- voices[voice].volume_pending = volume;
- voices[voice].volume_irq_mode = VMODE_START_NOTE;
-
- gus_rampoff ();
- gus_ramp_range (2000, 4065);
- gus_ramp_rate (0, 63); /* Fastest possible rate */
- gus_rampon (0x20 | 0x40); /* Ramp down, once, irq */
- }
- }
- RESTORE_INTR (flags);
- return ret_val;
-}
-
-static void
-guswave_reset (int dev)
-{
- int i;
-
- for (i = 0; i < 32; i++)
- {
- gus_voice_init (i);
- gus_voice_init2 (i);
- }
-}
-
-static int
-guswave_open (int dev, int mode)
-{
- int err;
-
- if (mode & OPEN_WRITE && gus_busy[gus_devnum] ||
- mode & OPEN_READ && gus_busy[gus_dspnum])
- return RET_ERROR (EBUSY);
-
- if(gus_busy[gus_devnum] == 0 && gus_busy[gus_dspnum] == 0)
- gus_initialize ();
- voice_alloc->timestamp = 0;
-
- if ((err = DMAbuf_open_dma (gus_devnum)) < 0)
- return err;
-
- RESET_WAIT_QUEUE (dram_sleeper, dram_sleep_flag);
- gus_busy[gus_devnum] = 1;
- active_device = GUS_DEV_WAVE;
-
- gus_reset ();
-
- return 0;
-}
-
-static void
-guswave_close (int dev)
-{
- gus_busy[gus_devnum] = 0;
- active_device = 0;
- gus_reset ();
-
- DMAbuf_close_dma (gus_devnum);
-}
-
-static int
-guswave_load_patch (int dev, int format, snd_rw_buf * addr,
- int offs, int count, int pmgr_flag)
-{
- struct patch_info patch;
- int instr;
- long sizeof_patch;
-
- unsigned long blk_size, blk_end, left, src_offs, target;
-
- sizeof_patch = (long) &patch.data[0] - (long) &patch; /* Header size */
-
- if (format != GUS_PATCH)
- {
- printk ("GUS Error: Invalid patch format (key) 0x%x\n", format);
- return RET_ERROR (EINVAL);
- }
-
- if (count < sizeof_patch)
- {
- printk ("GUS Error: Patch header too short\n");
- return RET_ERROR (EINVAL);
- }
-
- count -= sizeof_patch;
-
- if (free_sample >= MAX_SAMPLE)
- {
- printk ("GUS: Sample table full\n");
- return RET_ERROR (ENOSPC);
- }
-
- /*
- * Copy the header from user space but ignore the first bytes which have
- * been transferred already.
- */
-
- COPY_FROM_USER (&((char *) &patch)[offs], addr, offs, sizeof_patch - offs);
-
- instr = patch.instr_no;
-
- if (instr < 0 || instr > MAX_PATCH)
- {
- printk ("GUS: Invalid patch number %d\n", instr);
- return RET_ERROR (EINVAL);
- }
-
- if (count < patch.len)
- {
- printk ("GUS Warning: Patch record too short (%d<%d)\n",
- count, (int) patch.len);
- patch.len = count;
- }
-
- if (patch.len <= 0 || patch.len > gus_mem_size)
- {
- printk ("GUS: Invalid sample length %d\n", (int) patch.len);
- return RET_ERROR (EINVAL);
- }
-
- if (patch.mode & WAVE_LOOPING)
- {
- if (patch.loop_start < 0 || patch.loop_start >= patch.len)
- {
- printk ("GUS: Invalid loop start\n");
- return RET_ERROR (EINVAL);
- }
-
- if (patch.loop_end < patch.loop_start || patch.loop_end > patch.len)
- {
- printk ("GUS: Invalid loop end\n");
- return RET_ERROR (EINVAL);
- }
- }
-
- free_mem_ptr = (free_mem_ptr + 31) & ~31; /* 32 byte alignment */
-
-#define GUS_BANK_SIZE (256*1024)
-
- if (patch.mode & WAVE_16_BITS)
- {
- /*
- * 16 bit samples must fit one 256k bank.
- */
- if (patch.len >= GUS_BANK_SIZE)
- {
- printk ("GUS: Sample (16 bit) too long %d\n", (int) patch.len);
- return RET_ERROR (ENOSPC);
- }
-
- if ((free_mem_ptr / GUS_BANK_SIZE) !=
- ((free_mem_ptr + patch.len) / GUS_BANK_SIZE))
- {
- unsigned long tmp_mem = /* Aling to 256K */
- ((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
-
- if ((tmp_mem + patch.len) > gus_mem_size)
- return RET_ERROR (ENOSPC);
-
- free_mem_ptr = tmp_mem; /* This leaves unusable memory */
- }
- }
-
- if ((free_mem_ptr + patch.len) > gus_mem_size)
- return RET_ERROR (ENOSPC);
-
- sample_ptrs[free_sample] = free_mem_ptr;
-
- /*
- * Tremolo is not possible with envelopes
- */
-
- if (patch.mode & WAVE_ENVELOPES)
- patch.mode &= ~WAVE_TREMOLO;
-
- memcpy ((char *) &samples[free_sample], &patch, sizeof_patch);
-
- /*
- * Link this_one sample to the list of samples for patch 'instr'.
- */
-
- samples[free_sample].key = patch_table[instr];
- patch_table[instr] = free_sample;
-
- /*
- * Use DMA to transfer the wave data to the DRAM
- */
-
- left = patch.len;
- src_offs = 0;
- target = free_mem_ptr;
-
- while (left) /* Not completely transferred yet */
- {
- blk_size = audio_devs[gus_devnum]->buffsize;
- if (blk_size > left)
- blk_size = left;
-
- /*
- * DMA cannot cross 256k bank boundaries. Check for that.
- */
- blk_end = target + blk_size;
-
- if ((target >> 18) != (blk_end >> 18))
- { /* Split the block */
-
- blk_end &= ~(256 * 1024 - 1);
- blk_size = blk_end - target;
- }
-
-#if defined(GUS_NO_DMA) || defined(GUS_PATCH_NO_DMA)
- /*
- * For some reason the DMA is not possible. We have to use PIO.
- */
- {
- long i;
- unsigned char data;
-
- for (i = 0; i < blk_size; i++)
- {
- GET_BYTE_FROM_USER (data, addr, sizeof_patch + i);
- if (patch.mode & WAVE_UNSIGNED)
-
- if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
- data ^= 0x80; /* Convert to signed */
- gus_poke (target + i, data);
- }
- }
-#else /* GUS_NO_DMA */
- {
- unsigned long address, hold_address;
- unsigned char dma_command;
- unsigned long flags;
-
- /*
- * OK, move now. First in and then out.
- */
-
- COPY_FROM_USER (audio_devs[gus_devnum]->dmap->raw_buf[0],
- addr, sizeof_patch + src_offs,
- blk_size);
-
- DISABLE_INTR (flags);
-/******** INTERRUPTS DISABLED NOW ********/
- gus_write8 (0x41, 0); /* Disable GF1 DMA */
- DMAbuf_start_dma (gus_devnum,
- audio_devs[gus_devnum]->dmap->raw_buf_phys[0],
- blk_size, DMA_MODE_WRITE);
-
- /*
- * Set the DRAM address for the wave data
- */
-
- address = target;
-
- if (audio_devs[gus_devnum]->dmachan > 3)
- {
- hold_address = address;
- address = address >> 1;
- address &= 0x0001ffffL;
- address |= (hold_address & 0x000c0000L);
- }
-
- gus_write16 (0x42, (address >> 4) & 0xffff); /* DRAM DMA address */
-
- /*
- * Start the DMA transfer
- */
-
- dma_command = 0x21; /* IRQ enable, DMA start */
- if (patch.mode & WAVE_UNSIGNED)
- dma_command |= 0x80; /* Invert MSB */
- if (patch.mode & WAVE_16_BITS)
- dma_command |= 0x40; /* 16 bit _DATA_ */
- if (audio_devs[gus_devnum]->dmachan > 3)
- dma_command |= 0x04; /* 16 bit DMA _channel_ */
-
- gus_write8 (0x41, dma_command); /* Lets bo luteet (=bugs) */
-
- /*
- * Sleep here until the DRAM DMA done interrupt is served
- */
- active_device = GUS_DEV_WAVE;
-
- DO_SLEEP (dram_sleeper, dram_sleep_flag, HZ);
- if (TIMED_OUT (dram_sleeper, dram_sleep_flag))
- printk ("GUS: DMA Transfer timed out\n");
- RESTORE_INTR (flags);
- }
-#endif /* GUS_NO_DMA */
-
- /*
- * Now the next part
- */
-
- left -= blk_size;
- src_offs += blk_size;
- target += blk_size;
-
- gus_write8 (0x41, 0); /* Stop DMA */
- }
-
- free_mem_ptr += patch.len;
-
- if (!pmgr_flag)
- pmgr_inform (gus_devnum, PM_E_PATCH_LOADED, instr, free_sample, 0, 0);
- free_sample++;
- return 0;
-}
-
-static void
-guswave_hw_control (int dev, unsigned char *event)
-{
- int voice, cmd;
- unsigned short p1, p2;
- unsigned long plong, flags;
-
- cmd = event[2];
- voice = event[3];
- p1 = *(unsigned short *) &event[4];
- p2 = *(unsigned short *) &event[6];
- plong = *(unsigned long *) &event[4];
-
- if ((voices[voice].volume_irq_mode == VMODE_START_NOTE) &&
- (cmd != _GUS_VOICESAMPLE) && (cmd != _GUS_VOICE_POS))
- do_volume_irq (voice);
-
- switch (cmd)
- {
-
- case _GUS_NUMVOICES:
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_select_max_voices (p1);
- RESTORE_INTR (flags);
- break;
-
- case _GUS_VOICESAMPLE:
- guswave_set_instr (dev, voice, p1);
- break;
-
- case _GUS_VOICEON:
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- p1 &= ~0x20; /* Don't allow interrupts */
- gus_voice_on (p1);
- RESTORE_INTR (flags);
- break;
-
- case _GUS_VOICEOFF:
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_voice_off ();
- RESTORE_INTR (flags);
- break;
-
- case _GUS_VOICEFADE:
- gus_voice_fade (voice);
- break;
-
- case _GUS_VOICEMODE:
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- p1 &= ~0x20; /* Don't allow interrupts */
- gus_voice_mode (p1);
- RESTORE_INTR (flags);
- break;
-
- case _GUS_VOICEBALA:
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_voice_balance (p1);
- RESTORE_INTR (flags);
- break;
-
- case _GUS_VOICEFREQ:
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_voice_freq (plong);
- RESTORE_INTR (flags);
- break;
-
- case _GUS_VOICEVOL:
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_voice_volume (p1);
- RESTORE_INTR (flags);
- break;
-
- case _GUS_VOICEVOL2: /* Just update the software voice level */
- voices[voice].initial_volume =
- voices[voice].current_volume = p1;
- break;
-
- case _GUS_RAMPRANGE:
- if (voices[voice].mode & WAVE_ENVELOPES)
- break; /* NO-NO */
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_ramp_range (p1, p2);
- RESTORE_INTR (flags);
- break;
-
- case _GUS_RAMPRATE:
- if (voices[voice].mode & WAVE_ENVELOPES)
- break; /* NJET-NJET */
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_ramp_rate (p1, p2);
- RESTORE_INTR (flags);
- break;
-
- case _GUS_RAMPMODE:
- if (voices[voice].mode & WAVE_ENVELOPES)
- break; /* NO-NO */
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- p1 &= ~0x20; /* Don't allow interrupts */
- gus_ramp_mode (p1);
- RESTORE_INTR (flags);
- break;
-
- case _GUS_RAMPON:
- if (voices[voice].mode & WAVE_ENVELOPES)
- break; /* EI-EI */
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- p1 &= ~0x20; /* Don't allow interrupts */
- gus_rampon (p1);
- RESTORE_INTR (flags);
- break;
-
- case _GUS_RAMPOFF:
- if (voices[voice].mode & WAVE_ENVELOPES)
- break; /* NEJ-NEJ */
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_rampoff ();
- RESTORE_INTR (flags);
- break;
-
- case _GUS_VOLUME_SCALE:
- volume_base = p1;
- volume_scale = p2;
- break;
-
- case _GUS_VOICE_POS:
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_set_voice_pos (voice, plong);
- RESTORE_INTR (flags);
- break;
-
- default:;
- }
-}
-
-static int
-gus_sampling_set_speed (int speed)
-{
-
- if (speed <= 0)
- speed = gus_sampling_speed;
-
- if (speed < 4000)
- speed = 4000;
-
- if (speed > 44100)
- speed = 44100;
-
- gus_sampling_speed = speed;
-
- if (only_read_access)
- {
- /* Compute nearest valid recording speed and return it */
-
- speed = (9878400 / (gus_sampling_speed + 2)) / 16;
- speed = (9878400 / (speed * 16)) - 2;
- }
- return speed;
-}
-
-static int
-gus_sampling_set_channels (int channels)
-{
- if (!channels)
- return gus_sampling_channels;
- if (channels > 2)
- channels = 2;
- if (channels < 1)
- channels = 1;
- gus_sampling_channels = channels;
- return channels;
-}
-
-static int
-gus_sampling_set_bits (int bits)
-{
- if (!bits)
- return gus_sampling_bits;
-
- if (bits != 8 && bits != 16)
- bits = 8;
-
- gus_sampling_bits = bits;
- return bits;
-}
-
-static int
-gus_sampling_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
-{
- switch (cmd)
- {
- case SOUND_PCM_WRITE_RATE:
- if (local)
- return gus_sampling_set_speed (arg);
- return IOCTL_OUT (arg, gus_sampling_set_speed (IOCTL_IN (arg)));
- break;
-
- case SOUND_PCM_READ_RATE:
- if (local)
- return gus_sampling_speed;
- return IOCTL_OUT (arg, gus_sampling_speed);
- break;
-
- case SNDCTL_DSP_STEREO:
- if (local)
- return gus_sampling_set_channels (arg + 1) - 1;
- return IOCTL_OUT (arg, gus_sampling_set_channels (IOCTL_IN (arg) + 1) - 1);
- break;
-
- case SOUND_PCM_WRITE_CHANNELS:
- if (local)
- return gus_sampling_set_channels (arg);
- return IOCTL_OUT (arg, gus_sampling_set_channels (IOCTL_IN (arg)));
- break;
-
- case SOUND_PCM_READ_CHANNELS:
- if (local)
- return gus_sampling_channels;
- return IOCTL_OUT (arg, gus_sampling_channels);
- break;
-
- case SNDCTL_DSP_SETFMT:
- if (local)
- return gus_sampling_set_bits (arg);
- return IOCTL_OUT (arg, gus_sampling_set_bits (IOCTL_IN (arg)));
- break;
-
- case SOUND_PCM_READ_BITS:
- if (local)
- return gus_sampling_bits;
- return IOCTL_OUT (arg, gus_sampling_bits);
-
- case SOUND_PCM_WRITE_FILTER: /* NOT POSSIBLE */
- return IOCTL_OUT (arg, RET_ERROR (EINVAL));
- break;
-
- case SOUND_PCM_READ_FILTER:
- return IOCTL_OUT (arg, RET_ERROR (EINVAL));
- break;
-
- }
- return RET_ERROR (EINVAL);
-}
-
-static void
-gus_sampling_reset (int dev)
-{
-}
-
-static int
-gus_sampling_open (int dev, int mode)
-{
- int dev_flag;
- int init_flag;
-#ifdef GUS_NO_DMA
- printk ("GUS: DMA mode not enabled. Device not supported\n");
- return RET_ERROR (ENXIO);
-#endif
- dev_flag = 0;
- init_flag = (gus_busy[gus_devnum] == 0 && gus_busy[gus_dspnum] == 0);
- if(mode & OPEN_WRITE)
- {
- if (gus_busy[gus_devnum])
- return RET_ERROR(EBUSY);
- if(dev != gus_devnum)
- return RET_ERROR(ENXIO);
- dev_flag = gus_busy[gus_devnum] = 1;
- }
- if(mode & OPEN_READ)
- {
- if(gus_busy[gus_dspnum]) {
- if (dev_flag) gus_busy[gus_devnum] = 0;
- return RET_ERROR(EBUSY);
- }
-
- if(dev != gus_dspnum) {
- if (dev_flag) gus_busy[gus_devnum] = 0;
- return RET_ERROR(ENXIO);
- }
- }
-
- if(init_flag)
- {
- gus_initialize ();
-
- active_device = 0;
-
- gus_reset ();
- reset_sample_memory ();
- gus_select_max_voices (14);
-
- pcm_active = 0;
- dma_active = 0;
- pcm_opened = 1;
- }
- if (mode & OPEN_READ)
- {
- recording_active = 1;
- set_input_volumes ();
- }
- only_read_access = !(mode & OPEN_WRITE);
-
- return 0;
-}
-
-static void
-gus_sampling_close (int dev)
-{
- gus_busy[dev] = 0;
- if (gus_busy[gus_devnum] == 0 && gus_busy[gus_dspnum] == 0) {
- active_device = 0;
- gus_reset();
- pcm_opened = 0;
- }
-
- if (recording_active)
- set_input_volumes ();
-
- recording_active = 0;
-}
-
-static void
-gus_sampling_update_volume (void)
-{
- unsigned long flags;
- int voice;
-
- if (pcm_active && pcm_opened)
- for (voice = 0; voice < gus_sampling_channels; voice++)
- {
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_rampoff ();
- gus_voice_volume (1530 + (25 * gus_pcm_volume));
- gus_ramp_range (65, 1530 + (25 * gus_pcm_volume));
- RESTORE_INTR (flags);
- }
-}
-
-static void
-play_next_pcm_block (void)
-{
- unsigned long flags;
- int speed = gus_sampling_speed;
- int this_one, is16bits, chn;
- unsigned long dram_loc;
- unsigned char mode[2], ramp_mode[2];
-
- if (!pcm_qlen)
- return;
-
- this_one = pcm_head;
-
- for (chn = 0; chn < gus_sampling_channels; chn++)
- {
- mode[chn] = 0x00;
- ramp_mode[chn] = 0x03; /* Ramping and rollover off */
-
- if (chn == 0)
- {
- mode[chn] |= 0x20; /* Loop IRQ */
- voices[chn].loop_irq_mode = LMODE_PCM;
- }
-
- if (gus_sampling_bits != 8)
- {
- is16bits = 1;
- mode[chn] |= 0x04; /* 16 bit data */
- }
- else
- is16bits = 0;
-
- dram_loc = this_one * pcm_bsize;
- dram_loc += chn * pcm_banksize;
-
- if (this_one == (pcm_nblk - 1)) /* Last fragment of the DRAM buffer */
- {
- mode[chn] |= 0x08; /* Enable loop */
- ramp_mode[chn] = 0x03; /* Disable rollover bit */
- }
- else
- {
- if (chn == 0)
- ramp_mode[chn] = 0x04; /* Enable rollover bit */
- }
-
- DISABLE_INTR (flags);
- gus_select_voice (chn);
- gus_voice_freq (speed);
-
- if (gus_sampling_channels == 1)
- gus_voice_balance (7); /* mono */
- else if (chn == 0)
- gus_voice_balance (0); /* left */
- else
- gus_voice_balance (15); /* right */
-
- if (!pcm_active) /* Playback not already active */
- {
- /*
- * The playback was not started yet (or there has been a pause).
- * Start the voice (again) and ask for a rollover irq at the end of
- * this_one block. If this_one one is last of the buffers, use just
- * the normal loop with irq.
- */
-
- gus_voice_off ();
- gus_rampoff ();
- gus_voice_volume (1530 + (25 * gus_pcm_volume));
- gus_ramp_range (65, 1530 + (25 * gus_pcm_volume));
-
- gus_write_addr (0x0a, dram_loc, is16bits); /* Starting position */
- gus_write_addr (0x02, chn * pcm_banksize, is16bits); /* Loop start */
-
- if (chn != 0)
- gus_write_addr (0x04, pcm_banksize + (pcm_bsize * pcm_nblk) - 1,
- is16bits); /* Loop end location */
- }
-
- if (chn == 0)
- gus_write_addr (0x04, dram_loc + pcm_datasize[this_one] - 1,
- is16bits); /* Loop end location */
- else
- mode[chn] |= 0x08; /* Enable looping */
-
- if (pcm_datasize[this_one] != pcm_bsize)
- {
- /*
- * Incompletely filled block. Possibly the last one.
- */
- if (chn == 0)
- {
- mode[chn] &= ~0x08; /* Disable looping */
- mode[chn] |= 0x20; /* Enable IRQ at the end */
- voices[0].loop_irq_mode = LMODE_PCM_STOP;
- ramp_mode[chn] = 0x03; /* No rollover bit */
- }
- else
- {
- gus_write_addr (0x04, dram_loc + pcm_datasize[this_one],
- is16bits); /* Loop end location */
- mode[chn] &= ~0x08; /* Disable looping */
- }
- }
-
- RESTORE_INTR (flags);
- }
-
- for (chn = 0; chn < gus_sampling_channels; chn++)
- {
- DISABLE_INTR (flags);
- gus_select_voice (chn);
- gus_write8 (0x0d, ramp_mode[chn]);
- gus_voice_on (mode[chn]);
- RESTORE_INTR (flags);
- }
-
- pcm_active = 1;
-}
-
-static void
-gus_transfer_output_block (int dev, unsigned long buf,
- int total_count, int intrflag, int chn)
-{
- /*
- * This routine transfers one block of audio data to the DRAM. In mono mode
- * it's called just once. When in stereo mode, this_one routine is called
- * once for both channels.
- *
- * The left/mono channel data is transferred to the beginning of dram and the
- * right data to the area pointed by gus_page_size.
- */
-
- int this_one, count;
- unsigned long flags;
- unsigned char dma_command;
- unsigned long address, hold_address;
-
- DISABLE_INTR (flags);
-
- count = total_count / gus_sampling_channels;
-
- if (chn == 0)
- {
- if (pcm_qlen >= pcm_nblk)
- printk ("GUS Warning: PCM buffers out of sync\n");
-
- this_one = pcm_current_block = pcm_tail;
- pcm_qlen++;
- pcm_tail = (pcm_tail + 1) % pcm_nblk;
- pcm_datasize[this_one] = count;
- }
- else
- this_one = pcm_current_block;
-
- gus_write8 (0x41, 0); /* Disable GF1 DMA */
- DMAbuf_start_dma (gus_devnum, buf + (chn * count), count, DMA_MODE_WRITE);
-
- address = this_one * pcm_bsize;
- address += chn * pcm_banksize;
-
- if (audio_devs[gus_devnum]->dmachan > 3)
- {
- hold_address = address;
- address = address >> 1;
- address &= 0x0001ffffL;
- address |= (hold_address & 0x000c0000L);
- }
-
- gus_write16 (0x42, (address >> 4) & 0xffff); /* DRAM DMA address */
-
- dma_command = 0x21; /* IRQ enable, DMA start */
-
- if (gus_sampling_bits != 8)
- dma_command |= 0x40; /* 16 bit _DATA_ */
- else
- dma_command |= 0x80; /* Invert MSB */
-
- if (audio_devs[gus_devnum]->dmachan > 3)
- dma_command |= 0x04; /* 16 bit DMA channel */
-
- gus_write8 (0x41, dma_command); /* Kickstart */
-
- if (chn == (gus_sampling_channels - 1)) /* Last channel */
- {
- /*
- * Last (right or mono) channel data
- */
- dma_active = 1; /* DMA started. There is a unacknowledged buffer */
- active_device = GUS_DEV_PCM_DONE;
- if (!pcm_active && (pcm_qlen > 0 || count < pcm_bsize))
- {
- play_next_pcm_block ();
- }
- }
- else
- {
- /*
- * Left channel data. The right channel
- * is transferred after DMA interrupt
- */
- active_device = GUS_DEV_PCM_CONTINUE;
- }
-
- RESTORE_INTR (flags);
-}
-
-static void
-gus_sampling_output_block (int dev, unsigned long buf, int total_count,
- int intrflag, int restart_dma)
-{
- pcm_current_buf = buf;
- pcm_current_count = total_count;
- pcm_current_intrflag = intrflag;
- pcm_current_dev = gus_devnum;
- gus_transfer_output_block (gus_devnum, buf, total_count, intrflag, 0);
-}
-
-static void
-gus_sampling_start_input (int dev, unsigned long buf, int count,
- int intrflag, int restart_dma)
-{
- unsigned long flags;
- unsigned char mode;
-
- DISABLE_INTR (flags);
-
- DMAbuf_start_dma (gus_dspnum, buf, count, DMA_MODE_READ);
-
- mode = 0xa0; /* DMA IRQ enabled, invert MSB */
-
- if (audio_devs[gus_dspnum]->dmachan > 3)
- mode |= 0x04; /* 16 bit DMA channel */
- if (gus_sampling_channels > 1)
- mode |= 0x02; /* Stereo */
- mode |= 0x01; /* DMA enable */
-
- gus_write8 (0x49, mode);
-
- RESTORE_INTR (flags);
-}
-
-static int
-gus_sampling_prepare_for_input (int dev, int bsize, int bcount)
-{
- unsigned int rate;
-
- rate = (9878400 / (gus_sampling_speed + 2)) / 16;
-
- gus_write8 (0x48, rate & 0xff); /* Set sampling rate */
-
- if (gus_sampling_bits != 8)
- {
- printk ("GUS Error: 16 bit recording not supported\n");
- return RET_ERROR (EINVAL);
- }
-
- return 0;
-}
-
-static int
-gus_sampling_prepare_for_output (int dev, int bsize, int bcount)
-{
- int i;
-
- long mem_ptr, mem_size;
-
- mem_ptr = 0;
- mem_size = gus_mem_size / gus_sampling_channels;
-
- if (mem_size > (256 * 1024))
- mem_size = 256 * 1024;
-
- pcm_bsize = bsize / gus_sampling_channels;
- pcm_head = pcm_tail = pcm_qlen = 0;
-
- pcm_nblk = MAX_PCM_BUFFERS;
- if ((pcm_bsize * pcm_nblk) > mem_size)
- pcm_nblk = mem_size / pcm_bsize;
-
- for (i = 0; i < pcm_nblk; i++)
- pcm_datasize[i] = 0;
-
- pcm_banksize = pcm_nblk * pcm_bsize;
-
- if (gus_sampling_bits != 8 && pcm_banksize == (256 * 1024))
- pcm_nblk--;
-
- return 0;
-}
-
-static int
-gus_local_qlen (int dev)
-{
- return pcm_qlen;
-}
-
-static void
-gus_copy_from_user (int dev, char *localbuf, int localoffs,
- snd_rw_buf * userbuf, int useroffs, int len)
-{
- if (gus_sampling_channels == 1)
- {
- COPY_FROM_USER (&localbuf[localoffs], userbuf, useroffs, len);
- }
- else if (gus_sampling_bits == 8)
-#if defined(__FreeBSD__)
- {
- char *in_left = gus_copy_buf;
- char *in_right = in_left + 1;
- char *out_left = localbuf + (localoffs / 2);
- char *out_right = out_left + pcm_bsize;
- int i;
-
- COPY_FROM_USER (gus_copy_buf, userbuf, useroffs, len);
-
- len /= 2;
-
- for (i = 0; i < len; i++)
- {
- *out_left++ = *in_left++;
- in_left++;
- *out_right++ = *in_right++;
- in_right++;
- }
- }
- else
- {
- short *in_left = (short *)gus_copy_buf;
- short *in_right = in_left + 1;
- short *out_left = (short *)localbuf + (localoffs / 4);
- short *out_right = out_left + (pcm_bsize / 2);
- int i;
-
- COPY_FROM_USER (gus_copy_buf, userbuf, useroffs, len);
-
- len /= 4;
-
- for (i = 0; i < len; i++)
- {
- *out_left++ = *in_left++;
- in_left++;
- *out_right++ = *in_right++;
- in_right++;
- }
- }
-#else
- {
- int in_left = useroffs;
- int in_right = useroffs + 1;
- char *out_left, *out_right;
- int i;
-
- len /= 2;
- localoffs /= 2;
- out_left = &localbuf[localoffs];
- out_right = out_left + pcm_bsize;
-
- for (i = 0; i < len; i++)
- {
- GET_BYTE_FROM_USER (*out_left++, userbuf, in_left);
- in_left += 2;
- GET_BYTE_FROM_USER (*out_right++, userbuf, in_right);
- in_right += 2;
- }
- }
- else
- {
- int in_left = useroffs / 2;
- int in_right = useroffs / 2 + 1;
- short *out_left, *out_right;
- int i;
-
- len /= 4;
- localoffs /= 2;
-
- out_left = (short *) &localbuf[localoffs];
- out_right = out_left + (pcm_bsize / 2);
-
- for (i = 0; i < len; i++)
- {
-#ifdef __FreeBSD__
- GET_SHORT_FROM_USER (*out_left++, userbuf, in_left);
- in_left += 2;
- GET_SHORT_FROM_USER (*out_right++, userbuf, in_right);
- in_right += 2;
-#else
- GET_SHORT_FROM_USER (*out_left++, (short *) userbuf, in_left);
- in_left += 2;
- GET_SHORT_FROM_USER (*out_right++, (short *) userbuf, in_right);
- in_right += 2;
-#endif
- }
- }
-#endif
-}
-
-static struct audio_operations gus_sampling_operations =
-{
- "Gravis UltraSound",
- NEEDS_RESTART,
- AFMT_U8 | AFMT_S16_LE,
- NULL,
- gus_sampling_open,
- gus_sampling_close,
- gus_sampling_output_block,
- gus_sampling_start_input,
- gus_sampling_ioctl,
- gus_sampling_prepare_for_input,
- gus_sampling_prepare_for_output,
- gus_sampling_reset,
- gus_sampling_reset,
- gus_local_qlen,
- gus_copy_from_user
-};
-
-static struct audio_operations gus_sampling_operations_read =
-{
- "Gravis UltraSound - read only",
- NEEDS_RESTART,
- AFMT_U8 | AFMT_S16_LE,
- NULL,
- gus_sampling_open,
- gus_sampling_close,
- gus_sampling_output_block,
- gus_sampling_start_input,
- gus_sampling_ioctl,
- gus_sampling_prepare_for_input,
- gus_sampling_prepare_for_output,
- gus_sampling_reset,
- gus_sampling_reset,
- gus_local_qlen,
- gus_copy_from_user
-};
-
-static void
-guswave_setup_voice (int dev, int voice, int chn)
-{
- struct channel_info *info =
- &synth_devs[gus_devnum]->chn_info[chn];
-
- guswave_set_instr (gus_devnum, voice, info->pgm_num);
-
- voices[voice].expression_vol =
- info->controllers[CTL_EXPRESSION]; /* Just msb */
- voices[voice].main_vol =
- (info->controllers[CTL_MAIN_VOLUME] * 100) / 128;
- voices[voice].panning =
- (info->controllers[CTL_PAN] * 2) - 128;
- voices[voice].bender = info->bender_value;
-}
-
-static void
-guswave_bender (int dev, int voice, int value)
-{
- int freq;
- unsigned long flags;
-
- voices[voice].bender = value - 8192;
- freq = compute_finetune (voices[voice].orig_freq, value,
- voices[voice].bender_range);
- voices[voice].current_freq = freq;
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
- gus_voice_freq (freq);
- RESTORE_INTR (flags);
-}
-
-static int
-guswave_patchmgr (int dev, struct patmgr_info *rec)
-{
- int i, n;
-
- switch (rec->command)
- {
- case PM_GET_DEVTYPE:
- rec->parm1 = PMTYPE_WAVE;
- return 0;
- break;
-
- case PM_GET_NRPGM:
- rec->parm1 = MAX_PATCH;
- return 0;
- break;
-
- case PM_GET_PGMMAP:
- rec->parm1 = MAX_PATCH;
-
- for (i = 0; i < MAX_PATCH; i++)
- {
- int ptr = patch_table[i];
-
- rec->data.data8[i] = 0;
-
- while (ptr >= 0 && ptr < free_sample)
- {
- rec->data.data8[i]++;
- ptr = samples[ptr].key; /* Follow link */
- }
- }
- return 0;
- break;
-
- case PM_GET_PGM_PATCHES:
- {
- int ptr = patch_table[rec->parm1];
-
- n = 0;
-
- while (ptr >= 0 && ptr < free_sample)
- {
- rec->data.data32[n++] = ptr;
- ptr = samples[ptr].key; /* Follow link */
- }
- }
- rec->parm1 = n;
- return 0;
- break;
-
- case PM_GET_PATCH:
- {
- int ptr = rec->parm1;
- struct patch_info *pat;
-
- if (ptr < 0 || ptr >= free_sample)
- return RET_ERROR (EINVAL);
-
- memcpy (rec->data.data8, (char *) &samples[ptr],
- sizeof (struct patch_info));
-
- pat = (struct patch_info *) rec->data.data8;
-
- pat->key = GUS_PATCH; /* Restore patch type */
- rec->parm1 = sample_ptrs[ptr]; /* DRAM location */
- rec->parm2 = sizeof (struct patch_info);
- }
- return 0;
- break;
-
- case PM_SET_PATCH:
- {
- int ptr = rec->parm1;
- struct patch_info *pat;
-
- if (ptr < 0 || ptr >= free_sample)
- return RET_ERROR (EINVAL);
-
- pat = (struct patch_info *) rec->data.data8;
-
- if (pat->len > samples[ptr].len) /* Cannot expand sample */
- return RET_ERROR (EINVAL);
-
- pat->key = samples[ptr].key; /* Ensure the link is correct */
-
- memcpy ((char *) &samples[ptr], rec->data.data8,
- sizeof (struct patch_info));
-
- pat->key = GUS_PATCH;
- }
- return 0;
- break;
-
- case PM_READ_PATCH: /* Returns a block of wave data from the DRAM */
- {
- int sample = rec->parm1;
- int n;
- long offs = rec->parm2;
- int l = rec->parm3;
-
- if (sample < 0 || sample >= free_sample)
- return RET_ERROR (EINVAL);
-
- if (offs < 0 || offs >= samples[sample].len)
- return RET_ERROR (EINVAL); /* Invalid offset */
-
- n = samples[sample].len - offs; /* Num of bytes left */
-
- if (l > n)
- l = n;
-
- if (l > sizeof (rec->data.data8))
- l = sizeof (rec->data.data8);
-
- if (l <= 0)
- return RET_ERROR (EINVAL); /*
- * Was there a bug?
- */
-
- offs += sample_ptrs[sample]; /*
- * Begin offsess + offset to DRAM
- */
-
- for (n = 0; n < l; n++)
- rec->data.data8[n] = gus_peek (offs++);
- rec->parm1 = n; /*
- * Nr of bytes copied
- */
- }
- return 0;
- break;
-
- case PM_WRITE_PATCH: /*
- * Writes a block of wave data to the DRAM
- */
- {
- int sample = rec->parm1;
- int n;
- long offs = rec->parm2;
- int l = rec->parm3;
-
- if (sample < 0 || sample >= free_sample)
- return RET_ERROR (EINVAL);
-
- if (offs < 0 || offs >= samples[sample].len)
- return RET_ERROR (EINVAL); /*
- * Invalid offset
- */
-
- n = samples[sample].len - offs; /*
- * Nr of bytes left
- */
-
- if (l > n)
- l = n;
-
- if (l > sizeof (rec->data.data8))
- l = sizeof (rec->data.data8);
-
- if (l <= 0)
- return RET_ERROR (EINVAL); /*
- * Was there a bug?
- */
-
- offs += sample_ptrs[sample]; /*
- * Begin offsess + offset to DRAM
- */
-
- for (n = 0; n < l; n++)
- gus_poke (offs++, rec->data.data8[n]);
- rec->parm1 = n; /*
- * Nr of bytes copied
- */
- }
- return 0;
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
-}
-
-static int
-guswave_alloc (int dev, int chn, int note, struct voice_alloc_info *alloc)
-{
- int i, p, best = -1, best_time = 0x7fffffff;
-
- p = alloc->ptr;
- /*
- * First look for a completely stopped voice
- */
-
- for (i = 0; i < alloc->max_voice; i++)
- {
- if (alloc->map[p] == 0)
- {
- alloc->ptr = p;
- return p;
- }
- if (alloc->alloc_times[p] < best_time)
- {
- best = p;
- best_time = alloc->alloc_times[p];
- }
- p = (p + 1) % alloc->max_voice;
- }
-
- /*
- * Then look for a releasing voice
- */
-
- for (i = 0; i < alloc->max_voice; i++)
- {
- if (alloc->map[p] == 0xffff)
- {
- alloc->ptr = p;
- return p;
- }
- p = (p + 1) % alloc->max_voice;
- }
-
- if (best >= 0)
- p = best;
-
- alloc->ptr = p;
- return p;
-}
-
-static struct synth_operations guswave_operations =
-{
- &gus_info,
- 0,
- SYNTH_TYPE_SAMPLE,
- SAMPLE_TYPE_GUS,
- guswave_open,
- guswave_close,
- guswave_ioctl,
- guswave_kill_note,
- guswave_start_note,
- guswave_set_instr,
- guswave_reset,
- guswave_hw_control,
- guswave_load_patch,
- guswave_aftertouch,
- guswave_controller,
- guswave_panning,
- guswave_volume_method,
- guswave_patchmgr,
- guswave_bender,
- guswave_alloc,
- guswave_setup_voice
-};
-
-static void
-set_input_volumes (void)
-{
- unsigned long flags;
- unsigned char mask = 0xff & ~0x06; /* Just line out enabled */
-
- DISABLE_INTR (flags);
-
- /*
- * Enable channels having vol > 10%
- * Note! bit 0x01 means line in DISABLED while 0x04 means
- * mic in ENABLED.
- */
- if (gus_line_vol > 10)
- mask &= ~0x01;
- if (gus_mic_vol > 10)
- mask |= 0x04;
-
- if (recording_active)
- {
- /*
- * Disable channel, if not selected for recording
- */
- if (!(gus_recmask & SOUND_MASK_LINE))
- mask |= 0x01;
- if (!(gus_recmask & SOUND_MASK_MIC))
- mask &= ~0x04;
- }
-
- mix_image &= ~0x07;
- mix_image |= mask & 0x07;
- OUTB (mix_image, u_Mixer);
-
- RESTORE_INTR (flags);
-}
-
-int
-gus_default_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
-{
-#define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
- SOUND_MASK_SYNTH|SOUND_MASK_PCM)
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (cmd & IOC_IN)
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- gus_recmask = IOCTL_IN (arg) & MIX_DEVS;
- if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
- gus_recmask = SOUND_MASK_MIC;
- /* Note! Input volumes are updated during next open for recording */
- return IOCTL_OUT (arg, gus_recmask);
- break;
-
- case SOUND_MIXER_MIC:
- {
- int vol = IOCTL_IN (arg) & 0xff;
-
- if (vol < 0)
- vol = 0;
- if (vol > 100)
- vol = 100;
- gus_mic_vol = vol;
- set_input_volumes ();
- return IOCTL_OUT (arg, vol | (vol << 8));
- }
- break;
-
- case SOUND_MIXER_LINE:
- {
- int vol = IOCTL_IN (arg) & 0xff;
-
- if (vol < 0)
- vol = 0;
- if (vol > 100)
- vol = 100;
- gus_line_vol = vol;
- set_input_volumes ();
- return IOCTL_OUT (arg, vol | (vol << 8));
- }
- break;
-
- case SOUND_MIXER_PCM:
- gus_pcm_volume = IOCTL_IN (arg) & 0xff;
- if (gus_pcm_volume < 0)
- gus_pcm_volume = 0;
- if (gus_pcm_volume > 100)
- gus_pcm_volume = 100;
- gus_sampling_update_volume ();
- return IOCTL_OUT (arg, gus_pcm_volume | (gus_pcm_volume << 8));
- break;
-
- case SOUND_MIXER_SYNTH:
- {
- int voice;
-
- gus_wave_volume = IOCTL_IN (arg) & 0xff;
-
- if (gus_wave_volume < 0)
- gus_wave_volume = 0;
- if (gus_wave_volume > 100)
- gus_wave_volume = 100;
-
- if (active_device == GUS_DEV_WAVE)
- for (voice = 0; voice < nr_voices; voice++)
- dynamic_volume_change (voice); /* Apply the new vol */
-
- return IOCTL_OUT (arg, gus_wave_volume | (gus_wave_volume << 8));
- }
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
- else
- switch (cmd & 0xff) /*
- * Return parameters
- */
- {
-
- case SOUND_MIXER_RECSRC:
- return IOCTL_OUT (arg, gus_recmask);
- break;
-
- case SOUND_MIXER_DEVMASK:
- return IOCTL_OUT (arg, MIX_DEVS);
- break;
-
- case SOUND_MIXER_STEREODEVS:
- return IOCTL_OUT (arg, 0);
- break;
-
- case SOUND_MIXER_RECMASK:
- return IOCTL_OUT (arg, SOUND_MASK_MIC | SOUND_MASK_LINE);
- break;
-
- case SOUND_MIXER_CAPS:
- return IOCTL_OUT (arg, 0);
- break;
-
- case SOUND_MIXER_MIC:
- return IOCTL_OUT (arg, gus_mic_vol | (gus_mic_vol << 8));
- break;
-
- case SOUND_MIXER_LINE:
- return IOCTL_OUT (arg, gus_line_vol | (gus_line_vol << 8));
- break;
-
- case SOUND_MIXER_PCM:
- return IOCTL_OUT (arg, gus_pcm_volume | (gus_pcm_volume << 8));
- break;
-
- case SOUND_MIXER_SYNTH:
- return IOCTL_OUT (arg, gus_wave_volume | (gus_wave_volume << 8));
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
- }
- else
- return RET_ERROR (EINVAL);
-}
-
-static struct mixer_operations gus_mixer_operations =
-{
- "Gravis Ultrasound",
- gus_default_mixer_ioctl
-};
-
-static long
-gus_default_mixer_init (long mem_start)
-{
- if (num_mixers < MAX_MIXER_DEV) /*
- * Don't install if there is another
- * mixer
- */
- mixer_devs[num_mixers++] = &gus_mixer_operations;
-
- return mem_start;
-}
-
-long
-gus_wave_init (long mem_start, int irq, int dma, int dma_read)
-{
- unsigned long flags;
- unsigned char val;
- char *model_num = "2.4";
- int gus_type = 0x24; /* 2.4 */
- int mixer_type = 0;
-
- if (irq < 0 || irq > 15)
- {
- printk ("ERROR! Invalid IRQ#%d. GUS Disabled", irq);
- return mem_start;
- }
-
- if (dma < 0 || dma > 7)
- {
- printk ("ERROR! Invalid DMA#%d. GUS Disabled", dma);
- return mem_start;
- }
-
- if (dma_read == 0) dma_read = dma;
- if (dma_read < 0 || dma_read > 7)
- {
- printk ("ERROR! Invalid DMA#%d. GUS DMA-read disabled", dma_read);
- dma_read = dma;
- }
- /*
- * Try to identify the GUS model.
- *
- * Versions < 3.6 don't have the digital ASIC. Try to probe it first.
- */
-
- DISABLE_INTR (flags);
- OUTB (0x20, gus_base + 0x0f);
- val = INB (gus_base + 0x0f);
- RESTORE_INTR (flags);
-
- if (val != 0xff && (val & 0x06)) /* Should be 0x02?? */
- {
- /*
- * It has the digital ASIC so the card is at least v3.4.
- * Next try to detect the true model.
- */
-
- val = INB (u_MixSelect);
-
- /*
- * Value 255 means pre-3.7 which don't have mixer.
- * Values 5 thru 9 mean v3.7 which has a ICS2101 mixer.
- * 10 and above is GUS MAX which has the CS4231 codec/mixer.
- *
- * Sorry. No GUS max support yet but it should be available
- * soon after the SDK for GUS MAX is available.
- */
-
- if (val == 255 || val < 5)
- {
- model_num = "3.4";
- gus_type = 0x34;
- }
- else if (val < 10)
- {
- model_num = "3.7";
- gus_type = 0x37;
- mixer_type = ICS2101;
- }
- else
- {
- model_num = "MAX";
- gus_type = 0x40;
- mixer_type = CS4231;
- }
- }
- else
- {
- /*
- * ASIC not detected so the card must be 2.2 or 2.4.
- * There could still be the 16-bit/mixer daughter card.
- * It has the same codec/mixer than MAX.
- * At this time there is no support for it but it will appear soon.
- */
- }
-
-
-#if defined(__FreeBSD__)
- printk ("gus0: <Gravis UltraSound %s (%dk)>", model_num,
- (int) gus_mem_size / 1024);
-#else
- printk (" <Gravis UltraSound %s (%dk)>", model_num, (int) gus_mem_size / 1024);
-#endif
-
- sprintf (gus_info.name, "Gravis UltraSound %s (%dk)", model_num, (int) gus_mem_size / 1024);
-
- gus_irq = irq;
- gus_dma = dma;
- gus_dma_read = dma_read;
-
- if (num_synths >= MAX_SYNTH_DEV)
- printk ("GUS Error: Too many synthesizers\n");
- else
- {
- voice_alloc = &guswave_operations.alloc;
- synth_devs[num_synths++] = &guswave_operations;
- }
-
-#if defined(__FreeBSD__)
- PERMANENT_MALLOC (char *, gus_copy_buf, DSP_BUFFSIZE, mem_start);
-#endif
-
- PERMANENT_MALLOC (struct patch_info *, samples,
- (MAX_SAMPLE + 1) * sizeof (*samples), mem_start);
-
- reset_sample_memory ();
-
- gus_initialize ();
-
- if (num_audiodevs < MAX_AUDIO_DEV)
- {
- audio_devs[gus_devnum = num_audiodevs++] = &gus_sampling_operations;
- audio_devs[gus_devnum]->dmachan = dma;
- audio_devs[gus_devnum]->buffcount = 1;
- audio_devs[gus_devnum]->buffsize = DSP_BUFFSIZE;
- gus_dspnum = gus_devnum;
- gus_busy[gus_devnum] = 0;
- gus_busy[gus_dspnum] = 0;
- }
- else
- printk ("GUS: Too many PCM devices available\n");
-
- if (num_audiodevs < MAX_AUDIO_DEV)
- {
- if(dma_read && dma != dma_read)
- {
- audio_devs[gus_dspnum = num_audiodevs++]= &gus_sampling_operations_read;
- audio_devs[gus_dspnum]->dmachan = gus_dma_read;
- audio_devs[gus_dspnum]->buffcount = 1;
- audio_devs[gus_dspnum]->buffsize = DSP_BUFFSIZE;
- gus_busy[gus_dspnum] = 0;
- }
- else
- {
- gus_dspnum = gus_devnum;
- }
- }
- else
- printk ("GUS READ: Too many PCM devices available\n");
-
- /*
- * Mixer dependent initialization.
- */
- switch (mixer_type)
- {
- case ICS2101:
- gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
- gus_wave_volume = 90;
- return ics2101_mixer_init (mem_start);
-
- case CS4231:
- /* Initialized elsewhere (ad1848.c) */
-#ifndef EXCLUDE_GUSMAX
- {
- unsigned char max_config = 0x40; /* Codec enable */
- long mixer_init_return;
-
- if (dma > 3)
- max_config |= 0x30; /* 16 bit playback and capture DMAs */
-
- max_config |= (gus_base >> 4) & 0x0f; /* Extract the X from 2X0 */
-
- OUTB (max_config, gus_base + 0x106); /* UltraMax control */
- mixer_init_return = gus_default_mixer_init(mem_start);
-
- if (ad1848_detect (gus_base + 0x10c))
- {
- gus_mic_vol = gus_line_vol = gus_pcm_volume = 100;
- gus_wave_volume = 90;
- have_gus_max = 1;
- ad1848_init ("GUS MAX", gus_base + 0x10c,
- -irq,
- dma_read, /* read write reversed */
- dma);
- }
- else
- printk ("[Where's the CS4231?]");
- return mixer_init_return;
- }
-#endif
- default:
- return gus_default_mixer_init (mem_start);
- }
-}
-
-static void
-do_loop_irq (int voice)
-{
- unsigned char tmp;
- int mode, parm;
- unsigned long flags;
-
- DISABLE_INTR (flags);
- gus_select_voice (voice);
-
- tmp = gus_read8 (0x00);
- tmp &= ~0x20; /*
- * Disable wave IRQ for this_one voice
- */
- gus_write8 (0x00, tmp);
-
- if (tmp & 0x03) /* Voice stopped */
- voice_alloc->map[voice] = 0;
-
- mode = voices[voice].loop_irq_mode;
- voices[voice].loop_irq_mode = 0;
- parm = voices[voice].loop_irq_parm;
-
- switch (mode)
- {
-
- case LMODE_FINISH: /*
- * Final loop finished, shoot volume down
- */
-
- if ((int) (gus_read16 (0x09) >> 4) < 100) /*
- * Get current volume
- */
- {
- gus_voice_off ();
- gus_rampoff ();
- gus_voice_init (voice);
- break;
- }
- gus_ramp_range (65, 4065);
- gus_ramp_rate (0, 63); /*
- * Fastest possible rate
- */
- gus_rampon (0x20 | 0x40); /*
- * Ramp down, once, irq
- */
- voices[voice].volume_irq_mode = VMODE_HALT;
- break;
-
- case LMODE_PCM_STOP:
- pcm_active = 0; /* Signal to the play_next_pcm_block routine */
- case LMODE_PCM:
- {
- int flag; /* 0 or 2 */
-
- pcm_qlen--;
- pcm_head = (pcm_head + 1) % pcm_nblk;
- if (pcm_qlen && pcm_active)
- {
- play_next_pcm_block ();
- }
- else
- { /* Underrun. Just stop the voice */
- gus_select_voice (0); /* Left channel */
- gus_voice_off ();
- gus_rampoff ();
- gus_select_voice (1); /* Right channel */
- gus_voice_off ();
- gus_rampoff ();
- pcm_active = 0;
- }
-
- /*
- * If the queue was full before this interrupt, the DMA transfer was
- * suspended. Let it continue now.
- */
- if (dma_active)
- {
- if (pcm_qlen == 0)
- flag = 1; /* Underflow */
- else
- flag = 0;
- dma_active = 0;
- }
- else
- flag = 2; /* Just notify the dmabuf.c */
- DMAbuf_outputintr (gus_devnum, flag);
- }
- break;
-
- default:;
- }
- RESTORE_INTR (flags);
-}
-
-static void
-do_volume_irq (int voice)
-{
- unsigned char tmp;
- int mode, parm;
- unsigned long flags;
-
- DISABLE_INTR (flags);
-
- gus_select_voice (voice);
-
- tmp = gus_read8 (0x0d);
- tmp &= ~0x20; /*
- * Disable volume ramp IRQ
- */
- gus_write8 (0x0d, tmp);
-
- mode = voices[voice].volume_irq_mode;
- voices[voice].volume_irq_mode = 0;
- parm = voices[voice].volume_irq_parm;
-
- switch (mode)
- {
- case VMODE_HALT: /*
- * Decay phase finished
- */
- RESTORE_INTR (flags);
- gus_voice_init (voice);
- break;
-
- case VMODE_ENVELOPE:
- gus_rampoff ();
- RESTORE_INTR (flags);
- step_envelope (voice);
- break;
-
- case VMODE_START_NOTE:
- RESTORE_INTR (flags);
- guswave_start_note2 (voices[voice].dev_pending, voice,
- voices[voice].note_pending, voices[voice].volume_pending);
- if (voices[voice].kill_pending)
- guswave_kill_note (voices[voice].dev_pending, voice,
- voices[voice].note_pending, 0);
-
- if (voices[voice].sample_pending >= 0)
- {
- guswave_set_instr (voices[voice].dev_pending, voice,
- voices[voice].sample_pending);
- voices[voice].sample_pending = -1;
- }
- break;
-
- default:;
- }
-}
-
-void
-gus_voice_irq (void)
-{
- unsigned long wave_ignore = 0, volume_ignore = 0;
- unsigned long voice_bit;
-
- unsigned char src, voice;
-
- while (1)
- {
- src = gus_read8 (0x0f); /*
- * Get source info
- */
- voice = src & 0x1f;
- src &= 0xc0;
-
- if (src == (0x80 | 0x40))
- return; /*
- * No interrupt
- */
-
- voice_bit = 1 << voice;
-
- if (!(src & 0x80)) /*
- * Wave IRQ pending
- */
- if (!(wave_ignore & voice_bit) && (int) voice < nr_voices) /*
- * Not done
- * yet
- */
- {
- wave_ignore |= voice_bit;
- do_loop_irq (voice);
- }
-
- if (!(src & 0x40)) /*
- * Volume IRQ pending
- */
- if (!(volume_ignore & voice_bit) && (int) voice < nr_voices) /*
- * Not done
- * yet
- */
- {
- volume_ignore |= voice_bit;
- do_volume_irq (voice);
- }
- }
-}
-
-void
-guswave_dma_irq (void)
-{
- unsigned char status;
-
- status = gus_look8 (0x41); /* Get DMA IRQ Status */
- if (status & 0x40) /* DMA interrupt pending */
- switch (active_device)
- {
- case GUS_DEV_WAVE:
- if (SOMEONE_WAITING (dram_sleeper, dram_sleep_flag))
- WAKE_UP (dram_sleeper, dram_sleep_flag);
- break;
-
- case GUS_DEV_PCM_CONTINUE: /* Left channel data transferred */
- gus_transfer_output_block (pcm_current_dev, pcm_current_buf,
- pcm_current_count,
- pcm_current_intrflag, 1);
- break;
-
- case GUS_DEV_PCM_DONE: /* Right or mono channel data transferred */
- if (pcm_qlen < pcm_nblk)
- {
- int flag = (1 - dma_active) * 2; /* 0 or 2 */
-
- if (pcm_qlen == 0)
- flag = 1; /* Underrun */
- dma_active = 0;
- DMAbuf_outputintr (gus_devnum, flag);
- }
- break;
-
- default:;
- }
-
- status = gus_look8 (0x49); /*
- * Get Sampling IRQ Status
- */
- if (status & 0x40) /*
- * Sampling Irq pending
- */
- {
- if (gus_dma_read && gus_dma_read != gus_dma)
- DMAbuf_inputintr (gus_dspnum);
- else
- DMAbuf_inputintr (gus_devnum);
- }
-
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/ics2101.c b/sys/pc98/pc98/sound/ics2101.c
deleted file mode 100644
index cec1e51..0000000
--- a/sys/pc98/pc98/sound/ics2101.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * sound/ics2101.c
- *
- * Driver for the ICS2101 mixer of GUS v3.7.
- *
- * Copyright by Hannu Savolainen 1994
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
-
-#include <machine/ultrasound.h>
-#include <i386/isa/sound/gus_hw.h>
-
-#define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
- SOUND_MASK_SYNTH| \
- SOUND_MASK_CD | SOUND_MASK_VOLUME)
-
-extern int gus_base;
-static int volumes[ICS_MIXDEVS];
-static int left_fix[ICS_MIXDEVS] =
-{1, 1, 1, 2, 1, 2};
-static int right_fix[ICS_MIXDEVS] =
-{2, 2, 2, 1, 2, 1};
-
-static int
-scale_vol (int vol)
-{
-#if 1
- /*
- * Experimental volume scaling by Risto Kankkunen.
- * This should give smoother volume response than just
- * a plain multiplication.
- */
- int e;
-
- if (vol < 0)
- vol = 0;
- if (vol > 100)
- vol = 100;
- vol = (31 * vol + 50) / 100;
- e = 0;
- if (vol)
- {
- while (vol < 16)
- {
- vol <<= 1;
- e--;
- }
- vol -= 16;
- e += 7;
- }
- return ((e << 4) + vol);
-#else
- return ((vol * 127) + 50) / 100;
-#endif
-}
-
-static void
-write_mix (int dev, int chn, int vol)
-{
- int *selector;
- unsigned long flags;
- int ctrl_addr = dev << 3;
- int attn_addr = dev << 3;
-
- vol = scale_vol (vol);
-
- if (chn == CHN_LEFT)
- {
- selector = left_fix;
- ctrl_addr |= 0x00;
- attn_addr |= 0x02;
- }
- else
- {
- selector = right_fix;
- ctrl_addr |= 0x01;
- attn_addr |= 0x03;
- }
-
- DISABLE_INTR (flags);
- OUTB (ctrl_addr, u_MixSelect);
- OUTB (selector[dev], u_MixData);
- OUTB (attn_addr, u_MixSelect);
- OUTB ((unsigned char) vol, u_MixData);
- RESTORE_INTR (flags);
-}
-
-static int
-set_volumes (int dev, int vol)
-{
- int left = vol & 0x00ff;
- int right = (vol >> 8) & 0x00ff;
-
- if (left < 0)
- left = 0;
- if (left > 100)
- left = 100;
- if (right < 0)
- right = 0;
- if (right > 100)
- right = 100;
-
- write_mix (dev, CHN_LEFT, left);
- write_mix (dev, CHN_RIGHT, right);
-
- vol = left + (right << 8);
- volumes[dev] = vol;
- return vol;
-}
-
-static int
-ics2101_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
-{
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (cmd & IOC_IN)
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- return gus_default_mixer_ioctl (dev, cmd, arg);
- break;
-
- case SOUND_MIXER_MIC:
- return IOCTL_OUT (arg, set_volumes (DEV_MIC, IOCTL_IN (arg)));
- break;
-
- case SOUND_MIXER_CD:
- return IOCTL_OUT (arg, set_volumes (DEV_CD, IOCTL_IN (arg)));
- break;
-
- case SOUND_MIXER_LINE:
- return IOCTL_OUT (arg, set_volumes (DEV_LINE, IOCTL_IN (arg)));
- break;
-
- case SOUND_MIXER_SYNTH:
- return IOCTL_OUT (arg, set_volumes (DEV_GF1, IOCTL_IN (arg)));
- break;
-
- case SOUND_MIXER_VOLUME:
- return IOCTL_OUT (arg, set_volumes (DEV_VOL, IOCTL_IN (arg)));
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
- else
- switch (cmd & 0xff) /*
- * Return parameters
- */
- {
-
- case SOUND_MIXER_RECSRC:
- return gus_default_mixer_ioctl (dev, cmd, arg);
- break;
-
- case SOUND_MIXER_DEVMASK:
- return IOCTL_OUT (arg, MIX_DEVS);
- break;
-
- case SOUND_MIXER_STEREODEVS:
- return IOCTL_OUT (arg, SOUND_MASK_LINE | SOUND_MASK_CD |
- SOUND_MASK_SYNTH | SOUND_MASK_VOLUME |
- SOUND_MASK_MIC);
- break;
-
- case SOUND_MIXER_RECMASK:
- return IOCTL_OUT (arg, SOUND_MASK_MIC | SOUND_MASK_LINE);
- break;
-
- case SOUND_MIXER_CAPS:
- return IOCTL_OUT (arg, 0);
- break;
-
- case SOUND_MIXER_MIC:
- return IOCTL_OUT (arg, volumes[DEV_MIC]);
- break;
-
- case SOUND_MIXER_LINE:
- return IOCTL_OUT (arg, volumes[DEV_LINE]);
- break;
-
- case SOUND_MIXER_CD:
- return IOCTL_OUT (arg, volumes[DEV_CD]);
- break;
-
- case SOUND_MIXER_VOLUME:
- return IOCTL_OUT (arg, volumes[DEV_VOL]);
- break;
-
- case SOUND_MIXER_SYNTH:
- return IOCTL_OUT (arg, volumes[DEV_GF1]);
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
- }
-
- return RET_ERROR (EINVAL);
-}
-
-static struct mixer_operations ics2101_mixer_operations =
-{
- "ICS2101 Multimedia Mixer",
- ics2101_mixer_ioctl
-};
-
-long
-ics2101_mixer_init (long mem_start)
-{
- int i;
-
- if (num_mixers < MAX_MIXER_DEV)
- {
- mixer_devs[num_mixers++] = &ics2101_mixer_operations;
-
- /*
- * Some GUS v3.7 cards had some channels flipped. Disable
- * the flipping feature if the model id is other than 5.
- */
-
- if (INB (u_MixSelect) != 5)
- {
- for (i = 0; i < ICS_MIXDEVS; i++)
- left_fix[i] = 1;
- for (i = 0; i < ICS_MIXDEVS; i++)
- right_fix[i] = 2;
- }
-
- set_volumes (DEV_GF1, 0x5a5a);
- set_volumes (DEV_CD, 0x5a5a);
- set_volumes (DEV_MIC, 0x0000);
- set_volumes (DEV_LINE, 0x5a5a);
- set_volumes (DEV_VOL, 0x5a5a);
- set_volumes (DEV_UNUSED, 0x0000);
- }
-
- return mem_start;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/local.h b/sys/pc98/pc98/sound/local.h
deleted file mode 100644
index c243e4b..0000000
--- a/sys/pc98/pc98/sound/local.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* for FreeBSD */
-/*
- * $Id: local.h,v 1.11 1994/11/01 17:26:50 ache Exp
- */
-
-#define DSP_BUFFSIZE 65536
-#define SELECTED_SOUND_OPTIONS 0xffffffff
-#define SOUND_CONFIG_DATE "Sun Feb 5 14:38:12 EST 1995"
-#define SOUND_CONFIG_BY "freebsd-hackers"
-#define SOUND_CONFIG_HOST "freefall"
-#define SOUND_CONFIG_DOMAIN "cdrom.com"
-
-/* determine if sound code should be compiled */
-#include "snd.h"
-#if NSND > 0
-#define KERNEL_SOUNDCARD
-#endif
-
-#define ALLOW_SELECT
-
-/* PSS code does not work */
-#ifndef EXCLUDE_PSS
-#define EXCLUDE_PSS
-#endif
-
-#include "gus.h"
-#if NGUS == 0 && !defined(EXCLUDE_GUS)
-#define EXCLUDE_GUS
-#endif
-
-#include "gusxvi.h"
-#if NGUSXVI == 0 && !defined(EXCLUDE_GUS16)
-#define EXCLUDE_GUS16
-#endif
-
-#include "mss.h"
-#if NMSS == 0 && !defined(EXCLUDE_MSS)
-#define EXCLUDE_MSS
-#endif
-
-#include "trix.h"
-#if NTRIX == 0 && !defined(EXCLUDE_TRIX)
-#define EXCLUDE_TRIX
-#endif
-
-#include "sscape.h"
-#if NSSCAPE == 0 && !defined(EXCLUDE_SSCAPE)
-#define EXCLUDE_SSCAPE
-#endif
-
-#if NGUS == 0 && !defined(EXCLUDE_GUSMAX)
-# define EXCLUDE_GUSMAX
-# if defined(EXCLUDE_GUS16) && defined(EXCLUDE_MSS) && !defined(EXCLUDE_AD1848)
-# define EXCLUDE_AD1848
-# endif
-#else
-# define GUSMAX_MIXER
-#endif
-
-#include "sb.h"
-#if NSB == 0 && !defined(EXCLUDE_SB)
-#define EXCLUDE_SB
-#endif
-
-#include "sbxvi.h"
-#if NSBXVI == 0 && !defined(EXCLUDE_SB16)
-#define EXCLUDE_SB16
-#endif
-
-#include "sbmidi.h"
-#if NSBMIDI == 0 && !defined(EXCLUDE_SB16MIDI)
-#define EXCLUDE_SB16MIDI
-#endif
-
-#include "pas.h"
-#if NPAS == 0 && !defined(EXCLUDE_PAS)
-#define EXCLUDE_PAS
-#endif
-
-#include "mpu.h"
-#if NMPU == 0 && !defined(EXCLUDE_MPU401)
-#define EXCLUDE_MPU401
-#endif
-
-#include "opl.h"
-#if NOPL == 0 && !defined(EXCLUDE_YM3812)
-#define EXCLUDE_YM3812
-#endif
-
-#include "uart.h"
-#if NUART == 0 && !defined(EXCLUDE_UART6850)
-#define EXCLUDE_UART6850
-#endif
-
-#ifdef PC98
-#include "pcm.h"
-#if NPCM == 0 && !defined(EXCLUDE_PCM86)
-#define EXCLUDE_PCM86
-#endif
-#endif
-
-
-/* nothing but a sequencer (Adlib/OPL) ? */
-#if NGUS == 0 && NSB == 0 && NSBMIDI == 0 && NPAS == 0 && NMPU == 0 && \
- NUART == 0 && NMSS == 0
-#ifndef EXCLUDE_MIDI
-#define EXCLUDE_MIDI
-#endif
-#ifndef EXCLUDE_AUDIO
-#if !defined(PC98) || defined(EXCLUDE_PCM86) && defined(EXCLUDE_MSS)
-#define EXCLUDE_AUDIO
-#endif
-#endif
-#endif
-
-/* nothing but a Midi (MPU/UART) ? */
-#if NGUS == 0 && NSB == 0 && NSBMIDI == 0 && NPAS == 0 && NOPL == 0 && \
- NMSS == 0
-/* MPU depends on sequencer timer */
-#if NMPU == 0 && !defined(EXCLUDE_SEQUENCER)
-#define EXCLUDE_SEQUENCER
-#endif
-#ifndef EXCLUDE_AUDIO
-#if !defined(PC98) || defined(EXCLUDE_PCM86) && defined(EXCLUDE_MSS)
-#define EXCLUDE_AUDIO
-#endif
-#endif
-#endif
diff --git a/sys/pc98/pc98/sound/midi_synth.c b/sys/pc98/pc98/sound/midi_synth.c
deleted file mode 100644
index 7e4ecb0..0000000
--- a/sys/pc98/pc98/sound/midi_synth.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * sound/midi_synth.c
- *
- * High level midi sequencer manager for dumb MIDI interfaces.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#define USE_SEQ_MACROS
-#define USE_SIMPLE_MACROS
-
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MIDI)
-
-#define _MIDI_SYNTH_C_
-
-DEFINE_WAIT_QUEUE (sysex_sleeper, sysex_sleep_flag);
-
-#include <i386/isa/sound/midi_synth.h>
-
-static int midi2synth[MAX_MIDI_DEV];
-static unsigned char prev_out_status[MAX_MIDI_DEV];
-
-#define STORE(cmd) \
-{ \
- int len; \
- unsigned char obuf[8]; \
- cmd; \
- seq_input_event(obuf, len); \
-}
-#define _seqbuf obuf
-#define _seqbufptr 0
-#define _SEQ_ADVBUF(x) len=x
-
-void
-do_midi_msg (int synthno, unsigned char *msg, int mlen)
-{
- switch (msg[0] & 0xf0)
- {
- case 0x90:
- if (msg[2] != 0)
- {
- STORE (SEQ_START_NOTE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
- break;
- }
- msg[2] = 64;
-
- case 0x80:
- STORE (SEQ_STOP_NOTE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
- break;
-
- case 0xA0:
- STORE (SEQ_KEY_PRESSURE (synthno, msg[0] & 0x0f, msg[1], msg[2]));
- break;
-
- case 0xB0:
- STORE (SEQ_CONTROL (synthno, msg[0] & 0x0f,
- msg[1], msg[2]));
- break;
-
- case 0xC0:
- STORE (SEQ_SET_PATCH (synthno, msg[0] & 0x0f, msg[1]));
- break;
-
- case 0xD0:
- STORE (SEQ_CHN_PRESSURE (synthno, msg[0] & 0x0f, msg[1]));
- break;
-
- case 0xE0:
- STORE (SEQ_BENDER (synthno, msg[0] & 0x0f,
- (msg[1] % 0x7f) | ((msg[2] & 0x7f) << 7)));
- break;
-
- default:
- printk ("MPU: Unknown midi channel message %02x\n", msg[0]);
- }
-}
-
-static void
-midi_outc (int midi_dev, int data)
-{
- int timeout;
-
- for (timeout = 0; timeout < 32000; timeout++)
- if (midi_devs[midi_dev]->putc (midi_dev, (unsigned char) (data & 0xff)))
- {
- if (data & 0x80) /*
- * Status byte
- */
- prev_out_status[midi_dev] =
- (unsigned char) (data & 0xff); /*
- * Store for running status
- */
- return; /*
- * Mission complete
- */
- }
-
- /*
- * Sorry! No space on buffers.
- */
- printk ("Midi send timed out\n");
-}
-
-static int
-prefix_cmd (int midi_dev, unsigned char status)
-{
- if ((char *) midi_devs[midi_dev]->prefix_cmd == NULL)
- return 1;
-
- return midi_devs[midi_dev]->prefix_cmd (midi_dev, status);
-}
-
-static void
-midi_synth_input (int dev, unsigned char data)
-{
- int orig_dev;
- struct midi_input_info *inc;
-
- static unsigned char len_tab[] = /* # of data bytes following a status
- */
- {
- 2, /* 8x */
- 2, /* 9x */
- 2, /* Ax */
- 2, /* Bx */
- 1, /* Cx */
- 1, /* Dx */
- 2, /* Ex */
- 0 /* Fx */
- };
-
- if (dev < 0 || dev > num_synths)
- return;
-
- if (data == 0xfe) /* Ignore active sensing */
- return;
-
- orig_dev = midi2synth[dev];
- inc = &midi_devs[orig_dev]->in_info;
-
- switch (inc->m_state)
- {
- case MST_INIT:
- if (data & 0x80) /* MIDI status byte */
- {
- if ((data & 0xf0) == 0xf0) /* Common message */
- {
- switch (data)
- {
- case 0xf0: /* Sysex */
- inc->m_state = MST_SYSEX;
- break; /* Sysex */
-
- case 0xf1: /* MTC quarter frame */
- case 0xf3: /* Song select */
- inc->m_state = MST_DATA;
- inc->m_ptr = 1;
- inc->m_left = 1;
- inc->m_buf[0] = data;
- break;
-
- case 0xf2: /* Song position pointer */
- inc->m_state = MST_DATA;
- inc->m_ptr = 1;
- inc->m_left = 2;
- inc->m_buf[0] = data;
- break;
-
- default:
- inc->m_buf[0] = data;
- inc->m_ptr = 1;
- do_midi_msg (dev, inc->m_buf, inc->m_ptr);
- inc->m_ptr = 0;
- inc->m_left = 0;
- }
- }
- else
- {
- inc->m_state = MST_DATA;
- inc->m_ptr = 1;
- inc->m_left = len_tab[(data >> 4) - 8];
- inc->m_buf[0] = inc->m_prev_status = data;
- }
- }
- else if (inc->m_prev_status & 0x80) /* Ignore if no previous status (yet) */
- { /* Data byte (use running status) */
- inc->m_state = MST_DATA;
- inc->m_ptr = 2;
- inc->m_left = len_tab[(data >> 4) - 8] - 1;
- inc->m_buf[0] = inc->m_prev_status;
- inc->m_buf[1] = data;
- }
- break; /* MST_INIT */
-
- case MST_DATA:
- inc->m_buf[inc->m_ptr++] = data;
- if (--inc->m_left <= 0)
- {
- inc->m_state = MST_INIT;
- do_midi_msg (dev, inc->m_buf, inc->m_ptr);
- inc->m_ptr = 0;
- }
- break; /* MST_DATA */
-
- case MST_SYSEX:
- if (data == 0xf7) /* Sysex end */
- {
- inc->m_state = MST_INIT;
- inc->m_left = 0;
- inc->m_ptr = 0;
- }
- break; /* MST_SYSEX */
-
- default:
- printk ("MIDI%d: Unexpected state %d (%02x)\n", orig_dev, inc->m_state,
- (int) data);
- inc->m_state = MST_INIT;
- }
-}
-
-static void
-midi_synth_output (int dev)
-{
- /*
- * Currently NOP
- */
-}
-
-int
-midi_synth_ioctl (int dev,
- unsigned int cmd, unsigned int arg)
-{
- /*
- * int orig_dev = synth_devs[dev]->midi_dev;
- */
-
- switch (cmd)
- {
-
- case SNDCTL_SYNTH_INFO:
- IOCTL_TO_USER ((char *) arg, 0, synth_devs[dev]->info,
- sizeof (struct synth_info));
-
- return 0;
- break;
-
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
-}
-
-int
-midi_synth_kill_note (int dev, int channel, int note, int velocity)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int msg, chn;
-
- if (note < 0 || note > 127)
- return 0;
- if (channel < 0 || channel > 15)
- return 0;
- if (velocity < 0)
- velocity = 0;
- if (velocity > 127)
- velocity = 127;
-
- msg = prev_out_status[orig_dev] & 0xf0;
- chn = prev_out_status[orig_dev] & 0x0f;
-
- if (chn == channel && ((msg == 0x90 && velocity == 64) || msg == 0x80))
- { /*
- * Use running status
- */
- if (!prefix_cmd (orig_dev, note))
- return 0;
-
- midi_outc (orig_dev, note);
-
- if (msg == 0x90) /*
- * Running status = Note on
- */
- midi_outc (orig_dev, 0); /*
- * Note on with velocity 0 == note
- * off
- */
- else
- midi_outc (orig_dev, velocity);
- }
- else
- {
- if (velocity == 64)
- {
- if (!prefix_cmd (orig_dev, 0x90 | (channel & 0x0f)))
- return 0;
- midi_outc (orig_dev, 0x90 | (channel & 0x0f)); /*
- * Note on
- */
- midi_outc (orig_dev, note);
- midi_outc (orig_dev, 0); /*
- * Zero G
- */
- }
- else
- {
- if (!prefix_cmd (orig_dev, 0x80 | (channel & 0x0f)))
- return 0;
- midi_outc (orig_dev, 0x80 | (channel & 0x0f)); /*
- * Note off
- */
- midi_outc (orig_dev, note);
- midi_outc (orig_dev, velocity);
- }
- }
-
- return 0;
-}
-
-int
-midi_synth_set_instr (int dev, int channel, int instr_no)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
-
- if (instr_no < 0 || instr_no > 127)
- return 0;
- if (channel < 0 || channel > 15)
- return 0;
-
- if (!prefix_cmd (orig_dev, 0xc0 | (channel & 0x0f)))
- return 0;
- midi_outc (orig_dev, 0xc0 | (channel & 0x0f)); /*
- * Program change
- */
- midi_outc (orig_dev, instr_no);
-
- return 0;
-}
-
-int
-midi_synth_start_note (int dev, int channel, int note, int velocity)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int msg, chn;
-
- if (note < 0 || note > 127)
- return 0;
- if (channel < 0 || channel > 15)
- return 0;
- if (velocity < 0)
- velocity = 0;
- if (velocity > 127)
- velocity = 127;
-
- msg = prev_out_status[orig_dev] & 0xf0;
- chn = prev_out_status[orig_dev] & 0x0f;
-
- if (chn == channel && msg == 0x90)
- { /*
- * Use running status
- */
- if (!prefix_cmd (orig_dev, note))
- return 0;
- midi_outc (orig_dev, note);
- midi_outc (orig_dev, velocity);
- }
- else
- {
- if (!prefix_cmd (orig_dev, 0x90 | (channel & 0x0f)))
- return 0;
- midi_outc (orig_dev, 0x90 | (channel & 0x0f)); /*
- * Note on
- */
- midi_outc (orig_dev, note);
- midi_outc (orig_dev, velocity);
- }
- return 0;
-}
-
-void
-midi_synth_reset (int dev)
-{
-}
-
-int
-midi_synth_open (int dev, int mode)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int err;
- unsigned long flags;
- struct midi_input_info *inc;
-
- if (orig_dev < 0 || orig_dev > num_midis)
- return RET_ERROR (ENXIO);
-
- midi2synth[orig_dev] = dev;
- prev_out_status[orig_dev] = 0;
-
- if ((err = midi_devs[orig_dev]->open (orig_dev, mode,
- midi_synth_input, midi_synth_output)) < 0)
- return err;
-
- inc = &midi_devs[orig_dev]->in_info;
-
- DISABLE_INTR (flags);
- inc->m_busy = 0;
- inc->m_state = MST_INIT;
- inc->m_ptr = 0;
- inc->m_left = 0;
- inc->m_prev_status = 0x00;
- RESTORE_INTR (flags);
-
- return 1;
-}
-
-void
-midi_synth_close (int dev)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
-
- /*
- * Shut up the synths by sending just single active sensing message.
- */
- midi_devs[orig_dev]->putc (orig_dev, 0xfe);
-
- midi_devs[orig_dev]->close (orig_dev);
-}
-
-void
-midi_synth_hw_control (int dev, unsigned char *event)
-{
-}
-
-int
-midi_synth_load_patch (int dev, int format, snd_rw_buf * addr,
- int offs, int count, int pmgr_flag)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
-
- struct sysex_info sysex;
- int i;
- unsigned long left, src_offs, eox_seen = 0;
- int first_byte = 1;
- int hdr_size = (unsigned long) &sysex.data[0] - (unsigned long) &sysex;
-
- if (!prefix_cmd (orig_dev, 0xf0))
- return 0;
-
- if (format != SYSEX_PATCH)
- {
- printk ("MIDI Error: Invalid patch format (key) 0x%x\n", format);
- return RET_ERROR (EINVAL);
- }
-
- if (count < hdr_size)
- {
- printk ("MIDI Error: Patch header too short\n");
- return RET_ERROR (EINVAL);
- }
-
- count -= hdr_size;
-
- /*
- * Copy the header from user space but ignore the first bytes which have
- * been transferred already.
- */
-
- COPY_FROM_USER (&((char *) &sysex)[offs], addr, offs, hdr_size - offs);
-
- if (count < sysex.len)
- {
- printk ("MIDI Warning: Sysex record too short (%d<%d)\n",
- count, (int) sysex.len);
- sysex.len = count;
- }
-
- left = sysex.len;
- src_offs = 0;
-
- RESET_WAIT_QUEUE (sysex_sleeper, sysex_sleep_flag);
-
- for (i = 0; i < left && !PROCESS_ABORTING (sysex_sleeper, sysex_sleep_flag); i++)
- {
- unsigned char data;
-
- GET_BYTE_FROM_USER (data, addr, hdr_size + i);
-
- eox_seen = (i > 0 && data & 0x80); /* End of sysex */
-
- if (eox_seen && data != 0xf7)
- data = 0xf7;
-
- if (i == 0)
- {
- if (data != 0xf0)
- {
- printk ("Error: Sysex start missing\n");
- return RET_ERROR (EINVAL);
- }
- }
-
- while (!midi_devs[orig_dev]->putc (orig_dev, (unsigned char) (data & 0xff)) &&
- !PROCESS_ABORTING (sysex_sleeper, sysex_sleep_flag))
- DO_SLEEP (sysex_sleeper, sysex_sleep_flag, 1); /* Wait for timeout */
-
- if (!first_byte && data & 0x80)
- return 0;
- first_byte = 0;
- }
-
- if (!eox_seen)
- midi_outc (orig_dev, 0xf7);
- return 0;
-}
-
-void
-midi_synth_panning (int dev, int channel, int pressure)
-{
-}
-
-void
-midi_synth_aftertouch (int dev, int channel, int pressure)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int msg, chn;
-
- if (pressure < 0 || pressure > 127)
- return;
- if (channel < 0 || channel > 15)
- return;
-
- msg = prev_out_status[orig_dev] & 0xf0;
- chn = prev_out_status[orig_dev] & 0x0f;
-
- if (msg != 0xd0 || chn != channel) /*
- * Test for running status
- */
- {
- if (!prefix_cmd (orig_dev, 0xd0 | (channel & 0x0f)))
- return;
- midi_outc (orig_dev, 0xd0 | (channel & 0x0f)); /*
- * Channel pressure
- */
- }
- else if (!prefix_cmd (orig_dev, pressure))
- return;
-
- midi_outc (orig_dev, pressure);
-}
-
-void
-midi_synth_controller (int dev, int channel, int ctrl_num, int value)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int chn, msg;
-
- if (ctrl_num < 1 || ctrl_num > 127)
- return; /* NOTE! Controller # 0 ignored */
- if (channel < 0 || channel > 15)
- return;
-
- msg = prev_out_status[orig_dev] & 0xf0;
- chn = prev_out_status[orig_dev] & 0x0f;
-
- if (msg != 0xb0 || chn != channel)
- {
- if (!prefix_cmd (orig_dev, 0xb0 | (channel & 0x0f)))
- return;
- midi_outc (orig_dev, 0xb0 | (channel & 0x0f));
- }
- else if (!prefix_cmd (orig_dev, ctrl_num))
- return;
-
- midi_outc (orig_dev, ctrl_num);
- midi_outc (orig_dev, value & 0x7f);
-}
-
-int
-midi_synth_patchmgr (int dev, struct patmgr_info *rec)
-{
- return RET_ERROR (EINVAL);
-}
-
-void
-midi_synth_bender (int dev, int channel, int value)
-{
- int orig_dev = synth_devs[dev]->midi_dev;
- int msg, prev_chn;
-
- if (channel < 0 || channel > 15)
- return;
-
- if (value < 0 || value > 16383)
- return;
-
- msg = prev_out_status[orig_dev] & 0xf0;
- prev_chn = prev_out_status[orig_dev] & 0x0f;
-
- if (msg != 0xd0 || prev_chn != channel) /*
- * Test for running status
- */
- {
- if (!prefix_cmd (orig_dev, 0xe0 | (channel & 0x0f)))
- return;
- midi_outc (orig_dev, 0xe0 | (channel & 0x0f));
- }
- else if (!prefix_cmd (orig_dev, value & 0x7f))
- return;
-
- midi_outc (orig_dev, value & 0x7f);
- midi_outc (orig_dev, (value >> 7) & 0x7f);
-}
-
-void
-midi_synth_setup_voice (int dev, int voice, int channel)
-{
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/midibuf.c b/sys/pc98/pc98/sound/midibuf.c
deleted file mode 100644
index bb4add6..0000000
--- a/sys/pc98/pc98/sound/midibuf.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * sound/midibuf.c
- *
- * Device file manager for /dev/midi#
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-static void drain_midi_queue __P((int dev));
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MIDI)
-
-/*
- * Don't make MAX_QUEUE_SIZE larger than 4000
- */
-
-#define MAX_QUEUE_SIZE 4000
-
-DEFINE_WAIT_QUEUES (midi_sleeper[MAX_MIDI_DEV], midi_sleep_flag[MAX_MIDI_DEV]);
-DEFINE_WAIT_QUEUES (input_sleeper[MAX_MIDI_DEV], input_sleep_flag[MAX_MIDI_DEV]);
-
-struct midi_buf
- {
- int len, head, tail;
- unsigned char queue[MAX_QUEUE_SIZE];
- };
-
-struct midi_parms
- {
- int prech_timeout; /*
- * Timeout before the first ch
- */
- };
-
-static struct midi_buf *midi_out_buf[MAX_MIDI_DEV] =
-{NULL};
-static struct midi_buf *midi_in_buf[MAX_MIDI_DEV] =
-{NULL};
-static struct midi_parms parms[MAX_MIDI_DEV];
-
-static void midi_poll (unsigned long dummy);
-
-DEFINE_TIMER (poll_timer, midi_poll);
-static volatile int open_devs = 0;
-
-#define DATA_AVAIL(q) (q->len)
-#define SPACE_AVAIL(q) (MAX_QUEUE_SIZE - q->len)
-
-#define QUEUE_BYTE(q, data) \
- if (SPACE_AVAIL(q)) \
- { \
- unsigned long flags; \
- DISABLE_INTR(flags); \
- q->queue[q->tail] = (data); \
- q->len++; q->tail = (q->tail+1) % MAX_QUEUE_SIZE; \
- RESTORE_INTR(flags); \
- }
-
-#define REMOVE_BYTE(q, data) \
- if (DATA_AVAIL(q)) \
- { \
- unsigned long flags; \
- DISABLE_INTR(flags); \
- data = q->queue[q->head]; \
- q->len--; q->head = (q->head+1) % MAX_QUEUE_SIZE; \
- RESTORE_INTR(flags); \
- }
-
-static void
-drain_midi_queue (int dev)
-{
-
- /*
- * Give the Midi driver time to drain its output queues
- */
-
- if (midi_devs[dev]->buffer_status != NULL)
- while (!PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]) &&
- midi_devs[dev]->buffer_status (dev))
- DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], HZ / 10);
-}
-
-static void
-midi_input_intr (int dev, unsigned char data)
-{
- if (midi_in_buf[dev] == NULL)
- return;
-
- if (data == 0xfe) /*
- * Active sensing
- */
- return; /*
- * Ignore
- */
-
- if (SPACE_AVAIL (midi_in_buf[dev]))
- {
- QUEUE_BYTE (midi_in_buf[dev], data);
- if (SOMEONE_WAITING (input_sleeper[dev], input_sleep_flag[dev]))
- WAKE_UP (input_sleeper[dev], input_sleep_flag[dev]);
- }
-#if defined(__FreeBSD__)
- if (selinfo[dev].si_pid)
- selwakeup(&selinfo[dev]);
-#endif
-}
-
-static void
-midi_output_intr (int dev)
-{
- /*
- * Currently NOP
- */
-#if defined(__FreeBSD__)
- if (selinfo[dev].si_pid)
- selwakeup(&selinfo[dev]);
-#endif
-}
-
-static void
-midi_poll (unsigned long dummy)
-{
- unsigned long flags;
- int dev;
-
- DISABLE_INTR (flags);
- if (open_devs)
- {
- for (dev = 0; dev < num_midis; dev++)
- if (midi_out_buf[dev] != NULL)
- {
- while (DATA_AVAIL (midi_out_buf[dev]) &&
- midi_devs[dev]->putc (dev,
- midi_out_buf[dev]->queue[midi_out_buf[dev]->head]))
- {
- midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
- midi_out_buf[dev]->len--;
- }
-
- if (DATA_AVAIL (midi_out_buf[dev]) < 100 &&
- SOMEONE_WAITING (midi_sleeper[dev], midi_sleep_flag[dev]))
- WAKE_UP (midi_sleeper[dev], midi_sleep_flag[dev]);
- }
- ACTIVATE_TIMER (poll_timer, midi_poll, 1); /*
- * Come back later
- */
- }
- RESTORE_INTR (flags);
-}
-
-int
-MIDIbuf_open (int dev, struct fileinfo *file)
-{
- int mode, err;
- unsigned long flags;
-
- dev = dev >> 4;
- mode = file->mode & O_ACCMODE;
-
- if (num_midis > MAX_MIDI_DEV)
- {
- printk ("Sound: FATAL ERROR: Too many midi interfaces\n");
- num_midis = MAX_MIDI_DEV;
- }
-
- if (dev < 0 || dev >= num_midis)
- {
- printk ("Sound: Nonexistent MIDI interface %d\n", dev);
- return RET_ERROR (ENXIO);
- }
-
- /*
- * Interrupts disabled. Be careful
- */
-
- DISABLE_INTR (flags);
- if ((err = midi_devs[dev]->open (dev, mode,
- midi_input_intr, midi_output_intr)) < 0)
- {
- RESTORE_INTR (flags);
- return err;
- }
-
- parms[dev].prech_timeout = 0;
-
- RESET_WAIT_QUEUE (midi_sleeper[dev], midi_sleep_flag[dev]);
- RESET_WAIT_QUEUE (input_sleeper[dev], input_sleep_flag[dev]);
-
- midi_in_buf[dev] = (struct midi_buf *) KERNEL_MALLOC (sizeof (struct midi_buf));
-
- if (midi_in_buf[dev] == NULL)
- {
- printk ("midi: Can't allocate buffer\n");
- midi_devs[dev]->close (dev);
- RESTORE_INTR (flags);
- return RET_ERROR (EIO);
- }
- midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
-
- midi_out_buf[dev] = (struct midi_buf *) KERNEL_MALLOC (sizeof (struct midi_buf));
-
- if (midi_out_buf[dev] == NULL)
- {
- printk ("midi: Can't allocate buffer\n");
- midi_devs[dev]->close (dev);
- KERNEL_FREE (midi_in_buf[dev]);
- midi_in_buf[dev] = NULL;
- RESTORE_INTR (flags);
- return RET_ERROR (EIO);
- }
- midi_out_buf[dev]->len = midi_out_buf[dev]->head = midi_out_buf[dev]->tail = 0;
- if (!open_devs)
- ACTIVATE_TIMER (poll_timer, midi_poll, 1); /*
- * Come back later
- */
- open_devs++;
- RESTORE_INTR (flags);
-
- return err;
-}
-
-void
-MIDIbuf_release (int dev, struct fileinfo *file)
-{
- int mode;
- unsigned long flags;
-
- dev = dev >> 4;
- mode = file->mode & O_ACCMODE;
-
- DISABLE_INTR (flags);
-
- /*
- * Wait until the queue is empty
- */
-
- if (mode != OPEN_READ)
- {
- midi_devs[dev]->putc (dev, 0xfe); /*
- * Active sensing to shut the
- * devices
- */
-
- while (!PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]) &&
- DATA_AVAIL (midi_out_buf[dev]))
- DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], 0); /*
- * Sync
- */
-
- drain_midi_queue (dev); /*
- * Ensure the output queues are empty
- */
- }
-
- midi_devs[dev]->close (dev);
- KERNEL_FREE (midi_in_buf[dev]);
- KERNEL_FREE (midi_out_buf[dev]);
- midi_in_buf[dev] = NULL;
- midi_out_buf[dev] = NULL;
- open_devs--;
- RESTORE_INTR (flags);
-}
-
-int
-MIDIbuf_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- unsigned long flags;
- int c, n, i;
- unsigned char tmp_data;
-
- dev = dev >> 4;
-
- if (!count)
- return 0;
-
- DISABLE_INTR (flags);
-
- c = 0;
-
- while (c < count)
- {
- n = SPACE_AVAIL (midi_out_buf[dev]);
-
- if (n == 0) /*
- * No space just now. We have to sleep
- */
- {
- DO_SLEEP (midi_sleeper[dev], midi_sleep_flag[dev], 0);
- if (PROCESS_ABORTING (midi_sleeper[dev], midi_sleep_flag[dev]))
- {
- RESTORE_INTR (flags);
- return RET_ERROR (EINTR);
- }
-
- n = SPACE_AVAIL (midi_out_buf[dev]);
- }
-
- if (n > (count - c))
- n = count - c;
-
- for (i = 0; i < n; i++)
- {
- COPY_FROM_USER (&tmp_data, buf, c, 1);
- QUEUE_BYTE (midi_out_buf[dev], tmp_data);
- c++;
- }
- }
-
- RESTORE_INTR (flags);
-
- return c;
-}
-
-
-int
-MIDIbuf_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- int n, c = 0;
- unsigned long flags;
- unsigned char tmp_data;
-
- dev = dev >> 4;
-
- DISABLE_INTR (flags);
-
- if (!DATA_AVAIL (midi_in_buf[dev])) /*
- * No data yet, wait
- */
- {
- DO_SLEEP (input_sleeper[dev], input_sleep_flag[dev],
- parms[dev].prech_timeout);
- if (PROCESS_ABORTING (input_sleeper[dev], input_sleep_flag[dev]))
- c = RET_ERROR (EINTR); /*
- * The user is getting restless
- */
- }
-
- if (c == 0 && DATA_AVAIL (midi_in_buf[dev])) /*
- * Got some bytes
- */
- {
- n = DATA_AVAIL (midi_in_buf[dev]);
- if (n > count)
- n = count;
- c = 0;
-
- while (c < n)
- {
- REMOVE_BYTE (midi_in_buf[dev], tmp_data);
- COPY_TO_USER (buf, c, &tmp_data, 1);
- c++;
- }
- }
-
- RESTORE_INTR (flags);
-
- return c;
-}
-
-int
-MIDIbuf_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned int arg)
-{
- int val;
-
- dev = dev >> 4;
-
- if (((cmd >> 8) & 0xff) == 'C')
- {
- if (midi_devs[dev]->coproc) /* Coprocessor ioctl */
- return midi_devs[dev]->coproc->ioctl (midi_devs[dev]->coproc->devc, cmd, arg, 0);
- else
- printk ("/dev/midi%d: No coprocessor for this device\n", dev);
-
- return RET_ERROR (EREMOTEIO);
- }
- else
- switch (cmd)
- {
-
- case SNDCTL_MIDI_PRETIME:
- val = IOCTL_IN (arg);
- if (val < 0)
- val = 0;
-
- val = (HZ * val) / 10;
- parms[dev].prech_timeout = val;
- return IOCTL_OUT (arg, val);
- break;
-
- default:
- return midi_devs[dev]->ioctl (dev, cmd, arg);
- }
-}
-
-#ifdef ALLOW_SELECT
-int
-MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
-{
- dev = dev >> 4;
-
- switch (sel_type)
- {
- case SEL_IN:
- if (!DATA_AVAIL (midi_in_buf[dev]))
- {
-#if defined(__FreeBSD__)
- selrecord(wait, &selinfo[dev]);
-#else
- input_sleep_flag[dev].mode = WK_SLEEP;
- select_wait (&input_sleeper[dev], wait);
-#endif
- return 0;
- }
- return 1;
- break;
-
- case SEL_OUT:
- if (SPACE_AVAIL (midi_out_buf[dev]))
- {
-#if defined(__FreeBSD__)
- selrecord(wait, &selinfo[dev]);
-#else
- midi_sleep_flag[dev].mode = WK_SLEEP;
- select_wait (&midi_sleeper[dev], wait);
-#endif
- return 0;
- }
- return 1;
- break;
-
- case SEL_EX:
- return 0;
- }
-
- return 0;
-}
-
-#endif /* ALLOW_SELECT */
-
-long
-MIDIbuf_init (long mem_start)
-{
- return mem_start;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/mpu401.c b/sys/pc98/pc98/sound/mpu401.c
deleted file mode 100644
index eaee157..0000000
--- a/sys/pc98/pc98/sound/mpu401.c
+++ /dev/null
@@ -1,1777 +0,0 @@
-/*
- * sound/mpu401.c
- *
- * The low level driver for Roland MPU-401 compatible Midi cards.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * Modified:
- * Riccardo Facchetti 24 Mar 1995
- * - Added the Audio Excel DSP 16 initialization routine.
- */
-
-#define USE_SEQ_MACROS
-#define USE_SIMPLE_MACROS
-
-#include <i386/isa/sound/sound_config.h>
-
-#ifdef CONFIGURE_SOUNDCARD
-
-#if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
-#include <i386/isa/sound/coproc.h>
-
-static int init_sequence[20]; /* NOTE! pos 0 = len, start pos 1. */
-static int timer_mode = TMR_INTERNAL, timer_caps = TMR_INTERNAL;
-
-struct mpu_config
- {
- int base; /*
- * I/O base
- */
- int irq;
- int opened; /*
- * Open mode
- */
- int devno;
- int synthno;
- int uart_mode;
- int initialized;
- int mode;
-#define MODE_MIDI 1
-#define MODE_SYNTH 2
- unsigned char version, revision;
- unsigned int capabilities;
-#define MPU_CAP_INTLG 0x10000000
-#define MPU_CAP_SYNC 0x00000010
-#define MPU_CAP_FSK 0x00000020
-#define MPU_CAP_CLS 0x00000040
-#define MPU_CAP_SMPTE 0x00000080
-#define MPU_CAP_2PORT 0x00000001
- int timer_flag;
-
-#define MBUF_MAX 10
-#define BUFTEST(dc) if (dc->m_ptr >= MBUF_MAX || dc->m_ptr < 0) \
- {printk("MPU: Invalid buffer pointer %d/%d, s=%d\n", dc->m_ptr, dc->m_left, dc->m_state);dc->m_ptr--;}
- int m_busy;
- unsigned char m_buf[MBUF_MAX];
- int m_ptr;
- int m_state;
- int m_left;
- unsigned char last_status;
- void (*inputintr) (int dev, unsigned char data);
- int shared_irq;
- };
-
-#define DATAPORT(base) (base)
-#define COMDPORT(base) (base+1)
-#define STATPORT(base) (base+1)
-
-#define mpu401_status(base) INB(STATPORT(base))
-#define input_avail(base) (!(mpu401_status(base)&INPUT_AVAIL))
-#define output_ready(base) (!(mpu401_status(base)&OUTPUT_READY))
-#define write_command(base, cmd) OUTB(cmd, COMDPORT(base))
-#define read_data(base) INB(DATAPORT(base))
-
-#define write_data(base, byte) OUTB(byte, DATAPORT(base))
-
-#define OUTPUT_READY 0x40
-#define INPUT_AVAIL 0x80
-#define MPU_ACK 0xF7
-#define MPU_RESET 0xFF
-#define UART_MODE_ON 0x3F
-
-static struct mpu_config dev_conf[MAX_MIDI_DEV] =
-{
- {0}};
-
-static int n_mpu_devs = 0;
-static int irq2dev[16] =
-{-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1};
-
-static int reset_mpu401 (struct mpu_config *devc);
-static void set_uart_mode (int dev, struct mpu_config *devc, int arg);
-static void mpu_timer_init (int midi_dev);
-static void mpu_timer_interrupt (void);
-static void timer_ext_event (struct mpu_config *devc, int event, int parm);
-
-static struct synth_info mpu_synth_info_proto =
-{"MPU-401 MIDI interface", 0, SYNTH_TYPE_MIDI, 0, 0, 128, 0, 128, SYNTH_CAP_INPUT};
-
-static struct synth_info mpu_synth_info[MAX_MIDI_DEV];
-
-/*
- * States for the input scanner
- */
-
-#define ST_INIT 0 /* Ready for timing byte or msg */
-#define ST_TIMED 1 /* Leading timing byte rcvd */
-#define ST_DATABYTE 2 /* Waiting for (nr_left) data bytes */
-
-#define ST_SYSMSG 100 /* System message (sysx etc). */
-#define ST_SYSEX 101 /* System exclusive msg */
-#define ST_MTC 102 /* Midi Time Code (MTC) qframe msg */
-#define ST_SONGSEL 103 /* Song select */
-#define ST_SONGPOS 104 /* Song position pointer */
-
-static unsigned char len_tab[] = /* # of data bytes following a status
- */
-{
- 2, /* 8x */
- 2, /* 9x */
- 2, /* Ax */
- 2, /* Bx */
- 1, /* Cx */
- 1, /* Dx */
- 2, /* Ex */
- 0 /* Fx */
-};
-
-#define STORE(cmd) \
-{ \
- int len; \
- unsigned char obuf[8]; \
- cmd; \
- seq_input_event(obuf, len); \
-}
-#define _seqbuf obuf
-#define _seqbufptr 0
-#define _SEQ_ADVBUF(x) len=x
-
-static int
-mpu_input_scanner (struct mpu_config *devc, unsigned char midic)
-{
-
- switch (devc->m_state)
- {
- case ST_INIT:
- switch (midic)
- {
- case 0xf8:
- /* Timer overflow */
- break;
-
- case 0xfc:
- printk ("<all end>");
- break;
-
- case 0xfd:
- if (devc->timer_flag)
- mpu_timer_interrupt ();
- break;
-
- case 0xfe:
- return MPU_ACK;
- break;
-
- case 0xf0:
- case 0xf1:
- case 0xf2:
- case 0xf3:
- case 0xf4:
- case 0xf5:
- case 0xf6:
- case 0xf7:
- printk ("<Trk data rq #%d>", midic & 0x0f);
- break;
-
- case 0xf9:
- printk ("<conductor rq>");
- break;
-
- case 0xff:
- devc->m_state = ST_SYSMSG;
- break;
-
- default:
- if (midic <= 0xef)
- {
- /* printk("mpu time: %d ", midic); */
- devc->m_state = ST_TIMED;
- }
- else
- printk ("<MPU: Unknown event %02x> ", midic);
- }
- break;
-
- case ST_TIMED:
- {
- int msg = (midic & 0xf0) >> 4;
-
- devc->m_state = ST_DATABYTE;
-
- if (msg < 8) /* Data byte */
- {
- /* printk("midi msg (running status) "); */
- msg = (devc->last_status & 0xf0) >> 4;
- msg -= 8;
- devc->m_left = len_tab[msg] - 1;
-
- devc->m_ptr = 2;
- devc->m_buf[0] = devc->last_status;
- devc->m_buf[1] = midic;
-
- if (devc->m_left <= 0)
- {
- devc->m_state = ST_INIT;
- do_midi_msg (devc->synthno, devc->m_buf, devc->m_ptr);
- devc->m_ptr = 0;
- }
- }
- else if (msg == 0xf) /* MPU MARK */
- {
- devc->m_state = ST_INIT;
-
- switch (midic)
- {
- case 0xf8:
- /* printk("NOP "); */
- break;
-
- case 0xf9:
- /* printk("meas end "); */
- break;
-
- case 0xfc:
- /* printk("data end "); */
- break;
-
- default:
- printk ("Unknown MPU mark %02x\n", midic);
- }
- }
- else
- {
- devc->last_status = midic;
- /* printk ("midi msg "); */
- msg -= 8;
- devc->m_left = len_tab[msg];
-
- devc->m_ptr = 1;
- devc->m_buf[0] = midic;
-
- if (devc->m_left <= 0)
- {
- devc->m_state = ST_INIT;
- do_midi_msg (devc->synthno, devc->m_buf, devc->m_ptr);
- devc->m_ptr = 0;
- }
- }
- }
- break;
-
- case ST_SYSMSG:
- switch (midic)
- {
- case 0xf0:
- printk ("<SYX>");
- devc->m_state = ST_SYSEX;
- break;
-
- case 0xf1:
- devc->m_state = ST_MTC;
- break;
-
- case 0xf2:
- devc->m_state = ST_SONGPOS;
- devc->m_ptr = 0;
- break;
-
- case 0xf3:
- devc->m_state = ST_SONGSEL;
- break;
-
- case 0xf6:
- /* printk("tune_request\n"); */
- devc->m_state = ST_INIT;
-
- /*
- * Real time messages
- */
- case 0xf8:
- /* midi clock */
- devc->m_state = ST_INIT;
- timer_ext_event (devc, TMR_CLOCK, 0);
- break;
-
- case 0xfA:
- devc->m_state = ST_INIT;
- timer_ext_event (devc, TMR_START, 0);
- break;
-
- case 0xFB:
- devc->m_state = ST_INIT;
- timer_ext_event (devc, TMR_CONTINUE, 0);
- break;
-
- case 0xFC:
- devc->m_state = ST_INIT;
- timer_ext_event (devc, TMR_STOP, 0);
- break;
-
- case 0xFE:
- /* active sensing */
- devc->m_state = ST_INIT;
- break;
-
- case 0xff:
- /* printk("midi hard reset"); */
- devc->m_state = ST_INIT;
- break;
-
- default:
- printk ("unknown MIDI sysmsg %0x\n", midic);
- devc->m_state = ST_INIT;
- }
- break;
-
- case ST_MTC:
- devc->m_state = ST_INIT;
- printk ("MTC frame %x02\n", midic);
- break;
-
- case ST_SYSEX:
- if (midic == 0xf7)
- {
- printk ("<EOX>");
- devc->m_state = ST_INIT;
- }
- else
- printk ("%02x ", midic);
- break;
-
- case ST_SONGPOS:
- BUFTEST (devc);
- devc->m_buf[devc->m_ptr++] = midic;
- if (devc->m_ptr == 2)
- {
- devc->m_state = ST_INIT;
- devc->m_ptr = 0;
- timer_ext_event (devc, TMR_SPP,
- ((devc->m_buf[1] & 0x7f) << 7) |
- (devc->m_buf[0] & 0x7f));
- }
- break;
-
- case ST_DATABYTE:
- BUFTEST (devc);
- devc->m_buf[devc->m_ptr++] = midic;
- if ((--devc->m_left) <= 0)
- {
- devc->m_state = ST_INIT;
- do_midi_msg (devc->synthno, devc->m_buf, devc->m_ptr);
- devc->m_ptr = 0;
- }
- break;
-
- default:
- printk ("Bad state %d ", devc->m_state);
- devc->m_state = ST_INIT;
- }
-
- return 1;
-}
-
-static void
-mpu401_input_loop (struct mpu_config *devc)
-{
- unsigned long flags;
- int busy;
- int n;
-
- DISABLE_INTR (flags);
- busy = devc->m_busy;
- devc->m_busy = 1;
- RESTORE_INTR (flags);
-
- if (busy) /* Already inside the scanner */
- return;
-
- n = 50;
-
- while (input_avail (devc->base) && n-- > 0)
- {
- unsigned char c = read_data (devc->base);
-
- if (devc->mode == MODE_SYNTH)
- {
- mpu_input_scanner (devc, c);
- }
- else if (devc->opened & OPEN_READ && devc->inputintr != NULL)
- devc->inputintr (devc->devno, c);
- }
-
- devc->m_busy = 0;
-}
-
-void
-mpuintr (INT_HANDLER_PARMS (irq, dummy))
-{
- struct mpu_config *devc;
- int dev;
-
-#ifdef linux
- sti ();
-#endif
-
- if (irq < 1 || irq > 15)
- {
- printk ("MPU-401: Interrupt #%d?\n", irq);
- return;
- }
-
- dev = irq2dev[irq];
- if (dev == -1)
- {
- /* printk ("MPU-401: Interrupt #%d?\n", irq); */
- return;
- }
-
- devc = &dev_conf[dev];
-
- if (input_avail (devc->base))
- if (devc->base != 0 && (devc->opened & OPEN_READ || devc->mode == MODE_SYNTH))
- mpu401_input_loop (devc);
- else
- {
- /* Dummy read (just to acknowledge the interrupt) */
- read_data (devc->base);
- }
-
-}
-
-static int
-mpu401_open (int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- int err;
- struct mpu_config *devc;
-
- if (dev < 0 || dev >= num_midis)
- return RET_ERROR (ENXIO);
-
- devc = &dev_conf[dev];
-
- if (devc->opened)
- {
- printk ("MPU-401: Midi busy\n");
- return RET_ERROR (EBUSY);
- }
-
- /*
- * Verify that the device is really running.
- * Some devices (such as Ensoniq SoundScape don't
- * work before the on board processor (OBP) is initialized
- * by downloadin it's microcode.
- */
-
- if (!devc->initialized)
- {
- if (mpu401_status (devc->base) == 0xff) /* Bus float */
- {
- printk ("MPU-401: Device not initialized properly\n");
- return RET_ERROR (EIO);
- }
- reset_mpu401 (devc);
- }
-
- irq2dev[devc->irq] = dev;
- if (devc->shared_irq == 0)
- if ((err = snd_set_irq_handler (devc->irq, mpuintr, midi_devs[dev]->info.name) < 0))
- {
- return err;
- }
-
- if (midi_devs[dev]->coproc)
- if ((err = midi_devs[dev]->coproc->
- open (midi_devs[dev]->coproc->devc, COPR_MIDI)) < 0)
- {
- if (devc->shared_irq == 0)
- snd_release_irq (devc->irq);
- printk ("MPU-401: Can't access coprocessor device\n");
-
- return err;
- }
-
- set_uart_mode (dev, devc, 1);
- devc->mode = MODE_MIDI;
- devc->synthno = 0;
-
- mpu401_input_loop (devc);
-
- devc->inputintr = input;
- devc->opened = mode;
-
- return 0;
-}
-
-static void
-mpu401_close (int dev)
-{
- struct mpu_config *devc;
-
- devc = &dev_conf[dev];
-
- if (devc->uart_mode)
- reset_mpu401 (devc); /*
- * This disables the UART mode
- */
- devc->mode = 0;
-
- if (devc->shared_irq == 0)
- snd_release_irq (devc->irq);
- devc->inputintr = NULL;
-
- if (midi_devs[dev]->coproc)
- midi_devs[dev]->coproc->close (midi_devs[dev]->coproc->devc, COPR_MIDI);
- devc->opened = 0;
-}
-
-static int
-mpu401_out (int dev, unsigned char midi_byte)
-{
- int timeout;
- unsigned long flags;
-
- struct mpu_config *devc;
-
- devc = &dev_conf[dev];
-
-#if 0
- /*
- * Test for input since pending input seems to block the output.
- */
-
- if (input_avail (devc->base))
- {
- mpu401_input_loop (devc);
- }
-#endif
- /*
- * Sometimes it takes about 13000 loops before the output becomes ready
- * (After reset). Normally it takes just about 10 loops.
- */
-
- for (timeout = 3000; timeout > 0 && !output_ready (devc->base); timeout--);
-
- DISABLE_INTR (flags);
- if (!output_ready (devc->base))
- {
- printk ("MPU-401: Send data timeout\n");
- RESTORE_INTR (flags);
- return 0;
- }
-
- write_data (devc->base, midi_byte);
- RESTORE_INTR (flags);
- return 1;
-}
-
-static int
-mpu401_command (int dev, mpu_command_rec * cmd)
-{
- int i, timeout, ok;
- int ret = 0;
- unsigned long flags;
- struct mpu_config *devc;
-
- devc = &dev_conf[dev];
-
- if (devc->uart_mode) /*
- * Not possible in UART mode
- */
- {
- printk ("MPU-401 commands not possible in the UART mode\n");
- return RET_ERROR (EINVAL);
- }
-
- /*
- * Test for input since pending input seems to block the output.
- */
- if (input_avail (devc->base))
- mpu401_input_loop (devc);
-
- /*
- * Sometimes it takes about 30000 loops before the output becomes ready
- * (After reset). Normally it takes just about 10 loops.
- */
-
- timeout = 30000;
-retry:
- if (timeout-- <= 0)
- {
- printk ("MPU-401: Command (0x%x) timeout\n", (int) cmd->cmd);
- return RET_ERROR (EIO);
- }
-
- DISABLE_INTR (flags);
-
- if (!output_ready (devc->base))
- {
- RESTORE_INTR (flags);
- goto retry;
- }
-
- write_command (devc->base, cmd->cmd);
- ok = 0;
- for (timeout = 50000; timeout > 0 && !ok; timeout--)
- if (input_avail (devc->base))
- {
- if (mpu_input_scanner (devc, read_data (devc->base)) == MPU_ACK)
- ok = 1;
- }
-
- if (!ok)
- {
- RESTORE_INTR (flags);
- /* printk ("MPU: No ACK to command (0x%x)\n", (int) cmd->cmd); */
- return RET_ERROR (EIO);
- }
-
- if (cmd->nr_args)
- for (i = 0; i < cmd->nr_args; i++)
- {
- for (timeout = 3000; timeout > 0 && !output_ready (devc->base); timeout--);
-
- if (!mpu401_out (dev, cmd->data[i]))
- {
- RESTORE_INTR (flags);
- printk ("MPU: Command (0x%x), parm send failed.\n", (int) cmd->cmd);
- return RET_ERROR (EIO);
- }
- }
-
- ret = 0;
- cmd->data[0] = 0;
-
- if (cmd->nr_returns)
- for (i = 0; i < cmd->nr_returns; i++)
- {
- ok = 0;
- for (timeout = 5000; timeout > 0 && !ok; timeout--)
- if (input_avail (devc->base))
- {
- cmd->data[i] = read_data (devc->base);
- ok = 1;
- }
-
- if (!ok)
- {
- RESTORE_INTR (flags);
- /* printk ("MPU: No response(%d) to command (0x%x)\n", i, (int) cmd->cmd); */
- return RET_ERROR (EIO);
- }
- }
-
- RESTORE_INTR (flags);
-
- return ret;
-}
-
-static int
-exec_cmd (int dev, int cmd, int data)
-{
- int ret;
-
- static mpu_command_rec rec;
-
- rec.cmd = cmd & 0xff;
- rec.nr_args = ((cmd & 0xf0) == 0xE0);
- rec.nr_returns = ((cmd & 0xf0) == 0xA0);
- rec.data[0] = data & 0xff;
-
- if ((ret = mpu401_command (dev, &rec)) < 0)
- return ret;
- return (unsigned char) rec.data[0];
-}
-
-static int
-mpu401_prefix_cmd (int dev, unsigned char status)
-{
- struct mpu_config *devc = &dev_conf[dev];
-
- if (devc->uart_mode)
- return 1;
-
- if (status < 0xf0)
- {
- if (exec_cmd (dev, 0xD0, 0) < 0)
- return 0;
-
- return 1;
- }
-
- switch (status)
- {
- case 0xF0:
- if (exec_cmd (dev, 0xDF, 0) < 0)
- return 0;
-
- return 1;
- break;
-
- default:
- return 0;
- }
-
- return 0;
-}
-
-static int
-mpu401_start_read (int dev)
-{
- return 0;
-}
-
-static int
-mpu401_end_read (int dev)
-{
- return 0;
-}
-
-static int
-mpu401_ioctl (int dev, unsigned cmd, unsigned arg)
-{
- struct mpu_config *devc;
-
- devc = &dev_conf[dev];
-
- switch (cmd)
- {
- case 1:
- IOCTL_FROM_USER ((char *) &init_sequence, (char *) arg, 0, sizeof (init_sequence));
- return 0;
- break;
-
- case SNDCTL_MIDI_MPUMODE:
- if (devc->version == 0)
- {
- printk ("MPU-401: Intelligent mode not supported by the HW\n");
- return RET_ERROR (EINVAL);
- }
- set_uart_mode (dev, devc, !IOCTL_IN (arg));
- return 0;
- break;
-
- case SNDCTL_MIDI_MPUCMD:
- {
- int ret;
- mpu_command_rec rec;
-
- IOCTL_FROM_USER ((char *) &rec, (char *) arg, 0, sizeof (rec));
-
- if ((ret = mpu401_command (dev, &rec)) < 0)
- return ret;
-
- IOCTL_TO_USER ((char *) arg, 0, (char *) &rec, sizeof (rec));
- return 0;
- }
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
-}
-
-static void
-mpu401_kick (int dev)
-{
-}
-
-static int
-mpu401_buffer_status (int dev)
-{
- return 0; /*
- * No data in buffers
- */
-}
-
-static int
-mpu_synth_ioctl (int dev,
- unsigned int cmd, unsigned int arg)
-{
- int midi_dev;
- struct mpu_config *devc;
-
- midi_dev = synth_devs[dev]->midi_dev;
-
- if (midi_dev < 0 || midi_dev > num_midis)
- return RET_ERROR (ENXIO);
-
- devc = &dev_conf[midi_dev];
-
- switch (cmd)
- {
-
- case SNDCTL_SYNTH_INFO:
- IOCTL_TO_USER ((char *) arg, 0, &mpu_synth_info[midi_dev],
- sizeof (struct synth_info));
-
- return 0;
- break;
-
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
-}
-
-static int
-mpu_synth_open (int dev, int mode)
-{
- int midi_dev, err;
- struct mpu_config *devc;
-
- midi_dev = synth_devs[dev]->midi_dev;
-
- if (midi_dev < 0 || midi_dev > num_midis)
- {
- return RET_ERROR (ENXIO);
- }
-
- devc = &dev_conf[midi_dev];
-
- /*
- * Verify that the device is really running.
- * Some devices (such as Ensoniq SoundScape don't
- * work before the on board processor (OBP) is initialized
- * by downloadin it's microcode.
- */
-
- if (!devc->initialized)
- {
- if (mpu401_status (devc->base) == 0xff) /* Bus float */
- {
- printk ("MPU-401: Device not initialized properly\n");
- return RET_ERROR (EIO);
- }
- reset_mpu401 (devc);
- }
-
- if (devc->opened)
- {
- printk ("MPU-401: Midi busy\n");
- return RET_ERROR (EBUSY);
- }
-
- devc->mode = MODE_SYNTH;
- devc->synthno = dev;
-
- devc->inputintr = NULL;
- irq2dev[devc->irq] = midi_dev;
- if (devc->shared_irq == 0)
- if ((err = snd_set_irq_handler (devc->irq, mpuintr, midi_devs[midi_dev]->info.name) < 0))
- {
- return err;
- }
-
- if (midi_devs[midi_dev]->coproc)
- if ((err = midi_devs[midi_dev]->coproc->
- open (midi_devs[midi_dev]->coproc->devc, COPR_MIDI)) < 0)
- {
- if (devc->shared_irq == 0)
- snd_release_irq (devc->irq);
- printk ("MPU-401: Can't access coprocessor device\n");
-
- return err;
- }
-
- devc->opened = mode;
- reset_mpu401 (devc);
-
- if (mode & OPEN_READ)
- {
- exec_cmd (midi_dev, 0x8B, 0); /* Enable data in stop mode */
- exec_cmd (midi_dev, 0x34, 0); /* Return timing bytes in stop mode */
- }
-
- return 0;
-}
-
-static void
-mpu_synth_close (int dev)
-{
- int midi_dev;
- struct mpu_config *devc;
-
- midi_dev = synth_devs[dev]->midi_dev;
-
- devc = &dev_conf[midi_dev];
- exec_cmd (midi_dev, 0x15, 0); /* Stop recording, playback and MIDI */
- exec_cmd (midi_dev, 0x8a, 0); /* Disable data in stopped mode */
-
- if (devc->shared_irq == 0)
- snd_release_irq (devc->irq);
- devc->inputintr = NULL;
-
- if (midi_devs[midi_dev]->coproc)
- midi_devs[midi_dev]->coproc->close (midi_devs[midi_dev]->coproc->devc, COPR_MIDI);
- devc->opened = 0;
- devc->mode = 0;
-}
-
-#define MIDI_SYNTH_NAME "MPU-401 UART Midi"
-#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
-#include <i386/isa/sound/midi_synth.h>
-
-static struct synth_operations mpu401_synth_proto =
-{
- NULL,
- 0,
- SYNTH_TYPE_MIDI,
- 0,
- mpu_synth_open,
- mpu_synth_close,
- mpu_synth_ioctl,
- midi_synth_kill_note,
- midi_synth_start_note,
- midi_synth_set_instr,
- midi_synth_reset,
- midi_synth_hw_control,
- midi_synth_load_patch,
- midi_synth_aftertouch,
- midi_synth_controller,
- midi_synth_panning,
- NULL,
- midi_synth_patchmgr,
- midi_synth_bender,
- NULL, /* alloc */
- midi_synth_setup_voice
-};
-
-static struct synth_operations mpu401_synth_operations[MAX_MIDI_DEV];
-
-static struct midi_operations mpu401_midi_proto =
-{
- {"MPU-401 Midi", 0, MIDI_CAP_MPU401, SNDCARD_MPU401},
- NULL,
- {0},
- mpu401_open,
- mpu401_close,
- mpu401_ioctl,
- mpu401_out,
- mpu401_start_read,
- mpu401_end_read,
- mpu401_kick,
- NULL,
- mpu401_buffer_status,
- mpu401_prefix_cmd
-};
-
-static struct midi_operations mpu401_midi_operations[MAX_MIDI_DEV];
-
-static void
-mpu401_chk_version (struct mpu_config *devc)
-{
- int tmp;
-
- devc->version = devc->revision = 0;
-
- if ((tmp = exec_cmd (num_midis, 0xAC, 0)) < 0)
- return;
-
- if ((tmp & 0xf0) > 0x20) /* Why it's larger than 2.x ??? */
- return;
-
- devc->version = tmp;
-
- if ((tmp = exec_cmd (num_midis, 0xAD, 0)) < 0)
- {
- devc->version = 0;
- return;
- }
- devc->revision = tmp;
-}
-
-long
-attach_mpu401 (long mem_start, struct address_info *hw_config)
-{
- unsigned long flags;
- char revision_char;
-
- struct mpu_config *devc;
-
- if (num_midis >= MAX_MIDI_DEV)
- {
- printk ("MPU-401: Too many midi devices detected\n");
- return mem_start;
- }
-
- devc = &dev_conf[num_midis];
-
- devc->base = hw_config->io_base;
- devc->irq = hw_config->irq;
- devc->opened = 0;
- devc->uart_mode = 0;
- devc->initialized = 0;
- devc->version = 0;
- devc->revision = 0;
- devc->capabilities = 0;
- devc->timer_flag = 0;
- devc->m_busy = 0;
- devc->m_state = ST_INIT;
- devc->shared_irq = hw_config->always_detect;
-
- if (!hw_config->always_detect)
- {
- /* Verify the hardware again */
- if (!reset_mpu401 (devc))
- return mem_start;
-
- DISABLE_INTR (flags);
- mpu401_chk_version (devc);
- if (devc->version == 0)
- mpu401_chk_version (devc);
- RESTORE_INTR (flags);
- }
-
- if (devc->version == 0)
- {
- memcpy ((char *) &mpu401_synth_operations[num_midis],
- (char *) &std_midi_synth,
- sizeof (struct synth_operations));
- }
- else
- {
- devc->capabilities |= MPU_CAP_INTLG; /* Supports intelligent mode */
- memcpy ((char *) &mpu401_synth_operations[num_midis],
- (char *) &mpu401_synth_proto,
- sizeof (struct synth_operations));
- }
-
- memcpy ((char *) &mpu401_midi_operations[num_midis],
- (char *) &mpu401_midi_proto,
- sizeof (struct midi_operations));
-
- mpu401_midi_operations[num_midis].converter =
- &mpu401_synth_operations[num_midis];
-
- memcpy ((char *) &mpu_synth_info[num_midis],
- (char *) &mpu_synth_info_proto,
- sizeof (struct synth_info));
-
- n_mpu_devs++;
-
- if (devc->version == 0x20 && devc->revision >= 0x07) /* MusicQuest interface */
- {
- int ports = (devc->revision & 0x08) ? 32 : 16;
-
- devc->capabilities |= MPU_CAP_SYNC | MPU_CAP_SMPTE |
- MPU_CAP_CLS | MPU_CAP_2PORT;
-
- revision_char = (devc->revision == 0x7f) ? 'M' : ' ';
-#if defined(__FreeBSD__)
- printk ("mpu0: <MQX-%d%c MIDI Interface>",
-#else
- printk (" <MQX-%d%c MIDI Interface>",
-#endif
- ports,
- revision_char);
- sprintf (mpu_synth_info[num_midis].name,
- "MQX-%d%c MIDI Interface #%d",
- ports,
- revision_char,
- n_mpu_devs);
- }
- else
- {
-
- revision_char = devc->revision ? devc->revision + '@' : ' ';
- if (devc->revision > ('Z' - '@'))
- revision_char = '+';
-
- devc->capabilities |= MPU_CAP_SYNC | MPU_CAP_FSK;
-
-#if defined(__FreeBSD__)
- printk ("mpu0: <MPU-401 MIDI Interface %d.%d%c>",
-#else
- printk (" <MPU-401 MIDI Interface %d.%d%c>",
-#endif
- (devc->version & 0xf0) >> 4,
- devc->version & 0x0f,
- revision_char);
- sprintf (mpu_synth_info[num_midis].name,
- "MPU-401 %d.%d%c Midi interface #%d",
- (devc->version & 0xf0) >> 4,
- devc->version & 0x0f,
- revision_char,
- n_mpu_devs);
- }
-
- strcpy (mpu401_midi_operations[num_midis].info.name,
- mpu_synth_info[num_midis].name);
-
- mpu401_synth_operations[num_midis].midi_dev = devc->devno = num_midis;
- mpu401_synth_operations[devc->devno].info =
- &mpu_synth_info[devc->devno];
-
- if (devc->capabilities & MPU_CAP_INTLG) /* Has timer */
- mpu_timer_init (num_midis);
-
- irq2dev[devc->irq] = num_midis;
- midi_devs[num_midis++] = &mpu401_midi_operations[devc->devno];
- return mem_start;
-}
-
-static int
-reset_mpu401 (struct mpu_config *devc)
-{
- unsigned long flags;
- int ok, timeout, n;
- int timeout_limit;
-
- /*
- * Send the RESET command. Try again if no success at the first time.
- * (If the device is in the UART mode, it will not ack the reset cmd).
- */
-
- ok = 0;
-
- timeout_limit = devc->initialized ? 30000 : 100000;
- devc->initialized = 1;
-
- for (n = 0; n < 2 && !ok; n++)
- {
- for (timeout = timeout_limit; timeout > 0 && !ok; timeout--)
- ok = output_ready (devc->base);
-
- write_command (devc->base, MPU_RESET); /*
- * Send MPU-401 RESET Command
- */
-
- /*
- * Wait at least 25 msec. This method is not accurate so let's make the
- * loop bit longer. Cannot sleep since this is called during boot.
- */
-
- for (timeout = timeout_limit * 2; timeout > 0 && !ok; timeout--)
- {
- DISABLE_INTR (flags);
- if (input_avail (devc->base))
- if (read_data (devc->base) == MPU_ACK)
- ok = 1;
- RESTORE_INTR (flags);
- }
-
- }
-
- devc->m_state = ST_INIT;
- devc->m_ptr = 0;
- devc->m_left = 0;
- devc->last_status = 0;
- devc->uart_mode = 0;
-
- return ok;
-}
-
-static void
-set_uart_mode (int dev, struct mpu_config *devc, int arg)
-{
-
- if (!arg && devc->version == 0)
- {
- return;
- }
-
- if ((devc->uart_mode == 0) == (arg == 0))
- {
- return; /* Already set */
- }
-
- reset_mpu401 (devc); /* This exits the uart mode */
-
- if (arg)
- {
- if (exec_cmd (dev, UART_MODE_ON, 0) < 0)
- {
- printk ("MPU%d: Can't enter UART mode\n", devc->devno);
- devc->uart_mode = 0;
- return;
- }
- }
- devc->uart_mode = arg;
-
-}
-
-int
-probe_mpu401 (struct address_info *hw_config)
-{
- int ok = 0;
- struct mpu_config tmp_devc;
-
- tmp_devc.base = hw_config->io_base;
- tmp_devc.irq = hw_config->irq;
- tmp_devc.initialized = 0;
-
-#if !defined(EXCLUDE_AEDSP16) && defined(AEDSP16_MPU401)
- /*
- * Initialize Audio Excel DSP 16 to MPU-401, before any operation.
- */
- InitAEDSP16_MPU401 (hw_config);
-#endif
-
- if (hw_config->always_detect)
- return 1;
-
- if (INB (hw_config->io_base + 1) == 0xff)
- return 0; /* Just bus float? */
-
- ok = reset_mpu401 (&tmp_devc);
-
- return ok;
-}
-
-/*****************************************************
- * Timer stuff
- ****************************************************/
-
-#if !defined(EXCLUDE_SEQUENCER)
-
-static volatile int timer_initialized = 0, timer_open = 0, tmr_running = 0;
-static volatile int curr_tempo, curr_timebase, hw_timebase;
-static int max_timebase = 8; /* 8*24=192 ppqn */
-static volatile unsigned long next_event_time;
-static volatile unsigned long curr_ticks, curr_clocks;
-static unsigned long prev_event_time;
-static int metronome_mode;
-
-static unsigned long
-clocks2ticks (unsigned long clocks)
-{
- /*
- * The MPU-401 supports just a limited set of possible timebase values.
- * Since the applications require more choices, the driver has to
- * program the HW to do it's best and to convert between the HW and
- * actual timebases.
- */
-
- return ((clocks * curr_timebase) + (hw_timebase / 2)) / hw_timebase;
-}
-
-static void
-set_timebase (int midi_dev, int val)
-{
- int hw_val;
-
- if (val < 48)
- val = 48;
- if (val > 1000)
- val = 1000;
-
- hw_val = val;
- hw_val = (hw_val + 23) / 24;
- if (hw_val > max_timebase)
- hw_val = max_timebase;
-
- if (exec_cmd (midi_dev, 0xC0 | (hw_val & 0x0f), 0) < 0)
- {
- printk ("MPU: Can't set HW timebase to %d\n", hw_val * 24);
- return;
- }
- hw_timebase = hw_val * 24;
- curr_timebase = val;
-
-}
-
-static void
-tmr_reset (void)
-{
- unsigned long flags;
-
- DISABLE_INTR (flags);
- next_event_time = 0xffffffff;
- prev_event_time = 0;
- curr_ticks = curr_clocks = 0;
- RESTORE_INTR (flags);
-}
-
-static void
-set_timer_mode (int midi_dev)
-{
- if (timer_mode & TMR_MODE_CLS)
- exec_cmd (midi_dev, 0x3c, 0); /* Use CLS sync */
- else if (timer_mode & TMR_MODE_SMPTE)
- exec_cmd (midi_dev, 0x3d, 0); /* Use SMPTE sync */
-
- if (timer_mode & TMR_INTERNAL)
- {
- exec_cmd (midi_dev, 0x80, 0); /* Use MIDI sync */
- }
- else
- {
- if (timer_mode & (TMR_MODE_MIDI | TMR_MODE_CLS))
- {
- exec_cmd (midi_dev, 0x82, 0); /* Use MIDI sync */
- exec_cmd (midi_dev, 0x91, 0); /* Enable ext MIDI ctrl */
- }
- else if (timer_mode & TMR_MODE_FSK)
- exec_cmd (midi_dev, 0x81, 0); /* Use FSK sync */
- }
-}
-
-static void
-stop_metronome (int midi_dev)
-{
- exec_cmd (midi_dev, 0x84, 0); /* Disable metronome */
-}
-
-static void
-setup_metronome (int midi_dev)
-{
- int numerator, denominator;
- int clks_per_click, num_32nds_per_beat;
- int beats_per_measure;
-
- numerator = ((unsigned) metronome_mode >> 24) & 0xff;
- denominator = ((unsigned) metronome_mode >> 16) & 0xff;
- clks_per_click = ((unsigned) metronome_mode >> 8) & 0xff;
- num_32nds_per_beat = (unsigned) metronome_mode & 0xff;
- beats_per_measure = (numerator * 4) >> denominator;
-
- if (!metronome_mode)
- exec_cmd (midi_dev, 0x84, 0); /* Disable metronome */
- else
- {
- exec_cmd (midi_dev, 0xE4, clks_per_click);
- exec_cmd (midi_dev, 0xE6, beats_per_measure);
- exec_cmd (midi_dev, 0x83, 0); /* Enable metronome without accents */
- }
-}
-
-static int
-start_timer (int midi_dev)
-{
- tmr_reset ();
- set_timer_mode (midi_dev);
-
- if (tmr_running)
- return TIMER_NOT_ARMED; /* Already running */
-
- if (timer_mode & TMR_INTERNAL)
- {
- exec_cmd (midi_dev, 0x02, 0); /* Send MIDI start */
- tmr_running = 1;
- return TIMER_NOT_ARMED;
- }
- else
- {
- exec_cmd (midi_dev, 0x35, 0); /* Enable mode messages to PC */
- exec_cmd (midi_dev, 0x38, 0); /* Enable sys common messages to PC */
- exec_cmd (midi_dev, 0x39, 0); /* Enable real time messages to PC */
- exec_cmd (midi_dev, 0x97, 0); /* Enable system exclusive messages to PC */
- }
-
- return TIMER_ARMED;
-}
-
-static int
-mpu_timer_open (int dev, int mode)
-{
- int midi_dev = sound_timer_devs[dev]->devlink;
-
- if (timer_open)
- return RET_ERROR (EBUSY);
-
- tmr_reset ();
- curr_tempo = 50;
- exec_cmd (midi_dev, 0xE0, 50);
- curr_timebase = hw_timebase = 120;
- set_timebase (midi_dev, 120);
- timer_open = 1;
- metronome_mode = 0;
- set_timer_mode (midi_dev);
-
- exec_cmd (midi_dev, 0xe7, 0x04); /* Send all clocks to host */
- exec_cmd (midi_dev, 0x95, 0); /* Enable clock to host */
-
- return 0;
-}
-
-static void
-mpu_timer_close (int dev)
-{
- int midi_dev = sound_timer_devs[dev]->devlink;
-
- timer_open = tmr_running = 0;
- exec_cmd (midi_dev, 0x15, 0); /* Stop all */
- exec_cmd (midi_dev, 0x94, 0); /* Disable clock to host */
- exec_cmd (midi_dev, 0x8c, 0); /* Disable measure end messages to host */
- stop_metronome (midi_dev);
-}
-
-static int
-mpu_timer_event (int dev, unsigned char *event)
-{
- unsigned char command = event[1];
- unsigned long parm = *(unsigned int *) &event[4];
- int midi_dev = sound_timer_devs[dev]->devlink;
-
- switch (command)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- if (parm <= curr_ticks) /* It's the time */
- return TIMER_NOT_ARMED;
-
- time = parm;
- next_event_time = prev_event_time = time;
-
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- if (tmr_running)
- break;
- return start_timer (midi_dev);
- break;
-
- case TMR_STOP:
- exec_cmd (midi_dev, 0x01, 0); /* Send MIDI stop */
- stop_metronome (midi_dev);
- tmr_running = 0;
- break;
-
- case TMR_CONTINUE:
- if (tmr_running)
- break;
- exec_cmd (midi_dev, 0x03, 0); /* Send MIDI continue */
- setup_metronome (midi_dev);
- tmr_running = 1;
- break;
-
- case TMR_TEMPO:
- if (parm)
- {
- if (parm < 8)
- parm = 8;
- if (parm > 250)
- parm = 250;
-
- if (exec_cmd (midi_dev, 0xE0, parm) < 0)
- printk ("MPU: Can't set tempo to %d\n", (int) parm);
- curr_tempo = parm;
- }
- break;
-
- case TMR_ECHO:
- seq_copy_to_input (event, 8);
- break;
-
- case TMR_TIMESIG:
- if (metronome_mode) /* Metronome enabled */
- {
- metronome_mode = parm;
- setup_metronome (midi_dev);
- }
- break;
-
- default:;
- }
-
- return TIMER_NOT_ARMED;
-}
-
-static unsigned long
-mpu_timer_get_time (int dev)
-{
- if (!timer_open)
- return 0;
-
- return curr_ticks;
-}
-
-static int
-mpu_timer_ioctl (int dev,
- unsigned int command, unsigned int arg)
-{
- int midi_dev = sound_timer_devs[dev]->devlink;
-
- switch (command)
- {
- case SNDCTL_TMR_SOURCE:
- {
- int parm = IOCTL_IN (arg) & timer_caps;
-
- if (parm != 0)
- {
- timer_mode = parm;
-
- if (timer_mode & TMR_MODE_CLS)
- exec_cmd (midi_dev, 0x3c, 0); /* Use CLS sync */
- else if (timer_mode & TMR_MODE_SMPTE)
- exec_cmd (midi_dev, 0x3d, 0); /* Use SMPTE sync */
- }
-
- return IOCTL_OUT (arg, timer_mode);
- }
- break;
-
- case SNDCTL_TMR_START:
- start_timer (midi_dev);
- return 0;
- break;
-
- case SNDCTL_TMR_STOP:
- tmr_running = 0;
- exec_cmd (midi_dev, 0x01, 0); /* Send MIDI stop */
- stop_metronome (midi_dev);
- return 0;
- break;
-
- case SNDCTL_TMR_CONTINUE:
- if (tmr_running)
- return 0;
- tmr_running = 1;
- exec_cmd (midi_dev, 0x03, 0); /* Send MIDI continue */
- return 0;
- break;
-
- case SNDCTL_TMR_TIMEBASE:
- {
- int val = IOCTL_IN (arg);
-
- if (val)
- set_timebase (midi_dev, val);
-
- return IOCTL_OUT (arg, curr_timebase);
- }
- break;
-
- case SNDCTL_TMR_TEMPO:
- {
- int val = IOCTL_IN (arg);
- int ret;
-
- if (val)
- {
- if (val < 8)
- val = 8;
- if (val > 250)
- val = 250;
- if ((ret = exec_cmd (midi_dev, 0xE0, val)) < 0)
- {
- printk ("MPU: Can't set tempo to %d\n", (int) val);
- return ret;
- }
-
- curr_tempo = val;
- }
-
- return IOCTL_OUT (arg, curr_tempo);
- }
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- if (IOCTL_IN (arg) != 0) /* Can't change */
- return RET_ERROR (EINVAL);
-
- return IOCTL_OUT (arg, ((curr_tempo * curr_timebase) + 30) / 60);
- break;
-
- case SNDCTL_TMR_METRONOME:
- metronome_mode = IOCTL_IN (arg);
- setup_metronome (midi_dev);
- return 0;
- break;
-
- default:
- }
-
- return RET_ERROR (EINVAL);
-}
-
-static void
-mpu_timer_arm (int dev, long time)
-{
- if (time < 0)
- time = curr_ticks + 1;
- else if (time <= curr_ticks) /* It's the time */
- return;
-
- next_event_time = prev_event_time = time;
-
- return;
-}
-
-static struct sound_timer_operations mpu_timer =
-{
- {"MPU-401 Timer", 0},
- 10, /* Priority */
- 0, /* Local device link */
- mpu_timer_open,
- mpu_timer_close,
- mpu_timer_event,
- mpu_timer_get_time,
- mpu_timer_ioctl,
- mpu_timer_arm
-};
-
-static void
-mpu_timer_interrupt (void)
-{
-
- if (!timer_open)
- return;
-
- if (!tmr_running)
- return;
-
- curr_clocks++;
- curr_ticks = clocks2ticks (curr_clocks);
-
- if (curr_ticks >= next_event_time)
- {
- next_event_time = 0xffffffff;
- sequencer_timer ();
- }
-}
-
-static void
-timer_ext_event (struct mpu_config *devc, int event, int parm)
-{
- int midi_dev = devc->devno;
-
- if (!devc->timer_flag)
- return;
-
- switch (event)
- {
- case TMR_CLOCK:
- printk ("<MIDI clk>");
- break;
-
- case TMR_START:
- printk ("Ext MIDI start\n");
- if (!tmr_running)
- if (timer_mode & TMR_EXTERNAL)
- {
- tmr_running = 1;
- setup_metronome (midi_dev);
- next_event_time = 0;
- STORE (SEQ_START_TIMER ());
- }
- break;
-
- case TMR_STOP:
- printk ("Ext MIDI stop\n");
- if (timer_mode & TMR_EXTERNAL)
- {
- tmr_running = 0;
- stop_metronome (midi_dev);
- STORE (SEQ_STOP_TIMER ());
- }
- break;
-
- case TMR_CONTINUE:
- printk ("Ext MIDI continue\n");
- if (timer_mode & TMR_EXTERNAL)
- {
- tmr_running = 1;
- setup_metronome (midi_dev);
- STORE (SEQ_CONTINUE_TIMER ());
- }
- break;
-
- case TMR_SPP:
- printk ("Songpos: %d\n", parm);
- if (timer_mode & TMR_EXTERNAL)
- {
- STORE (SEQ_SONGPOS (parm));
- }
- break;
- }
-}
-
-static void
-mpu_timer_init (int midi_dev)
-{
- struct mpu_config *devc;
- int n;
-
- devc = &dev_conf[midi_dev];
-
- if (timer_initialized)
- return; /* There is already a similar timer */
-
- timer_initialized = 1;
-
- mpu_timer.devlink = midi_dev;
- dev_conf[midi_dev].timer_flag = 1;
-
-#if 1
- if (num_sound_timers >= MAX_TIMER_DEV)
- n = 0; /* Overwrite the system timer */
- else
- n = num_sound_timers++;
-#else
- n = 0;
-#endif
- sound_timer_devs[n] = &mpu_timer;
-
- if (devc->version < 0x20) /* Original MPU-401 */
- timer_caps = TMR_INTERNAL | TMR_EXTERNAL | TMR_MODE_FSK | TMR_MODE_MIDI;
- else
- {
- /*
- * The version number 2.0 is used (at least) by the
- * MusicQuest cards and the Roland Super-MPU.
- *
- * MusicQuest has given a special meaning to the bits of the
- * revision number. The Super-MPU returns 0.
- */
-
- if (devc->revision)
- timer_caps |= TMR_EXTERNAL | TMR_MODE_MIDI;
-
- if (devc->revision & 0x02)
- timer_caps |= TMR_MODE_CLS;
-
-#if 0
- if (devc->revision & 0x04)
- timer_caps |= TMR_MODE_SMPTE;
-#endif
-
- if (devc->revision & 0x40)
- max_timebase = 10; /* Has the 216 and 240 ppqn modes */
- }
-
- timer_mode = (TMR_INTERNAL | TMR_MODE_MIDI) & timer_caps;
-
-}
-
-#endif
-
-#endif
-
-#endif
diff --git a/sys/pc98/pc98/sound/opl3.c b/sys/pc98/pc98/sound/opl3.c
index 749e38f..42379cd 100644
--- a/sys/pc98/pc98/sound/opl3.c
+++ b/sys/pc98/pc98/sound/opl3.c
@@ -34,11 +34,7 @@
* hooft@chem.ruu.nl
*/
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
#include <i386/isa/sound/sound_config.h>
-#endif
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_YM3812)
diff --git a/sys/pc98/pc98/sound/pas2_card.c b/sys/pc98/pc98/sound/pas2_card.c
deleted file mode 100644
index eeff8ae..0000000
--- a/sys/pc98/pc98/sound/pas2_card.c
+++ /dev/null
@@ -1,420 +0,0 @@
-#define _PAS2_CARD_C_
-/*
- * sound/pas2_card.c
- *
- * Detection routine for the Pro Audio Spectrum cards.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PAS)
-
-#define DEFINE_TRANSLATIONS
-#include <i386/isa/sound/pas.h>
-
-static int config_pas_hw __P((struct address_info *hw_config));
-static int detect_pas_hw __P((struct address_info *hw_config));
-static void pas2_msg __P((char *foo));
-
-/*
- * The Address Translation code is used to convert I/O register addresses to
- * be relative to the given base -register
- */
-
-int translat_code;
-static int pas_intr_mask = 0;
-static int pas_irq = 0;
-
-char pas_model;
-static char *pas_model_names[] =
-{"", "Pro AudioSpectrum+", "CDPC", "Pro AudioSpectrum 16", "Pro AudioSpectrum 16D"};
-
-extern void mix_write (unsigned char data, int ioaddr);
-/*
- * pas_read() and pas_write() are equivalents of INB() and OUTB()
- */
-/*
- * These routines perform the I/O address translation required
- */
-/*
- * to support other than the default base address
- */
-
-unsigned char
-pas_read (int ioaddr)
-{
- return INB (ioaddr ^ translat_code);
-}
-
-void
-pas_write (unsigned char data, int ioaddr)
-{
- OUTB (data, ioaddr ^ translat_code);
-}
-
-static void
-pas2_msg (char *foo)
-{
- printk (" PAS2: %s.\n", foo);
-}
-
-/******************* Begin of the Interrupt Handler ********************/
-
-void
-pasintr (INT_HANDLER_PARMS (irq, dummy))
-{
- int status;
-
- status = pas_read (INTERRUPT_STATUS);
- pas_write (status, INTERRUPT_STATUS); /*
- * Clear interrupt
- */
-
- if (status & I_S_PCM_SAMPLE_BUFFER_IRQ)
- {
-#ifndef EXCLUDE_AUDIO
- pas_pcm_interrupt (status, 1);
-#endif
- status &= ~I_S_PCM_SAMPLE_BUFFER_IRQ;
- }
- if (status & I_S_MIDI_IRQ)
- {
-#ifndef EXCLUDE_MIDI
-#ifdef EXCLUDE_PRO_MIDI
- pas_midi_interrupt ();
-#endif
-#endif
- status &= ~I_S_MIDI_IRQ;
- }
-
-}
-
-int
-pas_set_intr (int mask)
-{
- int err;
-
- if (!mask)
- return 0;
-
- if (!pas_intr_mask)
- {
- if ((err = snd_set_irq_handler (pas_irq, pasintr, "PAS16")) < 0)
- return err;
- }
- pas_intr_mask |= mask;
-
- pas_write (pas_intr_mask, INTERRUPT_MASK);
- return 0;
-}
-
-int
-pas_remove_intr (int mask)
-{
- if (!mask)
- return 0;
-
- pas_intr_mask &= ~mask;
- pas_write (pas_intr_mask, INTERRUPT_MASK);
-
- if (!pas_intr_mask)
- {
- snd_release_irq (pas_irq);
- }
- return 0;
-}
-
-/******************* End of the Interrupt handler **********************/
-
-/******************* Begin of the Initialization Code ******************/
-
-static int
-config_pas_hw (struct address_info *hw_config)
-{
- char ok = 1;
- unsigned int_ptrs; /* scsi/sound interrupt pointers */
-
- pas_irq = hw_config->irq;
-
- pas_write (0x00, INTERRUPT_MASK);
-
- pas_write (0x36, SAMPLE_COUNTER_CONTROL); /*
- * Local timer control *
- * register
- */
-
- pas_write (0x36, SAMPLE_RATE_TIMER); /*
- * Sample rate timer (16 bit)
- */
- pas_write (0, SAMPLE_RATE_TIMER);
-
- pas_write (0x74, SAMPLE_COUNTER_CONTROL); /*
- * Local timer control *
- * register
- */
-
- pas_write (0x74, SAMPLE_BUFFER_COUNTER); /*
- * Sample count register (16
- * * bit)
- */
- pas_write (0, SAMPLE_BUFFER_COUNTER);
-
- pas_write (F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER | F_F_MIXER_UNMUTE | 1, FILTER_FREQUENCY);
- pas_write (P_C_PCM_DMA_ENABLE | P_C_PCM_MONO | P_C_PCM_DAC_MODE | P_C_MIXER_CROSS_L_TO_L | P_C_MIXER_CROSS_R_TO_R, PCM_CONTROL);
- pas_write (S_M_PCM_RESET | S_M_FM_RESET | S_M_SB_RESET | S_M_MIXER_RESET /*
- * |
- * S_M_OPL3_DUAL_MONO
- */ , SERIAL_MIXER);
-
- pas_write (I_C_1_BOOT_RESET_ENABLE
-#ifdef PAS_JOYSTICK_ENABLE
- | I_C_1_JOYSTICK_ENABLE
-#endif
- ,IO_CONFIGURATION_1);
-
- if (pas_irq < 0 || pas_irq > 15)
- {
- printk ("PAS2: Invalid IRQ %d", pas_irq);
- ok = 0;
- }
- else
- {
- int_ptrs = pas_read (IO_CONFIGURATION_3);
- int_ptrs |= I_C_3_PCM_IRQ_translate[pas_irq] & 0xf;
- pas_write (int_ptrs, IO_CONFIGURATION_3);
- if (!I_C_3_PCM_IRQ_translate[pas_irq])
- {
- printk ("PAS2: Invalid IRQ %d", pas_irq);
- ok = 0;
- }
- }
-
- if (hw_config->dma < 0 || hw_config->dma > 7)
- {
- printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
- ok = 0;
- }
- else
- {
- pas_write (I_C_2_PCM_DMA_translate[hw_config->dma], IO_CONFIGURATION_2);
- if (!I_C_2_PCM_DMA_translate[hw_config->dma])
- {
- printk ("PAS2: Invalid DMA selection %d", hw_config->dma);
- ok = 0;
- }
- }
-
- /*
- * This fixes the timing problems of the PAS due to the Symphony chipset
- * as per Media Vision. Only define this if your PAS doesn't work correctly.
- */
-#ifdef SYMPHONY_PAS
- OUTB (0x05, 0xa8);
- OUTB (0x60, 0xa9);
-#endif
-
-#ifdef BROKEN_BUS_CLOCK
- pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND | S_C_1_FM_EMULATE_CLOCK, SYSTEM_CONFIGURATION_1);
-#else
- /*
- * pas_write(S_C_1_PCS_ENABLE, SYSTEM_CONFIGURATION_1);
- */
- pas_write (S_C_1_PCS_ENABLE | S_C_1_PCS_STEREO | S_C_1_PCS_REALSOUND, SYSTEM_CONFIGURATION_1);
-#endif
- pas_write (0x18, SYSTEM_CONFIGURATION_3); /*
- * ???
- */
-
- pas_write (F_F_MIXER_UNMUTE | 0x01, FILTER_FREQUENCY); /*
- * Sets mute
- * off and *
- * selects
- * filter
- * rate * of
- * 17.897 kHz
- */
-
- if (pas_model == PAS_16 || pas_model == PAS_16D)
- pas_write (8, PRESCALE_DIVIDER);
- else
- pas_write (0, PRESCALE_DIVIDER);
-
- mix_write (P_M_MV508_ADDRESS | 5, PARALLEL_MIXER);
- mix_write (5, PARALLEL_MIXER);
-
-#if !defined(EXCLUDE_SB_EMULATION) || !defined(EXCLUDE_SB)
-
- {
- struct address_info *sb_config;
-
- if ((sb_config = sound_getconf (SNDCARD_SB)))
- {
- unsigned char irq_dma;
-
- /*
- * Turn on Sound Blaster compatibility
- */
- /*
- * bit 1 = SB emulation
- */
- /*
- * bit 0 = MPU401 emulation (CDPC only :-( )
- */
- pas_write (0x02, COMPATIBILITY_ENABLE);
-
- /*
- * "Emulation address"
- */
- pas_write ((sb_config->io_base >> 4) & 0x0f, EMULATION_ADDRESS);
-
- if (!E_C_SB_DMA_translate[sb_config->dma])
- printk ("\n\nPAS16 Warning: Invalid SB DMA %d\n\n",
- sb_config->dma);
-
- if (!E_C_SB_IRQ_translate[sb_config->irq])
- printk ("\n\nPAS16 Warning: Invalid SB IRQ %d\n\n",
- sb_config->irq);
-
- irq_dma = E_C_SB_DMA_translate[sb_config->dma] |
- E_C_SB_IRQ_translate[sb_config->irq];
-
- pas_write (irq_dma, EMULATION_CONFIGURATION);
- }
- }
-#endif
-
- if (!ok)
- pas2_msg ("Driver not enabled");
-
- return ok;
-}
-
-static int
-detect_pas_hw (struct address_info *hw_config)
-{
- unsigned char board_id, foo;
-
- /*
- * WARNING: Setting an option like W:1 or so that disables warm boot reset
- * of the card will screw up this detect code something fierce. Adding code
- * to handle this means possibly interfering with other cards on the bus if
- * you have something on base port 0x388. SO be forewarned.
- */
-
- OUTB (0xBC, MASTER_DECODE); /*
- * Talk to first board
- */
- OUTB (hw_config->io_base >> 2, MASTER_DECODE); /*
- * Set base address
- */
- translat_code = PAS_DEFAULT_BASE ^ hw_config->io_base;
- pas_write (1, WAIT_STATE); /*
- * One wait-state
- */
-
- board_id = pas_read (INTERRUPT_MASK);
-
- if (board_id == 0xff)
- return 0;
-
- /*
- * We probably have a PAS-series board, now check for a PAS2-series board
- * by trying to change the board revision bits. PAS2-series hardware won't
- * let you do this - the bits are read-only.
- */
-
- foo = board_id ^ 0xe0;
-
- pas_write (foo, INTERRUPT_MASK);
- foo = INB (INTERRUPT_MASK);
- pas_write (board_id, INTERRUPT_MASK);
-
- if (board_id != foo) /*
- * Not a PAS2
- */
- return 0;
-
- pas_model = pas_read (CHIP_REV);
-
- return pas_model;
-}
-
-long
-attach_pas_card (long mem_start, struct address_info *hw_config)
-{
- pas_irq = hw_config->irq;
-
- if (detect_pas_hw (hw_config))
- {
-
- if (pas_model = pas_read (CHIP_REV))
- {
-#ifdef __FreeBSD__
- printk ("pas0: <%s rev %d>", pas_model_names[(int) pas_model], pas_read (BOARD_REV_ID));
-#else
- printk (" <%s rev %d>", pas_model_names[(int) pas_model], pas_read (BOARD_REV_ID));
-#endif
- }
-
- if (config_pas_hw (hw_config))
- {
-
-#ifndef EXCLUDE_AUDIO
- mem_start = pas_pcm_init (mem_start, hw_config);
-#endif
-
-#if !defined(EXCLUDE_SB_EMULATION) && !defined(EXCLUDE_SB)
-
- sb_dsp_disable_midi (); /*
- * The SB emulation don't support *
- * midi
- */
-#endif
-
-#ifndef EXCLUDE_YM3812
- enable_opl3_mode (0x388, 0x38a, 0);
-#endif
-
-#ifndef EXCLUDE_MIDI
-#ifdef EXCLUDE_PRO_MIDI
- mem_start = pas_midi_init (mem_start);
-#endif
-#endif
-
- pas_init_mixer ();
- }
- }
-
- return mem_start;
-}
-
-int
-probe_pas (struct address_info *hw_config)
-{
- return detect_pas_hw (hw_config);
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/pas2_midi.c b/sys/pc98/pc98/sound/pas2_midi.c
deleted file mode 100644
index a83158e..0000000
--- a/sys/pc98/pc98/sound/pas2_midi.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * sound/pas2_midi.c
- *
- * The low level driver for the PAS Midi Interface.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#ifdef CONFIGURE_SOUNDCARD
-
-#include <i386/isa/sound/pas.h>
-
-#if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_MIDI) && defined(EXCLUDE_PRO_MIDI)
-
-static int midi_busy = 0, input_opened = 0;
-static int my_dev;
-static volatile int ofifo_bytes = 0;
-
-static unsigned char tmp_queue[256];
-static volatile int qlen;
-static volatile unsigned char qhead, qtail;
-
-static void (*midi_input_intr) (int dev, unsigned char data);
-
-static int
-pas_midi_open (int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- int err;
- unsigned long flags;
- unsigned char ctrl;
-
-
- if (midi_busy)
- {
- printk ("PAS2: Midi busy\n");
- return RET_ERROR (EBUSY);
- }
-
- /*
- * Reset input and output FIFO pointers
- */
- pas_write (M_C_RESET_INPUT_FIFO | M_C_RESET_OUTPUT_FIFO,
- MIDI_CONTROL);
-
- DISABLE_INTR (flags);
-
- if ((err = pas_set_intr (I_M_MIDI_IRQ_ENABLE)) < 0)
- return err;
-
- /*
- * Enable input available and output FIFO empty interrupts
- */
-
- ctrl = 0;
- input_opened = 0;
- midi_input_intr = input;
-
- if (mode == OPEN_READ || mode == OPEN_READWRITE)
- {
- ctrl |= M_C_ENA_INPUT_IRQ; /*
- * Enable input
- */
- input_opened = 1;
- }
-
- if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
- {
- ctrl |= M_C_ENA_OUTPUT_IRQ | /*
- * Enable output
- */
- M_C_ENA_OUTPUT_HALF_IRQ;
- }
-
- pas_write (ctrl,
- MIDI_CONTROL);
-
- /*
- * Acknowledge any pending interrupts
- */
-
- pas_write (0xff, MIDI_STATUS);
- ofifo_bytes = 0;
-
- RESTORE_INTR (flags);
-
- midi_busy = 1;
- qlen = qhead = qtail = 0;
- return 0;
-}
-
-static void
-pas_midi_close (int dev)
-{
-
- /*
- * Reset FIFO pointers, disable intrs
- */
- pas_write (M_C_RESET_INPUT_FIFO | M_C_RESET_OUTPUT_FIFO, MIDI_CONTROL);
-
- pas_remove_intr (I_M_MIDI_IRQ_ENABLE);
- midi_busy = 0;
-}
-
-static int
-dump_to_midi (unsigned char midi_byte)
-{
- int fifo_space, x;
-
- fifo_space = ((x = pas_read (MIDI_FIFO_STATUS)) >> 4) & 0x0f;
-
- if (fifo_space == 15 || (fifo_space < 2 && ofifo_bytes > 13)) /*
- * Fifo
- * full
- */
- {
- return 0; /*
- * Upper layer will call again
- */
- }
-
- ofifo_bytes++;
-
- pas_write (midi_byte, MIDI_DATA);
-
- return 1;
-}
-
-static int
-pas_midi_out (int dev, unsigned char midi_byte)
-{
-
- unsigned long flags;
-
- /*
- * Drain the local queue first
- */
-
- DISABLE_INTR (flags);
-
- while (qlen && dump_to_midi (tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
-
- RESTORE_INTR (flags);
-
- /*
- * Output the byte if the local queue is empty.
- */
-
- if (!qlen)
- if (dump_to_midi (midi_byte))
- return 1; /*
- * OK
- */
-
- /*
- * Put to the local queue
- */
-
- if (qlen >= 256)
- return 0; /*
- * Local queue full
- */
-
- DISABLE_INTR (flags);
-
- tmp_queue[qtail] = midi_byte;
- qlen++;
- qtail++;
-
- RESTORE_INTR (flags);
-
- return 1;
-}
-
-static int
-pas_midi_start_read (int dev)
-{
- return 0;
-}
-
-static int
-pas_midi_end_read (int dev)
-{
- return 0;
-}
-
-static int
-pas_midi_ioctl (int dev, unsigned cmd, unsigned arg)
-{
- return RET_ERROR (EINVAL);
-}
-
-static void
-pas_midi_kick (int dev)
-{
- ofifo_bytes = 0;
-}
-
-static int
-pas_buffer_status (int dev)
-{
- return !qlen;
-}
-
-#define MIDI_SYNTH_NAME "Pro Audio Spectrum Midi"
-#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
-#include <i386/isa/sound/midi_synth.h>
-
-static struct midi_operations pas_midi_operations =
-{
- {"Pro Audio Spectrum", 0, 0, SNDCARD_PAS},
- &std_midi_synth,
- {0},
- pas_midi_open,
- pas_midi_close,
- pas_midi_ioctl,
- pas_midi_out,
- pas_midi_start_read,
- pas_midi_end_read,
- pas_midi_kick,
- NULL, /*
- * command
- */
- pas_buffer_status,
- NULL
-};
-
-long
-pas_midi_init (long mem_start)
-{
- if (num_midis >= MAX_MIDI_DEV)
- {
- printk ("Sound: Too many midi devices detected\n");
- return mem_start;
- }
-
- std_midi_synth.midi_dev = my_dev = num_midis;
- midi_devs[num_midis++] = &pas_midi_operations;
- return mem_start;
-}
-
-void
-pas_midi_interrupt (void)
-{
- unsigned char stat;
- int i, incount;
- unsigned long flags;
-
- stat = pas_read (MIDI_STATUS);
-
- if (stat & M_S_INPUT_AVAIL) /*
- * Input byte available
- */
- {
- incount = pas_read (MIDI_FIFO_STATUS) & 0x0f; /*
- * Input FIFO count
- */
- if (!incount)
- incount = 16;
-
- for (i = 0; i < incount; i++)
- if (input_opened)
- {
- midi_input_intr (my_dev, pas_read (MIDI_DATA));
- }
- else
- pas_read (MIDI_DATA); /*
- * Flush
- */
- }
-
- if (stat & (M_S_OUTPUT_EMPTY | M_S_OUTPUT_HALF_EMPTY))
- {
- if (!(stat & M_S_OUTPUT_EMPTY))
- {
- ofifo_bytes = 8;
- }
- else
- {
- ofifo_bytes = 0;
- }
-
- DISABLE_INTR (flags);
-
- while (qlen && dump_to_midi (tmp_queue[qhead]))
- {
- qlen--;
- qhead++;
- }
-
- RESTORE_INTR (flags);
- }
-
-#if 0
- if (stat & M_S_FRAMING_ERROR)
- printk ("MIDI framing error\n");
-#endif
-
- if (stat & M_S_OUTPUT_OVERRUN)
- {
- printk ("MIDI output overrun %x,%x,%d \n", pas_read (MIDI_FIFO_STATUS), stat, ofifo_bytes);
- ofifo_bytes = 100;
- }
-
- pas_write (stat, MIDI_STATUS); /*
- * Acknowledge interrupts
- */
-}
-
-#endif
-
-#endif
diff --git a/sys/pc98/pc98/sound/pas2_mixer.c b/sys/pc98/pc98/sound/pas2_mixer.c
deleted file mode 100644
index c1ba76b..0000000
--- a/sys/pc98/pc98/sound/pas2_mixer.c
+++ /dev/null
@@ -1,340 +0,0 @@
-#define _PAS2_MIXER_C_
-
-/*
- * sound/pas2_mixer.c
- *
- * Mixer routines for the Pro Audio Spectrum cards.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PAS)
-
-#include <i386/isa/sound/pas.h>
-
-extern void mix_write __P((unsigned char data, int ioaddr));
-static int pas_mixer_ioctl __P((int dev, unsigned int cmd, unsigned int arg));
-static void set_mode __P((int new_mode));
-
-#define TRACE(what) /* (what) */
-
-extern int translat_code;
-extern char pas_model;
-
-static int rec_devices = (SOUND_MASK_MIC); /* Default recording source */
-static int mode_control = 0;
-
-#define POSSIBLE_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
- SOUND_MASK_CD | SOUND_MASK_ALTPCM)
-
-#define SUPPORTED_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
- SOUND_MASK_CD | SOUND_MASK_ALTPCM | SOUND_MASK_IMIX | \
- SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_RECLEV | \
- SOUND_MASK_MUTE | SOUND_MASK_ENHANCE | SOUND_MASK_LOUD)
-
-static unsigned short levels[SOUND_MIXER_NRDEVICES] =
-{
- 0x3232, /* Master Volume */
- 0x3232, /* Bass */
- 0x3232, /* Treble */
- 0x5050, /* FM */
- 0x4b4b, /* PCM */
- 0x3232, /* PC Speaker */
- 0x4b4b, /* Ext Line */
- 0x4b4b, /* Mic */
- 0x4b4b, /* CD */
- 0x6464, /* Recording monitor */
- 0x4b4b, /* SB PCM */
- 0x6464 /* Recording level */
-};
-
-void
-mix_write (unsigned char data, int ioaddr)
-{
- /*
- * The Revision D cards have a problem with their MVA508 interface. The
- * kludge-o-rama fix is to make a 16-bit quantity with identical LSB and
- * MSBs out of the output byte and to do a 16-bit out to the mixer port -
- * 1. We need to do this because it isn't timing problem but chip access
- * sequence problem.
- */
-
- if (pas_model == PAS_16D)
- {
- OUTW (data | (data << 8), (ioaddr ^ translat_code) - 1);
- OUTB (0x80, 0);
- }
- else
- pas_write (data, ioaddr);
-}
-
-static int
-mixer_output (int right_vol, int left_vol, int div, int bits,
- int mixer) /* Input or output mixer */
-{
- int left = left_vol * div / 100;
- int right = right_vol * div / 100;
-
-
- if (bits & P_M_MV508_MIXER)
- { /*
- * Select input or output mixer
- */
- left |= mixer;
- right |= mixer;
- }
-
- if (bits == P_M_MV508_BASS || bits == P_M_MV508_TREBLE)
- { /*
- * Bass and treble are mono devices
- */
- mix_write (P_M_MV508_ADDRESS | bits, PARALLEL_MIXER);
- mix_write (left, PARALLEL_MIXER);
- right_vol = left_vol;
- }
- else
- {
- mix_write (P_M_MV508_ADDRESS | P_M_MV508_LEFT | bits, PARALLEL_MIXER);
- mix_write (left, PARALLEL_MIXER);
- mix_write (P_M_MV508_ADDRESS | P_M_MV508_RIGHT | bits, PARALLEL_MIXER);
- mix_write (right, PARALLEL_MIXER);
- }
-
- return (left_vol | (right_vol << 8));
-}
-
-static void
-set_mode (int new_mode)
-{
- mix_write (P_M_MV508_ADDRESS | P_M_MV508_MODE, PARALLEL_MIXER);
- mix_write (new_mode, PARALLEL_MIXER);
-
- mode_control = new_mode;
-}
-
-static int
-pas_mixer_set (int whichDev, unsigned int level)
-{
- int left, right, devmask, changed, i, mixer = 0;
-
- TRACE (printk ("static int pas_mixer_set(int whichDev = %d, unsigned int level = %X)\n", whichDev, level));
-
- left = level & 0x7f;
- right = (level & 0x7f00) >> 8;
-
- if (whichDev < SOUND_MIXER_NRDEVICES)
- if ((1 << whichDev) & rec_devices)
- mixer = P_M_MV508_INPUTMIX;
- else
- mixer = P_M_MV508_OUTPUTMIX;
-
- switch (whichDev)
- {
- case SOUND_MIXER_VOLUME: /* Master volume (0-63) */
- levels[whichDev] = mixer_output (right, left, 63, P_M_MV508_MASTER_A, 0);
- break;
-
- /*
- * Note! Bass and Treble are mono devices. Will use just the left
- * channel.
- */
- case SOUND_MIXER_BASS: /* Bass (0-12) */
- levels[whichDev] = mixer_output (right, left, 12, P_M_MV508_BASS, 0);
- break;
- case SOUND_MIXER_TREBLE: /* Treble (0-12) */
- levels[whichDev] = mixer_output (right, left, 12, P_M_MV508_TREBLE, 0);
- break;
-
- case SOUND_MIXER_SYNTH: /* Internal synthesizer (0-31) */
- levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_FM, mixer);
- break;
- case SOUND_MIXER_PCM: /* PAS PCM (0-31) */
- levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_PCM, mixer);
- break;
- case SOUND_MIXER_ALTPCM: /* SB PCM (0-31) */
- levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_SB, mixer);
- break;
- case SOUND_MIXER_SPEAKER: /* PC speaker (0-31) */
- levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_SPEAKER, mixer);
- break;
- case SOUND_MIXER_LINE: /* External line (0-31) */
- levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_LINE, mixer);
- break;
- case SOUND_MIXER_CD: /* CD (0-31) */
- levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_CDROM, mixer);
- break;
- case SOUND_MIXER_MIC: /* External microphone (0-31) */
- levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_MIC, mixer);
- break;
- case SOUND_MIXER_IMIX: /* Recording monitor (0-31) (Output mixer only) */
- levels[whichDev] = mixer_output (right, left, 31, P_M_MV508_MIXER | P_M_MV508_IMIXER,
- P_M_MV508_OUTPUTMIX);
- break;
- case SOUND_MIXER_RECLEV: /* Recording level (0-15) */
- levels[whichDev] = mixer_output (right, left, 15, P_M_MV508_MASTER_B, 0);
- break;
-
- case SOUND_MIXER_MUTE:
- return 0;
- break;
-
- case SOUND_MIXER_ENHANCE:
- i = 0;
- level &= 0x7f;
- if (level)
- i = (level / 20) - 1;
-
- mode_control &= ~P_M_MV508_ENHANCE_BITS;
- mode_control |= P_M_MV508_ENHANCE_BITS;
- set_mode (mode_control);
-
- if (i)
- i = (i + 1) * 20;
- return i;
- break;
-
- case SOUND_MIXER_LOUD:
- mode_control &= ~P_M_MV508_LOUDNESS;
- if (level)
- mode_control |= P_M_MV508_LOUDNESS;
- set_mode (mode_control);
- return !!level; /* 0 or 1 */
- break;
-
- case SOUND_MIXER_RECSRC:
- devmask = level & POSSIBLE_RECORDING_DEVICES;
-
- changed = devmask ^ rec_devices;
- rec_devices = devmask;
-
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- if (changed & (1 << i))
- {
- pas_mixer_set (i, levels[i]);
- }
- return rec_devices;
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
-
- return (levels[whichDev]);
-}
-
-/*****/
-
-static void
-pas_mixer_reset (void)
-{
- int foo;
-
- TRACE (printk ("pas2_mixer.c: void pas_mixer_reset(void)\n"));
-
- for (foo = 0; foo < SOUND_MIXER_NRDEVICES; foo++)
- pas_mixer_set (foo, levels[foo]);
-
- set_mode (P_M_MV508_LOUDNESS | P_M_MV508_ENHANCE_40);
-}
-
-int
-pas_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
-{
- TRACE (printk ("pas2_mixer.c: int pas_mixer_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
-
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (cmd & IOC_IN)
- return IOCTL_OUT (arg, pas_mixer_set (cmd & 0xff, IOCTL_IN (arg)));
- else
- { /*
- * Read parameters
- */
-
- switch (cmd & 0xff)
- {
-
- case SOUND_MIXER_RECSRC:
- return IOCTL_OUT (arg, rec_devices);
- break;
-
- case SOUND_MIXER_STEREODEVS:
- return IOCTL_OUT (arg, SUPPORTED_MIXER_DEVICES & ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE));
- break;
-
- case SOUND_MIXER_DEVMASK:
- return IOCTL_OUT (arg, SUPPORTED_MIXER_DEVICES);
- break;
-
- case SOUND_MIXER_RECMASK:
- return IOCTL_OUT (arg, POSSIBLE_RECORDING_DEVICES & SUPPORTED_MIXER_DEVICES);
- break;
-
- case SOUND_MIXER_CAPS:
- return IOCTL_OUT (arg, 0); /* No special capabilities */
- break;
-
- case SOUND_MIXER_MUTE:
- return IOCTL_OUT (arg, 0); /* No mute yet */
- break;
-
- case SOUND_MIXER_ENHANCE:
- if (!(mode_control & P_M_MV508_ENHANCE_BITS))
- return IOCTL_OUT (arg, 0);
- return IOCTL_OUT (arg, ((mode_control & P_M_MV508_ENHANCE_BITS) + 1) * 20);
- break;
-
- case SOUND_MIXER_LOUD:
- if (mode_control & P_M_MV508_LOUDNESS)
- return IOCTL_OUT (arg, 1);
- return IOCTL_OUT (arg, 0);
- break;
-
- default:
- return IOCTL_OUT (arg, levels[cmd & 0xff]);
- }
- }
- }
- return RET_ERROR (EINVAL);
-}
-
-static struct mixer_operations pas_mixer_operations =
-{
- "Pro Audio Spectrum 16",
- pas_mixer_ioctl
-};
-
-int
-pas_init_mixer (void)
-{
- pas_mixer_reset ();
-
- if (num_mixers < MAX_MIXER_DEV)
- mixer_devs[num_mixers++] = &pas_mixer_operations;
- return 1;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/patmgr.c b/sys/pc98/pc98/sound/patmgr.c
deleted file mode 100644
index 9053415..0000000
--- a/sys/pc98/pc98/sound/patmgr.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * sound/patmgr.c
- *
- * The patch maneger interface for the /dev/sequencer
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#define PATMGR_C
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SEQUENCER)
-
-DEFINE_WAIT_QUEUES (server_procs[MAX_SYNTH_DEV],
- server_wait_flag[MAX_SYNTH_DEV]);
-
-static struct patmgr_info *mbox[MAX_SYNTH_DEV] =
-{NULL};
-static volatile int msg_direction[MAX_SYNTH_DEV] =
-{0};
-
-static int pmgr_opened[MAX_SYNTH_DEV] =
-{0};
-
-#define A_TO_S 1
-#define S_TO_A 2
-
-DEFINE_WAIT_QUEUE (appl_proc, appl_wait_flag);
-
-int
-pmgr_open (int dev)
-{
- if (dev < 0 || dev >= num_synths)
- return RET_ERROR (ENXIO);
-
- if (pmgr_opened[dev])
- return RET_ERROR (EBUSY);
- pmgr_opened[dev] = 1;
-
- RESET_WAIT_QUEUE (server_procs[dev], server_wait_flag[dev]);
-
- return 0;
-}
-
-void
-pmgr_release (int dev)
-{
-
- if (mbox[dev]) /*
- * Killed in action. Inform the client
- */
- {
-
- mbox[dev]->key = PM_ERROR;
- mbox[dev]->parm1 = RET_ERROR (EIO);
-
- if (SOMEONE_WAITING (appl_proc, appl_wait_flag))
- WAKE_UP (appl_proc, appl_wait_flag);
- }
-
- pmgr_opened[dev] = 0;
-}
-
-int
-pmgr_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- unsigned long flags;
- int ok = 0;
-
- if (count != sizeof (struct patmgr_info))
- {
- printk ("PATMGR%d: Invalid read count\n", dev);
- return RET_ERROR (EIO);
- }
-
- while (!ok && !PROCESS_ABORTING (server_procs[dev], server_wait_flag[dev]))
- {
- DISABLE_INTR (flags);
-
- while (!(mbox[dev] && msg_direction[dev] == A_TO_S) &&
- !PROCESS_ABORTING (server_procs[dev], server_wait_flag[dev]))
- {
- DO_SLEEP (server_procs[dev], server_wait_flag[dev], 0);
- }
-
- if (mbox[dev] && msg_direction[dev] == A_TO_S)
- {
- COPY_TO_USER (buf, 0, (char *) mbox[dev], count);
- msg_direction[dev] = 0;
- ok = 1;
- }
-
- RESTORE_INTR (flags);
-
- }
-
- if (!ok)
- return RET_ERROR (EINTR);
- return count;
-}
-
-int
-pmgr_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- unsigned long flags;
-
- if (count < 4)
- {
- printk ("PATMGR%d: Write count < 4\n", dev);
- return RET_ERROR (EIO);
- }
-
- COPY_FROM_USER (mbox[dev], buf, 0, 4);
-
- if (*(unsigned char *) mbox[dev] == SEQ_FULLSIZE)
- {
- int tmp_dev;
-
- tmp_dev = ((unsigned short *) mbox[dev])[2];
- if (tmp_dev != dev)
- return RET_ERROR (ENXIO);
-
- return synth_devs[dev]->load_patch (dev, *(unsigned short *) mbox[dev],
- buf, 4, count, 1);
- }
-
- if (count != sizeof (struct patmgr_info))
- {
- printk ("PATMGR%d: Invalid write count\n", dev);
- return RET_ERROR (EIO);
- }
-
- /*
- * If everything went OK, there should be a preallocated buffer in the
- * mailbox and a client waiting.
- */
-
- DISABLE_INTR (flags);
-
- if (mbox[dev] && !msg_direction[dev])
- {
- COPY_FROM_USER (&((char *) mbox[dev])[4], buf, 4, count - 4);
- msg_direction[dev] = S_TO_A;
-
- if (SOMEONE_WAITING (appl_proc, appl_wait_flag))
- {
- WAKE_UP (appl_proc, appl_wait_flag);
- }
- }
-
- RESTORE_INTR (flags);
-
- return count;
-}
-
-int
-pmgr_access (int dev, struct patmgr_info *rec)
-{
- unsigned long flags;
- int err = 0;
-
- DISABLE_INTR (flags);
-
- if (mbox[dev])
- printk (" PATMGR: Server %d mbox full. Why?\n", dev);
- else
- {
- rec->key = PM_K_COMMAND;
- mbox[dev] = rec;
- msg_direction[dev] = A_TO_S;
-
- if (SOMEONE_WAITING (server_procs[dev], server_wait_flag[dev]))
- {
- WAKE_UP (server_procs[dev], server_wait_flag[dev]);
- }
-
- DO_SLEEP (appl_proc, appl_wait_flag, 0);
-
- if (msg_direction[dev] != S_TO_A)
- {
- rec->key = PM_ERROR;
- rec->parm1 = RET_ERROR (EIO);
- }
- else if (rec->key == PM_ERROR)
- {
- err = rec->parm1;
- if (err > 0)
- err = -err;
- }
-
- mbox[dev] = NULL;
- msg_direction[dev] = 0;
- }
-
- RESTORE_INTR (flags);
-
- return err;
-}
-
-int
-pmgr_inform (int dev, int event, unsigned long p1, unsigned long p2,
- unsigned long p3, unsigned long p4)
-{
- unsigned long flags;
- int err = 0;
-
- if (!pmgr_opened[dev])
- return 0;
-
- DISABLE_INTR (flags);
-
- if (mbox[dev])
- printk (" PATMGR: Server %d mbox full. Why?\n", dev);
- else
- {
- if ((mbox[dev] =
- (struct patmgr_info *) KERNEL_MALLOC (sizeof (struct patmgr_info))) == NULL)
- {
- printk ("pmgr: Couldn't allocate memory for a message\n");
- return 0;
- }
-
- mbox[dev]->key = PM_K_EVENT;
- mbox[dev]->command = event;
- mbox[dev]->parm1 = p1;
- mbox[dev]->parm2 = p2;
- mbox[dev]->parm3 = p3;
- msg_direction[dev] = A_TO_S;
-
- if (SOMEONE_WAITING (server_procs[dev], server_wait_flag[dev]))
- {
- WAKE_UP (server_procs[dev], server_wait_flag[dev]);
- }
-
- DO_SLEEP (appl_proc, appl_wait_flag, 0);
- if (mbox[dev])
- KERNEL_FREE (mbox[dev]);
- mbox[dev] = NULL;
- msg_direction[dev] = 0;
- }
-
- RESTORE_INTR (flags);
-
- return err;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/pcm86.c b/sys/pc98/pc98/sound/pcm86.c
index 974bafe..40c7c25 100644
--- a/sys/pc98/pc98/sound/pcm86.c
+++ b/sys/pc98/pc98/sound/pcm86.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pcm86.c,v 2.4 1996/01/24 19:53:34 abtk Exp $
+ * $Id: pcm86.c,v 1.2 1996/09/12 11:11:16 asami Exp $
*/
/*
@@ -36,7 +36,7 @@
*/
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
#ifdef CONFIGURE_SOUNDCARD
diff --git a/sys/pc98/pc98/sound/sb16_dsp.c b/sys/pc98/pc98/sound/sb16_dsp.c
index a195dba..5e84e67 100644
--- a/sys/pc98/pc98/sound/sb16_dsp.c
+++ b/sys/pc98/pc98/sound/sb16_dsp.c
@@ -34,11 +34,7 @@
/*
* #define DEB_DMARES
*/
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
#include <i386/isa/sound/sound_config.h>
-#endif
#include <i386/isa/sound/sb.h>
#include <i386/isa/sound/sb_mixer.h>
diff --git a/sys/pc98/pc98/sound/sb16_midi.c b/sys/pc98/pc98/sound/sb16_midi.c
index 6cd70f6..7dae750 100644
--- a/sys/pc98/pc98/sound/sb16_midi.c
+++ b/sys/pc98/pc98/sound/sb16_midi.c
@@ -27,11 +27,7 @@
*
*/
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
#include <i386/isa/sound/sound_config.h>
-#endif
#ifdef CONFIGURE_SOUNDCARD
diff --git a/sys/pc98/pc98/sound/sb_card.c b/sys/pc98/pc98/sound/sb_card.c
deleted file mode 100644
index 6656df7..0000000
--- a/sys/pc98/pc98/sound/sb_card.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * sound/sb_card.c
- *
- * Detection routine for the SoundBlaster cards.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * Modified:
- * Riccardo Facchetti 24 Mar 1995
- * - Added the Audio Excel DSP 16 initialization routine.
- */
-
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
-
-long
-attach_sb_card (long mem_start, struct address_info *hw_config)
-{
-#if !defined(EXCLUDE_AUDIO) || !defined(EXCLUDE_MIDI)
- if (!sb_dsp_detect (hw_config))
- return mem_start;
- mem_start = sb_dsp_init (mem_start, hw_config);
-#endif
-
- return mem_start;
-}
-
-int
-probe_sb (struct address_info *hw_config)
-{
-#if !defined(EXCLUDE_AEDSP16) && defined(AEDSP16_SBPRO)
- /*
- * Initialize Audio Excel DSP 16 to SBPRO.
- */
- InitAEDSP16_SBPRO (hw_config);
-#endif
- return sb_dsp_detect (hw_config);
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/sb_dsp.c b/sys/pc98/pc98/sound/sb_dsp.c
index f8922c9..82a2178 100644
--- a/sys/pc98/pc98/sound/sb_dsp.c
+++ b/sys/pc98/pc98/sound/sb_dsp.c
@@ -33,11 +33,7 @@
* Code added for MV ProSonic/Jazz 16 in 16 bit mode
*/
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
#include <i386/isa/sound/sound_config.h>
-#endif
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
diff --git a/sys/pc98/pc98/sound/sb_midi.c b/sys/pc98/pc98/sound/sb_midi.c
deleted file mode 100644
index 0c63af5..0000000
--- a/sys/pc98/pc98/sound/sb_midi.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * sound/sb_dsp.c
- *
- * The low level driver for the SoundBlaster DS chips.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_MIDI)
-
-#include <i386/isa/sound/sb.h>
-#undef SB_TEST_IRQ
-
-/*
- * The DSP channel can be used either for input or output. Variable
- * 'sb_irq_mode' will be set when the program calls read or write first time
- * after open. Current version doesn't support mode changes without closing
- * and reopening the device. Support for this feature may be implemented in a
- * future version of this driver.
- */
-
-extern int sb_dsp_ok; /* Set to 1 atfer successful initialization */
-extern int sbc_base;
-
-extern int sb_midi_mode;
-extern int sb_midi_busy; /*
-
-
- * * * * 1 if the process has output to MIDI
- *
- */
-extern int sb_dsp_busy;
-extern int sb_dsp_highspeed;
-
-extern volatile int sb_irq_mode;
-extern int sb_duplex_midi;
-extern int sb_intr_active;
-static int input_opened = 0;
-static int my_dev;
-
-void (*midi_input_intr) (int dev, unsigned char data);
-
-static int
-sb_midi_open (int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- int ret;
-
- if (!sb_dsp_ok)
- {
- printk ("SB Error: MIDI hardware not installed\n");
- return RET_ERROR (ENXIO);
- }
-
- if (sb_midi_busy)
- return RET_ERROR (EBUSY);
-
- if (mode != OPEN_WRITE && !sb_duplex_midi)
- {
- if (num_midis == 1)
- printk ("SoundBlaster: Midi input not currently supported\n");
- return RET_ERROR (EPERM);
- }
-
- sb_midi_mode = NORMAL_MIDI;
- if (mode != OPEN_WRITE)
- {
- if (sb_dsp_busy || sb_intr_active)
- return RET_ERROR (EBUSY);
- sb_midi_mode = UART_MIDI;
- }
-
- if (sb_dsp_highspeed)
- {
- printk ("SB Error: Midi output not possible during stereo or high speed audio\n");
- return RET_ERROR (EBUSY);
- }
-
- if (sb_midi_mode == UART_MIDI)
- {
- sb_irq_mode = IMODE_MIDI;
-
- sb_reset_dsp ();
-
- if (!sb_dsp_command (0x35))
- return RET_ERROR (EIO); /*
- * Enter the UART mode
- */
- sb_intr_active = 1;
-
- if ((ret = sb_get_irq ()) < 0)
- {
- sb_reset_dsp ();
- return 0; /*
- * IRQ not free
- */
- }
- input_opened = 1;
- midi_input_intr = input;
- }
-
- sb_midi_busy = 1;
-
- return 0;
-}
-
-static void
-sb_midi_close (int dev)
-{
- if (sb_midi_mode == UART_MIDI)
- {
- sb_reset_dsp (); /*
- * The only way to kill the UART mode
- */
- sb_free_irq ();
- }
- sb_intr_active = 0;
- sb_midi_busy = 0;
- input_opened = 0;
-}
-
-static int
-sb_midi_out (int dev, unsigned char midi_byte)
-{
- unsigned long flags;
-
- if (sb_midi_mode == NORMAL_MIDI)
- {
- DISABLE_INTR (flags);
- if (sb_dsp_command (0x38))
- sb_dsp_command (midi_byte);
- else
- printk ("SB Error: Unable to send a MIDI byte\n");
- RESTORE_INTR (flags);
- }
- else
- sb_dsp_command (midi_byte); /*
- * UART write
- */
-
- return 1;
-}
-
-static int
-sb_midi_start_read (int dev)
-{
- if (sb_midi_mode != UART_MIDI)
- {
- printk ("SoundBlaster: MIDI input not implemented.\n");
- return RET_ERROR (EPERM);
- }
- return 0;
-}
-
-static int
-sb_midi_end_read (int dev)
-{
- if (sb_midi_mode == UART_MIDI)
- {
- sb_reset_dsp ();
- sb_intr_active = 0;
- }
- return 0;
-}
-
-static int
-sb_midi_ioctl (int dev, unsigned cmd, unsigned arg)
-{
- return RET_ERROR (EPERM);
-}
-
-void
-sb_midi_interrupt (int dummy)
-{
- unsigned long flags;
- unsigned char data;
-
- DISABLE_INTR (flags);
-
- data = INB (DSP_READ);
- if (input_opened)
- midi_input_intr (my_dev, data);
-
- RESTORE_INTR (flags);
-}
-
-#define MIDI_SYNTH_NAME "SoundBlaster Midi"
-#define MIDI_SYNTH_CAPS 0
-#include <i386/isa/sound/midi_synth.h>
-
-static struct midi_operations sb_midi_operations =
-{
- {"SoundBlaster", 0, 0, SNDCARD_SB},
- &std_midi_synth,
- {0},
- sb_midi_open,
- sb_midi_close,
- sb_midi_ioctl,
- sb_midi_out,
- sb_midi_start_read,
- sb_midi_end_read,
- NULL, /*
- * Kick
- */
- NULL, /*
- * command
- */
- NULL, /*
- * buffer_status
- */
- NULL
-};
-
-void
-sb_midi_init (int model)
-{
- if (num_midis >= MAX_MIDI_DEV)
- {
- printk ("Sound: Too many midi devices detected\n");
- return;
- }
-
- std_midi_synth.midi_dev = num_midis;
- my_dev = num_midis;
- midi_devs[num_midis++] = &sb_midi_operations;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/sb_mixer.c b/sys/pc98/pc98/sound/sb_mixer.c
deleted file mode 100644
index b044412..0000000
--- a/sys/pc98/pc98/sound/sb_mixer.c
+++ /dev/null
@@ -1,591 +0,0 @@
-
-/*
- * sound/sb_mixer.c
- *
- * The low level mixer driver for the SoundBlaster Pro and SB16 cards.
- *
- * Copyright by Hannu Savolainen 1994
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * Modified:
- * Hunyue Yau Jan 6 1994
- * Added code to support the Sound Galaxy NX Pro mixer.
- *
- */
-
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_SBPRO)
-#define __SB_MIXER_C__
-
-#include <i386/isa/sound/sb.h>
-#include <i386/isa/sound/sb_mixer.h>
-#undef SB_TEST_IRQ
-
-extern int sbc_base;
-extern int sbc_major;
-extern int Jazz16_detected;
-
-static int mixer_initialized = 0;
-
-static int supported_rec_devices;
-static int supported_devices;
-static int recmask = 0;
-static int mixer_model;
-static int mixer_caps;
-static mixer_tab *iomap;
-
-void
-sb_setmixer (unsigned int port, unsigned int value)
-{
- unsigned long flags;
-
- DISABLE_INTR (flags);
- OUTB ((unsigned char) (port & 0xff), MIXER_ADDR); /*
- * Select register
- */
- tenmicrosec ();
- OUTB ((unsigned char) (value & 0xff), MIXER_DATA);
- tenmicrosec ();
- RESTORE_INTR (flags);
-}
-
-int
-sb_getmixer (unsigned int port)
-{
- int val;
- unsigned long flags;
-
- DISABLE_INTR (flags);
- OUTB ((unsigned char) (port & 0xff), MIXER_ADDR); /*
- * Select register
- */
- tenmicrosec ();
- val = INB (MIXER_DATA);
- tenmicrosec ();
- RESTORE_INTR (flags);
-
- return val;
-}
-
-void
-sb_mixer_set_stereo (int mode)
-{
- if (!mixer_initialized)
- return;
-
- sb_setmixer (OUT_FILTER, ((sb_getmixer (OUT_FILTER) & ~STEREO_DAC)
- | (mode ? STEREO_DAC : MONO_DAC)));
-}
-
-/*
- * Returns:
- * 0 No mixer detected.
- * 1 Only a plain Sound Blaster Pro style mixer detected.
- * 2 The Sound Galaxy NX Pro mixer detected.
- */
-static int
-detect_mixer (void)
-{
-#ifdef __SGNXPRO__
- int oldbass, oldtreble;
-
-#endif
- int retcode = 1;
-
- /*
- * Detect the mixer by changing parameters of two volume channels. If the
- * values read back match with the values written, the mixer is there (is
- * it?)
- */
- sb_setmixer (FM_VOL, 0xff);
- sb_setmixer (VOC_VOL, 0x33);
-
- if (sb_getmixer (FM_VOL) != 0xff)
- return 0; /*
- * No match
- */
- if (sb_getmixer (VOC_VOL) != 0x33)
- return 0;
-
-#ifdef __SGNXPRO__
- /* Attempt to detect the SG NX Pro by check for valid bass/treble
- * registers.
- */
- oldbass = sb_getmixer (BASS_LVL);
- oldtreble = sb_getmixer (TREBLE_LVL);
-
- sb_setmixer (BASS_LVL, 0xaa);
- sb_setmixer (TREBLE_LVL, 0x55);
-
- if ((sb_getmixer (BASS_LVL) != 0xaa) ||
- (sb_getmixer (TREBLE_LVL) != 0x55))
- {
- retcode = 1; /* 1 == Only SB Pro detected */
- }
- else
- retcode = 2; /* 2 == SG NX Pro detected */
- /* Restore register in either case since SG NX Pro has EEPROM with
- * 'preferred' values stored.
- */
- sb_setmixer (BASS_LVL, oldbass);
- sb_setmixer (TREBLE_LVL, oldtreble);
-
- /*
- * If the SB version is 3.X (SB Pro), assume we have a SG NX Pro 16.
- * In this case it's good idea to disable the Disney Sound Source
- * compatibility mode. It's useless and just causes noise every time the
- * LPT-port is accessed.
- *
- * Also place the card into WSS mode.
- */
- if (sbc_major == 3)
- {
- OUTB (0x01, sbc_base + 0x1c);
- OUTB (0x00, sbc_base + 0x1a);
- }
-
-#endif
- return retcode;
-}
-
-static void
-change_bits (unsigned char *regval, int dev, int chn, int newval)
-{
- unsigned char mask;
- int shift;
-
- mask = (1 << (*iomap)[dev][chn].nbits) - 1;
- newval = (int) ((newval * mask) + 50) / 100; /*
- * Scale it
- */
-
- shift = (*iomap)[dev][chn].bitoffs - (*iomap)[dev][LEFT_CHN].nbits + 1;
-
- *regval &= ~(mask << shift); /*
- * Filter out the previous value
- */
- *regval |= (newval & mask) << shift; /*
- * Set the new value
- */
-}
-
-static int
-sb_mixer_get (int dev)
-{
- if (!((1 << dev) & supported_devices))
- return RET_ERROR (EINVAL);
-
- return levels[dev];
-}
-
-#ifdef JAZZ16
-static char smw_mix_regs[] = /* Left mixer registers */
-{
- 0x0b, /* SOUND_MIXER_VOLUME */
- 0x0d, /* SOUND_MIXER_BASS */
- 0x0d, /* SOUND_MIXER_TREBLE */
- 0x05, /* SOUND_MIXER_SYNTH */
- 0x09, /* SOUND_MIXER_PCM */
- 0x00, /* SOUND_MIXER_SPEAKER */
- 0x03, /* SOUND_MIXER_LINE */
- 0x01, /* SOUND_MIXER_MIC */
- 0x07, /* SOUND_MIXER_CD */
- 0x00, /* SOUND_MIXER_IMIX */
- 0x00, /* SOUND_MIXER_ALTPCM */
- 0x00, /* SOUND_MIXER_RECLEV */
- 0x00, /* SOUND_MIXER_IGAIN */
- 0x00, /* SOUND_MIXER_OGAIN */
- 0x00, /* SOUND_MIXER_LINE1 */
- 0x00, /* SOUND_MIXER_LINE2 */
- 0x00 /* SOUND_MIXER_LINE3 */
-};
-
-static void
-smw_mixer_init (void)
-{
- int i;
-
- sb_setmixer (0x00, 0x18); /* Mute unused (Telephone) line */
- sb_setmixer (0x10, 0x38); /* Config register 2 */
-
- supported_devices = 0;
- for (i = 0; i < sizeof (smw_mix_regs); i++)
- if (smw_mix_regs[i] != 0)
- supported_devices |= (1 << i);
-
- supported_rec_devices = supported_devices &
- ~(SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_PCM |
- SOUND_MASK_VOLUME);
-}
-
-static int
-smw_mixer_set (int dev, int value)
-{
- int left = value & 0x000000ff;
- int right = (value & 0x0000ff00) >> 8;
- int reg, val;
-
- if (left > 100)
- left = 100;
- if (right > 100)
- right = 100;
-
- if (dev > 31)
- return RET_ERROR (EINVAL);
-
- if (!(supported_devices & (1 << dev))) /* Not supported */
- return RET_ERROR (EINVAL);
-
- switch (dev)
- {
- case SOUND_MIXER_VOLUME:
- sb_setmixer (0x0b, 96 - (96 * left / 100)); /* 96=mute, 0=max */
- sb_setmixer (0x0c, 96 - (96 * right / 100));
- break;
-
- case SOUND_MIXER_BASS:
- case SOUND_MIXER_TREBLE:
- levels[dev] = left | (right << 8);
-
- /* Set left bass and treble values */
- val = ((levels[SOUND_MIXER_TREBLE] & 0xff) * 16 / 100) << 4;
- val |= ((levels[SOUND_MIXER_BASS] & 0xff) * 16 / 100) & 0x0f;
- sb_setmixer (0x0d, val);
-
- /* Set right bass and treble values */
- val = (((levels[SOUND_MIXER_TREBLE] >> 8) & 0xff) * 16 / 100) << 4;
- val |= (((levels[SOUND_MIXER_BASS] >> 8) & 0xff) * 16 / 100) & 0x0f;
- sb_setmixer (0x0e, val);
- break;
-
- default:
- reg = smw_mix_regs[dev];
- if (reg == 0)
- return RET_ERROR (EINVAL);
- sb_setmixer (reg, (24 - (24 * left / 100)) | 0x20); /* 24=mute, 0=max */
- sb_setmixer (reg + 1, (24 - (24 * right / 100)) | 0x40);
- }
-
- levels[dev] = left | (right << 8);
- return left | (right << 8);
-}
-
-#endif
-
-static int
-sb_mixer_set (int dev, int value)
-{
- int left = value & 0x000000ff;
- int right = (value & 0x0000ff00) >> 8;
-
- int regoffs;
- unsigned char val;
-
-#ifdef JAZZ16
- if (Jazz16_detected == 2)
- return smw_mixer_set (dev, value);
-#endif
-
- if (left > 100)
- left = 100;
- if (right > 100)
- right = 100;
-
- if (dev > 31)
- return RET_ERROR (EINVAL);
-
- if (!(supported_devices & (1 << dev))) /*
- * Not supported
- */
- return RET_ERROR (EINVAL);
-
- regoffs = (*iomap)[dev][LEFT_CHN].regno;
-
- if (regoffs == 0)
- return RET_ERROR (EINVAL);
-
- val = sb_getmixer (regoffs);
- change_bits (&val, dev, LEFT_CHN, left);
-
- levels[dev] = left | (left << 8);
-
- if ((*iomap)[dev][RIGHT_CHN].regno != regoffs) /*
- * Change register
- */
- {
- sb_setmixer (regoffs, val); /*
- * Save the old one
- */
- regoffs = (*iomap)[dev][RIGHT_CHN].regno;
-
- if (regoffs == 0)
- return left | (left << 8); /*
- * Just left channel present
- */
-
- val = sb_getmixer (regoffs); /*
- * Read the new one
- */
- }
-
- change_bits (&val, dev, RIGHT_CHN, right);
-
- sb_setmixer (regoffs, val);
-
- levels[dev] = left | (right << 8);
- return left | (right << 8);
-}
-
-static void
-set_recsrc (int src)
-{
- sb_setmixer (RECORD_SRC, (sb_getmixer (RECORD_SRC) & ~7) | (src & 0x7));
-}
-
-static int
-set_recmask (int mask)
-{
- int devmask, i;
- unsigned char regimageL, regimageR;
-
- devmask = mask & supported_rec_devices;
-
- switch (mixer_model)
- {
- case 3:
-
- if (devmask != SOUND_MASK_MIC &&
- devmask != SOUND_MASK_LINE &&
- devmask != SOUND_MASK_CD)
- { /*
- * More than one devices selected. Drop the *
- * previous selection
- */
- devmask &= ~recmask;
- }
-
- if (devmask != SOUND_MASK_MIC &&
- devmask != SOUND_MASK_LINE &&
- devmask != SOUND_MASK_CD)
- { /*
- * More than one devices selected. Default to
- * * mic
- */
- devmask = SOUND_MASK_MIC;
- }
-
-
- if (devmask ^ recmask) /*
- * Input source changed
- */
- {
- switch (devmask)
- {
-
- case SOUND_MASK_MIC:
- set_recsrc (SRC_MIC);
- break;
-
- case SOUND_MASK_LINE:
- set_recsrc (SRC_LINE);
- break;
-
- case SOUND_MASK_CD:
- set_recsrc (SRC_CD);
- break;
-
- default:
- set_recsrc (SRC_MIC);
- }
- }
-
- break;
-
- case 4:
- if (!devmask)
- devmask = SOUND_MASK_MIC;
-
- regimageL = regimageR = 0;
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- if ((1 << i) & devmask)
- {
- regimageL |= sb16_recmasks_L[i];
- regimageR |= sb16_recmasks_R[i];
- }
- sb_setmixer (SB16_IMASK_L, regimageL);
- sb_setmixer (SB16_IMASK_R, regimageR);
- break;
- }
-
- recmask = devmask;
- return recmask;
-}
-
-static int
-sb_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
-{
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (cmd & IOC_IN)
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- return IOCTL_OUT (arg, set_recmask (IOCTL_IN (arg)));
- break;
-
- default:
-
- return IOCTL_OUT (arg, sb_mixer_set (cmd & 0xff, IOCTL_IN (arg)));
- }
- else
- switch (cmd & 0xff) /*
- * Return parameters
- */
- {
-
- case SOUND_MIXER_RECSRC:
- return IOCTL_OUT (arg, recmask);
- break;
-
- case SOUND_MIXER_DEVMASK:
- return IOCTL_OUT (arg, supported_devices);
- break;
-
- case SOUND_MIXER_STEREODEVS:
- if (Jazz16_detected)
- return IOCTL_OUT (arg, supported_devices);
- else
- return IOCTL_OUT (arg, supported_devices &
- ~(SOUND_MASK_MIC | SOUND_MASK_SPEAKER));
- break;
-
- case SOUND_MIXER_RECMASK:
- return IOCTL_OUT (arg, supported_rec_devices);
- break;
-
- case SOUND_MIXER_CAPS:
- return IOCTL_OUT (arg, mixer_caps);
- break;
-
- default:
- return IOCTL_OUT (arg, sb_mixer_get (cmd & 0xff));
- }
- }
- else
- return RET_ERROR (EINVAL);
-}
-
-static struct mixer_operations sb_mixer_operations =
-{
- "SoundBlaster",
- sb_mixer_ioctl
-};
-
-static void
-sb_mixer_reset (void)
-{
- int i;
-
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- sb_mixer_set (i, levels[i]);
- set_recmask (SOUND_MASK_MIC);
-}
-
-/*
- * Returns a code depending on whether a SG NX Pro was detected.
- * 1 == Plain SB Pro
- * 2 == SG NX Pro detected.
- * 3 == SB16
- *
- * Used to update message.
- */
-int
-sb_mixer_init (int major_model)
-{
- int mixer_type = 0;
-
- sb_setmixer (0x00, 0); /* Reset mixer */
-
- if (!(mixer_type = detect_mixer ()))
- return 0; /* No mixer. Why? */
-
- mixer_initialized = 1;
- mixer_model = major_model;
-
- switch (major_model)
- {
- case 3:
- mixer_caps = SOUND_CAP_EXCL_INPUT;
-
-#ifdef JAZZ16
- if (Jazz16_detected == 2) /* SM Wave */
- {
- supported_devices = 0;
- supported_rec_devices = 0;
- iomap = &sbpro_mix;
- smw_mixer_init ();
- mixer_type = 1;
- }
- else
-#endif
-#ifdef __SGNXPRO__
- if (mixer_type == 2) /* A SGNXPRO was detected */
- {
- supported_devices = SGNXPRO_MIXER_DEVICES;
- supported_rec_devices = SGNXPRO_RECORDING_DEVICES;
- iomap = &sgnxpro_mix;
- }
- else
-#endif
- {
- supported_devices = SBPRO_MIXER_DEVICES;
- supported_rec_devices = SBPRO_RECORDING_DEVICES;
- iomap = &sbpro_mix;
- mixer_type = 1;
- }
- break;
-
- case 4:
- mixer_caps = 0;
- supported_devices = SB16_MIXER_DEVICES;
- supported_rec_devices = SB16_RECORDING_DEVICES;
- iomap = &sb16_mix;
- mixer_type = 3;
- break;
-
- default:
- printk ("SB Warning: Unsupported mixer type\n");
- return 0;
- }
-
- if (num_mixers < MAX_MIXER_DEV)
- mixer_devs[num_mixers++] = &sb_mixer_operations;
- sb_mixer_reset ();
- return mixer_type;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/sequencer.c b/sys/pc98/pc98/sound/sequencer.c
deleted file mode 100644
index 30da4c6..0000000
--- a/sys/pc98/pc98/sound/sequencer.c
+++ /dev/null
@@ -1,1992 +0,0 @@
-/*
- * sound/sequencer.c
- *
- * The sequencer personality manager.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#define SEQUENCER_C
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-#include <i386/isa/sound/midi_ctrl.h>
-
-extern void seq_drain_midi_queues __P((void));
-
-#ifdef CONFIGURE_SOUNDCARD
-
-#ifndef EXCLUDE_SEQUENCER
-
-static int sequencer_ok = 0;
-static struct sound_timer_operations *tmr;
-static int tmr_no = -1; /* Currently selected timer */
-static int pending_timer = -1; /* For timer change operation */
-
-/*
- * Local counts for number of synth and MIDI devices. These are initialized
- * by the sequencer_open.
- */
-static int max_mididev = 0;
-static int max_synthdev = 0;
-
-/*
- * The seq_mode gives the operating mode of the sequencer:
- * 1 = level1 (the default)
- * 2 = level2 (extended capabilites)
- */
-
-#define SEQ_1 1
-#define SEQ_2 2
-static int seq_mode = SEQ_1;
-
-DEFINE_WAIT_QUEUE (seq_sleeper, seq_sleep_flag);
-DEFINE_WAIT_QUEUE (midi_sleeper, midi_sleep_flag);
-
-static int midi_opened[MAX_MIDI_DEV] =
-{0};
-static int midi_written[MAX_MIDI_DEV] =
-{0};
-
-static unsigned long prev_input_time = 0;
-static int prev_event_time;
-static unsigned long seq_time = 0;
-
-#include <i386/isa/sound/tuning.h>
-
-#define EV_SZ 8
-#define IEV_SZ 8
-static unsigned char *queue = NULL;
-static unsigned char *iqueue = NULL;
-
-static volatile int qhead = 0, qtail = 0, qlen = 0;
-static volatile int iqhead = 0, iqtail = 0, iqlen = 0;
-static volatile int seq_playing = 0;
-static int sequencer_busy = 0;
-static int output_treshold;
-static int pre_event_timeout;
-static unsigned synth_open_mask;
-
-static int seq_queue (unsigned char *note, char nonblock);
-static void seq_startplay (void);
-static int seq_sync (void);
-static void seq_reset (void);
-static int pmgr_present[MAX_SYNTH_DEV] =
-{0};
-
-#if MAX_SYNTH_DEV > 15
-#error Too many synthesizer devices enabled.
-#endif
-
-int
-sequencer_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- int c = count, p = 0;
- int ev_len;
- unsigned long flags;
-
- dev = dev >> 4;
-
- ev_len = seq_mode == SEQ_1 ? 4 : 8;
-
- if (dev) /*
- * Patch manager device
- */
- return pmgr_read (dev - 1, file, buf, count);
-
- DISABLE_INTR (flags);
- if (!iqlen)
- {
- if (ISSET_FILE_FLAG (file, O_NONBLOCK))
- {
- RESTORE_INTR (flags);
- return RET_ERROR (EAGAIN);
- }
-
- DO_SLEEP (midi_sleeper, midi_sleep_flag, pre_event_timeout);
-
- if (!iqlen)
- {
- RESTORE_INTR (flags);
- return 0;
- }
- }
-
- while (iqlen && c >= ev_len)
- {
-
- COPY_TO_USER (buf, p, &iqueue[iqhead * IEV_SZ], ev_len);
- p += ev_len;
- c -= ev_len;
-
- iqhead = (iqhead + 1) % SEQ_MAX_QUEUE;
- iqlen--;
- }
- RESTORE_INTR (flags);
-
- return count - c;
-}
-
-static void
-sequencer_midi_output (int dev)
-{
- /*
- * Currently NOP
- */
-}
-
-void
-seq_copy_to_input (unsigned char *event, int len)
-{
- unsigned long flags;
-
- /*
- * Verify that the len is valid for the current mode.
- */
-
- if (len != 4 && len != 8)
- return;
- if ((seq_mode == SEQ_1) != (len == 4))
- return;
-
- if (iqlen >= (SEQ_MAX_QUEUE - 1))
- return; /* Overflow */
-
- DISABLE_INTR (flags);
- memcpy (&iqueue[iqtail * IEV_SZ], event, len);
- iqlen++;
- iqtail = (iqtail + 1) % SEQ_MAX_QUEUE;
-
- if (SOMEONE_WAITING (midi_sleeper, midi_sleep_flag))
- {
- WAKE_UP (midi_sleeper, midi_sleep_flag);
- }
- RESTORE_INTR (flags);
-#if defined(__FreeBSD__)
- if (selinfo[0].si_pid)
- selwakeup(&selinfo[0]);
-#endif
-}
-
-static void
-sequencer_midi_input (int dev, unsigned char data)
-{
- unsigned int tstamp;
- unsigned char event[4];
-
- if (data == 0xfe) /* Ignore active sensing */
- return;
-
- tstamp = GET_TIME () - seq_time;
- if (tstamp != prev_input_time)
- {
- tstamp = (tstamp << 8) | SEQ_WAIT;
-
- seq_copy_to_input ((unsigned char *) &tstamp, 4);
- prev_input_time = tstamp;
- }
-
- event[0] = SEQ_MIDIPUTC;
- event[1] = data;
- event[2] = dev;
- event[3] = 0;
-
- seq_copy_to_input (event, 4);
-}
-
-void
-seq_input_event (unsigned char *event, int len)
-{
- unsigned long this_time;
-
- if (seq_mode == SEQ_2)
- this_time = tmr->get_time (tmr_no);
- else
- this_time = GET_TIME () - seq_time;
-
- if (this_time != prev_input_time)
- {
- unsigned char tmp_event[8];
-
- tmp_event[0] = EV_TIMING;
- tmp_event[1] = TMR_WAIT_ABS;
- tmp_event[2] = 0;
- tmp_event[3] = 0;
- *(unsigned long *) &tmp_event[4] = this_time;
-
- seq_copy_to_input (tmp_event, 8);
- prev_input_time = this_time;
- }
-
- seq_copy_to_input (event, len);
-}
-
-int
-sequencer_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- unsigned char event[EV_SZ], ev_code;
- int p = 0, c, ev_size;
- int err;
- int mode = file->mode & O_ACCMODE;
-
- dev = dev >> 4;
-
- DEB (printk ("sequencer_write(dev=%d, count=%d)\n", dev, count));
-
- if (mode == OPEN_READ)
- return RET_ERROR (EIO);
-
- if (dev) /*
- * Patch manager device
- */
- return pmgr_write (dev - 1, file, buf, count);
-
- c = count;
-
- while (c >= 4)
- {
- COPY_FROM_USER (event, buf, p, 4);
- ev_code = event[0];
-
- if (ev_code == SEQ_FULLSIZE)
- {
- int err;
-
- dev = *(unsigned short *) &event[2];
- if (dev < 0 || dev >= max_synthdev)
- return RET_ERROR (ENXIO);
-
- if (!(synth_open_mask & (1 << dev)))
- return RET_ERROR (ENXIO);
-
- err = synth_devs[dev]->load_patch (dev, *(short *) &event[0], buf, p + 4, c, 0);
- if (err < 0)
- return err;
-
- return err;
- }
-
- if (ev_code >= 128)
- {
- if (seq_mode == SEQ_2 && ev_code == SEQ_EXTENDED)
- {
- printk ("Sequencer: Invalid level 2 event %x\n", ev_code);
- return RET_ERROR (EINVAL);
- }
-
- ev_size = 8;
-
- if (c < ev_size)
- {
- if (!seq_playing)
- seq_startplay ();
- return count - c;
- }
-
- COPY_FROM_USER (&event[4], buf, p + 4, 4);
-
- }
- else
- {
- if (seq_mode == SEQ_2)
- {
- printk ("Sequencer: 4 byte event in level 2 mode\n");
- return RET_ERROR (EINVAL);
- }
- ev_size = 4;
- }
-
- if (event[0] == SEQ_MIDIPUTC)
- {
-
- if (!midi_opened[event[2]])
- {
- int mode;
- int dev = event[2];
-
- if (dev >= max_mididev)
- {
- printk ("Sequencer Error: Nonexistent MIDI device %d\n", dev);
- return RET_ERROR (ENXIO);
- }
-
- mode = file->mode & O_ACCMODE;
-
- if ((err = midi_devs[dev]->open (dev, mode,
- sequencer_midi_input, sequencer_midi_output)) < 0)
- {
- seq_reset ();
- printk ("Sequencer Error: Unable to open Midi #%d\n", dev);
- return err;
- }
-
- midi_opened[dev] = 1;
- }
-
- }
-
- if (!seq_queue (event, ISSET_FILE_FLAG (file, O_NONBLOCK)))
- {
- int processed = count - c;
-
- if (!seq_playing)
- seq_startplay ();
-
- if (!processed && ISSET_FILE_FLAG (file, O_NONBLOCK))
- return RET_ERROR (EAGAIN);
- else
- return processed;
- }
-
- p += ev_size;
- c -= ev_size;
- }
-
- if (!seq_playing)
- seq_startplay ();
-
- return count; /* This will "eat" chunks shorter than 4 bytes (if written
- * alone) Should we really do that ?
- */
-}
-
-static int
-seq_queue (unsigned char *note, char nonblock)
-{
-
- /*
- * Test if there is space in the queue
- */
-
- if (qlen >= SEQ_MAX_QUEUE)
- if (!seq_playing)
- seq_startplay (); /*
- * Give chance to drain the queue
- */
-
- if (!nonblock && qlen >= SEQ_MAX_QUEUE && !SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))
- {
- /*
- * Sleep until there is enough space on the queue
- */
- DO_SLEEP (seq_sleeper, seq_sleep_flag, 0);
- }
-
- if (qlen >= SEQ_MAX_QUEUE)
- {
- return 0; /*
- * To be sure
- */
- }
- memcpy (&queue[qtail * EV_SZ], note, EV_SZ);
-
- qtail = (qtail + 1) % SEQ_MAX_QUEUE;
- qlen++;
-
- return 1;
-}
-
-static int
-extended_event (unsigned char *q)
-{
- int dev = q[2];
-
- if (dev < 0 || dev >= max_synthdev)
- return RET_ERROR (ENXIO);
-
- if (!(synth_open_mask & (1 << dev)))
- return RET_ERROR (ENXIO);
-
- switch (q[1])
- {
- case SEQ_NOTEOFF:
- synth_devs[dev]->kill_note (dev, q[3], q[4], q[5]);
- break;
-
- case SEQ_NOTEON:
- if (q[4] > 127 && q[4] != 255)
- return 0;
-
- synth_devs[dev]->start_note (dev, q[3], q[4], q[5]);
- break;
-
- case SEQ_PGMCHANGE:
- synth_devs[dev]->set_instr (dev, q[3], q[4]);
- break;
-
- case SEQ_AFTERTOUCH:
- synth_devs[dev]->aftertouch (dev, q[3], q[4]);
- break;
-
- case SEQ_BALANCE:
- synth_devs[dev]->panning (dev, q[3], (char) q[4]);
- break;
-
- case SEQ_CONTROLLER:
- synth_devs[dev]->controller (dev, q[3], q[4], *(short *) &q[5]);
- break;
-
- case SEQ_VOLMODE:
- if (synth_devs[dev]->volume_method != NULL)
- synth_devs[dev]->volume_method (dev, q[3]);
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
-
- return 0;
-}
-
-static int
-find_voice (int dev, int chn, int note)
-{
- unsigned short key;
- int i;
-
- key = (chn << 8) | (note + 1);
-
- for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
- if (synth_devs[dev]->alloc.map[i] == key)
- return i;
-
- return -1;
-}
-
-static int
-alloc_voice (int dev, int chn, int note)
-{
- unsigned short key;
- int voice;
-
- key = (chn << 8) | (note + 1);
-
- voice = synth_devs[dev]->alloc_voice (dev, chn, note,
- &synth_devs[dev]->alloc);
- synth_devs[dev]->alloc.map[voice] = key;
- synth_devs[dev]->alloc.alloc_times[voice] =
- synth_devs[dev]->alloc.timestamp++;
- return voice;
-}
-
-static void
-seq_chn_voice_event (unsigned char *event)
-{
- unsigned char dev = event[1];
- unsigned char cmd = event[2];
- unsigned char chn = event[3];
- unsigned char note = event[4];
- unsigned char parm = event[5];
- int voice = -1;
-
- if ((int) dev > max_synthdev)
- return;
- if (!(synth_open_mask & (1 << dev)))
- return;
- if (!synth_devs[dev])
- return;
-
- if (seq_mode == SEQ_2)
- {
- if (synth_devs[dev]->alloc_voice)
- voice = find_voice (dev, chn, note);
-
- if (cmd == MIDI_NOTEON && parm == 0)
- {
- cmd = MIDI_NOTEOFF;
- parm = 64;
- }
- }
-
- switch (cmd)
- {
- case MIDI_NOTEON:
- if (note > 127 && note != 255) /* Not a seq2 feature */
- return;
-
- if (voice == -1 && seq_mode == SEQ_2 && synth_devs[dev]->alloc_voice)
- { /* Internal synthesizer (FM, GUS, etc) */
- voice = alloc_voice (dev, chn, note);
- }
-
- if (voice == -1)
- voice = chn;
-
- if (seq_mode == SEQ_2 && dev < num_synths)
- {
- /*
- * The MIDI channel 10 is a percussive channel. Use the note
- * number to select the proper patch (128 to 255) to play.
- */
-
- if (chn == 9)
- {
- synth_devs[dev]->set_instr (dev, voice, 128 + note);
- note = 60; /* Middle C */
-
- }
- }
-
- if (seq_mode == SEQ_2)
- {
- synth_devs[dev]->setup_voice (dev, voice, chn);
- }
-
- synth_devs[dev]->start_note (dev, voice, note, parm);
- break;
-
- case MIDI_NOTEOFF:
- if (voice == -1)
- voice = chn;
- synth_devs[dev]->kill_note (dev, voice, note, parm);
- break;
-
- case MIDI_KEY_PRESSURE:
- if (voice == -1)
- voice = chn;
- synth_devs[dev]->aftertouch (dev, voice, parm);
- break;
-
- default:;
- }
-}
-
-static void
-seq_chn_common_event (unsigned char *event)
-{
- unsigned char dev = event[1];
- unsigned char cmd = event[2];
- unsigned char chn = event[3];
- unsigned char p1 = event[4];
-
- /* unsigned char p2 = event[5]; */
- unsigned short w14 = *(short *) &event[6];
-
- if ((int) dev > max_synthdev)
- return;
- if (!(synth_open_mask & (1 << dev)))
- return;
- if (!synth_devs[dev])
- return;
-
- switch (cmd)
- {
- case MIDI_PGM_CHANGE:
- if (seq_mode == SEQ_2)
- {
- synth_devs[dev]->chn_info[chn].pgm_num = p1;
- if (dev >= num_synths)
- synth_devs[dev]->set_instr (dev, chn, p1);
- }
- else
- synth_devs[dev]->set_instr (dev, chn, p1);
-
- break;
-
- case MIDI_CTL_CHANGE:
-
- if (seq_mode == SEQ_2)
- {
- if (chn > 15 || p1 > 127)
- break;
-
- synth_devs[dev]->chn_info[chn].controllers[p1] = w14 & 0x7f;
-
- if (dev < num_synths)
- {
- int val = w14 & 0x7f;
- int i, key;
-
- if (p1 < 64) /* Combine MSB and LSB */
- {
- val = ((synth_devs[dev]->
- chn_info[chn].controllers[p1 & ~32] & 0x7f) << 7)
- | (synth_devs[dev]->
- chn_info[chn].controllers[p1 | 32] & 0x7f);
- p1 &= ~32;
- }
-
- /* Handle all playing notes on this channel */
-
- key = (chn << 8);
-
- for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
- if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)
- synth_devs[dev]->controller (dev, i, p1, val);
- }
- else
- synth_devs[dev]->controller (dev, chn, p1, w14);
- }
- else /* Mode 1 */
- synth_devs[dev]->controller (dev, chn, p1, w14);
- break;
-
- case MIDI_PITCH_BEND:
- if (seq_mode == SEQ_2)
- {
- synth_devs[dev]->chn_info[chn].bender_value = w14;
-
- if (dev < num_synths)
- { /* Handle all playing notes on this channel */
- int i, key;
-
- key = (chn << 8);
-
- for (i = 0; i < synth_devs[dev]->alloc.max_voice; i++)
- if ((synth_devs[dev]->alloc.map[i] & 0xff00) == key)
- synth_devs[dev]->bender (dev, i, w14);
- }
- else
- synth_devs[dev]->bender (dev, chn, w14);
- }
- else /* MODE 1 */
- synth_devs[dev]->bender (dev, chn, w14);
- break;
-
- default:;
- }
-}
-
-static int
-seq_timing_event (unsigned char *event)
-{
- unsigned char cmd = event[1];
- unsigned int parm = *(int *) &event[4];
-
- if (seq_mode == SEQ_2)
- {
- int ret;
-
- if ((ret = tmr->event (tmr_no, event)) == TIMER_ARMED)
- {
- if ((SEQ_MAX_QUEUE - qlen) >= output_treshold)
- {
- unsigned long flags;
-
- DISABLE_INTR (flags);
- if (SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))
- {
- WAKE_UP (seq_sleeper, seq_sleep_flag);
- }
- RESTORE_INTR (flags);
-#if defined(__FreeBSD__)
- /* must issue a wakeup for anyone waiting (select) XXX */
-#endif
- }
- }
- return ret;
- }
-
- switch (cmd)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
-
- /*
- * NOTE! No break here. Execution of TMR_WAIT_REL continues in the
- * next case (TMR_WAIT_ABS)
- */
-
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- seq_playing = 1;
- time = parm;
- prev_event_time = time;
-
- request_sound_timer (time);
-
- if ((SEQ_MAX_QUEUE - qlen) >= output_treshold)
- {
- unsigned long flags;
-
- DISABLE_INTR (flags);
- if (SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))
- {
- WAKE_UP (seq_sleeper, seq_sleep_flag);
- }
- RESTORE_INTR (flags);
-#if defined(__FreeBSD__)
- /* must issue a wakeup for select XXX */
-#endif
- }
-
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- seq_time = GET_TIME ();
- prev_input_time = 0;
- prev_event_time = 0;
- break;
-
- case TMR_STOP:
- break;
-
- case TMR_CONTINUE:
- break;
-
- case TMR_TEMPO:
- break;
-
- case TMR_ECHO:
- if (seq_mode == SEQ_2)
- seq_copy_to_input (event, 8);
- else
- {
- parm = (parm << 8 | SEQ_ECHO);
- seq_copy_to_input ((unsigned char *) &parm, 4);
- }
- break;
-
- default:;
- }
-
- return TIMER_NOT_ARMED;
-}
-
-static void
-seq_local_event (unsigned char *event)
-{
- /* unsigned char cmd = event[1]; */
-
- printk ("seq_local_event() called. WHY????????\n");
-}
-
-static int
-play_event (unsigned char *q)
-{
- /*
- * NOTE! This routine returns
- * 0 = normal event played.
- * 1 = Timer armed. Suspend playback until timer callback.
- * 2 = MIDI output buffer full. Restore queue and suspend until timer
- */
- unsigned long *delay;
-
- switch (q[0])
- {
- case SEQ_NOTEOFF:
- if (synth_open_mask & (1 << 0))
- if (synth_devs[0])
- synth_devs[0]->kill_note (0, q[1], 255, q[3]);
- break;
-
- case SEQ_NOTEON:
- if (q[4] < 128 || q[4] == 255)
- if (synth_open_mask & (1 << 0))
- if (synth_devs[0])
- synth_devs[0]->start_note (0, q[1], q[2], q[3]);
- break;
-
- case SEQ_WAIT:
- delay = (unsigned long *) q; /*
- * Bytes 1 to 3 are containing the *
- * delay in GET_TIME()
- */
- *delay = (*delay >> 8) & 0xffffff;
-
- if (*delay > 0)
- {
- long time;
-
- seq_playing = 1;
- time = *delay;
- prev_event_time = time;
-
- request_sound_timer (time);
-
- if ((SEQ_MAX_QUEUE - qlen) >= output_treshold)
- {
- unsigned long flags;
-
- DISABLE_INTR (flags);
- if (SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))
- {
- WAKE_UP (seq_sleeper, seq_sleep_flag);
- }
- RESTORE_INTR (flags);
-#if defined(__FreeBSD__)
- /* must issue a wakeup for selects XXX */
-#endif
- }
- /*
- * The timer is now active and will reinvoke this function
- * after the timer expires. Return to the caller now.
- */
- return 1;
- }
- break;
-
- case SEQ_PGMCHANGE:
- if (synth_open_mask & (1 << 0))
- if (synth_devs[0])
- synth_devs[0]->set_instr (0, q[1], q[2]);
- break;
-
- case SEQ_SYNCTIMER: /*
- * Reset timer
- */
- seq_time = GET_TIME ();
- prev_input_time = 0;
- prev_event_time = 0;
- break;
-
- case SEQ_MIDIPUTC: /*
- * Put a midi character
- */
- if (midi_opened[q[2]])
- {
- int dev;
-
- dev = q[2];
-
- if (!midi_devs[dev]->putc (dev, q[1]))
- {
- /*
- * Output FIFO is full. Wait one timer cycle and try again.
- */
-
- seq_playing = 1;
- request_sound_timer (-1);
- return 2;
- }
- else
- midi_written[dev] = 1;
- }
- break;
-
- case SEQ_ECHO:
- seq_copy_to_input (q, 4); /*
- * Echo back to the process
- */
- break;
-
- case SEQ_PRIVATE:
- if ((int) q[1] < max_synthdev)
- synth_devs[q[1]]->hw_control (q[1], q);
- break;
-
- case SEQ_EXTENDED:
- extended_event (q);
- break;
-
- case EV_CHN_VOICE:
- seq_chn_voice_event (q);
- break;
-
- case EV_CHN_COMMON:
- seq_chn_common_event (q);
- break;
-
- case EV_TIMING:
- if (seq_timing_event (q) == TIMER_ARMED)
- {
- return 1;
- }
- break;
-
- case EV_SEQ_LOCAL:
- seq_local_event (q);
- break;
-
- default:;
- }
-
- return 0;
-}
-
-static void
-seq_startplay (void)
-{
- unsigned long flags;
- int this_one, action;
-
- while (qlen > 0)
- {
-
- DISABLE_INTR (flags);
- qhead = ((this_one = qhead) + 1) % SEQ_MAX_QUEUE;
- qlen--;
- RESTORE_INTR (flags);
-
- seq_playing = 1;
-
- if ((action = play_event (&queue[this_one * EV_SZ])))
- { /* Suspend playback. Next timer routine invokes this routine again */
- if (action == 2)
- {
- qlen++;
- qhead = this_one;
- }
- return;
- }
-
- }
-
- seq_playing = 0;
-
- if ((SEQ_MAX_QUEUE - qlen) >= output_treshold)
- {
- unsigned long flags;
-
- DISABLE_INTR (flags);
- if (SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))
- {
- WAKE_UP (seq_sleeper, seq_sleep_flag);
- }
- RESTORE_INTR (flags);
-#if defined(__FreeBSD__)
- /* must issue a wakeup for selects XXX */
-#endif
- }
-}
-
-static void
-reset_controllers (int dev, unsigned char *controller, int update_dev)
-{
-
- int i;
-
- for (i = 0; i < 128; i++)
- controller[i] = ctrl_def_values[i];
-}
-
-static void
-setup_mode2 (void)
-{
- int dev;
-
- max_synthdev = num_synths;
-
- for (dev = 0; dev < num_midis; dev++)
- if (midi_devs[dev]->converter != NULL)
- {
- synth_devs[max_synthdev++] =
- midi_devs[dev]->converter;
- }
-
- for (dev = 0; dev < max_synthdev; dev++)
- {
- int chn;
-
- for (chn = 0; chn < 16; chn++)
- {
- synth_devs[dev]->chn_info[chn].pgm_num = 0;
- reset_controllers (dev,
- synth_devs[dev]->chn_info[chn].controllers,
- 0);
- synth_devs[dev]->chn_info[chn].bender_value = (1 << 7); /* Neutral */
- }
- }
-
- max_mididev = 0;
- seq_mode = SEQ_2;
-}
-
-int
-sequencer_open (int dev, struct fileinfo *file)
-{
- int retval, mode, i;
- int level, tmp;
-
- level = ((dev & 0x0f) == SND_DEV_SEQ2) ? 2 : 1;
-
- dev = dev >> 4;
- mode = file->mode & O_ACCMODE;
-
- DEB (printk ("sequencer_open(dev=%d)\n", dev));
-
- if (!sequencer_ok)
- {
- printk ("Soundcard: Sequencer not initialized\n");
- return RET_ERROR (ENXIO);
- }
-
- if (dev) /*
- * Patch manager device
- */
- {
- int err;
-
- dev--;
-
- if (dev >= MAX_SYNTH_DEV)
- return RET_ERROR (ENXIO);
- if (pmgr_present[dev])
- return RET_ERROR (EBUSY);
- if ((err = pmgr_open (dev)) < 0)
- return err; /*
- * Failed
- */
-
- pmgr_present[dev] = 1;
- return err;
- }
-
- if (sequencer_busy)
- {
- printk ("Sequencer busy\n");
- return RET_ERROR (EBUSY);
- }
-
- max_mididev = num_midis;
- max_synthdev = num_synths;
- pre_event_timeout = 0;
- seq_mode = SEQ_1;
-
- if (pending_timer != -1)
- {
- tmr_no = pending_timer;
- pending_timer = -1;
- }
-
- if (tmr_no == -1) /* Not selected yet */
- {
- int i, best;
-
- best = -1;
- for (i = 0; i < num_sound_timers; i++)
- if (sound_timer_devs[i]->priority > best)
- {
- tmr_no = i;
- best = sound_timer_devs[i]->priority;
- }
-
- if (tmr_no == -1) /* Should not be */
- tmr_no = 0;
- }
-
- tmr = sound_timer_devs[tmr_no];
-
- if (level == 2)
- {
- if (tmr == NULL)
- {
- printk ("sequencer: No timer for level 2\n");
- return RET_ERROR (ENXIO);
- }
- setup_mode2 ();
- }
-
- if (seq_mode == SEQ_1 && (mode == OPEN_READ || mode == OPEN_READWRITE))
- if (!max_mididev)
- {
- printk ("Sequencer: No Midi devices. Input not possible\n");
- return RET_ERROR (ENXIO);
- }
-
- if (!max_synthdev && !max_mididev)
- return RET_ERROR (ENXIO);
-
- synth_open_mask = 0;
-
- for (i = 0; i < max_mididev; i++)
- {
- midi_opened[i] = 0;
- midi_written[i] = 0;
- }
-
- /*
- * if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
- */
- for (i = 0; i < max_synthdev; i++) /*
- * Open synth devices
- */
- if ((tmp = synth_devs[i]->open (i, mode)) < 0)
- {
- printk ("Sequencer: Warning! Cannot open synth device #%d (%d)\n", i, tmp);
- if (synth_devs[i]->midi_dev)
- printk ("(Maps to MIDI dev #%d)\n", synth_devs[i]->midi_dev);
- }
- else
- {
- synth_open_mask |= (1 << i);
- if (synth_devs[i]->midi_dev) /*
- * Is a midi interface
- */
- midi_opened[synth_devs[i]->midi_dev] = 1;
- }
-
- seq_time = GET_TIME ();
- prev_input_time = 0;
- prev_event_time = 0;
-
- if (seq_mode == SEQ_1 && (mode == OPEN_READ || mode == OPEN_READWRITE))
- { /*
- * Initialize midi input devices
- */
- for (i = 0; i < max_mididev; i++)
- if (!midi_opened[i])
- {
- if ((retval = midi_devs[i]->open (i, mode,
- sequencer_midi_input, sequencer_midi_output)) >= 0)
- midi_opened[i] = 1;
- }
- }
-
- if (seq_mode == SEQ_2)
- {
- tmr->open (tmr_no, seq_mode);
- }
-
- sequencer_busy = 1;
- RESET_WAIT_QUEUE (seq_sleeper, seq_sleep_flag);
- RESET_WAIT_QUEUE (midi_sleeper, midi_sleep_flag);
- output_treshold = SEQ_MAX_QUEUE / 2;
-
- for (i = 0; i < num_synths; i++)
- if (pmgr_present[i])
- pmgr_inform (i, PM_E_OPENED, 0, 0, 0, 0);
-
- return 0;
-}
-
-void
-seq_drain_midi_queues (void)
-{
- int i, n;
-
- /*
- * Give the Midi drivers time to drain their output queues
- */
-
- n = 1;
-
- while (!PROCESS_ABORTING (seq_sleeper, seq_sleep_flag) && n)
- {
- n = 0;
-
- for (i = 0; i < max_mididev; i++)
- if (midi_opened[i] && midi_written[i])
- if (midi_devs[i]->buffer_status != NULL)
- if (midi_devs[i]->buffer_status (i))
- n++;
-
- /*
- * Let's have a delay
- */
- if (n)
- {
- DO_SLEEP (seq_sleeper, seq_sleep_flag, HZ / 10);
- }
- }
-}
-
-void
-sequencer_release (int dev, struct fileinfo *file)
-{
- int i;
- int mode = file->mode & O_ACCMODE;
-
- dev = dev >> 4;
-
- DEB (printk ("sequencer_release(dev=%d)\n", dev));
-
- if (dev) /*
- * Patch manager device
- */
- {
- dev--;
- pmgr_release (dev);
- pmgr_present[dev] = 0;
- return;
- }
-
- /*
- * * Wait until the queue is empty (if we don't have nonblock)
- */
-
- if (mode != OPEN_READ && !ISSET_FILE_FLAG (file, O_NONBLOCK))
- while (!PROCESS_ABORTING (seq_sleeper, seq_sleep_flag) && qlen)
- {
- seq_sync ();
- }
-
- if (mode != OPEN_READ)
- seq_drain_midi_queues (); /*
- * Ensure the output queues are empty
- */
- seq_reset ();
- if (mode != OPEN_READ)
- seq_drain_midi_queues (); /*
- * Flush the all notes off messages
- */
-
- for (i = 0; i < max_synthdev; i++)
- if (synth_open_mask & (1 << i)) /*
- * Actually opened
- */
- if (synth_devs[i])
- {
- synth_devs[i]->close (i);
-
- if (synth_devs[i]->midi_dev)
- midi_opened[synth_devs[i]->midi_dev] = 0;
- }
-
- for (i = 0; i < num_synths; i++)
- if (pmgr_present[i])
- pmgr_inform (i, PM_E_CLOSED, 0, 0, 0, 0);
-
- for (i = 0; i < max_mididev; i++)
- if (midi_opened[i])
- midi_devs[i]->close (i);
-
- if (seq_mode == SEQ_2)
- tmr->close (tmr_no);
-
- sequencer_busy = 0;
-}
-
-static int
-seq_sync (void)
-{
- unsigned long flags;
-
- if (qlen && !seq_playing && !PROCESS_ABORTING (seq_sleeper, seq_sleep_flag))
- seq_startplay ();
-
- DISABLE_INTR (flags);
- if (qlen && !SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))
- {
- DO_SLEEP (seq_sleeper, seq_sleep_flag, 0);
- }
- RESTORE_INTR (flags);
-
- return qlen;
-}
-
-static void
-midi_outc (int dev, unsigned char data)
-{
- /*
- * NOTE! Calls sleep(). Don't call this from interrupt.
- */
-
- int n;
- unsigned long flags;
-
- /*
- * This routine sends one byte to the Midi channel.
- * If the output Fifo is full, it waits until there
- * is space in the queue
- */
-
- n = 3 * HZ; /* Timeout */
-
- DISABLE_INTR (flags);
- while (n && !midi_devs[dev]->putc (dev, data))
- {
- DO_SLEEP (seq_sleeper, seq_sleep_flag, 4);
- n--;
- }
- RESTORE_INTR (flags);
-}
-
-static void
-seq_reset (void)
-{
- /*
- * NOTE! Calls sleep(). Don't call this from interrupt.
- */
-
- int i;
- int chn;
- unsigned long flags;
-
- sound_stop_timer ();
- seq_time = GET_TIME ();
- prev_input_time = 0;
- prev_event_time = 0;
-
- qlen = qhead = qtail = 0;
- iqlen = iqhead = iqtail = 0;
-
- for (i = 0; i < max_synthdev; i++)
- if (synth_open_mask & (1 << i))
- if (synth_devs[i])
- synth_devs[i]->reset (i);
-
- if (seq_mode == SEQ_2)
- {
-
- for (chn = 0; chn < 16; chn++)
- for (i = 0; i < max_synthdev; i++)
- if (synth_open_mask & (1 << i))
- if (synth_devs[i])
- {
- synth_devs[i]->controller (i, chn, 123, 0); /* All notes off */
- synth_devs[i]->controller (i, chn, 121, 0); /* Reset all ctl */
- synth_devs[i]->bender (i, chn, 1 << 13); /* Bender off */
- }
-
- }
- else
- /* seq_mode == SEQ_1 */
- {
- for (i = 0; i < max_mididev; i++)
- if (midi_written[i]) /*
- * Midi used. Some notes may still be playing
- */
- {
- /*
- * Sending just a ACTIVE SENSING message should be enough to stop all
- * playing notes. Since there are devices not recognizing the
- * active sensing, we have to send some all notes off messages also.
- */
- midi_outc (i, 0xfe);
-
- for (chn = 0; chn < 16; chn++)
- {
- midi_outc (i,
- (unsigned char) (0xb0 + (chn & 0x0f))); /* control change */
- midi_outc (i, 0x7b); /* All notes off */
- midi_outc (i, 0); /* Dummy parameter */
- }
-
- midi_devs[i]->close (i);
-
- midi_written[i] = 0;
- midi_opened[i] = 0;
- }
- }
-
- seq_playing = 0;
-
- DISABLE_INTR (flags);
- if (SOMEONE_WAITING (seq_sleeper, seq_sleep_flag))
- {
- /* printk ("Sequencer Warning: Unexpected sleeping process - Waking up\n"); */
- WAKE_UP (seq_sleeper, seq_sleep_flag);
- }
- RESTORE_INTR (flags);
-
-}
-
-static void
-seq_panic (void)
-{
- /*
- * This routine is called by the application in case the user
- * wants to reset the system to the default state.
- */
-
- seq_reset ();
-
- /*
- * Since some of the devices don't recognize the active sensing and
- * all notes off messages, we have to shut all notes manually.
- *
- * TO BE IMPLEMENTED LATER
- */
-
- /*
- * Also return the controllers to their default states
- */
-}
-
-int
-sequencer_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned int arg)
-{
- int midi_dev, orig_dev;
- int mode = file->mode & O_ACCMODE;
-
- orig_dev = dev = dev >> 4;
-
- switch (cmd)
- {
- case SNDCTL_TMR_TIMEBASE:
- case SNDCTL_TMR_TEMPO:
- case SNDCTL_TMR_START:
- case SNDCTL_TMR_STOP:
- case SNDCTL_TMR_CONTINUE:
- case SNDCTL_TMR_METRONOME:
- case SNDCTL_TMR_SOURCE:
- if (dev) /* Patch manager */
- return RET_ERROR (EIO);
-
- if (seq_mode != SEQ_2)
- return RET_ERROR (EINVAL);
- return tmr->ioctl (tmr_no, cmd, arg);
- break;
-
- case SNDCTL_TMR_SELECT:
- if (dev) /* Patch manager */
- return RET_ERROR (EIO);
-
- if (seq_mode != SEQ_2)
- return RET_ERROR (EINVAL);
- pending_timer = IOCTL_IN (arg);
-
- if (pending_timer < 0 || pending_timer >= num_sound_timers)
- {
- pending_timer = -1;
- return RET_ERROR (EINVAL);
- }
-
- return IOCTL_OUT (arg, pending_timer);
- break;
-
- case SNDCTL_SEQ_PANIC:
- seq_panic ();
- break;
-
- case SNDCTL_SEQ_SYNC:
- if (dev) /*
- * Patch manager
- */
- return RET_ERROR (EIO);
-
- if (mode == OPEN_READ)
- return 0;
- while (qlen && !PROCESS_ABORTING (seq_sleeper, seq_sleep_flag))
- seq_sync ();
- if (qlen)
- return RET_ERROR (EINTR);
- else
- return 0;
- break;
-
- case SNDCTL_SEQ_RESET:
- if (dev) /*
- * Patch manager
- */
- return RET_ERROR (EIO);
-
- seq_reset ();
- return 0;
- break;
-
- case SNDCTL_SEQ_TESTMIDI:
- if (dev) /*
- * Patch manager
- */
- return RET_ERROR (EIO);
-
- midi_dev = IOCTL_IN (arg);
- if (midi_dev >= max_mididev)
- return RET_ERROR (ENXIO);
-
- if (!midi_opened[midi_dev])
- {
- int err, mode;
-
- mode = file->mode & O_ACCMODE;
- if ((err = midi_devs[midi_dev]->open (midi_dev, mode,
- sequencer_midi_input,
- sequencer_midi_output)) < 0)
- return err;
- }
-
- midi_opened[midi_dev] = 1;
-
- return 0;
- break;
-
- case SNDCTL_SEQ_GETINCOUNT:
- if (dev) /*
- * Patch manager
- */
- return RET_ERROR (EIO);
-
- if (mode == OPEN_WRITE)
- return 0;
- return IOCTL_OUT (arg, iqlen);
- break;
-
- case SNDCTL_SEQ_GETOUTCOUNT:
-
- if (mode == OPEN_READ)
- return 0;
- return IOCTL_OUT (arg, SEQ_MAX_QUEUE - qlen);
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- if (dev) /* Patch manager */
- return RET_ERROR (EIO);
-
- /*
- * If *arg == 0, just return the current rate
- */
- if (seq_mode == SEQ_2)
- return tmr->ioctl (tmr_no, cmd, arg);
-
- if (IOCTL_IN (arg) != 0)
- return RET_ERROR (EINVAL);
-
- return IOCTL_OUT (arg, HZ);
- break;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- dev = IOCTL_IN (arg);
- if (dev < 0 || dev >= num_synths)
- return RET_ERROR (ENXIO);
-
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return RET_ERROR (EBUSY);
-
- if (!orig_dev && pmgr_present[dev])
- pmgr_inform (dev, PM_E_PATCH_RESET, 0, 0, 0, 0);
-
- return synth_devs[dev]->ioctl (dev, cmd, arg);
- break;
-
- case SNDCTL_SEQ_NRSYNTHS:
- return IOCTL_OUT (arg, max_synthdev);
- break;
-
- case SNDCTL_SEQ_NRMIDIS:
- return IOCTL_OUT (arg, max_mididev);
- break;
-
- case SNDCTL_SYNTH_MEMAVL:
- {
- int dev = IOCTL_IN (arg);
-
- if (dev < 0 || dev >= num_synths)
- return RET_ERROR (ENXIO);
-
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return RET_ERROR (EBUSY);
-
- return IOCTL_OUT (arg, synth_devs[dev]->ioctl (dev, cmd, arg));
- }
- break;
-
- case SNDCTL_FM_4OP_ENABLE:
- {
- int dev = IOCTL_IN (arg);
-
- if (dev < 0 || dev >= num_synths)
- return RET_ERROR (ENXIO);
-
- if (!(synth_open_mask & (1 << dev)))
- return RET_ERROR (ENXIO);
-
- synth_devs[dev]->ioctl (dev, cmd, arg);
- return 0;
- }
- break;
-
- case SNDCTL_SYNTH_INFO:
- {
- struct synth_info inf;
- int dev;
-
- IOCTL_FROM_USER ((char *) &inf, (char *) arg, 0, sizeof (inf));
- dev = inf.device;
-
- if (dev < 0 || dev >= max_synthdev)
- return RET_ERROR (ENXIO);
-
- if (!(synth_open_mask & (1 << dev)) && !orig_dev)
- return RET_ERROR (EBUSY);
-
- return synth_devs[dev]->ioctl (dev, cmd, arg);
- }
- break;
-
- case SNDCTL_SEQ_OUTOFBAND:
- {
- struct seq_event_rec event;
- unsigned long flags;
-
- IOCTL_FROM_USER ((char *) &event, (char *) arg, 0, sizeof (event));
-
- DISABLE_INTR (flags);
- play_event (event.arr);
- RESTORE_INTR (flags);
-
- return 0;
- }
- break;
-
- case SNDCTL_MIDI_INFO:
- {
- struct midi_info inf;
- int dev;
-
- IOCTL_FROM_USER ((char *) &inf, (char *) arg, 0, sizeof (inf));
- dev = inf.device;
-
- if (dev < 0 || dev >= max_mididev)
- return RET_ERROR (ENXIO);
-
- IOCTL_TO_USER ((char *) arg, 0, (char *) &(midi_devs[dev]->info), sizeof (inf));
- return 0;
- }
- break;
-
- case SNDCTL_PMGR_IFACE:
- {
- struct patmgr_info *inf;
- int dev, err;
-
- if ((inf = (struct patmgr_info *) KERNEL_MALLOC (sizeof (*inf))) == NULL)
- {
- printk ("patmgr: Can't allocate memory for a message\n");
- return RET_ERROR (EIO);
- }
-
- IOCTL_FROM_USER ((char *) inf, (char *) arg, 0, sizeof (*inf));
- dev = inf->device;
-
- if (dev < 0 || dev >= num_synths)
- {
- KERNEL_FREE (inf);
- return RET_ERROR (ENXIO);
- }
-
- if (!synth_devs[dev]->pmgr_interface)
- {
- KERNEL_FREE (inf);
- return RET_ERROR (ENXIO);
- }
-
- if ((err = synth_devs[dev]->pmgr_interface (dev, inf)) == -1)
- {
- KERNEL_FREE (inf);
- return err;
- }
-
- IOCTL_TO_USER ((char *) arg, 0, (char *) inf, sizeof (*inf));
- KERNEL_FREE (inf);
- return 0;
- }
- break;
-
- case SNDCTL_PMGR_ACCESS:
- {
- struct patmgr_info *inf;
- int dev, err;
-
- if ((inf = (struct patmgr_info *) KERNEL_MALLOC (sizeof (*inf))) == NULL)
- {
- printk ("patmgr: Can't allocate memory for a message\n");
- return RET_ERROR (EIO);
- }
-
- IOCTL_FROM_USER ((char *) inf, (char *) arg, 0, sizeof (*inf));
- dev = inf->device;
-
- if (dev < 0 || dev >= num_synths)
- {
- KERNEL_FREE (inf);
- return RET_ERROR (ENXIO);
- }
-
- if (!pmgr_present[dev])
- {
- KERNEL_FREE (inf);
- return RET_ERROR (ESRCH);
- }
-
- if ((err = pmgr_access (dev, inf)) < 0)
- {
- KERNEL_FREE (inf);
- return err;
- }
-
- IOCTL_TO_USER ((char *) arg, 0, (char *) inf, sizeof (*inf));
- KERNEL_FREE (inf);
- return 0;
- }
- break;
-
- case SNDCTL_SEQ_TRESHOLD:
- {
- int tmp = IOCTL_IN (arg);
-
- if (dev) /*
- * Patch manager
- */
- return RET_ERROR (EIO);
-
- if (tmp < 1)
- tmp = 1;
- if (tmp >= SEQ_MAX_QUEUE)
- tmp = SEQ_MAX_QUEUE - 1;
- output_treshold = tmp;
- return 0;
- }
- break;
-
- case SNDCTL_MIDI_PRETIME:
- {
- int val = IOCTL_IN (arg);
-
- if (val < 0)
- val = 0;
-
- val = (HZ * val) / 10;
- pre_event_timeout = val;
- return IOCTL_OUT (arg, val);
- }
- break;
-
- default:
- if (dev) /*
- * Patch manager
- */
- return RET_ERROR (EIO);
-
- if (mode == OPEN_READ)
- return RET_ERROR (EIO);
-
- if (!synth_devs[0])
- return RET_ERROR (ENXIO);
- if (!(synth_open_mask & (1 << 0)))
- return RET_ERROR (ENXIO);
- return synth_devs[0]->ioctl (0, cmd, arg);
- break;
- }
-
- return RET_ERROR (EINVAL);
-}
-
-#ifdef ALLOW_SELECT
-int
-sequencer_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
-{
- unsigned long flags;
-
- dev = dev >> 4;
-
- switch (sel_type)
- {
- case SEL_IN:
- DISABLE_INTR (flags);
- if (!iqlen)
- {
-#if defined(__FreeBSD__)
- selrecord(wait, &selinfo[dev]);
-#else
- midi_sleep_flag.mode = WK_SLEEP;
- select_wait (&midi_sleeper, wait);
-#endif
- RESTORE_INTR (flags);
- return 0;
- }
- midi_sleep_flag.mode &= ~WK_SLEEP;
- RESTORE_INTR (flags);
- return 1;
- break;
-
- case SEL_OUT:
- DISABLE_INTR (flags);
- if (qlen >= SEQ_MAX_QUEUE)
- {
-#if defined(__FreeBSD__)
- selrecord(wait, &selinfo[dev]);
-#else
- seq_sleep_flag.mode = WK_SLEEP;
- select_wait (&seq_sleeper, wait);
-#endif
- RESTORE_INTR (flags);
- return 0;
- }
- seq_sleep_flag.mode &= ~WK_SLEEP;
- RESTORE_INTR (flags);
- return 1;
- break;
-
- case SEL_EX:
- return 0;
- }
-
- return 0;
-}
-
-#endif
-
-void
-sequencer_timer (void)
-{
- seq_startplay ();
-}
-
-int
-note_to_freq (int note_num)
-{
-
- /*
- * This routine converts a midi note to a frequency (multiplied by 1000)
- */
-
- int note, octave, note_freq;
- int notes[] =
- {
- 261632, 277189, 293671, 311132, 329632, 349232,
- 369998, 391998, 415306, 440000, 466162, 493880
- };
-
-#define BASE_OCTAVE 5
-
- octave = note_num / 12;
- note = note_num % 12;
-
- note_freq = notes[note];
-
- if (octave < BASE_OCTAVE)
- note_freq >>= (BASE_OCTAVE - octave);
- else if (octave > BASE_OCTAVE)
- note_freq <<= (octave - BASE_OCTAVE);
-
- /*
- * note_freq >>= 1;
- */
-
- return note_freq;
-}
-
-unsigned long
-compute_finetune (unsigned long base_freq, int bend, int range)
-{
- unsigned long amount;
- int negative, semitones, cents, multiplier = 1;
-
- if (!bend)
- return base_freq;
- if (!range)
- return base_freq;
-
- if (!base_freq)
- return base_freq;
-
- if (range >= 8192)
- range = 8191;
-
- bend = bend * range / 8192;
- if (!bend)
- return base_freq;
-
- negative = bend < 0 ? 1 : 0;
-
- if (bend < 0)
- bend *= -1;
- if (bend > range)
- bend = range;
-
- /*
- if (bend > 2399)
- bend = 2399;
- */
- while (bend > 2399)
- {
- multiplier *= 4;
- bend -= 2400;
- }
-
- semitones = bend / 100;
- cents = bend % 100;
-
- amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents])
- / 10000;
-
- if (negative)
- return (base_freq * 10000) / amount; /*
- * Bend down
- */
- else
- return (base_freq * amount) / 10000; /*
- * Bend up
- */
-}
-
-
-long
-sequencer_init (long mem_start)
-{
-
- sequencer_ok = 1;
- PERMANENT_MALLOC (unsigned char *, queue, SEQ_MAX_QUEUE * EV_SZ, mem_start);
- PERMANENT_MALLOC (unsigned char *, iqueue, SEQ_MAX_QUEUE * IEV_SZ, mem_start);
-
- return mem_start;
-}
-
-#else
-/*
- * Stub version
- */
-int
-sequencer_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- return RET_ERROR (EIO);
-}
-
-int
-sequencer_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- return RET_ERROR (EIO);
-}
-
-int
-sequencer_open (int dev, struct fileinfo *file)
-{
- return RET_ERROR (ENXIO);
-}
-
-void
-sequencer_release (int dev, struct fileinfo *file)
-{
-}
-int
-sequencer_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned int arg)
-{
- return RET_ERROR (EIO);
-}
-
-int
-sequencer_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
-{
- return RET_ERROR (EIO);
-}
-
-long
-sequencer_init (long mem_start)
-{
- return mem_start;
-}
-
-#ifdef ALLOW_SELECT
-int
-sequencer_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
-{
- return RET_ERROR (EIO);
-}
-
-#endif
-
-#endif
-
-#endif
diff --git a/sys/pc98/pc98/sound/sound.doc b/sys/pc98/pc98/sound/sound.doc
deleted file mode 100644
index 002bb26..0000000
--- a/sys/pc98/pc98/sound/sound.doc
+++ /dev/null
@@ -1,120 +0,0 @@
-$Id: sound.doc,v 1.6 1996/04/11 15:34:22 smpatel Exp $
-
-Instructions on using audio on a FreeBSD 2.1 (or 2.0-current) system.
-See also /sys/i386/conf/LINT.
-
-To enable sound driver support, the controller sound code must be included
-in your config file:
-
-# SB = SoundBlaster; PAS = ProAudioSpectrum; GUS = Gravis UltraSound
-# Controls all sound devices
-controller snd0
-
-Uncomment one or more of these device entries, depending on what type of
-sound card you have:
-
-# ProAudioSpectrum PCM and Midi - for PAS
-#device pas0 at isa? port 0x388 irq 10 drq 6 vector pasintr
-
-# SoundBlaster DSP driver - for SB, SB Pro, SB16, PAS(emulating SB)
-#device sb0 at isa? port 0x220 irq 7 drq 1 vector sbintr
-
-# SoundBlaster 16 DSP driver - for SB16 - requires sb0 device
-#device sbxvi0 at isa? drq 5
-
-# SoundBlaster 16 MIDI - for SB16 - requires sb0 device
-#device sbmidi0 at isa? port 0x300
-
-# Gravis UltraSound - for GUS, GUS16, GUSMAX
-# For cards that use 2 DMA Channels:
-# drq = Write DMA Channel, flags = Read DMA Channel
-#device gus0 at isa? port 0x220 irq 11 drq 1 flags 0x3 vector gusintr
-
-# Gravis UltraSound 16 bit option - for GUS16 - requires gus0
-#device gusxvi0 at isa? port 0x530 irq 7 drq 3 vector adintr
-
-# MS Sound System (AD1848 Based Boards)
-#device mss0 at isa? port 0x530 irq 10 drq 1 vector adintr
-
-# Yamaha OPL-2/OPL-3 FM - for SB, SB Pro, SB16, PAS
-#device opl0 at isa? port 0x388
-
-# MPU-401 - for MPU-401 standalone card
-#device mpu0 at isa? port 0x330 irq 6 drq 0
-
-# 6850 UART Midi
-#device uart0 at isa? port 0x330 irq 5 vector "m6850intr"
-
-You may add one or more of the following depending on what you do and don't
-want compiled into your kernel. Note: Excluding things with EXCLUDE_...
-is NOT recommended unless you really know what you're doing.
-
-#options EXCLUDE_AUDIO # NO digital audio support
-#options EXCLUDE_SEQUENCER # NO sequencer support
-#options EXCLUDE_MIDI # NO MIDI support whatsoever
-#options EXCLUDE_SBPRO # EXCLUDE SB Pro support
-#options EXCLUDE_SB_EMULATION # NO PAS SB emulation support
-#options EXCLUDE_GUS_IODETECT # NO GUS io detection
-#options EXCLUDE_PRO_MIDI # NO PAS MIDI support
-
-Other Options:
-
-#options SYMPHONY_PAS
- Adds some code to make pas work with Symphony chipsets. Only use
- this if your pas doesn't work and you have a Symphony chipset.
-
-#options BROKEN_BUS_CLOCK
- Some systems with the OPTI chipset and a PAS will require you to
- use this option. Symptoms are that you will hear a lot of clicking and
- popping sounds, like a geiger counter, coming out of the PAS even when
- it is not playing anything.
-
-#options MOZART_PORT
- Adds support for Mozart (OAK OTI-601). (Part of the MSS driver)
-
-#options OPTI_MAD16_PORT
- Adds support for the OPTI MAD16 Chip. (Part of the MSS driver)
- If your soundcard has a chip labeled "OPTi 82C929" then try this.
-
-#options __SGNXPRO__
- Adds support for the SG NX Pro mixer. (Part of the SB driver)
-
-#options JAZZ16
- Adds support for the MV Jazz16 (ProSonic etc). (Part of the SB Driver)
-
-#options SM_WAVE
- Adds support for the SoundMan Wave (Part of the SB Driver)
- Note: You will need to do some work to get this to work.
- See i386/isa/sound/configure.c
-
-#options SM_GAMES
- Adds support for the Logitech SoundMan Games (Part of the SB Driver)
-
-#options PAS_JOYSTICK_ENABLE
- Enables the gameport on the ProAudio Spectrum
-
-NOTE: The MPU-401 driver may or may not work, and is unfortunately
-unverifiable since no one I know has one. If you can test this,
-please let me know! Also note that you will have to change these
-settings if your soundcard is set for a non-standard address or IRQ.
-Please check your documentation (or verify with any provided DOS utilities
-that may have come with your card) and set the IRQ or address fields
-accordingly.
-
-
-Also: You can configure more then one card on a single DMA using
-the conflicts keyword in your configuration file. This is useful for boards
-with more then one type of emulation.
-
-
-Probing problems: Since the SB16 uses the same IRQ and addresses for
-the different drivers, some of the snd drivers will not be probed because
-the kernel thinks there is a conflict. This can be worked-around by
-using the "conflicts" keyword on the sb16's device line.
-
-
-For further information, contact multimedia@freebsd.org
-
- - Jordan Hubbard (jkh@freefall.cdrom.com)
- - Steven Wallace (swallace@freefall.cdrom.com)
- - Sujal Patel (smpatel@wam.umd.edu)
diff --git a/sys/pc98/pc98/sound/sound_calls.h b/sys/pc98/pc98/sound/sound_calls.h
deleted file mode 100644
index d52da0b..0000000
--- a/sys/pc98/pc98/sound/sound_calls.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * DMA buffer calls
- */
-
-int DMAbuf_open(int dev, int mode);
-int DMAbuf_release(int dev, int mode);
-int DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock);
-int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock);
-int DMAbuf_rmchars(int dev, int buff_no, int c);
-int DMAbuf_start_output(int dev, int buff_no, int l);
-int DMAbuf_ioctl(int dev, unsigned int cmd, unsigned int arg, int local);
-long DMAbuf_init(long mem_start);
-int DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode);
-int DMAbuf_open_dma (int dev);
-void DMAbuf_close_dma (int dev);
-void DMAbuf_reset_dma (int dev);
-void DMAbuf_inputintr(int dev);
-void DMAbuf_outputintr(int dev, int underflow_flag);
-#ifdef ALLOW_SELECT
-int DMAbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
-#endif
-
-/*
- * System calls for /dev/dsp and /dev/audio
- */
-
-int audio_read (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int audio_write (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int audio_open (int dev, struct fileinfo *file);
-void audio_release (int dev, struct fileinfo *file);
-int audio_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned int arg);
-int audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig);
-long audio_init (long mem_start);
-
-#ifdef ALLOW_SELECT
-int audio_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
-#endif
-
-/*
- * System calls for the /dev/sequencer
- */
-
-int sequencer_read (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int sequencer_write (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int sequencer_open (int dev, struct fileinfo *file);
-void sequencer_release (int dev, struct fileinfo *file);
-int sequencer_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned int arg);
-int sequencer_lseek (int dev, struct fileinfo *file, off_t offset, int orig);
-long sequencer_init (long mem_start);
-void sequencer_timer(void);
-int note_to_freq(int note_num);
-unsigned long compute_finetune(unsigned long base_freq, int bend, int range);
-void seq_input_event(unsigned char *event, int len);
-void seq_copy_to_input (unsigned char *event, int len);
-
-#ifdef ALLOW_SELECT
-int sequencer_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
-#endif
-
-/*
- * System calls for the /dev/midi
- */
-
-int MIDIbuf_read (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int MIDIbuf_write (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int MIDIbuf_open (int dev, struct fileinfo *file);
-void MIDIbuf_release (int dev, struct fileinfo *file);
-int MIDIbuf_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned int arg);
-int MIDIbuf_lseek (int dev, struct fileinfo *file, off_t offset, int orig);
-void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
-long MIDIbuf_init(long mem_start);
-
-#ifdef ALLOW_SELECT
-int MIDIbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
-#endif
-
-/*
- * System calls for the generic midi interface.
- *
- */
-
-long CMIDI_init (long mem_start);
-int CMIDI_open (int dev, struct fileinfo *file);
-int CMIDI_write (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int CMIDI_read (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int CMIDI_close (int dev, struct fileinfo *file);
-
-/*
- *
- * Misc calls from various sources
- */
-
-/* From soundcard.c */
-long soundcard_init(long mem_start);
-void tenmicrosec(void);
-void request_sound_timer (int count);
-void sound_stop_timer(void);
-int snd_set_irq_handler (int interrupt_level, INT_HANDLER_PROTO(), char *name);
-void snd_release_irq(int vect);
-void sound_dma_malloc(int dev);
-void sound_dma_free(int dev);
-
-/* From sound_switch.c */
-int sound_read_sw (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int sound_write_sw (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int sound_open_sw (int dev, struct fileinfo *file);
-void sound_release_sw (int dev, struct fileinfo *file);
-int sound_ioctl_sw (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned long arg);
-
-/* From sb_dsp.c */
-int sb_dsp_detect (struct address_info *hw_config);
-long sb_dsp_init (long mem_start, struct address_info *hw_config);
-void sb_dsp_disable_midi(void);
-int sb_get_irq(void);
-void sb_free_irq(void);
-int sb_dsp_command (unsigned char val);
-int sb_reset_dsp (void);
-
-/* From sb16_dsp.c */
-void sb16_dsp_interrupt (int irq);
-long sb16_dsp_init(long mem_start, struct address_info *hw_config);
-int sb16_dsp_detect(struct address_info *hw_config);
-
-/* From sb16_midi.c */
-void sb16midiintr (int unit);
-long attach_sb16midi(long mem_start, struct address_info * hw_config);
-int probe_sb16midi(struct address_info *hw_config);
-void sb_midi_interrupt(int dummy);
-
-/* From sb_midi.c */
-void sb_midi_init(int model);
-
-/* From sb_mixer.c */
-void sb_setmixer (unsigned int port, unsigned int value);
-int sb_getmixer (unsigned int port);
-void sb_mixer_set_stereo(int mode);
-int sb_mixer_init(int major_model);
-
-/* From opl3.c */
-int opl3_detect (int ioaddr);
-long opl3_init(long mem_start);
-
-/* From sb_card.c */
-long attach_sb_card(long mem_start, struct address_info *hw_config);
-int probe_sb(struct address_info *hw_config);
-
-/* From adlib_card.c */
-long attach_adlib_card(long mem_start, struct address_info *hw_config);
-int probe_adlib(struct address_info *hw_config);
-
-/* From pas_card.c */
-long attach_pas_card(long mem_start, struct address_info *hw_config);
-int probe_pas(struct address_info *hw_config);
-int pas_set_intr(int mask);
-int pas_remove_intr(int mask);
-unsigned char pas_read(int ioaddr);
-void pas_write(unsigned char data, int ioaddr);
-
-/* From pas_audio.c */
-void pas_pcm_interrupt(unsigned char status, int cause);
-long pas_pcm_init(long mem_start, struct address_info *hw_config);
-
-/* From pas_mixer.c */
-int pas_init_mixer(void);
-
-/* From pas_midi.c */
-long pas_midi_init(long mem_start);
-void pas_midi_interrupt(void);
-
-/* From gus_card.c */
-long attach_gus_card(long mem_start, struct address_info * hw_config);
-int probe_gus(struct address_info *hw_config);
-int gus_set_midi_irq(int num);
-long attach_gus_db16(long mem_start, struct address_info * hw_config);
-int probe_gus_db16(struct address_info *hw_config);
-
-/* From gus_wave.c */
-int gus_wave_detect(int baseaddr);
-long gus_wave_init(long mem_start, int irq, int dma, int dma_read);
-void gus_voice_irq(void);
-void gus_write8(int reg, unsigned int data);
-void guswave_dma_irq(void);
-void gus_delay(void);
-int gus_default_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg);
-
-/* From gus_midi.c */
-long gus_midi_init(long mem_start);
-void gus_midi_interrupt(int dummy);
-
-/* From mpu401.c */
-long attach_mpu401(long mem_start, struct address_info * hw_config);
-int probe_mpu401(struct address_info *hw_config);
-void mpuintr(INT_HANDLER_PARMS(irq, dummy));
-
-/* From uart6850.c */
-long attach_uart6850(long mem_start, struct address_info * hw_config);
-int probe_uart6850(struct address_info *hw_config);
-
-/* From opl3.c */
-void enable_opl3_mode(int left, int right, int both);
-
-/* From patmgr.c */
-int pmgr_open(int dev);
-void pmgr_release(int dev);
-int pmgr_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count);
-int pmgr_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count);
-int pmgr_access(int dev, struct patmgr_info *rec);
-int pmgr_inform(int dev, int event, unsigned long parm1, unsigned long parm2,
- unsigned long parm3, unsigned long parm4);
-
-/* From ics2101.c */
-long ics2101_mixer_init(long mem_start);
-
-/* From sound_timer.c */
-void sound_timer_init(int io_base);
-void sound_timer_interrupt(void);
-
-/* From ad1848.c */
-void ad1848_init (char *name, int io_base, int irq, int dma_playback, int dma_capture);
-int ad1848_detect (int io_base);
-void ad1848_interrupt (INT_HANDLER_PARMS(irq, dummy));
-long attach_ms_sound(long mem_start, struct address_info * hw_config);
-int probe_ms_sound(struct address_info *hw_config);
-
-/* From pss.c */
-int probe_pss (struct address_info *hw_config);
-long attach_pss (long mem_start, struct address_info *hw_config);
-int probe_pss_mpu (struct address_info *hw_config);
-long attach_pss_mpu (long mem_start, struct address_info *hw_config);
-int probe_pss_mss (struct address_info *hw_config);
-long attach_pss_mss (long mem_start, struct address_info *hw_config);
-
-/* From sscape.c */
-int probe_sscape (struct address_info *hw_config);
-long attach_sscape (long mem_start, struct address_info *hw_config);
-int probe_ss_ms_sound (struct address_info *hw_config);
-long attach_ss_ms_sound(long mem_start, struct address_info * hw_config);
-
-int pss_read (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int pss_write (int dev, struct fileinfo *file, snd_rw_buf *buf, int count);
-int pss_open (int dev, struct fileinfo *file);
-void pss_release (int dev, struct fileinfo *file);
-int pss_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned int arg);
-int pss_lseek (int dev, struct fileinfo *file, off_t offset, int orig);
-long pss_init(long mem_start);
-
-#ifdef PC98
-/* From pcm86.c */
-int probe_pcm86(struct address_info *hw_config);
-long attach_pcm86(long mem_start, struct address_info *hw_config);
-#endif PC98
-
-/* From aedsp16.c */
-int InitAEDSP16_SBPRO(struct address_info *hw_config);
-int InitAEDSP16_MSS(struct address_info *hw_config);
-int InitAEDSP16_MPU401(struct address_info *hw_config);
-
-/* From midi_synth.c */
-void do_midi_msg (int synthno, unsigned char *msg, int mlen);
-
-/* From trix.c */
-long attach_trix_wss (long mem_start, struct address_info *hw_config);
-int probe_trix_wss (struct address_info *hw_config);
-long attach_trix_sb (long mem_start, struct address_info *hw_config);
-int probe_trix_sb (struct address_info *hw_config);
-long attach_trix_mpu (long mem_start, struct address_info *hw_config);
-int probe_trix_mpu (struct address_info *hw_config);
diff --git a/sys/pc98/pc98/sound/sound_switch.c b/sys/pc98/pc98/sound/sound_switch.c
index 551c1c1..83994e0 100644
--- a/sys/pc98/pc98/sound/sound_switch.c
+++ b/sys/pc98/pc98/sound/sound_switch.c
@@ -27,11 +27,7 @@
*
*/
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
#include <i386/isa/sound/sound_config.h>
-#endif
#ifdef CONFIGURE_SOUNDCARD
diff --git a/sys/pc98/pc98/sound/sound_timer.c b/sys/pc98/pc98/sound/sound_timer.c
deleted file mode 100644
index 8e4e002..0000000
--- a/sys/pc98/pc98/sound/sound_timer.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * sound/sound_timer.c
- *
- * Timer for the level 2 interface of the /dev/sequencer. Uses the
- * 80 and 320 usec timers of OPL-3 (PAS16 only) and GUS.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#define SEQUENCER_C
-#include <i386/isa/sound/sound_config.h>
-
-#ifdef CONFIGURE_SOUNDCARD
-
-#if !defined(EXCLUDE_SEQUENCER) && (!defined(EXCLUDE_GUS) || (!defined(EXCLUDE_PAS) && !defined(EXCLUDE_YM3812)))
-
-static volatile int initialized = 0, opened = 0, tmr_running = 0;
-static volatile time_t tmr_offs, tmr_ctr;
-static volatile unsigned long ticks_offs;
-static volatile int curr_tempo, curr_timebase;
-static volatile unsigned long curr_ticks;
-static volatile unsigned long next_event_time;
-static unsigned long prev_event_time;
-static volatile int select_addr, data_addr;
-static volatile int curr_timer = 0;
-static volatile unsigned long usecs_per_tmr; /* Length of the current interval */
-
-
-static void
-timer_command (unsigned int addr, unsigned int val)
-{
- int i;
-
- OUTB ((unsigned char) (addr & 0xff), select_addr);
-
- for (i = 0; i < 2; i++)
- INB (select_addr);
-
- OUTB ((unsigned char) (val & 0xff), data_addr);
-
- for (i = 0; i < 2; i++)
- INB (select_addr);
-}
-
-static void
-arm_timer (int timer, unsigned int interval)
-{
-
- curr_timer = timer;
-
- if (timer == 1)
- {
- gus_write8 (0x46, 256 - interval); /* Set counter for timer 1 */
- gus_write8 (0x45, 0x04); /* Enable timer 1 IRQ */
- timer_command (0x04, 0x01); /* Start timer 1 */
- }
- else
- {
- gus_write8 (0x47, 256 - interval); /* Set counter for timer 2 */
- gus_write8 (0x45, 0x08); /* Enable timer 2 IRQ */
- timer_command (0x04, 0x02); /* Start timer 2 */
- }
-}
-
-static unsigned long
-tmr2ticks (int tmr_value)
-{
- /*
- * Convert timer ticks to MIDI ticks
- */
-
- unsigned long tmp;
- unsigned long scale;
-
- tmp = tmr_value * usecs_per_tmr; /* Convert to usecs */
-
- scale = (60 * 1000000) / (curr_tempo * curr_timebase); /* usecs per MIDI tick */
-
- return (tmp + (scale / 2)) / scale;
-}
-
-static void
-reprogram_timer (void)
-{
- unsigned long usecs_per_tick;
- int timer_no, resolution;
- int divisor;
-
- usecs_per_tick = (60 * 1000000) / (curr_tempo * curr_timebase);
-
- /*
- * Don't kill the system by setting too high timer rate
- */
- if (usecs_per_tick < 2000)
- usecs_per_tick = 2000;
-
- if (usecs_per_tick > (256 * 80))
- {
- timer_no = 2;
- resolution = 320; /* usec */
- }
- else
- {
- timer_no = 1;
- resolution = 80; /* usec */
- }
-
- divisor = (usecs_per_tick + (resolution / 2)) / resolution;
- usecs_per_tmr = divisor * resolution;
-
- arm_timer (timer_no, divisor);
-}
-
-static void
-tmr_reset (void)
-{
- unsigned long flags;
-
- DISABLE_INTR (flags);
- tmr_offs = 0;
- ticks_offs = 0;
- tmr_ctr = 0;
- next_event_time = 0xffffffff;
- prev_event_time = 0;
- curr_ticks = 0;
- RESTORE_INTR (flags);
-}
-
-static int
-timer_open (int dev, int mode)
-{
- if (opened)
- return RET_ERROR (EBUSY);
-
- tmr_reset ();
- curr_tempo = 60;
- curr_timebase = HZ;
- opened = 1;
- reprogram_timer ();
-
- return 0;
-}
-
-static void
-timer_close (int dev)
-{
- opened = tmr_running = 0;
- gus_write8 (0x45, 0); /* Disable both timers */
-}
-
-static int
-timer_event (int dev, unsigned char *event)
-{
- unsigned char cmd = event[1];
- unsigned long parm = *(int *) &event[4];
-
- switch (cmd)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- if (parm <= curr_ticks) /* It's the time */
- return TIMER_NOT_ARMED;
-
- time = parm;
- next_event_time = prev_event_time = time;
-
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- tmr_reset ();
- tmr_running = 1;
- reprogram_timer ();
- break;
-
- case TMR_STOP:
- tmr_running = 0;
- break;
-
- case TMR_CONTINUE:
- tmr_running = 1;
- reprogram_timer ();
- break;
-
- case TMR_TEMPO:
- if (parm)
- {
- if (parm < 8)
- parm = 8;
- if (parm > 250)
- parm = 250;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks (tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = parm;
- reprogram_timer ();
- }
- break;
-
- case TMR_ECHO:
- seq_copy_to_input (event, 8);
- break;
-
- default:;
- }
-
- return TIMER_NOT_ARMED;
-}
-
-static unsigned long
-timer_get_time (int dev)
-{
- if (!opened)
- return 0;
-
- return curr_ticks;
-}
-
-static int
-timer_ioctl (int dev,
- unsigned int cmd, unsigned int arg)
-{
- switch (cmd)
- {
- case SNDCTL_TMR_SOURCE:
- return IOCTL_OUT (arg, TMR_INTERNAL);
- break;
-
- case SNDCTL_TMR_START:
- tmr_reset ();
- tmr_running = 1;
- return 0;
- break;
-
- case SNDCTL_TMR_STOP:
- tmr_running = 0;
- return 0;
- break;
-
- case SNDCTL_TMR_CONTINUE:
- tmr_running = 1;
- return 0;
- break;
-
- case SNDCTL_TMR_TIMEBASE:
- {
- int val = IOCTL_IN (arg);
-
- if (val)
- {
- if (val < 1)
- val = 1;
- if (val > 1000)
- val = 1000;
- curr_timebase = val;
- }
-
- return IOCTL_OUT (arg, curr_timebase);
- }
- break;
-
- case SNDCTL_TMR_TEMPO:
- {
- int val = IOCTL_IN (arg);
-
- if (val)
- {
- if (val < 8)
- val = 8;
- if (val > 250)
- val = 250;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks (tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = val;
- reprogram_timer ();
- }
-
- return IOCTL_OUT (arg, curr_tempo);
- }
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- if (IOCTL_IN (arg) != 0) /* Can't change */
- return RET_ERROR (EINVAL);
-
- return IOCTL_OUT (arg, ((curr_tempo * curr_timebase) + 30) / 60);
- break;
-
- case SNDCTL_TMR_METRONOME:
- /* NOP */
- break;
-
- default:
- }
-
- return RET_ERROR (EINVAL);
-}
-
-static void
-timer_arm (int dev, long time)
-{
- if (time < 0)
- time = curr_ticks + 1;
- else if (time <= curr_ticks) /* It's the time */
- return;
-
- next_event_time = prev_event_time = time;
-
- return;
-}
-
-static struct sound_timer_operations sound_timer =
-{
- {"OPL-3/GUS Timer", 0},
- 1, /* Priority */
- 0, /* Local device link */
- timer_open,
- timer_close,
- timer_event,
- timer_get_time,
- timer_ioctl,
- timer_arm
-};
-
-void
-sound_timer_interrupt (void)
-{
- gus_write8 (0x45, 0); /* Ack IRQ */
- timer_command (4, 0x80); /* Reset IRQ flags */
-
- if (!opened)
- return;
-
- if (curr_timer == 1)
- gus_write8 (0x45, 0x04); /* Start timer 1 again */
- else
- gus_write8 (0x45, 0x08); /* Start timer 2 again */
-
- if (!tmr_running)
- return;
-
- tmr_ctr++;
- curr_ticks = ticks_offs + tmr2ticks (tmr_ctr);
-
- if (curr_ticks >= next_event_time)
- {
- next_event_time = 0xffffffff;
- sequencer_timer ();
- }
-}
-
-void
-sound_timer_init (int io_base)
-{
- int n;
-
- if (initialized)
- return; /* There is already a similar timer */
-
- select_addr = io_base;
- data_addr = io_base + 1;
-
- initialized = 1;
-
-#if 1
- if (num_sound_timers >= MAX_TIMER_DEV)
- n = 0; /* Overwrite the system timer */
- else
- n = num_sound_timers++;
-#else
- n = 0;
-#endif
-
- sound_timer_devs[n] = &sound_timer;
-}
-
-#endif
-#endif
diff --git a/sys/pc98/pc98/sound/soundcard.c b/sys/pc98/pc98/sound/soundcard.c
index 6a85fb9..1709503 100644
--- a/sys/pc98/pc98/sound/soundcard.c
+++ b/sys/pc98/pc98/sound/soundcard.c
@@ -26,24 +26,16 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: soundcard.c,v 1.5 1996/09/12 11:11:59 asami Exp $
+ * $Id: soundcard.c,v 1.6 1996/10/29 08:36:59 asami Exp $
*/
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
#include <i386/isa/sound/sound_config.h>
-#endif
#include <vm/vm.h>
#include <vm/vm_extern.h>
#ifdef CONFIGURE_SOUNDCARD
-#ifdef PC98
-#include <pc98/pc98/sound/dev_table.h>
-#else
#include <i386/isa/sound/dev_table.h>
-#endif
#include <i386/isa/isa_device.h>
#include <sys/conf.h>
#include <sys/kernel.h>
diff --git a/sys/pc98/pc98/sound/sscape.c b/sys/pc98/pc98/sound/sscape.c
deleted file mode 100644
index 23d39ce..0000000
--- a/sys/pc98/pc98/sound/sscape.c
+++ /dev/null
@@ -1,1120 +0,0 @@
-/*
- * sound/sscape.c
- *
- * Low level driver for Ensoniq Soundscape
- *
- * Copyright by Hannu Savolainen 1994
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SSCAPE)
-
-#include <i386/isa/sound/coproc.h>
-
-/*
- * I/O ports
- */
-#define MIDI_DATA 0
-#define MIDI_CTRL 1
-#define HOST_CTRL 2
-#define TX_READY 0x02
-#define RX_READY 0x01
-#define HOST_DATA 3
-#define ODIE_ADDR 4
-#define ODIE_DATA 5
-
-/*
- * Indirect registers
- */
-#define GA_INTSTAT_REG 0
-#define GA_INTENA_REG 1
-#define GA_DMAA_REG 2
-#define GA_DMAB_REG 3
-#define GA_INTCFG_REG 4
-#define GA_DMACFG_REG 5
-#define GA_CDCFG_REG 6
-#define GA_SMCFGA_REG 7
-#define GA_SMCFGB_REG 8
-#define GA_HMCTL_REG 9
-
-/*
- * DMA channel identifiers (A and B)
- */
-#define SSCAPE_DMA_A 0
-#define SSCAPE_DMA_B 1
-
-#define PORT(name) (devc->base+name)
-
-/*
- * Host commands recognized by the OBP microcode
- */
-#define CMD_GEN_HOST_ACK 0x80
-#define CMD_GEN_MPU_ACK 0x81
-#define CMD_GET_BOARD_TYPE 0x82
-#define CMD_SET_CONTROL 0x88
-#define CMD_GET_CONTROL 0x89
-#define CMD_SET_MT32 0x96
-#define CMD_GET_MT32 0x97
-#define CMD_SET_EXTMIDI 0x9b
-#define CMD_GET_EXTMIDI 0x9c
-
-#define CMD_ACK 0x80
-
-typedef struct sscape_info
- {
- int base, irq, dma;
- int ok; /* Properly detected */
- int dma_allocated;
- int my_audiodev;
- int opened;
- }
-
-sscape_info;
-static struct sscape_info dev_info =
-{0};
-static struct sscape_info *devc = &dev_info;
-
-DEFINE_WAIT_QUEUE (sscape_sleeper, sscape_sleep_flag);
-
-#ifdef REVEAL_SPEA
-/* Spea and Reveal have assigned interrupt bits differently than Ensoniq */
-static char valid_interrupts[] =
-{9, 7, 5, 15};
-
-#else
-static char valid_interrupts[] =
-{9, 5, 7, 10};
-
-#endif
-
-static unsigned char
-sscape_read (struct sscape_info *devc, int reg)
-{
- unsigned long flags;
- unsigned char val;
-
- DISABLE_INTR (flags);
- OUTB (reg, PORT (ODIE_ADDR));
- val = INB (PORT (ODIE_DATA));
- RESTORE_INTR (flags);
- return val;
-}
-
-static void
-sscape_write (struct sscape_info *devc, int reg, int data)
-{
- unsigned long flags;
-
- DISABLE_INTR (flags);
- OUTB (reg, PORT (ODIE_ADDR));
- OUTB (data, PORT (ODIE_DATA));
- RESTORE_INTR (flags);
-}
-
-static void
-host_open (struct sscape_info *devc)
-{
- OUTB (0x00, PORT (HOST_CTRL)); /* Put the board to the host mode */
-}
-
-static void
-host_close (struct sscape_info *devc)
-{
- OUTB (0x03, PORT (HOST_CTRL)); /* Put the board to the MIDI mode */
-}
-
-static int
-host_write (struct sscape_info *devc, unsigned char *data, int count)
-{
- unsigned long flags;
- int i, timeout;
-
- DISABLE_INTR (flags);
-
- /*
- * Send the command and data bytes
- */
-
- for (i = 0; i < count; i++)
- {
- for (timeout = 10000; timeout > 0; timeout--)
- if (INB (PORT (HOST_CTRL)) & TX_READY)
- break;
-
- if (timeout <= 0)
- {
- RESTORE_INTR (flags);
- return 0;
- }
-
- OUTB (data[i], PORT (HOST_DATA));
- }
-
-
- RESTORE_INTR (flags);
-
- return 1;
-}
-
-static int
-host_read (struct sscape_info *devc)
-{
- unsigned long flags;
- int timeout;
- unsigned char data;
-
- DISABLE_INTR (flags);
-
- /*
- * Read a byte
- */
-
- for (timeout = 10000; timeout > 0; timeout--)
- if (INB (PORT (HOST_CTRL)) & RX_READY)
- break;
-
- if (timeout <= 0)
- {
- RESTORE_INTR (flags);
- return -1;
- }
-
- data = INB (PORT (HOST_DATA));
-
- RESTORE_INTR (flags);
-
- return data;
-}
-
-static int
-host_command1 (struct sscape_info *devc, int cmd)
-{
- unsigned char buf[10];
-
- buf[0] = (unsigned char) (cmd & 0xff);
-
- return host_write (devc, buf, 1);
-}
-
-static int
-host_command2 (struct sscape_info *devc, int cmd, int parm1)
-{
- unsigned char buf[10];
-
- buf[0] = (unsigned char) (cmd & 0xff);
- buf[1] = (unsigned char) (parm1 & 0xff);
-
- return host_write (devc, buf, 2);
-}
-
-static int
-host_command3 (struct sscape_info *devc, int cmd, int parm1, int parm2)
-{
- unsigned char buf[10];
-
- buf[0] = (unsigned char) (cmd & 0xff);
- buf[1] = (unsigned char) (parm1 & 0xff);
- buf[2] = (unsigned char) (parm2 & 0xff);
-
- return host_write (devc, buf, 3);
-}
-
-static void
-set_mt32 (struct sscape_info *devc, int value)
-{
- host_open (devc);
- host_command2 (devc, CMD_SET_MT32,
- value ? 1 : 0);
- if (host_read (devc) != CMD_ACK)
- {
- printk ("SNDSCAPE: Setting MT32 mode failed\n");
- }
- host_close (devc);
-}
-
-static int
-get_board_type (struct sscape_info *devc)
-{
- int tmp;
-
- host_open (devc);
- if (!host_command1 (devc, CMD_GET_BOARD_TYPE))
- tmp = -1;
- else
- tmp = host_read (devc);
- host_close (devc);
- return tmp;
-}
-
-void
-sscapeintr (INT_HANDLER_PARMS (irq, dummy))
-{
- unsigned char bits, tmp;
- static int debug = 0;
-
- printk ("sscapeintr(0x%02x)\n", (bits = sscape_read (devc, GA_INTSTAT_REG)));
- if (SOMEONE_WAITING (sscape_sleeper, sscape_sleep_flag))
- {
- WAKE_UP (sscape_sleeper, sscape_sleep_flag);
- }
-
- if (bits & 0x02) /* Host interface interrupt */
- {
- printk ("SSCAPE: Host interrupt, data=%02x\n", host_read (devc));
- }
-
-#if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
- if (bits & 0x01)
- {
- mpuintr (INT_HANDLER_CALL (irq));
- if (debug++ > 10) /* Temporary debugging hack */
- {
- sscape_write (devc, GA_INTENA_REG, 0x00); /* Disable all interrupts */
- }
- }
-#endif
-
- /*
- * Acknowledge interrupts (toggle the interrupt bits)
- */
-
- tmp = sscape_read (devc, GA_INTENA_REG);
- sscape_write (devc, GA_INTENA_REG, (~bits & 0x0e) | (tmp & 0xf1));
-
-}
-
-static void
-sscape_enable_intr (struct sscape_info *devc, unsigned intr_bits)
-{
- unsigned char temp, orig;
-
- temp = orig = sscape_read (devc, GA_INTENA_REG);
- temp |= intr_bits;
- temp |= 0x80; /* Master IRQ enable */
-
- if (temp == orig)
- return; /* No change */
-
- sscape_write (devc, GA_INTENA_REG, temp);
-}
-
-static void
-sscape_disable_intr (struct sscape_info *devc, unsigned intr_bits)
-{
- unsigned char temp, orig;
-
- temp = orig = sscape_read (devc, GA_INTENA_REG);
- temp &= ~intr_bits;
- if ((temp & ~0x80) == 0x00)
- temp = 0x00; /* Master IRQ disable */
- if (temp == orig)
- return; /* No change */
-
- sscape_write (devc, GA_INTENA_REG, temp);
-}
-
-static void
-do_dma (struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
-{
- unsigned char temp;
-
- if (dma_chan != SSCAPE_DMA_A)
- {
- printk ("SSCAPE: Tried to use DMA channel != A. Why?\n");
- return;
- }
-
- DMAbuf_start_dma (devc->my_audiodev,
- buf,
- blk_size, mode);
-
- temp = devc->dma << 4; /* Setup DMA channel select bits */
- if (devc->dma <= 3)
- temp |= 0x80; /* 8 bit DMA channel */
-
- temp |= 1; /* Trigger DMA */
- sscape_write (devc, GA_DMAA_REG, temp);
- temp &= 0xfe; /* Clear DMA trigger */
- sscape_write (devc, GA_DMAA_REG, temp);
-}
-
-static int
-verify_mpu (struct sscape_info *devc)
-{
- /*
- * The SoundScape board could be in three modes (MPU, 8250 and host).
- * If the card is not in the MPU mode, enabling the MPU driver will
- * cause infinite loop (the driver believes that there is always some
- * received data in the buffer.
- *
- * Detect this by looking if there are more than 10 received MIDI bytes
- * (0x00) in the buffer.
- */
-
- int i;
-
- for (i = 0; i < 10; i++)
- {
- if (INB (devc->base + HOST_CTRL) & 0x80)
- return 1;
-
- if (INB (devc->base) != 0x00)
- return 1;
- }
-
- printk ("SoundScape: The device is not in the MPU-401 mode\n");
- return 0;
-}
-
-static int
-sscape_coproc_open (void *dev_info, int sub_device)
-{
- if (sub_device == COPR_MIDI)
- {
- set_mt32 (devc, 0);
- if (!verify_mpu (devc))
- return RET_ERROR (EIO);
- }
-
- return 0;
-}
-
-static void
-sscape_coproc_close (void *dev_info, int sub_device)
-{
- struct sscape_info *devc = dev_info;
- unsigned long flags;
-
- DISABLE_INTR (flags);
- if (devc->dma_allocated)
- {
- sscape_write (devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */
-#ifndef EXCLUDE_NATIVE_PCM
- DMAbuf_close_dma (devc->my_audiodev);
-#endif
- devc->dma_allocated = 0;
- }
- RESET_WAIT_QUEUE (sscape_sleeper, sscape_sleep_flag);
- RESTORE_INTR (flags);
-
- return;
-}
-
-static void
-sscape_coproc_reset (void *dev_info)
-{
-}
-
-static int
-sscape_download_boot (struct sscape_info *devc, unsigned char *block, int size, int flag)
-{
- unsigned long flags;
- unsigned char temp;
- int done, timeout;
-
- if (flag & CPF_FIRST)
- {
- /*
- * First block. Have to allocate DMA and to reset the board
- * before continuing.
- */
-
- DISABLE_INTR (flags);
- if (devc->dma_allocated == 0)
- {
-#ifndef EXCLUDE_NATIVE_PCM
- if (DMAbuf_open_dma (devc->my_audiodev) < 0)
- {
- RESTORE_INTR (flags);
- return 0;
- }
-#endif
-
- devc->dma_allocated = 1;
- }
- RESTORE_INTR (flags);
-
- sscape_write (devc, GA_HMCTL_REG,
- (temp = sscape_read (devc, GA_HMCTL_REG)) & 0x3f); /*Reset */
-
- for (timeout = 10000; timeout > 0; timeout--)
- sscape_read (devc, GA_HMCTL_REG); /* Delay */
-
- /* Take board out of reset */
- sscape_write (devc, GA_HMCTL_REG,
- (temp = sscape_read (devc, GA_HMCTL_REG)) | 0x80);
- }
-
- /*
- * Transfer one code block using DMA
- */
- memcpy (audio_devs[devc->my_audiodev]->dmap->raw_buf[0], block, size);
-
- DISABLE_INTR (flags);
-/******** INTERRUPTS DISABLED NOW ********/
- do_dma (devc, SSCAPE_DMA_A,
- audio_devs[devc->my_audiodev]->dmap->raw_buf_phys[0],
- size, DMA_MODE_WRITE);
-
- /*
- * Wait until transfer completes.
- */
- RESET_WAIT_QUEUE (sscape_sleeper, sscape_sleep_flag);
- done = 0;
- timeout = 100;
- while (!done && timeout-- > 0)
- {
- int resid;
-
- DO_SLEEP (sscape_sleeper, sscape_sleep_flag, 1);
- clear_dma_ff (devc->dma);
- if ((resid = get_dma_residue (devc->dma)) == 0)
- done = 1;
- }
-
- RESTORE_INTR (flags);
- if (!done)
- return 0;
-
- if (flag & CPF_LAST)
- {
- /*
- * Take the board out of reset
- */
- OUTB (0x00, PORT (HOST_CTRL));
- OUTB (0x00, PORT (MIDI_CTRL));
-
- temp = sscape_read (devc, GA_HMCTL_REG);
- temp |= 0x40;
- sscape_write (devc, GA_HMCTL_REG, temp); /* Kickstart the board */
-
- /*
- * Wait until the ODB wakes up
- */
-
- DISABLE_INTR (flags);
- done = 0;
- timeout = 5 * HZ;
- while (!done && timeout-- > 0)
- {
- DO_SLEEP (sscape_sleeper, sscape_sleep_flag, 1);
- if (INB (PORT (HOST_DATA)) == 0xff) /* OBP startup acknowledge */
- done = 1;
- }
- RESTORE_INTR (flags);
- if (!done)
- {
- printk ("SoundScape: The OBP didn't respond after code download\n");
- return 0;
- }
-
- DISABLE_INTR (flags);
- done = 0;
- timeout = 5 * HZ;
- while (!done && timeout-- > 0)
- {
- DO_SLEEP (sscape_sleeper, sscape_sleep_flag, 1);
- if (INB (PORT (HOST_DATA)) == 0xfe) /* Host startup acknowledge */
- done = 1;
- }
- RESTORE_INTR (flags);
- if (!done)
- {
- printk ("SoundScape: OBP Initialization failed.\n");
- return 0;
- }
-
- printk ("SoundScape board of type %d initialized OK\n",
- get_board_type (devc));
-
-#ifdef SSCAPE_DEBUG3
- /*
- * Temporary debugging aid. Print contents of the registers after
- * downloading the code.
- */
- {
- int i;
-
- for (i = 0; i < 13; i++)
- printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i));
- }
-#endif
-
- }
-
- return 1;
-}
-
-static int
-download_boot_block (void *dev_info, copr_buffer * buf)
-{
- if (buf->len <= 0 || buf->len > sizeof (buf->data))
- return RET_ERROR (EINVAL);
-
- if (!sscape_download_boot (devc, buf->data, buf->len, buf->flags))
- {
- printk ("SSCAPE: Unable to load microcode block to the OBP.\n");
- return RET_ERROR (EIO);
- }
-
- return 0;
-}
-
-static int
-sscape_coproc_ioctl (void *dev_info, unsigned int cmd, unsigned int arg, int local)
-{
-
- switch (cmd)
- {
- case SNDCTL_COPR_RESET:
- sscape_coproc_reset (dev_info);
- return 0;
- break;
-
- case SNDCTL_COPR_LOAD:
- {
- copr_buffer *buf;
- int err;
-
- buf = (copr_buffer *) KERNEL_MALLOC (sizeof (copr_buffer));
- IOCTL_FROM_USER ((char *) buf, (char *) arg, 0, sizeof (*buf));
- err = download_boot_block (dev_info, buf);
- KERNEL_FREE (buf);
- return err;
- }
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
-
- return RET_ERROR (EINVAL);
-}
-
-static coproc_operations sscape_coproc_operations =
-{
- "SoundScape M68K",
- sscape_coproc_open,
- sscape_coproc_close,
- sscape_coproc_ioctl,
- sscape_coproc_reset,
- &dev_info
-};
-
-static int
-sscape_audio_open (int dev, int mode)
-{
- unsigned long flags;
- sscape_info *devc = (sscape_info *) audio_devs[dev]->devc;
-
- DISABLE_INTR (flags);
- if (devc->opened)
- {
- RESTORE_INTR (flags);
- return RET_ERROR (EBUSY);
- }
-
- if (devc->dma_allocated == 0)
- {
- int err;
-
- if ((err = DMAbuf_open_dma (devc->my_audiodev)) < 0)
- {
- RESTORE_INTR (flags);
- return err;
- }
-
- devc->dma_allocated = 1;
- }
-
- devc->opened = 1;
- RESTORE_INTR (flags);
-#ifdef SSCAPE_DEBUG4
- /*
- * Temporary debugging aid. Print contents of the registers
- * when the device is opened.
- */
- {
- int i;
-
- for (i = 0; i < 13; i++)
- printk ("I%d = %02x\n", i, sscape_read (devc, i));
- }
-#endif
-
- return 0;
-}
-
-static void
-sscape_audio_close (int dev)
-{
- unsigned long flags;
- sscape_info *devc = (sscape_info *) audio_devs[dev]->devc;
-
- DEB (printk ("sscape_audio_close(void)\n"));
-
- DISABLE_INTR (flags);
-
- if (devc->dma_allocated)
- {
- sscape_write (devc, GA_DMAA_REG, 0x20); /* DMA channel disabled */
- DMAbuf_close_dma (dev);
- devc->dma_allocated = 0;
- }
- devc->opened = 0;
-
- RESTORE_INTR (flags);
-}
-
-static int
-set_speed (sscape_info * devc, int arg)
-{
- return 8000;
-}
-
-static int
-set_channels (sscape_info * devc, int arg)
-{
- return 1;
-}
-
-static int
-set_format (sscape_info * devc, int arg)
-{
- return AFMT_U8;
-}
-
-static int
-sscape_audio_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
-{
- sscape_info *devc = (sscape_info *) audio_devs[dev]->devc;
-
- switch (cmd)
- {
- case SOUND_PCM_WRITE_RATE:
- if (local)
- return set_speed (devc, arg);
- return IOCTL_OUT (arg, set_speed (devc, IOCTL_IN (arg)));
-
- case SOUND_PCM_READ_RATE:
- if (local)
- return 8000;
- return IOCTL_OUT (arg, 8000);
-
- case SNDCTL_DSP_STEREO:
- if (local)
- return set_channels (devc, arg + 1) - 1;
- return IOCTL_OUT (arg, set_channels (devc, IOCTL_IN (arg) + 1) - 1);
-
- case SOUND_PCM_WRITE_CHANNELS:
- if (local)
- return set_channels (devc, arg);
- return IOCTL_OUT (arg, set_channels (devc, IOCTL_IN (arg)));
-
- case SOUND_PCM_READ_CHANNELS:
- if (local)
- return 1;
- return IOCTL_OUT (arg, 1);
-
- case SNDCTL_DSP_SAMPLESIZE:
- if (local)
- return set_format (devc, arg);
- return IOCTL_OUT (arg, set_format (devc, IOCTL_IN (arg)));
-
- case SOUND_PCM_READ_BITS:
- if (local)
- return 8;
- return IOCTL_OUT (arg, 8);
-
- default:;
- }
- return RET_ERROR (EINVAL);
-}
-
-static void
-sscape_audio_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
-{
-}
-
-static void
-sscape_audio_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
-{
-}
-
-static int
-sscape_audio_prepare_for_input (int dev, int bsize, int bcount)
-{
- return 0;
-}
-
-static int
-sscape_audio_prepare_for_output (int dev, int bsize, int bcount)
-{
- return 0;
-}
-
-static void
-sscape_audio_halt (int dev)
-{
-}
-
-static void
-sscape_audio_reset (int dev)
-{
- sscape_audio_halt (dev);
-}
-
-static struct audio_operations sscape_audio_operations =
-{
- "Ensoniq SoundScape channel A",
- 0,
- AFMT_U8 | AFMT_S16_LE,
- NULL,
- sscape_audio_open,
- sscape_audio_close,
- sscape_audio_output_block,
- sscape_audio_start_input,
- sscape_audio_ioctl,
- sscape_audio_prepare_for_input,
- sscape_audio_prepare_for_output,
- sscape_audio_reset,
- sscape_audio_halt,
- NULL,
- NULL
-};
-
-long
-attach_sscape (long mem_start, struct address_info *hw_config)
-{
- int my_dev;
-
-#ifndef SSCAPE_REGS
- /*
- * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
- * These values are card
- * dependent. If you have another SoundScape based card, you have to
- * find the correct values. Do the following:
- * - Compile this driver with SSCAPE_DEBUG1 defined.
- * - Shut down and power off your machine.
- * - Boot with DOS so that the SSINIT.EXE program is run.
- * - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
- * when detecting the SoundScape.
- * - Modify the following list to use the values printed during boot.
- * Undefine the SSCAPE_DEBUG1
- */
-#define SSCAPE_REGS { \
-/* I0 */ 0x00, \
- 0xf0, /* Note! Ignored. Set always to 0xf0 */ \
- 0x20, /* Note! Ignored. Set always to 0x20 */ \
- 0x20, /* Note! Ignored. Set always to 0x20 */ \
- 0xf5, /* Ignored */ \
- 0x10, \
- 0x00, \
- 0x2e, /* I7 MEM config A. Likely to vary between models */ \
- 0x00, /* I8 MEM config A. Likely to vary between models */ \
-/* I9 */ 0x40 /* Ignored */ \
- }
-#endif
-
- unsigned long flags;
- static unsigned char regs[10] = SSCAPE_REGS;
-
- int i, irq_bits = 0xff;
-
- if (!probe_sscape (hw_config))
- return mem_start;
-
- printk (" <Ensoniq Soundscape>");
-
- for (i = 0; i < sizeof (valid_interrupts); i++)
- if (hw_config->irq == valid_interrupts[i])
- {
- irq_bits = i;
- break;
- }
-
- if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
- {
- printk ("Invalid IRQ%d\n", hw_config->irq);
- return mem_start;
- }
-
- DISABLE_INTR (flags);
-
- for (i = 1; i < 10; i++)
- switch (i)
- {
- case 1: /* Host interrupt enable */
- sscape_write (devc, i, 0xf0); /* All interrupts enabled */
- break;
-
- case 2: /* DMA A status/trigger register */
- case 3: /* DMA B status/trigger register */
- sscape_write (devc, i, 0x20); /* DMA channel disabled */
- break;
-
- case 4: /* Host interrupt config reg */
- sscape_write (devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
- break;
-
- case 5: /* Don't destroy CD-ROM DMA config bits (0xc0) */
- sscape_write (devc, i, (regs[i] & 0x3f) |
- (sscape_read (devc, i) & 0x0c));
- break;
-
- case 6: /* CD-ROM config. Don't touch. */
- break;
-
- case 9: /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
- sscape_write (devc, i,
- (sscape_read (devc, i) & 0xf0) | 0x00);
- break;
-
- default:
- sscape_write (devc, i, regs[i]);
- }
-
- RESTORE_INTR (flags);
-
-#ifdef SSCAPE_DEBUG2
- /*
- * Temporary debugging aid. Print contents of the registers after
- * changing them.
- */
- {
- int i;
-
- for (i = 0; i < 13; i++)
- printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i));
- }
-#endif
-
-#if !defined(EXCLUDE_MIDI) && !defined(EXCLUDE_MPU_EMU)
- hw_config->always_detect = 1;
- if (probe_mpu401 (hw_config))
- {
- int prev_devs;
-
- prev_devs = num_midis;
- mem_start = attach_mpu401 (mem_start, hw_config);
-
- if (num_midis == (prev_devs + 1)) /* The MPU driver installed itself */
- midi_devs[prev_devs]->coproc = &sscape_coproc_operations;
- }
-#endif
-
-#ifndef EXCLUDE_NATIVE_PCM
- /* Not supported yet */
-
-#ifndef EXCLUDE_AUDIO
- if (num_audiodevs < MAX_AUDIO_DEV)
- {
- audio_devs[my_dev = num_audiodevs++] = &sscape_audio_operations;
- audio_devs[my_dev]->dmachan = hw_config->dma;
- audio_devs[my_dev]->buffcount = 1;
- audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
- audio_devs[my_dev]->devc = devc;
- devc->my_audiodev = my_dev;
- devc->opened = 0;
- audio_devs[my_dev]->coproc = &sscape_coproc_operations;
- if (snd_set_irq_handler (hw_config->irq, sscapeintr, "SoundScape") < 0)
- printk ("Error: Can't allocate IRQ for SoundScape\n");
-
- sscape_write (devc, GA_INTENA_REG, 0x80); /* Master IRQ enable */
- }
- else
- printk ("SoundScape: More than enough audio devices detected\n");
-#endif
-#endif
- devc->ok = 1;
- return mem_start;
-}
-
-int
-probe_sscape (struct address_info *hw_config)
-{
- unsigned char save;
-
- devc->base = hw_config->io_base;
- devc->irq = hw_config->irq;
- devc->dma = hw_config->dma;
-
- /*
- * First check that the address register of "ODIE" is
- * there and that it has exactly 4 writeable bits.
- * First 4 bits
- */
- if ((save = INB (PORT (ODIE_ADDR))) & 0xf0)
- return 0;
-
- OUTB (0x00, PORT (ODIE_ADDR));
- if (INB (PORT (ODIE_ADDR)) != 0x00)
- return 0;
-
- OUTB (0xff, PORT (ODIE_ADDR));
- if (INB (PORT (ODIE_ADDR)) != 0x0f)
- return 0;
-
- OUTB (save, PORT (ODIE_ADDR));
-
- /*
- * Now verify that some indirect registers return zero on some bits.
- * This may break the driver with some future revisions of "ODIE" but...
- */
-
- if (sscape_read (devc, 0) & 0x0c)
- return 0;
-
- if (sscape_read (devc, 1) & 0x0f)
- return 0;
-
- if (sscape_read (devc, 5) & 0x0f)
- return 0;
-
-#ifdef SSCAPE_DEBUG1
- /*
- * Temporary debugging aid. Print contents of the registers before
- * changing them.
- */
- {
- int i;
-
- for (i = 0; i < 13; i++)
- printk ("I%d = %02x (old value)\n", i, sscape_read (devc, i));
- }
-#endif
-
- return 1;
-}
-
-int
-probe_ss_ms_sound (struct address_info *hw_config)
-{
- int i, irq_bits = 0xff;
-
- if (devc->ok == 0)
- {
- printk ("SoundScape: Invalid initialization order.\n");
- return 0;
- }
-
- for (i = 0; i < sizeof (valid_interrupts); i++)
- if (hw_config->irq == valid_interrupts[i])
- {
- irq_bits = i;
- break;
- }
-#ifdef REVEAL_SPEA
- {
- int tmp, status = 0;
- int cc;
-
- if (!((tmp = sscape_read (devc, GA_HMCTL_REG)) & 0xc0))
- {
- sscape_write (devc, GA_HMCTL_REG, tmp | 0x80);
- for (cc = 0; cc < 200000; ++cc)
- INB (devc->base + ODIE_ADDR);
- }
- }
-#endif
-
- if (hw_config->irq > 15 || irq_bits == 0xff)
- {
- printk ("SoundScape: Invalid MSS IRQ%d\n", hw_config->irq);
- return 0;
- }
-
- return ad1848_detect (hw_config->io_base);
-}
-
-long
-attach_ss_ms_sound (long mem_start, struct address_info *hw_config)
-{
- /*
- * This routine configures the SoundScape card for use with the
- * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
- * config registers of the "ODIE".
- */
-
- int i, irq_bits = 0xff;
-
-#ifdef EXCLUDE_NATIVE_PCM
- int prev_devs = num_audiodevs;
-
-#endif
-
- /*
- * Setup the DMA polarity.
- */
- sscape_write (devc, GA_DMACFG_REG, 0x50);
-
- /*
- * Take the gate-arry off of the DMA channel.
- */
- sscape_write (devc, GA_DMAB_REG, 0x20);
-
- /*
- * Init the AD1848 (CD-ROM) config reg.
- */
-
- for (i = 0; i < sizeof (valid_interrupts); i++)
- if (hw_config->irq == valid_interrupts[i])
- {
- irq_bits = i;
- break;
- }
-
- sscape_write (devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) |
- (irq_bits << 1));
-
- if (hw_config->irq == devc->irq)
- printk ("SoundScape: Warning! The WSS mode can't share IRQ with MIDI\n");
-
- ad1848_init ("SoundScape", hw_config->io_base,
- hw_config->irq,
- hw_config->dma,
- hw_config->dma);
-
-#ifdef EXCLUDE_NATIVE_PCM
- if (num_audiodevs == (prev_devs + 1)) /* The AD1848 driver installed itself */
- audio_devs[prev_devs]->coproc = &sscape_coproc_operations;
-#endif
-#ifdef SSCAPE_DEBUG5
- /*
- * Temporary debugging aid. Print contents of the registers
- * after the AD1848 device has been initialized.
- */
- {
- int i;
-
- for (i = 0; i < 13; i++)
- printk ("I%d = %02x\n", i, sscape_read (devc, i));
- }
-#endif
-
- return mem_start;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/sys_timer.c b/sys/pc98/pc98/sound/sys_timer.c
deleted file mode 100644
index 8abeacb..0000000
--- a/sys/pc98/pc98/sound/sys_timer.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * sound/sys_timer.c
- *
- * The default timer for the Level 2 sequencer interface
- * Uses the (100HZ) timer of kernel.
- *
- * Copyright by Hannu Savolainen 1993
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#define SEQUENCER_C
-#ifdef PC98
-#include <pc98/pc98/sound/sound_config.h>
-#else
-#include <i386/isa/sound/sound_config.h>
-#endif
-
-#ifdef CONFIGURE_SOUNDCARD
-
-#ifndef EXCLUDE_SEQUENCER
-
-static volatile int opened = 0, tmr_running = 0;
-static volatile time_t tmr_offs, tmr_ctr;
-static volatile unsigned long ticks_offs;
-static volatile int curr_tempo, curr_timebase;
-static volatile unsigned long curr_ticks;
-static volatile unsigned long next_event_time;
-static unsigned long prev_event_time;
-
-static void poll_def_tmr (unsigned long dummy);
-
-DEFINE_TIMER (def_tmr, poll_def_tmr);
-
-static unsigned long
-tmr2ticks (int tmr_value)
-{
- /*
- * Convert system timer ticks (HZ) to MIDI ticks
- */
-
- unsigned long tmp;
- unsigned long scale;
-
- tmp = (tmr_value * 1000) / HZ; /* Convert to msecs */
-
- scale = (60 * 1000) / (curr_tempo * curr_timebase); /* msecs per MIDI tick */
-
- return (tmp + (scale / 2)) / scale;
-}
-
-static void
-poll_def_tmr (unsigned long dummy)
-{
-
- if (opened)
- {
- ACTIVATE_TIMER (def_tmr, poll_def_tmr, 1);
-
- if (tmr_running)
- {
- tmr_ctr++;
- curr_ticks = ticks_offs + tmr2ticks (tmr_ctr);
-
- if (curr_ticks >= next_event_time)
- {
- next_event_time = 0xffffffff;
- sequencer_timer ();
- }
- }
- }
-}
-
-static void
-tmr_reset (void)
-{
- unsigned long flags;
-
- DISABLE_INTR (flags);
- tmr_offs = 0;
- ticks_offs = 0;
- tmr_ctr = 0;
- next_event_time = 0xffffffff;
- prev_event_time = 0;
- curr_ticks = 0;
- RESTORE_INTR (flags);
-}
-
-static int
-def_tmr_open (int dev, int mode)
-{
- if (opened)
- return RET_ERROR (EBUSY);
-
- tmr_reset ();
- curr_tempo = 60;
- curr_timebase = HZ;
- opened = 1;
-
- ACTIVATE_TIMER (def_tmr, poll_def_tmr, 1);
-
- return 0;
-}
-
-static void
-def_tmr_close (int dev)
-{
- opened = tmr_running = 0;
-}
-
-static int
-def_tmr_event (int dev, unsigned char *event)
-{
- unsigned char cmd = event[1];
- unsigned long parm = *(int *) &event[4];
-
- switch (cmd)
- {
- case TMR_WAIT_REL:
- parm += prev_event_time;
- case TMR_WAIT_ABS:
- if (parm > 0)
- {
- long time;
-
- if (parm <= curr_ticks) /* It's the time */
- return TIMER_NOT_ARMED;
-
- time = parm;
- next_event_time = prev_event_time = time;
-
- return TIMER_ARMED;
- }
- break;
-
- case TMR_START:
- tmr_reset ();
- tmr_running = 1;
- break;
-
- case TMR_STOP:
- tmr_running = 0;
- break;
-
- case TMR_CONTINUE:
- tmr_running = 1;
- break;
-
- case TMR_TEMPO:
- if (parm)
- {
- if (parm < 8)
- parm = 8;
- if (parm > 250)
- parm = 250;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks (tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = parm;
- }
- break;
-
- case TMR_ECHO:
- seq_copy_to_input (event, 8);
- break;
-
- default:;
- }
-
- return TIMER_NOT_ARMED;
-}
-
-static unsigned long
-def_tmr_get_time (int dev)
-{
- if (!opened)
- return 0;
-
- return curr_ticks;
-}
-
-static int
-def_tmr_ioctl (int dev,
- unsigned int cmd, unsigned int arg)
-{
- switch (cmd)
- {
- case SNDCTL_TMR_SOURCE:
- return IOCTL_OUT (arg, TMR_INTERNAL);
- break;
-
- case SNDCTL_TMR_START:
- tmr_reset ();
- tmr_running = 1;
- return 0;
- break;
-
- case SNDCTL_TMR_STOP:
- tmr_running = 0;
- return 0;
- break;
-
- case SNDCTL_TMR_CONTINUE:
- tmr_running = 1;
- return 0;
- break;
-
- case SNDCTL_TMR_TIMEBASE:
- {
- int val = IOCTL_IN (arg);
-
- if (val)
- {
- if (val < 1)
- val = 1;
- if (val > 1000)
- val = 1000;
- curr_timebase = val;
- }
-
- return IOCTL_OUT (arg, curr_timebase);
- }
- break;
-
- case SNDCTL_TMR_TEMPO:
- {
- int val = IOCTL_IN (arg);
-
- if (val)
- {
- if (val < 8)
- val = 8;
- if (val > 250)
- val = 250;
- tmr_offs = tmr_ctr;
- ticks_offs += tmr2ticks (tmr_ctr);
- tmr_ctr = 0;
- curr_tempo = val;
- }
-
- return IOCTL_OUT (arg, curr_tempo);
- }
- break;
-
- case SNDCTL_SEQ_CTRLRATE:
- if (IOCTL_IN (arg) != 0) /* Can't change */
- return RET_ERROR (EINVAL);
-
- return IOCTL_OUT (arg, ((curr_tempo * curr_timebase) + 30) / 60);
- break;
-
- case SNDCTL_TMR_METRONOME:
- /* NOP */
- break;
-
- default:;
- }
-
- return RET_ERROR (EINVAL);
-}
-
-static void
-def_tmr_arm (int dev, long time)
-{
- if (time < 0)
- time = curr_ticks + 1;
- else if (time <= curr_ticks) /* It's the time */
- return;
-
- next_event_time = prev_event_time = time;
-
- return;
-}
-
-struct sound_timer_operations default_sound_timer =
-{
- {"System Timer", 0},
- 0, /* Priority */
- 0, /* Local device link */
- def_tmr_open,
- def_tmr_close,
- def_tmr_event,
- def_tmr_get_time,
- def_tmr_ioctl,
- def_tmr_arm
-};
-
-#endif
-#endif
diff --git a/sys/pc98/pc98/sound/trix.c b/sys/pc98/pc98/sound/trix.c
deleted file mode 100644
index 21ca20a..0000000
--- a/sys/pc98/pc98/sound/trix.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * sound/trix.c
- *
- * Low level driver for the MediaTriX AudioTriX Pro
- * (MT-0002-PC Control Chip)
- *
- * Copyright by Hannu Savolainen 1995
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_TRIX)
-
-#ifdef INCLUDE_TRIX_BOOT
-#include <i386/isa/sound/trix_boot.h>
-#endif
-
-static int kilroy_was_here = 0; /* Don't detect twice */
-static int sb_initialized = 0;
-static int mpu_initialized = 0;
-
-static unsigned char
-trix_read (int addr)
-{
- OUTB ((unsigned char) addr, 0x390); /* MT-0002-PC ASIC address */
- return INB (0x391); /* MT-0002-PC ASIC data */
-}
-
-static void
-trix_write (int addr, int data)
-{
- OUTB ((unsigned char) addr, 0x390); /* MT-0002-PC ASIC address */
- OUTB ((unsigned char) data, 0x391); /* MT-0002-PC ASIC data */
-}
-
-static void
-download_boot (int base)
-{
- int i = 0, n = sizeof (trix_boot);
-
- trix_write (0xf8, 0x00); /* ??????? */
- OUTB (0x01, base + 6); /* Clear the internal data pointer */
- OUTB (0x00, base + 6); /* Restart */
-
- /*
- * Write the boot code to the RAM upload/download register.
- * Each write increments the internal data pointer.
- */
- OUTB (0x01, base + 6); /* Clear the internal data pointer */
- OUTB (0x1A, 0x390); /* Select RAM download/upload port */
-
- for (i = 0; i < n; i++)
- OUTB (trix_boot[i], 0x391);
- for (i = n; i < 10016; i++) /* Clear up to first 16 bytes of data RAM */
- OUTB (0x00, 0x391);
- OUTB (0x00, base + 6); /* Reset */
- OUTB (0x50, 0x390); /* ?????? */
-}
-
-static int
-trix_set_wss_port (struct address_info *hw_config)
-{
- unsigned char addr_bits;
-
- if (kilroy_was_here) /* Already initialized */
- return 0;
-
- kilroy_was_here = 1;
-
- if (trix_read (0x15) != 0x71) /* No asic signature */
- return 0;
-
- /*
- * Disable separate wave playback and recording DMA channels since
- * the driver doesn't support duplex mode yet.
- */
-
- trix_write (0x13, trix_read (0x13) & ~0x80);
- trix_write (0x14, trix_read (0x14) & ~0x80);
-
- /*
- * Configure the ASIC to place the codec to the proper I/O location
- */
-
- switch (hw_config->io_base)
- {
- case 0x530:
- addr_bits = 0;
- break;
- case 0x604:
- addr_bits = 1;
- break;
- case 0xE80:
- addr_bits = 2;
- break;
- case 0xF40:
- addr_bits = 3;
- break;
- default:
- return 0;
- }
-
- trix_write (0x19, (trix_read (0x19) & 0x03) | addr_bits);
- return 1;
-}
-
-/*
- * Probe and attach routines for the Windows Sound System mode of
- * AudioTriX Pro
- */
-
-int
-probe_trix_wss (struct address_info *hw_config)
-{
- /*
- * Check if the IO port returns valid signature. The original MS Sound
- * system returns 0x04 while some cards (AudioTriX Pro for example)
- * return 0x00.
- */
- if (!trix_set_wss_port (hw_config))
- return 0;
-
- if ((INB (hw_config->io_base + 3) & 0x3f) != 0x00)
- {
- DDB (printk ("No MSS signature detected on port 0x%x\n", hw_config->io_base));
- return 0;
- }
-
- if (hw_config->irq > 11)
- {
- printk ("AudioTriX: Bad WSS IRQ %d\n", hw_config->irq);
- return 0;
- }
-
- if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
- {
- printk ("AudioTriX: Bad WSS DMA %d\n", hw_config->dma);
- return 0;
- }
-
- /*
- * Check that DMA0 is not in use with a 8 bit board.
- */
-
- if (hw_config->dma == 0 && INB (hw_config->io_base + 3) & 0x80)
- {
- printk ("AudioTriX: Can't use DMA0 with a 8 bit card\n");
- return 0;
- }
-
- if (hw_config->irq > 7 && hw_config->irq != 9 && INB (hw_config->io_base + 3) & 0x80)
- {
- printk ("AudioTriX: Can't use IRQ%d with a 8 bit card\n", hw_config->irq);
- return 0;
- }
-
- return ad1848_detect (hw_config->io_base + 4);
-}
-
-long
-attach_trix_wss (long mem_start, struct address_info *hw_config)
-{
- static unsigned char interrupt_bits[12] =
- {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20};
- char bits;
-
- static unsigned char dma_bits[4] =
- {1, 2, 0, 3};
-
- int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
-
- if (!kilroy_was_here)
- return mem_start;
-
- /*
- * Set the IRQ and DMA addresses.
- */
-
- bits = interrupt_bits[hw_config->irq];
- if (bits == -1)
- return mem_start;
-
- OUTB (bits | 0x40, config_port);
- if ((INB (version_port) & 0x40) == 0)
- printk ("[IRQ Conflict?]");
-
- OUTB (bits | dma_bits[hw_config->dma], config_port); /* Write IRQ+DMA setup */
-
- ad1848_init ("AudioTriX Pro", hw_config->io_base + 4,
- hw_config->irq,
- hw_config->dma,
- hw_config->dma);
- return mem_start;
-}
-
-int
-probe_trix_sb (struct address_info *hw_config)
-{
-
- int tmp;
- unsigned char conf;
- static char irq_translate[] =
- {-1, -1, -1, 0, 1, 2, -1, 3};
-
-#ifndef INCLUDE_TRIX_BOOT
- return 0; /* No boot code -> no fun */
-#endif
- if (!kilroy_was_here)
- return 0; /* AudioTriX Pro has not been detected earlier */
-
- if (sb_initialized)
- return 0;
-
- if (hw_config->io_base & 0xffffff8f != 0x200)
- return 0;
-
- tmp = hw_config->irq;
- if (tmp > 7)
- return 0;
- if (irq_translate[tmp] == -1)
- return 0;
-
- tmp = hw_config->dma;
- if (tmp != 1 && tmp != 3)
- return 0;
-
- conf = 0x84; /* DMA and IRQ enable */
- conf |= hw_config->io_base & 0x70; /* I/O address bits */
- conf |= irq_translate[hw_config->irq];
- if (hw_config->dma == 3)
- conf |= 0x08;
- trix_write (0x1b, conf);
-
- download_boot (hw_config->io_base);
- sb_initialized = 1;
-
- return 1;
-}
-
-long
-attach_trix_sb (long mem_start, struct address_info *hw_config)
-{
- printk (" <AudioTriX>");
- return mem_start;
-}
-
-long
-attach_trix_mpu (long mem_start, struct address_info *hw_config)
-{
- return attach_mpu401 (mem_start, hw_config);
-}
-
-int
-probe_trix_mpu (struct address_info *hw_config)
-{
- unsigned char conf;
- static char irq_bits[] =
- {-1, -1, -1, 1, 2, 3, -1, 4, -1, 5};
-
- if (!kilroy_was_here)
- return 0; /* AudioTriX Pro has not been detected earlier */
-
- if (!sb_initialized)
- return 0;
-
- if (mpu_initialized)
- return 0;
-
- if (hw_config->irq > 9)
- return 0;
-
- if (irq_bits[hw_config->irq] == -1)
- return 0;
-
- switch (hw_config->io_base)
- {
- case 0x330:
- conf = 0x00;
- break;
- case 0x370:
- conf = 0x04;
- break;
- case 0x3b0:
- conf = 0x08;
- break;
- case 0x3f0:
- conf = 0x0c;
- break;
- default:
- return 0; /* Invalid port */
- }
-
- conf |= irq_bits[hw_config->irq] << 4;
-
- trix_write (0x19, (trix_read (0x19) & 0x83) | conf);
-
- mpu_initialized = 1;
-
- return probe_mpu401 (hw_config);
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/uart6850.c b/sys/pc98/pc98/sound/uart6850.c
deleted file mode 100644
index d925727..0000000
--- a/sys/pc98/pc98/sound/uart6850.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * sound/uart6850.c
- *
- * Copyright by Hannu Savolainen 1993
- *
- * Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
- * added 6850 support, used with COVOX SoundMaster II and custom cards.
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#ifdef CONFIGURE_SOUNDCARD
-
-#if !defined(EXCLUDE_UART6850) && !defined(EXCLUDE_MIDI)
-
-#define DATAPORT (uart6850_base) /*
- * * * Midi6850 Data I/O Port on IBM
- * */
-#define COMDPORT (uart6850_base+1) /*
- * * * Midi6850 Command Port on IBM */
-#define STATPORT (uart6850_base+1) /*
- * * * Midi6850 Status Port on IBM */
-
-#define uart6850_status() INB(STATPORT)
-#define input_avail() ((uart6850_status()&INPUT_AVAIL))
-#define output_ready() ((uart6850_status()&OUTPUT_READY))
-#define uart6850_cmd(cmd) OUTB(cmd, COMDPORT)
-#define uart6850_read() INB(DATAPORT)
-#define uart6850_write(byte) OUTB(byte, DATAPORT)
-
-#define OUTPUT_READY 0x02 /*
- * * * Mask for Data Read Ready Bit */
-#define INPUT_AVAIL 0x01 /*
- * * * Mask for Data Send Ready Bit */
-
-#define UART_RESET 0x95 /*
- * * * 6850 Total Reset Command */
-#define UART_MODE_ON 0x03 /*
- * * * 6850 Send/Receive UART Mode */
-
-static int uart6850_opened = 0;
-static int uart6850_base = 0x330;
-static int uart6850_irq;
-static int uart6850_detected = 0;
-static int my_dev;
-
-static int reset_uart6850 (void);
-static void (*midi_input_intr) (int dev, unsigned char data);
-
-static void
-uart6850_input_loop (void)
-{
- int count;
-
- count = 10;
-
- while (count) /*
- * Not timed out
- */
- if (input_avail ())
- {
- unsigned char c = uart6850_read ();
-
- count = 100;
-
- if (uart6850_opened & OPEN_READ)
- midi_input_intr (my_dev, c);
- }
- else
- while (!input_avail () && count)
- count--;
-}
-
-void
-m6850intr (int unit)
-{
- if (input_avail ())
- uart6850_input_loop ();
-}
-
-/*
- * It looks like there is no input interrupts in the UART mode. Let's try
- * polling.
- */
-
-static void
-poll_uart6850 (unsigned long dummy)
-{
- unsigned long flags;
-
- DEFINE_TIMER (uart6850_timer, poll_uart6850);
-
- if (!(uart6850_opened & OPEN_READ))
- return; /*
- * No longer required
- */
-
- DISABLE_INTR (flags);
-
- if (input_avail ())
- uart6850_input_loop ();
-
- ACTIVATE_TIMER (uart6850_timer, poll_uart6850, 1); /*
- * Come back later
- */
-
- RESTORE_INTR (flags);
-}
-
-static int
-uart6850_open (int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- if (uart6850_opened)
- {
- printk ("Midi6850: Midi busy\n");
- return RET_ERROR (EBUSY);
- }
-
- uart6850_cmd (UART_RESET);
-
- uart6850_input_loop ();
-
- midi_input_intr = input;
- uart6850_opened = mode;
- poll_uart6850 (0); /*
- * Enable input polling
- */
-
- return 0;
-}
-
-static void
-uart6850_close (int dev)
-{
- uart6850_cmd (UART_MODE_ON);
-
- uart6850_opened = 0;
-}
-
-static int
-uart6850_out (int dev, unsigned char midi_byte)
-{
- int timeout;
- unsigned long flags;
-
- /*
- * Test for input since pending input seems to block the output.
- */
-
- DISABLE_INTR (flags);
-
- if (input_avail ())
- uart6850_input_loop ();
-
- RESTORE_INTR (flags);
-
- /*
- * Sometimes it takes about 13000 loops before the output becomes ready
- * (After reset). Normally it takes just about 10 loops.
- */
-
- for (timeout = 30000; timeout > 0 && !output_ready (); timeout--); /*
- * Wait
- */
-
- if (!output_ready ())
- {
- printk ("Midi6850: Timeout\n");
- return 0;
- }
-
- uart6850_write (midi_byte);
- return 1;
-}
-
-static int
-uart6850_command (int dev, unsigned char *midi_byte)
-{
- return 1;
-}
-
-static int
-uart6850_start_read (int dev)
-{
- return 0;
-}
-
-static int
-uart6850_end_read (int dev)
-{
- return 0;
-}
-
-static int
-uart6850_ioctl (int dev, unsigned cmd, unsigned arg)
-{
- return RET_ERROR (EINVAL);
-}
-
-static void
-uart6850_kick (int dev)
-{
-}
-
-static int
-uart6850_buffer_status (int dev)
-{
- return 0; /*
- * No data in buffers
- */
-}
-
-#define MIDI_SYNTH_NAME "6850 UART Midi"
-#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
-#include <i386/isa/sound/midi_synth.h>
-
-static struct midi_operations uart6850_operations =
-{
- {"6850 UART", 0, 0, SNDCARD_UART6850},
- &std_midi_synth,
- {0},
- uart6850_open,
- uart6850_close,
- uart6850_ioctl,
- uart6850_out,
- uart6850_start_read,
- uart6850_end_read,
- uart6850_kick,
- uart6850_command,
- uart6850_buffer_status
-};
-
-
-long
-attach_uart6850 (long mem_start, struct address_info *hw_config)
-{
- int ok, timeout;
- unsigned long flags;
-
- if (num_midis >= MAX_MIDI_DEV)
- {
- printk ("Sound: Too many midi devices detected\n");
- return mem_start;
- }
-
- uart6850_base = hw_config->io_base;
- uart6850_irq = hw_config->irq;
-
- if (!uart6850_detected)
- return RET_ERROR (EIO);
-
- DISABLE_INTR (flags);
-
- for (timeout = 30000; timeout < 0 && !output_ready (); timeout--); /*
- * Wait
- */
- uart6850_cmd (UART_MODE_ON);
-
- ok = 1;
-
- RESTORE_INTR (flags);
-
-#if defined(__FreeBSD__)
- printk ("uart0: <6850 Midi Interface>");
-#else
- printk (" <6850 Midi Interface>");
-#endif
-
- std_midi_synth.midi_dev = my_dev = num_midis;
- midi_devs[num_midis++] = &uart6850_operations;
- return mem_start;
-}
-
-static int
-reset_uart6850 (void)
-{
- uart6850_read ();
- return 1; /*
- * OK
- */
-}
-
-
-int
-probe_uart6850 (struct address_info *hw_config)
-{
- int ok = 0;
-
- uart6850_base = hw_config->io_base;
- uart6850_irq = hw_config->irq;
-
- if (snd_set_irq_handler (uart6850_irq, m6850intr, "MIDI6850") < 0)
- return 0;
-
- ok = reset_uart6850 ();
-
- uart6850_detected = ok;
- return ok;
-}
-
-#endif
-
-#endif
diff --git a/sys/pc98/pc98/sound/ulaw.h b/sys/pc98/pc98/sound/ulaw.h
deleted file mode 100644
index 4a071dd..0000000
--- a/sys/pc98/pc98/sound/ulaw.h
+++ /dev/null
@@ -1,71 +0,0 @@
-static unsigned char ulaw_dsp[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 2,
- 5, 9, 13, 17, 21, 25, 29, 33,
- 37, 41, 45, 49, 53, 57, 61, 65,
- 68, 70, 72, 74, 76, 78, 80, 82,
- 84, 86, 88, 90, 92, 94, 96, 98,
- 100, 101, 102, 103, 104, 105, 106, 107,
- 108, 109, 110, 111, 112, 113, 114, 115,
- 115, 116, 116, 117, 117, 118, 118, 119,
- 119, 120, 120, 121, 121, 122, 122, 123,
- 123, 123, 124, 124, 124, 124, 125, 125,
- 125, 125, 126, 126, 126, 126, 127, 127,
- 127, 127, 127, 127, 128, 128, 128, 128,
- 128, 128, 128, 128, 128, 128, 128, 128,
- 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255,
- 252, 248, 244, 240, 236, 232, 228, 224,
- 220, 216, 212, 208, 204, 200, 196, 192,
- 189, 187, 185, 183, 181, 179, 177, 175,
- 173, 171, 169, 167, 165, 163, 161, 159,
- 157, 156, 155, 154, 153, 152, 151, 150,
- 149, 148, 147, 146, 145, 144, 143, 142,
- 142, 141, 141, 140, 140, 139, 139, 138,
- 138, 137, 137, 136, 136, 135, 135, 134,
- 134, 134, 133, 133, 133, 133, 132, 132,
- 132, 132, 131, 131, 131, 131, 130, 130,
- 130, 130, 130, 130, 129, 129, 129, 129,
- 129, 129, 129, 129, 128, 128, 128, 128,
-};
-
-#ifndef DSP_ULAW_NOT_WANTED
-static unsigned char dsp_ulaw[] = {
- 31, 31, 31, 32, 32, 32, 32, 33,
- 33, 33, 33, 34, 34, 34, 34, 35,
- 35, 35, 35, 36, 36, 36, 36, 37,
- 37, 37, 37, 38, 38, 38, 38, 39,
- 39, 39, 39, 40, 40, 40, 40, 41,
- 41, 41, 41, 42, 42, 42, 42, 43,
- 43, 43, 43, 44, 44, 44, 44, 45,
- 45, 45, 45, 46, 46, 46, 46, 47,
- 47, 47, 47, 48, 48, 49, 49, 50,
- 50, 51, 51, 52, 52, 53, 53, 54,
- 54, 55, 55, 56, 56, 57, 57, 58,
- 58, 59, 59, 60, 60, 61, 61, 62,
- 62, 63, 63, 64, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, 75, 76,
- 77, 78, 79, 81, 83, 85, 87, 89,
- 91, 93, 95, 99, 103, 107, 111, 119,
- 255, 247, 239, 235, 231, 227, 223, 221,
- 219, 217, 215, 213, 211, 209, 207, 206,
- 205, 204, 203, 202, 201, 200, 199, 198,
- 197, 196, 195, 194, 193, 192, 191, 191,
- 190, 190, 189, 189, 188, 188, 187, 187,
- 186, 186, 185, 185, 184, 184, 183, 183,
- 182, 182, 181, 181, 180, 180, 179, 179,
- 178, 178, 177, 177, 176, 176, 175, 175,
- 175, 175, 174, 174, 174, 174, 173, 173,
- 173, 173, 172, 172, 172, 172, 171, 171,
- 171, 171, 170, 170, 170, 170, 169, 169,
- 169, 169, 168, 168, 168, 168, 167, 167,
- 167, 167, 166, 166, 166, 166, 165, 165,
- 165, 165, 164, 164, 164, 164, 163, 163,
- 163, 163, 162, 162, 162, 162, 161, 161,
- 161, 161, 160, 160, 160, 160, 159, 159,
-};
-#endif /* !DSP_ULAW_NOT_WANTED */
diff --git a/sys/pc98/pc98/spkr.c b/sys/pc98/pc98/spkr.c
index 611bd16..5bfbe08 100644
--- a/sys/pc98/pc98/spkr.c
+++ b/sys/pc98/pc98/spkr.c
@@ -4,12 +4,12 @@
* v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993
* modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su>
*
- * $Id: spkr.c,v 1.3 1996/08/30 10:43:09 asami Exp $
+ * $Id: spkr.c,v 1.4 1996/09/04 09:52:27 asami Exp $
*/
/*
* modified for PC98
- * $Id: spkr.c,v 1.3 1996/08/30 10:43:09 asami Exp $
+ * $Id: spkr.c,v 1.4 1996/09/04 09:52:27 asami Exp $
*/
#include "speaker.h"
@@ -19,23 +19,18 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-#include <sys/errno.h>
#include <sys/buf.h>
-#include <sys/proc.h>
#include <sys/uio.h>
#include <sys/conf.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/timerreg.h>
#else
#include <i386/isa/isa.h>
-#include <i386/isa/timerreg.h>
#endif
+#include <i386/isa/timerreg.h>
#include <machine/clock.h>
#include <machine/speaker.h>
-
-
#ifdef DEVFS
#include <sys/devfsext.h>
void *devfs_token;
@@ -55,53 +50,25 @@ static struct cdevsw spkr_cdevsw =
/**************** MACHINE DEPENDENT PART STARTS HERE *************************
*
* This section defines a function tone() which causes a tone of given
- * frequency and duration from the 80x86's console speaker.
+ * frequency and duration from the ISA console speaker.
* Another function endtone() is defined to force sound off, and there is
* also a rest() entry point to do pauses.
*
* Audible sound is generated using the Programmable Interval Timer (PIT) and
- * Programmable Peripheral Interface (PPI) attached to the 80x86's speaker. The
+ * Programmable Peripheral Interface (PPI) attached to the ISA speaker. The
* PPI controls whether sound is passed through at all; the PIT's channel 2 is
* used to generate clicks (a square wave) of whatever frequency is desired.
*/
/*
- * PIT and PPI port addresses and control values
- *
- * Most of the magic is hidden in the TIMER_PREP value, which selects PIT
- * channel 2, frequency LSB first, square-wave mode and binary encoding.
- * The encoding is as follows:
- *
- * +----------+----------+---------------+-----+
- * | 1 0 | 1 1 | 0 1 1 | 0 |
- * | SC1 SC0 | RW1 RW0 | M2 M1 M0 | BCD |
- * +----------+----------+---------------+-----+
- * Counter Write Mode 3 Binary
- * Channel 2 LSB first, (Square Wave) Encoding
- * MSB second
+ * PPI control values.
+ * XXX should be in a header and used in clock.c.
*/
#ifdef PC98
#define PPI_SPKR 0x08 /* turn these PPI bits on to pass sound */
#define PIT_COUNT 0x3fdb /* PIT count address */
-#define PIT_MODE 0x76 /* set timer mode for sound generation */
#else
#define PPI_SPKR 0x03 /* turn these PPI bits on to pass sound */
-#define PIT_MODE 0xB6 /* set timer mode for sound generation */
-#endif
-
-/*
- * Magic numbers for timer control.
- */
-#ifdef PC98
-#ifndef AUTO_CLOCK
-#ifndef PC98_8M
-#define TIMER_CLK 2457600L /* ???? for 5MHz system */
-#else
-#define TIMER_CLK 1996800L /* ???? for 8MHz system */
-#endif
-#endif /* !AUTO_CLOCK */
-#else /* IBM_PC */
-#define TIMER_CLK 1193180L /* corresponds to 18.2 MHz tick rate */
#endif
#define SPKRPRI PSOCK
@@ -131,7 +98,7 @@ tone(thz, ticks)
else
divisor = 2457600L / thz;
#else
- divisor = TIMER_CLK / thz;
+ divisor = timer_freq / thz;
#endif /* PC98 */
#ifdef DEBUG
@@ -142,9 +109,9 @@ tone(thz, ticks)
sps = splclock();
#ifdef PC98
- if (acquire_timer1(PIT_MODE)) {
+ if (acquire_timer1(TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT)) {
#else
- if (acquire_timer2(PIT_MODE)) {
+ if (acquire_timer2(TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT)) {
#endif
/* enter list of waiting procs ??? */
splx(sps);
diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c
index 12514f3..1f98d41 100644
--- a/sys/pc98/pc98/syscons.c
+++ b/sys/pc98/pc98/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.11 1996/10/23 07:25:30 asami Exp $
+ * $Id: syscons.c,v 1.12 1996/10/29 08:36:27 asami Exp $
*/
#include "sc.h"
@@ -69,8 +69,8 @@
#define KANJI
#include <pc98/pc98/pc98.h>
#include <i386/isa/isa_device.h>
-#include <pc98/pc98/timerreg.h>
-#include <pc98/pc98/kbdtables.h>
+#include <i386/isa/timerreg.h>
+#include <i386/isa/kbdtables.h>
#include <pc98/pc98/syscons.h>
#else
#include <i386/isa/isa.h>
@@ -122,8 +122,7 @@ static term_stat kernel_console;
static default_attr *current_default;
static int flags = 0;
static char init_done = COLD;
-static u_short buffer[ROW*COL];
-static char in_debugger = FALSE;
+static u_short sc_buffer[ROW*COL];
static char switch_in_progress = FALSE;
static char write_in_progress = FALSE;
static char blink_in_progress = FALSE;
@@ -180,7 +179,6 @@ struct tty *sccons[MAXCONS+2];
#define MOUSE_TTY &sccons[MAXCONS+1]
static struct tty sccons[MAXCONS+2];
#endif
-
#define SC_MOUSE 128
#define SC_CONSOLE 255
#ifdef PC98
@@ -210,7 +208,9 @@ static int scprobe(struct isa_device *dev);
static void scstart(struct tty *tp);
static void scmousestart(struct tty *tp);
static void scinit(void);
-static u_int scgetc(int noblock);
+static u_int scgetc(u_int flags);
+#define SCGETC_CN 1
+#define SCGETC_NONBLOCK 2
static scr_stat *get_scr_stat(dev_t dev);
static scr_stat *alloc_scp(void);
static void init_scp(scr_stat *scp);
@@ -252,7 +252,7 @@ static void toggle_splash_screen(scr_stat *scp);
#endif
struct isa_driver scdriver = {
- scprobe, scattach, "sc", 1
+ scprobe, scattach, "sc", 1
};
static d_open_t scopen;
@@ -499,8 +499,10 @@ scattach(struct isa_device *dev)
scp->atr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
M_DEVBUF, M_NOWAIT);
#endif
- /* copy screen to buffer */
- bcopyw(buffer, scp->scr_buf, scp->xsize * scp->ysize * sizeof(u_short));
+
+ /* copy temporary buffer to final buffer */
+ bcopyw(sc_buffer, scp->scr_buf, scp->xsize * scp->ysize * sizeof(u_short));
+
#ifdef PC98
bcopyw(Atrat, scp->atr_buf, scp->xsize * scp->ysize * sizeof(u_short));
#endif
@@ -697,7 +699,7 @@ scintr(int unit)
mark_all(cur_console);
}
- c = scgetc(1);
+ c = scgetc(SCGETC_NONBLOCK);
cur_tty = VIRTUAL_TTY(get_scr_num());
if (!(cur_tty->t_state & TS_ISOPEN))
@@ -1347,7 +1349,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
case KIOCSOUND: /* make tone (*data) hz */
if (scp == cur_console) {
if (*(int*)data) {
- int pitch = TIMER_FREQ/(*(int*)data);
+ int pitch = timer_freq / *(int*)data;
#ifdef PC98
/* enable counter 1 */
@@ -1602,10 +1604,8 @@ sccnputc(dev_t dev, int c)
scp->term = kernel_console;
current_default = &kernel_default;
- if ((scp->scr_buf == buffer || in_debugger) &&
- !(scp->status & UNKNOWN_MODE)) {
+ if (!(scp->status & UNKNOWN_MODE))
remove_cursor_image(scp);
- }
buf[0] = c;
ansi_put(scp, buf, 1);
kernel_console = scp->term;
@@ -1633,7 +1633,7 @@ int
sccngetc(dev_t dev)
{
int s = spltty(); /* block scintr while we poll */
- int c = scgetc(0);
+ int c = scgetc(SCGETC_CN);
splx(s);
return(c);
}
@@ -1644,7 +1644,7 @@ sccncheckc(dev_t dev)
int c, s;
s = spltty();
- c = scgetc(1);
+ c = scgetc(SCGETC_CN | SCGETC_NONBLOCK);
splx(s);
return(c == NOKEY ? -1 : c); /* c == -1 can't happen */
}
@@ -1680,6 +1680,7 @@ scrn_timer()
/* should we just return ? */
if ((scp->status&UNKNOWN_MODE) || blink_in_progress || switch_in_progress) {
timeout((timeout_func_t)scrn_timer, 0, hz/10);
+ splx(s);
return;
}
@@ -3009,10 +3010,8 @@ scinit(void)
#ifdef AUTO_CLOCK
if (pc98_machine_type & M_8M) {
BELL_PITCH = 1339;
- TIMER_FREQ = 1996800L;
} else {
BELL_PITCH = 1678;
- TIMER_FREQ = 2457600L;
}
#endif /* AUTO_CLOCK */
outb(0x62, 0xd);
@@ -3079,8 +3078,13 @@ scinit(void)
current_default = &user_default;
console[0] = &main_console;
init_scp(console[0]);
- console[0]->scr_buf = console[0]->mouse_pos = buffer;
- console[0]->cursor_pos = console[0]->cursor_oldpos = buffer + hw_cursor;
+
+ /* copy screen to temporary buffer */
+ bcopyw(Crtat, sc_buffer,
+ console[0]->xsize * console[0]->ysize * sizeof(u_short));
+
+ console[0]->scr_buf = console[0]->mouse_pos = sc_buffer;
+ console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor;
#ifdef PC98
console[0]->atr_buf = Atrat;
console[0]->cursor_atr = Atrat + hw_cursor;
@@ -3265,12 +3269,13 @@ history_down_line(scr_stat *scp)
}
/*
- * scgetc(noblock) - get character from keyboard.
- * If noblock = 0 wait until a key is pressed.
- * Else return NOKEY.
+ * scgetc(flags) - get character from keyboard.
+ * If flags & SCGETC_CN, then avoid harmful side effects.
+ * If flags & SCGETC_NONBLOCK, then wait until a key is pressed, else
+ * return NOKEY if there is nothing there.
*/
static u_int
-scgetc(int noblock)
+scgetc(u_int flags)
{
u_char scancode, keycode;
u_int state, action;
@@ -3286,17 +3291,18 @@ next_code:
{
kbd_wait();
scancode = inb(KB_DATA);
- } else if (noblock)
+ } else if (flags & SCGETC_NONBLOCK)
#else
scancode = inb(KB_DATA);
- else if (noblock)
+ else if (flags & SCGETC_NONBLOCK)
#endif
return(NOKEY);
else
goto next_code;
/* do the /dev/random device a favour */
- add_keyboard_randomness(scancode);
+ if (!(flags & SCGETC_CN))
+ add_keyboard_randomness(scancode);
if (cur_console->status & KBD_RAW_MODE)
return scancode;
@@ -3731,9 +3737,7 @@ next_code:
if (cur_console->smode.mode == VT_AUTO &&
console[0]->smode.mode == VT_AUTO)
switch_scr(cur_console, 0);
- in_debugger = TRUE;
Debugger("manual escape to debugger");
- in_debugger = FALSE;
return(NOKEY);
#else
printf("No debugger in kernel\n");
diff --git a/sys/pc98/pc98/syscons.h b/sys/pc98/pc98/syscons.h
index 39bd568..bb20855 100644
--- a/sys/pc98/pc98/syscons.h
+++ b/sys/pc98/pc98/syscons.h
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.h,v 1.5 1996/10/23 07:25:33 asami Exp $
+ * $Id: syscons.h,v 1.6 1996/10/29 08:36:28 asami Exp $
*/
#ifndef _PC98_PC98_SYSCONS_H_
@@ -98,14 +98,11 @@
#ifndef AUTO_CLOCK
#ifndef PC98_8M
#define BELL_PITCH 1678
-#define TIMER_FREQ 2457600 /* should be in pc98.h */
#else
#define BELL_PITCH 1339
-#define TIMER_FREQ 1996800 /* should be in pc98.h */
#endif
#else /* AUTO_CLOCK */
static unsigned int BELL_PITCH = 1678;
-static unsigned int TIMER_FREQ = 2457600;
#endif /* AUTO_CLOCK */
#else /* IBM-PC */
#define BELL_PITCH 800
diff --git a/sys/pc98/pc98/timerreg.h b/sys/pc98/pc98/timerreg.h
deleted file mode 100644
index 3ab9ae8..0000000
--- a/sys/pc98/pc98/timerreg.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*-
- * Copyright (c) 1993 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.
- *
- * from: Header: timerreg.h,v 1.2 93/02/28 15:08:58 mccanne Exp
- * timerreg.h,v 1.2 1993/10/16 13:46:26 rgrimes Exp
- */
-
-/*
- *
- * Register definitions for the Intel 8253 Programmable Interval Timer.
- *
- * This chip has three independent 16-bit down counters that can be
- * read on the fly. There are three mode registers and three countdown
- * registers. The countdown registers are addressed directly, via the
- * first three I/O ports. The three mode registers are accessed via
- * the fourth I/O port, with two bits in the mode byte indicating the
- * register. (Why are hardware interfaces always so braindead?).
- *
- * To write a value into the countdown register, the mode register
- * is first programmed with a command indicating the which byte of
- * the two byte register is to be modified. The three possibilities
- * are load msb (TMR_MR_MSB), load lsb (TMR_MR_LSB), or load lsb then
- * msb (TMR_MR_BOTH).
- *
- * To read the current value ("on the fly") from the countdown register,
- * you write a "latch" command into the mode register, then read the stable
- * value from the corresponding I/O port. For example, you write
- * TMR_MR_LATCH into the corresponding mode register. Presumably,
- * after doing this, a write operation to the I/O port would result
- * in undefined behavior (but hopefully not fry the chip).
- * Reading in this manner has no side effects.
- *
- * The outputs of the three timers are connected as follows:
- *
- * timer 0 -> irq 0
- * timer 1 -> speaker (via keyboard controller)
- * timer 2 -> RS232C
- *
- * Timer 0 is used to call hardclock.
- * Timer 1 is used to generate console beeps.
- */
-
-/*
- * Macros for specifying values to be written into a mode register.
- */
-#define TIMER_CNTR0 0x071 /* timer 0 counter port */
-#define TIMER_CNTR1 0x3fdb /* timer 1 counter port */
-#define TIMER_CNTR2 0x075 /* timer 2 counter port */
-#define TIMER_MODE 0x077 /* timer mode port */
-#define TIMER_SEL0 0x00 /* select counter 0 */
-#define TIMER_SEL1 0x40 /* select counter 1 */
-#define TIMER_SEL2 0x80 /* select counter 2 */
-#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */
-#define TIMER_ONESHOT 0x02 /* mode 1, one shot */
-#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */
-#define TIMER_SQWAVE 0x06 /* mode 3, square wave */
-#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */
-#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */
-#define TIMER_LATCH 0x00 /* latch counter for reading */
-#define TIMER_LSB 0x10 /* r/w counter LSB */
-#define TIMER_MSB 0x20 /* r/w counter MSB */
-#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */
-#define TIMER_BCD 0x01 /* count in BCD */
-
diff --git a/sys/pc98/pc98/vector.s b/sys/pc98/pc98/vector.s
deleted file mode 100644
index cfa37ad..0000000
--- a/sys/pc98/pc98/vector.s
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * from: vector.s, 386BSD 0.1 unknown origin
- * $Id: vector.s,v 1.1.1.1 1996/06/14 10:04:48 asami Exp $
- */
-
-#include "opt_auto_eoi.h"
-
-/*
- * modified for PC98
- * vector.s,v 1.2 1994/03/14 09:44:21 kakefuda Exp
- */
-
-#include <i386/isa/icu.h>
-#ifdef PC98
-#include <pc98/pc98/pc98.h>
-#else
-#include <i386/isa/isa.h>
-#endif
-
-#define ICU_EOI 0x20 /* XXX - define elsewhere */
-
-#define IRQ_BIT(irq_num) (1 << ((irq_num) % 8))
-#define IRQ_BYTE(irq_num) ((irq_num) / 8)
-
-#ifdef AUTO_EOI_1
-#define ENABLE_ICU1 /* use auto-EOI to reduce i/o */
-#define OUTB_ICU1
-#else
-#define ENABLE_ICU1 \
- movb $ICU_EOI,%al ; /* as soon as possible send EOI ... */ \
- OUTB_ICU1 /* ... to clear in service bit */
-#define OUTB_ICU1 \
- outb %al,$IO_ICU1
-#endif
-
-#ifdef AUTO_EOI_2
-/*
- * The data sheet says no auto-EOI on slave, but it sometimes works.
- */
-#define ENABLE_ICU1_AND_2 ENABLE_ICU1
-#else
-#define ENABLE_ICU1_AND_2 \
- movb $ICU_EOI,%al ; /* as above */ \
- outb %al,$IO_ICU2 ; /* but do second icu first ... */ \
- OUTB_ICU1 /* ... then first icu (if !AUTO_EOI_1) */
-#endif
-
-#ifdef FAST_INTR_HANDLER_USES_ES
-#define ACTUALLY_PUSHED 1
-#define MAYBE_MOVW_AX_ES movl %ax,%es
-#define MAYBE_POPL_ES popl %es
-#define MAYBE_PUSHL_ES pushl %es
-#else
-/*
- * We can usually skip loading %es for fastintr handlers. %es should
- * only be used for string instructions, and fastintr handlers shouldn't
- * do anything slow enough to justify using a string instruction.
- */
-#define ACTUALLY_PUSHED 0
-#define MAYBE_MOVW_AX_ES
-#define MAYBE_POPL_ES
-#define MAYBE_PUSHL_ES
-#endif
-
-/*
- * Macros for interrupt interrupt entry, call to handler, and exit.
- *
- * XXX - the interrupt frame is set up to look like a trap frame. This is
- * usually a waste of time. The only interrupt handlers that want a frame
- * are the clock handler (it wants a clock frame), the npx handler (it's
- * easier to do right all in assembler). The interrupt return routine
- * needs a trap frame for rare AST's (it could easily convert the frame).
- * The direct costs of setting up a trap frame are two pushl's (error
- * code and trap number), an addl to get rid of these, and pushing and
- * popping the call-saved regs %esi, %edi and %ebp twice, The indirect
- * costs are making the driver interface nonuniform so unpending of
- * interrupts is more complicated and slower (call_driver(unit) would
- * be easier than ensuring an interrupt frame for all handlers. Finally,
- * there are some struct copies in the npx handler and maybe in the clock
- * handler that could be avoided by working more with pointers to frames
- * instead of frames.
- *
- * XXX - should we do a cld on every system entry to avoid the requirement
- * for scattered cld's?
- *
- * Coding notes for *.s:
- *
- * If possible, avoid operations that involve an operand size override.
- * Word-sized operations might be smaller, but the operand size override
- * makes them slower on on 486's and no faster on 386's unless perhaps
- * the instruction pipeline is depleted. E.g.,
- *
- * Use movl to seg regs instead of the equivalent but more descriptive
- * movw - gas generates an irelevant (slower) operand size override.
- *
- * Use movl to ordinary regs in preference to movw and especially
- * in preference to movz[bw]l. Use unsigned (long) variables with the
- * top bits clear instead of unsigned short variables to provide more
- * opportunities for movl.
- *
- * If possible, use byte-sized operations. They are smaller and no slower.
- *
- * Use (%reg) instead of 0(%reg) - gas generates larger code for the latter.
- *
- * If the interrupt frame is made more flexible, INTR can push %eax first
- * and decide the ipending case with less overhead, e.g., by avoiding
- * loading segregs.
- */
-
-#define FAST_INTR(irq_num, vec_name, enable_icus) \
- .text ; \
- SUPERALIGN_TEXT ; \
-IDTVEC(vec_name) ; \
- pushl %eax ; /* save only call-used registers */ \
- pushl %ecx ; \
- pushl %edx ; \
- pushl %ds ; \
- MAYBE_PUSHL_ES ; \
- movl $KDSEL,%eax ; \
- movl %ax,%ds ; \
- MAYBE_MOVW_AX_ES ; \
- FAKE_MCOUNT((4+ACTUALLY_PUSHED)*4(%esp)) ; \
- pushl _intr_unit + (irq_num) * 4 ; \
- call *_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
- enable_icus ; /* (re)enable ASAP (helps edge trigger?) */ \
- addl $4,%esp ; \
- incl _cnt+V_INTR ; /* book-keeping can wait */ \
- movl _intr_countp + (irq_num) * 4,%eax ; \
- incl (%eax) ; \
- movl _cpl,%eax ; /* are we unmasking pending HWIs or SWIs? */ \
- notl %eax ; \
- andl _ipending,%eax ; \
- jne 1f ; /* yes, handle them */ \
- MEXITCOUNT ; \
- MAYBE_POPL_ES ; \
- popl %ds ; \
- popl %edx ; \
- popl %ecx ; \
- popl %eax ; \
- iret ; \
-; \
- ALIGN_TEXT ; \
-1: ; \
- movl _cpl,%eax ; \
- movl $HWI_MASK|SWI_MASK,_cpl ; /* limit nesting ... */ \
- sti ; /* ... to do this as early as possible */ \
- MAYBE_POPL_ES ; /* discard most of thin frame ... */ \
- popl %ecx ; /* ... original %ds ... */ \
- popl %edx ; \
- xchgl %eax,4(%esp) ; /* orig %eax; save cpl */ \
- pushal ; /* build fat frame (grrr) ... */ \
- pushl %ecx ; /* ... actually %ds ... */ \
- pushl %es ; \
- movl $KDSEL,%eax ; \
- movl %ax,%es ; \
- movl (2+8+0)*4(%esp),%ecx ; /* ... %ecx from thin frame ... */ \
- movl %ecx,(2+6)*4(%esp) ; /* ... to fat frame ... */ \
- movl (2+8+1)*4(%esp),%eax ; /* ... cpl from thin frame */ \
- pushl %eax ; \
- subl $4,%esp ; /* junk for unit number */ \
- incb _intr_nesting_level ; \
- MEXITCOUNT ; \
- jmp _doreti
-
-#define INTR(irq_num, vec_name, icu, enable_icus, reg) \
- .text ; \
- SUPERALIGN_TEXT ; \
-IDTVEC(vec_name) ; \
- pushl $0 ; /* dummy error code */ \
- pushl $0 ; /* dummy trap type */ \
- pushal ; \
- pushl %ds ; /* save our data and extra segments ... */ \
- pushl %es ; \
- movl $KDSEL,%eax ; /* ... and reload with kernel's own ... */ \
- movl %ax,%ds ; /* ... early for obsolete reasons */ \
- movl %ax,%es ; \
- movb _imen + IRQ_BYTE(irq_num),%al ; \
- orb $IRQ_BIT(irq_num),%al ; \
- movb %al,_imen + IRQ_BYTE(irq_num) ; \
- outb %al,$icu+2 ; \
- enable_icus ; \
- incl _cnt+V_INTR ; /* tally interrupts */ \
- movl _cpl,%eax ; \
- testb $IRQ_BIT(irq_num),%reg ; \
- jne 2f ; \
- incb _intr_nesting_level ; \
-__CONCAT(Xresume,irq_num): ; \
- FAKE_MCOUNT(12*4(%esp)) ; /* XXX late to avoid double count */ \
- movl _intr_countp + (irq_num) * 4,%eax ; \
- incl (%eax) ; \
- movl _cpl,%eax ; \
- pushl %eax ; \
- pushl _intr_unit + (irq_num) * 4 ; \
- orl _intr_mask + (irq_num) * 4,%eax ; \
- movl %eax,_cpl ; \
- sti ; \
- call *_intr_handler + (irq_num) * 4 ; \
- cli ; /* must unmask _imen and icu atomically */ \
- movb _imen + IRQ_BYTE(irq_num),%al ; \
- andb $~IRQ_BIT(irq_num),%al ; \
- movb %al,_imen + IRQ_BYTE(irq_num) ; \
- outb %al,$icu+2 ; \
- sti ; /* XXX _doreti repeats the cli/sti */ \
- MEXITCOUNT ; \
- /* We could usually avoid the following jmp by inlining some of */ \
- /* _doreti, but it's probably better to use less cache. */ \
- jmp _doreti ; \
-; \
- ALIGN_TEXT ; \
-2: ; \
- /* XXX skip mcounting here to avoid double count */ \
- orb $IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \
- popl %es ; \
- popl %ds ; \
- popal ; \
- addl $4+4,%esp ; \
- iret
-
-MCOUNT_LABEL(bintr)
- FAST_INTR(0,fastintr0, ENABLE_ICU1)
- FAST_INTR(1,fastintr1, ENABLE_ICU1)
- FAST_INTR(2,fastintr2, ENABLE_ICU1)
- FAST_INTR(3,fastintr3, ENABLE_ICU1)
- FAST_INTR(4,fastintr4, ENABLE_ICU1)
- FAST_INTR(5,fastintr5, ENABLE_ICU1)
- FAST_INTR(6,fastintr6, ENABLE_ICU1)
- FAST_INTR(7,fastintr7, ENABLE_ICU1)
- FAST_INTR(8,fastintr8, ENABLE_ICU1_AND_2)
- FAST_INTR(9,fastintr9, ENABLE_ICU1_AND_2)
- FAST_INTR(10,fastintr10, ENABLE_ICU1_AND_2)
- FAST_INTR(11,fastintr11, ENABLE_ICU1_AND_2)
- FAST_INTR(12,fastintr12, ENABLE_ICU1_AND_2)
- FAST_INTR(13,fastintr13, ENABLE_ICU1_AND_2)
- FAST_INTR(14,fastintr14, ENABLE_ICU1_AND_2)
- FAST_INTR(15,fastintr15, ENABLE_ICU1_AND_2)
- INTR(0,intr0, IO_ICU1, ENABLE_ICU1, al)
- INTR(1,intr1, IO_ICU1, ENABLE_ICU1, al)
- INTR(2,intr2, IO_ICU1, ENABLE_ICU1, al)
- INTR(3,intr3, IO_ICU1, ENABLE_ICU1, al)
- INTR(4,intr4, IO_ICU1, ENABLE_ICU1, al)
- INTR(5,intr5, IO_ICU1, ENABLE_ICU1, al)
- INTR(6,intr6, IO_ICU1, ENABLE_ICU1, al)
- INTR(7,intr7, IO_ICU1, ENABLE_ICU1, al)
- INTR(8,intr8, IO_ICU2, ENABLE_ICU1_AND_2, ah)
- INTR(9,intr9, IO_ICU2, ENABLE_ICU1_AND_2, ah)
- INTR(10,intr10, IO_ICU2, ENABLE_ICU1_AND_2, ah)
- INTR(11,intr11, IO_ICU2, ENABLE_ICU1_AND_2, ah)
- INTR(12,intr12, IO_ICU2, ENABLE_ICU1_AND_2, ah)
- INTR(13,intr13, IO_ICU2, ENABLE_ICU1_AND_2, ah)
- INTR(14,intr14, IO_ICU2, ENABLE_ICU1_AND_2, ah)
- INTR(15,intr15, IO_ICU2, ENABLE_ICU1_AND_2, ah)
-MCOUNT_LABEL(eintr)
-
- .data
-ihandlers: /* addresses of interrupt handlers */
- /* actually resumption addresses for HWI's */
- .long Xresume0, Xresume1, Xresume2, Xresume3
- .long Xresume4, Xresume5, Xresume6, Xresume7
- .long Xresume8, Xresume9, Xresume10, Xresume11
- .long Xresume12, Xresume13, Xresume14, Xresume15
- .long swi_tty, swi_net, 0, 0, 0, 0, 0, 0
- .long 0, 0, 0, 0, 0, 0, _softclock, swi_ast
-imasks: /* masks for interrupt handlers */
- .space NHWI*4 /* padding; HWI masks are elsewhere */
- .long SWI_TTY_MASK, SWI_NET_MASK, 0, 0, 0, 0, 0, 0
- .long 0, 0, 0, 0, 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK
- .globl _intr_nesting_level
-_intr_nesting_level:
- .byte 0
- .space 3
-
-/*
- * Interrupt counters and names. The format of these and the label names
- * must agree with what vmstat expects. The tables are indexed by device
- * ids so that we don't have to move the names around as devices are
- * attached.
- */
-#include "vector.h"
- .globl _intrcnt, _eintrcnt
-_intrcnt:
- .space (NR_DEVICES + ICU_LEN) * 4
-_eintrcnt:
-
- .globl _intrnames, _eintrnames
-_intrnames:
- .ascii DEVICE_NAMES
- .asciz "stray irq0"
- .asciz "stray irq1"
- .asciz "stray irq2"
- .asciz "stray irq3"
- .asciz "stray irq4"
- .asciz "stray irq5"
- .asciz "stray irq6"
- .asciz "stray irq7"
- .asciz "stray irq8"
- .asciz "stray irq9"
- .asciz "stray irq10"
- .asciz "stray irq11"
- .asciz "stray irq12"
- .asciz "stray irq13"
- .asciz "stray irq14"
- .asciz "stray irq15"
-_eintrnames:
-
- .text
OpenPOWER on IntegriCloud