summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorasami <asami@FreeBSD.org>1996-11-02 10:41:28 +0000
committerasami <asami@FreeBSD.org>1996-11-02 10:41:28 +0000
commit223875ec7d51de4b686f9069a84494af29734cf6 (patch)
tree9675654af532c3965b39dbb0dd6f132eab3714d7
parent2ccb731676c10d2eff50861371a9cb4cdb505e81 (diff)
downloadFreeBSD-src-223875ec7d51de4b686f9069a84494af29734cf6.zip
FreeBSD-src-223875ec7d51de4b686f9069a84494af29734cf6.tar.gz
The last update/merge of PC98 stuff before 2.2. The whole
pc98/pc98/sound directory has vanished now! Submitted by: FreeBSD(98) Development Team
-rw-r--r--sys/conf/files.pc9826
-rw-r--r--sys/conf/options.pc983
-rw-r--r--sys/i386/isa/lptreg.h26
-rw-r--r--sys/i386/isa/sound/ad1848.c56
-rw-r--r--sys/i386/isa/sound/opl3.c8
-rw-r--r--sys/i386/isa/sound/pas2_pcm.c4
-rw-r--r--sys/i386/isa/sound/pcm86.c (renamed from sys/pc98/pc98/sound/pcm86.c)2
-rw-r--r--sys/i386/isa/sound/sb16_dsp.c24
-rw-r--r--sys/i386/isa/sound/sb16_midi.c6
-rw-r--r--sys/i386/isa/sound/sb_dsp.c29
-rw-r--r--sys/i386/isa/sound/sound_switch.c6
-rw-r--r--sys/i386/isa/sound/soundcard.c26
-rw-r--r--sys/i386/isa/wdreg.h33
-rw-r--r--sys/pc98/boot/biosboot/Makefile6
-rw-r--r--sys/pc98/boot/biosboot/serial.S7
-rw-r--r--sys/pc98/cbus/fdc.c5
-rw-r--r--sys/pc98/cbus/sio.c13
-rw-r--r--sys/pc98/conf/files.pc9826
-rw-r--r--sys/pc98/conf/options.pc983
-rw-r--r--sys/pc98/i386/machdep.c12
-rw-r--r--sys/pc98/i386/userconfig.c9
-rw-r--r--sys/pc98/pc98/fd.c5
-rw-r--r--sys/pc98/pc98/fdc.h84
-rw-r--r--sys/pc98/pc98/ft.c5
-rw-r--r--sys/pc98/pc98/lpt.c16
-rw-r--r--sys/pc98/pc98/lptreg.h59
-rw-r--r--sys/pc98/pc98/machdep.c12
-rw-r--r--sys/pc98/pc98/sio.c13
-rw-r--r--sys/pc98/pc98/sioreg.h6
-rw-r--r--sys/pc98/pc98/sound/COPYING25
-rw-r--r--sys/pc98/pc98/sound/ad1848.c1529
-rw-r--r--sys/pc98/pc98/sound/opl3.c1292
-rw-r--r--sys/pc98/pc98/sound/pas2_pcm.c461
-rw-r--r--sys/pc98/pc98/sound/sb16_dsp.c593
-rw-r--r--sys/pc98/pc98/sound/sb16_midi.c311
-rw-r--r--sys/pc98/pc98/sound/sb_dsp.c1252
-rw-r--r--sys/pc98/pc98/sound/sound_config.h384
-rw-r--r--sys/pc98/pc98/sound/sound_switch.c544
-rw-r--r--sys/pc98/pc98/sound/soundcard.c573
-rw-r--r--sys/pc98/pc98/spkr.c12
-rw-r--r--sys/pc98/pc98/wcd.c1217
-rw-r--r--sys/pc98/pc98/wd.c33
-rw-r--r--sys/pc98/pc98/wdreg.h222
43 files changed, 339 insertions, 8639 deletions
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index 08f74ae..f4849e2 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.pc98,v 1.8 1996/10/23 07:24:49 asami Exp $
+# $Id: files.pc98,v 1.9 1996/10/30 22:39:31 asami Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -151,17 +151,17 @@ pc98/isa/seagate.c optional sea device-driver
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
+i386/isa/sound/pcm86.c optional pcm 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
+i386/isa/sound/soundcard.c optional snd device-driver
+i386/isa/sound/sound_switch.c optional snd 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
+i386/isa/sound/opl3.c optional opl 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
@@ -170,9 +170,9 @@ 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
+i386/isa/sound/ad1848.c optional gusxvi device-driver
+i386/isa/sound/ad1848.c optional gus device-driver
+i386/isa/sound/ad1848.c optional mss 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
@@ -181,17 +181,17 @@ 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
+i386/isa/sound/pas2_pcm.c optional pas 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
+i386/isa/sound/sb_dsp.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
+i386/isa/sound/sb16_dsp.c optional sbxvi device-driver
+i386/isa/sound/sb16_midi.c optional sbmidi 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
@@ -206,7 +206,7 @@ pc98/isa/ultra14f.c optional uha device-driver
pc98/pc98/wd.c optional wdc device-driver
pc98/pc98/wd.c optional wd device-driver
i386/isa/atapi.c optional atapi device-driver
-pc98/pc98/wcd.c optional wcd device-driver
+i386/isa/wcd.c optional wcd device-driver
pc98/isa/wd7000.c optional wds device-driver
pc98/pc98/wt.c optional wt device-driver
i386/linux/imgact_linux.c optional compat_linux
diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98
index 106083c..e9cca8e 100644
--- a/sys/conf/options.pc98
+++ b/sys/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.7 1996/10/29 08:36:14 asami Exp $
+# $Id: options.pc98,v 1.8 1996/10/30 22:39:32 asami Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -17,6 +17,7 @@ BREAK_TO_DEBUGGER opt_comconsole.h
COMCONSOLE opt_comconsole.h
CONADDR opt_comconsole.h
CONUNIT opt_comconsole.h
+CONSPEED opt_comconsole.h
COM_ESP opt_sio.h
COM_MULTIPORT opt_sio.h
DSI_SOFT_MODEM opt_sio.h
diff --git a/sys/i386/isa/lptreg.h b/sys/i386/isa/lptreg.h
index 9e10ba9..583e96f 100644
--- a/sys/i386/isa/lptreg.h
+++ b/sys/i386/isa/lptreg.h
@@ -6,7 +6,7 @@
* William Jolitz.
*
* form: @(#)lptreg.h 1.1 (Berkeley) 12/19/90
- * $Id$
+ * $Id: lptreg.h,v 1.2 1993/10/16 13:46:12 rgrimes Exp $
*/
/*
@@ -16,6 +16,29 @@
* Copyright (C) William Jolitz 1990
*/
+/*
+ * modified for PC9801 by A.Kojima
+ * Kyoto University Microcomputer Club (KMC)
+ */
+
+#ifdef PC98
+#define lpt_pstb_ctrl (-9) /* PSTB enable control */
+#define LPC_EN_PSTB 0xc /* PSTB enable */
+#define LPC_DIS_PSTB 0xd /* PSTB disable */
+
+#define lpt_data 0 /* Data to/from printer (R/W) */
+
+#define lpt_status 2 /* Status of printer (R) */
+#define LPS_NBSY 0x4 /* printer no ack of data */
+
+#define lpt_control 6 /* Control printer (W) */
+#define LPC_MODE8255 0x82 /* 8255 mode */
+#define LPC_IRQ8 0x6 /* IRQ8 active */
+#define LPC_NIRQ8 0x7 /* IRQ8 inactive */
+#define LPC_PSTB 0xe /* PSTB active */
+#define LPC_NPSTB 0xf /* PSTB inactive */
+
+#else /* IBM-PC */
#define lpt_data 0 /* Data to/from printer (R/W) */
#define lpt_status 1 /* Status of printer (R) */
@@ -30,4 +53,5 @@
#define LPC_AUTOL 0x02 /* automatic linefeed */
#define LPC_NINIT 0x04 /* initialize printer */
#define LPC_SEL 0x08 /* printer selected */
+#endif
#define LPC_ENA 0x10 /* printer out of paper */
diff --git a/sys/i386/isa/sound/ad1848.c b/sys/i386/isa/sound/ad1848.c
index 8c385bd..0dc5464 100644
--- a/sys/i386/isa/sound/ad1848.c
+++ b/sys/i386/isa/sound/ad1848.c
@@ -157,9 +157,15 @@ wait_for_calibration (ad1848_info * devc)
*/
timeout = 100000;
+#ifdef PC98
+ while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
+ timeout--;
+ if ((INB (devc->base) & 0x80) == 0x80)
+#else
while (timeout > 0 && INB (devc->base) & 0x80)
timeout--;
if (INB (devc->base) & 0x80)
+#endif
printk ("ad1848: Auto calibration timed out(1).\n");
timeout = 100;
@@ -474,7 +480,11 @@ static struct audio_operations ad1848_pcm_operations[MAX_AUDIO_DEV] =
{
{
"Generic AD1848 codec",
+#ifdef PC98
+ NEEDS_RESTART,
+#else
DMA_AUTOMODE,
+#endif
AFMT_U8, /* Will be set later */
NULL,
ad1848_open,
@@ -910,8 +920,22 @@ ad1848_prepare_for_IO (int dev, int bsize, int bcount)
* Write to I8 starts resyncronization. Wait until it completes.
*/
timeout = 10000;
+#ifdef PC98
+ while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
+#else
while (timeout > 0 && INB (devc->base) == 0x80)
+#endif
+ timeout--;
+
+#ifdef PC98
+ ad_write (devc, 8, fs);
+ /*
+ * Write to I8 starts resyncronization. Wait until it completes.
+ */
+ timeout = 10000;
+ while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
timeout--;
+#endif
/*
* If mode == 2 (CS4231), set I28 also. It's the capture format register.
@@ -924,11 +948,26 @@ ad1848_prepare_for_IO (int dev, int bsize, int bcount)
* Write to I28 starts resyncronization. Wait until it completes.
*/
timeout = 10000;
+#ifdef PC98
+ while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
+#else
while (timeout > 0 && INB (devc->base) == 0x80)
+#endif
timeout--;
}
+#ifdef PC98
+ ad_write (devc, 28, fs);
+
+ /*
+ * Write to I28 starts resyncronization. Wait until it completes.
+ */
+ timeout = 10000;
+ while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
+ timeout--;
+#endif
+
ad_leave_MCE (devc); /*
* Starts the calibration process and
* enters playback mode after it.
@@ -950,7 +989,13 @@ ad1848_halt (int dev)
ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
ad_mute (devc);
+#ifdef PC98
+ ad_enter_MCE (devc);
+#endif
ad_write (devc, 9, ad_read (devc, 9) & ~0x03); /* Stop DMA */
+#ifdef PC98
+ ad_leave_MCE (devc);
+#endif
OUTB (0, io_Status (devc)); /* Clear interrupt status */
ad_enter_MCE (devc);
@@ -1399,7 +1444,11 @@ probe_ms_sound (struct address_info *hw_config)
return 0;
}
+#ifdef PC98
+ if (hw_config->irq > 12)
+#else
if (hw_config->irq > 11)
+#endif
{
printk ("MSS: Bad IRQ %d\n", hw_config->irq);
return 0;
@@ -1433,10 +1482,17 @@ probe_ms_sound (struct address_info *hw_config)
long
attach_ms_sound (long mem_start, struct address_info *hw_config)
{
+#ifdef PC98
+ static char interrupt_bits[13] =
+ {
+ -1, -1, -1, 0x08, -1, 0x10, -1, -1, -1, -1, 0x18, -1, 0x20
+ };
+#else
static char interrupt_bits[12] =
{
-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
};
+#endif
char bits;
static char dma_bits[4] =
diff --git a/sys/i386/isa/sound/opl3.c b/sys/i386/isa/sound/opl3.c
index b3660b7..42379cd 100644
--- a/sys/i386/isa/sound/opl3.c
+++ b/sys/i386/isa/sound/opl3.c
@@ -47,7 +47,11 @@
static int opl3_enabled = 0;
static int opl4_enabled = 0;
+#ifdef PC98
+static int left_address = 0x28d2, right_address = 0x28d2, both_address = 0;
+#else
static int left_address = 0x388, right_address = 0x388, both_address = 0;
+#endif
static int nr_voices = 9;
static int logical_voices[MAX_VOICE] =
@@ -812,10 +816,14 @@ opl3_command (int io_addr, unsigned int addr, unsigned int val)
for (i = 0; i < 2; i++)
INB (io_addr);
+#ifdef PC98
+ OUTB ((unsigned char) (val & 0xff), io_addr + 0x100);
+#else
OUTB ((unsigned char) (val & 0xff), io_addr + 1); /*
* Write to register
*
*/
+#endif
if (!opl3_enabled)
{
diff --git a/sys/i386/isa/sound/pas2_pcm.c b/sys/i386/isa/sound/pas2_pcm.c
index 97ae76c..db91165 100644
--- a/sys/i386/isa/sound/pas2_pcm.c
+++ b/sys/i386/isa/sound/pas2_pcm.c
@@ -377,7 +377,11 @@ pas_pcm_prepare_for_output (int dev, int bsize, int bcount)
static struct audio_operations pas_pcm_operations =
{
"Pro Audio Spectrum",
+#ifdef PC98
+ NEEDS_RESTART,
+#else
DMA_AUTOMODE,
+#endif
AFMT_U8 | AFMT_S16_LE,
NULL,
pas_pcm_open,
diff --git a/sys/pc98/pc98/sound/pcm86.c b/sys/i386/isa/sound/pcm86.c
index 40c7c25..aa7e3d7 100644
--- a/sys/pc98/pc98/sound/pcm86.c
+++ b/sys/i386/isa/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 1.2 1996/09/12 11:11:16 asami Exp $
+ * $Id: pcm86.c,v 2.4 1996/01/24 19:53:34 abtk Exp $
*/
/*
diff --git a/sys/i386/isa/sound/sb16_dsp.c b/sys/i386/isa/sound/sb16_dsp.c
index d5af2c1..5e84e67 100644
--- a/sys/i386/isa/sound/sb16_dsp.c
+++ b/sys/i386/isa/sound/sb16_dsp.c
@@ -84,7 +84,11 @@ static void dsp_cleanup (void);
static struct audio_operations sb16_dsp_operations =
{
"SoundBlaster 16",
+#ifdef PC98
+ NEEDS_RESTART,
+#else
DMA_AUTOMODE,
+#endif
AFMT_U8 | AFMT_S16_LE,
NULL,
sb16_dsp_open,
@@ -447,6 +451,17 @@ set_irq_hw (int level)
switch (level)
{
+#ifdef PC98
+ case 5:
+ ival = 8;
+ break;
+ case 3:
+ ival = 1;
+ break;
+ case 10:
+ ival = 2;
+ break;
+#else
case 5:
ival = 2;
break;
@@ -459,6 +474,7 @@ set_irq_hw (int level)
case 10:
ival = 8;
break;
+#endif
default:
printk ("SB16_IRQ_LEVEL %d does not exist\n", level);
return;
@@ -517,6 +533,9 @@ sb16_dsp_detect (struct address_info *hw_config)
if (sbc_major < 4) /* Set by the plain SB driver */
return 0; /* Not a SB16 */
+#ifdef PC98
+ hw_config->dma = sb_config->dma;
+#else
if (hw_config->dma < 4)
if (hw_config->dma != sb_config->dma)
{
@@ -524,11 +543,16 @@ sb16_dsp_detect (struct address_info *hw_config)
sb_config->dma, hw_config->dma);
return 0;
}
+#endif
dma16 = hw_config->dma;
dma8 = sb_config->dma;
set_irq_hw (sb_config->irq);
+#ifdef PC98
+ sb_setmixer (DMA_NR, hw_config->dma == 0 ? 1 : 2);
+#else
sb_setmixer (DMA_NR, (1 << hw_config->dma) | (1 << sb_config->dma));
+#endif
DEB (printk ("SoundBlaster 16: IRQ %d DMA %d OK\n", sb_config->irq, hw_config->dma));
diff --git a/sys/i386/isa/sound/sb16_midi.c b/sys/i386/isa/sound/sb16_midi.c
index 4e45e2e..7dae750 100644
--- a/sys/i386/isa/sound/sb16_midi.c
+++ b/sys/i386/isa/sound/sb16_midi.c
@@ -35,9 +35,15 @@
#include <i386/isa/sound/sb.h>
+#ifdef PC98
+#define DATAPORT (sb16midi_base)
+#define COMDPORT (sb16midi_base+0x100)
+#define STATPORT (sb16midi_base+0x100)
+#else
#define DATAPORT (sb16midi_base)
#define COMDPORT (sb16midi_base+1)
#define STATPORT (sb16midi_base+1)
+#endif
#define sb16midi_status() INB(STATPORT)
#define input_avail() (!(sb16midi_status()&INPUT_AVAIL))
diff --git a/sys/i386/isa/sound/sb_dsp.c b/sys/i386/isa/sound/sb_dsp.c
index 560fc79..82a2178 100644
--- a/sys/i386/isa/sound/sb_dsp.c
+++ b/sys/i386/isa/sound/sb_dsp.c
@@ -1067,6 +1067,30 @@ sb_dsp_detect (struct address_info *hw_config)
return 0;
#endif
+#ifdef PC98
+ switch (sbc_irq)
+ {
+ case 3:
+ sb_setmixer (IRQ_NR, 1);
+ break;
+ case 5:
+ sb_setmixer (IRQ_NR, 8);
+ break;
+ case 10:
+ sb_setmixer (IRQ_NR, 2);
+ break;
+ }
+ switch (hw_config->dma)
+ {
+ case 0:
+ sb_setmixer (DMA_NR, 1);
+ break;
+ case 3:
+ sb_setmixer (DMA_NR, 2);
+ break;
+ }
+#endif
+
return 1; /*
* Detected
*/
@@ -1137,8 +1161,13 @@ sb_dsp_init (long mem_start, struct address_info *hw_config)
#ifndef EXCLUDE_YM3812
+#ifdef PC98
+ if (sbc_major > 3 ||
+ (sbc_major == 3 && INB (0x28d2) == 0x00))
+#else
if (sbc_major > 3 ||
(sbc_major == 3 && INB (0x388) == 0x00)) /* Should be 0x06 if not OPL-3 */
+#endif
enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);
#endif
diff --git a/sys/i386/isa/sound/sound_switch.c b/sys/i386/isa/sound/sound_switch.c
index 21bcd69..83994e0 100644
--- a/sys/i386/isa/sound/sound_switch.c
+++ b/sys/i386/isa/sound/sound_switch.c
@@ -171,10 +171,16 @@ init_status (void)
return;
if (!put_status_int (snd_installed_cards[i].config.irq, 10))
return;
+#ifdef PC98
+ if (snd_installed_cards[i].config.dma >= 0) {
+#endif
if (!put_status (" drq "))
return;
if (!put_status_int (snd_installed_cards[i].config.dma, 10))
return;
+#ifdef PC98
+ }
+#endif
if (!snd_installed_cards[i].enabled)
if (!put_status (")"))
diff --git a/sys/i386/isa/sound/soundcard.c b/sys/i386/isa/sound/soundcard.c
index c7af8ab..3a06b6c 100644
--- a/sys/i386/isa/sound/soundcard.c
+++ b/sys/i386/isa/sound/soundcard.c
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: soundcard.c,v 1.42 1996/03/28 14:31:13 scrappy Exp $
+ * $Id: soundcard.c,v 1.43 1996/09/10 08:26:06 bde Exp $
*/
#include <i386/isa/sound/sound_config.h>
@@ -91,6 +91,9 @@ struct isa_driver gusxvidriver = {sndprobe, sndattach, "gusxvi"};
struct isa_driver gusmaxdriver = {sndprobe, sndattach, "gusmax"};
struct isa_driver uartdriver = {sndprobe, sndattach, "uart"};
struct isa_driver mssdriver = {sndprobe, sndattach, "mss"};
+#ifdef PC98
+struct isa_driver pcmdriver = {sndprobe, sndattach, "pcm"};
+#endif
static unsigned short
ipri_to_irq (unsigned short ipri);
@@ -274,6 +277,10 @@ driver_to_voxunit(struct isa_driver *driver)
return(SNDCARD_GUS16);
else if(driver == &mssdriver)
return(SNDCARD_MSS);
+#ifdef PC98
+ else if(driver == &pcmdriver)
+ return(SNDCARD_PCM86);
+#endif
else
return(0);
}
@@ -291,6 +298,19 @@ sndprobe (struct isa_device *dev)
hw_config.dma_read = dev->id_flags; /* misuse the flags field for read dma*/
if(unit)
+#ifdef PC98
+ if(unit == SNDCARD_PCM86) {
+ int result;
+
+ result = sndtable_probe (unit, &hw_config);
+ dev->id_iobase = hw_config.io_base;
+ dev->id_irq = (1 << hw_config.irq);
+ dev->id_drq = hw_config.dma;
+
+ return result;
+ }
+ else
+#endif
return sndtable_probe (unit, &hw_config);
else
return 0;
@@ -468,7 +488,11 @@ sound_mem_init (void)
for (dev = 0; dev < num_audiodevs; dev++) /* Enumerate devices */
if (!(dsp_init_mask & (1 << dev))) /* Not already done */
+#ifdef PC98
+ if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
+#else
if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan > 0)
+#endif
{
dsp_init_mask |= (1 << dev);
dmap = audio_devs[dev]->dmap;
diff --git a/sys/i386/isa/wdreg.h b/sys/i386/isa/wdreg.h
index 20d37da..2a0a32f 100644
--- a/sys/i386/isa/wdreg.h
+++ b/sys/i386/isa/wdreg.h
@@ -34,12 +34,42 @@
* SUCH DAMAGE.
*
* from: @(#)wdreg.h 7.1 (Berkeley) 5/9/91
- * $Id: wdreg.h,v 1.11 1996/01/28 22:16:20 wollman Exp $
+ * $Id: wdreg.h,v 1.12 1996/06/08 10:03:38 bde Exp $
+ */
+
+/*
+ * modified for PC9801 by F.Ukai
+ * Kyoto University Microcomputer Club (KMC)
*/
/*
* Disk Controller register definitions.
*/
+#ifdef PC98
+#define wd_data 0x0 /* data register (R/W - 16 bits) */
+#define wd_error 0x2 /* error register (R) */
+#define wd_precomp wd_error /* write precompensation (W) */
+#define wd_features wd_error /* features register (W) */
+#define wd_seccnt 0x4 /* sector count (R/W) */
+#define wd_sector 0x6 /* first sector number (R/W) */
+#define wd_cyl_lo 0x8 /* cylinder address, low byte (R/W) */
+#define wd_cyl_hi 0xa /* cylinder address, high byte (R/W)*/
+#define wd_sdh 0xc /* sector size/drive/head (R/W)*/
+#define wd_command 0xe /* command register (W) */
+#define wd_status wd_command /* immediate status (R) */
+
+#define wd_altsts_nec 0x10c /*alternate fixed disk status(via 1015) (R)*/
+#define wd_ctlr_nec 0x10c /*fixed disk controller control(via 1015) (W)*/
+#define wd_altsts_epson 0x3 /*alternate fixed disk status(via 1015) (R)*/
+#define wd_ctlr_epson 0x3 /*fixed disk controller control(via 1015) (W)*/
+#define wd_altsts wd_alsts_nec
+#define wd_ctlr wd_ctlr_nec
+
+#define WDCTL_4BIT 0x8 /* use four head bits (wd1003) */
+#define WDCTL_RST 0x4 /* reset the controller */
+#define WDCTL_IDS 0x2 /* disable controller interrupts */
+#define wd_digin 0x10e /* disk controller input(via 1015) (R)*/
+#else /* IBM-PC */
#define wd_data 0x0 /* data register (R/W - 16 bits) */
#define wd_error 0x1 /* error register (R) */
#define wd_precomp wd_error /* write precompensation (W) */
@@ -58,6 +88,7 @@
#define WDCTL_RST 0x4 /* reset the controller */
#define WDCTL_IDS 0x2 /* disable controller interrupts */
#define wd_digin 0x207 /* disk controller input(via 1015) (R)*/
+#endif /* PC98 */
/*
* Status Bits.
diff --git a/sys/pc98/boot/biosboot/Makefile b/sys/pc98/boot/biosboot/Makefile
index 61f5c04..9cb20ed 100644
--- a/sys/pc98/boot/biosboot/Makefile
+++ b/sys/pc98/boot/biosboot/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.3 1996/09/12 11:08:41 asami Exp $
+# $Id: Makefile,v 1.4 1996/10/23 07:24:27 asami Exp $
#
PROG= boot
@@ -37,6 +37,10 @@ CFLAGS+= -DCOMCONSOLE=${BOOT_COMCONSOLE_PORT} \
-DCOMCONSOLE_CLK=${BOOT_COMCONSOLE_CLK} \
-DCOMCONSOLE_MODE=${BOOT_COMCONSOLE_MODE}
+# feature not implemented
+# BOOT_COMCONSOLE_SPEED?=9600
+# CFLAGS+= -DCONSPEED=${BOOT_COMCONSOLE_SPEED}
+
# Enable code to take the default boot string from a fixed location on the
# disk. See nextboot(8) and README.386BSD for more info.
#CFLAGS+= -DNAMEBLOCK
diff --git a/sys/pc98/boot/biosboot/serial.S b/sys/pc98/boot/biosboot/serial.S
index d1091cd..d8d4b6f 100644
--- a/sys/pc98/boot/biosboot/serial.S
+++ b/sys/pc98/boot/biosboot/serial.S
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
- * $Id: serial.S,v 1.3 1995/04/21 16:30:18 bde Exp $
+ * $Id: serial.S,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
*/
/*
@@ -72,6 +72,11 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.file "serial.s"
#include "asm.h"
+#ifdef PC98
+#include "../../pc98/sioreg.h"
+#else
+#include "../../isa/sioreg.h"
+#endif
.text
/*
diff --git a/sys/pc98/cbus/fdc.c b/sys/pc98/cbus/fdc.c
index be8751c..4ca93de 100644
--- a/sys/pc98/cbus/fdc.c
+++ b/sys/pc98/cbus/fdc.c
@@ -43,7 +43,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.6 1996/09/10 09:37:50 asami Exp $
+ * $Id: fd.c,v 1.7 1996/10/23 07:25:15 asami Exp $
*
*/
@@ -75,14 +75,13 @@
#include <pc98/pc98/epsonio.h>
#include <i386/isa/isa_device.h>
#include <pc98/pc98/fdreg.h>
-#include <pc98/pc98/fdc.h>
#else
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/fdreg.h>
-#include <i386/isa/fdc.h>
#include <i386/isa/rtc.h>
#endif
+#include <i386/isa/fdc.h>
#include <machine/stdarg.h>
#if NFT > 0
#include <sys/ftape.h>
diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c
index bcd8f13..c72f7b8 100644
--- a/sys/pc98/cbus/sio.c
+++ b/sys/pc98/cbus/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.7 1996/09/12 11:09:56 asami Exp $
+ * $Id: sio.c,v 1.8 1996/10/09 21:46:46 asami Exp $
*/
#include "opt_comconsole.h"
@@ -423,6 +423,7 @@ static struct cdevsw sio_cdevsw = {
static int comconsole = -1;
static speed_t comdefaultrate = TTYDEF_SPEED;
+static speed_t condefaultrate = CONSPEED;
static u_int com_events; /* input chars + weighted output completions */
static int sio_timeout;
static int sio_timeouts_until_log;
@@ -1130,9 +1131,11 @@ sioattach(isdp)
com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
com->it_in.c_lflag = TTYDEF_LFLAG;
com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
- }
+ com->it_in.c_ispeed = com->it_in.c_ospeed = condefaultrate;
+ } else
+ com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
+
termioschars(&com->it_in);
- com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
com->it_out = com->it_in;
/* attempt to determine UART type */
@@ -3052,7 +3055,7 @@ siocnopen(sp)
/*
* Save all the device control registers except the fifo register
- * and set our default ones (cs8 -parenb speed=comdefaultrate).
+ * and set our default ones (cs8 -parenb speed=condefaultrate).
* We can't save the fifo register since it is read-only.
*/
iobase = siocniobase;
@@ -3069,7 +3072,7 @@ siocnopen(sp)
* data input register. This also reduces the effects of the
* UMC8669F bug.
*/
- divisor = ttspeedtab(comdefaultrate, comspeedtab);
+ divisor = ttspeedtab(condefaultrate, comspeedtab);
dlbl = divisor & 0xFF;
if (sp->dlbl != dlbl)
outb(iobase + com_dlbl, dlbl);
diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98
index 08f74ae..f4849e2 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.8 1996/10/23 07:24:49 asami Exp $
+# $Id: files.pc98,v 1.9 1996/10/30 22:39:31 asami Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
@@ -151,17 +151,17 @@ pc98/isa/seagate.c optional sea device-driver
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
+i386/isa/sound/pcm86.c optional pcm 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
+i386/isa/sound/soundcard.c optional snd device-driver
+i386/isa/sound/sound_switch.c optional snd 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
+i386/isa/sound/opl3.c optional opl 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
@@ -170,9 +170,9 @@ 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
+i386/isa/sound/ad1848.c optional gusxvi device-driver
+i386/isa/sound/ad1848.c optional gus device-driver
+i386/isa/sound/ad1848.c optional mss 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
@@ -181,17 +181,17 @@ 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
+i386/isa/sound/pas2_pcm.c optional pas 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
+i386/isa/sound/sb_dsp.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
+i386/isa/sound/sb16_dsp.c optional sbxvi device-driver
+i386/isa/sound/sb16_midi.c optional sbmidi 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
@@ -206,7 +206,7 @@ pc98/isa/ultra14f.c optional uha device-driver
pc98/pc98/wd.c optional wdc device-driver
pc98/pc98/wd.c optional wd device-driver
i386/isa/atapi.c optional atapi device-driver
-pc98/pc98/wcd.c optional wcd device-driver
+i386/isa/wcd.c optional wcd device-driver
pc98/isa/wd7000.c optional wds device-driver
pc98/pc98/wt.c optional wt device-driver
i386/linux/imgact_linux.c optional compat_linux
diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98
index 106083c..e9cca8e 100644
--- a/sys/pc98/conf/options.pc98
+++ b/sys/pc98/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.7 1996/10/29 08:36:14 asami Exp $
+# $Id: options.pc98,v 1.8 1996/10/30 22:39:32 asami Exp $
BOUNCEPAGES opt_bounce.h
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -17,6 +17,7 @@ BREAK_TO_DEBUGGER opt_comconsole.h
COMCONSOLE opt_comconsole.h
CONADDR opt_comconsole.h
CONUNIT opt_comconsole.h
+CONSPEED opt_comconsole.h
COM_ESP opt_sio.h
COM_MULTIPORT opt_sio.h
DSI_SOFT_MODEM opt_sio.h
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c
index 282b74dc..c6539d9 100644
--- a/sys/pc98/i386/machdep.c
+++ b/sys/pc98/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.10 1996/10/23 07:25:00 asami Exp $
+ * $Id: machdep.c,v 1.11 1996/10/29 08:36:16 asami Exp $
*/
#include "npx.h"
@@ -697,6 +697,16 @@ cpu_boot(int howto)
}
/*
+ * Shutdown the CPU as much as possible
+ */
+void
+cpu_halt(void)
+{
+ for (;;)
+ __asm__ ("hlt");
+}
+
+/*
* Clear registers on exec
*/
void
diff --git a/sys/pc98/i386/userconfig.c b/sys/pc98/i386/userconfig.c
index 55ead7a..d15a654 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.9 1996/10/29 08:36:17 asami Exp $
+ ** $Id: userconfig.c,v 1.10 1996/10/30 22:39:36 asami Exp $
**/
/**
@@ -1390,6 +1390,7 @@ yesnocancel(char *str)
for(;;)
switch(getchar())
{
+ case -1:
case 'n':
case 'N':
return(0);
@@ -1577,6 +1578,7 @@ editval(int x, int y, int width, int hex, int min, int max, int *val, int ro)
VetRet(KEY_TAB); /* verify and maybe return */
break;
+ case -1:
case 'q':
case 'Q':
VetRet(KEY_EXIT);
@@ -2247,7 +2249,7 @@ visuserconfig(void)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: userconfig.c,v 1.9 1996/10/29 08:36:17 asami Exp $
+ * $Id: userconfig.c,v 1.63 1996/10/30 21:40:15 julian Exp $
*/
#include "scbus.h"
@@ -2679,6 +2681,7 @@ introfunc(CmdParm *parms)
extended = 0;
break;
+ case -1:
case 'Q':
case 'q':
clear();
@@ -2804,7 +2807,7 @@ cngets(char *input, int maxin)
continue;
}
printf("%c", c);
- if ((++nchars == maxin) || (c == '\n') || (c == '\r')) {
+ if ((++nchars == maxin) || (c == '\n') || (c == '\r') || ( c == -1)) {
*input = '\0';
break;
}
diff --git a/sys/pc98/pc98/fd.c b/sys/pc98/pc98/fd.c
index be8751c..4ca93de 100644
--- a/sys/pc98/pc98/fd.c
+++ b/sys/pc98/pc98/fd.c
@@ -43,7 +43,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.6 1996/09/10 09:37:50 asami Exp $
+ * $Id: fd.c,v 1.7 1996/10/23 07:25:15 asami Exp $
*
*/
@@ -75,14 +75,13 @@
#include <pc98/pc98/epsonio.h>
#include <i386/isa/isa_device.h>
#include <pc98/pc98/fdreg.h>
-#include <pc98/pc98/fdc.h>
#else
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/fdreg.h>
-#include <i386/isa/fdc.h>
#include <i386/isa/rtc.h>
#endif
+#include <i386/isa/fdc.h>
#include <machine/stdarg.h>
#if NFT > 0
#include <sys/ftape.h>
diff --git a/sys/pc98/pc98/fdc.h b/sys/pc98/pc98/fdc.h
deleted file mode 100644
index b763b1c..0000000
--- a/sys/pc98/pc98/fdc.h
+++ /dev/null
@@ -1,84 +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.
- *
- * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fdc.h,v 1.6 1996/05/03 14:57:22 phk Exp $
- *
- */
-
-enum fdc_type
-{
- FDC_NE765, FDC_I82077, FDC_NE72065, FDC_UNKNOWN = -1
-};
-
-
-/***********************************************************************\
-* Per controller structure. *
-\***********************************************************************/
-struct fdc_data
-{
- int fdcu; /* our unit number */
- int baseport;
- int dmachan;
- int flags;
-#define FDC_ATTACHED 0x01
-#define FDC_HASFTAPE 0x02
-#define FDC_TAPE_BUSY 0x04
-#define FDC_STAT_VALID 0x08
- struct fd_data *fd;
- int fdu; /* the active drive */
- int state;
- int retry;
- int fdout; /* mirror of the w/o digital output reg */
- u_long status[7]; /* copy of the registers */
- enum fdc_type fdct; /* chip version of FDC */
- int fdc_errs; /* number of logged errors */
- struct buf_queue_head head; /* Head of buf chain */
-};
-
-/***********************************************************************\
-* Throughout this file the following conventions will be used: *
-* fd is a pointer to the fd_data struct for the drive in question *
-* fdc is a pointer to the fdc_data struct for the controller *
-* fdu is the floppy drive unit number *
-* fdcu is the floppy controller unit number *
-* fdsu is the floppy drive unit number on that controller. (sub-unit) *
-\***********************************************************************/
-typedef int fdu_t;
-typedef int fdcu_t;
-typedef int fdsu_t;
-typedef struct fd_data *fd_p;
-typedef struct fdc_data *fdc_p;
-typedef enum fdc_type fdc_t;
-
-#define FDUNIT(s) (((s)>>6)&03)
-#define FDTYPE(s) ((s)&077)
diff --git a/sys/pc98/pc98/ft.c b/sys/pc98/pc98/ft.c
index 36630f2..c3d0c39 100644
--- a/sys/pc98/pc98/ft.c
+++ b/sys/pc98/pc98/ft.c
@@ -17,7 +17,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*
* ft.c - QIC-40/80 floppy tape driver
- * $Id: ft.c,v 1.4 1996/09/03 10:23:26 asami Exp $
+ * $Id: ft.c,v 1.5 1996/09/10 09:37:55 asami Exp $
*
* 01/19/95 ++sg
* Cleaned up recalibrate/seek code at attach time for FreeBSD 2.x.
@@ -84,12 +84,11 @@
#include <i386/isa/isa_device.h>
#ifdef PC98
#include <pc98/pc98/fdreg.h>
-#include <pc98/pc98/fdc.h>
#else
#include <i386/isa/fdreg.h>
-#include <i386/isa/fdc.h>
#include <i386/isa/rtc.h>
#endif
+#include <i386/isa/fdc.h>
#include <i386/isa/ftreg.h>
extern int ftintr __P((ftu_t ftu));
diff --git a/sys/pc98/pc98/lpt.c b/sys/pc98/pc98/lpt.c
index 0d3588c..84235d6 100644
--- a/sys/pc98/pc98/lpt.c
+++ b/sys/pc98/pc98/lpt.c
@@ -46,7 +46,7 @@
* SUCH DAMAGE.
*
* from: unknown origin, 386BSD 0.1
- * $Id: lpt.c,v 1.4 1996/09/03 10:23:44 asami Exp $
+ * $Id: lpt.c,v 1.5 1996/09/10 09:38:13 asami Exp $
*/
/*
@@ -125,13 +125,11 @@
#ifdef PC98
#include <pc98/pc98/pc98.h>
-#include <i386/isa/isa_device.h>
-#include <pc98/pc98/lptreg.h>
-#else /* !PC98 */
+#else
#include <i386/isa/isa.h>
+#endif
#include <i386/isa/isa_device.h>
#include <i386/isa/lptreg.h>
-#endif /* PC98 */
#ifdef INET
#include <sys/mbuf.h>
@@ -384,16 +382,12 @@ lpt_port_test (short port, u_char data, u_char mask)
* Quick exit on fail added.
*/
-#ifdef PC98
int
lptprobe(struct isa_device *dvp)
{
+#ifdef PC98
return 8;
-}
#else
-int
-lptprobe(struct isa_device *dvp)
-{
short port;
static short next_bios_lpt = 0;
int status;
@@ -450,8 +444,8 @@ end_probe:
outb(dvp->id_iobase+lpt_control, 0);
return (status);
-}
#endif
+}
/* XXX Todo - try and detect if interrupt is working */
int
diff --git a/sys/pc98/pc98/lptreg.h b/sys/pc98/pc98/lptreg.h
deleted file mode 100644
index 7c3693f..0000000
--- a/sys/pc98/pc98/lptreg.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * 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.
- *
- * form: @(#)lptreg.h 1.1 (Berkeley) 12/19/90
- * $Id: lptreg.h,v 1.2 1993/10/16 13:46:12 rgrimes Exp $
- */
-
-/*
- * AT Parallel Port (for lineprinter)
- * Interface port and bit definitions
- * Written by William Jolitz 12/18/90
- * Copyright (C) William Jolitz 1990
- */
-#if 0
-static char rcsid[] = "$Id: lptreg.h,v 1.1 1992/11/01 20:09:14 ukai Exp $";
-#endif
-/*
- * modified for PC9801 by A.Kojima
- * Kyoto University Microcomputer Club (KMC)
- */
-
-#ifdef PC98
-#define lpt_pstb_ctrl (-9) /* PSTB enable control */
-#define LPC_EN_PSTB 0xc /* PSTB enable */
-#define LPC_DIS_PSTB 0xd /* PSTB disable */
-
-#define lpt_data 0 /* Data to/from printer (R/W) */
-
-#define lpt_status 2 /* Status of printer (R) */
-#define LPS_NBSY 0x4 /* printer no ack of data */
-
-#define lpt_control 6 /* Control printer (W) */
-#define LPC_MODE8255 0x82 /* 8255 mode */
-#define LPC_IRQ8 0x6 /* IRQ8 active */
-#define LPC_NIRQ8 0x7 /* IRQ8 inactive */
-#define LPC_PSTB 0xe /* PSTB active */
-#define LPC_NPSTB 0xf /* PSTB inactive */
-
-#else /* IBM-PC */
-#define lpt_data 0 /* Data to/from printer (R/W) */
-
-#define lpt_status 1 /* Status of printer (R) */
-#define LPS_NERR 0x08 /* printer no error */
-#define LPS_SEL 0x10 /* printer selected */
-#define LPS_OUT 0x20 /* printer out of paper */
-#define LPS_NACK 0x40 /* printer no ack of data */
-#define LPS_NBSY 0x80 /* printer no ack of data */
-
-#define lpt_control 2 /* Control printer (R/W) */
-#define LPC_STB 0x01 /* strobe data to printer */
-#define LPC_AUTOL 0x02 /* automatic linefeed */
-#define LPC_NINIT 0x04 /* initialize printer */
-#define LPC_SEL 0x08 /* printer selected */
-#endif
-#define LPC_ENA 0x10 /* printer out of paper */
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 282b74dc..c6539d9 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.10 1996/10/23 07:25:00 asami Exp $
+ * $Id: machdep.c,v 1.11 1996/10/29 08:36:16 asami Exp $
*/
#include "npx.h"
@@ -697,6 +697,16 @@ cpu_boot(int howto)
}
/*
+ * Shutdown the CPU as much as possible
+ */
+void
+cpu_halt(void)
+{
+ for (;;)
+ __asm__ ("hlt");
+}
+
+/*
* Clear registers on exec
*/
void
diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c
index bcd8f13..c72f7b8 100644
--- a/sys/pc98/pc98/sio.c
+++ b/sys/pc98/pc98/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.7 1996/09/12 11:09:56 asami Exp $
+ * $Id: sio.c,v 1.8 1996/10/09 21:46:46 asami Exp $
*/
#include "opt_comconsole.h"
@@ -423,6 +423,7 @@ static struct cdevsw sio_cdevsw = {
static int comconsole = -1;
static speed_t comdefaultrate = TTYDEF_SPEED;
+static speed_t condefaultrate = CONSPEED;
static u_int com_events; /* input chars + weighted output completions */
static int sio_timeout;
static int sio_timeouts_until_log;
@@ -1130,9 +1131,11 @@ sioattach(isdp)
com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
com->it_in.c_lflag = TTYDEF_LFLAG;
com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
- }
+ com->it_in.c_ispeed = com->it_in.c_ospeed = condefaultrate;
+ } else
+ com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
+
termioschars(&com->it_in);
- com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
com->it_out = com->it_in;
/* attempt to determine UART type */
@@ -3052,7 +3055,7 @@ siocnopen(sp)
/*
* Save all the device control registers except the fifo register
- * and set our default ones (cs8 -parenb speed=comdefaultrate).
+ * and set our default ones (cs8 -parenb speed=condefaultrate).
* We can't save the fifo register since it is read-only.
*/
iobase = siocniobase;
@@ -3069,7 +3072,7 @@ siocnopen(sp)
* data input register. This also reduces the effects of the
* UMC8669F bug.
*/
- divisor = ttspeedtab(comdefaultrate, comspeedtab);
+ divisor = ttspeedtab(condefaultrate, comspeedtab);
dlbl = divisor & 0xFF;
if (sp->dlbl != dlbl)
outb(iobase + com_dlbl, dlbl);
diff --git a/sys/pc98/pc98/sioreg.h b/sys/pc98/pc98/sioreg.h
index 70602f0..d8f8d57 100644
--- a/sys/pc98/pc98/sioreg.h
+++ b/sys/pc98/pc98/sioreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)comreg.h 7.2 (Berkeley) 5/9/91
- * $Id: sioreg.h,v 1.4 1995/12/10 13:39:15 phk Exp $
+ * $Id: sioreg.h,v 1.1.1.1 1996/06/14 10:04:46 asami Exp $
*/
@@ -123,3 +123,7 @@
#ifndef CONUNIT
#define CONUNIT (0)
#endif
+
+#ifndef CONSPEED
+#define CONSPEED (9600)
+#endif
diff --git a/sys/pc98/pc98/sound/COPYING b/sys/pc98/pc98/sound/COPYING
deleted file mode 100644
index d1509c5..0000000
--- a/sys/pc98/pc98/sound/COPYING
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.
- *
- */
diff --git a/sys/pc98/pc98/sound/ad1848.c b/sys/pc98/pc98/sound/ad1848.c
deleted file mode 100644
index 0dc5464..0000000
--- a/sys/pc98/pc98/sound/ad1848.c
+++ /dev/null
@@ -1,1529 +0,0 @@
-/*
- * sound/ad1848.c
- *
- * The low level driver for the AD1848/CS4248 codec chip which
- * is used for example in the MS Sound System.
- *
- * The CS4231 which is used in the GUS MAX and some other cards is
- * upwards compatible with AD1848 and this driver is able to drive it.
- *
- * Copyright by Hannu Savolainen 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.
- *
- * Modified:
- * Riccardo Facchetti 24 Mar 1995
- * - Added the Audio Excel DSP 16 initialization routine.
- */
-
-#define DEB(x)
-#define DEB1(x)
-#include <i386/isa/sound/sound_config.h>
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AD1848)
-
-#include <i386/isa/sound/ad1848_mixer.h>
-
-#define IMODE_NONE 0
-#define IMODE_OUTPUT 1
-#define IMODE_INPUT 2
-#define IMODE_INIT 3
-#define IMODE_MIDI 4
-
-typedef struct
- {
- int base;
- int irq;
- int dma_capture, dma_playback;
- unsigned char MCE_bit;
- unsigned char saved_regs[16];
-
- int speed;
- unsigned char speed_bits;
- int channels;
- int audio_format;
- unsigned char format_bits;
-
- int xfer_count;
- int irq_mode;
- int intr_active;
- int opened;
- char *chip_name;
- int mode;
-
- /* Mixer parameters */
- int recmask;
- int supported_devices;
- int supported_rec_devices;
- unsigned short levels[32];
- }
-
-ad1848_info;
-
-static int nr_ad1848_devs = 0;
-static char irq2dev[16] =
-{-1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1};
-
-static char mixer2codec[MAX_MIXER_DEV] =
-{0};
-
-static int ad_format_mask[3 /*devc->mode */ ] =
-{
- 0,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW,
- AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW | AFMT_U16_LE | AFMT_IMA_ADPCM
-};
-
-static ad1848_info dev_info[MAX_AUDIO_DEV];
-
-#define io_Index_Addr(d) ((d)->base)
-#define io_Indexed_Data(d) ((d)->base+1)
-#define io_Status(d) ((d)->base+2)
-#define io_Polled_IO(d) ((d)->base+3)
-
-static int ad1848_open (int dev, int mode);
-static void ad1848_close (int dev);
-static int ad1848_ioctl (int dev, unsigned int cmd, unsigned int arg, int local);
-static void ad1848_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart);
-static void ad1848_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart);
-static int ad1848_prepare_for_IO (int dev, int bsize, int bcount);
-static void ad1848_reset (int dev);
-static void ad1848_halt (int dev);
-
-static int
-ad_read (ad1848_info * devc, int reg)
-{
- unsigned long flags;
- int x;
- int timeout = 100;
-
- while (timeout > 0 && INB (devc->base) == 0x80) /*Are we initializing */
- timeout--;
-
- DISABLE_INTR (flags);
- OUTB ((unsigned char) (reg & 0xff) | devc->MCE_bit, io_Index_Addr (devc));
- x = INB (io_Indexed_Data (devc));
- /* printk("(%02x<-%02x) ", reg|devc->MCE_bit, x); */
- RESTORE_INTR (flags);
-
- return x;
-}
-
-static void
-ad_write (ad1848_info * devc, int reg, int data)
-{
- unsigned long flags;
- int timeout = 100;
-
- while (timeout > 0 && INB (devc->base) == 0x80) /*Are we initializing */
- timeout--;
-
- DISABLE_INTR (flags);
- OUTB ((unsigned char) (reg & 0xff) | devc->MCE_bit, io_Index_Addr (devc));
- OUTB ((unsigned char) (data & 0xff), io_Indexed_Data (devc));
- /* printk("(%02x->%02x) ", reg|devc->MCE_bit, data); */
- RESTORE_INTR (flags);
-}
-
-static void
-wait_for_calibration (ad1848_info * devc)
-{
- int timeout = 0;
-
- /*
- * Wait until the auto calibration process has finished.
- *
- * 1) Wait until the chip becomes ready (reads don't return 0x80).
- * 2) Wait until the ACI bit of I11 gets on and then off.
- */
-
- timeout = 100000;
-#ifdef PC98
- while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
- timeout--;
- if ((INB (devc->base) & 0x80) == 0x80)
-#else
- while (timeout > 0 && INB (devc->base) & 0x80)
- timeout--;
- if (INB (devc->base) & 0x80)
-#endif
- printk ("ad1848: Auto calibration timed out(1).\n");
-
- timeout = 100;
- while (timeout > 0 && !(ad_read (devc, 11) & 0x20))
- timeout--;
- if (!(ad_read (devc, 11) & 0x20))
- return;
-
- timeout = 10000;
- while (timeout > 0 && ad_read (devc, 11) & 0x20)
- timeout--;
- if (ad_read (devc, 11) & 0x20)
- printk ("ad1848: Auto calibration timed out(3).\n");
-}
-
-static void
-ad_mute (ad1848_info * devc)
-{
- int i;
- unsigned char prev;
-
- /*
- * Save old register settings and mute output channels
- */
- for (i = 6; i < 8; i++)
- {
- prev = devc->saved_regs[i] = ad_read (devc, i);
- ad_write (devc, i, prev | 0x80);
- }
-}
-
-static void
-ad_unmute (ad1848_info * devc)
-{
- int i;
-
- /*
- * Restore back old volume registers (unmute)
- */
- for (i = 6; i < 8; i++)
- {
- ad_write (devc, i, devc->saved_regs[i] & ~0x80);
- }
-}
-
-static void
-ad_enter_MCE (ad1848_info * devc)
-{
- unsigned long flags;
- int timeout = 1000;
- unsigned short prev;
-
- while (timeout > 0 && INB (devc->base) == 0x80) /*Are we initializing */
- timeout--;
-
- DISABLE_INTR (flags);
-
- devc->MCE_bit = 0x40;
- prev = INB (io_Index_Addr (devc));
- if (prev & 0x40)
- {
- RESTORE_INTR (flags);
- return;
- }
-
- OUTB (devc->MCE_bit, io_Index_Addr (devc));
- RESTORE_INTR (flags);
-}
-
-static void
-ad_leave_MCE (ad1848_info * devc)
-{
- unsigned long flags;
- unsigned char prev;
- int timeout = 1000;
-
- while (timeout > 0 && INB (devc->base) == 0x80) /*Are we initializing */
- timeout--;
-
- DISABLE_INTR (flags);
-
- devc->MCE_bit = 0x00;
- prev = INB (io_Index_Addr (devc));
- OUTB (0x00, io_Index_Addr (devc)); /* Clear the MCE bit */
-
- if (prev & 0x40 == 0) /* Not in MCE mode */
- {
- RESTORE_INTR (flags);
- return;
- }
-
- OUTB (0x00, io_Index_Addr (devc)); /* Clear the MCE bit */
- wait_for_calibration (devc);
- RESTORE_INTR (flags);
-}
-
-
-static int
-ad1848_set_recmask (ad1848_info * devc, int mask)
-{
- unsigned char recdev;
- int i, n;
-
- mask &= devc->supported_rec_devices;
-
- n = 0;
- for (i = 0; i < 32; i++) /* Count selected device bits */
- if (mask & (1 << i))
- n++;
-
- if (n == 0)
- mask = SOUND_MASK_MIC;
- else if (n != 1) /* Too many devices selected */
- {
- mask &= ~devc->recmask; /* Filter out active settings */
-
- n = 0;
- for (i = 0; i < 32; i++) /* Count selected device bits */
- if (mask & (1 << i))
- n++;
-
- if (n != 1)
- mask = SOUND_MASK_MIC;
- }
-
- switch (mask)
- {
- case SOUND_MASK_MIC:
- recdev = 2;
- break;
-
- case SOUND_MASK_LINE:
- case SOUND_MASK_LINE3:
- recdev = 0;
- break;
-
- case SOUND_MASK_CD:
- case SOUND_MASK_LINE1:
- recdev = 1;
- break;
-
- default:
- mask = SOUND_MASK_MIC;
- recdev = 2;
- }
-
- recdev <<= 6;
- ad_write (devc, 0, (ad_read (devc, 0) & 0x3f) | recdev);
- ad_write (devc, 1, (ad_read (devc, 1) & 0x3f) | recdev);
-
- devc->recmask = mask;
- return mask;
-}
-
-static void
-change_bits (unsigned char *regval, int dev, int chn, int newval)
-{
- unsigned char mask;
- int shift;
-
- if (mix_devices[dev][chn].polarity == 1) /* Reverse */
- newval = 100 - newval;
-
- mask = (1 << mix_devices[dev][chn].nbits) - 1;
- shift = mix_devices[dev][chn].bitpos;
- newval = (int) ((newval * mask) + 50) / 100; /* Scale it */
-
- *regval &= ~(mask << shift); /* Clear bits */
- *regval |= (newval & mask) << shift; /* Set new value */
-}
-
-static int
-ad1848_mixer_get (ad1848_info * devc, int dev)
-{
- if (!((1 << dev) & devc->supported_devices))
- return RET_ERROR (EINVAL);
-
- return devc->levels[dev];
-}
-
-static int
-ad1848_mixer_set (ad1848_info * devc, int dev, int value)
-{
- int left = value & 0x000000ff;
- int right = (value & 0x0000ff00) >> 8;
-
- int regoffs;
- unsigned char val;
-
- if (left > 100)
- left = 100;
- if (right > 100)
- right = 100;
-
- if (dev > 31)
- return RET_ERROR (EINVAL);
-
- if (!(devc->supported_devices & (1 << dev)))
- return RET_ERROR (EINVAL);
-
- if (mix_devices[dev][LEFT_CHN].nbits == 0)
- return RET_ERROR (EINVAL);
-
- /*
- * Set the left channel
- */
-
- regoffs = mix_devices[dev][LEFT_CHN].regno;
- val = ad_read (devc, regoffs);
- change_bits (&val, dev, LEFT_CHN, left);
- devc->levels[dev] = left | (left << 8);
- ad_write (devc, regoffs, val);
- devc->saved_regs[regoffs] = val;
-
- /*
- * Set the left right
- */
-
- if (mix_devices[dev][RIGHT_CHN].nbits == 0)
- return left | (left << 8); /* Was just a mono channel */
-
- regoffs = mix_devices[dev][RIGHT_CHN].regno;
- val = ad_read (devc, regoffs);
- change_bits (&val, dev, RIGHT_CHN, right);
- ad_write (devc, regoffs, val);
- devc->saved_regs[regoffs] = val;
-
- devc->levels[dev] = left | (right << 8);
- return left | (right << 8);
-}
-
-static void
-ad1848_mixer_reset (ad1848_info * devc)
-{
- int i;
-
- devc->recmask = 0;
- if (devc->mode == 2)
- devc->supported_devices = MODE2_MIXER_DEVICES;
- else
- devc->supported_devices = MODE1_MIXER_DEVICES;
-
- devc->supported_rec_devices = MODE1_REC_DEVICES;
-
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- ad1848_mixer_set (devc, i, devc->levels[i] = default_mixer_levels[i]);
- ad1848_set_recmask (devc, SOUND_MASK_MIC);
-}
-
-static int
-ad1848_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
-{
- ad1848_info *devc;
-
- int codec_dev = mixer2codec[dev];
-
- if (!codec_dev)
- return RET_ERROR (ENXIO);
-
- codec_dev--;
-
- devc = (ad1848_info *) audio_devs[codec_dev]->devc;
-
- if (((cmd >> 8) & 0xff) == 'M')
- {
- if (cmd & IOC_IN)
- switch (cmd & 0xff)
- {
- case SOUND_MIXER_RECSRC:
- return IOCTL_OUT (arg, ad1848_set_recmask (devc, IOCTL_IN (arg)));
- break;
-
- default:
- return IOCTL_OUT (arg, ad1848_mixer_set (devc, cmd & 0xff, IOCTL_IN (arg)));
- }
- else
- switch (cmd & 0xff) /*
- * Return parameters
- */
- {
-
- case SOUND_MIXER_RECSRC:
- return IOCTL_OUT (arg, devc->recmask);
- break;
-
- case SOUND_MIXER_DEVMASK:
- return IOCTL_OUT (arg, devc->supported_devices);
- break;
-
- case SOUND_MIXER_STEREODEVS:
- return IOCTL_OUT (arg, devc->supported_devices &
- ~(SOUND_MASK_SPEAKER | SOUND_MASK_IMIX));
- break;
-
- case SOUND_MIXER_RECMASK:
- return IOCTL_OUT (arg, devc->supported_rec_devices);
- break;
-
- case SOUND_MIXER_CAPS:
- return IOCTL_OUT (arg, SOUND_CAP_EXCL_INPUT);
- break;
-
- default:
- return IOCTL_OUT (arg, ad1848_mixer_get (devc, cmd & 0xff));
- }
- }
- else
- return RET_ERROR (EINVAL);
-}
-
-static struct audio_operations ad1848_pcm_operations[MAX_AUDIO_DEV] =
-{
- {
- "Generic AD1848 codec",
-#ifdef PC98
- NEEDS_RESTART,
-#else
- DMA_AUTOMODE,
-#endif
- AFMT_U8, /* Will be set later */
- NULL,
- ad1848_open,
- ad1848_close,
- ad1848_output_block,
- ad1848_start_input,
- ad1848_ioctl,
- ad1848_prepare_for_IO,
- ad1848_prepare_for_IO,
- ad1848_reset,
- ad1848_halt,
- NULL,
- NULL
- }};
-
-static struct mixer_operations ad1848_mixer_operations =
-{
- "AD1848/CS4248/CS4231",
- ad1848_mixer_ioctl
-};
-
-static int
-ad1848_open (int dev, int mode)
-{
- int err;
- ad1848_info *devc = NULL;
- unsigned long flags;
-
- DEB (printk ("ad1848_open(int mode = %X)\n", mode));
-
- if (dev < 0 || dev >= num_audiodevs)
- return RET_ERROR (ENXIO);
-
- devc = (ad1848_info *) audio_devs[dev]->devc;
-
- DISABLE_INTR (flags);
- if (devc->opened)
- {
- RESTORE_INTR (flags);
- printk ("ad1848: Already opened\n");
- return RET_ERROR (EBUSY);
- }
-
- if (devc->irq) /* Not managed by another driver */
- if ((err = snd_set_irq_handler (devc->irq, ad1848_interrupt,
- audio_devs[dev]->name)) < 0)
- {
- printk ("ad1848: IRQ in use\n");
- RESTORE_INTR (flags);
- return err;
- }
-
- if (DMAbuf_open_dma (dev) < 0)
- {
- RESTORE_INTR (flags);
- printk ("ad1848: DMA in use\n");
- return RET_ERROR (EBUSY);
- }
-
- devc->intr_active = 0;
- devc->opened = 1;
- RESTORE_INTR (flags);
-
- return 0;
-}
-
-static void
-ad1848_close (int dev)
-{
- unsigned long flags;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
-
- DEB (printk ("ad1848_close(void)\n"));
-
- DISABLE_INTR (flags);
-
- devc->intr_active = 0;
- if (devc->irq) /* Not managed by another driver */
- snd_release_irq (devc->irq);
- ad1848_reset (dev);
- DMAbuf_close_dma (dev);
- devc->opened = 0;
-
- RESTORE_INTR (flags);
-}
-
-static int
-set_speed (ad1848_info * devc, int arg)
-{
- /*
- * The sampling speed is encoded in the least significant nible of I8. The
- * LSB selects the clock source (0=24.576 MHz, 1=16.9344 Mhz) and other
- * three bits select the divisor (indirectly):
- *
- * The available speeds are in the following table. Keep the speeds in
- * the increasing order.
- */
- typedef struct
- {
- int speed;
- unsigned char bits;
- }
- speed_struct;
-
- static speed_struct speed_table[] =
- {
- {5510, (0 << 1) | 1},
- {5510, (0 << 1) | 1},
- {6620, (7 << 1) | 1},
- {8000, (0 << 1) | 0},
- {9600, (7 << 1) | 0},
- {11025, (1 << 1) | 1},
- {16000, (1 << 1) | 0},
- {18900, (2 << 1) | 1},
- {22050, (3 << 1) | 1},
- {27420, (2 << 1) | 0},
- {32000, (3 << 1) | 0},
- {33075, (6 << 1) | 1},
- {37800, (4 << 1) | 1},
- {44100, (5 << 1) | 1},
- {48000, (6 << 1) | 0}
- };
-
- int i, n, selected = -1;
-
- n = sizeof (speed_table) / sizeof (speed_struct);
-
- if (arg < speed_table[0].speed)
- selected = 0;
- if (arg > speed_table[n - 1].speed)
- selected = n - 1;
-
- for (i = 1 /*really */ ; selected == -1 && i < n; i++)
- if (speed_table[i].speed == arg)
- selected = i;
- else if (speed_table[i].speed > arg)
- {
- int diff1, diff2;
-
- diff1 = arg - speed_table[i - 1].speed;
- diff2 = speed_table[i].speed - arg;
-
- if (diff1 < diff2)
- selected = i - 1;
- else
- selected = i;
- }
-
- if (selected == -1)
- {
- printk ("ad1848: Can't find speed???\n");
- selected = 3;
- }
-
- devc->speed = speed_table[selected].speed;
- devc->speed_bits = speed_table[selected].bits;
- return devc->speed;
-}
-
-static int
-set_channels (ad1848_info * devc, int arg)
-{
- if (arg != 1 && arg != 2)
- return devc->channels;
-
- devc->channels = arg;
- return arg;
-}
-
-static int
-set_format (ad1848_info * devc, int arg)
-{
-
- static struct format_tbl
- {
- int format;
- unsigned char bits;
- }
- format2bits[] =
- {
- {
- 0, 0
- }
- ,
- {
- AFMT_MU_LAW, 1
- }
- ,
- {
- AFMT_A_LAW, 3
- }
- ,
- {
- AFMT_IMA_ADPCM, 5
- }
- ,
- {
- AFMT_U8, 0
- }
- ,
- {
- AFMT_S16_LE, 2
- }
- ,
- {
- AFMT_S16_BE, 6
- }
- ,
- {
- AFMT_S8, 0
- }
- ,
- {
- AFMT_U16_LE, 0
- }
- ,
- {
- AFMT_U16_BE, 0
- }
- };
- int i, n = sizeof (format2bits) / sizeof (struct format_tbl);
-
- if (!(arg & ad_format_mask[devc->mode]))
- arg = AFMT_U8;
-
- devc->audio_format = arg;
-
- for (i = 0; i < n; i++)
- if (format2bits[i].format == arg)
- {
- if ((devc->format_bits = format2bits[i].bits) == 0)
- return devc->audio_format = AFMT_U8; /* Was not supported */
-
- return arg;
- }
-
- /* Still hanging here. Something must be terribly wrong */
- devc->format_bits = 0;
- return devc->audio_format = AFMT_U8;
-}
-
-static int
-ad1848_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
-{
- ad1848_info *devc = (ad1848_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 devc->speed;
- return IOCTL_OUT (arg, devc->speed);
-
- 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 devc->channels;
- return IOCTL_OUT (arg, devc->channels);
-
- 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 devc->audio_format;
- return IOCTL_OUT (arg, devc->audio_format);
-
- default:;
- }
- return RET_ERROR (EINVAL);
-}
-
-static void
-ad1848_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
-{
- unsigned long flags, cnt;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
-
- cnt = count;
-
- if (devc->audio_format == AFMT_IMA_ADPCM)
- {
- cnt /= 4;
- }
- else
- {
- if (devc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
- cnt >>= 1;
- }
- if (devc->channels > 1)
- cnt >>= 1;
- cnt--;
-
- if (audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == devc->xfer_count)
- {
- devc->irq_mode = IMODE_OUTPUT;
- devc->intr_active = 1;
- return; /*
- * Auto DMA mode on. No need to react
- */
- }
- DISABLE_INTR (flags);
-
- if (dma_restart)
- {
- /* ad1848_halt (dev); */
- DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
- }
-
- ad_enter_MCE (devc);
-
- ad_write (devc, 15, (unsigned char) (cnt & 0xff));
- ad_write (devc, 14, (unsigned char) ((cnt >> 8) & 0xff));
-
- ad_write (devc, 9, 0x0d); /*
- * Playback enable, single DMA channel mode,
- * auto calibration on.
- */
-
- ad_leave_MCE (devc); /*
- * Starts the calibration process and
- * enters playback mode after it.
- */
- ad_unmute (devc);
-
- devc->xfer_count = cnt;
- devc->irq_mode = IMODE_OUTPUT;
- devc->intr_active = 1;
- INB (io_Status (devc));
- OUTB (0, io_Status (devc)); /* Clear pending interrupts */
- RESTORE_INTR (flags);
-}
-
-static void
-ad1848_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
-{
- unsigned long flags, cnt;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
-
- int count_reg = 14; /* (devc->mode == 1) ? 14 : 30; */
-
- cnt = count;
- if (devc->audio_format == AFMT_IMA_ADPCM)
- {
- cnt /= 4;
- }
- else
- {
- if (devc->audio_format & (AFMT_S16_LE | AFMT_S16_BE)) /* 16 bit data */
- cnt >>= 1;
- }
- if (devc->channels > 1)
- cnt >>= 1;
- cnt--;
-
- if (audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == devc->xfer_count)
- {
- devc->irq_mode = IMODE_INPUT;
- devc->intr_active = 1;
- return; /*
- * Auto DMA mode on. No need to react
- */
- }
- DISABLE_INTR (flags);
-
- if (dma_restart)
- {
- /* ad1848_halt (dev); */
- DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
- }
-
- ad_enter_MCE (devc);
-
- ad_write (devc, count_reg + 1, (unsigned char) (cnt & 0xff));
- ad_write (devc, count_reg, (unsigned char) ((cnt >> 8) & 0xff));
-
- ad_write (devc, 9, 0x0e); /*
- * Capture enable, single DMA channel mode,
- * auto calibration on.
- */
-
- ad_leave_MCE (devc); /*
- * Starts the calibration process and
- * enters playback mode after it.
- */
- ad_unmute (devc);
-
- devc->xfer_count = cnt;
- devc->irq_mode = IMODE_INPUT;
- devc->intr_active = 1;
- INB (io_Status (devc));
- OUTB (0, io_Status (devc)); /* Clear interrupt status */
- RESTORE_INTR (flags);
-}
-
-static int
-ad1848_prepare_for_IO (int dev, int bsize, int bcount)
-{
- int timeout;
- unsigned char fs;
- unsigned long flags;
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
-
- DISABLE_INTR (flags);
- ad_enter_MCE (devc); /* Enables changes to the format select reg */
- fs = devc->speed_bits | (devc->format_bits << 5);
-
- if (devc->channels > 1)
- fs |= 0x10;
-
- ad_write (devc, 8, fs);
- /*
- * Write to I8 starts resyncronization. Wait until it completes.
- */
- timeout = 10000;
-#ifdef PC98
- while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
-#else
- while (timeout > 0 && INB (devc->base) == 0x80)
-#endif
- timeout--;
-
-#ifdef PC98
- ad_write (devc, 8, fs);
- /*
- * Write to I8 starts resyncronization. Wait until it completes.
- */
- timeout = 10000;
- while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
- timeout--;
-#endif
-
- /*
- * If mode == 2 (CS4231), set I28 also. It's the capture format register.
- */
- if (devc->mode == 2)
- {
- ad_write (devc, 28, fs);
-
- /*
- * Write to I28 starts resyncronization. Wait until it completes.
- */
- timeout = 10000;
-#ifdef PC98
- while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
-#else
- while (timeout > 0 && INB (devc->base) == 0x80)
-#endif
- timeout--;
-
- }
-
-#ifdef PC98
- ad_write (devc, 28, fs);
-
- /*
- * Write to I28 starts resyncronization. Wait until it completes.
- */
- timeout = 10000;
- while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
- timeout--;
-#endif
-
- ad_leave_MCE (devc); /*
- * Starts the calibration process and
- * enters playback mode after it.
- */
- RESTORE_INTR (flags);
- devc->xfer_count = 0;
- return 0;
-}
-
-static void
-ad1848_reset (int dev)
-{
- ad1848_halt (dev);
-}
-
-static void
-ad1848_halt (int dev)
-{
- ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc;
-
- ad_mute (devc);
-#ifdef PC98
- ad_enter_MCE (devc);
-#endif
- ad_write (devc, 9, ad_read (devc, 9) & ~0x03); /* Stop DMA */
-#ifdef PC98
- ad_leave_MCE (devc);
-#endif
- OUTB (0, io_Status (devc)); /* Clear interrupt status */
-
- ad_enter_MCE (devc);
- OUTB (0, io_Status (devc)); /* Clear interrupt status */
- ad_write (devc, 15, 0); /* Clear DMA counter */
- ad_write (devc, 14, 0); /* Clear DMA counter */
-
- if (devc->mode == 2)
- {
- ad_write (devc, 30, 0); /* Clear DMA counter */
- ad_write (devc, 31, 0); /* Clear DMA counter */
- }
-
- ad_write (devc, 9, ad_read (devc, 9) & ~0x03); /* Stop DMA */
-
- OUTB (0, io_Status (devc)); /* Clear interrupt status */
- OUTB (0, io_Status (devc)); /* Clear interrupt status */
- ad_leave_MCE (devc);
-
- DMAbuf_reset_dma (dev);
-}
-
-int
-ad1848_detect (int io_base)
-{
-
- unsigned char tmp;
- int i;
- ad1848_info *devc = &dev_info[nr_ad1848_devs];
- unsigned char tmp1 = 0xff, tmp2 = 0xff;
-
- if (nr_ad1848_devs >= MAX_AUDIO_DEV)
- {
- AUDIO_DDB (printk ("ad1848 detect error - step 0\n"));
- return 0;
- }
-
- devc->base = io_base;
- devc->MCE_bit = 0x40;
- devc->irq = 0;
- devc->dma_capture = 0;
- devc->dma_playback = 0;
- devc->opened = 0;
- devc->chip_name = "AD1848";
- devc->mode = 1; /* MODE1 = original AD1848 */
-
- /*
- * Check that the I/O address is in use.
- *
- * The bit 0x80 of the base I/O port is known to be 0 after the
- * chip has performed it's power on initialization. Just assume
- * this has happened before the OS is starting.
- *
- * If the I/O address is unused, it typically returns 0xff.
- */
-
- if ((INB (devc->base) & 0x80) != 0x00) /* Not a AD1884 */
- {
- AUDIO_DDB (printk ("ad1848 detect error - step A\n"));
- return 0;
- }
-
- /*
- * Test if it's possible to change contents of the indirect registers.
- * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only
- * so try to avoid using it.
- */
-
- ad_write (devc, 0, 0xaa);
- ad_write (devc, 1, 0x45); /* 0x55 with bit 0x10 clear */
-
- if ((tmp1 = ad_read (devc, 0)) != 0xaa || (tmp2 = ad_read (devc, 1)) != 0x45)
- {
- AUDIO_DDB (printk ("ad1848 detect error - step B (%x/%x)\n", tmp1, tmp2));
- return 0;
- }
-
- ad_write (devc, 0, 0x45);
- ad_write (devc, 1, 0xaa);
-
- if ((tmp1 = ad_read (devc, 0)) != 0x45 || (tmp2 = ad_read (devc, 1)) != 0xaa)
- {
- AUDIO_DDB (printk ("ad1848 detect error - step C (%x/%x)\n", tmp1, tmp2));
- return 0;
- }
-
- /*
- * The indirect register I12 has some read only bits. Lets
- * try to change them.
- */
-
- tmp = ad_read (devc, 12);
- ad_write (devc, 12, (~tmp) & 0x0f);
-
- if ((tmp & 0x0f) != ((tmp1 = ad_read (devc, 12)) & 0x0f))
- {
- AUDIO_DDB (printk ("ad1848 detect error - step D (%x)\n", tmp1));
- return 0;
- }
-
- /*
- * NOTE! Last 4 bits of the reg I12 tell the chip revision.
- * 0x01=RevB and 0x0A=RevC.
- */
-
- /*
- * The original AD1848/CS4248 has just 15 indirect registers. This means
- * that I0 and I16 should return the same value (etc.).
- * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test fails
- * with CS4231.
- */
-
- ad_write (devc, 12, 0); /* Mode2=disabled */
-
- for (i = 0; i < 16; i++)
- if ((tmp1 = ad_read (devc, i)) != (tmp2 = ad_read (devc, i + 16)))
- {
- AUDIO_DDB (printk ("ad1848 detect error - step F(%d/%x/%x)\n", i, tmp1, tmp2));
- return 0;
- }
-
- /*
- * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit (0x40).
- * The bit 0x80 is always 1 in CS4248 and CS4231.
- */
-
- ad_write (devc, 12, 0x40); /* Set mode2, clear 0x80 */
-
- tmp1 = ad_read (devc, 12);
- if (tmp1 & 0x80)
- devc->chip_name = "CS4248"; /* Our best knowledge just now */
-
- if ((tmp1 & 0xc0) == (0x80 | 0x40))
- {
- /*
- * CS4231 detected - is it?
- *
- * Verify that setting I0 doesn't change I16.
- */
- ad_write (devc, 16, 0); /* Set I16 to known value */
-
- ad_write (devc, 0, 0x45);
- if ((tmp1 = ad_read (devc, 16)) != 0x45) /* No change -> CS4231? */
- {
-
- ad_write (devc, 0, 0xaa);
- if ((tmp1 = ad_read (devc, 16)) == 0xaa) /* Rotten bits? */
- {
- AUDIO_DDB (printk ("ad1848 detect error - step H(%x)\n", tmp1));
- return 0;
- }
-
- /*
- * Verify that some bits of I25 are read only.
- */
-
- tmp1 = ad_read (devc, 25); /* Original bits */
- ad_write (devc, 25, ~tmp1); /* Invert all bits */
- if ((ad_read (devc, 25) & 0xe7) == (tmp1 & 0xe7))
- {
- /*
- * It's a CS4231
- */
- devc->chip_name = "CS4231";
-
-
-#ifdef MOZART_PORT
- if (devc->base != MOZART_PORT)
-#endif
- devc->mode = 2;
-
-
- }
- ad_write (devc, 25, tmp1); /* Restore bits */
- }
- }
-
- return 1;
-}
-
-void
-ad1848_init (char *name, int io_base, int irq, int dma_playback, int dma_capture)
-{
- /*
- * NOTE! If irq < 0, there is another driver which has allocated the IRQ
- * so that this driver doesn't need to allocate/deallocate it.
- * The actually used IRQ is ABS(irq).
- */
-
- /*
- * Initial values for the indirect registers of CS4248/AD1848.
- */
- static int init_values[] =
- {
- 0xa8, 0xa8, 0x08, 0x08, 0x08, 0x08, 0x80, 0x80,
- 0x00, 0x08, 0x02, 0x00, 0x8a, 0x01, 0x00, 0x00,
-
- /* Positions 16 to 31 just for CS4231 */
- 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
- int i, my_dev;
- ad1848_info *devc = &dev_info[nr_ad1848_devs];
-
- if (!ad1848_detect (io_base))
- return;
-
- devc->irq = (irq > 0) ? irq : 0;
- devc->dma_capture = dma_playback;
- devc->dma_playback = dma_capture;
- devc->opened = 0;
-
- if (nr_ad1848_devs != 0)
- {
- memcpy ((char *) &ad1848_pcm_operations[nr_ad1848_devs],
- (char *) &ad1848_pcm_operations[0],
- sizeof (struct audio_operations));
- }
-
- for (i = 0; i < 16; i++)
- ad_write (devc, i, init_values[i]);
-
- ad_mute (devc);
-
- if (devc->mode == 2)
- {
- ad_write (devc, 12, ad_read (devc, 12) | 0x40); /* Mode2 = enabled */
- for (i = 16; i < 32; i++)
- ad_write (devc, i, init_values[i]);
- }
-
- OUTB (0, io_Status (devc)); /* Clear pending interrupts */
-
- if (name[0] != 0)
- sprintf (ad1848_pcm_operations[nr_ad1848_devs].name,
- "%s (%s)", name, devc->chip_name);
- else
- sprintf (ad1848_pcm_operations[nr_ad1848_devs].name,
- "Generic audio codec (%s)", devc->chip_name);
-
-#if defined(__FreeBSD__)
- if (strcmp(name, "MS Sound System")) /* *sigh* */
- printk ("\ngus0: <%s>", ad1848_pcm_operations[nr_ad1848_devs].name);
- else
- printk ("mss0: <%s>", ad1848_pcm_operations[nr_ad1848_devs].name);
-#else
- printk (" <%s>", ad1848_pcm_operations[nr_ad1848_devs].name);
-#endif
-
- if (num_audiodevs < MAX_AUDIO_DEV)
- {
- audio_devs[my_dev = num_audiodevs++] = &ad1848_pcm_operations[nr_ad1848_devs];
- if (irq > 0)
- irq2dev[irq] = my_dev;
- else if (irq < 0)
- irq2dev[-irq] = my_dev;
-
- audio_devs[my_dev]->dmachan = dma_playback;
- audio_devs[my_dev]->buffcount = 1;
- audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
- audio_devs[my_dev]->devc = devc;
- audio_devs[my_dev]->format_mask = ad_format_mask[devc->mode];
- nr_ad1848_devs++;
-
- /*
- * Toggle the MCE bit. It completes the initialization phase.
- */
-
- ad_enter_MCE (devc); /* In case the bit was off */
- ad_leave_MCE (devc);
-
- if (num_mixers < MAX_MIXER_DEV)
- {
- mixer2codec[num_mixers] = my_dev + 1;
- audio_devs[my_dev]->mixer_dev = num_mixers;
- mixer_devs[num_mixers++] = &ad1848_mixer_operations;
- ad1848_mixer_reset (devc);
- }
- }
- else
- printk ("AD1848: Too many PCM devices available\n");
-}
-
-void
-ad1848_interrupt (INT_HANDLER_PARMS (irq, dummy))
-{
- unsigned char status;
- ad1848_info *devc;
- int dev;
-
- if (irq < 0 || irq > 15)
- return; /* Bogus irq */
- dev = irq2dev[irq];
- if (dev < 0 || dev >= num_audiodevs)
- return; /* Bogus dev */
-
- devc = (ad1848_info *) audio_devs[dev]->devc;
- status = INB (io_Status (devc));
-
- if (status == 0x80)
- printk ("ad1848_interrupt: Why?\n");
-
- if (status & 0x01)
- {
- if (devc->opened && devc->irq_mode == IMODE_OUTPUT)
- {
- DMAbuf_outputintr (dev, 1);
- }
-
- if (devc->opened && devc->irq_mode == IMODE_INPUT)
- DMAbuf_inputintr (dev);
- }
-
- OUTB (0, io_Status (devc)); /* Clear interrupt status */
-
- status = INB (io_Status (devc));
- if (status == 0x80 || status & 0x01)
- {
- printk ("ad1848: Problems when clearing interrupt, status=%x\n", status);
- OUTB (0, io_Status (devc)); /* Try again */
- }
-}
-
-#ifdef MOZART_PORT
-/*
- * Experimental initialization sequence for Mozart soundcard
- * (OAK OTI-601 sound chip).
- * by Gregor Hoffleit <flight@mathi.uni-heidelberg.de>
- * Some comments by Hannu Savolainen.
- */
-
-int
-mozart_init (int io_base)
-{
- int i;
- unsigned char byte;
- static int mozart_detected_here = 0;
-
- /*
- * Valid ports are 0x530 and 0xf40. The DOS based software doesn't allow
- * other ports. The OTI-601 preliminary specification says that
- * 0xe80 and 0x604 are also possible but it's safest to ignore them.
- */
-
- if ((io_base != 0x530) && (io_base != 0xf40))
- {
- printk ("Mozart: invalid io_base(%x)\n", io_base);
- return 0;
- }
-
- if (mozart_detected_here == io_base) /* Already detected this card */
- return 1;
-
- if (mozart_detected_here != 0)
- return 0; /* Don't allow detecting another Mozart card. */
-
- /*
- * The Mozart chip (OAK OTI-601) must be enabled before _each_ write
- * by writing a secret password (0xE2) to the password register (0xf8f).
- * Any I/O cycle after writing the password closes the gate and disbles
- * further access.
- */
-
- if (INB (0xf88) != 0) /* Appears to return 0 while the gate is closed */
- {
- AUDIO_DDB (printk ("No Mozart signature detected on port 0xf88\n"));
- return 0;
- }
-
- OUTB (0xe2, 0xf8f); /* A secret password which opens the gate */
- OUTB (0x10, 0xf91); /* Enable access to codec registers during SB mode */
- for (i = 0; i < 100; i++) /* Delay */
- tenmicrosec ();
- OUTB (0xe2, 0xf8f); /* Sesam */
- byte = INB (0xf8d); /* Read MC1 (Mode control register) */
-
- /* Read the same register again but with gate closed at this time. */
- if (INB (0xf8d) == 0xff) /* Bus float. Should be 0 if Mozart present */
- {
- AUDIO_DDB (printk ("Seems to be no Mozart chip set\n"));
- return 0;
- }
- AUDIO_DDB (printk ("mozart_init: read 0x%x on 0xf8d\n", byte));
- byte = byte | 0x80; /* Switch to WSS mode (disables SB) */
- byte = byte & 0xcf; /* Clear sound base, disable CD, enable joystick */
-
- if (io_base == 0xf40)
- byte = byte | 0x20;
- for (i = 0; i < 100; i++)
- tenmicrosec ();
- OUTB (0xe2, 0xf8f); /* Open the gate again */
- OUTB (byte, 0xf8d); /* Write the modified value back to MC1 */
- AUDIO_DDB (printk ("mozart_init: wrote 0x%x on 0xf8d\n", byte));
- OUTB (0xe2, 0xf8f); /* Here we come again */
- OUTB (0x20, 0xf91); /* Protect WSS shadow registers against write */
-
- for (i = 0; i < 1000; i++)
- tenmicrosec ();
-
- return 1;
-}
-
-#endif /* MOZART_PORT */
-
-#ifdef OPTI_MAD16_PORT
-#include <i386/isa/sound/mad16.h>
-#endif
-
-/*
- * Some extra code for the MS Sound System
- */
-
-int
-probe_ms_sound (struct address_info *hw_config)
-{
-#if !defined(EXCLUDE_AEDSP16) && defined(AEDSP16_MSS)
- /*
- * Initialize Audio Excel DSP 16 to MSS: before any operation
- * we must enable MSS I/O ports.
- */
-
- InitAEDSP16_MSS (hw_config);
-#endif
-
- /*
- * Check if the IO port returns valid signature. The original MS Sound
- * system returns 0x04 while some cards (AudioTriX Pro for example)
- * return 0x00.
- */
-
-#ifdef MOZART_PORT
- if (hw_config->io_base == MOZART_PORT)
- mozart_init (hw_config->io_base);
-#endif
-
-#ifdef OPTI_MAD16_PORT
- if (hw_config->io_base == OPTI_MAD16_PORT)
- mad16init (hw_config->io_base);
-#endif
-
- if ((INB (hw_config->io_base + 3) & 0x3f) != 0x04 &&
- (INB (hw_config->io_base + 3) & 0x3f) != 0x00)
- {
- AUDIO_DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n",
- hw_config->io_base, INB (hw_config->io_base + 3)));
- return 0;
- }
-
-#ifdef PC98
- if (hw_config->irq > 12)
-#else
- if (hw_config->irq > 11)
-#endif
- {
- printk ("MSS: Bad IRQ %d\n", hw_config->irq);
- return 0;
- }
-
- if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
- {
- printk ("MSS: Bad 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 ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
- return 0;
- }
-
- if (hw_config->irq > 7 && hw_config->irq != 9 && INB (hw_config->io_base + 3) & 0x80)
- {
- printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
- return 0;
- }
-
- return ad1848_detect (hw_config->io_base + 4);
-}
-
-long
-attach_ms_sound (long mem_start, struct address_info *hw_config)
-{
-#ifdef PC98
- static char interrupt_bits[13] =
- {
- -1, -1, -1, 0x08, -1, 0x10, -1, -1, -1, -1, 0x18, -1, 0x20
- };
-#else
- static char interrupt_bits[12] =
- {
- -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
- };
-#endif
- char bits;
-
- static char dma_bits[4] =
- {
- 1, 2, 0, 3
- };
-
- int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
-
- if (!ad1848_detect (hw_config->io_base + 4))
- 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 ("MS Sound System", hw_config->io_base + 4,
- hw_config->irq,
- hw_config->dma,
- hw_config->dma);
- return mem_start;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/opl3.c b/sys/pc98/pc98/sound/opl3.c
deleted file mode 100644
index 42379cd..0000000
--- a/sys/pc98/pc98/sound/opl3.c
+++ /dev/null
@@ -1,1292 +0,0 @@
-/*
- * sound/opl3.c
- *
- * A low level driver for Yamaha YM3812 and OPL-3 -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.
- *
- */
-
-/*
- * Major improvements to the FM handling 30AUG92 by Rob Hooft,
- */
-/*
- * hooft@chem.ruu.nl
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_YM3812)
-
-#include <i386/isa/sound/opl3.h>
-
-#define MAX_VOICE 18
-#define OFFS_4OP 11 /*
- * * * Definitions for the operators OP3 and
- * * OP4 * * begin here */
-
-static int opl3_enabled = 0;
-static int opl4_enabled = 0;
-#ifdef PC98
-static int left_address = 0x28d2, right_address = 0x28d2, both_address = 0;
-#else
-static int left_address = 0x388, right_address = 0x388, both_address = 0;
-#endif
-
-static int nr_voices = 9;
-static int logical_voices[MAX_VOICE] =
-{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
-
-struct voice_info
- {
- unsigned char keyon_byte;
- long bender;
- long bender_range;
- unsigned long orig_freq;
- unsigned long current_freq;
- int mode;
- };
-
-static struct voice_info voices[MAX_VOICE];
-static struct voice_alloc_info *voice_alloc;
-static struct channel_info *chn_info;
-
-static struct sbi_instrument *instrmap;
-static struct sbi_instrument *active_instrument[MAX_VOICE] =
-{NULL};
-
-static struct synth_info fm_info =
-{"OPL-2", 0, SYNTH_TYPE_FM, FM_TYPE_ADLIB, 0, 9, 0, SBFM_MAXINSTR, 0};
-
-static int already_initialized = 0;
-
-static int opl3_ok = 0;
-static int opl3_busy = 0;
-static int fm_model = 0; /*
-
-
- * * * * 0=no fm, 1=mono, 2=SB Pro 1, 3=SB
- * Pro 2 * * */
-
-static int store_instr (int instr_no, struct sbi_instrument *instr);
-static void freq_to_fnum (int freq, int *block, int *fnum);
-static void opl3_command (int io_addr, unsigned int addr, unsigned int val);
-static int opl3_kill_note (int dev, int voice, int note, int velocity);
-static unsigned char connection_mask = 0x00;
-
-void
-enable_opl3_mode (int left, int right, int both)
-{
- if (opl3_enabled)
- return;
-
- opl3_enabled = 1;
- left_address = left;
- right_address = right;
- both_address = both;
- fm_info.capabilities = SYNTH_CAP_OPL3;
- fm_info.synth_subtype = FM_TYPE_OPL3;
-}
-
-static void
-enter_4op_mode (void)
-{
- int i;
- static int voices_4op[MAX_VOICE] =
- {0, 1, 2, 9, 10, 11, 6, 7, 8, 15, 16, 17};
-
- connection_mask = 0x3f; /* Connect all possible 4 OP voices */
- opl3_command (right_address, CONNECTION_SELECT_REGISTER, 0x3f);
-
- for (i = 0; i < 3; i++)
- physical_voices[i].voice_mode = 4;
- for (i = 3; i < 6; i++)
- physical_voices[i].voice_mode = 0;
-
- for (i = 9; i < 12; i++)
- physical_voices[i].voice_mode = 4;
- for (i = 12; i < 15; i++)
- physical_voices[i].voice_mode = 0;
-
- for (i = 0; i < 12; i++)
- logical_voices[i] = voices_4op[i];
- voice_alloc->max_voice = nr_voices = 12;
-}
-
-static int
-opl3_ioctl (int dev,
- unsigned int cmd, unsigned int arg)
-{
- switch (cmd)
- {
-
- case SNDCTL_FM_LOAD_INSTR:
- {
- struct sbi_instrument ins;
-
- IOCTL_FROM_USER ((char *) &ins, (char *) arg, 0, sizeof (ins));
-
- if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR)
- {
- printk ("FM Error: Invalid instrument number %d\n", ins.channel);
- return RET_ERROR (EINVAL);
- }
-
- pmgr_inform (dev, PM_E_PATCH_LOADED, ins.channel, 0, 0, 0);
- return store_instr (ins.channel, &ins);
- }
- break;
-
- case SNDCTL_SYNTH_INFO:
- fm_info.nr_voices = (nr_voices == 12) ? 6 : nr_voices;
-
- IOCTL_TO_USER ((char *) arg, 0, &fm_info, sizeof (fm_info));
- return 0;
- break;
-
- case SNDCTL_SYNTH_MEMAVL:
- return 0x7fffffff;
- break;
-
- case SNDCTL_FM_4OP_ENABLE:
- if (opl3_enabled)
- enter_4op_mode ();
- return 0;
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
-
-}
-
-int
-opl3_detect (int ioaddr)
-{
- /*
- * This function returns 1 if the FM chicp is present at the given I/O port
- * The detection algorithm plays with the timer built in the FM chip and
- * looks for a change in the status register.
- *
- * Note! The timers of the FM chip are not connected to AdLib (and compatible)
- * boards.
- *
- * Note2! The chip is initialized if detected.
- */
-
- unsigned char stat1, stat2, signature;
- int i;
-
- if (already_initialized)
- {
- return 0; /*
- * Do avoid duplicate initializations
- */
- }
-
- if (opl3_enabled)
- ioaddr = left_address;
-
- /* Reset timers 1 and 2 */
- opl3_command (ioaddr, TIMER_CONTROL_REGISTER, TIMER1_MASK | TIMER2_MASK);
-
- /* Reset the IRQ of the FM chip */
- opl3_command (ioaddr, TIMER_CONTROL_REGISTER, IRQ_RESET);
-
- signature = stat1 = INB (ioaddr); /* Status register */
-
- if ((stat1 & 0xE0) != 0x00)
- {
- return 0; /*
- * Should be 0x00
- */
- }
-
- opl3_command (ioaddr, TIMER1_REGISTER, 0xff); /* Set timer1 to 0xff */
-
- opl3_command (ioaddr, TIMER_CONTROL_REGISTER,
- TIMER2_MASK | TIMER1_START); /*
- * Unmask and start timer 1
- */
-
- /*
- * Now we have to delay at least 80 usec
- */
-
- for (i = 0; i < 50; i++)
- tenmicrosec ();
-
- stat2 = INB (ioaddr); /*
- * Read status after timers have expired
- */
-
- /*
- * Stop the timers
- */
-
- /* Reset timers 1 and 2 */
- opl3_command (ioaddr, TIMER_CONTROL_REGISTER, TIMER1_MASK | TIMER2_MASK);
- /* Reset the IRQ of the FM chip */
- opl3_command (ioaddr, TIMER_CONTROL_REGISTER, IRQ_RESET);
-
- if ((stat2 & 0xE0) != 0xc0)
- {
- return 0; /*
- * There is no YM3812
- */
- }
-
- /*
- * There is a FM chicp in this address. Detect the type (OPL2 to OPL4)
- */
-
- if (signature == 0x06) /* OPL2 */
- {
- opl3_enabled = 0;
- }
- else if (signature == 0x00) /* OPL3 or OPL4 */
- {
- unsigned char tmp;
-
- if (!opl3_enabled) /* Was not already enabled */
- {
- left_address = ioaddr;
- right_address = ioaddr + 2;
- opl3_enabled = 1;
- }
-
- /*
- * Detect availability of OPL4 (_experimental_). Works propably
- * only after a cold boot. In addition the OPL4 port
- * of the chip may not be connected to the PC bus at all.
- */
-
- opl3_command (right_address, OPL3_MODE_REGISTER, 0x00);
- opl3_command (right_address, OPL3_MODE_REGISTER, OPL3_ENABLE | OPL4_ENABLE);
-
- if ((tmp = INB (ioaddr)) == 0x02) /* Have a OPL4 */
- {
- opl4_enabled = 1;
- }
- opl3_command (right_address, OPL3_MODE_REGISTER, 0);
-
- }
-
- for (i = 0; i < 9; i++)
- opl3_command (ioaddr, KEYON_BLOCK + i, 0); /*
- * Note off
- */
-
- opl3_command (ioaddr, TEST_REGISTER, ENABLE_WAVE_SELECT);
- opl3_command (ioaddr, PERCUSSION_REGISTER, 0x00); /*
- * Melodic mode.
- */
-
- return 1;
-}
-
-static int
-opl3_kill_note (int dev, int voice, int note, int velocity)
-{
- struct physical_voice_info *map;
-
- if (voice < 0 || voice >= nr_voices)
- return 0;
-
- voice_alloc->map[voice] = 0;
-
- map = &physical_voices[logical_voices[voice]];
-
- DEB (printk ("Kill note %d\n", voice));
-
- if (map->voice_mode == 0)
- return 0;
-
- opl3_command (map->ioaddr, KEYON_BLOCK + map->voice_num, voices[voice].keyon_byte & ~0x20);
-
- voices[voice].keyon_byte = 0;
- voices[voice].bender = 0;
- voices[voice].bender_range = 200; /*
- * 200 cents = 2 semitones
- */
- voices[voice].orig_freq = 0;
- voices[voice].current_freq = 0;
- voices[voice].mode = 0;
-
- return 0;
-}
-
-#define HIHAT 0
-#define CYMBAL 1
-#define TOMTOM 2
-#define SNARE 3
-#define BDRUM 4
-#define UNDEFINED TOMTOM
-#define DEFAULT TOMTOM
-
-static int
-store_instr (int instr_no, struct sbi_instrument *instr)
-{
-
- if (instr->key != FM_PATCH && (instr->key != OPL3_PATCH || !opl3_enabled))
- printk ("FM warning: Invalid patch format field (key) 0x%x\n", instr->key);
- memcpy ((char *) &(instrmap[instr_no]), (char *) instr, sizeof (*instr));
-
- return 0;
-}
-
-static int
-opl3_set_instr (int dev, int voice, int instr_no)
-{
- if (voice < 0 || voice >= nr_voices)
- return 0;
-
- if (instr_no < 0 || instr_no >= SBFM_MAXINSTR)
- return 0;
-
- active_instrument[voice] = &instrmap[instr_no];
- return 0;
-}
-
-/*
- * The next table looks magical, but it certainly is not. Its values have
- * been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception
- * for i=0. This log-table converts a linear volume-scaling (0..127) to a
- * logarithmic scaling as present in the FM-synthesizer chips. so : Volume
- * 64 = 0 db = relative volume 0 and: Volume 32 = -6 db = relative
- * volume -8 it was implemented as a table because it is only 128 bytes and
- * it saves a lot of log() calculations. (RH)
- */
-static char fm_volume_table[128] =
-{-64, -48, -40, -35, -32, -29, -27, -26, /*
- * 0 - 7
- */
- -24, -23, -21, -20, -19, -18, -18, -17, /*
- * 8 - 15
- */
- -16, -15, -15, -14, -13, -13, -12, -12, /*
- * 16 - 23
- */
- -11, -11, -10, -10, -10, -9, -9, -8, /*
- * 24 - 31
- */
- -8, -8, -7, -7, -7, -6, -6, -6, /*
- * 32 - 39
- */
- -5, -5, -5, -5, -4, -4, -4, -4, /*
- * 40 - 47
- */
- -3, -3, -3, -3, -2, -2, -2, -2, /*
- * 48 - 55
- */
- -2, -1, -1, -1, -1, 0, 0, 0, /*
- * 56 - 63
- */
- 0, 0, 0, 1, 1, 1, 1, 1, /*
- * 64 - 71
- */
- 1, 2, 2, 2, 2, 2, 2, 2, /*
- * 72 - 79
- */
- 3, 3, 3, 3, 3, 3, 3, 4, /*
- * 80 - 87
- */
- 4, 4, 4, 4, 4, 4, 4, 5, /*
- * 88 - 95
- */
- 5, 5, 5, 5, 5, 5, 5, 5, /*
- * 96 - 103
- */
- 6, 6, 6, 6, 6, 6, 6, 6, /*
- * 104 - 111
- */
- 6, 7, 7, 7, 7, 7, 7, 7, /*
- * 112 - 119
- */
- 7, 7, 7, 8, 8, 8, 8, 8}; /*
-
-
- * * * * 120 - 127 */
-
-static void
-calc_vol (unsigned char *regbyte, int volume)
-{
- int level = (~*regbyte & 0x3f);
-
- if (level)
- level += fm_volume_table[volume];
-
- if (level > 0x3f)
- level = 0x3f;
- if (level < 0)
- level = 0;
-
- *regbyte = (*regbyte & 0xc0) | (~level & 0x3f);
-}
-
-static void
-set_voice_volume (int voice, int volume)
-{
- unsigned char vol1, vol2, vol3, vol4;
- struct sbi_instrument *instr;
- struct physical_voice_info *map;
-
- if (voice < 0 || voice >= nr_voices)
- return;
-
- map = &physical_voices[logical_voices[voice]];
-
- instr = active_instrument[voice];
-
- if (!instr)
- instr = &instrmap[0];
-
- if (instr->channel < 0)
- return;
-
- if (voices[voice].mode == 0)
- return;
-
- if (voices[voice].mode == 2)
- { /*
- * 2 OP voice
- */
-
- vol1 = instr->operators[2];
- vol2 = instr->operators[3];
-
- if ((instr->operators[10] & 0x01))
- { /*
- * Additive synthesis
- */
- calc_vol (&vol1, volume);
- calc_vol (&vol2, volume);
- }
- else
- { /*
- * FM synthesis
- */
- calc_vol (&vol2, volume);
- }
-
- opl3_command (map->ioaddr, KSL_LEVEL + map->op[0], vol1); /*
- * Modulator
- * volume
- */
- opl3_command (map->ioaddr, KSL_LEVEL + map->op[1], vol2); /*
- * Carrier
- * volume
- */
- }
- else
- { /*
- * 4 OP voice
- */
- int connection;
-
- vol1 = instr->operators[2];
- vol2 = instr->operators[3];
- vol3 = instr->operators[OFFS_4OP + 2];
- vol4 = instr->operators[OFFS_4OP + 3];
-
- /*
- * The connection method for 4 OP voices is defined by the rightmost
- * bits at the offsets 10 and 10+OFFS_4OP
- */
-
- connection = ((instr->operators[10] & 0x01) << 1) | (instr->operators[10 + OFFS_4OP] & 0x01);
-
- switch (connection)
- {
- case 0:
- calc_vol (&vol4, volume); /*
- * Just the OP 4 is carrier
- */
- break;
-
- case 1:
- calc_vol (&vol2, volume);
- calc_vol (&vol4, volume);
- break;
-
- case 2:
- calc_vol (&vol1, volume);
- calc_vol (&vol4, volume);
- break;
-
- case 3:
- calc_vol (&vol1, volume);
- calc_vol (&vol3, volume);
- calc_vol (&vol4, volume);
- break;
-
- default: /*
- * Why ??
- */ ;
- }
-
- opl3_command (map->ioaddr, KSL_LEVEL + map->op[0], vol1);
- opl3_command (map->ioaddr, KSL_LEVEL + map->op[1], vol2);
- opl3_command (map->ioaddr, KSL_LEVEL + map->op[2], vol3);
- opl3_command (map->ioaddr, KSL_LEVEL + map->op[3], vol4);
- }
-}
-
-static int
-opl3_start_note (int dev, int voice, int note, int volume)
-{
- unsigned char data, fpc;
- int block, fnum, freq, voice_mode;
- struct sbi_instrument *instr;
- struct physical_voice_info *map;
-
- if (voice < 0 || voice >= nr_voices)
- return 0;
-
- map = &physical_voices[logical_voices[voice]];
-
- if (map->voice_mode == 0)
- return 0;
-
- if (note == 255) /*
- * Just change the volume
- */
- {
- set_voice_volume (voice, volume);
- return 0;
- }
-
- /*
- * Kill previous note before playing
- */
- opl3_command (map->ioaddr, KSL_LEVEL + map->op[1], 0xff); /*
- * Carrier
- * volume to
- * min
- */
- opl3_command (map->ioaddr, KSL_LEVEL + map->op[0], 0xff); /*
- * Modulator
- * volume to
- */
-
- if (map->voice_mode == 4)
- {
- opl3_command (map->ioaddr, KSL_LEVEL + map->op[2], 0xff);
- opl3_command (map->ioaddr, KSL_LEVEL + map->op[3], 0xff);
- }
-
- opl3_command (map->ioaddr, KEYON_BLOCK + map->voice_num, 0x00); /*
- * Note
- * off
- */
-
- instr = active_instrument[voice];
-
- if (!instr)
- instr = &instrmap[0];
-
- if (instr->channel < 0)
- {
- printk (
- "OPL3: Initializing voice %d with undefined instrument\n",
- voice);
- return 0;
- }
-
- if (map->voice_mode == 2 && instr->key == OPL3_PATCH)
- return 0; /*
- * Cannot play
- */
-
- voice_mode = map->voice_mode;
-
- if (voice_mode == 4)
- {
- int voice_shift;
-
- voice_shift = (map->ioaddr == left_address) ? 0 : 3;
- voice_shift += map->voice_num;
-
- if (instr->key != OPL3_PATCH) /*
- * Just 2 OP patch
- */
- {
- voice_mode = 2;
- connection_mask &= ~(1 << voice_shift);
- }
- else
- {
- connection_mask |= (1 << voice_shift);
- }
-
- opl3_command (right_address, CONNECTION_SELECT_REGISTER, connection_mask);
- }
-
- /*
- * Set Sound Characteristics
- */
- opl3_command (map->ioaddr, AM_VIB + map->op[0], instr->operators[0]);
- opl3_command (map->ioaddr, AM_VIB + map->op[1], instr->operators[1]);
-
- /*
- * Set Attack/Decay
- */
- opl3_command (map->ioaddr, ATTACK_DECAY + map->op[0], instr->operators[4]);
- opl3_command (map->ioaddr, ATTACK_DECAY + map->op[1], instr->operators[5]);
-
- /*
- * Set Sustain/Release
- */
- opl3_command (map->ioaddr, SUSTAIN_RELEASE + map->op[0], instr->operators[6]);
- opl3_command (map->ioaddr, SUSTAIN_RELEASE + map->op[1], instr->operators[7]);
-
- /*
- * Set Wave Select
- */
- opl3_command (map->ioaddr, WAVE_SELECT + map->op[0], instr->operators[8]);
- opl3_command (map->ioaddr, WAVE_SELECT + map->op[1], instr->operators[9]);
-
- /*
- * Set Feedback/Connection
- */
- fpc = instr->operators[10];
- if (!(fpc & 0x30))
- fpc |= 0x30; /*
- * Ensure that at least one chn is enabled
- */
- opl3_command (map->ioaddr, FEEDBACK_CONNECTION + map->voice_num,
- fpc);
-
- /*
- * If the voice is a 4 OP one, initialize the operators 3 and 4 also
- */
-
- if (voice_mode == 4)
- {
-
- /*
- * Set Sound Characteristics
- */
- opl3_command (map->ioaddr, AM_VIB + map->op[2], instr->operators[OFFS_4OP + 0]);
- opl3_command (map->ioaddr, AM_VIB + map->op[3], instr->operators[OFFS_4OP + 1]);
-
- /*
- * Set Attack/Decay
- */
- opl3_command (map->ioaddr, ATTACK_DECAY + map->op[2], instr->operators[OFFS_4OP + 4]);
- opl3_command (map->ioaddr, ATTACK_DECAY + map->op[3], instr->operators[OFFS_4OP + 5]);
-
- /*
- * Set Sustain/Release
- */
- opl3_command (map->ioaddr, SUSTAIN_RELEASE + map->op[2], instr->operators[OFFS_4OP + 6]);
- opl3_command (map->ioaddr, SUSTAIN_RELEASE + map->op[3], instr->operators[OFFS_4OP + 7]);
-
- /*
- * Set Wave Select
- */
- opl3_command (map->ioaddr, WAVE_SELECT + map->op[2], instr->operators[OFFS_4OP + 8]);
- opl3_command (map->ioaddr, WAVE_SELECT + map->op[3], instr->operators[OFFS_4OP + 9]);
-
- /*
- * Set Feedback/Connection
- */
- fpc = instr->operators[OFFS_4OP + 10];
- if (!(fpc & 0x30))
- fpc |= 0x30; /*
- * Ensure that at least one chn is enabled
- */
- opl3_command (map->ioaddr, FEEDBACK_CONNECTION + map->voice_num + 3, fpc);
- }
-
- voices[voice].mode = voice_mode;
-
- set_voice_volume (voice, volume);
-
- freq = voices[voice].orig_freq = note_to_freq (note) / 1000;
-
- /*
- * 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;
-
- freq_to_fnum (freq, &block, &fnum);
-
- /*
- * Play note
- */
-
- data = fnum & 0xff; /*
- * Least significant bits of fnumber
- */
- opl3_command (map->ioaddr, FNUM_LOW + map->voice_num, data);
-
- data = 0x20 | ((block & 0x7) << 2) | ((fnum >> 8) & 0x3);
- voices[voice].keyon_byte = data;
- opl3_command (map->ioaddr, KEYON_BLOCK + map->voice_num, data);
- if (voice_mode == 4)
- opl3_command (map->ioaddr, KEYON_BLOCK + map->voice_num + 3, data);
-
- return 0;
-}
-
-static void
-freq_to_fnum (int freq, int *block, int *fnum)
-{
- int f, octave;
-
- /*
- * Converts the note frequency to block and fnum values for the FM chip
- */
- /*
- * First try to compute the block -value (octave) where the note belongs
- */
-
- f = freq;
-
- octave = 5;
-
- if (f == 0)
- octave = 0;
- else if (f < 261)
- {
- while (f < 261)
- {
- octave--;
- f <<= 1;
- }
- }
- else if (f > 493)
- {
- while (f > 493)
- {
- octave++;
- f >>= 1;
- }
- }
-
- if (octave > 7)
- octave = 7;
-
- *fnum = freq * (1 << (20 - octave)) / 49716;
- *block = octave;
-}
-
-static void
-opl3_command (int io_addr, unsigned int addr, unsigned int val)
-{
- int i;
-
- /*
- * The original 2-OP synth requires a quite long delay after writing to a
- * register. The OPL-3 survives with just two INBs
- */
-
- OUTB ((unsigned char) (addr & 0xff), io_addr); /*
- * Select register
- *
- */
-
- if (!opl3_enabled)
- tenmicrosec ();
- else
- for (i = 0; i < 2; i++)
- INB (io_addr);
-
-#ifdef PC98
- OUTB ((unsigned char) (val & 0xff), io_addr + 0x100);
-#else
- OUTB ((unsigned char) (val & 0xff), io_addr + 1); /*
- * Write to register
- *
- */
-#endif
-
- if (!opl3_enabled)
- {
- tenmicrosec ();
- tenmicrosec ();
- tenmicrosec ();
- }
- else
- for (i = 0; i < 2; i++)
- INB (io_addr);
-}
-
-static void
-opl3_reset (int dev)
-{
- int i;
-
- for (i = 0; i < nr_voices; i++)
- {
- opl3_command (physical_voices[logical_voices[i]].ioaddr,
- KSL_LEVEL + physical_voices[logical_voices[i]].op[0], 0xff);
-
- opl3_command (physical_voices[logical_voices[i]].ioaddr,
- KSL_LEVEL + physical_voices[logical_voices[i]].op[1], 0xff);
-
- if (physical_voices[logical_voices[i]].voice_mode == 4)
- {
- opl3_command (physical_voices[logical_voices[i]].ioaddr,
- KSL_LEVEL + physical_voices[logical_voices[i]].op[2], 0xff);
-
- opl3_command (physical_voices[logical_voices[i]].ioaddr,
- KSL_LEVEL + physical_voices[logical_voices[i]].op[3], 0xff);
- }
-
- opl3_kill_note (dev, i, 0, 64);
- }
-
- if (opl3_enabled)
- {
- voice_alloc->max_voice = nr_voices = 18;
-
- for (i = 0; i < 18; i++)
- logical_voices[i] = i;
-
- for (i = 0; i < 18; i++)
- physical_voices[i].voice_mode = 2;
-
- }
-
-}
-
-static int
-opl3_open (int dev, int mode)
-{
- int i;
-
- if (!opl3_ok)
- return RET_ERROR (ENXIO);
- if (opl3_busy)
- return RET_ERROR (EBUSY);
- opl3_busy = 1;
-
- voice_alloc->max_voice = nr_voices = opl3_enabled ? 18 : 9;
- voice_alloc->timestamp = 0;
-
- for (i = 0; i < 18; i++)
- {
- voice_alloc->map[i] = 0;
- voice_alloc->alloc_times[i] = 0;
- }
-
- connection_mask = 0x00; /*
- * Just 2 OP voices
- */
- if (opl3_enabled)
- opl3_command (right_address, CONNECTION_SELECT_REGISTER, connection_mask);
- return 0;
-}
-
-static void
-opl3_close (int dev)
-{
- opl3_busy = 0;
- voice_alloc->max_voice = nr_voices = opl3_enabled ? 18 : 9;
-
- fm_info.nr_drums = 0;
- fm_info.perc_mode = 0;
-
- opl3_reset (dev);
-}
-
-static void
-opl3_hw_control (int dev, unsigned char *event)
-{
-}
-
-static int
-opl3_load_patch (int dev, int format, snd_rw_buf * addr,
- int offs, int count, int pmgr_flag)
-{
- struct sbi_instrument ins;
-
- if (count < sizeof (ins))
- {
- printk ("FM Error: Patch record too short\n");
- return RET_ERROR (EINVAL);
- }
-
- COPY_FROM_USER (&((char *) &ins)[offs], (char *) addr, offs, sizeof (ins) - offs);
-
- if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR)
- {
- printk ("FM Error: Invalid instrument number %d\n", ins.channel);
- return RET_ERROR (EINVAL);
- }
- ins.key = format;
-
- return store_instr (ins.channel, &ins);
-}
-
-static void
-opl3_panning (int dev, int voice, int pressure)
-{
-}
-
-static void
-opl3_volume_method (int dev, int mode)
-{
-}
-
-#define SET_VIBRATO(cell) { \
- tmp = instr->operators[(cell-1)+(((cell-1)/2)*OFFS_4OP)]; \
- if (pressure > 110) \
- tmp |= 0x40; /* Vibrato on */ \
- opl3_command (map->ioaddr, AM_VIB + map->op[cell-1], tmp);}
-
-static void
-opl3_aftertouch (int dev, int voice, int pressure)
-{
- int tmp;
- struct sbi_instrument *instr;
- struct physical_voice_info *map;
-
- if (voice < 0 || voice >= nr_voices)
- return;
-
- map = &physical_voices[logical_voices[voice]];
-
- DEB (printk ("Aftertouch %d\n", voice));
-
- if (map->voice_mode == 0)
- return;
-
- /*
- * Adjust the amount of vibrato depending the pressure
- */
-
- instr = active_instrument[voice];
-
- if (!instr)
- instr = &instrmap[0];
-
- if (voices[voice].mode == 4)
- {
- int connection = ((instr->operators[10] & 0x01) << 1) | (instr->operators[10 + OFFS_4OP] & 0x01);
-
- switch (connection)
- {
- case 0:
- SET_VIBRATO (4);
- break;
-
- case 1:
- SET_VIBRATO (2);
- SET_VIBRATO (4);
- break;
-
- case 2:
- SET_VIBRATO (1);
- SET_VIBRATO (4);
- break;
-
- case 3:
- SET_VIBRATO (1);
- SET_VIBRATO (3);
- SET_VIBRATO (4);
- break;
-
- }
- /*
- * Not implemented yet
- */
- }
- else
- {
- SET_VIBRATO (1);
-
- if ((instr->operators[10] & 0x01)) /*
- * Additive synthesis
- */
- SET_VIBRATO (2);
- }
-}
-
-#undef SET_VIBRATO
-
-static void
-bend_pitch (int dev, int voice, int value)
-{
- unsigned char data;
- int block, fnum, freq;
- struct physical_voice_info *map;
-
- map = &physical_voices[logical_voices[voice]];
-
- if (map->voice_mode == 0)
- return;
-
- voices[voice].bender = value;
- if (!value)
- return;
- if (!(voices[voice].keyon_byte & 0x20))
- return; /*
- * Not keyed on
- */
-
- freq = compute_finetune (voices[voice].orig_freq, voices[voice].bender, voices[voice].bender_range);
- voices[voice].current_freq = freq;
-
- freq_to_fnum (freq, &block, &fnum);
-
- data = fnum & 0xff; /*
- * Least significant bits of fnumber
- */
- opl3_command (map->ioaddr, FNUM_LOW + map->voice_num, data);
-
- data = 0x20 | ((block & 0x7) << 2) | ((fnum >> 8) & 0x3); /*
- * *
- * KEYON|OCTAVE|MS
- *
- * * bits * *
- * of * f-num
- *
- */
- voices[voice].keyon_byte = data;
- opl3_command (map->ioaddr, KEYON_BLOCK + map->voice_num, data);
-}
-
-static void
-opl3_controller (int dev, int voice, int ctrl_num, int value)
-{
- if (voice < 0 || voice >= nr_voices)
- return;
-
- switch (ctrl_num)
- {
- case CTRL_PITCH_BENDER:
- bend_pitch (dev, voice, value);
- break;
-
- case CTRL_PITCH_BENDER_RANGE:
- voices[voice].bender_range = value;
- break;
- }
-}
-
-static int
-opl3_patchmgr (int dev, struct patmgr_info *rec)
-{
- return RET_ERROR (EINVAL);
-}
-
-static void
-opl3_bender (int dev, int voice, int value)
-{
- if (voice < 0 || voice >= nr_voices)
- return;
-
- bend_pitch (dev, voice, value);
-}
-
-static int
-opl3_alloc_voice (int dev, int chn, int note, struct voice_alloc_info *alloc)
-{
- int i, p, best, first, avail_voices, best_time = 0x7fffffff;
- struct sbi_instrument *instr;
- int is4op;
- int instr_no;
-
- if (chn < 0 || chn > 15)
- instr_no = 0;
- else
- instr_no = chn_info[chn].pgm_num;
-
- instr = &instrmap[instr_no];
- if (instr->channel < 0 || /* Instrument not loaded */
- nr_voices != 12) /* Not in 4 OP mode */
- is4op = 0;
- else if (nr_voices == 12) /* 4 OP mode */
- is4op = (instr->key == OPL3_PATCH);
- else
- is4op = 0;
-
- if (is4op)
- {
- first = p = 0;
- avail_voices = 6;
- }
- else
- {
- if (nr_voices == 12) /* 4 OP mode. Use the '2 OP only' voices first */
- first = p = 6;
- else
- first = p = 0;
- avail_voices = nr_voices;
- }
-
- /*
- * Now try to find a free voice
- */
- best = first;
-
- for (i = 0; i < avail_voices; i++)
- {
- if (alloc->map[p] == 0)
- {
- return p;
- }
- if (alloc->alloc_times[p] < best_time) /* Find oldest playing note */
- {
- best_time = alloc->alloc_times[p];
- best = p;
- }
- p = (p + 1) % avail_voices;
- }
-
- /*
- * Insert some kind of priority mechanism here.
- */
-
- if (best < 0)
- best = 0;
- if (best > nr_voices)
- best -= nr_voices;
-
- return best; /* All voices in use. Select the first one. */
-}
-
-static void
-opl3_setup_voice (int dev, int voice, int chn)
-{
- struct channel_info *info =
- &synth_devs[dev]->chn_info[chn];
-
- opl3_set_instr (dev, voice,
- info->pgm_num);
-
- voices[voice].bender = info->bender_value;
-}
-
-static struct synth_operations opl3_operations =
-{
- &fm_info,
- 0,
- SYNTH_TYPE_FM,
- FM_TYPE_ADLIB,
- opl3_open,
- opl3_close,
- opl3_ioctl,
- opl3_kill_note,
- opl3_start_note,
- opl3_set_instr,
- opl3_reset,
- opl3_hw_control,
- opl3_load_patch,
- opl3_aftertouch,
- opl3_controller,
- opl3_panning,
- opl3_volume_method,
- opl3_patchmgr,
- opl3_bender,
- opl3_alloc_voice,
- opl3_setup_voice
-};
-
-long
-opl3_init (long mem_start)
-{
- int i;
-
- PERMANENT_MALLOC (struct sbi_instrument *, instrmap,
- SBFM_MAXINSTR * sizeof (*instrmap), mem_start);
-
- if (num_synths >= MAX_SYNTH_DEV)
- printk ("OPL3 Error: Too many synthesizers\n");
- else
- {
- synth_devs[num_synths++] = &opl3_operations;
- voice_alloc = &opl3_operations.alloc;
- chn_info = &opl3_operations.chn_info[0];
- }
-
- fm_model = 0;
- opl3_ok = 1;
- if (opl3_enabled)
- {
- if (opl4_enabled)
-#if defined(__FreeBSD__)
- printk ("opl0: <Yamaha OPL4/OPL3 FM>");
- else
- printk ("opl0: <Yamaha OPL-3 FM>");
-#else
- printk (" <Yamaha OPL4/OPL3 FM>");
- else
- printk (" <Yamaha OPL-3 FM>");
-#endif
-
- fm_model = 2;
- voice_alloc->max_voice = nr_voices = 18;
- fm_info.nr_drums = 0;
- fm_info.capabilities |= SYNTH_CAP_OPL3;
- strcpy (fm_info.name, "Yamaha OPL-3");
-
- for (i = 0; i < 18; i++)
- if (physical_voices[i].ioaddr == USE_LEFT)
- physical_voices[i].ioaddr = left_address;
- else
- physical_voices[i].ioaddr = right_address;
-
-
- opl3_command (right_address, OPL3_MODE_REGISTER, OPL3_ENABLE); /*
- * Enable
- * OPL-3
- * mode
- */
- opl3_command (right_address, CONNECTION_SELECT_REGISTER, 0x00); /*
- * Select
- * all
- * 2-OP
- * *
- * voices
- */
- }
- else
- {
-#if defined(__FreeBSD__)
- printk ("opl0: <Yamaha 2-OP FM>");
-#else
- printk (" <Yamaha 2-OP FM>");
-#endif
- fm_model = 1;
- voice_alloc->max_voice = nr_voices = 9;
- fm_info.nr_drums = 0;
-
- for (i = 0; i < 18; i++)
- physical_voices[i].ioaddr = left_address;
- };
-
- already_initialized = 1;
- for (i = 0; i < SBFM_MAXINSTR; i++)
- instrmap[i].channel = -1;
-
- return mem_start;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/pas2_pcm.c b/sys/pc98/pc98/sound/pas2_pcm.c
deleted file mode 100644
index db91165..0000000
--- a/sys/pc98/pc98/sound/pas2_pcm.c
+++ /dev/null
@@ -1,461 +0,0 @@
-#define _PAS2_PCM_C_
-/*
- * sound/pas2_pcm.c
- *
- * The low level driver for the Pro Audio Spectrum ADC/DAC.
- *
- * 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>
-
-static int pcm_set_bits __P((int arg));
-static int pcm_set_channels __P((int arg));
-static int pcm_set_speed __P((int arg));
-
-#if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_AUDIO)
-
-#define TRACE(WHAT) /*
- * * * (WHAT) */
-
-#define PAS_PCM_INTRBITS (0x08)
-/*
- * Sample buffer timer interrupt enable
- */
-
-#define PCM_NON 0
-#define PCM_DAC 1
-#define PCM_ADC 2
-
-static unsigned long pcm_speed = 0; /* sampling rate */
-static unsigned char pcm_channels = 1; /* channels (1 or 2) */
-static unsigned char pcm_bits = 8; /* bits/sample (8 or 16) */
-static unsigned char pcm_filter = 0; /* filter FLAG */
-static unsigned char pcm_mode = PCM_NON;
-static unsigned long pcm_count = 0;
-static unsigned short pcm_bitsok = 8; /* mask of OK bits */
-static int my_devnum = 0;
-
-static int
-pcm_set_speed (int arg)
-{
- int foo, tmp;
- unsigned long flags;
-
- if (arg > 44100)
- arg = 44100;
- if (arg < 5000)
- arg = 5000;
-
- foo = (1193180 + (arg / 2)) / arg;
- arg = 1193180 / foo;
-
- if (pcm_channels & 2)
- foo = foo >> 1;
-
- pcm_speed = arg;
-
- tmp = pas_read (FILTER_FREQUENCY);
-
- /*
- * Set anti-aliasing filters according to sample rate. You reall *NEED*
- * to enable this feature for all normal recording unless you want to
- * experiment with aliasing effects.
- * These filters apply to the selected "recording" source.
- * I (pfw) don't know the encoding of these 5 bits. The values shown
- * come from the SDK found on ftp.uwp.edu:/pub/msdos/proaudio/.
- */
-#if !defined NO_AUTO_FILTER_SET
- tmp &= 0xe0;
- if (pcm_speed >= 2 * 17897)
- tmp |= 0x21;
- else if (pcm_speed >= 2 * 15909)
- tmp |= 0x22;
- else if (pcm_speed >= 2 * 11931)
- tmp |= 0x29;
- else if (pcm_speed >= 2 * 8948)
- tmp |= 0x31;
- else if (pcm_speed >= 2 * 5965)
- tmp |= 0x39;
- else if (pcm_speed >= 2 * 2982)
- tmp |= 0x24;
- pcm_filter = tmp;
-#endif
-
- DISABLE_INTR (flags);
-
- pas_write (tmp & ~(F_F_PCM_RATE_COUNTER | F_F_PCM_BUFFER_COUNTER), FILTER_FREQUENCY);
- pas_write (S_C_C_SAMPLE_RATE | S_C_C_LSB_THEN_MSB | S_C_C_SQUARE_WAVE, SAMPLE_COUNTER_CONTROL);
- pas_write (foo & 0xff, SAMPLE_RATE_TIMER);
- pas_write ((foo >> 8) & 0xff, SAMPLE_RATE_TIMER);
- pas_write (tmp, FILTER_FREQUENCY);
-
- RESTORE_INTR (flags);
-
- return pcm_speed;
-}
-
-static int
-pcm_set_channels (int arg)
-{
-
- if ((arg != 1) && (arg != 2))
- return pcm_channels;
-
- if (arg != pcm_channels)
- {
- pas_write (pas_read (PCM_CONTROL) ^ P_C_PCM_MONO, PCM_CONTROL);
-
- pcm_channels = arg;
- pcm_set_speed (pcm_speed); /*
- * The speed must be reinitialized
- */
- }
-
- return pcm_channels;
-}
-
-static int
-pcm_set_bits (int arg)
-{
- if ((arg & pcm_bitsok) != arg)
- return pcm_bits;
-
- if (arg != pcm_bits)
- {
- pas_write (pas_read (SYSTEM_CONFIGURATION_2) ^ S_C_2_PCM_16_BIT, SYSTEM_CONFIGURATION_2);
-
- pcm_bits = arg;
- }
-
- return pcm_bits;
-}
-
-static int
-pas_pcm_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
-{
- TRACE (printk ("pas2_pcm.c: static int pas_pcm_ioctl(unsigned int cmd = %X, unsigned int arg = %X)\n", cmd, arg));
-
- switch (cmd)
- {
- case SOUND_PCM_WRITE_RATE:
- if (local)
- return pcm_set_speed (arg);
- return IOCTL_OUT (arg, pcm_set_speed (IOCTL_IN (arg)));
- break;
-
- case SOUND_PCM_READ_RATE:
- if (local)
- return pcm_speed;
- return IOCTL_OUT (arg, pcm_speed);
- break;
-
- case SNDCTL_DSP_STEREO:
- if (local)
- return pcm_set_channels (arg + 1) - 1;
- return IOCTL_OUT (arg, pcm_set_channels (IOCTL_IN (arg) + 1) - 1);
- break;
-
- case SOUND_PCM_WRITE_CHANNELS:
- if (local)
- return pcm_set_channels (arg);
- return IOCTL_OUT (arg, pcm_set_channels (IOCTL_IN (arg)));
- break;
-
- case SOUND_PCM_READ_CHANNELS:
- if (local)
- return pcm_channels;
- return IOCTL_OUT (arg, pcm_channels);
- break;
-
- case SNDCTL_DSP_SETFMT:
- if (local)
- return pcm_set_bits (arg);
- return IOCTL_OUT (arg, pcm_set_bits (IOCTL_IN (arg)));
- break;
-
- case SOUND_PCM_READ_BITS:
- if (local)
- return pcm_bits;
- return IOCTL_OUT (arg, pcm_bits);
-
- case SOUND_PCM_WRITE_FILTER: /*
- * NOT YET IMPLEMENTED
- */
- if (IOCTL_IN (arg) > 1)
- return IOCTL_OUT (arg, RET_ERROR (EINVAL));
- break;
-
- pcm_filter = IOCTL_IN (arg);
- case SOUND_PCM_READ_FILTER:
- return IOCTL_OUT (arg, pcm_filter);
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
-
- return RET_ERROR (EINVAL);
-}
-
-static void
-pas_pcm_reset (int dev)
-{
- TRACE (printk ("pas2_pcm.c: static void pas_pcm_reset(void)\n"));
-
- pas_write (pas_read (PCM_CONTROL) & ~P_C_PCM_ENABLE, PCM_CONTROL);
-}
-
-static int
-pas_pcm_open (int dev, int mode)
-{
- int err;
-
- TRACE (printk ("pas2_pcm.c: static int pas_pcm_open(int mode = %X)\n", mode));
-
- if ((err = pas_set_intr (PAS_PCM_INTRBITS)) < 0)
- return err;
-
- if (DMAbuf_open_dma (dev) < 0)
- {
- pas_remove_intr (PAS_PCM_INTRBITS);
- return RET_ERROR (EBUSY);
- }
-
- pcm_count = 0;
-
- return 0;
-}
-
-static void
-pas_pcm_close (int dev)
-{
- unsigned long flags;
-
- TRACE (printk ("pas2_pcm.c: static void pas_pcm_close(void)\n"));
-
- DISABLE_INTR (flags);
-
- pas_pcm_reset (dev);
- DMAbuf_close_dma (dev);
- pas_remove_intr (PAS_PCM_INTRBITS);
- pcm_mode = PCM_NON;
-
- RESTORE_INTR (flags);
-}
-
-static void
-pas_pcm_output_block (int dev, unsigned long buf, int count,
- int intrflag, int restart_dma)
-{
- unsigned long flags, cnt;
-
- TRACE (printk ("pas2_pcm.c: static void pas_pcm_output_block(char *buf = %P, int count = %X)\n", buf, count));
-
- cnt = count;
- if (audio_devs[dev]->dmachan > 3)
- cnt >>= 1;
-
- if (audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == pcm_count)
- return; /*
- * Auto mode on. No need to react
- */
-
- DISABLE_INTR (flags);
-
- pas_write (pas_read (PCM_CONTROL) & ~P_C_PCM_ENABLE,
- PCM_CONTROL);
-
- if (restart_dma)
- DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
-
- if (audio_devs[dev]->dmachan > 3)
- count >>= 1;
-
- if (count != pcm_count)
- {
- pas_write (pas_read (FILTER_FREQUENCY) & ~F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY);
- pas_write (S_C_C_SAMPLE_BUFFER | S_C_C_LSB_THEN_MSB | S_C_C_SQUARE_WAVE, SAMPLE_COUNTER_CONTROL);
- pas_write (count & 0xff, SAMPLE_BUFFER_COUNTER);
- pas_write ((count >> 8) & 0xff, SAMPLE_BUFFER_COUNTER);
- pas_write (pas_read (FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY);
-
- pcm_count = count;
- }
- pas_write (pas_read (FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER, FILTER_FREQUENCY);
- pas_write (pas_read (PCM_CONTROL) | P_C_PCM_ENABLE | P_C_PCM_DAC_MODE, PCM_CONTROL);
-
- pcm_mode = PCM_DAC;
-
- RESTORE_INTR (flags);
-}
-
-static void
-pas_pcm_start_input (int dev, unsigned long buf, int count,
- int intrflag, int restart_dma)
-{
- unsigned long flags;
- int cnt;
-
- TRACE (printk ("pas2_pcm.c: static void pas_pcm_start_input(char *buf = %P, int count = %X)\n", buf, count));
-
- cnt = count;
- if (audio_devs[dev]->dmachan > 3)
- cnt >>= 1;
-
- if (audio_devs[my_devnum]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == pcm_count)
- return; /*
- * Auto mode on. No need to react
- */
-
- DISABLE_INTR (flags);
-
- if (restart_dma)
- DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
-
- if (audio_devs[dev]->dmachan > 3)
- count >>= 1;
-
- if (count != pcm_count)
- {
- pas_write (pas_read (FILTER_FREQUENCY) & ~F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY);
- pas_write (S_C_C_SAMPLE_BUFFER | S_C_C_LSB_THEN_MSB | S_C_C_SQUARE_WAVE, SAMPLE_COUNTER_CONTROL);
- pas_write (count & 0xff, SAMPLE_BUFFER_COUNTER);
- pas_write ((count >> 8) & 0xff, SAMPLE_BUFFER_COUNTER);
- pas_write (pas_read (FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER, FILTER_FREQUENCY);
-
- pcm_count = count;
- }
- pas_write (pas_read (FILTER_FREQUENCY) | F_F_PCM_BUFFER_COUNTER | F_F_PCM_RATE_COUNTER, FILTER_FREQUENCY);
- pas_write ((pas_read (PCM_CONTROL) | P_C_PCM_ENABLE) & ~P_C_PCM_DAC_MODE, PCM_CONTROL);
-
- pcm_mode = PCM_ADC;
-
- RESTORE_INTR (flags);
-}
-
-static int
-pas_pcm_prepare_for_input (int dev, int bsize, int bcount)
-{
- return 0;
-}
-static int
-pas_pcm_prepare_for_output (int dev, int bsize, int bcount)
-{
- return 0;
-}
-
-static struct audio_operations pas_pcm_operations =
-{
- "Pro Audio Spectrum",
-#ifdef PC98
- NEEDS_RESTART,
-#else
- DMA_AUTOMODE,
-#endif
- AFMT_U8 | AFMT_S16_LE,
- NULL,
- pas_pcm_open,
- pas_pcm_close,
- pas_pcm_output_block,
- pas_pcm_start_input,
- pas_pcm_ioctl,
- pas_pcm_prepare_for_input,
- pas_pcm_prepare_for_output,
- pas_pcm_reset,
- pas_pcm_reset,
- NULL,
- NULL
-};
-
-long
-pas_pcm_init (long mem_start, struct address_info *hw_config)
-{
- TRACE (printk ("pas2_pcm.c: long pas_pcm_init(long mem_start = %X)\n", mem_start));
-
- pcm_bitsok = 8;
- if (pas_read (OPERATION_MODE_1) & O_M_1_PCM_TYPE)
- pcm_bitsok |= 16;
-
- pcm_set_speed (DSP_DEFAULT_SPEED);
-
- if (num_audiodevs < MAX_AUDIO_DEV)
- {
- audio_devs[my_devnum = num_audiodevs++] = &pas_pcm_operations;
- audio_devs[my_devnum]->dmachan = hw_config->dma;
- audio_devs[my_devnum]->buffcount = 1;
- audio_devs[my_devnum]->buffsize = DSP_BUFFSIZE;
- }
- else
- printk ("PAS2: Too many PCM devices available\n");
-
- return mem_start;
-}
-
-void
-pas_pcm_interrupt (unsigned char status, int cause)
-{
- if (cause == 1) /*
- * PCM buffer done
- */
- {
- /*
- * Halt the PCM first. Otherwise we don't have time to start a new
- * block before the PCM chip proceeds to the next sample
- */
-
- if (!(audio_devs[my_devnum]->flags & DMA_AUTOMODE))
- {
- pas_write (pas_read (PCM_CONTROL) & ~P_C_PCM_ENABLE,
- PCM_CONTROL);
- }
-
- switch (pcm_mode)
- {
-
- case PCM_DAC:
- DMAbuf_outputintr (my_devnum, 1);
- break;
-
- case PCM_ADC:
- DMAbuf_inputintr (my_devnum);
- break;
-
- default:
- printk ("PAS: Unexpected PCM interrupt\n");
- }
- }
-}
-
-#endif
-
-#endif
diff --git a/sys/pc98/pc98/sound/sb16_dsp.c b/sys/pc98/pc98/sound/sb16_dsp.c
deleted file mode 100644
index 5e84e67..0000000
--- a/sys/pc98/pc98/sound/sb16_dsp.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * sound/sb16_dsp.c
- *
- * The low level driver for the SoundBlaster DSP chip.
- *
- * (C) 1993 J. Schubert (jsb@sth.ruhr-uni-bochum.de)
- *
- * based on SB-driver by (C) Hannu Savolainen
- *
- * 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 DEB(x)
-#define DEB1(x)
-/*
- * #define DEB_DMARES
- */
-#include <i386/isa/sound/sound_config.h>
-#include <i386/isa/sound/sb.h>
-#include <i386/isa/sound/sb_mixer.h>
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_AUDIO) && !defined(EXCLUDE_SBPRO)
-
-extern int sbc_base;
-extern int sbc_major;
-extern int sbc_minor;
-
-static int sb16_dsp_ok = 0; /*
-
-
- * * * * Set to 1 after successful *
- * * initialization */
-static int dsp_16bit = 0;
-static int dsp_stereo = 0;
-static int dsp_current_speed = 8000; /*
-
-
- * * * * DSP_DEFAULT_SPEED; */
-static int dsp_busy = 0;
-static int dma16, dma8;
-static unsigned long dsp_count = 0;
-
-static int irq_mode = IMODE_NONE; /*
-
-
- * * * * IMODE_INPUT, IMODE_OUTPUT
- * or * * IMODE_NONE */
-static int my_dev = 0;
-
-static volatile int intr_active = 0;
-
-static int sb16_dsp_open (int dev, int mode);
-static void sb16_dsp_close (int dev);
-static void sb16_dsp_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart);
-static void sb16_dsp_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart);
-static int sb16_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local);
-static int sb16_dsp_prepare_for_input (int dev, int bsize, int bcount);
-static int sb16_dsp_prepare_for_output (int dev, int bsize, int bcount);
-static void sb16_dsp_reset (int dev);
-static void sb16_dsp_halt (int dev);
-static int dsp_set_speed (int);
-static int dsp_set_stereo (int);
-static void dsp_cleanup (void);
-
-static struct audio_operations sb16_dsp_operations =
-{
- "SoundBlaster 16",
-#ifdef PC98
- NEEDS_RESTART,
-#else
- DMA_AUTOMODE,
-#endif
- AFMT_U8 | AFMT_S16_LE,
- NULL,
- sb16_dsp_open,
- sb16_dsp_close,
- sb16_dsp_output_block,
- sb16_dsp_start_input,
- sb16_dsp_ioctl,
- sb16_dsp_prepare_for_input,
- sb16_dsp_prepare_for_output,
- sb16_dsp_reset,
- sb16_dsp_halt,
- NULL,
- NULL
-};
-
-static int
-sb_dsp_command01 (unsigned char val)
-{
- int i = 1 << 16;
-
- while (--i & (!INB (DSP_STATUS) & 0x80));
- if (!i)
- printk ("SB16 sb_dsp_command01 Timeout\n");
- return sb_dsp_command (val);
-}
-
-static int
-dsp_set_speed (int mode)
-{
- DEB (printk ("dsp_set_speed(%d)\n", mode));
- if (mode)
- {
- if (mode < 5000)
- mode = 5000;
- if (mode > 44100)
- mode = 44100;
- dsp_current_speed = mode;
- }
- return mode;
-}
-
-static int
-dsp_set_stereo (int mode)
-{
- DEB (printk ("dsp_set_stereo(%d)\n", mode));
-
- dsp_stereo = mode;
-
- return mode;
-}
-
-static int
-dsp_set_bits (int arg)
-{
- DEB (printk ("dsp_set_bits(%d)\n", arg));
-
- if (arg)
- switch (arg)
- {
- case 8:
- dsp_16bit = 0;
- break;
- case 16:
- dsp_16bit = 1;
- break;
- default:
- dsp_16bit = 0;
- }
- return dsp_16bit ? 16 : 8;
-}
-
-static int
-sb16_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
-{
- switch (cmd)
- {
- case SOUND_PCM_WRITE_RATE:
- if (local)
- return dsp_set_speed (arg);
- return IOCTL_OUT (arg, dsp_set_speed (IOCTL_IN (arg)));
-
- case SOUND_PCM_READ_RATE:
- if (local)
- return dsp_current_speed;
- return IOCTL_OUT (arg, dsp_current_speed);
-
- case SNDCTL_DSP_STEREO:
- if (local)
- return dsp_set_stereo (arg);
- return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg)));
-
- case SOUND_PCM_WRITE_CHANNELS:
- if (local)
- return dsp_set_stereo (arg - 1) + 1;
- return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);
-
- case SOUND_PCM_READ_CHANNELS:
- if (local)
- return dsp_stereo + 1;
- return IOCTL_OUT (arg, dsp_stereo + 1);
-
- case SNDCTL_DSP_SETFMT:
- if (local)
- return dsp_set_bits (arg);
- return IOCTL_OUT (arg, dsp_set_bits (IOCTL_IN (arg)));
-
- case SOUND_PCM_READ_BITS:
- if (local)
- return dsp_16bit ? 16 : 8;
- return IOCTL_OUT (arg, dsp_16bit ? 16 : 8);
-
- case SOUND_PCM_WRITE_FILTER: /*
- * NOT YET IMPLEMENTED
- */
- if (IOCTL_IN (arg) > 1)
- return IOCTL_OUT (arg, RET_ERROR (EINVAL));
- default:
- return RET_ERROR (EINVAL);
- }
-
- return RET_ERROR (EINVAL);
-}
-
-static int
-sb16_dsp_open (int dev, int mode)
-{
- int retval;
-
- DEB (printk ("sb16_dsp_open()\n"));
- if (!sb16_dsp_ok)
- {
- printk ("SB16 Error: SoundBlaster board not installed\n");
- return RET_ERROR (ENXIO);
- }
-
- if (intr_active)
- return RET_ERROR (EBUSY);
-
- retval = sb_get_irq ();
- if (retval < 0)
- return retval;
-
- sb_reset_dsp ();
-
- if (ALLOC_DMA_CHN (dma8, "SB16 (8bit)"))
- {
- printk ("SB16: Unable to grab DMA%d\n", dma8);
- sb_free_irq ();
- return RET_ERROR (EBUSY);
- }
-
- if (dma16 != dma8)
- if (ALLOC_DMA_CHN (dma16, "SB16 (16bit)"))
- {
- printk ("SB16: Unable to grab DMA%d\n", dma16);
- sb_free_irq ();
- RELEASE_DMA_CHN (dma8);
- return RET_ERROR (EBUSY);
- }
-
- irq_mode = IMODE_NONE;
- dsp_busy = 1;
-
- return 0;
-}
-
-static void
-sb16_dsp_close (int dev)
-{
- unsigned long flags;
-
- DEB (printk ("sb16_dsp_close()\n"));
- sb_dsp_command01 (0xd9);
- sb_dsp_command01 (0xd5);
-
- DISABLE_INTR (flags);
- RELEASE_DMA_CHN (dma8);
-
- if (dma16 != dma8)
- RELEASE_DMA_CHN (dma16);
- sb_free_irq ();
- dsp_cleanup ();
- dsp_busy = 0;
- RESTORE_INTR (flags);
-}
-
-static void
-sb16_dsp_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
-{
- unsigned long flags, cnt;
-
- cnt = count;
- if (dsp_16bit)
- cnt >>= 1;
- cnt--;
-
-#ifdef DEB_DMARES
- printk ("output_block: %x %d %d\n", buf, count, intrflag);
- if (intrflag)
- {
- int pos, chan = audio_devs[dev]->dmachan;
-
- DISABLE_INTR (flags);
- clear_dma_ff (chan);
- disable_dma (chan);
- pos = get_dma_residue (chan);
- enable_dma (chan);
- RESTORE_INTR (flags);
- printk ("dmapos=%d %x\n", pos, pos);
- }
-#endif
- if (audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == dsp_count)
- {
- irq_mode = IMODE_OUTPUT;
- intr_active = 1;
- return; /*
- * Auto mode on. No need to react
- */
- }
- DISABLE_INTR (flags);
-
- if (dma_restart)
- {
- sb16_dsp_halt (dev);
- DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
- }
- sb_dsp_command (0x41);
- sb_dsp_command ((unsigned char) ((dsp_current_speed >> 8) & 0xff));
- sb_dsp_command ((unsigned char) (dsp_current_speed & 0xff));
- sb_dsp_command ((unsigned char) (dsp_16bit ? 0xb6 : 0xc6));
- sb_dsp_command ((unsigned char) ((dsp_stereo ? 0x20 : 0) +
- (dsp_16bit ? 0x10 : 0)));
- sb_dsp_command01 ((unsigned char) (cnt & 0xff));
- sb_dsp_command ((unsigned char) (cnt >> 8));
-
- dsp_count = cnt;
- irq_mode = IMODE_OUTPUT;
- intr_active = 1;
- RESTORE_INTR (flags);
-}
-
-static void
-sb16_dsp_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
-{
- unsigned long flags, cnt;
-
- cnt = count;
- if (dsp_16bit)
- cnt >>= 1;
- cnt--;
-
-#ifdef DEB_DMARES
- printk ("start_input: %x %d %d\n", buf, count, intrflag);
- if (intrflag)
- {
- int pos, chan = audio_devs[dev]->dmachan;
-
- DISABLE_INTR (flags);
- clear_dma_ff (chan);
- disable_dma (chan);
- pos = get_dma_residue (chan);
- enable_dma (chan);
- RESTORE_INTR (flags);
- printk ("dmapos=%d %x\n", pos, pos);
- }
-#endif
- if (audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- cnt == dsp_count)
- {
- irq_mode = IMODE_INPUT;
- intr_active = 1;
- return; /*
- * Auto mode on. No need to react
- */
- }
- DISABLE_INTR (flags);
-
- if (dma_restart)
- {
- sb_reset_dsp ();
- DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
- }
-
- sb_dsp_command (0x42);
- sb_dsp_command ((unsigned char) ((dsp_current_speed >> 8) & 0xff));
- sb_dsp_command ((unsigned char) (dsp_current_speed & 0xff));
- sb_dsp_command ((unsigned char) (dsp_16bit ? 0xbe : 0xce));
- sb_dsp_command ((unsigned char) ((dsp_stereo ? 0x20 : 0) +
- (dsp_16bit ? 0x10 : 0)));
- sb_dsp_command01 ((unsigned char) (cnt & 0xff));
- sb_dsp_command ((unsigned char) (cnt >> 8));
-
- dsp_count = cnt;
- irq_mode = IMODE_INPUT;
- intr_active = 1;
- RESTORE_INTR (flags);
-}
-
-static int
-sb16_dsp_prepare_for_input (int dev, int bsize, int bcount)
-{
- audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8;
- dsp_count = 0;
- dsp_cleanup ();
- return 0;
-}
-
-static int
-sb16_dsp_prepare_for_output (int dev, int bsize, int bcount)
-{
- audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8;
- dsp_count = 0;
- dsp_cleanup ();
- return 0;
-}
-
-static void
-dsp_cleanup (void)
-{
- irq_mode = IMODE_NONE;
- intr_active = 0;
-}
-
-static void
-sb16_dsp_reset (int dev)
-{
- unsigned long flags;
-
- DISABLE_INTR (flags);
-
- sb_reset_dsp ();
- dsp_cleanup ();
-
- RESTORE_INTR (flags);
-}
-
-static void
-sb16_dsp_halt (int dev)
-{
- if (dsp_16bit)
- {
- sb_dsp_command01 (0xd9);
- sb_dsp_command01 (0xd5);
- }
- else
- {
- sb_dsp_command01 (0xda);
- sb_dsp_command01 (0xd0);
- }
- DMAbuf_reset_dma (dev);
-}
-
-static void
-set_irq_hw (int level)
-{
- int ival;
-
- switch (level)
- {
-#ifdef PC98
- case 5:
- ival = 8;
- break;
- case 3:
- ival = 1;
- break;
- case 10:
- ival = 2;
- break;
-#else
- case 5:
- ival = 2;
- break;
- case 7:
- ival = 4;
- break;
- case 9:
- ival = 1;
- break;
- case 10:
- ival = 8;
- break;
-#endif
- default:
- printk ("SB16_IRQ_LEVEL %d does not exist\n", level);
- return;
- }
- sb_setmixer (IRQ_NR, ival);
-}
-
-long
-sb16_dsp_init (long mem_start, struct address_info *hw_config)
-{
- if (sbc_major < 4)
- return mem_start; /* Not a SB16 */
-
- sprintf (sb16_dsp_operations.name, "SoundBlaster 16 %d.%d", sbc_major, sbc_minor);
-
-#if defined(__FreeBSD__)
- printk ("sbxvo0: <%s>", sb16_dsp_operations.name);
-#else
- printk (" <%s>", sb16_dsp_operations.name);
-#endif
-
- if (num_audiodevs < MAX_AUDIO_DEV)
- {
- audio_devs[my_dev = num_audiodevs++] = &sb16_dsp_operations;
- audio_devs[my_dev]->dmachan = hw_config->dma;
- audio_devs[my_dev]->buffcount = 1;
- audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
- }
- else
- printk ("SB: Too many DSP devices available\n");
- sb16_dsp_ok = 1;
- return mem_start;
-}
-
-int
-sb16_dsp_detect (struct address_info *hw_config)
-{
- struct address_info *sb_config;
-
- if (sb16_dsp_ok)
- return 1; /* Can't drive two cards */
-
- if (!(sb_config = sound_getconf (SNDCARD_SB)))
- {
- printk ("SB16 Error: Plain SB not configured\n");
- return 0;
- }
-
- /*
- * sb_setmixer(OPSW,0xf); if(sb_getmixer(OPSW)!=0xf) return 0;
- */
-
- if (!sb_reset_dsp ())
- return 0;
-
- if (sbc_major < 4) /* Set by the plain SB driver */
- return 0; /* Not a SB16 */
-
-#ifdef PC98
- hw_config->dma = sb_config->dma;
-#else
- if (hw_config->dma < 4)
- if (hw_config->dma != sb_config->dma)
- {
- printk ("SB16 Error: Invalid DMA channel %d/%d\n",
- sb_config->dma, hw_config->dma);
- return 0;
- }
-#endif
-
- dma16 = hw_config->dma;
- dma8 = sb_config->dma;
- set_irq_hw (sb_config->irq);
-#ifdef PC98
- sb_setmixer (DMA_NR, hw_config->dma == 0 ? 1 : 2);
-#else
- sb_setmixer (DMA_NR, (1 << hw_config->dma) | (1 << sb_config->dma));
-#endif
-
- DEB (printk ("SoundBlaster 16: IRQ %d DMA %d OK\n", sb_config->irq, hw_config->dma));
-
- /*
- * dsp_showmessage(0xe3,99);
- */
- sb16_dsp_ok = 1;
- return 1;
-}
-
-void
-sb16_dsp_interrupt (int unused)
-{
- int data;
-
- data = INB (DSP_DATA_AVL16); /*
- * Interrupt acknowledge
- */
-
- if (intr_active)
- switch (irq_mode)
- {
- case IMODE_OUTPUT:
- intr_active = 0;
- DMAbuf_outputintr (my_dev, 1);
- break;
-
- case IMODE_INPUT:
- intr_active = 0;
- DMAbuf_inputintr (my_dev);
- break;
-
- default:
- printk ("SoundBlaster: Unexpected interrupt\n");
- }
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/sb16_midi.c b/sys/pc98/pc98/sound/sb16_midi.c
deleted file mode 100644
index 7dae750..0000000
--- a/sys/pc98/pc98/sound/sb16_midi.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * sound/sb16_midi.c
- *
- * The low level driver for the MPU-401 UART emulation of the SB16.
- *
- * 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
-
-#if !defined(EXCLUDE_SB) && !defined(EXCLUDE_SB16) && !defined(EXCLUDE_MIDI)
-
-#include <i386/isa/sound/sb.h>
-
-#ifdef PC98
-#define DATAPORT (sb16midi_base)
-#define COMDPORT (sb16midi_base+0x100)
-#define STATPORT (sb16midi_base+0x100)
-#else
-#define DATAPORT (sb16midi_base)
-#define COMDPORT (sb16midi_base+1)
-#define STATPORT (sb16midi_base+1)
-#endif
-
-#define sb16midi_status() INB(STATPORT)
-#define input_avail() (!(sb16midi_status()&INPUT_AVAIL))
-#define output_ready() (!(sb16midi_status()&OUTPUT_READY))
-#define sb16midi_cmd(cmd) OUTB(cmd, COMDPORT)
-#define sb16midi_read() INB(DATAPORT)
-#define sb16midi_write(byte) OUTB(byte, DATAPORT)
-
-#define OUTPUT_READY 0x40
-#define INPUT_AVAIL 0x80
-#define MPU_ACK 0xFE
-#define MPU_RESET 0xFF
-#define UART_MODE_ON 0x3F
-
-extern int sbc_major;
-
-static int sb16midi_opened = 0;
-static int sb16midi_base = 0x330;
-static int sb16midi_detected = 0;
-static int my_dev;
-extern int sbc_base;
-
-static int reset_sb16midi (void);
-static void (*midi_input_intr) (int dev, unsigned char data);
-
-static void
-sb16midi_input_loop (void)
-{
- while (input_avail ())
- {
- unsigned char c = sb16midi_read ();
-
- if (sb16midi_opened & OPEN_READ)
- midi_input_intr (my_dev, c);
- }
-}
-
-void
-sb16midiintr (int unit)
-{
- if (input_avail ())
- sb16midi_input_loop ();
-}
-
-static int
-sb16midi_open (int dev, int mode,
- void (*input) (int dev, unsigned char data),
- void (*output) (int dev)
-)
-{
- if (sb16midi_opened)
- {
- return RET_ERROR (EBUSY);
- }
-
- sb16midi_input_loop ();
-
- midi_input_intr = input;
- sb16midi_opened = mode;
-
- return 0;
-}
-
-static void
-sb16midi_close (int dev)
-{
- sb16midi_opened = 0;
-}
-
-static int
-sb16midi_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 ())
- sb16midi_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 ("MPU-401: Timeout\n");
- return 0;
- }
-
- sb16midi_write (midi_byte);
- return 1;
-}
-
-static int
-sb16midi_start_read (int dev)
-{
- return 0;
-}
-
-static int
-sb16midi_end_read (int dev)
-{
- return 0;
-}
-
-static int
-sb16midi_ioctl (int dev, unsigned cmd, unsigned arg)
-{
- return RET_ERROR (EINVAL);
-}
-
-static void
-sb16midi_kick (int dev)
-{
-}
-
-static int
-sb16midi_buffer_status (int dev)
-{
- return 0; /*
- * No data in buffers
- */
-}
-
-#define MIDI_SYNTH_NAME "SoundBlaster 16 Midi"
-#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
-#include <i386/isa/sound/midi_synth.h>
-
-static struct midi_operations sb16midi_operations =
-{
- {"SoundBlaster 16 Midi", 0, 0, SNDCARD_SB16MIDI},
- &std_midi_synth,
- {0},
- sb16midi_open,
- sb16midi_close,
- sb16midi_ioctl,
- sb16midi_out,
- sb16midi_start_read,
- sb16midi_end_read,
- sb16midi_kick,
- NULL,
- sb16midi_buffer_status,
- NULL
-};
-
-
-long
-attach_sb16midi (long mem_start, struct address_info *hw_config)
-{
- int ok, timeout;
- unsigned long flags;
-
- sb16midi_base = hw_config->io_base;
-
- if (!sb16midi_detected)
- return RET_ERROR (EIO);
-
- DISABLE_INTR (flags);
- for (timeout = 30000; timeout < 0 && !output_ready (); timeout--); /*
- * Wait
- */
- sb16midi_cmd (UART_MODE_ON);
-
- ok = 0;
- for (timeout = 50000; timeout > 0 && !ok; timeout--)
- if (input_avail ())
- if (sb16midi_read () == MPU_ACK)
- ok = 1;
-
- RESTORE_INTR (flags);
-
- if (num_midis >= MAX_MIDI_DEV)
- {
- printk ("Sound: Too many midi devices detected\n");
- return mem_start;
- }
-
- printk (" <SoundBlaster MPU-401>");
-
- std_midi_synth.midi_dev = my_dev = num_midis;
- midi_devs[num_midis++] = &sb16midi_operations;
- return mem_start;
-}
-
-static int
-reset_sb16midi (void)
-{
- unsigned long flags;
- int ok, timeout, n;
-
- /*
- * Send the RESET command. Try again if no success at the first time.
- */
-
- ok = 0;
-
- DISABLE_INTR (flags);
-
- for (n = 0; n < 2 && !ok; n++)
- {
- for (timeout = 30000; timeout < 0 && !output_ready (); timeout--); /*
- * Wait
- */
- sb16midi_cmd (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 = 50000; timeout > 0 && !ok; timeout--)
- if (input_avail ())
- if (sb16midi_read () == MPU_ACK)
- ok = 1;
-
- }
-
- sb16midi_opened = 0;
- if (ok)
- sb16midi_input_loop (); /*
- * Flush input before enabling interrupts
- */
-
- RESTORE_INTR (flags);
-
- return ok;
-}
-
-
-int
-probe_sb16midi (struct address_info *hw_config)
-{
- int ok = 0;
-
- if (sbc_major < 4)
- return 0; /* Not a SB16 */
-
- sb16midi_base = hw_config->io_base;
-
- if (sb_get_irq () < 0)
- return 0;
-
- ok = reset_sb16midi ();
-
- sb16midi_detected = ok;
- return ok;
-}
-
-#endif
-
-#endif
diff --git a/sys/pc98/pc98/sound/sb_dsp.c b/sys/pc98/pc98/sound/sb_dsp.c
deleted file mode 100644
index 82a2178..0000000
--- a/sys/pc98/pc98/sound/sb_dsp.c
+++ /dev/null
@@ -1,1252 +0,0 @@
-/*
- * sound/sb_dsp.c
- *
- * The low level driver for the SoundBlaster DSP chip (SB1.0 to 2.1, SB Pro).
- *
- * 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 Sound Galaxy NX Pro
- *
- * JRA Gibson April 1995
- * Code added for MV ProSonic/Jazz 16 in 16 bit mode
- */
-
-#include <i386/isa/sound/sound_config.h>
-
-#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
-
-#include <i386/isa/sound/sb.h>
-#include <i386/isa/sound/sb_mixer.h>
-#undef SB_TEST_IRQ
-
-int sbc_base = 0;
-static int sbc_irq = 0;
-static int open_mode = 0; /* Read, write or both */
-int Jazz16_detected = 0;
-
-/*
- * 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.
- */
-
-int sb_dsp_ok = 0; /*
-
-
- * * * * Set to 1 after successful
- * initialization * */
-static int midi_disabled = 0;
-int sb_dsp_highspeed = 0;
-int sbc_major = 1, sbc_minor = 0; /*
-
-
- * * * * DSP version */
-static int dsp_stereo = 0;
-static int dsp_current_speed = DSP_DEFAULT_SPEED;
-static int sb16 = 0;
-static int irq_verified = 0;
-
-int sb_midi_mode = NORMAL_MIDI;
-int sb_midi_busy = 0; /*
-
-
- * * * * 1 if the process has output
- * to * * MIDI */
-int sb_dsp_busy = 0;
-
-volatile int sb_irq_mode = IMODE_NONE; /*
-
-
- * * * * IMODE_INPUT, *
- * IMODE_OUTPUT * * or *
- * IMODE_NONE */
-static volatile int irq_ok = 0;
-
-#ifdef JAZZ16
-/* 16 bit support
- */
-
-static int dsp_16bit = 0;
-static int dma8 = 1;
-static int dma16 = 5;
-
-static int dsp_set_bits (int arg);
-static int initialize_ProSonic16 (void);
-
-/* end of 16 bit support
- */
-#endif
-
-int sb_duplex_midi = 0;
-static int my_dev = 0;
-
-volatile int sb_intr_active = 0;
-
-static int dsp_speed (int);
-static int dsp_set_stereo (int mode);
-
-#if !defined(EXCLUDE_MIDI) || !defined(EXCLUDE_AUDIO)
-
-/*
- * Common code for the midi and pcm functions
- */
-
-int
-sb_dsp_command (unsigned char val)
-{
- int i;
- unsigned long limit;
-
- limit = GET_TIME () + HZ / 10; /*
- * The timeout is 0.1 secods
- */
-
- /*
- * Note! the i<500000 is an emergency exit. The sb_dsp_command() is sometimes
- * called while interrupts are disabled. This means that the timer is
- * disabled also. However the timeout situation is a abnormal condition.
- * Normally the DSP should be ready to accept commands after just couple of
- * loops.
- */
-
- for (i = 0; i < 500000 && GET_TIME () < limit; i++)
- {
- if ((INB (DSP_STATUS) & 0x80) == 0)
- {
- OUTB (val, DSP_COMMAND);
- return 1;
- }
- }
-
- printk ("SoundBlaster: DSP Command(%x) Timeout.\n", val);
- printk ("IRQ conflict???\n");
- return 0;
-}
-
-void
-sbintr (INT_HANDLER_PARMS (irq, dummy))
-{
- int status;
-
-#ifndef EXCLUDE_SBPRO
- if (sb16)
- {
- unsigned char src = sb_getmixer (IRQ_STAT); /* Interrupt source register */
-
-#ifndef EXCLUDE_SB16
- if (src & 3)
- sb16_dsp_interrupt (irq);
-
-#ifndef EXCLUDE_MIDI
- if (src & 4)
- sb16midiintr (irq); /*
- * SB MPU401 interrupt
- */
-#endif
-
-#endif
-
- if (!(src & 1))
- return; /*
- * Not a DSP interupt
- */
- }
-#endif
-
- status = INB (DSP_DATA_AVAIL); /*
- * Clear interrupt
- */
-
- if (sb_intr_active)
- switch (sb_irq_mode)
- {
- case IMODE_OUTPUT:
- sb_intr_active = 0;
- DMAbuf_outputintr (my_dev, 1);
- break;
-
- case IMODE_INPUT:
- sb_intr_active = 0;
- DMAbuf_inputintr (my_dev);
- /*
- * A complete buffer has been input. Let's start new one
- */
- break;
-
- case IMODE_INIT:
- sb_intr_active = 0;
- irq_ok = 1;
- break;
-
- case IMODE_MIDI:
-#ifndef EXCLUDE_MIDI
- sb_midi_interrupt (irq);
-#endif
- break;
-
- default:
- printk ("SoundBlaster: Unexpected interrupt\n");
- }
-}
-
-static int sb_irq_usecount = 0;
-
-int
-sb_get_irq (void)
-{
- int ok;
-
- if (!sb_irq_usecount)
- if ((ok = snd_set_irq_handler (sbc_irq, sbintr, "SoundBlaster")) < 0)
- return ok;
-
- sb_irq_usecount++;
-
- return 0;
-}
-
-void
-sb_free_irq (void)
-{
- if (!sb_irq_usecount)
- return;
-
- sb_irq_usecount--;
-
- if (!sb_irq_usecount)
- snd_release_irq (sbc_irq);
-}
-
-int
-sb_reset_dsp (void)
-{
- int loopc;
-
- OUTB (1, DSP_RESET);
- tenmicrosec ();
- OUTB (0, DSP_RESET);
- tenmicrosec ();
- tenmicrosec ();
- tenmicrosec ();
-
- for (loopc = 0; loopc < 1000 && !(INB (DSP_DATA_AVAIL) & 0x80); loopc++); /*
- * Wait
- * for
- * data
- * *
- * available
- * status
- */
-
- if (INB (DSP_READ) != 0xAA)
- return 0; /*
- * Sorry
- */
-
- return 1;
-}
-
-#endif
-
-#ifndef EXCLUDE_AUDIO
-
-static void
-dsp_speaker (char state)
-{
- if (state)
- sb_dsp_command (DSP_CMD_SPKON);
- else
- sb_dsp_command (DSP_CMD_SPKOFF);
-}
-
-static int
-dsp_speed (int speed)
-{
- unsigned char tconst;
- unsigned long flags;
- int max_speed = 44100;
-
- if (speed < 4000)
- speed = 4000;
-
- /*
- * Older SB models don't support higher speeds than 22050.
- */
-
- if (sbc_major < 2 ||
- (sbc_major == 2 && sbc_minor == 0))
- max_speed = 22050;
-
- /*
- * SB models earlier than SB Pro have low limit for the input speed.
- */
- if (open_mode != OPEN_WRITE) /* Recording is possible */
- if (sbc_major < 3) /* Limited input speed with these cards */
- if (sbc_major == 2 && sbc_minor > 0)
- max_speed = 15000;
- else
- max_speed = 13000;
-
- if (speed > max_speed)
- speed = max_speed; /*
- * Invalid speed
- */
-
- /* Logitech SoundMan Games and Jazz16 cards can support 44.1kHz stereo */
-#if !defined (SM_GAMES)
- /*
- * Max. stereo speed is 22050
- */
- if (dsp_stereo && speed > 22050 && Jazz16_detected == 0)
- speed = 22050;
-#endif
-
- if ((speed > 22050) && sb_midi_busy)
- {
- printk ("SB Warning: High speed DSP not possible simultaneously with MIDI output\n");
- speed = 22050;
- }
-
- if (dsp_stereo)
- speed *= 2;
-
- /*
- * Now the speed should be valid
- */
-
- if (speed > 22050)
- { /*
- * High speed mode
- */
- int tmp;
-
- tconst = (unsigned char) ((65536 -
- ((256000000 + speed / 2) / speed)) >> 8);
- sb_dsp_highspeed = 1;
-
- DISABLE_INTR (flags);
- if (sb_dsp_command (0x40))
- sb_dsp_command (tconst);
- RESTORE_INTR (flags);
-
- tmp = 65536 - (tconst << 8);
- speed = (256000000 + tmp / 2) / tmp;
- }
- else
- {
- int tmp;
-
- sb_dsp_highspeed = 0;
- tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff;
-
- DISABLE_INTR (flags);
- if (sb_dsp_command (0x40)) /*
- * Set time constant
- */
- sb_dsp_command (tconst);
- RESTORE_INTR (flags);
-
- tmp = 256 - tconst;
- speed = (1000000 + tmp / 2) / tmp;
- }
-
- if (dsp_stereo)
- speed /= 2;
-
- dsp_current_speed = speed;
- return speed;
-}
-
-static int
-dsp_set_stereo (int mode)
-{
- dsp_stereo = 0;
-
-#ifdef EXCLUDE_SBPRO
- return 0;
-#else
- if (sbc_major < 3 || sb16)
- return 0; /*
- * Sorry no stereo
- */
-
- if (mode && sb_midi_busy)
- {
- printk ("SB Warning: Stereo DSP not possible simultaneously with MIDI output\n");
- return 0;
- }
-
- dsp_stereo = !!mode;
- return dsp_stereo;
-#endif
-}
-
-static void
-sb_dsp_output_block (int dev, unsigned long buf, int count,
- int intrflag, int restart_dma)
-{
- unsigned long flags;
-
- if (!sb_irq_mode)
- dsp_speaker (ON);
-
- sb_irq_mode = IMODE_OUTPUT;
- DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
-
- if (audio_devs[dev]->dmachan > 3)
- count >>= 1;
- count--;
-
- if (sb_dsp_highspeed)
- {
- DISABLE_INTR (flags);
- if (sb_dsp_command (0x48)) /*
- * High speed size
- */
- {
- sb_dsp_command ((unsigned char) (count & 0xff));
- sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
- sb_dsp_command (0x91); /*
- * High speed 8 bit DAC
- */
- }
- else
- printk ("SB Error: Unable to start (high speed) DAC\n");
- RESTORE_INTR (flags);
- }
- else
- {
- DISABLE_INTR (flags);
- if (sb_dsp_command (0x14)) /*
- * 8-bit DAC (DMA)
- */
- {
- sb_dsp_command ((unsigned char) (count & 0xff));
- sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
- }
- else
- printk ("SB Error: Unable to start DAC\n");
- RESTORE_INTR (flags);
- }
- sb_intr_active = 1;
-}
-
-static void
-sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag,
- int restart_dma)
-{
- /*
- * Start a DMA input to the buffer pointed by dmaqtail
- */
-
- unsigned long flags;
-
- if (!sb_irq_mode)
- dsp_speaker (OFF);
-
- sb_irq_mode = IMODE_INPUT;
- DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
-
- if (audio_devs[dev]->dmachan > 3)
- count >>= 1;
- count--;
-
- if (sb_dsp_highspeed)
- {
- DISABLE_INTR (flags);
- if (sb_dsp_command (0x48)) /*
- * High speed size
- */
- {
- sb_dsp_command ((unsigned char) (count & 0xff));
- sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
- sb_dsp_command (0x99); /*
- * High speed 8 bit ADC
- */
- }
- else
- printk ("SB Error: Unable to start (high speed) ADC\n");
- RESTORE_INTR (flags);
- }
- else
- {
- DISABLE_INTR (flags);
- if (sb_dsp_command (0x24)) /*
- * 8-bit ADC (DMA)
- */
- {
- sb_dsp_command ((unsigned char) (count & 0xff));
- sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
- }
- else
- printk ("SB Error: Unable to start ADC\n");
- RESTORE_INTR (flags);
- }
-
- sb_intr_active = 1;
-}
-
-static void
-dsp_cleanup (void)
-{
- sb_intr_active = 0;
-}
-
-static int
-sb_dsp_prepare_for_input (int dev, int bsize, int bcount)
-{
- dsp_cleanup ();
- dsp_speaker (OFF);
-
- if (sbc_major == 3) /*
- * SB Pro
- */
- {
-#ifdef JAZZ16
- /* Select correct dma channel
- * for 16/8 bit acccess
- */
- audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8;
- if (dsp_stereo)
- sb_dsp_command (dsp_16bit ? 0xac : 0xa8);
- else
- sb_dsp_command (dsp_16bit ? 0xa4 : 0xa0);
-#else
- /* 8 bit only cards use this
- */
- if (dsp_stereo)
- sb_dsp_command (0xa8);
- else
- sb_dsp_command (0xa0);
-#endif
- dsp_speed (dsp_current_speed); /*
- * Speed must be recalculated if
- * #channels * changes
- */
- }
- return 0;
-}
-
-static int
-sb_dsp_prepare_for_output (int dev, int bsize, int bcount)
-{
- dsp_cleanup ();
- dsp_speaker (ON);
-
-#ifndef EXCLUDE_SBPRO
- if (sbc_major == 3) /*
- * SB Pro
- */
- {
-#ifdef JAZZ16
- /* 16 bit specific instructions
- */
- audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8;
- if (Jazz16_detected != 2) /* SM Wave */
- sb_mixer_set_stereo (dsp_stereo);
- if (dsp_stereo)
- sb_dsp_command (dsp_16bit ? 0xac : 0xa8);
- else
- sb_dsp_command (dsp_16bit ? 0xa4 : 0xa0);
-#else
- sb_mixer_set_stereo (dsp_stereo);
-#endif
- dsp_speed (dsp_current_speed); /*
- * Speed must be recalculated if
- * #channels * changes
- */
- }
-#endif
- return 0;
-}
-
-static void
-sb_dsp_halt_xfer (int dev)
-{
-}
-
-static int
-verify_irq (void)
-{
-#if 0
- DEFINE_WAIT_QUEUE (testq, testf);
-
- irq_ok = 0;
-
- if (sb_get_irq () == -1)
- {
- printk ("*** SB Error: Irq %d already in use\n", sbc_irq);
- return 0;
- }
-
-
- sb_irq_mode = IMODE_INIT;
-
- sb_dsp_command (0xf2); /*
- * This should cause immediate interrupt
- */
-
- DO_SLEEP (testq, testf, HZ / 5);
-
- sb_free_irq ();
-
- if (!irq_ok)
- {
- printk ("SB Warning: IRQ%d test not passed!", sbc_irq);
- irq_ok = 1;
- }
-#else
- irq_ok = 1;
-#endif
- return irq_ok;
-}
-
-static int
-sb_dsp_open (int dev, int mode)
-{
- int retval;
-
- if (!sb_dsp_ok)
- {
- printk ("SB Error: SoundBlaster board not installed\n");
- return RET_ERROR (ENXIO);
- }
-
- if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI))
- {
- printk ("SB: PCM not possible during MIDI input\n");
- return RET_ERROR (EBUSY);
- }
-
- if (!irq_verified)
- {
- verify_irq ();
- irq_verified = 1;
- }
- else if (!irq_ok)
- printk ("SB Warning: Incorrect IRQ setting %d\n",
- sbc_irq);
-
- retval = sb_get_irq ();
- if (retval)
- return retval;
-
- /* Allocate 8 bit dma
- */
- if (DMAbuf_open_dma (dev) < 0)
- {
- sb_free_irq ();
- printk ("SB: DMA Busy\n");
- return RET_ERROR (EBUSY);
- }
-#ifdef JAZZ16
- /* Allocate 16 bit dma
- */
- if (Jazz16_detected != 0)
- if (dma16 != dma8)
- {
- if (ALLOC_DMA_CHN (dma16, "Jazz16 16 bit"))
- {
- sb_free_irq ();
- RELEASE_DMA_CHN (dma8);
- return RET_ERROR (EBUSY);
- }
- }
-#endif
-
- sb_irq_mode = IMODE_NONE;
-
- sb_dsp_busy = 1;
- open_mode = mode;
-
- return 0;
-}
-
-static void
-sb_dsp_close (int dev)
-{
-#ifdef JAZZ16
- /* Release 16 bit dma channel
- */
- if (Jazz16_detected)
- RELEASE_DMA_CHN (dma16);
-#endif
-
- DMAbuf_close_dma (dev);
- sb_free_irq ();
- dsp_cleanup ();
- dsp_speaker (OFF);
- sb_dsp_busy = 0;
- sb_dsp_highspeed = 0;
- open_mode = 0;
-}
-
-#ifdef JAZZ16
-/* Function dsp_set_bits() only required for 16 bit cards
- */
-static int
-dsp_set_bits (int arg)
-{
- if (arg)
- if (Jazz16_detected == 0)
- dsp_16bit = 0;
- else
- switch (arg)
- {
- case 8:
- dsp_16bit = 0;
- break;
- case 16:
- dsp_16bit = 1;
- break;
- default:
- dsp_16bit = 0;
- }
- return dsp_16bit ? 16 : 8;
-}
-
-#endif /* ifdef JAZZ16 */
-
-static int
-sb_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
-{
- switch (cmd)
- {
- case SOUND_PCM_WRITE_RATE:
- if (local)
- return dsp_speed (arg);
- return IOCTL_OUT (arg, dsp_speed (IOCTL_IN (arg)));
- break;
-
- case SOUND_PCM_READ_RATE:
- if (local)
- return dsp_current_speed;
- return IOCTL_OUT (arg, dsp_current_speed);
- break;
-
- case SOUND_PCM_WRITE_CHANNELS:
- if (local)
- return dsp_set_stereo (arg - 1) + 1;
- return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);
- break;
-
- case SOUND_PCM_READ_CHANNELS:
- if (local)
- return dsp_stereo + 1;
- return IOCTL_OUT (arg, dsp_stereo + 1);
- break;
-
- case SNDCTL_DSP_STEREO:
- if (local)
- return dsp_set_stereo (arg);
- return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg)));
- break;
-
-#ifdef JAZZ16
- /* Word size specific cases here.
- * SNDCTL_DSP_SETFMT=SOUND_PCM_WRITE_BITS
- */
- case SNDCTL_DSP_SETFMT:
- if (local)
- return dsp_set_bits (arg);
- return IOCTL_OUT (arg, dsp_set_bits (IOCTL_IN (arg)));
- break;
-
- case SOUND_PCM_READ_BITS:
- if (local)
- return dsp_16bit ? 16 : 8;
- return IOCTL_OUT (arg, dsp_16bit ? 16 : 8);
- break;
-#else
- case SOUND_PCM_WRITE_BITS:
- case SOUND_PCM_READ_BITS:
- if (local)
- return 8;
- return IOCTL_OUT (arg, 8); /*
- * Only 8 bits/sample supported
- */
- break;
-#endif /* ifdef JAZZ16 */
-
- case SOUND_PCM_WRITE_FILTER:
- case SOUND_PCM_READ_FILTER:
- return RET_ERROR (EINVAL);
- break;
-
- default:
- return RET_ERROR (EINVAL);
- }
-
- return RET_ERROR (EINVAL);
-}
-
-static void
-sb_dsp_reset (int dev)
-{
- unsigned long flags;
-
- DISABLE_INTR (flags);
-
- sb_reset_dsp ();
- dsp_speed (dsp_current_speed);
- dsp_cleanup ();
-
- RESTORE_INTR (flags);
-}
-
-#endif
-
-
-#ifdef JAZZ16
-
-/*
- * Initialization of a Media Vision ProSonic 16 Soundcard.
- * The function initializes a ProSonic 16 like PROS.EXE does for DOS. It sets
- * the base address, the DMA-channels, interrupts and enables the joystickport.
- *
- * Also used by Jazz 16 (same card, different name)
- *
- * written 1994 by Rainer Vranken
- * E-Mail: rvranken@polaris.informatik.uni-essen.de
- */
-
-
-#ifndef MPU_BASE /* take default values if not specified */
-#define MPU_BASE 0x330
-#endif
-#ifndef MPU_IRQ
-#define MPU_IRQ 9
-#endif
-
-unsigned int
-get_sb_byte (void)
-{
- int i;
-
- for (i = 1000; i; i--)
- if (INB (DSP_DATA_AVAIL) & 0x80)
- {
- return INB (DSP_READ);
- }
-
- return 0xffff;
-}
-
-#ifdef SM_WAVE
-/*
- * Logitech Soundman Wave detection and initialization by Hannu Savolainen.
- *
- * There is a microcontroller (8031) in the SM Wave card for MIDI emulation.
- * it's located at address MPU_BASE+4. MPU_BASE+7 is a SM Wave specific
- * control register for MC reset, SCSI, OPL4 and DSP (future expansion)
- * address decoding. Otherwise the SM Wave is just a ordinary MV Jazz16
- * based soundcard.
- */
-
-static void
-smw_putmem (int base, int addr, unsigned char val)
-{
- unsigned long flags;
-
- DISABLE_INTR (flags);
-
- OUTB (addr & 0xff, base + 1); /* Low address bits */
- OUTB (addr >> 8, base + 2); /* High address bits */
- OUTB (val, base); /* Data */
-
- RESTORE_INTR (flags);
-}
-
-static unsigned char
-smw_getmem (int base, int addr)
-{
- unsigned long flags;
- unsigned char val;
-
- DISABLE_INTR (flags);
-
- OUTB (addr & 0xff, base + 1); /* Low address bits */
- OUTB (addr >> 8, base + 2); /* High address bits */
- val = INB (base); /* Data */
-
- RESTORE_INTR (flags);
- return val;
-}
-
-static int
-initialize_smw (void)
-{
-#ifdef SMW_MIDI0001_INCLUDED
-#include <i386/isa/sound/smw-midi0001.h>
-#else
- unsigned char smw_ucode[1];
- int smw_ucodeLen = 0;
-
-#endif
-
- int mp_base = MPU_BASE + 4; /* Microcontroller base */
- int i;
- unsigned char control;
-
- /*
- * Reset the microcontroller so that the RAM can be accessed
- */
-
- control = INB (MPU_BASE + 7);
- OUTB (control | 3, MPU_BASE + 7); /* Set last two bits to 1 (?) */
- OUTB ((control & 0xfe) | 2, MPU_BASE + 7); /* xxxxxxx0 resets the mc */
-
- for (i = 0; i < 300; i++) /* Wait at least 1ms */
- tenmicrosec ();
-
- OUTB (control & 0xfc, MPU_BASE + 7); /* xxxxxx00 enables RAM */
-
- /*
- * Detect microcontroller by probing the 8k RAM area
- */
- smw_putmem (mp_base, 0, 0x00);
- smw_putmem (mp_base, 1, 0xff);
- tenmicrosec ();
-
- if (smw_getmem (mp_base, 0) != 0x00 || smw_getmem (mp_base, 1) != 0xff)
- {
- printk ("\nSM Wave: No microcontroller RAM detected (%02x, %02x)\n",
- smw_getmem (mp_base, 0), smw_getmem (mp_base, 1));
- return 0; /* No RAM */
- }
-
- /*
- * There is RAM so assume it's really a SM Wave
- */
-
-#ifdef SMW_MIDI0001_INCLUDED
- if (smw_ucodeLen != 8192)
- {
- printk ("\nSM Wave: Invalid microcode (MIDI0001.BIN) length\n");
- return 1;
- }
-#endif
-
- /*
- * Download microcode
- */
-
- for (i = 0; i < 8192; i++)
- smw_putmem (mp_base, i, smw_ucode[i]);
-
- /*
- * Verify microcode
- */
-
- for (i = 0; i < 8192; i++)
- if (smw_getmem (mp_base, i) != smw_ucode[i])
- {
- printk ("SM Wave: Microcode verification failed\n");
- return 0;
- }
-
- control = 0;
-#ifdef SMW_SCSI_IRQ
- /*
- * Set the SCSI interrupt (IRQ2/9, IRQ3 or IRQ10). The SCSI interrupt
- * is disabled by default.
- *
- * Btw the Zilog 5380 SCSI controller is located at MPU base + 0x10.
- */
- {
- static unsigned char scsi_irq_bits[] =
- {0, 0, 3, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0};
-
- control |= scsi_irq_bits[SMW_SCSI_IRQ] << 6;
- }
-#endif
-
-#ifdef SMW_OPL4_ENABLE
- /*
- * Make the OPL4 chip visible on the PC bus at 0x380.
- *
- * There is no need to enable this feature since VoxWare
- * doesn't support OPL4 yet. Also there is no RAM in SM Wave so
- * enabling OPL4 is pretty useless.
- */
- control |= 0x10; /* Uses IRQ12 if bit 0x20 == 0 */
- /* control |= 0x20; Uncomment this if you want to use IRQ7 */
-#endif
-
- OUTB (control | 0x03, MPU_BASE + 7); /* xxxxxx11 restarts */
- return 1;
-}
-
-#endif
-
-static int
-initialize_ProSonic16 (void)
-{
- int x;
- static unsigned char int_translat[16] =
- {0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6}, dma_translat[8] =
- {0, 1, 0, 2, 0, 3, 0, 4};
-
- OUTB (0xAF, 0x201); /* ProSonic/Jazz16 wakeup */
- for (x = 0; x < 1000; ++x) /* wait 10 milliseconds */
- tenmicrosec ();
- OUTB (0x50, 0x201);
- OUTB ((sbc_base & 0x70) | ((MPU_BASE & 0x30) >> 4), 0x201);
-
- if (sb_reset_dsp ())
- { /* OK. We have at least a SB */
-
- /* Check the version number of ProSonic (I guess) */
-
- if (!sb_dsp_command (0xFA))
- return 1;
- if (get_sb_byte () != 0x12)
- return 1;
-
- if (sb_dsp_command (0xFB) && /* set DMA-channels and Interrupts */
- sb_dsp_command ((dma_translat[JAZZ_DMA16] << 4) | dma_translat[SBC_DMA]) &&
- sb_dsp_command ((int_translat[MPU_IRQ] << 4) | int_translat[sbc_irq]))
- {
- Jazz16_detected = 1;
-#ifdef SM_WAVE
- if (initialize_smw ())
- Jazz16_detected = 2;
-#endif
- sb_dsp_disable_midi ();
- }
-
- return 1; /* There was at least a SB */
- }
- return 0; /* No SB or ProSonic16 detected */
-}
-
-#endif /* ifdef JAZZ16 */
-
-int
-sb_dsp_detect (struct address_info *hw_config)
-{
- sbc_base = hw_config->io_base;
- sbc_irq = hw_config->irq;
-
- if (sb_dsp_ok)
- return 0; /*
- * Already initialized
- */
-#ifdef JAZZ16
- dma8 = hw_config->dma;
- dma16 = JAZZ_DMA16;
-
- if (!initialize_ProSonic16 ())
- return 0;
-#else
- if (!sb_reset_dsp ())
- return 0;
-#endif
-
-#ifdef PC98
- switch (sbc_irq)
- {
- case 3:
- sb_setmixer (IRQ_NR, 1);
- break;
- case 5:
- sb_setmixer (IRQ_NR, 8);
- break;
- case 10:
- sb_setmixer (IRQ_NR, 2);
- break;
- }
- switch (hw_config->dma)
- {
- case 0:
- sb_setmixer (DMA_NR, 1);
- break;
- case 3:
- sb_setmixer (DMA_NR, 2);
- break;
- }
-#endif
-
- return 1; /*
- * Detected
- */
-}
-
-#ifndef EXCLUDE_AUDIO
-static struct audio_operations sb_dsp_operations =
-{
- "SoundBlaster",
- NOTHING_SPECIAL,
- AFMT_U8, /* Just 8 bits. Poor old SB */
- NULL,
- sb_dsp_open,
- sb_dsp_close,
- sb_dsp_output_block,
- sb_dsp_start_input,
- sb_dsp_ioctl,
- sb_dsp_prepare_for_input,
- sb_dsp_prepare_for_output,
- sb_dsp_reset,
- sb_dsp_halt_xfer,
- NULL, /* local_qlen */
- NULL /* copy_from_user */
-};
-
-#endif
-
-long
-sb_dsp_init (long mem_start, struct address_info *hw_config)
-{
- int i;
- int mixer_type = 0;
-
- sbc_major = sbc_minor = 0;
- sb_dsp_command (0xe1); /*
- * Get version
- */
-
- for (i = 1000; i; i--)
- {
- if (INB (DSP_DATA_AVAIL) & 0x80)
- { /*
- * wait for Data Ready
- */
- if (sbc_major == 0)
- sbc_major = INB (DSP_READ);
- else
- {
- sbc_minor = INB (DSP_READ);
- break;
- }
- }
- }
-
- if (sbc_major == 2 || sbc_major == 3)
- sb_duplex_midi = 1;
-
- if (sbc_major == 4)
- sb16 = 1;
-
-#ifndef EXCLUDE_SBPRO
- if (sbc_major >= 3)
- mixer_type = sb_mixer_init (sbc_major);
-#else
- if (sbc_major >= 3)
- printk ("\n\n\n\nNOTE! SB Pro support is required with your soundcard!\n\n\n");
-#endif
-
-#ifndef EXCLUDE_YM3812
-
-#ifdef PC98
- if (sbc_major > 3 ||
- (sbc_major == 3 && INB (0x28d2) == 0x00))
-#else
- if (sbc_major > 3 ||
- (sbc_major == 3 && INB (0x388) == 0x00)) /* Should be 0x06 if not OPL-3 */
-#endif
- enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);
-#endif
-
-#ifndef EXCLUDE_AUDIO
- if (sbc_major >= 3)
- {
- if (Jazz16_detected)
- {
- if (Jazz16_detected == 2)
- sprintf (sb_dsp_operations.name, "SoundMan Wave %d.%d", sbc_major, sbc_minor);
- else
- sprintf (sb_dsp_operations.name, "MV Jazz16 %d.%d", sbc_major, sbc_minor);
- sb_dsp_operations.format_mask |= AFMT_S16_LE; /* Hurrah, 16 bits */
- }
- else
-#ifdef __SGNXPRO__
- if (mixer_type == 2)
- {
- sprintf (sb_dsp_operations.name, "Sound Galaxy NX Pro %d.%d", sbc_major, sbc_minor);
- }
- else
-#endif
-
- if (sbc_major == 4)
- {
- sprintf (sb_dsp_operations.name, "SoundBlaster 16 %d.%d", sbc_major, sbc_minor);
- }
- else
- {
- sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", sbc_major, sbc_minor);
- }
- }
- else
- {
- sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", sbc_major, sbc_minor);
- }
-
-#if defined(__FreeBSD__)
- printk ("sb0: <%s>", sb_dsp_operations.name);
-#else
- printk (" <%s>", sb_dsp_operations.name);
-#endif
-
-#if !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SBPRO)
- if (!sb16) /*
- * There is a better driver for SB16
- */
-#endif
- if (num_audiodevs < MAX_AUDIO_DEV)
- {
- audio_devs[my_dev = num_audiodevs++] = &sb_dsp_operations;
- audio_devs[my_dev]->buffcount = DSP_BUFFCOUNT;
- audio_devs[my_dev]->buffsize = (
- (sbc_major > 2 || sbc_major == 2 && sbc_minor > 0) ?
- 16 : 8) * 1024;
- audio_devs[my_dev]->dmachan = hw_config->dma;
- }
- else
- printk ("SB: Too many DSP devices available\n");
-#else
- printk (" <SoundBlaster (configured without audio support)>");
-#endif
-
-#ifndef EXCLUDE_MIDI
- if (!midi_disabled && !sb16) /*
- * Midi don't work in the SB emulation mode *
- * of PAS, SB16 has better midi interface
- */
- sb_midi_init (sbc_major);
-#endif
-
- sb_dsp_ok = 1;
- return mem_start;
-}
-
-void
-sb_dsp_disable_midi (void)
-{
- midi_disabled = 1;
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/sound_config.h b/sys/pc98/pc98/sound/sound_config.h
deleted file mode 100644
index a714c33..0000000
--- a/sys/pc98/pc98/sound/sound_config.h
+++ /dev/null
@@ -1,384 +0,0 @@
-/* sound_config.h
- *
- * A driver for Soundcards, misc configuration parameters.
- *
- *
- * 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/local.h>
-#else
-#include <i386/isa/sound/local.h>
-#endif
-#include <i386/isa/sound/os.h>
-#include <i386/isa/sound/soundvers.h>
-
-#if !defined(PSS_MPU_BASE) && defined(EXCLUDE_SSCAPE) && defined(EXCLUDE_TRIX)
-#define EXCLUDE_MPU_EMU
-#endif
-
-#if defined(ISC) || defined(SCO) || defined(SVR42)
-#define GENERIC_SYSV
-#endif
-
-/*
- * Disable the AD1848 driver if there are no other drivers requiring it.
- */
-
-#if defined(EXCLUDE_GUS16) && defined(EXCLUDE_MSS) && defined(EXCLUDE_PSS) && defined(EXCLUDE_GUSMAX) && defined(EXCLUDE_SSCAPE) && defined(EXCLUDE_TRIX)
-#define EXCLUDE_AD1848
-#endif
-
-#ifdef PSS_MSS_BASE
-#undef EXCLUDE_AD1848
-#endif
-
-#undef CONFIGURE_SOUNDCARD
-#undef DYNAMIC_BUFFER
-
-#ifdef KERNEL_SOUNDCARD
-#define CONFIGURE_SOUNDCARD
-#define DYNAMIC_BUFFER
-#undef LOADABLE_SOUNDCARD
-#endif
-
-#ifdef EXCLUDE_SEQUENCER
-#define EXCLUDE_MIDI
-#define EXCLUDE_YM3812
-#define EXCLUDE_OPL3
-#endif
-
-#ifndef SND_DEFAULT_ENABLE
-#define SND_DEFAULT_ENABLE 1
-#endif
-
-#ifdef CONFIGURE_SOUNDCARD
-
-/* ****** IO-address, DMA and IRQ settings ****
-
-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
-#endif
-
-#ifndef PAS_IRQ
-#define PAS_IRQ 5
-#endif
-
-#ifndef PAS_DMA
-#define PAS_DMA 3
-#endif
-
-#ifndef GUS_BASE
-#define GUS_BASE 0x220
-#endif
-
-#ifndef GUS_IRQ
-#define GUS_IRQ 15
-#endif
-
-#ifndef GUS_MIDI_IRQ
-#define GUS_MIDI_IRQ GUS_IRQ
-#endif
-
-#ifndef GUS_DMA
-#define GUS_DMA 6
-#endif
-
-#ifndef GUS_DMA_READ
-#define GUS_DMA_READ 3
-#endif
-
-#ifndef MPU_BASE
-#define MPU_BASE 0x330
-#endif
-
-#ifndef MPU_IRQ
-#define MPU_IRQ 6
-#endif
-
-/* Echo Personal Sound System */
-#ifndef PSS_BASE
-#define PSS_BASE 0x220 /* 0x240 or */
-#endif
-
-#ifndef PSS_IRQ
-#define PSS_IRQ 7
-#endif
-
-#ifndef PSS_DMA
-#define PSS_DMA 1
-#endif
-
-#ifndef MSS_BASE
-#define MSS_BASE 0
-#endif
-
-#ifndef MSS_DMA
-#define MSS_DMA 0
-#endif
-
-#ifndef MSS_IRQ
-#define MSS_IRQ 0
-#endif
-
-#ifndef GUS16_BASE
-#define GUS16_BASE 0
-#endif
-
-#ifndef GUS16_DMA
-#define GUS16_DMA 0
-#endif
-
-#ifndef GUS16_IRQ
-#define GUS16_IRQ 0
-#endif
-
-#ifndef SSCAPE_BASE
-#define SSCAPE_BASE 0
-#endif
-
-#ifndef SSCAPE_DMA
-#define SSCAPE_DMA 0
-#endif
-
-#ifndef SSCAPE_IRQ
-#define SSCAPE_IRQ 0
-#endif
-
-#ifndef SSCAPE_MSS_BASE
-#define SSCAPE_MSS_BASE 0
-#endif
-
-#ifndef SSCAPE_MSS_DMA
-#define SSCAPE_MSS_DMA 0
-#endif
-
-#ifndef SSCAPE_MSS_IRQ
-#define SSCAPE_MSS_IRQ 0
-#endif
-
-#ifndef TRIX_BASE
-#define TRIX_BASE 0x530
-#endif
-
-#ifndef TRIX_IRQ
-#define TRIX_IRQ 10
-#endif
-
-#ifndef TRIX_DMA
-#define TRIX_DMA 1
-#endif
-
-#ifndef U6850_BASE
-#define U6850_BASE 0x330
-#endif
-
-#ifndef U6850_IRQ
-#define U6850_IRQ 5
-#endif
-
-#ifndef U6850_DMA
-#define U6850_DMA 1
-#endif
-
-#ifndef MAX_REALTIME_FACTOR
-#define MAX_REALTIME_FACTOR 4
-#endif
-
-/************* PCM DMA buffer sizes *******************/
-
-/* If you are using high playback or recording speeds, the default buffersize
- is too small. DSP_BUFFSIZE must be 64k or less.
-
- A rule of thumb is 64k for PAS16, 32k for PAS+, 16k for SB Pro and
- 4k for SB.
-
- If you change the DSP_BUFFSIZE, don't modify this file.
- Use the make config command instead. */
-
-#ifndef DSP_BUFFSIZE
-#define DSP_BUFFSIZE (4096)
-#endif
-
-#ifndef DSP_BUFFCOUNT
-#define DSP_BUFFCOUNT 2 /* 2 is recommended. */
-#endif
-
-#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) */
-#define SEQ_MAX_QUEUE 1024
-
-#define SBFM_MAXINSTR (256) /* Size of the FM Instrument bank */
-/* 128 instruments for general MIDI setup and 16 unassigned */
-
-/*
- * Minor numbers for the sound driver.
- *
- * Unfortunately Creative called the codec chip of SB as a DSP. For this
- * reason the /dev/dsp is reserved for digitized audio use. There is a
- * device for true DSP processors but it will be called something else.
- * In v3.0 it's /dev/sndproc but this could be a temporary solution.
- */
-
-#define SND_NDEVS 256 /* Number of supported devices */
-#define SND_DEV_CTL 0 /* Control port /dev/mixer */
-#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
- synthesizer and MIDI output) */
-#define SND_DEV_MIDIN 2 /* Raw midi access */
-#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
-#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
-#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
-#define SND_DEV_STATUS 6 /* /dev/sndstat */
-/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
-#define SND_DEV_SEQ2 8 /* /dev/sequecer, level 2 interface */
-#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
-#define SND_DEV_PSS SND_DEV_SNDPROC
-
-#define DSP_DEFAULT_SPEED 8000
-
-#define ON 1
-#define OFF 0
-
-#define MAX_AUDIO_DEV 5
-#define MAX_MIXER_DEV 5
-#define MAX_SYNTH_DEV 3
-#define MAX_MIDI_DEV 6
-#define MAX_TIMER_DEV 3
-
-struct fileinfo {
- int mode; /* Open mode */
- DECLARE_FILE(); /* Reference to file-flags. OS-dependent. */
- };
-
-struct address_info {
- int io_base;
- int irq;
- int dma; /* write dma channel */
- int dma_read; /* read dma channel */
- int always_detect; /* 1=Trust me, it's there */
-};
-
-#define SYNTH_MAX_VOICES 32
-
-struct voice_alloc_info {
- int max_voice;
- int used_voices;
- int ptr; /* For device specific use */
- unsigned short map[SYNTH_MAX_VOICES]; /* (ch << 8) | (note+1) */
- int timestamp;
- int alloc_times[SYNTH_MAX_VOICES];
- };
-
-struct channel_info {
- int pgm_num;
- int bender_value;
- unsigned char controllers[128];
- };
-
-/*
- * Process wakeup reasons
- */
-#define WK_NONE 0x00
-#define WK_WAKEUP 0x01
-#define WK_TIMEOUT 0x02
-#define WK_SIGNAL 0x04
-#define WK_SLEEP 0x08
-
-#define OPEN_READ 1
-#define OPEN_WRITE 2
-#define OPEN_READWRITE 3
-
-#ifdef PC98
-#include <pc98/pc98/sound/sound_calls.h>
-#include <pc98/pc98/sound/dev_table.h>
-#else
-#include <i386/isa/sound/sound_calls.h>
-#include <i386/isa/sound/dev_table.h>
-#endif
-
-#ifndef DEB
-#define DEB(x)
-#endif
-
-#ifndef AUDIO_DDB
-#define AUDIO_DDB(x)
-#endif
-
-#define TIMER_ARMED 121234
-#define TIMER_NOT_ARMED 1
-
-#endif
diff --git a/sys/pc98/pc98/sound/sound_switch.c b/sys/pc98/pc98/sound/sound_switch.c
deleted file mode 100644
index 83994e0..0000000
--- a/sys/pc98/pc98/sound/sound_switch.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * sound/sound_switch.c
- *
- * The system call switch
- *
- * 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
-
-struct sbc_device
- {
- int usecount;
- };
-
-static struct sbc_device sbc_devices[SND_NDEVS] =
-{
- {0}};
-
-static int in_use = 0; /*
-
-
- * * * * Total # of open device files
- * (excluding * * * minor 0) */
-
-/*
- * /dev/sndstatus -device
- */
-static char *status_buf = NULL;
-static int status_len, status_ptr;
-static int status_busy = 0;
-
-static int
-put_status (char *s)
-{
- int l;
-
- for (l = 0; l < 256, s[l]; l++); /*
- * l=strlen(s);
- */
-
- if (status_len + l >= 4000)
- return 0;
-
- memcpy (&status_buf[status_len], s, l);
- status_len += l;
-
- return 1;
-}
-
-static int
-put_status_int (unsigned int val, int radix)
-{
- int l, v;
-
- static char hx[] = "0123456789abcdef";
- char buf[11];
-
- if (!val)
- return put_status ("0");
-
- l = 0;
- buf[10] = 0;
-
- while (val)
- {
- v = val % radix;
- val = val / radix;
-
- buf[9 - l] = hx[v];
- l++;
- }
-
- if (status_len + l >= 4000)
- return 0;
-
- memcpy (&status_buf[status_len], &buf[10 - l], l);
- status_len += l;
-
- return 1;
-}
-
-static void
-init_status (void)
-{
- /*
- * Write the status information to the status_buf and update status_len.
- * There is a limit of 4000 bytes for the data.
- */
-
- int i;
-
- status_ptr = 0;
-
- put_status ("VoxWare Sound Driver:" SOUND_VERSION_STRING
- " (" SOUND_CONFIG_DATE " " SOUND_CONFIG_BY "@"
- SOUND_CONFIG_HOST "." SOUND_CONFIG_DOMAIN ")"
- "\n");
-
- if (!put_status ("Config options: "))
- return;
- if (!put_status_int (SELECTED_SOUND_OPTIONS, 16))
- return;
-
- if (!put_status ("\n\nInstalled drivers: \n"))
- return;
-
- for (i = 0; i < (num_sound_drivers - 1); i++)
- {
- if (!put_status ("Type "))
- return;
- if (!put_status_int (sound_drivers[i].card_type, 10))
- return;
- if (!put_status (": "))
- return;
- if (!put_status (sound_drivers[i].name))
- return;
-
- if (!put_status ("\n"))
- return;
- }
-
- if (!put_status ("\n\nCard config: \n"))
- return;
-
- for (i = 0; i < (num_sound_cards - 1); i++)
- {
- int drv;
-
- if (!snd_installed_cards[i].enabled)
- if (!put_status ("("))
- return;
-
- /*
- * if (!put_status_int(snd_installed_cards[i].card_type, 10)) return;
- * if (!put_status (": ")) return;
- */
-
- if ((drv = snd_find_driver (snd_installed_cards[i].card_type)) != -1)
- if (!put_status (sound_drivers[drv].name))
- return;
-
- if (!put_status (" at 0x"))
- return;
- if (!put_status_int (snd_installed_cards[i].config.io_base, 16))
- return;
- if (!put_status (" irq "))
- return;
- if (!put_status_int (snd_installed_cards[i].config.irq, 10))
- return;
-#ifdef PC98
- if (snd_installed_cards[i].config.dma >= 0) {
-#endif
- if (!put_status (" drq "))
- return;
- if (!put_status_int (snd_installed_cards[i].config.dma, 10))
- return;
-#ifdef PC98
- }
-#endif
-
- if (!snd_installed_cards[i].enabled)
- if (!put_status (")"))
- return;
-
- if (!put_status ("\n"))
- return;
- }
-
-#ifdef EXCLUDE_AUDIO
- if (!put_status ("\nAudio devices: NOT ENABLED IN CONFIG\n"))
- return;
-#else
- if (!put_status ("\nAudio devices:\n"))
- return;
-
- for (i = 0; i < num_audiodevs; i++)
- {
- if (!put_status_int (i, 10))
- return;
- if (!put_status (": "))
- return;
- if (!put_status (audio_devs[i]->name))
- return;
- if (!put_status ("\n"))
- return;
- }
-#endif
-
-#ifdef EXCLUDE_SEQUENCER
- if (!put_status ("\nSynth devices: NOT ENABLED IN CONFIG\n"))
- return;
-#else
- if (!put_status ("\nSynth devices:\n"))
- return;
-
- for (i = 0; i < num_synths; i++)
- {
- if (!put_status_int (i, 10))
- return;
- if (!put_status (": "))
- return;
- if (!put_status (synth_devs[i]->info->name))
- return;
- if (!put_status ("\n"))
- return;
- }
-#endif
-
-#ifdef EXCLUDE_MIDI
- if (!put_status ("\nMidi devices: NOT ENABLED IN CONFIG\n"))
- return;
-#else
- if (!put_status ("\nMidi devices:\n"))
- return;
-
- for (i = 0; i < num_midis; i++)
- {
- if (!put_status_int (i, 10))
- return;
- if (!put_status (": "))
- return;
- if (!put_status (midi_devs[i]->info.name))
- return;
- if (!put_status ("\n"))
- return;
- }
-#endif
-
- if (!put_status ("\nTimers:\n"))
- return;
-
- for (i = 0; i < num_sound_timers; i++)
- {
- if (!put_status_int (i, 10))
- return;
- if (!put_status (": "))
- return;
- if (!put_status (sound_timer_devs[i]->info.name))
- return;
- if (!put_status ("\n"))
- return;
- }
-
- if (!put_status ("\nMixers:\n"))
- return;
-
- for (i = 0; i < num_mixers; i++)
- {
- if (!put_status_int (i, 10))
- return;
- if (!put_status (": "))
- return;
- if (!put_status (mixer_devs[i]->name))
- return;
- if (!put_status ("\n"))
- return;
- }
-}
-
-static int
-read_status (snd_rw_buf * buf, int count)
-{
- /*
- * Return at most 'count' bytes from the status_buf.
- */
- int l, c;
-
- l = count;
- c = status_len - status_ptr;
-
- if (l > c)
- l = c;
- if (l <= 0)
- return 0;
-
- COPY_TO_USER (buf, 0, &status_buf[status_ptr], l);
- status_ptr += l;
-
- return l;
-}
-
-int
-sound_read_sw (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
- DEB (printk ("sound_read_sw(dev=%d, count=%d)\n", dev, count));
-
- switch (dev & 0x0f)
- {
- case SND_DEV_STATUS:
- return read_status (buf, count);
- break;
-
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- return audio_read (dev, file, buf, count);
- break;
-
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- return sequencer_read (dev, file, buf, count);
- break;
-
-#ifndef EXCLUDE_MIDI
- case SND_DEV_MIDIN:
- return MIDIbuf_read (dev, file, buf, count);
-#endif
-
- default:
- printk ("Sound: Undefined minor device %d\n", dev);
- }
-
- return RET_ERROR (EPERM);
-}
-
-int
-sound_write_sw (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
-{
-
- DEB (printk ("sound_write_sw(dev=%d, count=%d)\n", dev, count));
-
- switch (dev & 0x0f)
- {
-
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- return sequencer_write (dev, file, buf, count);
- break;
-
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- return audio_write (dev, file, buf, count);
- break;
-
-#ifndef EXCLUDE_MIDI
- case SND_DEV_MIDIN:
- return MIDIbuf_write (dev, file, buf, count);
-#endif
-
- default:
- return RET_ERROR (EPERM);
- }
-
- return count;
-}
-
-int
-sound_open_sw (int dev, struct fileinfo *file)
-{
- int retval;
-
- DEB (printk ("sound_open_sw(dev=%d) : usecount=%d\n", dev, sbc_devices[dev].usecount));
-
- if ((dev >= SND_NDEVS) || (dev < 0))
- {
- printk ("Invalid minor device %d\n", dev);
- return RET_ERROR (ENXIO);
- }
-
- switch (dev & 0x0f)
- {
- case SND_DEV_STATUS:
- if (status_busy)
- return RET_ERROR (EBUSY);
- status_busy = 1;
- if ((status_buf = (char *) KERNEL_MALLOC (4000)) == NULL)
- return RET_ERROR (EIO);
- status_len = status_ptr = 0;
- init_status ();
- break;
-
- case SND_DEV_CTL:
- return 0;
- break;
-
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- if ((retval = sequencer_open (dev, file)) < 0)
- return retval;
- break;
-
-#ifndef EXCLUDE_MIDI
- case SND_DEV_MIDIN:
- if ((retval = MIDIbuf_open (dev, file)) < 0)
- return retval;
- break;
-#endif
-
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- if ((retval = audio_open (dev, file)) < 0)
- return retval;
- break;
-
- default:
- printk ("Invalid minor device %d\n", dev);
- return RET_ERROR (ENXIO);
- }
-
- sbc_devices[dev].usecount++;
- in_use++;
-
- return 0;
-}
-
-void
-sound_release_sw (int dev, struct fileinfo *file)
-{
-
- DEB (printk ("sound_release_sw(dev=%d)\n", dev));
-
- switch (dev & 0x0f)
- {
- case SND_DEV_STATUS:
- if (status_buf)
- KERNEL_FREE (status_buf);
- status_buf = NULL;
- status_busy = 0;
- break;
-
- case SND_DEV_CTL:
- break;
-
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- sequencer_release (dev, file);
- break;
-
-#ifndef EXCLUDE_MIDI
- case SND_DEV_MIDIN:
- MIDIbuf_release (dev, file);
- break;
-#endif
-
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- audio_release (dev, file);
- break;
-
- default:
- printk ("Sound error: Releasing unknown device 0x%02x\n", dev);
- }
-
- sbc_devices[dev].usecount--;
- in_use--;
-}
-
-int
-sound_ioctl_sw (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned long arg)
-{
- DEB (printk ("sound_ioctl_sw(dev=%d, cmd=0x%x, arg=0x%x)\n", dev, cmd, arg));
-
- if ((cmd >> 8) & 0xff == 'M' && num_mixers > 0) /* Mixer ioctl */
- if ((dev & 0x0f) != SND_DEV_CTL)
- {
- int dtype = dev & 0x0f;
- int mixdev;
-
- switch (dtype)
- {
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- mixdev = audio_devs[dev >> 4]->mixer_dev;
- if (mixdev < 0 || mixdev >= num_mixers)
- return RET_ERROR (ENXIO);
- return mixer_devs[mixdev]->ioctl (mixdev, cmd, arg);
- break;
-
- default:
- return mixer_devs[0]->ioctl (0, cmd, arg);
- }
- }
-
- switch (dev & 0x0f)
- {
-
- case SND_DEV_CTL:
-
- if (!num_mixers)
- return RET_ERROR (ENXIO);
-
- dev = dev >> 4;
-
- if (dev >= num_mixers)
- return RET_ERROR (ENXIO);
-
- return mixer_devs[dev]->ioctl (dev, cmd, arg);
- break;
-
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- return sequencer_ioctl (dev, file, cmd, arg);
- break;
-
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- return audio_ioctl (dev, file, cmd, arg);
- break;
-
-#ifndef EXCLUDE_MIDI
- case SND_DEV_MIDIN:
- return MIDIbuf_ioctl (dev, file, cmd, arg);
- break;
-#endif
-
- default:
- return RET_ERROR (EPERM);
- break;
- }
-
- return RET_ERROR (EPERM);
-}
-
-#endif
diff --git a/sys/pc98/pc98/sound/soundcard.c b/sys/pc98/pc98/sound/soundcard.c
deleted file mode 100644
index 1709503..0000000
--- a/sys/pc98/pc98/sound/soundcard.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * sound/386bsd/soundcard.c
- *
- * Soundcard driver for FreeBSD.
- *
- * 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.
- *
- * $Id: soundcard.c,v 1.6 1996/10/29 08:36:59 asami Exp $
- */
-
-#include <i386/isa/sound/sound_config.h>
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-#ifdef CONFIGURE_SOUNDCARD
-
-#include <i386/isa/sound/dev_table.h>
-#include <i386/isa/isa_device.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#ifdef DEVFS
-#include <sys/devfsext.h>
-#endif /*DEVFS*/
-
-#define FIX_RETURN(ret) { \
- int tmp_ret = (ret); \
- if (tmp_ret<0) return -tmp_ret; else return 0; \
- }
-
-static int timer_running = 0;
-
-static int soundcards_installed = 0; /* Number of installed
- * soundcards */
-static int soundcard_configured = 0;
-
-static struct fileinfo files[SND_NDEVS];
-
-#ifdef DEVFS
-static void * snd_devfs_token[SND_NDEVS];
-static void * sndstat_devfs_token;
-#endif
-
-struct selinfo selinfo[SND_NDEVS >> 4];
-
-static int sndprobe (struct isa_device *dev);
-static int sndattach (struct isa_device *dev);
-static void sound_mem_init(void);
-
-static d_open_t sndopen;
-static d_close_t sndclose;
-static d_read_t sndread;
-static d_write_t sndwrite;
-static d_ioctl_t sndioctl;
-static d_select_t sndselect;
-
-#define CDEV_MAJOR 30
-static struct cdevsw snd_cdevsw =
- { sndopen, sndclose, sndread, sndwrite, /*30*/
- sndioctl, nostop, nullreset, nodevtotty,/* sound */
- sndselect, nommap, NULL, "snd", NULL, -1 };
-
-struct isa_driver opldriver = {sndprobe, sndattach, "opl"};
-struct isa_driver sbdriver = {sndprobe, sndattach, "sb"};
-struct isa_driver sbxvidriver = {sndprobe, sndattach, "sbxvi"};
-struct isa_driver sbmididriver = {sndprobe, sndattach, "sbmidi"};
-struct isa_driver pasdriver = {sndprobe, sndattach, "pas"};
-struct isa_driver mpudriver = {sndprobe, sndattach, "mpu"};
-struct isa_driver gusdriver = {sndprobe, sndattach, "gus"};
-struct isa_driver gusxvidriver = {sndprobe, sndattach, "gusxvi"};
-struct isa_driver gusmaxdriver = {sndprobe, sndattach, "gusmax"};
-struct isa_driver uartdriver = {sndprobe, sndattach, "uart"};
-struct isa_driver mssdriver = {sndprobe, sndattach, "mss"};
-#ifdef PC98
-struct isa_driver pcmdriver = {sndprobe, sndattach, "pcm"};
-#endif
-
-static unsigned short
-ipri_to_irq (unsigned short ipri);
-
-void
-adintr(INT_HANDLER_PARMS(unit,dummy))
-{
-#ifndef EXCLUDE_AD1848
- static short unit_to_irq[4] = { -1, -1, -1, -1 };
- struct isa_device *dev;
-
- if (unit_to_irq [unit] > 0)
- ad1848_interrupt(INT_HANDLER_CALL (unit_to_irq [unit]));
- else {
- dev = find_isadev (isa_devtab_null, &mssdriver, unit);
- if (!dev)
- printk ("ad1848: Couldn't determine unit\n");
- else {
- unit_to_irq [unit] = ipri_to_irq (dev->id_irq);
- ad1848_interrupt(INT_HANDLER_CALL (unit_to_irq [unit]));
- }
- }
-#endif
-}
-
-unsigned
-long
-get_time(void)
-{
-struct timeval timecopy;
-int x;
-
- x = splclock();
- timecopy = time;
- splx(x);
- return timecopy.tv_usec/(1000000/HZ) +
- (unsigned long)timecopy.tv_sec*HZ;
-}
-
-
-static int
-sndread (dev_t dev, struct uio *buf, int ioflag)
-{
- int count = buf->uio_resid;
-
- dev = minor (dev);
-
- FIX_RETURN (sound_read_sw (dev, &files[dev], buf, count));
-}
-
-static int
-sndwrite (dev_t dev, struct uio *buf, int ioflag)
-{
- int count = buf->uio_resid;
-
- dev = minor (dev);
-
- FIX_RETURN (sound_write_sw (dev, &files[dev], buf, count));
-}
-
-static int
-sndopen (dev_t dev, int flags, int fmt, struct proc *p)
-{
- dev = minor (dev);
-
- if (!soundcard_configured && dev)
- {
- printk ("SoundCard Error: The soundcard system has not been configured\n");
- FIX_RETURN (-ENODEV);
- }
-
- files[dev].mode = 0;
-
- if (flags & FREAD && flags & FWRITE)
- files[dev].mode = OPEN_READWRITE;
- else if (flags & FREAD)
- files[dev].mode = OPEN_READ;
- else if (flags & FWRITE)
- files[dev].mode = OPEN_WRITE;
-
- selinfo[dev >> 4].si_pid = 0;
- selinfo[dev >> 4].si_flags = 0;
-
- FIX_RETURN(sound_open_sw (dev, &files[dev]));
-}
-
-static int
-sndclose (dev_t dev, int flags, int fmt, struct proc *p)
-{
-
- dev = minor (dev);
-
- sound_release_sw(dev, &files[dev]);
- FIX_RETURN (0);
-}
-
-static int
-sndioctl (dev_t dev, int cmd, caddr_t arg, int flags, struct proc *p)
-{
- dev = minor (dev);
-
- FIX_RETURN (sound_ioctl_sw (dev, &files[dev], cmd, (unsigned int) arg));
-}
-
-static int
-sndselect (dev_t dev, int rw, struct proc *p)
-{
- dev = minor (dev);
-
- DEB (printk ("snd_select(dev=%d, rw=%d, pid=%d)\n", dev, rw, p->p_pid));
-#ifdef ALLOW_SELECT
- switch (dev & 0x0f)
- {
-#ifndef EXCLUDE_SEQUENCER
- case SND_DEV_SEQ:
- case SND_DEV_SEQ2:
- return sequencer_select (dev, &files[dev], rw, p);
- break;
-#endif
-
-#ifndef EXCLUDE_MIDI
- case SND_DEV_MIDIN:
- return MIDIbuf_select (dev, &files[dev], rw, p);
- break;
-#endif
-
-#ifndef EXCLUDE_AUDIO
- case SND_DEV_DSP:
- case SND_DEV_DSP16:
- case SND_DEV_AUDIO:
- return audio_select (dev, &files[dev], rw, p);
- break;
-#endif
-
- default:
- return 0;
- }
-
-#endif
-
- return 0;
-}
-
-static unsigned short
-ipri_to_irq (unsigned short ipri)
-{
- /*
- * Converts the ipri (bitmask) to the corresponding irq number
- */
- int irq;
-
- for (irq = 0; irq < 16; irq++)
- if (ipri == (1 << irq))
- return irq;
-
- return -1; /* Invalid argument */
-}
-
-static int
-driver_to_voxunit(struct isa_driver *driver)
-{
- /* converts a sound driver pointer into the equivalent
- VoxWare device unit number */
- if(driver == &opldriver)
- return(SNDCARD_ADLIB);
- else if(driver == &sbdriver)
- return(SNDCARD_SB);
- else if(driver == &pasdriver)
- return(SNDCARD_PAS);
- else if(driver == &gusdriver)
- return(SNDCARD_GUS);
- else if(driver == &mpudriver)
- return(SNDCARD_MPU401);
- else if(driver == &sbxvidriver)
- return(SNDCARD_SB16);
- else if(driver == &sbmididriver)
- return(SNDCARD_SB16MIDI);
- else if(driver == &uartdriver)
- return(SNDCARD_UART6850);
- else if(driver == &gusdriver)
- return(SNDCARD_GUS16);
- else if(driver == &mssdriver)
- return(SNDCARD_MSS);
-#ifdef PC98
- else if(driver == &pcmdriver)
- return(SNDCARD_PCM86);
-#endif
- else
- return(0);
-}
-
-static int
-sndprobe (struct isa_device *dev)
-{
- struct address_info hw_config;
- int unit;
-
- unit = driver_to_voxunit(dev->id_driver);
- hw_config.io_base = dev->id_iobase;
- hw_config.irq = ipri_to_irq (dev->id_irq);
- hw_config.dma = dev->id_drq;
- hw_config.dma_read = dev->id_flags; /* misuse the flags field for read dma*/
-
- if(unit)
-#ifdef PC98
- if(unit == SNDCARD_PCM86) {
- int result;
-
- result = sndtable_probe (unit, &hw_config);
- dev->id_iobase = hw_config.io_base;
- dev->id_irq = (1 << hw_config.irq);
- dev->id_drq = hw_config.dma;
-
- return result;
- }
- else
-#endif
- return sndtable_probe (unit, &hw_config);
- else
- return 0;
-}
-
-static int
-sndattach (struct isa_device *dev)
-{
- int unit;
- static int midi_initialized = 0;
- static int seq_initialized = 0;
- unsigned long mem_start = 0xefffffffUL;
- struct address_info hw_config;
-
- unit = driver_to_voxunit(dev->id_driver);
- hw_config.io_base = dev->id_iobase;
- hw_config.irq = ipri_to_irq (dev->id_irq);
- hw_config.dma = dev->id_drq;
- hw_config.dma_read = dev->id_flags; /* misuse the flags field for read dma*/
-
- if(!unit)
- return FALSE;
- if (!sndtable_init_card (unit, &hw_config))
- {
- printf (" <Driver not configured>");
- return FALSE;
- }
-
- /*
- * Init the high level sound driver
- */
-
- if (!(soundcards_installed = sndtable_get_cardcount ()))
- {
- printf (" <No such hardware>");
- return FALSE; /* No cards detected */
- }
-
- printf("\n");
-
-#ifndef EXCLUDE_AUDIO
- if (num_audiodevs) /* Audio devices present */
- {
- mem_start = DMAbuf_init (mem_start);
- mem_start = audio_init (mem_start);
- sound_mem_init ();
- }
-
- soundcard_configured = 1;
-#endif
-
-#ifndef EXCLUDE_MIDI
- if (num_midis && !midi_initialized)
- {
- midi_initialized = 1;
- mem_start = MIDIbuf_init (mem_start);
- }
-#endif
-
-#ifndef EXCLUDE_SEQUENCER
- if ((num_midis + num_synths) && !seq_initialized)
- {
- seq_initialized = 1;
- mem_start = sequencer_init (mem_start);
- }
-#endif
-
-#ifdef DEVFS
-/* XXX */ /* find out where to store the tokens.. */
-/* XXX */ /* should only create devices if that card has them */
-#define SND_UID 0
-#define SND_GID 13
-
- snd_devfs_token[unit]=
- devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_CTL, DV_CHR,
- SND_UID, SND_GID, 0660, "mixer%d", unit);
-
-#ifndef EXCLUDE_SEQUENCER
- snd_devfs_token[unit]=
- devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_SEQ, DV_CHR,
- SND_UID, SND_GID, 0660, "sequencer%d", unit);
- snd_devfs_token[unit]=
- devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_SEQ2, DV_CHR,
- SND_UID, SND_GID, 0660, "music%d", unit);
-#endif
-
-#ifndef EXCLUDE_MIDI
- snd_devfs_token[unit]=
- devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_MIDIN,
- DV_CHR, SND_UID, SND_GID, 0660, "midi%d",
- unit);
-#endif
-
-#ifndef EXCLUDE_AUDIO
- snd_devfs_token[unit]=
- devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_DSP, DV_CHR,
- SND_UID, SND_GID, 0660, "dsp%d", unit);
- snd_devfs_token[unit]=
- devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_AUDIO,
- DV_CHR, SND_UID, SND_GID, 0660, "audio%d",
- unit);
- snd_devfs_token[unit]=
- devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_DSP16,
- DV_CHR, SND_UID, SND_GID, 0660, "dspW%d",
- unit);
-#endif
-
- snd_devfs_token[unit]=
- devfs_add_devswf(&snd_cdevsw, (unit << 4)+SND_DEV_SNDPROC,
- DV_CHR, SND_UID, SND_GID, 0660, "pss%d",
- unit);
-
- if ( ! sndstat_devfs_token) {
- sndstat_devfs_token =
- devfs_add_devswf(&snd_cdevsw, 6, DV_CHR, SND_UID, SND_GID,
- 0660, "sndstat");
- }
-#endif /* DEVFS */
- return TRUE;
-}
-
-void
-tenmicrosec (void)
-{
- int i;
-
- for (i = 0; i < 16; i++)
- inb (0x80);
-}
-
-#ifndef EXCLUDE_SEQUENCER
-void
-request_sound_timer (int count)
-{
- static int current = 0;
- int tmp = count;
-
- if (count < 0)
- timeout ((timeout_func_t)sequencer_timer, 0, -count);
- else
- {
-
- if (count < current)
- current = 0; /* Timer restarted */
-
- count = count - current;
-
- current = tmp;
-
- if (!count)
- count = 1;
-
- timeout ((timeout_func_t)sequencer_timer, 0, count);
- }
- timer_running = 1;
-}
-
-void
-sound_stop_timer (void)
-{
- if (timer_running)
- untimeout ((timeout_func_t)sequencer_timer, 0);
- timer_running = 0;
-}
-#endif
-
-#ifndef EXCLUDE_AUDIO
-static void
-sound_mem_init (void)
-{
- int dev;
- unsigned long dma_pagesize;
- struct dma_buffparms *dmap;
- static unsigned long dsp_init_mask = 0;
-
- for (dev = 0; dev < num_audiodevs; dev++) /* Enumerate devices */
- if (!(dsp_init_mask & (1 << dev))) /* Not already done */
-#ifdef PC98
- if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan >= 0)
-#else
- if (audio_devs[dev]->buffcount > 0 && audio_devs[dev]->dmachan > 0)
-#endif
- {
- dsp_init_mask |= (1 << dev);
- dmap = audio_devs[dev]->dmap;
-
- if (audio_devs[dev]->flags & DMA_AUTOMODE)
- audio_devs[dev]->buffcount = 1;
-
- audio_devs[dev]->buffsize &= ~0xfff; /* Truncate to n*4k */
-
- if (audio_devs[dev]->dmachan > 3 && audio_devs[dev]->buffsize > 65536)
- dma_pagesize = 131072; /* 128k */
- else
- dma_pagesize = 65536;
-
- /* More sanity checks */
-
- if (audio_devs[dev]->buffsize > dma_pagesize)
- audio_devs[dev]->buffsize = dma_pagesize;
- if (audio_devs[dev]->buffsize < 4096)
- audio_devs[dev]->buffsize = 4096;
-
- /* Now allocate the buffers */
-
- for (dmap->raw_count = 0; dmap->raw_count < audio_devs[dev]->buffcount; dmap->raw_count++)
- {
- char *tmpbuf = (char *)vm_page_alloc_contig(audio_devs[dev]->buffsize, 0ul, 0xfffffful, dma_pagesize);
-
- if (tmpbuf == NULL)
- {
- printk ("snd: Unable to allocate %ld bytes of buffer\n",
- audio_devs[dev]->buffsize);
- return;
- }
-
- dmap->raw_buf[dmap->raw_count] = tmpbuf;
- /*
- * Use virtual address as the physical address, since
- * isa_dmastart performs the phys address computation.
- */
- dmap->raw_buf_phys[dmap->raw_count] =
- (unsigned long) dmap->raw_buf[dmap->raw_count];
- }
- } /* for dev */
-
-}
-
-#endif
-
-int
-snd_set_irq_handler (int interrupt_level, INT_HANDLER_PROTO(), char *name)
-{
- return 1;
-}
-
-
-void
-snd_release_irq(int vect)
-{
-}
-
-static snd_devsw_installed = 0;
-
-static void
-snd_drvinit(void *unused)
-{
- dev_t dev;
-
- if( ! snd_devsw_installed ) {
- dev = makedev(CDEV_MAJOR, 0);
- cdevsw_add(&dev,&snd_cdevsw, NULL);
- snd_devsw_installed = 1;
- }
-}
-
-SYSINIT(snddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,snd_drvinit,NULL)
-
-#endif
-
diff --git a/sys/pc98/pc98/spkr.c b/sys/pc98/pc98/spkr.c
index 5bfbe08..d6a1960 100644
--- a/sys/pc98/pc98/spkr.c
+++ b/sys/pc98/pc98/spkr.c
@@ -4,12 +4,11 @@
* 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.4 1996/09/04 09:52:27 asami Exp $
+ * $Id: spkr.c,v 1.5 1996/10/30 22:40:14 asami Exp $
*/
/*
- * modified for PC98
- * $Id: spkr.c,v 1.4 1996/09/04 09:52:27 asami Exp $
+ * modified for PC98 by Kakefuda
*/
#include "speaker.h"
@@ -92,14 +91,7 @@ tone(thz, ticks)
if (thz <= 0)
return;
-#if defined(PC98) && defined(AUTO_CLOCK)
- if (pc98_machine_type & M_8M)
- divisor = 1996800L / thz;
- else
- divisor = 2457600L / thz;
-#else
divisor = timer_freq / thz;
-#endif /* PC98 */
#ifdef DEBUG
(void) printf("tone: thz=%d ticks=%d\n", thz, ticks);
diff --git a/sys/pc98/pc98/wcd.c b/sys/pc98/pc98/wcd.c
deleted file mode 100644
index c090817..0000000
--- a/sys/pc98/pc98/wcd.c
+++ /dev/null
@@ -1,1217 +0,0 @@
-/*
- * IDE CD-ROM driver for FreeBSD.
- * Supports ATAPI-compatible drives.
- *
- * 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 20:27:42 MSK 1995
- */
-
-#include "wdc.h"
-#include "wcd.h"
-#include "opt_atapi.h"
-
-#if NWCD > 0 && NWDC > 0 && defined (ATAPI)
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/malloc.h>
-#include <sys/buf.h>
-#include <sys/ioctl.h>
-#include <sys/disklabel.h>
-#include <sys/cdio.h>
-#include <sys/conf.h>
-#ifdef DEVFS
-#include <sys/devfsext.h>
-#endif /*DEVFS*/
-
-#include <machine/cpufunc.h>
-
-#ifdef PC98
-#include <pc98/pc98/atapi.h>
-#else
-#include <i386/isa/atapi.h>
-#endif
-
-static d_open_t wcdropen;
-static d_open_t wcdbopen;
-static d_close_t wcdrclose;
-static d_close_t wcdbclose;
-static d_ioctl_t wcdioctl;
-static d_strategy_t wcdstrategy;
-
-#define CDEV_MAJOR 69
-#define BDEV_MAJOR 19
-extern struct cdevsw wcd_cdevsw;
-static struct bdevsw wcd_bdevsw =
- { wcdbopen, wcdbclose, wcdstrategy, wcdioctl, /*19*/
- nodump, nopsize, 0, "wcd", &wcd_cdevsw, -1 };
-
-static struct cdevsw wcd_cdevsw =
- { wcdropen, wcdrclose, rawread, nowrite, /*69*/
- wcdioctl, nostop, nullreset, nodevtotty,/* atapi */
- seltrue, nommap, wcdstrategy, "wcd",
- &wcd_bdevsw, -1 };
-
-#ifndef ATAPI_STATIC
-static
-#endif
-int wcdattach(struct atapi*, int, struct atapi_params*, int);
-
-#define NUNIT (NWDC*2) /* Max. number of devices */
-#define UNIT(d) ((minor(d) >> 3) & 3) /* Unit part of minor device number */
-#define SECSIZE 2048 /* CD-ROM sector size in bytes */
-
-#define F_BOPEN 0x0001 /* The block device is opened */
-#define F_MEDIA_CHANGED 0x0002 /* The media have changed since open */
-#define F_DEBUG 0x0004 /* Print debug info */
-
-/*
- * Disc table of contents.
- */
-#define MAXTRK 99
-struct toc {
- struct ioc_toc_header hdr;
- struct cd_toc_entry tab[MAXTRK+1]; /* One extra for the leadout */
-};
-
-/*
- * Volume size info.
- */
-struct volinfo {
- u_long volsize; /* Volume size in blocks */
- u_long blksize; /* Block size in bytes */
-} info;
-
-/*
- * Current subchannel status.
- */
-struct subchan {
- u_char void0;
- u_char audio_status;
- u_short data_length;
- u_char data_format;
- u_char control;
- u_char track;
- u_char indx;
- u_long abslba;
- u_long rellba;
-};
-
-/*
- * Audio Control Parameters Page
- */
-struct audiopage {
- /* Mode data header */
- u_short data_length;
- u_char medium_type;
- u_char reserved1[5];
-
- /* Audio control page */
- u_char page_code;
-#define AUDIO_PAGE 0x0e
-#define AUDIO_PAGE_MASK 0x4e /* changeable values */
- u_char param_len;
- u_char flags;
-#define CD_PA_SOTC 0x02 /* mandatory */
-#define CD_PA_IMMED 0x04 /* always 1 */
- u_char reserved3[3];
- u_short lb_per_sec;
- struct port_control {
- u_char channels : 4;
-#define CHANNEL_0 1 /* mandatory */
-#define CHANNEL_1 2 /* mandatory */
-#define CHANNEL_2 4 /* optional */
-#define CHANNEL_3 8 /* optional */
- u_char volume;
- } port[4];
-};
-
-/*
- * CD-ROM Capabilities and Mechanical Status Page
- */
-struct cappage {
- /* Mode data header */
- u_short data_length;
- u_char medium_type;
-#define MDT_UNKNOWN 0x00
-#define MDT_DATA_120 0x01
-#define MDT_AUDIO_120 0x02
-#define MDT_COMB_120 0x03
-#define MDT_PHOTO_120 0x04
-#define MDT_DATA_80 0x05
-#define MDT_AUDIO_80 0x06
-#define MDT_COMB_80 0x07
-#define MDT_PHOTO_80 0x08
-#define MDT_NO_DISC 0x70
-#define MDT_DOOR_OPEN 0x71
-#define MDT_FMT_ERROR 0x72
- u_char reserved1[5];
-
- /* Capabilities page */
- u_char page_code;
-#define CAP_PAGE 0x2a
- u_char param_len;
- u_char reserved2[2];
-
- u_char audio_play : 1; /* audio play supported */
- u_char composite : 1; /* composite audio/video supported */
- u_char dport1 : 1; /* digital audio on port 1 */
- u_char dport2 : 1; /* digital audio on port 2 */
- u_char mode2_form1 : 1; /* mode 2 form 1 (XA) read */
- u_char mode2_form2 : 1; /* mode 2 form 2 format */
- u_char multisession : 1; /* multi-session photo-CD */
- u_char : 1;
- u_char cd_da : 1; /* audio-CD read supported */
- u_char cd_da_stream : 1; /* CD-DA streaming */
- u_char rw : 1; /* combined R-W subchannels */
- u_char rw_corr : 1; /* R-W subchannel data corrected */
- u_char c2 : 1; /* C2 error pointers supported */
- u_char isrc : 1; /* can return the ISRC info */
- u_char upc : 1; /* can return the catalog number UPC */
- u_char : 1;
- u_char lock : 1; /* could be locked */
- u_char locked : 1; /* current lock state */
- u_char prevent : 1; /* prevent jumper installed */
- u_char eject : 1; /* can eject */
- u_char : 1;
- u_char mech : 3; /* loading mechanism type */
-#define MECH_CADDY 0
-#define MECH_TRAY 1
-#define MECH_POPUP 2
-#define MECH_CHANGER 4
-#define MECH_CARTRIDGE 5
- u_char sep_vol : 1; /* independent volume of channels */
- u_char sep_mute : 1; /* independent mute of channels */
- u_char : 6;
-
- u_short max_speed; /* max raw data rate in bytes/1000 */
- u_short max_vol_levels; /* number of discrete volume levels */
- u_short buf_size; /* internal buffer size in bytes/1024 */
- u_short cur_speed; /* current data rate in bytes/1000 */
-
- /* Digital drive output format description (optional?) */
- u_char reserved3;
- u_char bckf : 1; /* data valid on failing edge of BCK */
- u_char rch : 1; /* high LRCK indicates left channel */
- u_char lsbf : 1; /* set if LSB first */
- u_char dlen: 2;
-#define DLEN_32 0 /* 32 BCKs */
-#define DLEN_16 1 /* 16 BCKs */
-#define DLEN_24 2 /* 24 BCKs */
-#define DLEN_24_I2S 3 /* 24 BCKs (I2S) */
- u_char : 3;
- u_char reserved4[2];
-};
-
-struct wcd {
- struct atapi *ata; /* Controller structure */
- int unit; /* IDE bus drive unit */
- int lun; /* Logical device unit */
- int flags; /* Device state flags */
- int refcnt; /* The number of raw opens */
- struct buf_queue_head buf_queue; /* Queue of i/o requests */
- struct atapi_params *param; /* Drive parameters table */
- struct toc toc; /* Table of disc contents */
- struct volinfo info; /* Volume size info */
- struct audiopage au; /* Audio page info */
- struct cappage cap; /* Capabilities page info */
- struct audiopage aumask; /* Audio page mask */
- struct subchan subchan; /* Subchannel info */
- char description[80]; /* Device description */
-#ifdef DEVFS
- void *ra_devfs_token;
- void *rc_devfs_token;
- void *a_devfs_token;
- void *c_devfs_token;
-#endif
-};
-
-struct wcd *wcdtab[NUNIT]; /* Drive info by unit number */
-static int wcdnlun = 0; /* Number of configured drives */
-
-static void wcd_start (struct wcd *t);
-static void wcd_done (struct wcd *t, struct buf *bp, int resid,
- struct atapires result);
-static void wcd_error (struct wcd *t, struct atapires result);
-static int wcd_read_toc (struct wcd *t);
-static int wcd_request_wait (struct wcd *t, 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, char *addr, int count);
-static void wcd_describe (struct wcd *t);
-static int wcd_open(dev_t dev, int rawflag);
-static int wcd_setchan (struct wcd *t,
- u_char c0, u_char c1, u_char c2, u_char c3);
-static int wcd_eject (struct wcd *t, int closeit);
-
-/*
- * Dump the array in hexadecimal format for debugging purposes.
- */
-static void wcd_dump (int lun, char *label, void *data, int len)
-{
- u_char *p = data;
-
- printf ("wcd%d: %s %x", lun, label, *p++);
- while (--len > 0)
- printf ("-%x", *p++);
- printf ("\n");
-}
-
-#ifndef ATAPI_STATIC
-static
-#endif
-int
-wcdattach (struct atapi *ata, int unit, struct atapi_params *ap, int debug)
-{
- struct wcd *t;
- struct atapires result;
- int lun;
-
- if (wcdnlun >= NUNIT) {
- printf ("wcd: too many units\n");
- return (0);
- }
- if (!atapi_request_immediate) {
- printf("wcd: configuration error, ATAPI core code not present!\n");
- printf("wcd: check `options ATAPI_STATIC' in your kernel config file!\n");
- return (0);
- }
- t = malloc (sizeof (struct wcd), M_TEMP, M_NOWAIT);
- if (! t) {
- printf ("wcd: out of memory\n");
- return (0);
- }
- wcdtab[wcdnlun] = t;
- bzero (t, sizeof (struct wcd));
- t->ata = ata;
- t->unit = unit;
- lun = t->lun = wcdnlun++;
- t->param = ap;
- t->flags = F_MEDIA_CHANGED;
- t->refcnt = 0;
- if (debug) {
- t->flags |= F_DEBUG;
- /* Print params. */
- wcd_dump (t->lun, "info", ap, sizeof *ap);
- }
-
- /* Get drive capabilities. */
- result = atapi_request_immediate (ata, unit, ATAPI_MODE_SENSE,
- 0, CAP_PAGE, 0, 0, 0, 0, sizeof (t->cap) >> 8, sizeof (t->cap),
- 0, 0, 0, 0, 0, 0, 0, (char*) &t->cap, sizeof (t->cap));
-
- /* Do it twice to avoid the stale media changed state. */
- if (result.code == RES_ERR &&
- (result.error & AER_SKEY) == AER_SK_UNIT_ATTENTION)
- result = atapi_request_immediate (ata, unit, ATAPI_MODE_SENSE,
- 0, CAP_PAGE, 0, 0, 0, 0, sizeof (t->cap) >> 8,
- sizeof (t->cap), 0, 0, 0, 0, 0, 0, 0,
- (char*) &t->cap, sizeof (t->cap));
-
- /* Some drives have shorter capabilities page. */
- if (result.code == RES_UNDERRUN)
- result.code = 0;
-
- if (result.code == 0) {
- wcd_describe (t);
- if (t->flags & F_DEBUG)
- wcd_dump (t->lun, "cap", &t->cap, sizeof t->cap);
- }
-
-
-#ifdef DEVFS
- t->ra_devfs_token =
- devfs_add_devswf(&wcd_cdevsw, dkmakeminor(lun, 0, 0),
- DV_CHR, UID_ROOT, GID_OPERATOR, 0640,
- "rwcd%da", lun);
- t->rc_devfs_token =
- devfs_add_devswf(&wcd_cdevsw, dkmakeminor(lun, 0, RAW_PART),
- DV_CHR, UID_ROOT, GID_OPERATOR, 0640,
- "rwcd%dc", lun);
- t->a_devfs_token =
- devfs_add_devswf(&wcd_bdevsw, dkmakeminor(lun, 0, 0),
- DV_BLK, UID_ROOT, GID_OPERATOR, 0640,
- "wcd%da", lun);
- t->c_devfs_token =
- devfs_add_devswf(&wcd_bdevsw, dkmakeminor(lun, 0, RAW_PART),
- DV_BLK, UID_ROOT, GID_OPERATOR, 0640,
- "wcd%dc", lun);
-#endif
- return (1);
-}
-
-void wcd_describe (struct wcd *t)
-{
- char *m;
-
- t->cap.max_speed = ntohs (t->cap.max_speed);
- t->cap.max_vol_levels = ntohs (t->cap.max_vol_levels);
- t->cap.buf_size = ntohs (t->cap.buf_size);
- t->cap.cur_speed = ntohs (t->cap.cur_speed);
-
- printf ("wcd%d: ", t->lun);
- if (t->cap.cur_speed != t->cap.max_speed)
- printf ("%d/", t->cap.cur_speed * 1000 / 1024);
- printf ("%dKb/sec", t->cap.max_speed * 1000 / 1024);
- if (t->cap.buf_size)
- printf (", %dKb cache", t->cap.buf_size);
-
- if (t->cap.audio_play)
- printf (", audio play");
- if (t->cap.max_vol_levels)
- printf (", %d volume levels", t->cap.max_vol_levels);
-
- switch (t->cap.mech) {
- default: m = 0; break;
- case MECH_CADDY: m = "caddy"; break;
- case MECH_TRAY: m = "tray"; break;
- case MECH_POPUP: m = "popup"; break;
- case MECH_CHANGER: m = "changer"; break;
- case MECH_CARTRIDGE: m = "cartridge"; break;
- }
- if (m)
- printf (", %s%s", t->cap.eject ? "ejectable " : "", m);
- else if (t->cap.eject)
- printf (", eject");
- printf ("\n");
-
- printf ("wcd%d: ", t->lun);
- switch (t->cap.medium_type) {
- case MDT_UNKNOWN: printf ("medium type unknown"); break;
- case MDT_DATA_120: printf ("120mm data disc loaded"); break;
- case MDT_AUDIO_120: printf ("120mm audio disc loaded"); break;
- case MDT_COMB_120: printf ("120mm data/audio disc loaded"); break;
- case MDT_PHOTO_120: printf ("120mm photo disc loaded"); break;
- case MDT_DATA_80: printf ("80mm data disc loaded"); break;
- case MDT_AUDIO_80: printf ("80mm audio disc loaded"); break;
- case MDT_COMB_80: printf ("80mm data/audio disc loaded"); break;
- case MDT_PHOTO_80: printf ("80mm photo disc loaded"); break;
- case MDT_NO_DISC: printf ("no disc inside"); break;
- case MDT_DOOR_OPEN: printf ("door open"); break;
- case MDT_FMT_ERROR: printf ("medium format error"); break;
- default: printf ("medium type=0x%x", t->cap.medium_type); break;
- }
- if (t->cap.lock)
- printf (t->cap.locked ? ", locked" : ", unlocked");
- if (t->cap.prevent)
- printf (", lock protected");
- printf ("\n");
-}
-
-static int
-wcd_open (dev_t dev, int rawflag)
-{
- int lun = UNIT(dev);
- struct wcd *t;
-
- /* Check that the device number is legal
- * and the ATAPI driver is loaded. */
- if (lun >= wcdnlun || ! atapi_request_immediate)
- return (ENXIO);
- t = wcdtab[lun];
-
- /* On the first open, read the table of contents. */
- if (! (t->flags & F_BOPEN) && ! t->refcnt) {
- /* Read table of contents. */
- if (wcd_read_toc (t) < 0)
- return (EIO);
-
- /* Lock the media. */
- wcd_request_wait (t, ATAPI_PREVENT_ALLOW,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
- }
- if (rawflag)
- ++t->refcnt;
- else
- t->flags |= F_BOPEN;
- return (0);
-}
-
-int wcdbopen (dev_t dev, int flags, int fmt, struct proc *p)
-{
- return wcd_open (dev, 0);
-}
-
-int wcdropen (dev_t dev, int flags, int fmt, struct proc *p)
-{
- return wcd_open (dev, 1);
-}
-
-/*
- * Close the device. Only called if we are the LAST
- * occurence of an open device.
- */
-int wcdbclose (dev_t dev, int flags, int fmt, struct proc *p)
-{
- int lun = UNIT(dev);
- struct wcd *t = wcdtab[lun];
-
- /* If we were the last open of the entire device, release it. */
- if (! t->refcnt)
- wcd_request_wait (t, ATAPI_PREVENT_ALLOW,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- t->flags &= ~F_BOPEN;
- return (0);
-}
-
-int wcdrclose (dev_t dev, int flags, int fmt, struct proc *p)
-{
- int lun = UNIT(dev);
- struct wcd *t = wcdtab[lun];
-
- /* If we were the last open of the entire device, release it. */
- if (! (t->flags & F_BOPEN) && t->refcnt == 1)
- wcd_request_wait (t, ATAPI_PREVENT_ALLOW,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- --t->refcnt;
- return (0);
-}
-
-/*
- * Actually translate the requested transfer into one the physical driver can
- * understand. The transfer is described by a buf and will include only one
- * physical transfer.
- */
-void wcdstrategy (struct buf *bp)
-{
- int lun = UNIT(bp->b_dev);
- struct wcd *t = wcdtab[lun];
- int x;
-
- /* Can't ever write to a CD. */
- if (! (bp->b_flags & B_READ)) {
- bp->b_error = EROFS;
- bp->b_flags |= B_ERROR;
- biodone (bp);
- return;
- }
-
- /* If it's a null transfer, return immediatly. */
- if (bp->b_bcount == 0) {
- bp->b_resid = 0;
- biodone (bp);
- return;
- }
-
- /* Process transfer request. */
- bp->b_pblkno = bp->b_blkno;
- bp->b_resid = bp->b_bcount;
- x = splbio();
-
- /* Place it in the queue of disk activities for this disk. */
- tqdisksort (&t->buf_queue, bp);
-
- /* Tell the device to get going on the transfer if it's
- * not doing anything, otherwise just wait for completion. */
- wcd_start (t);
- splx(x);
-}
-
-/*
- * Look to see if there is a buf waiting for the device
- * and that the device is not already busy. If both are true,
- * It dequeues the buf and creates an ATAPI command to perform the
- * transfer in the buf.
- * The bufs are queued by the strategy routine (wcdstrategy).
- * Must be called at the correct (splbio) level.
- */
-static void wcd_start (struct wcd *t)
-{
- struct buf *bp = TAILQ_FIRST(&t->buf_queue);
- u_long blkno, nblk;
-
- /* See if there is a buf to do and we are not already doing one. */
- if (! bp)
- return;
-
- /* Unqueue the request. */
- TAILQ_REMOVE(&t->buf_queue, bp, b_act);
-
- /* Should reject all queued entries if media have changed. */
- if (t->flags & F_MEDIA_CHANGED) {
- bp->b_error = EIO;
- bp->b_flags |= B_ERROR;
- biodone (bp);
- return;
- }
-
- /* We have a buf, now we should make a command
- * First, translate the block to absolute and put it in terms of the
- * logical blocksize of the device.
- * What if something asks for 512 bytes not on a 2k boundary? */
- blkno = bp->b_blkno / (SECSIZE / 512);
- nblk = (bp->b_bcount + (SECSIZE - 1)) / SECSIZE;
-
- atapi_request_callback (t->ata, t->unit, ATAPI_READ_BIG, 0,
- blkno>>24, blkno>>16, blkno>>8, blkno, 0, nblk>>8, nblk, 0, 0,
- 0, 0, 0, 0, 0, (u_char*) bp->b_un.b_addr, bp->b_bcount,
- wcd_done, t, bp);
-}
-
-static void wcd_done (struct wcd *t, struct buf *bp, int resid,
- struct atapires result)
-{
- if (result.code) {
- wcd_error (t, result);
- bp->b_error = EIO;
- bp->b_flags |= B_ERROR;
- } else
- bp->b_resid = resid;
- biodone (bp);
- wcd_start (t);
-}
-
-static void wcd_error (struct wcd *t, struct atapires result)
-{
- if (result.code != RES_ERR)
- return;
- switch (result.error & AER_SKEY) {
- case AER_SK_NOT_READY:
- if (result.error & ~AER_SKEY) {
- /* Audio disc. */
- printf ("wcd%d: cannot read audio disc\n", t->lun);
- return;
- }
- /* Tray open. */
- if (! (t->flags & F_MEDIA_CHANGED))
- printf ("wcd%d: tray open\n", t->lun);
- t->flags |= F_MEDIA_CHANGED;
- return;
-
- case AER_SK_UNIT_ATTENTION:
- /* Media changed. */
- if (! (t->flags & F_MEDIA_CHANGED))
- printf ("wcd%d: media changed\n", t->lun);
- t->flags |= F_MEDIA_CHANGED;
- return;
-
- case AER_SK_ILLEGAL_REQUEST:
- /* Unknown command or invalid command arguments. */
- if (t->flags & F_DEBUG)
- printf ("wcd%d: invalid command\n", t->lun);
- return;
- }
- printf ("wcd%d: i/o error, status=%b, error=%b\n", t->lun,
- result.status, ARS_BITS, result.error, AER_BITS);
-}
-
-static int wcd_request_wait (struct wcd *t, 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, char *addr, int count)
-{
- struct atapires result;
-
- result = atapi_request_wait (t->ata, t->unit, cmd,
- a1, a2, a3, a4, a5, a6, a7, a8, a9, 0, 0, 0, 0, 0, 0,
- addr, count);
- if (result.code) {
- wcd_error (t, result);
- return (EIO);
- }
- return (0);
-}
-
-static inline void lba2msf (int lba, u_char *m, u_char *s, u_char *f)
-{
- lba += 150; /* offset of first logical frame */
- lba &= 0xffffff; /* negative lbas use only 24 bits */
- *m = lba / (60 * 75);
- lba %= (60 * 75);
- *s = lba / 75;
- *f = lba % 75;
-}
-
-/*
- * Perform special action on behalf of the user.
- * Knows about the internals of this device
- */
-int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
-{
- int lun = UNIT(dev);
- struct wcd *t = wcdtab[lun];
- int error = 0;
-
- if (t->flags & F_MEDIA_CHANGED)
- switch (cmd) {
- case CDIOCSETDEBUG:
- case CDIOCCLRDEBUG:
- case CDIOCRESET:
- /* These ops are media change transparent. */
- break;
- default:
- /* Read table of contents. */
- wcd_read_toc (t);
-
- /* Lock the media. */
- wcd_request_wait (t, ATAPI_PREVENT_ALLOW,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
- break;
- }
- switch (cmd) {
- default:
- return (ENOTTY);
-
- case CDIOCSETDEBUG:
- if (p->p_cred->pc_ucred->cr_uid)
- return (EPERM);
- t->flags |= F_DEBUG;
- atapi_debug (t->ata, 1);
- return 0;
-
- case CDIOCCLRDEBUG:
- if (p->p_cred->pc_ucred->cr_uid)
- return (EPERM);
- t->flags &= ~F_DEBUG;
- atapi_debug (t->ata, 0);
- return 0;
-
- case CDIOCRESUME:
- return wcd_request_wait (t, ATAPI_PAUSE,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
-
- case CDIOCPAUSE:
- return wcd_request_wait (t, ATAPI_PAUSE,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
- case CDIOCSTART:
- return wcd_request_wait (t, ATAPI_START_STOP,
- 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
-
- case CDIOCSTOP:
- return wcd_request_wait (t, ATAPI_START_STOP,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
- case CDIOCALLOW:
- return wcd_request_wait (t, ATAPI_PREVENT_ALLOW,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
- case CDIOCPREVENT:
- return wcd_request_wait (t, ATAPI_PREVENT_ALLOW,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
-
- case CDIOCRESET:
- if (p->p_cred->pc_ucred->cr_uid)
- return (EPERM);
- return wcd_request_wait (t, ATAPI_TEST_UNIT_READY,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
- case CDIOCEJECT:
- /* Don't allow eject if the device is opened
- * by somebody (not us) in block mode. */
- if ((t->flags & F_BOPEN) && t->refcnt)
- return (EBUSY);
- return wcd_eject (t, 0);
-
- case CDIOCCLOSE:
- if ((t->flags & F_BOPEN) && t->refcnt)
- return (0);
- return wcd_eject (t, 1);
-
- case CDIOREADTOCHEADER:
- if (! t->toc.hdr.ending_track)
- return (EIO);
- bcopy (&t->toc.hdr, addr, sizeof t->toc.hdr);
- break;
-
- case CDIOREADTOCENTRYS: {
- struct ioc_read_toc_entry *te =
- (struct ioc_read_toc_entry*) addr;
- struct toc *toc = &t->toc;
- struct toc buf;
- u_long len;
- u_char starting_track = te->starting_track;
-
- if (! t->toc.hdr.ending_track)
- return (EIO);
-
- if ( te->data_len < sizeof(toc->tab[0])
- || (te->data_len % sizeof(toc->tab[0])) != 0
- || te->address_format != CD_MSF_FORMAT
- && te->address_format != CD_LBA_FORMAT
- )
- return EINVAL;
-
- if (starting_track == 0)
- starting_track = toc->hdr.starting_track;
- else if (starting_track == 170) /* Handle leadout request */
- starting_track = toc->hdr.ending_track + 1;
- else if (starting_track < toc->hdr.starting_track ||
- starting_track > toc->hdr.ending_track + 1)
- return (EINVAL);
-
- len = ((toc->hdr.ending_track + 1 - starting_track) + 1) *
- sizeof(toc->tab[0]);
- if (te->data_len < len)
- len = te->data_len;
- if (len > sizeof(toc->tab))
- return EINVAL;
-
- /* Convert to MSF format, if needed. */
- if (te->address_format == CD_MSF_FORMAT) {
- struct cd_toc_entry *e;
-
- buf = t->toc;
- toc = &buf;
- e = toc->tab + (toc->hdr.ending_track + 1 -
- toc->hdr.starting_track) + 1;
- while (--e >= toc->tab)
- lba2msf (ntohl(e->addr.lba), &e->addr.msf.minute,
- &e->addr.msf.second, &e->addr.msf.frame);
- }
- return copyout (toc->tab + starting_track -
- toc->hdr.starting_track, te->data, len);
- }
- case CDIOCREADSUBCHANNEL: {
- struct ioc_read_subchannel *args =
- (struct ioc_read_subchannel*) addr;
- struct cd_sub_channel_info data;
- u_long len = args->data_len;
- int abslba, rellba;
-
- if (len > sizeof(data) ||
- len < sizeof(struct cd_sub_channel_header))
- return (EINVAL);
-
- if (wcd_request_wait (t, ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0,
- 0, 0, sizeof (t->subchan) >> 8, sizeof (t->subchan),
- 0, (char*)&t->subchan, sizeof (t->subchan)) != 0)
- return (EIO);
- if (t->flags & F_DEBUG)
- wcd_dump (t->lun, "subchan", &t->subchan, sizeof t->subchan);
-
- abslba = t->subchan.abslba;
- rellba = t->subchan.rellba;
- if (args->address_format == CD_MSF_FORMAT) {
- lba2msf (ntohl(abslba),
- &data.what.position.absaddr.msf.minute,
- &data.what.position.absaddr.msf.second,
- &data.what.position.absaddr.msf.frame);
- lba2msf (ntohl(rellba),
- &data.what.position.reladdr.msf.minute,
- &data.what.position.reladdr.msf.second,
- &data.what.position.reladdr.msf.frame);
- } else {
- data.what.position.absaddr.lba = abslba;
- data.what.position.reladdr.lba = rellba;
- }
- data.header.audio_status = t->subchan.audio_status;
- data.what.position.control = t->subchan.control & 0xf;
- data.what.position.addr_type = t->subchan.control >> 4;
- data.what.position.track_number = t->subchan.track;
- data.what.position.index_number = t->subchan.indx;
-
- return copyout (&data, args->data, len);
- }
- case CDIOCPLAYMSF: {
- struct ioc_play_msf *args = (struct ioc_play_msf*) addr;
-
- return wcd_request_wait (t, ATAPI_PLAY_MSF, 0, 0,
- args->start_m, args->start_s, args->start_f,
- args->end_m, args->end_s, args->end_f, 0, 0, 0);
- }
- case CDIOCPLAYBLOCKS: {
- struct ioc_play_blocks *args = (struct ioc_play_blocks*) addr;
-
- return wcd_request_wait (t, ATAPI_PLAY_BIG, 0,
- args->blk >> 24 & 0xff, args->blk >> 16 & 0xff,
- args->blk >> 8 & 0xff, args->blk & 0xff,
- args->len >> 24 & 0xff, args->len >> 16 & 0xff,
- args->len >> 8 & 0xff, args->len & 0xff, 0, 0);
- }
- case CDIOCPLAYTRACKS: {
- struct ioc_play_track *args = (struct ioc_play_track*) addr;
- u_long start, len;
- int t1, t2;
-
- if (! t->toc.hdr.ending_track)
- return (EIO);
-
- /* Ignore index fields,
- * play from start_track to end_track inclusive. */
- if (args->end_track < t->toc.hdr.ending_track+1)
- ++args->end_track;
- if (args->end_track > t->toc.hdr.ending_track+1)
- args->end_track = t->toc.hdr.ending_track+1;
- t1 = args->start_track - t->toc.hdr.starting_track;
- t2 = args->end_track - t->toc.hdr.starting_track;
- if (t1 < 0 || t2 < 0)
- return (EINVAL);
- start = ntohl(t->toc.tab[t1].addr.lba);
- len = ntohl(t->toc.tab[t2].addr.lba) - start;
-
- return wcd_request_wait (t, ATAPI_PLAY_BIG, 0,
- start >> 24 & 0xff, start >> 16 & 0xff,
- start >> 8 & 0xff, start & 0xff,
- len >> 24 & 0xff, len >> 16 & 0xff,
- len >> 8 & 0xff, len & 0xff, 0, 0);
- }
- case CDIOCGETVOL: {
- struct ioc_vol *arg = (struct ioc_vol*) addr;
-
- error = wcd_request_wait (t, ATAPI_MODE_SENSE, 0, AUDIO_PAGE,
- 0, 0, 0, 0, sizeof (t->au) >> 8, sizeof (t->au), 0,
- (char*) &t->au, sizeof (t->au));
- if (error)
- return (error);
- if (t->flags & F_DEBUG)
- wcd_dump (t->lun, "au", &t->au, sizeof t->au);
- if (t->au.page_code != AUDIO_PAGE)
- return (EIO);
- arg->vol[0] = t->au.port[0].volume;
- arg->vol[1] = t->au.port[1].volume;
- arg->vol[2] = t->au.port[2].volume;
- arg->vol[3] = t->au.port[3].volume;
- break;
- }
- case CDIOCSETVOL: {
- struct ioc_vol *arg = (struct ioc_vol*) addr;
-
- error = wcd_request_wait (t, ATAPI_MODE_SENSE, 0, AUDIO_PAGE,
- 0, 0, 0, 0, sizeof (t->au) >> 8, sizeof (t->au), 0,
- (char*) &t->au, sizeof (t->au));
- if (error)
- return (error);
- if (t->flags & F_DEBUG)
- wcd_dump (t->lun, "au", &t->au, sizeof t->au);
- if (t->au.page_code != AUDIO_PAGE)
- return (EIO);
-
- error = wcd_request_wait (t, ATAPI_MODE_SENSE, 0,
- AUDIO_PAGE_MASK, 0, 0, 0, 0, sizeof (t->aumask) >> 8,
- sizeof (t->aumask), 0, (char*) &t->aumask,
- sizeof (t->aumask));
- if (error)
- return (error);
- if (t->flags & F_DEBUG)
- wcd_dump (t->lun, "mask", &t->aumask, sizeof t->aumask);
-
- /* Sony-55E requires the data length field to be zeroed. */
- t->au.data_length = 0;
-
- t->au.port[0].channels = CHANNEL_0;
- t->au.port[1].channels = CHANNEL_1;
- t->au.port[0].volume = arg->vol[0] & t->aumask.port[0].volume;
- t->au.port[1].volume = arg->vol[1] & t->aumask.port[1].volume;
- t->au.port[2].volume = arg->vol[2] & t->aumask.port[2].volume;
- t->au.port[3].volume = arg->vol[3] & t->aumask.port[3].volume;
- return wcd_request_wait (t, ATAPI_MODE_SELECT_BIG, 0x10,
- 0, 0, 0, 0, 0, sizeof (t->au) >> 8, sizeof (t->au),
- 0, (char*) &t->au, - sizeof (t->au));
- }
- case CDIOCSETPATCH: {
- struct ioc_patch *arg = (struct ioc_patch*) addr;
-
- return wcd_setchan (t, arg->patch[0], arg->patch[1],
- arg->patch[2], arg->patch[3]);
- }
- case CDIOCSETMONO:
- return wcd_setchan (t, CHANNEL_0 | CHANNEL_1,
- CHANNEL_0 | CHANNEL_1, 0, 0);
-
- case CDIOCSETSTERIO:
- return wcd_setchan (t, CHANNEL_0, CHANNEL_1, 0, 0);
-
- case CDIOCSETMUTE:
- return wcd_setchan (t, 0, 0, 0, 0);
-
- case CDIOCSETLEFT:
- return wcd_setchan (t, CHANNEL_0, CHANNEL_0, 0, 0);
-
- case CDIOCSETRIGHT:
- return wcd_setchan (t, CHANNEL_1, CHANNEL_1, 0, 0);
- }
- return (error);
-}
-
-/*
- * Read the entire TOC for the disc into our internal buffer.
- */
-static int wcd_read_toc (struct wcd *t)
-{
- int ntracks, len;
- struct atapires result;
-
- bzero (&t->toc, sizeof (t->toc));
- bzero (&t->info, sizeof (t->info));
-
- /* Check for the media.
- * Do it twice to avoid the stale media changed state. */
- result = atapi_request_wait (t->ata, t->unit, ATAPI_TEST_UNIT_READY,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
- if (result.code == RES_ERR &&
- (result.error & AER_SKEY) == AER_SK_UNIT_ATTENTION) {
- t->flags |= F_MEDIA_CHANGED;
- result = atapi_request_wait (t->ata, t->unit,
- ATAPI_TEST_UNIT_READY, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0);
- }
- if (result.code) {
- wcd_error (t, result);
- return (EIO);
- }
- t->flags &= ~F_MEDIA_CHANGED;
-
- /* First read just the header, so we know how long the TOC is. */
- len = sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry);
- if (wcd_request_wait (t, ATAPI_READ_TOC, 0, 0, 0, 0, 0, 0,
- len >> 8, len & 0xff, 0, (char*)&t->toc, len) != 0) {
-err: bzero (&t->toc, sizeof (t->toc));
- return (0);
- }
-
- ntracks = t->toc.hdr.ending_track - t->toc.hdr.starting_track + 1;
- if (ntracks <= 0 || ntracks > MAXTRK)
- goto err;
-
- /* Now read the whole schmeer. */
- len = sizeof(struct ioc_toc_header) +
- ntracks * sizeof(struct cd_toc_entry);
- if (wcd_request_wait (t, ATAPI_READ_TOC, 0, 0, 0, 0, 0, 0,
- len >> 8, len & 0xff, 0, (char*)&t->toc, len) & 0xff)
- goto err;
-
- NTOHS(t->toc.hdr.len);
-
- /* Read disc capacity. */
- if (wcd_request_wait (t, ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0, 0,
- 0, sizeof(t->info), 0, (char*)&t->info, sizeof(t->info)) != 0)
- bzero (&t->info, sizeof (t->info));
-
- /* make fake leadout entry */
- t->toc.tab[ntracks].control = t->toc.tab[ntracks-1].control;
- t->toc.tab[ntracks].addr_type = t->toc.tab[ntracks-1].addr_type;
- t->toc.tab[ntracks].track = 170; /* magic */
- t->toc.tab[ntracks].addr.lba = t->info.volsize;
-
- NTOHL(t->info.volsize);
- NTOHL(t->info.blksize);
-
- /* Print the disc description string on every disc change.
- * It would help to track the history of disc changes. */
- if (t->info.volsize && t->toc.hdr.ending_track &&
- (t->flags & F_MEDIA_CHANGED) && (t->flags & F_DEBUG)) {
- printf ("wcd%d: ", t->lun);
- if (t->toc.tab[0].control & 4)
- printf ("%ldMB ", t->info.volsize / 512);
- else
- printf ("%ld:%ld audio ", t->info.volsize/75/60,
- t->info.volsize/75%60);
- printf ("(%ld sectors), %d tracks\n", t->info.volsize,
- t->toc.hdr.ending_track - t->toc.hdr.starting_track + 1);
- }
- return (0);
-}
-
-/*
- * Set up the audio channel masks.
- */
-static int wcd_setchan (struct wcd *t,
- u_char c0, u_char c1, u_char c2, u_char c3)
-{
- int error;
-
- error = wcd_request_wait (t, ATAPI_MODE_SENSE, 0, AUDIO_PAGE,
- 0, 0, 0, 0, sizeof (t->au) >> 8, sizeof (t->au), 0,
- (char*) &t->au, sizeof (t->au));
- if (error)
- return (error);
- if (t->flags & F_DEBUG)
- wcd_dump (t->lun, "au", &t->au, sizeof t->au);
- if (t->au.page_code != AUDIO_PAGE)
- return (EIO);
-
- /* Sony-55E requires the data length field to be zeroed. */
- t->au.data_length = 0;
-
- t->au.port[0].channels = c0;
- t->au.port[1].channels = c1;
- t->au.port[2].channels = c2;
- t->au.port[3].channels = c3;
- return wcd_request_wait (t, ATAPI_MODE_SELECT_BIG, 0x10,
- 0, 0, 0, 0, 0, sizeof (t->au) >> 8, sizeof (t->au),
- 0, (char*) &t->au, - sizeof (t->au));
-}
-
-static int wcd_eject (struct wcd *t, int closeit)
-{
- struct atapires result;
-
- /* Try to stop the disc. */
- result = atapi_request_wait (t->ata, t->unit, ATAPI_START_STOP,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
- if (result.code == RES_ERR &&
- ((result.error & AER_SKEY) == AER_SK_NOT_READY ||
- (result.error & AER_SKEY) == AER_SK_UNIT_ATTENTION)) {
- int err;
-
- if (!closeit)
- return (0);
- /*
- * The disc was unloaded.
- * Load it (close tray).
- * Read the table of contents.
- */
- err = wcd_request_wait (t, ATAPI_START_STOP,
- 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0);
- if (err)
- return (err);
-
- /* Read table of contents. */
- wcd_read_toc (t);
-
- /* Lock the media. */
- wcd_request_wait (t, ATAPI_PREVENT_ALLOW,
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
-
- return (0);
- }
-
- if (result.code) {
- wcd_error (t, result);
- return (EIO);
- }
-
- if (closeit)
- return (0);
-
- /* Give it some time to stop spinning. */
- tsleep ((caddr_t)&lbolt, PRIBIO, "wcdej1", 0);
- tsleep ((caddr_t)&lbolt, PRIBIO, "wcdej2", 0);
-
- /* Unlock. */
- wcd_request_wait (t, ATAPI_PREVENT_ALLOW,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
-
- /* Eject. */
- t->flags |= F_MEDIA_CHANGED;
- return wcd_request_wait (t, ATAPI_START_STOP,
- 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0);
-}
-
-#ifdef WCD_MODULE
-/*
- * Loadable ATAPI CD-ROM driver stubs.
- */
-#include <sys/exec.h>
-#include <sys/sysent.h>
-#include <sys/lkm.h>
-
-/*
- * Construct lkm_dev structures (see lkm.h).
- * Our bdevsw/cdevsw slot numbers are 19/69.
- */
-
-
-MOD_DEV(wcd, LM_DT_BLOCK, BDEV_MAJOR, &wcd_bdevsw);
-MOD_DEV(rwcd, LM_DT_CHAR, CDEV_MAJOR, &wcd_cdevsw);
-
-/*
- * Function called when loading the driver.
- */
-int wcd_load (struct lkm_table *lkmtp, int cmd)
-{
- struct atapi *ata;
- int n, u;
-
- if (! atapi_start)
- /* No ATAPI driver available. */
- return EPROTONOSUPPORT;
- n = 0;
- for (ata=atapi_tab; ata<atapi_tab+2; ++ata)
- if (ata->port)
- for (u=0; u<2; ++u)
- /* Probing controller ata->ctrlr, unit u. */
- if (ata->params[u] && ! ata->attached[u] &&
- wcdattach (ata, u, ata->params[u],
- ata->debug) >= 0)
- {
- /* Drive found. */
- ata->attached[u] = 1;
- ++n;
- }
- if (! n)
- /* No IDE CD-ROMs found. */
- return ENXIO;
- return 0;
-}
-
-/*
- * Function called when unloading the driver.
- */
-int wcd_unload (struct lkm_table *lkmtp, int cmd)
-{
- struct wcd **t;
-
- for (t=wcdtab; t<wcdtab+wcdnlun; ++t)
- if (((*t)->flags & F_BOPEN) || (*t)->refcnt)
- /* The device is opened, cannot unload the driver. */
- return EBUSY;
- for (t=wcdtab; t<wcdtab+wcdnlun; ++t) {
- (*t)->ata->attached[(*t)->unit] = 0;
- free (*t, M_TEMP);
- }
- wcdnlun = 0;
- bzero (wcdtab, sizeof(wcdtab));
- return 0;
-}
-
-/*
- * Dispatcher function for the module (load/unload/stat).
- */
-int wcd_mod (struct lkm_table *lkmtp, int cmd, int ver)
-{
- int err = 0;
-
- if (ver != LKM_VERSION)
- return EINVAL;
-
- if (cmd == LKM_E_LOAD)
- err = wcd_load (lkmtp, cmd);
- else if (cmd == LKM_E_UNLOAD)
- err = wcd_unload (lkmtp, cmd);
- if (err)
- return err;
-
- /* Register the cdevsw entry. */
- lkmtp->private.lkm_dev = &rwcd_module;
- err = lkmdispatch (lkmtp, cmd);
- if (err)
- return err;
-
- /* Register the bdevsw entry. */
- lkmtp->private.lkm_dev = &wcd_module;
- return lkmdispatch (lkmtp, cmd);
-}
-#endif /* WCD_MODULE */
-
-static wcd_devsw_installed = 0;
-
-static void wcd_drvinit(void *unused)
-{
- dev_t dev;
-
- if( ! wcd_devsw_installed ) {
- dev = makedev(CDEV_MAJOR, 0);
- cdevsw_add(&dev,&wcd_cdevsw, NULL);
- dev = makedev(BDEV_MAJOR, 0);
- bdevsw_add(&dev,&wcd_bdevsw, NULL);
- wcd_devsw_installed = 1;
- }
-}
-
-SYSINIT(wcddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,wcd_drvinit,NULL)
-
-
-#endif /* NWCD && NWDC && ATAPI */
diff --git a/sys/pc98/pc98/wd.c b/sys/pc98/pc98/wd.c
index 970a544..b023177 100644
--- a/sys/pc98/pc98/wd.c
+++ b/sys/pc98/pc98/wd.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
- * $Id: wd.c,v 1.8 1996/10/09 21:46:52 asami Exp $
+ * $Id: wd.c,v 1.9 1996/10/23 07:25:35 asami Exp $
*/
/* TODO:
@@ -89,14 +89,11 @@
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/epsonio.h>
-#include <i386/isa/isa_device.h>
-#include <pc98/pc98/wdreg.h>
#else
-#include <i386/i386/cons.h>
#include <i386/isa/isa.h>
+#endif
#include <i386/isa/isa_device.h>
#include <i386/isa/wdreg.h>
-#endif
#include <sys/syslog.h>
#include <sys/dkstat.h>
#include <vm/vm.h>
@@ -105,12 +102,8 @@
#include <vm/pmap.h>
#ifdef ATAPI
-#ifdef PC98
-#include <pc98/pc98/atapi.h>
-#else
#include <i386/isa/atapi.h>
#endif
-#endif
extern void wdstart(int ctrlr);
@@ -252,6 +245,10 @@ static timeout_t wdtimeout;
static int wdunwedge(struct disk *du);
static int wdwait(struct disk *du, u_char bits_wanted, int timeout);
+struct isa_driver wdcdriver = {
+ wdprobe, wdattach, "wdc",
+};
+
static d_open_t wdopen;
static d_close_t wdclose;
static d_strategy_t wdstrategy;
@@ -266,10 +263,6 @@ static struct bdevsw wd_bdevsw =
{ wdopen, wdclose, wdstrategy, wdioctl, /*0*/
wddump, wdsize, 0, "wd", &wd_cdevsw, -1 };
-struct isa_driver wdcdriver = {
- wdprobe, wdattach, "wdc",
-};
-
/*
* Probe for controller.
*/
@@ -489,11 +482,25 @@ wdattach(struct isa_device *dvp)
printf("wd%d: size unknown, using %s values\n",
lunit, du->dk_dd.d_secperunit > 17
? "BIOS" : "fake");
+#ifdef PC98 /* XXX */
+ if (du->dk_dd.d_secperunit > 8 * 1024 * 1024) {
+ du->dk_dd.d_ncylinders =
+ bootinfo.bi_bios_geom[du->dk_unit] >> 16;
+ du->dk_dd.d_secperunit =
+ du->dk_dd.d_ncylinders
+ * du->dk_dd.d_ntracks
+ * du->dk_dd.d_nsectors;
+ }
+#endif
printf(
"wd%d: %luMB (%lu sectors), %lu cyls, %lu heads, %lu S/T, %lu B/S\n",
lunit,
du->dk_dd.d_secperunit
+#ifdef PC98
+ / ( 1024 * 1024 / du->dk_dd.d_secsize) ,
+#else
* du->dk_dd.d_secsize / (1024 * 1024),
+#endif
du->dk_dd.d_secperunit,
du->dk_dd.d_ncylinders,
du->dk_dd.d_ntracks,
diff --git a/sys/pc98/pc98/wdreg.h b/sys/pc98/pc98/wdreg.h
deleted file mode 100644
index 5edd123..0000000
--- a/sys/pc98/pc98/wdreg.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*-
- * Copyright (c) 1991 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.
- *
- * from: @(#)wdreg.h 7.1 (Berkeley) 5/9/91
- * $Id: wdreg.h,v 1.12 1996/06/08 10:03:38 bde Exp $
- */
-
-#if 0
-static char rcsid[] = "$Id: wdreg.h,v 1.2 1992/12/06 14:05:28 ukai Exp ukai $";
-#endif
-
-/*
- * modified for PC9801 by F.Ukai
- * Kyoto University Microcomputer Club (KMC)
- */
-
-/*
- * Disk Controller register definitions.
- */
-#ifdef PC98
- /***** PC98 *****/
-#define wd_data 0x0 /* data register (R/W - 16 bits) */
-#define wd_error 0x2 /* error register (R) */
-#define wd_precomp wd_error /* write precompensation (W) */
-#define wd_features wd_error /* features register (W) */
-#define wd_seccnt 0x4 /* sector count (R/W) */
-#define wd_sector 0x6 /* first sector number (R/W) */
-#define wd_cyl_lo 0x8 /* cylinder address, low byte (R/W) */
-#define wd_cyl_hi 0xa /* cylinder address, high byte (R/W)*/
-#define wd_sdh 0xc /* sector size/drive/head (R/W)*/
-#define wd_command 0xe /* command register (W) */
-#define wd_status wd_command /* immediate status (R) */
-
-#define wd_altsts_nec 0x10c /*alternate fixed disk status(via 1015) (R)*/
-#define wd_ctlr_nec 0x10c /*fixed disk controller control(via 1015) (W)*/
-#define wd_altsts_epson 0x3 /*alternate fixed disk status(via 1015) (R)*/
-#define wd_ctlr_epson 0x3 /*fixed disk controller control(via 1015) (W)*/
-
-#define WDCTL_4BIT 0x8 /* use four head bits (wd1003) */
-#define WDCTL_RST 0x4 /* reset the controller */
-#define WDCTL_IDS 0x2 /* disable controller interrupts */
-#define wd_digin 0x10e /* disk controller input(via 1015) (R)*/
-#else /* IBM-PC */
- /***** IBM-PC *****/
-#define wd_data 0x0 /* data register (R/W - 16 bits) */
-#define wd_error 0x1 /* error register (R) */
-#define wd_precomp wd_error /* write precompensation (W) */
-#define wd_seccnt 0x2 /* sector count (R/W) */
-#define wd_sector 0x3 /* first sector number (R/W) */
-#define wd_cyl_lo 0x4 /* cylinder address, low byte (R/W) */
-#define wd_cyl_hi 0x5 /* cylinder address, high byte (R/W)*/
-#define wd_sdh 0x6 /* sector size/drive/head (R/W)*/
-#define wd_command 0x7 /* command register (W) */
-#define wd_status wd_command /* immediate status (R) */
-
-#define wd_altsts 0x206 /*alternate fixed disk status(via 1015) (R)*/
-#define wd_ctlr 0x206 /*fixed disk controller control(via 1015) (W)*/
-#define WDCTL_4BIT 0x8 /* use four head bits (wd1003) */
-#define WDCTL_RST 0x4 /* reset the controller */
-#define WDCTL_IDS 0x2 /* disable controller interrupts */
-#define wd_digin 0x207 /* disk controller input(via 1015) (R)*/
-#endif /* PC98 */
-
-/*
- * Status Bits.
- */
-#define WDCS_BUSY 0x80 /* Controller busy bit. */
-#define WDCS_READY 0x40 /* Selected drive is ready */
-#define WDCS_WRTFLT 0x20 /* Write fault */
-#define WDCS_SEEKCMPLT 0x10 /* Seek complete */
-#define WDCS_DRQ 0x08 /* Data request bit. */
-#define WDCS_ECCCOR 0x04 /* ECC correction made in data */
-#define WDCS_INDEX 0x02 /* Index pulse from selected drive */
-#define WDCS_ERR 0x01 /* Error detect bit. */
-
-#define WDCS_BITS "\020\010busy\007rdy\006wrtflt\005seekdone\004drq\003ecc_cor\002index\001err"
-#define WDERR_ABORT 0x04
-
-#define WDERR_BITS "\020\010badblk\007uncorr\006id_crc\005no_id\003abort\002tr000\001no_dam"
-
-/*
- * Commands for Disk Controller.
- */
-#define WDCC_RESTORE 0x10 /* disk restore code -- resets cntlr */
-
-#define WDCC_READ 0x20 /* disk read code */
-#define WDCC_WRITE 0x30 /* disk write code */
-#define WDCC__LONG 0x02 /* modifier -- access ecc bytes */
-#define WDCC__NORETRY 0x01 /* modifier -- no retrys */
-
-#define WDCC_FORMAT 0x50 /* disk format code */
-#define WDCC_DIAGNOSE 0x90 /* controller diagnostic */
-#define WDCC_IDC 0x91 /* initialize drive command */
-#define WDCC_READ_MULTI 0xC4 /* read multiple */
-#define WDCC_WRITE_MULTI 0xC5 /* write multiple */
-#define WDCC_SET_MULTI 0xC6 /* set multiple count */
-
-
-#define WDCC_EXTDCMD 0xE0 /* send extended command */
-#define WDCC_READP 0xEC /* read parameters from controller */
-#define WDCC_FEATURES 0xEF /* features control */
-
-#define WDFEA_RCACHE 0xAA /* read cache enable */
-#define WDFEA_WCACHE 0x02 /* write cache enable */
-
-#define WD_STEP 0 /* winchester- default 35us step */
-
-#define WDSD_IBM 0xa0 /* forced to 512 byte sector, ecc */
-
-#ifdef KERNEL
-/*
- * read parameters command returns this:
- */
-struct wdparams {
- /* drive info */
- short wdp_config; /* general configuration bits */
- short wdp_cylinders; /* number of cylinders */
- short wdp_reserved;
- short wdp_heads; /* number of heads */
- short wdp_unfbytespertrk; /* number of unformatted bytes/track */
- short wdp_unfbytes; /* number of unformatted bytes/sector */
- short wdp_sectors; /* number of sectors per track */
- short wdp_vendorunique[3];
- /* controller info */
- char wdp_serial[20]; /* serial number */
- short wdp_buffertype; /* buffer type */
-#define WDTYPE_SINGLEPORTSECTOR 1 /* single port, single sector buffer */
-#define WDTYPE_DUALPORTMULTI 2 /* dual port, multiple sector buffer */
-#define WDTYPE_DUALPORTMULTICACHE 3 /* above plus track cache */
- short wdp_buffersize; /* buffer size, in 512-byte units */
- short wdp_necc; /* ecc bytes appended */
- char wdp_rev[8]; /* firmware revision */
- char wdp_model[40]; /* model name */
- short wdp_nsecperint; /* sectors per interrupt */
- short wdp_usedmovsd; /* can use double word read/write? */
-};
-
-/*
- * wd driver entry points
- */
-#ifdef B_FORMAT
-int wdformat(struct buf *bp);
-#endif
-
-/*
- * IDE DMA support.
- * This is based on what is needed for the IDE DMA function of the Intel
- * Triton chipset; hopefully it's general enough to be used for other
- * chipsets as well.
- *
- * To use this:
- * For each drive which you might want to do DMA on, call wdd_candma()
- * to get a cookie. If it returns a null pointer, then the drive
- * can't do DMA.
- *
- * Set up the transfer be calling wdd_dmaprep(). The cookie is what
- * you got before; vaddr is the virtual address of the buffer to be
- * written; len is the length of the buffer; and direction is either
- * B_READ or B_WRITE.
- *
- * Send a read/write DMA command to the drive.
- *
- * Call wdd_dmastart().
- *
- * Wait for an interrupt. Multi-sector transfers will only interrupt
- * at the end of the transfer.
- *
- * Call wdd_dmadone(). It will return the status as defined by the
- * WDDS_* constants below.
- */
-struct wddma {
- void *(*wdd_candma) /* returns a cookie if can do DMA */
- __P((int ctlr, int drive));
- int (*wdd_dmaprep) /* prepare DMA hardware */
- __P((void *cookie, char *vaddr, u_long len, int direction));
- void (*wdd_dmastart) /* begin DMA transfer */
- __P((void *cookie));
- int (*wdd_dmadone) /* DMA transfer completed */
- __P((void *cookie));
- int (*wdd_dmastatus) /* return status of DMA */
- __P((void *cookie));
-};
-
-#define WDDS_ACTIVE 0x0001
-#define WDDS_ERROR 0x0002
-#define WDDS_INTERRUPT 0x0004
-
-extern struct wddma wddma;
-
-#endif /* KERNEL */
OpenPOWER on IntegriCloud