summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1994-04-23 01:50:14 +0000
committerache <ache@FreeBSD.org>1994-04-23 01:50:14 +0000
commit8c1b1c10fa5c063441fc84538cf506af4de8e39a (patch)
treeeefc94a690c6ee2a3b9ead56cb983ce789332964
parent17ab3af527a10374eb42d4a22109e18a16d8a96b (diff)
downloadFreeBSD-src-8c1b1c10fa5c063441fc84538cf506af4de8e39a.zip
FreeBSD-src-8c1b1c10fa5c063441fc84538cf506af4de8e39a.tar.gz
Update sound driver to version 2.5
-rw-r--r--sys/i386/isa/sound/CHANGELOG22
-rw-r--r--sys/i386/isa/sound/RELNOTES.Linux47
-rw-r--r--sys/i386/isa/sound/adlib_card.c10
-rw-r--r--sys/i386/isa/sound/audio.c20
-rw-r--r--sys/i386/isa/sound/dev_table.c21
-rw-r--r--sys/i386/isa/sound/dev_table.h4
-rw-r--r--sys/i386/isa/sound/dmabuf.c81
-rw-r--r--sys/i386/isa/sound/gus_card.c10
-rw-r--r--sys/i386/isa/sound/gus_hw.h15
-rw-r--r--sys/i386/isa/sound/gus_midi.c10
-rw-r--r--sys/i386/isa/sound/gus_vol.c63
-rw-r--r--sys/i386/isa/sound/gus_wave.c1211
-rw-r--r--sys/i386/isa/sound/midibuf.c12
-rw-r--r--sys/i386/isa/sound/mpu401.c79
-rw-r--r--sys/i386/isa/sound/opl3.c52
-rw-r--r--sys/i386/isa/sound/pas.h6
-rw-r--r--sys/i386/isa/sound/pas2_card.c18
-rw-r--r--sys/i386/isa/sound/pas2_midi.c16
-rw-r--r--sys/i386/isa/sound/pas2_mixer.c14
-rw-r--r--sys/i386/isa/sound/pas2_pcm.c29
-rw-r--r--sys/i386/isa/sound/patmgr.c10
-rw-r--r--sys/i386/isa/sound/sb16_dsp.c86
-rw-r--r--sys/i386/isa/sound/sb16_midi.c65
-rw-r--r--sys/i386/isa/sound/sb_card.c10
-rw-r--r--sys/i386/isa/sound/sb_dsp.c131
-rw-r--r--sys/i386/isa/sound/sb_midi.c42
-rw-r--r--sys/i386/isa/sound/sb_mixer.c89
-rw-r--r--sys/i386/isa/sound/sb_mixer.h40
-rw-r--r--sys/i386/isa/sound/sequencer.c36
-rw-r--r--sys/i386/isa/sound/sound_calls.h7
-rw-r--r--sys/i386/isa/sound/sound_switch.c11
31 files changed, 1302 insertions, 965 deletions
diff --git a/sys/i386/isa/sound/CHANGELOG b/sys/i386/isa/sound/CHANGELOG
index 78168dd..6a9bef1 100644
--- a/sys/i386/isa/sound/CHANGELOG
+++ b/sys/i386/isa/sound/CHANGELOG
@@ -1,6 +1,26 @@
-Changelog for version 2.4
+Changelog for version 2.5
-------------------------
+Since 2.5-beta2
+- Some fine tuning to the GUS v3.7 mixer code.
+- Fixed speed limits for the plain SB (1.0 to 2.0).
+
+Since 2.5-beta
+- Fixed OPL-3 detection with SB. Caused problems with PAS16.
+- GUS v3.7 mixer support.
+
+Since 2.4
+- Mixer support for Sound Galaxy NX Pro (define __SGNXPRO__ on your local.h).
+- Fixed truncated sound on /dev/dsp when the device is closed.
+- Linear volume mode for GUS
+- Pitch bends larger than +/- 2 octaves.
+- MIDI recording for SB and SB Pro. (Untested).
+- Some other fixes.
+- SB16 MIDI and DSP drivers only initialized if SB16 actually installed.
+- Implemented better detection for OPL-3. This should be usefull if you
+ have an old SB Pro (the non-OPL-3 one) or a SB 2.0 clone which has a OPL-3.
+- SVR4.2 support by Ian Hartas. Initial ALPHA TEST version (untested).
+
Since 2.3b
- Fixed bug which made it impossible to make long recordings to disk.
Recording was not restarted after a buffer overflow situation.
diff --git a/sys/i386/isa/sound/RELNOTES.Linux b/sys/i386/isa/sound/RELNOTES.Linux
index bd47ede..ea57d0a 100644
--- a/sys/i386/isa/sound/RELNOTES.Linux
+++ b/sys/i386/isa/sound/RELNOTES.Linux
@@ -1,5 +1,15 @@
-Release notes for the Linux Sound Driver 2.4
+Release notes for the Linux Sound Driver 2.5
--------------------------------------------
+There is also a version called 2.5-beta floating around the net. This
+version contains some fixes after it. Mainly to the SB and GUS code.
+
+CAUTION! The SVR4.2 port has not been tested much. Backup your system
+ carefully before trying it.
+
+This is mainly a bug fix release. There are couple of new things such as
+linear volume mode for GUS and MIDI recording for SB 2.0 and SB Pro.
+Also this version supports the mixer of GUS v3.7. (Support for GUS MAX and
+the 16-bit daughtercard is coming sooner or later).
NOTE! The sound driver is a part of the Linux kernel distribution also.
Check that your kernel doesn't have more recent version than this
@@ -17,17 +27,13 @@ time with the /dev/dsp. Also the WaveBlaster daughter board is supported.
No support for the ASP chip yet (the ASP chip can be installed but it's
not used by the driver).
-You will need the snd-util-2.4.tar.gz and snd-data-0.1.tar.Z
+You will need the snd-util-2.5.tar.gz and snd-data-0.1.tar.Z
packages to use this driver. They should be in the same
ftp site or BBS from where you got this driver. For
example at nic.funet.fi:pub/OS/Linux/*.
-There is a new version of the tracker program available (tracker-3_19.lzh) but
-I don't know where it is available. The tracker 3.10 has bugs and it don't work
-without some fixes. Look at the README of the snd-util-2.3.
-
If you are looking for the installation instructions, please
-look at linux/Readme.
+look at $OS/Readme.
This version supports the following soundcards:
GUS, SoundBlaster, SB Pro, SB16, Pro Audio Spectrum 16 and AdLib.
@@ -220,21 +226,28 @@ This driver contains code by several contributors. In addition several other
persons have given usefull suggestions. The following is a list of major
contributors. (I could have forgotten some names.)
- Craig Metz 1/2 of the PAS16 Mixer and PCM support
- Rob Hooft Volume computation algorithm for the FM synth.
- Mika Liljeberg uLaw encoding and decoding routines
- Greg Lee Volume computation algorithm for the GUS and
- lot's of valuable suggestions.
- Andy Warner ISC port
- Jim Lowe FreeBSD port
+ Craig Metz 1/2 of the PAS16 Mixer and PCM support
+ Rob Hooft Volume computation algorithm for the FM synth.
+ Mika Liljeberg uLaw encoding and decoding routines
+ Greg Lee Volume computation algorithm for the GUS and
+ lot's of valuable suggestions.
+ Andy Warner Initial ISC port
+ Jim Lowe Initial FreeBSD port
Anders Baekgaard Bughunting and valuable suggestions.
- Joerg Schubert SB16 DSP support.
- Andrew Robinson Improvements to the GUS driver
+ Joerg Schubert SB16 DSP support.
+ Andrew Robinson Improvements to the GUS driver
+ Megens SA MIDI recording for SB and SB Pro.
+ Mikael Nordqvist Linear volume support for GUS.
+ Ian Hartas SVR4.2 port
+ Markus Aroharju and
+ Risto Kankkunen Major contributions to the mixer support
+ of GUS v3.7.
+ Hunyue Yau Sound Galaxy NX Pro mixer support.
Regards,
Hannu Savolainen
-hsavolai@cs.helsinki.fi
+hannu@voxware.pp.fi, Hannu.Savolainen@Helsinki.fi
Snail mail: Hannu Savolainen
Pallaksentie 4 A 2
diff --git a/sys/i386/isa/sound/adlib_card.c b/sys/i386/isa/sound/adlib_card.c
index 3b7df5e..6365069 100644
--- a/sys/i386/isa/sound/adlib_card.c
+++ b/sys/i386/isa/sound/adlib_card.c
@@ -1,10 +1,10 @@
/*
* sound/adlib_card.c
- *
+ *
* Detection routine for the AdLib card.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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 "sound_config.h"
diff --git a/sys/i386/isa/sound/audio.c b/sys/i386/isa/sound/audio.c
index 84c1f6c..f27f9d5 100644
--- a/sys/i386/isa/sound/audio.c
+++ b/sys/i386/isa/sound/audio.c
@@ -1,10 +1,10 @@
/*
* sound/audio.c
- *
+ *
* Device file manager for /dev/audio
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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 "sound_config.h"
@@ -116,9 +116,9 @@ translate_bytes (const void *table, void *buff, unsigned long n)
"1:\tlodsb\n\t"
"xlatb\n\t"
"stosb\n\t"
-"loop 1b\n\t":
-: "b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
-: "bx", "cx", "di", "si", "ax");
+ "loop 1b\n\t":
+ :"b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
+ :"bx", "cx", "di", "si", "ax");
}
#endif
@@ -183,7 +183,7 @@ audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
/* This just allows interrupts while the conversion is running */
__asm__ ("sti");
#endif
- translate_bytes (ulaw_dsp, &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
+ translate_bytes (ulaw_dsp, (unsigned char *) &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
}
c -= l;
@@ -244,7 +244,7 @@ audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
__asm__ ("sti");
#endif
- translate_bytes (dsp_ulaw, dmabuf, l);
+ translate_bytes (dsp_ulaw, (unsigned char *) dmabuf, l);
}
COPY_TO_USER (buf, p, dmabuf, l);
diff --git a/sys/i386/isa/sound/dev_table.c b/sys/i386/isa/sound/dev_table.c
index 5f6fc7b..7f7cae1 100644
--- a/sys/i386/isa/sound/dev_table.c
+++ b/sys/i386/isa/sound/dev_table.c
@@ -1,10 +1,10 @@
/*
* sound/dev_table.c
- *
+ *
* Device call tables.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
+ *
*/
#define _DEV_TABLE_C_
@@ -116,12 +116,12 @@ sndtable_get_cardcount (void)
}
#ifdef linux
-void
+void
sound_setup (char *str, int *ints)
{
int i, n = sizeof (supported_drivers) / sizeof (struct card_info);
-/*
+ /*
* First disable all drivers
*/
@@ -130,7 +130,7 @@ sound_setup (char *str, int *ints)
if (ints[0] == 0 || ints[1] == 0)
return;
-/*
+ /*
* Then enable them one by time
*/
@@ -169,8 +169,9 @@ sound_setup (char *str, int *ints)
}
}
}
+
#else
-void
+void
sound_chconf (int card_type, int ioaddr, int irq, int dma)
{
int i, n = sizeof (supported_drivers) / sizeof (struct card_info);
@@ -193,6 +194,7 @@ sound_chconf (int card_type, int ioaddr, int irq, int dma)
supported_drivers[ptr].config.dma = dma;
}
}
+
#endif
struct address_info *
@@ -211,4 +213,5 @@ sound_getconf (int card_type)
return &supported_drivers[ptr].config;
}
+
#endif
diff --git a/sys/i386/isa/sound/dev_table.h b/sys/i386/isa/sound/dev_table.h
index 63e4776..4b656ba 100644
--- a/sys/i386/isa/sound/dev_table.h
+++ b/sys/i386/isa/sound/dev_table.h
@@ -58,6 +58,9 @@ struct generic_midi_info{
struct audio_operations {
char name[32];
+ int flags;
+#define NOTHING_SPECIAL 0
+#define NEEDS_RESTART 1
int (*open) (int dev, int mode);
void (*close) (int dev);
void (*output_block) (int dev, unsigned long buf,
@@ -96,6 +99,7 @@ struct synth_operations {
void (*aftertouch) (int dev, int voice, int pressure);
void (*controller) (int dev, int voice, int ctrl_num, int value);
void (*panning) (int dev, int voice, int value);
+ void (*volume_method) (int dev, int mode);
int (*pmgr_interface) (int dev, struct patmgr_info *info);
};
diff --git a/sys/i386/isa/sound/dmabuf.c b/sys/i386/isa/sound/dmabuf.c
index 4b75e40..851a70a1 100644
--- a/sys/i386/isa/sound/dmabuf.c
+++ b/sys/i386/isa/sound/dmabuf.c
@@ -1,10 +1,10 @@
/*
* sound/dmabuf.c
- *
+ *
* The DMA buffer manager for digitized voice applications
- *
+ *
* 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
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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 "sound_config.h"
@@ -49,10 +49,6 @@
#define DMODE_OUTPUT 1
#define DMODE_INPUT 2
-extern int sb_dsp_ok;
-extern struct audio_operations sb_dsp_operations;
-static int force_reset = 0;
-
DEFINE_WAIT_QUEUES (dev_sleeper[MAX_DSP_DEV], dev_sleep_flag[MAX_DSP_DEV]);
static int dma_mode[MAX_DSP_DEV] =
@@ -91,7 +87,7 @@ static int bufferalloc_done[MAX_DSP_DEV] =
* Logical buffers for each devices
*/
-static int dev_nbufs[MAX_DSP_DEV]; /* # of logical buffers ( >=
+static int dev_nbufs[MAX_DSP_DEV]; /* # of logical buffers ( >=
* sound_buffcounts[dev] */
static int dev_counts[MAX_DSP_DEV][MAX_SUB_BUFFERS];
@@ -243,9 +239,6 @@ dma_reset (int dev)
int retval;
unsigned long flags;
- if (!force_reset && sb_dsp_ok && dsp_devs[dev] == &sb_dsp_operations)
- return; /* We don't need this code for SB */
-
DISABLE_INTR (flags);
dsp_devs[dev]->reset (dev);
dsp_devs[dev]->close (dev);
@@ -262,23 +255,18 @@ static int
dma_sync (int dev)
{
unsigned long flags;
- unsigned long time;
- int timed_out;
if (dma_mode[dev] == DMODE_OUTPUT)
{
DISABLE_INTR (flags);
- timed_out = 0;
- time = GET_TIME ();
-
while ((!(PROCESS_ABORTING (dev_sleeper[dev], dev_sleep_flag[dev]) ||
- dmabuf_interrupted[dev]) && !timed_out)
+ dmabuf_interrupted[dev]))
&& dev_qlen[dev])
{
DO_SLEEP (dev_sleeper[dev], dev_sleep_flag[dev], 10 * HZ);
- if ((GET_TIME () - time) > (10 * HZ))
- timed_out = 1;
+ if (TIMED_OUT (dev_sleeper[dev], dev_sleep_flag[dev]))
+ return dev_qlen[dev];
}
RESTORE_INTR (flags);
@@ -445,9 +433,7 @@ DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
switch (cmd)
{
case SNDCTL_DSP_RESET:
- force_reset = 1;
dma_reset (dev);
- force_reset = 0;
return 0;
break;
@@ -494,6 +480,7 @@ DMAbuf_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
return dsp_devs[dev]->ioctl (dev, cmd, arg, local);
}
+ /* NOTREACHED */
return RET_ERROR (EIO);
}
@@ -576,7 +563,8 @@ DMAbuf_start_output (int dev, int buff_no, int l)
dev_counts[dev][dev_qtail[dev]] = l;
- dev_needs_restart[dev] = (l != dev_buffsize[dev]);
+ dev_needs_restart[dev] = (l != dev_buffsize[dev]) &&
+ (sound_dma_automode[dev] || dsp_devs[dev]->flags & NEEDS_RESTART);
dev_qtail[dev] = (dev_qtail[dev] + 1) % dev_nbufs[dev];
@@ -615,11 +603,11 @@ DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
disable_dma (chan);
clear_dma_ff (chan);
set_dma_mode (chan, dma_mode | DMA_AUTOINIT);
- set_dma_addr (chan, (caddr_t)snd_raw_buf_phys[dev][0]);
- set_dma_count (chan, (unsigned)sound_buffsizes[dev]);
- enable_dma ((unsigned)chan);
+ set_dma_addr (chan, snd_raw_buf_phys[dev][0]);
+ set_dma_count (chan, sound_buffsizes[dev]);
+ enable_dma (chan);
RESTORE_INTR (flags);
-#else
+#else /* linux */
#ifdef __386BSD__
printk ("sound: Invalid DMA mode for device %d\n", dev);
@@ -628,24 +616,24 @@ DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
(caddr_t)snd_raw_buf_phys[dev][0],
sound_buffsizes[dev],
chan);
-#else
-#if defined(ISC) || defined(SCO)
+#else /* __386BSD__ */
+#if defined(ISC) || defined(SCO) || defined(SVR42)
#ifndef DMAMODE_AUTO
printk ("sound: Invalid DMA mode for device %d\n", dev);
-#endif
+#endif /* DMAMODE_AUTO */
dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode)
#ifdef DMAMODE_AUTO
| DMAMODE_AUTO
-#endif
+#endif /* DMAMODE_AUTO */
,
snd_raw_buf_phys[dev][0], count);
dma_enable (chan);
-#else
+#else /* SYSV */
#error This routine is not valid for this OS.
-#endif
-#endif
+#endif /* SYSV */
+#endif /* __386BSD__ */
-#endif
+#endif /* linux */
}
else
{
@@ -658,24 +646,24 @@ DMAbuf_start_dma (int dev, unsigned long physaddr, int count, int dma_mode)
set_dma_count (chan, count);
enable_dma (chan);
RESTORE_INTR (flags);
-#else
+#else /* linux */
#ifdef __386BSD__
isa_dmastart ((dma_mode == DMA_MODE_READ) ? B_READ : B_WRITE,
(caddr_t)physaddr,
count,
chan);
-#else
+#else /* __386BSD__ */
-#if defined(ISC) || defined(SCO)
+#if defined(ISC) || defined(SCO) || defined(SVR42)
dma_param (chan, ((dma_mode == DMA_MODE_READ) ? DMA_Rdmode : DMA_Wrmode),
physaddr, count);
dma_enable (chan);
-#else
+#else /* SYSV */
#error This routine is not valid for this OS.
-#endif /* !ISC */
-#endif
+#endif /* SYSV */
+#endif /* __386BSD__ */
-#endif
+#endif /* linux */
}
return count;
@@ -724,7 +712,8 @@ DMAbuf_outputintr (int dev, int underrun_flag)
{
dev_underrun[dev]++;
dsp_devs[dev]->halt_xfer (dev);
- dev_needs_restart[dev] = 1;
+ dev_needs_restart[dev] = (sound_dma_automode[dev] ||
+ dsp_devs[dev]->flags & NEEDS_RESTART);
}
DISABLE_INTR (flags);
@@ -750,7 +739,7 @@ DMAbuf_inputintr (int dev)
dev_underrun[dev]++;
dsp_devs[dev]->halt_xfer (dev);
dev_active[dev] = 0;
- dev_needs_restart[dev] = 1;
+ dev_needs_restart[dev] = sound_dma_automode[dev];
}
else
{
@@ -810,7 +799,7 @@ DMAbuf_reset_dma (int chan)
/*
* The sound_mem_init() is called by mem_init() immediately after mem_map is
* initialized and before free_page_list is created.
- *
+ *
* This routine allocates DMA buffers at the end of available physical memory (
* <16M) and marks pages reserved at mem_map.
*/
diff --git a/sys/i386/isa/sound/gus_card.c b/sys/i386/isa/sound/gus_card.c
index 29cc3d5..c7cfc0a 100644
--- a/sys/i386/isa/sound/gus_card.c
+++ b/sys/i386/isa/sound/gus_card.c
@@ -1,10 +1,10 @@
/*
* sound/gus_card.c
- *
+ *
* Detection routine for the Gravis Ultrasound.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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 "sound_config.h"
diff --git a/sys/i386/isa/sound/gus_hw.h b/sys/i386/isa/sound/gus_hw.h
index 48233e7..f97a0b8 100644
--- a/sys/i386/isa/sound/gus_hw.h
+++ b/sys/i386/isa/sound/gus_hw.h
@@ -24,6 +24,8 @@
#define u_Command (gus_base + 0x103)
#define u_DataLo (gus_base + 0x104)
#define u_DataHi (gus_base + 0x105)
+#define u_MixData (gus_base + 0x106) /* Rev. 3.7+ mixing */
+#define u_MixSelect (gus_base + 0x506) /* registers. */
#define u_IrqStatus u_Status
# define MIDI_TX_IRQ 0x01 /* pending MIDI xmit IRQ */
# define MIDI_RX_IRQ 0x02 /* pending MIDI recv IRQ */
@@ -32,4 +34,17 @@
# define WAVETABLE_IRQ 0x20 /* pending wavetable IRQ */
# define ENVELOPE_IRQ 0x40 /* pending volume envelope IRQ */
# define DMA_TC_IRQ 0x80 /* pending dma tc IRQ */
+
+#define ICS2101 1
+# define ICS_MIXDEVS 6
+# define DEV_MIC 0
+# define DEV_LINE 1
+# define DEV_CD 2
+# define DEV_GF1 3
+# define DEV_UNUSED 4
+# define DEV_VOL 5
+
+# define CHN_LEFT 0
+# define CHN_RIGHT 1
+#define CS4231 2
#define u_DRAMIO (gus_base + 0x107)
diff --git a/sys/i386/isa/sound/gus_midi.c b/sys/i386/isa/sound/gus_midi.c
index 5e06f7f..935c5c9 100644
--- a/sys/i386/isa/sound/gus_midi.c
+++ b/sys/i386/isa/sound/gus_midi.c
@@ -1,10 +1,10 @@
/*
* sound/gus2_midi.c
- *
+ *
* The low level driver for the GUS Midi Interface.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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 "sound_config.h"
diff --git a/sys/i386/isa/sound/gus_vol.c b/sys/i386/isa/sound/gus_vol.c
index 6e56d54..055a117 100644
--- a/sys/i386/isa/sound/gus_vol.c
+++ b/sys/i386/isa/sound/gus_vol.c
@@ -1,17 +1,18 @@
-/*
+/*
* gus_vol.c - Compute volume for GUS.
- *
+ *
* Greg Lee 1993.
*/
#include "sound_config.h"
#ifndef EXCLUDE_GUS
+#include "gus_linearvol.h"
#define GUS_VOLUME gus_wave_volume
extern int gus_wave_volume;
-/*
+/*
* Calculate gus volume from note velocity, main volume, expression, and
* intrinsic patch volume given in patch library. Expression is multiplied
* in, so it emphasizes differences in note velocity, while main volume is
@@ -20,7 +21,7 @@ extern int gus_wave_volume;
* to expression controller messages, if they were found to be used for
* dynamic volume adjustments, so here, main volume can be assumed to be
* constant throughout a song.)
- *
+ *
* Intrinsic patch volume is added in, but if over 64 is also multiplied in, so
* we can give a big boost to very weak voices like nylon guitar and the
* basses. The normal value is 64. Strings are assigned lower values.
@@ -31,27 +32,27 @@ gus_adagio_vol (int vel, int mainv, int xpn, int voicev)
int i, m, n, x;
- /*
+ /*
* A voice volume of 64 is considered neutral, so adjust the main volume if
* something other than this neutral value was assigned in the patch
* library.
*/
x = 256 + 6 * (voicev - 64);
- /*
- * Boost expression by voice volume above neutral.
+ /*
+ * Boost expression by voice volume above neutral.
*/
if (voicev > 65)
xpn += voicev - 64;
xpn += (voicev - 64) / 2;
- /*
- * Combine multiplicative and level components.
+ /*
+ * Combine multiplicative and level components.
*/
x = vel * xpn * 6 + (voicev / 4) * x;
#ifdef GUS_VOLUME
- /*
+ /*
* Further adjustment by installation-specific master volume control
* (default 60).
*/
@@ -72,7 +73,7 @@ gus_adagio_vol (int vel, int mainv, int xpn, int voicev)
else if (x >= 65535)
return ((15 << 8) | 255);
- /*
+ /*
* Convert to gus's logarithmic form with 4 bit exponent i and 8 bit
* mantissa m.
*/
@@ -89,14 +90,14 @@ gus_adagio_vol (int vel, int mainv, int xpn, int voicev)
n >>= 1;
i++;
}
- /*
+ /*
* Mantissa is part of linear volume not expressed in exponent. (This is
* not quite like real logs -- I wonder if it's right.)
*/
m = x - (1 << i);
- /*
- * Adjust mantissa to 8 bits.
+ /*
+ * Adjust mantissa to 8 bits.
*/
if (m > 0)
{
@@ -109,4 +110,38 @@ gus_adagio_vol (int vel, int mainv, int xpn, int voicev)
return ((i << 8) + m);
}
+/*
+ * Volume-values are interpreted as linear values. Volume is based on the
+ * value supplied with SEQ_START_NOTE(), channel main volume (if compiled in)
+ * and the volume set by the mixer-device (default 60%).
+ */
+
+unsigned short
+gus_linear_vol (int vol, int mainvol)
+{
+ int mixer_mainvol;
+
+ if (vol <= 0)
+ vol = 0;
+ else if (vol >= 127)
+ vol = 127;
+
+#ifdef GUS_VOLUME
+ mixer_mainvol = GUS_VOLUME;
+#else
+ mixer_mainvol = 100;
+#endif
+
+#ifdef GUS_USE_CHN_MAIN_VOLUME
+ if (mainvol <= 0)
+ mainvol = 0;
+ else if (mainvol >= 127)
+ mainvol = 127;
+#else
+ mainvol = 128;
+#endif
+
+ return gus_linearvol[(((vol * mainvol) / 128) * mixer_mainvol) / 100];
+}
+
#endif
diff --git a/sys/i386/isa/sound/gus_wave.c b/sys/i386/isa/sound/gus_wave.c
index db5ad81..948dd407 100644
--- a/sys/i386/isa/sound/gus_wave.c
+++ b/sys/i386/isa/sound/gus_wave.c
@@ -1,11 +1,10 @@
-
-/*
+/*
* sound/gus_wave.c
- *
+ *
* Driver for the Gravis UltraSound wave table synth.
- *
+ *
* 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
@@ -13,7 +12,7 @@
* 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
@@ -25,13 +24,11 @@
* 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 "sound_config.h"
-#ifdef linux
-#include <linux/ultrasound.h>
-#elif __FreeBSD__
+#ifdef __FreeBSD__
#include <machine/ultrasound.h>
#else
#include "ultrasound.h"
@@ -67,7 +64,7 @@ struct voice_info
unsigned char env_rate[6];
unsigned char env_offset[6];
- /*
+ /*
* Volume computation parameters for gus_adagio_vol()
*/
int main_vol, expression_vol, patch_vol;
@@ -94,22 +91,21 @@ static int gus_line_vol = 100, gus_mic_vol = 0;
static int gus_recmask = SOUND_MASK_MIC;
static int recording_active = 0;
-#define VOL_METHOD_ADAGIO 1
int gus_wave_volume = 60;
int gus_pcm_volume = 80;
static unsigned char mix_image = 0x00;
-/*
+/*
* Current version of this driver doesn't allow synth and PCM functions
* at the same time. The active_device specifies the active driver
*/
static int active_device = 0;
-#define GUS_DEV_WAVE 1 /*
+#define GUS_DEV_WAVE 1 /*
* * * Wave table synth */
-#define GUS_DEV_PCM_DONE 2 /*
+#define GUS_DEV_PCM_DONE 2 /*
* * * PCM device, transfer done */
-#define GUS_DEV_PCM_CONTINUE 3 /*
+#define GUS_DEV_PCM_CONTINUE 3 /*
* * * PCM device, transfer the
* second * * * chn */
@@ -119,31 +115,31 @@ static int gus_sampling_bits;
DEFINE_WAIT_QUEUE (dram_sleeper, dram_sleep_flag);
-/*
+/*
* Variables and buffers for PCM output
*/
-#define MAX_PCM_BUFFERS (32*MAX_REALTIME_FACTOR) /*
+#define MAX_PCM_BUFFERS (32*MAX_REALTIME_FACTOR) /*
* * * Don't
- * * * change
- *
+ * * * change
+ *
*/
-static int pcm_bsize, /*
- * Current blocksize
+static int pcm_bsize, /*
+ * Current blocksize
*/
- pcm_nblk, /*
- * Current # of blocks
+ pcm_nblk, /*
+ * Current # of blocks
*/
- pcm_banksize; /*
+ pcm_banksize; /*
* * * * # bytes allocated for channels */
-static int pcm_datasize[MAX_PCM_BUFFERS]; /*
+static int pcm_datasize[MAX_PCM_BUFFERS]; /*
* * * * Actual # of bytes
* in blk * */
-static volatile int pcm_head, pcm_tail, pcm_qlen; /*
+static volatile int pcm_head, pcm_tail, pcm_qlen; /*
* * * * DRAM queue
@@ -160,62 +156,62 @@ struct voice_info voices[32];
static int freq_div_table[] =
{
- 44100, /*
- * 14
+ 44100, /*
+ * 14
*/
- 41160, /*
- * 15
+ 41160, /*
+ * 15
*/
- 38587, /*
- * 16
+ 38587, /*
+ * 16
*/
- 36317, /*
- * 17
+ 36317, /*
+ * 17
*/
- 34300, /*
- * 18
+ 34300, /*
+ * 18
*/
- 32494, /*
- * 19
+ 32494, /*
+ * 19
*/
- 30870, /*
- * 20
+ 30870, /*
+ * 20
*/
- 29400, /*
- * 21
+ 29400, /*
+ * 21
*/
- 28063, /*
- * 22
+ 28063, /*
+ * 22
*/
- 26843, /*
- * 23
+ 26843, /*
+ * 23
*/
- 25725, /*
- * 24
+ 25725, /*
+ * 24
*/
- 24696, /*
- * 25
+ 24696, /*
+ * 25
*/
- 23746, /*
- * 26
+ 23746, /*
+ * 26
*/
- 22866, /*
- * 27
+ 22866, /*
+ * 27
*/
- 22050, /*
- * 28
+ 22050, /*
+ * 28
*/
- 21289, /*
- * 29
+ 21289, /*
+ * 29
*/
- 20580, /*
- * 30
+ 20580, /*
+ * 30
*/
- 19916, /*
- * 31
+ 19916, /*
+ * 31
*/
- 19293 /*
- * 32
+ 19293 /*
+ * 32
*/
};
@@ -234,13 +230,14 @@ static struct synth_info gus_info =
static void gus_poke (long addr, unsigned char data);
static void compute_and_set_volume (int voice, int volume, int ramp_time);
extern unsigned short gus_adagio_vol (int vel, int mainv, int xpn, int voicev);
+extern unsigned short gus_linear_vol (int vol, int mainvol);
static void compute_volume (int voice, int volume);
static void do_volume_irq (int voice);
static void set_input_volumes (void);
-#define INSTANT_RAMP -1 /*
+#define INSTANT_RAMP -1 /*
* * * Dont use ramping */
-#define FAST_RAMP 0 /*
+#define FAST_RAMP 0 /*
* * * Fastest possible ramp */
static void
@@ -255,8 +252,8 @@ reset_sample_memory (void)
for (i = 0; i < 32; i++)
patch_map[i] = -1;
- gus_poke (0, 0); /*
- * Put silence here
+ gus_poke (0, 0); /*
+ * Put silence here
*/
gus_poke (1, 0);
@@ -392,7 +389,7 @@ gus_write_addr (int reg, unsigned long address, int is16bit)
if (is16bit)
{
- /*
+ /*
* Special processing required for 16 bit patches
*/
@@ -404,6 +401,10 @@ gus_write_addr (int reg, unsigned long address, int is16bit)
gus_write16 (reg, (unsigned short) ((address >> 7) & 0xffff));
gus_write16 (reg + 1, (unsigned short) ((address << 9) & 0xffff));
+ /* Could writing twice fix problems with GUS_VOICE_POS() ? Lets try... */
+ gus_delay ();
+ gus_write16 (reg, (unsigned short) ((address >> 7) & 0xffff));
+ gus_write16 (reg + 1, (unsigned short) ((address << 9) & 0xffff));
}
static void
@@ -447,13 +448,13 @@ gus_voice_mode (unsigned int m)
{
unsigned char mode = (unsigned char) (m & 0xff);
- gus_write8 (0x00, (gus_read8 (0x00) & 0x03) | (mode & 0xfc)); /*
- * Don't
- * start
- * or
+ gus_write8 (0x00, (gus_read8 (0x00) & 0x03) | (mode & 0xfc)); /*
+ * Don't
+ * start
+ * or
* stop
* *
- * voice
+ * voice
*/
gus_delay ();
gus_write8 (0x00, (gus_read8 (0x00) & 0x03) | (mode & 0xfc));
@@ -474,8 +475,8 @@ gus_voice_freq (unsigned long freq)
static void
gus_voice_volume (unsigned int vol)
{
- gus_write8 (0x0d, 0x03); /*
- * Stop ramp before setting volume
+ gus_write8 (0x0d, 0x03); /*
+ * Stop ramp before setting volume
*/
gus_write16 (0x09, (unsigned short) (vol << 4));
}
@@ -514,13 +515,13 @@ gus_ramp_mode (unsigned int m)
{
unsigned char mode = (unsigned char) (m & 0xff);
- gus_write8 (0x0d, (gus_read8 (0x0d) & 0x03) | (mode & 0xfc)); /*
- * Don't
- * start
- * or
+ gus_write8 (0x0d, (gus_read8 (0x0d) & 0x03) | (mode & 0xfc)); /*
+ * Don't
+ * start
+ * or
* stop
* *
- * ramping
+ * ramping
*/
gus_delay ();
gus_write8 (0x0d, (gus_read8 (0x0d) & 0x03) | (mode & 0xfc));
@@ -554,14 +555,14 @@ gus_voice_init (int voice)
DISABLE_INTR (flags);
gus_select_voice (voice);
gus_voice_volume (0);
- gus_write_addr (0x0a, 0, 0); /*
- * Set current position to 0
+ gus_write_addr (0x0a, 0, 0); /*
+ * Set current position to 0
*/
- gus_write8 (0x00, 0x03); /*
- * Voice off
+ gus_write8 (0x00, 0x03); /*
+ * Voice off
*/
- gus_write8 (0x0d, 0x03); /*
- * Ramping off
+ gus_write8 (0x0d, 0x03); /*
+ * Ramping off
*/
RESTORE_INTR (flags);
@@ -594,18 +595,22 @@ step_envelope (int voice)
{
unsigned vol, prev_vol, phase;
unsigned char rate;
+ long int flags;
if (voices[voice].mode & WAVE_SUSTAIN_ON && voices[voice].env_phase == 2)
{
+ DISABLE_INTR (flags);
+ gus_select_voice (voice);
gus_rampoff ();
- return; /*
- * Sustain
+ RESTORE_INTR (flags);
+ return; /*
+ * Sustain
*/
}
if (voices[voice].env_phase >= 5)
{
- /*
+ /*
* Shoot the voice off
*/
@@ -614,25 +619,30 @@ step_envelope (int voice)
}
prev_vol = voices[voice].current_volume;
- gus_voice_volume (prev_vol);
phase = ++voices[voice].env_phase;
-
compute_volume (voice, voices[voice].midi_volume);
-
vol = voices[voice].initial_volume * voices[voice].env_offset[phase] / 255;
rate = voices[voice].env_rate[phase];
- gus_write8 (0x06, rate); /*
- * Ramping rate
+
+ DISABLE_INTR (flags);
+ gus_select_voice (voice);
+
+ gus_voice_volume (prev_vol);
+
+
+ gus_write8 (0x06, rate); /*
+ * Ramping rate
*/
voices[voice].volume_irq_mode = VMODE_ENVELOPE;
- if (((vol - prev_vol) / 64) == 0) /*
- * No significant volume change
+ if (((vol - prev_vol) / 64) == 0) /*
+ * No significant volume change
*/
{
- step_envelope (voice); /*
- * Continue with the next phase
+ RESTORE_INTR (flags);
+ step_envelope (voice); /*
+ * Continue with the next phase
*/
return;
}
@@ -642,8 +652,8 @@ step_envelope (int voice)
if (vol >= (4096 - 64))
vol = 4096 - 65;
gus_ramp_range (0, vol);
- gus_rampon (0x20); /*
- * Increasing, irq
+ gus_rampon (0x20); /*
+ * Increasing, irq
*/
}
else
@@ -651,11 +661,12 @@ step_envelope (int voice)
if (vol <= 64)
vol = 65;
gus_ramp_range (vol, 4030);
- gus_rampon (0x60); /*
- * Decreasing, irq
+ gus_rampon (0x60); /*
+ * Decreasing, irq
*/
}
voices[voice].current_volume = vol;
+ RESTORE_INTR (flags);
}
static void
@@ -668,25 +679,26 @@ init_envelope (int voice)
}
static void
-start_release (int voice)
+start_release (int voice, long int flags)
{
if (gus_read8 (0x00) & 0x03)
- return; /*
- * Voice already stopped
+ return; /*
+ * Voice already stopped
*/
- voices[voice].env_phase = 2; /*
- * Will be incremented by step_envelope
+ voices[voice].env_phase = 2; /*
+ * Will be incremented by step_envelope
*/
voices[voice].current_volume =
voices[voice].initial_volume =
- gus_read16 (0x09) >> 4; /*
- * Get current volume
+ gus_read16 (0x09) >> 4; /*
+ * Get current volume
*/
voices[voice].mode &= ~WAVE_SUSTAIN_ON;
gus_rampoff ();
+ RESTORE_INTR (flags);
step_envelope (voice);
}
@@ -694,32 +706,37 @@ static void
gus_voice_fade (int voice)
{
int instr_no = sample_map[voice], is16bits;
+ long int flags;
+
+ DISABLE_INTR (flags);
+ gus_select_voice (voice);
if (instr_no < 0 || instr_no > MAX_SAMPLE)
{
- gus_write8 (0x00, 0x03); /*
- * Hard stop
+ gus_write8 (0x00, 0x03); /*
+ * Hard stop
*/
+ RESTORE_INTR (flags);
return;
}
- is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /*
+ is16bits = (samples[instr_no].mode & WAVE_16_BITS) ? 1 : 0; /*
* 8 or 16
* bit
- * samples
+ * samples
*/
if (voices[voice].mode & WAVE_ENVELOPES)
{
- start_release (voice);
+ start_release (voice, flags);
return;
}
- /*
+ /*
* Ramp the volume down but not too quickly.
*/
- if ((gus_read16 (0x09) >> 4) < 100) /*
- * Get current volume
+ if ((gus_read16 (0x09) >> 4) < 100) /*
+ * Get current volume
*/
{
gus_voice_off ();
@@ -730,10 +747,11 @@ gus_voice_fade (int voice)
gus_ramp_range (65, 4030);
gus_ramp_rate (2, 4);
- gus_rampon (0x40 | 0x20); /*
- * Down, once, irq
+ gus_rampon (0x40 | 0x20); /*
+ * Down, once, irq
*/
voices[voice].volume_irq_mode = VMODE_HALT;
+ RESTORE_INTR (flags);
}
static void
@@ -748,24 +766,24 @@ gus_reset (void)
for (i = 0; i < 32; i++)
{
- gus_voice_init (i); /*
- * Turn voice off
+ gus_voice_init (i); /*
+ * Turn voice off
*/
gus_voice_init2 (i);
}
- INB (u_Status); /*
- * Touch the status register
+ INB (u_Status); /*
+ * Touch the status register
*/
- gus_look8 (0x41); /*
- * Clear any pending DMA IRQs
+ gus_look8 (0x41); /*
+ * Clear any pending DMA IRQs
*/
- gus_look8 (0x49); /*
- * Clear any pending sample IRQs
+ gus_look8 (0x49); /*
+ * Clear any pending sample IRQs
*/
- gus_read8 (0x0f); /*
- * Clear pending IRQs
+ gus_read8 (0x0f); /*
+ * Clear pending IRQs
*/
}
@@ -774,7 +792,7 @@ static void
gus_initialize (void)
{
unsigned long flags;
- unsigned char dma_image, irq_image, tmp;
+ register unsigned char dma_image, irq_image, tmp;
static unsigned char gus_irq_map[16] =
{0, 0, 1, 3, 0, 2, 0, 4, 0, 0, 0, 5, 6, 0, 0, 7};
@@ -784,74 +802,74 @@ gus_initialize (void)
DISABLE_INTR (flags);
- gus_write8 (0x4c, 0); /*
- * Reset GF1
+ gus_write8 (0x4c, 0); /*
+ * Reset GF1
*/
gus_delay ();
gus_delay ();
- gus_write8 (0x4c, 1); /*
- * Release Reset
+ gus_write8 (0x4c, 1); /*
+ * Release Reset
*/
gus_delay ();
gus_delay ();
- /*
+ /*
* Clear all interrupts
*/
- gus_write8 (0x41, 0); /*
- * DMA control
+ gus_write8 (0x41, 0); /*
+ * DMA control
*/
- gus_write8 (0x45, 0); /*
- * Timer control
+ gus_write8 (0x45, 0); /*
+ * Timer control
*/
- gus_write8 (0x49, 0); /*
- * Sample control
+ gus_write8 (0x49, 0); /*
+ * Sample control
*/
gus_select_max_voices (24);
- INB (u_Status); /*
- * Touch the status register
+ INB (u_Status); /*
+ * Touch the status register
*/
- gus_look8 (0x41); /*
- * Clear any pending DMA IRQs
+ gus_look8 (0x41); /*
+ * Clear any pending DMA IRQs
*/
- gus_look8 (0x49); /*
- * Clear any pending sample IRQs
+ gus_look8 (0x49); /*
+ * Clear any pending sample IRQs
*/
- gus_read8 (0x0f); /*
- * Clear pending IRQs
+ gus_read8 (0x0f); /*
+ * Clear pending IRQs
*/
- gus_reset (); /*
- * Resets all voices
+ gus_reset (); /*
+ * Resets all voices
*/
- gus_look8 (0x41); /*
- * Clear any pending DMA IRQs
+ gus_look8 (0x41); /*
+ * Clear any pending DMA IRQs
*/
- gus_look8 (0x49); /*
- * Clear any pending sample IRQs
+ gus_look8 (0x49); /*
+ * Clear any pending sample IRQs
*/
- gus_read8 (0x0f); /*
- * Clear pending IRQs
+ gus_read8 (0x0f); /*
+ * Clear pending IRQs
*/
- gus_write8 (0x4c, 7); /*
- * Master reset | DAC enable | IRQ enable
+ gus_write8 (0x4c, 7); /*
+ * Master reset | DAC enable | IRQ enable
*/
- /*
+ /*
* Set up for Digital ASIC
*/
OUTB (0x05, gus_base + 0x0f);
- mix_image |= 0x02; /*
- * Disable line out
+ mix_image |= 0x02; /*
+ * Disable line out
*/
OUTB (mix_image, u_Mixer);
@@ -859,11 +877,11 @@ gus_initialize (void)
OUTB (0x00, gus_base + 0x0f);
- /*
+ /*
* Now set up the DMA and IRQ interface
- *
+ *
* The GUS supports two IRQs and two DMAs.
- *
+ *
* Just one DMA channel is used. This prevents simultaneous ADC and DAC.
* Adding this support requires significant changes to the dmabuf.c, dsp.c
* and audio.c also.
@@ -874,79 +892,79 @@ gus_initialize (void)
if (!tmp)
printk ("Warning! GUS IRQ not selected\n");
irq_image |= tmp;
- irq_image |= 0x40; /*
- * Combine IRQ1 (GF1) and IRQ2 (Midi)
+ irq_image |= 0x40; /*
+ * Combine IRQ1 (GF1) and IRQ2 (Midi)
*/
- dma_image = 0x40; /*
- * Combine DMA1 (DRAM) and IRQ2 (ADC)
+ dma_image = 0x40; /*
+ * Combine DMA1 (DRAM) and IRQ2 (ADC)
*/
tmp = gus_dma_map[gus_dma];
if (!tmp)
printk ("Warning! GUS DMA not selected\n");
dma_image |= tmp;
- /*
+ /*
* For some reason the IRQ and DMA addresses must be written twice
*/
- /*
- * Doing it first time
+ /*
+ * Doing it first time
*/
- OUTB (mix_image, u_Mixer); /*
- * Select DMA control
+ OUTB (mix_image, u_Mixer); /*
+ * Select DMA control
*/
- OUTB (dma_image | 0x80, u_IRQDMAControl); /*
- * Set DMA address
+ OUTB (dma_image | 0x80, u_IRQDMAControl); /*
+ * Set DMA address
*/
- OUTB (mix_image | 0x40, u_Mixer); /*
- * Select IRQ control
+ OUTB (mix_image | 0x40, u_Mixer); /*
+ * Select IRQ control
*/
- OUTB (irq_image, u_IRQDMAControl); /*
- * Set IRQ address
+ OUTB (irq_image, u_IRQDMAControl); /*
+ * Set IRQ address
*/
- /*
- * Doing it second time
+ /*
+ * Doing it second time
*/
- OUTB (mix_image, u_Mixer); /*
- * Select DMA control
+ OUTB (mix_image, u_Mixer); /*
+ * Select DMA control
*/
- OUTB (dma_image, u_IRQDMAControl); /*
- * Set DMA address
+ OUTB (dma_image, u_IRQDMAControl); /*
+ * Set DMA address
*/
- OUTB (mix_image | 0x40, u_Mixer); /*
- * Select IRQ control
+ OUTB (mix_image | 0x40, u_Mixer); /*
+ * Select IRQ control
*/
- OUTB (irq_image, u_IRQDMAControl); /*
- * Set IRQ address
+ OUTB (irq_image, u_IRQDMAControl); /*
+ * Set IRQ address
*/
- gus_select_voice (0); /*
- * This disables writes to IRQ/DMA reg
+ gus_select_voice (0); /*
+ * This disables writes to IRQ/DMA reg
*/
- mix_image &= ~0x02; /*
- * Enable line out
+ mix_image &= ~0x02; /*
+ * Enable line out
*/
- mix_image |= 0x08; /*
- * Enable IRQ
+ mix_image |= 0x08; /*
+ * Enable IRQ
*/
- OUTB (mix_image, u_Mixer); /*
- * Turn mixer channels on
+ OUTB (mix_image, u_Mixer); /*
+ * Turn mixer channels on
* Note! Mic in is left off.
*/
- gus_select_voice (0); /*
- * This disables writes to IRQ/DMA reg
+ gus_select_voice (0); /*
+ * This disables writes to IRQ/DMA reg
*/
- gusintr (0); /*
- * Serve pending interrupts
+ gusintr (0); /*
+ * Serve pending interrupts
*/
RESTORE_INTR (flags);
}
@@ -1054,13 +1072,13 @@ guswave_set_instr (int dev, int voice, int instr_no)
if (sample_no < 0)
{
printk ("GUS: Undefined patch %d for voice %d\n", instr_no, voice);
- return RET_ERROR (EINVAL); /*
- * Patch not defined
+ return RET_ERROR (EINVAL);/*
+ * Patch not defined
*/
}
- if (sample_ptrs[sample_no] == -1) /*
- * Sample not loaded
+ if (sample_ptrs[sample_no] == -1) /*
+ * Sample not loaded
*/
{
printk ("GUS: Sample #%d not loaded for patch %d (voice %d)\n", sample_no, instr_no, voice);
@@ -1083,13 +1101,15 @@ guswave_kill_note (int dev, int voice, int velocity)
DISABLE_INTR (flags);
if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
- voices[voice].kill_pending = 1;
+ {
+ voices[voice].kill_pending = 1;
+ RESTORE_INTR (flags);
+ }
else
{
- gus_select_voice (voice);
+ RESTORE_INTR (flags);
gus_voice_fade (voice);
}
- RESTORE_INTR (flags);
return 0;
}
@@ -1100,16 +1120,16 @@ guswave_aftertouch (int dev, int voice, int pressure)
short lo_limit, hi_limit;
unsigned long flags;
- return; /*
- * Currently disabled
+ return; /*
+ * Currently disabled
*/
if (voice < 0 || voice > 31)
return;
if (voices[voice].mode & WAVE_ENVELOPES && voices[voice].env_phase != 2)
- return; /*
- * Don't mix with envelopes
+ return; /*
+ * Don't mix with envelopes
*/
if (pressure < 32)
@@ -1117,8 +1137,8 @@ guswave_aftertouch (int dev, int voice, int pressure)
DISABLE_INTR (flags);
gus_select_voice (voice);
gus_rampoff ();
- compute_and_set_volume (voice, 255, 0); /*
- * Back to original volume
+ compute_and_set_volume (voice, 255, 0); /*
+ * Back to original volume
*/
RESTORE_INTR (flags);
return;
@@ -1138,8 +1158,8 @@ guswave_aftertouch (int dev, int voice, int pressure)
}
gus_ramp_range (lo_limit, hi_limit);
gus_ramp_rate (3, 8);
- gus_rampon (0x58); /*
- * Bidirectional, Down, Loop
+ gus_rampon (0x58); /*
+ * Bidirectional, Down, Loop
*/
RESTORE_INTR (flags);
}
@@ -1152,6 +1172,13 @@ guswave_panning (int dev, int voice, int value)
}
static void
+guswave_volume_method (int dev, int mode)
+{
+ if (mode == VOL_METHOD_LINEAR || mode == VOL_METHOD_ADAGIO)
+ volume_method = mode;
+}
+
+static void
compute_volume (int voice, int volume)
{
if (volume < 128)
@@ -1166,6 +1193,11 @@ compute_volume (int voice, int volume)
voices[voice].patch_vol);
break;
+ case VOL_METHOD_LINEAR: /* Totally ignores patch-volume and expression */
+ voices[voice].initial_volume =
+ gus_linear_vol (volume, voices[voice].main_vol);
+ break;
+
default:
voices[voice].initial_volume = volume_base +
(voices[voice].midi_volume * volume_scale);
@@ -1181,16 +1213,16 @@ compute_and_set_volume (int voice, int volume, int ramp_time)
int current, target, rate;
unsigned long flags;
+ compute_volume (voice, volume);
+ voices[voice].current_volume = voices[voice].initial_volume;
+
DISABLE_INTR (flags);
-/*
+ /*
* CAUTION! Interrupts disabled. Enable them before returning
*/
gus_select_voice (voice);
- compute_volume (voice, volume);
- voices[voice].current_volume = voices[voice].initial_volume;
-
current = gus_read16 (0x09) >> 4;
target = voices[voice].initial_volume;
@@ -1208,8 +1240,8 @@ compute_and_set_volume (int voice, int volume, int ramp_time)
rate = 16;
gus_ramp_rate (0, rate);
- if ((target - current) / 64 == 0) /*
- * Too close
+ if ((target - current) / 64 == 0) /*
+ * Too close
*/
{
gus_rampoff ();
@@ -1223,8 +1255,8 @@ compute_and_set_volume (int voice, int volume, int ramp_time)
if (target > (4095 - 65))
target = 4095 - 65;
gus_ramp_range (current, target);
- gus_rampon (0x00); /*
- * Ramp up, once, no irq
+ gus_rampon (0x00); /*
+ * Ramp up, once, no irq
*/
}
else
@@ -1233,8 +1265,8 @@ compute_and_set_volume (int voice, int volume, int ramp_time)
target = 65;
gus_ramp_range (target, current);
- gus_rampon (0x40); /*
- * Ramp down, once, no irq
+ gus_rampon (0x40); /*
+ * Ramp down, once, no irq
*/
}
RESTORE_INTR (flags);
@@ -1248,14 +1280,14 @@ dynamic_volume_change (int voice)
DISABLE_INTR (flags);
gus_select_voice (voice);
- status = gus_read8 (0x00); /*
- * Voice status
+ status = gus_read8 (0x00); /*
+ * Voice status
*/
RESTORE_INTR (flags);
if (status & 0x03)
- return; /*
- * Voice not started
+ return; /*
+ * Voice not started
*/
if (!(voices[voice].mode & WAVE_ENVELOPES))
@@ -1264,19 +1296,19 @@ dynamic_volume_change (int voice)
return;
}
- /*
+ /*
* Voice is running and has envelopes.
*/
DISABLE_INTR (flags);
gus_select_voice (voice);
- status = gus_read8 (0x0d); /*
- * Ramping status
+ status = gus_read8 (0x0d); /*
+ * Ramping status
*/
RESTORE_INTR (flags);
- if (status & 0x03) /*
- * Sustain phase?
+ if (status & 0x03) /*
+ * Sustain phase?
*/
{
compute_and_set_volume (voice, voices[voice].midi_volume, 1);
@@ -1288,11 +1320,11 @@ dynamic_volume_change (int voice)
compute_volume (voice, voices[voice].midi_volume);
-#if 0 /*
+#if 0 /*
* * * Is this really required */
voices[voice].current_volume =
- gus_read16 (0x09) >> 4; /*
- * Get current volume
+ gus_read16 (0x09) >> 4; /*
+ * Get current volume
*/
voices[voice].env_phase--;
@@ -1334,10 +1366,12 @@ guswave_controller (int dev, int voice, int ctrl_num, int value)
value /= 128;
#endif
case CTRL_EXPRESSION:
- volume_method = VOL_METHOD_ADAGIO;
- voices[voice].expression_vol = value;
- if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
- dynamic_volume_change (voice);
+ if (volume_method == VOL_METHOD_ADAGIO)
+ {
+ voices[voice].expression_vol = value;
+ if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
+ dynamic_volume_change (voice);
+ }
break;
#ifdef FUTURE_VERSION
@@ -1350,14 +1384,13 @@ guswave_controller (int dev, int voice, int ctrl_num, int value)
#endif
case CTRL_MAIN_VOLUME:
- volume_method = VOL_METHOD_ADAGIO;
voices[voice].main_vol = value;
if (voices[voice].volume_irq_mode != VMODE_START_NOTE)
dynamic_volume_change (voice);
break;
- default: /*
- * Ignore
+ default: /*
+ * Ignore
*/
break;
}
@@ -1402,7 +1435,7 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
note_freq = note_to_freq (note_num);
- /*
+ /*
* Find a sample within a patch so that the note_freq is between low_note
* and high_note.
*/
@@ -1423,8 +1456,8 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
if (samples[samplep].low_note <= note_freq && note_freq <= samples[samplep].high_note)
sample = samplep;
else
- samplep = samples[samplep].key; /*
- * Follow link
+ samplep = samples[samplep].key; /*
+ * Follow link
*/
}
if (sample == -1)
@@ -1433,15 +1466,15 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
if (sample == -1)
{
printk ("GUS: Patch %d not defined for note %d\n", patch, note_num);
- return 0; /*
- * Should play default patch ???
+ return 0; /*
+ * Should play default patch ???
*/
}
- is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0; /*
+ is16bits = (samples[sample].mode & WAVE_16_BITS) ? 1 : 0; /*
* 8 or 16
* bit
- * samples
+ * samples
*/
voices[voice].mode = samples[sample].mode;
voices[voice].patch_vol = samples[sample].volume;
@@ -1459,8 +1492,8 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
sample_map[voice] = sample;
- base_note = samples[sample].base_note / 100; /*
- * To avoid overflows
+ base_note = samples[sample].base_note / 100; /*
+ * To avoid overflows
*/
note_freq /= 100;
@@ -1468,7 +1501,7 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
voices[voice].orig_freq = freq;
- /*
+ /*
* Since the pitch bender may have been set before playing the note, we
* have to calculate the bending now.
*/
@@ -1485,8 +1518,8 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
if (samples[sample].mode & WAVE_16_BITS)
{
- mode |= 0x04; /*
- * 16 bits
+ mode |= 0x04; /*
+ * 16 bits
*/
if ((sample_ptrs[sample] >> 18) !=
((sample_ptrs[sample] + samples[sample].len) >> 18))
@@ -1499,10 +1532,13 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
DISABLE_INTR (flags);
gus_select_voice (voice);
- gus_voice_off (); /*
- * It may still be running
+ gus_voice_off (); /*
+ * It may still be running
*/
gus_rampoff ();
+
+ RESTORE_INTR (flags);
+
if (voices[voice].mode & WAVE_ENVELOPES)
{
compute_volume (voice, volume);
@@ -1511,6 +1547,9 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
else
compute_and_set_volume (voice, volume, 0);
+ DISABLE_INTR (flags);
+ gus_select_voice (voice);
+
if (samples[sample].mode & WAVE_LOOP_BACK)
gus_write_addr (0x0a, sample_ptrs[sample] + samples[sample].len -
voices[voice].offset_pending, is16bits); /* Sample
@@ -1521,13 +1560,13 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
if (samples[sample].mode & WAVE_LOOPING)
{
- mode |= 0x08; /*
- * Looping on
+ mode |= 0x08; /*
+ * Looping on
*/
if (samples[sample].mode & WAVE_BIDIR_LOOP)
- mode |= 0x10; /*
- * Bidirectional looping on
+ mode |= 0x10; /*
+ * Bidirectional looping on
*/
if (samples[sample].mode & WAVE_LOOP_BACK)
@@ -1538,35 +1577,35 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
mode |= 0x40;
}
- gus_write_addr (0x02, sample_ptrs[sample] + samples[sample].loop_start, is16bits); /*
- * Loop
- * start
- * location
+ gus_write_addr (0x02, sample_ptrs[sample] + samples[sample].loop_start, is16bits); /*
+ * Loop
+ * start
+ * location
*/
- gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].loop_end, is16bits); /*
- * Loop
- * end
- * location
+ gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].loop_end, is16bits); /*
+ * Loop
+ * end
+ * location
*/
}
else
{
- mode |= 0x20; /*
- * Loop irq at the end
+ mode |= 0x20; /*
+ * Loop irq at the end
*/
- voices[voice].loop_irq_mode = LMODE_FINISH; /*
+ voices[voice].loop_irq_mode = LMODE_FINISH; /*
* Ramp it down at
- * the * end
+ * the * end
*/
voices[voice].loop_irq_parm = 1;
- gus_write_addr (0x02, sample_ptrs[sample], is16bits); /*
- * Loop start
- * location
+ gus_write_addr (0x02, sample_ptrs[sample], is16bits); /*
+ * Loop start
+ * location
*/
- gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].len - 1, is16bits); /*
- * Loop
- * end
- * location
+ gus_write_addr (0x04, sample_ptrs[sample] + samples[sample].len - 1, is16bits); /*
+ * Loop
+ * end
+ * location
*/
}
gus_voice_freq (freq);
@@ -1577,9 +1616,9 @@ guswave_start_note2 (int dev, int voice, int note_num, int volume)
return 0;
}
-/*
+/*
* * New guswave_start_note by Andrew J. Robinson attempts to minimize
- * clicking * when the note playing on the voice is changed. It uses volume
+ * clicking * when the note playing on the voice is changed. It uses volume
* ramping. */
static int
@@ -1595,14 +1634,17 @@ guswave_start_note (int dev, int voice, int note_num, int volume)
if (voices[voice].volume_irq_mode == VMODE_START_NOTE)
voices[voice].volume_pending = volume;
else
- ret_val = guswave_start_note2 (dev, voice, note_num, volume);
+ {
+ RESTORE_INTR (flags);
+ ret_val = guswave_start_note2 (dev, voice, note_num, volume);
+ }
}
else
{
gus_select_voice (voice);
mode = gus_read8 (0x00);
if (mode & 0x20)
- gus_write8 (0x00, mode & 0xdf); /* No interrupt! */
+ gus_write8 (0x00, mode & 0xdf); /* No interrupt! */
voices[voice].offset_pending = 0;
voices[voice].kill_pending = 0;
@@ -1611,9 +1653,11 @@ guswave_start_note (int dev, int voice, int note_num, int volume)
if (voices[voice].sample_pending >= 0)
{
+ RESTORE_INTR (flags);
guswave_set_instr (voices[voice].dev_pending, voice,
voices[voice].sample_pending);
voices[voice].sample_pending = -1;
+ DISABLE_INTR (flags);
}
if ((mode & 0x01) || ((gus_read16 (0x09) >> 4) < 2065))
@@ -1629,11 +1673,11 @@ guswave_start_note (int dev, int voice, int note_num, int volume)
gus_rampoff ();
gus_ramp_range (2000, 4065);
- gus_ramp_rate (0, 63); /* Fastest possible rate */
+ gus_ramp_rate (0, 63);/* Fastest possible rate */
gus_rampon (0x20 | 0x40); /* Ramp down, once, irq */
+ RESTORE_INTR (flags);
}
}
- RESTORE_INTR (flags);
return ret_val;
}
@@ -1691,10 +1735,10 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
unsigned long blk_size, blk_end, left, src_offs, target;
- sizeof_patch = (long) &patch.data[0] - (long) &patch; /*
+ sizeof_patch = (long) &patch.data[0] - (long) &patch; /*
* Size of
* the header
- * * info
+ * * info
*/
if (format != GUS_PATCH)
@@ -1717,7 +1761,7 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
return RET_ERROR (ENOSPC);
}
- /*
+ /*
* Copy the header from user space but ignore the first bytes which have
* been transferred already.
*/
@@ -1760,15 +1804,15 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
}
}
- free_mem_ptr = (free_mem_ptr + 31) & ~31; /*
- * Alignment 32 bytes
+ free_mem_ptr = (free_mem_ptr + 31) & ~31; /*
+ * Alignment 32 bytes
*/
#define GUS_BANK_SIZE (256*1024)
if (patch.mode & WAVE_16_BITS)
{
- /*
+ /*
* 16 bit samples must fit one 256k bank.
*/
if (patch.len >= GUS_BANK_SIZE)
@@ -1780,16 +1824,16 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
if ((free_mem_ptr / GUS_BANK_SIZE) !=
((free_mem_ptr + patch.len) / GUS_BANK_SIZE))
{
- unsigned long tmp_mem = /*
- * Align to 256K*N
+ unsigned long tmp_mem = /*
+ * Align to 256K*N
*/
((free_mem_ptr / GUS_BANK_SIZE) + 1) * GUS_BANK_SIZE;
if ((tmp_mem + patch.len) > gus_mem_size)
return RET_ERROR (ENOSPC);
- free_mem_ptr = tmp_mem; /*
- * This leaves unusable memory
+ free_mem_ptr = tmp_mem; /*
+ * This leaves unusable memory
*/
}
}
@@ -1799,8 +1843,8 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
sample_ptrs[free_sample] = free_mem_ptr;
- /*
- * Tremolo is not possible with envelopes
+ /*
+ * Tremolo is not possible with envelopes
*/
if (patch.mode & WAVE_ENVELOPES)
@@ -1808,14 +1852,14 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
memcpy ((char *) &samples[free_sample], &patch, sizeof_patch);
- /*
+ /*
* Link this_one sample to the list of samples for patch 'instr'.
*/
samples[free_sample].key = patch_table[instr];
patch_table[instr] = free_sample;
- /*
+ /*
* Use DMA to transfer the wave data to the DRAM
*/
@@ -1823,22 +1867,22 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
src_offs = 0;
target = free_mem_ptr;
- while (left) /*
- * Not all moved
+ while (left) /*
+ * Not all moved
*/
{
blk_size = sound_buffsizes[gus_devnum];
if (blk_size > left)
blk_size = left;
- /*
+ /*
* DMA cannot cross 256k bank boundaries. Check for that.
*/
blk_end = target + blk_size;
if ((target >> 18) != (blk_end >> 18))
- { /*
- * Have to split the block
+ { /*
+ * Have to split the block
*/
blk_end &= ~(256 * 1024 - 1);
@@ -1846,7 +1890,7 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
}
#if defined(GUS_NO_DMA) || defined(GUS_PATCH_NO_DMA)
- /*
+ /*
* For some reason the DMA is not possible. We have to use PIO.
*/
{
@@ -1859,20 +1903,20 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
if (patch.mode & WAVE_UNSIGNED)
if (!(patch.mode & WAVE_16_BITS) || (i & 0x01))
- data ^= 0x80; /*
- * Convert to signed
+ data ^= 0x80; /*
+ * Convert to signed
*/
gus_poke (target + i, data);
}
}
-#else /*
+#else /*
* * * GUS_NO_DMA */
{
unsigned long address, hold_address;
unsigned char dma_command;
unsigned long flags;
- /*
+ /*
* OK, move now. First in and then out.
*/
@@ -1881,13 +1925,13 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
blk_size);
DISABLE_INTR (flags); /******** INTERRUPTS DISABLED NOW ********/
- gus_write8 (0x41, 0); /*
- * Disable GF1 DMA
+ gus_write8 (0x41, 0); /*
+ * Disable GF1 DMA
*/
DMAbuf_start_dma (gus_devnum, snd_raw_buf_phys[gus_devnum][0],
blk_size, DMA_MODE_WRITE);
- /*
+ /*
* Set the DRAM address for the wave data
*/
@@ -1901,35 +1945,35 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
address |= (hold_address & 0x000c0000L);
}
- gus_write16 (0x42, (address >> 4) & 0xffff); /*
- * DRAM DMA address
+ gus_write16 (0x42, (address >> 4) & 0xffff); /*
+ * DRAM DMA address
*/
- /*
+ /*
* Start the DMA transfer
*/
- dma_command = 0x21; /*
- * IRQ enable, DMA start
+ dma_command = 0x21; /*
+ * IRQ enable, DMA start
*/
if (patch.mode & WAVE_UNSIGNED)
- dma_command |= 0x80; /*
- * Invert MSB
+ dma_command |= 0x80; /*
+ * Invert MSB
*/
if (patch.mode & WAVE_16_BITS)
- dma_command |= 0x40; /*
- * 16 bit _DATA_
+ dma_command |= 0x40; /*
+ * 16 bit _DATA_
*/
if (sound_dsp_dmachan[gus_devnum] > 3)
- dma_command |= 0x04; /*
- * 16 bit DMA channel
+ dma_command |= 0x04; /*
+ * 16 bit DMA channel
*/
- gus_write8 (0x41, dma_command); /*
- * Let's go luteet (=bugs)
+ gus_write8 (0x41, dma_command); /*
+ * Let's go luteet (=bugs)
*/
- /*
+ /*
* Sleep here until the DRAM DMA done interrupt is served
*/
active_device = GUS_DEV_WAVE;
@@ -1939,10 +1983,10 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
printk ("GUS: DMA Transfer timed out\n");
RESTORE_INTR (flags);
}
-#endif /*
+#endif /*
* * * GUS_NO_DMA */
- /*
+ /*
* Now the next part
*/
@@ -1950,8 +1994,8 @@ guswave_load_patch (int dev, int format, snd_rw_buf * addr,
src_offs += blk_size;
target += blk_size;
- gus_write8 (0x41, 0); /*
- * Stop DMA
+ gus_write8 (0x41, 0); /*
+ * Stop DMA
*/
}
@@ -1997,8 +2041,8 @@ guswave_hw_control (int dev, unsigned char *event)
case _GUS_VOICEON:
DISABLE_INTR (flags);
gus_select_voice (voice);
- p1 &= ~0x20; /*
- * Disable intr
+ p1 &= ~0x20; /*
+ * Disable intr
*/
gus_voice_on (p1);
RESTORE_INTR (flags);
@@ -2012,17 +2056,14 @@ guswave_hw_control (int dev, unsigned char *event)
break;
case _GUS_VOICEFADE:
- DISABLE_INTR (flags);
- gus_select_voice (voice);
gus_voice_fade (voice);
- RESTORE_INTR (flags);
break;
case _GUS_VOICEMODE:
DISABLE_INTR (flags);
gus_select_voice (voice);
- p1 &= ~0x20; /*
- * Disable intr
+ p1 &= ~0x20; /*
+ * Disable intr
*/
gus_voice_mode (p1);
RESTORE_INTR (flags);
@@ -2049,8 +2090,8 @@ guswave_hw_control (int dev, unsigned char *event)
RESTORE_INTR (flags);
break;
- case _GUS_VOICEVOL2: /*
- * Just update the voice value
+ case _GUS_VOICEVOL2: /*
+ * Just update the voice value
*/
voices[voice].initial_volume =
voices[voice].current_volume = p1;
@@ -2058,8 +2099,8 @@ guswave_hw_control (int dev, unsigned char *event)
case _GUS_RAMPRANGE:
if (voices[voice].mode & WAVE_ENVELOPES)
- break; /*
- * NO-NO
+ break; /*
+ * NO-NO
*/
DISABLE_INTR (flags);
gus_select_voice (voice);
@@ -2069,8 +2110,8 @@ guswave_hw_control (int dev, unsigned char *event)
case _GUS_RAMPRATE:
if (voices[voice].mode & WAVE_ENVELOPES)
- break; /*
- * NO-NO
+ break; /*
+ * NO-NO
*/
DISABLE_INTR (flags);
gus_select_voice (voice);
@@ -2080,13 +2121,13 @@ guswave_hw_control (int dev, unsigned char *event)
case _GUS_RAMPMODE:
if (voices[voice].mode & WAVE_ENVELOPES)
- break; /*
- * NO-NO
+ break; /*
+ * NO-NO
*/
DISABLE_INTR (flags);
gus_select_voice (voice);
- p1 &= ~0x20; /*
- * Disable intr
+ p1 &= ~0x20; /*
+ * Disable intr
*/
gus_ramp_mode (p1);
RESTORE_INTR (flags);
@@ -2094,13 +2135,13 @@ guswave_hw_control (int dev, unsigned char *event)
case _GUS_RAMPON:
if (voices[voice].mode & WAVE_ENVELOPES)
- break; /*
- * NO-NO
+ break; /*
+ * NO-NO
*/
DISABLE_INTR (flags);
gus_select_voice (voice);
- p1 &= ~0x20; /*
- * Disable intr
+ p1 &= ~0x20; /*
+ * Disable intr
*/
gus_rampon (p1);
RESTORE_INTR (flags);
@@ -2108,8 +2149,8 @@ guswave_hw_control (int dev, unsigned char *event)
case _GUS_RAMPOFF:
if (voices[voice].mode & WAVE_ENVELOPES)
- break; /*
- * NO-NO
+ break; /*
+ * NO-NO
*/
DISABLE_INTR (flags);
gus_select_voice (voice);
@@ -2218,8 +2259,8 @@ gus_sampling_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
return gus_sampling_bits;
return IOCTL_OUT (arg, gus_sampling_bits);
- case SOUND_PCM_WRITE_FILTER: /*
- * NOT YET IMPLEMENTED
+ case SOUND_PCM_WRITE_FILTER: /*
+ * NOT YET IMPLEMENTED
*/
return IOCTL_OUT (arg, RET_ERROR (EINVAL));
break;
@@ -2319,14 +2360,14 @@ play_next_pcm_block (void)
for (chn = 0; chn < gus_sampling_channels; chn++)
{
mode[chn] = 0x00;
- ramp_mode[chn] = 0x03; /*
- * Ramping and rollover off
+ ramp_mode[chn] = 0x03; /*
+ * Ramping and rollover off
*/
if (chn == 0)
{
- mode[chn] |= 0x20; /*
- * Loop irq
+ mode[chn] |= 0x20; /*
+ * Loop irq
*/
voices[chn].loop_irq_mode = LMODE_PCM;
}
@@ -2334,8 +2375,8 @@ play_next_pcm_block (void)
if (gus_sampling_bits != 8)
{
is16bits = 1;
- mode[chn] |= 0x04; /*
- * 16 bit data
+ mode[chn] |= 0x04; /*
+ * 16 bit data
*/
}
else
@@ -2344,22 +2385,22 @@ play_next_pcm_block (void)
dram_loc = this_one * pcm_bsize;
dram_loc += chn * pcm_banksize;
- if (this_one == (pcm_nblk - 1)) /*
- * Last of the DRAM buffers
+ if (this_one == (pcm_nblk - 1)) /*
+ * Last of the DRAM buffers
*/
{
- mode[chn] |= 0x08; /*
- * Enable loop
+ mode[chn] |= 0x08; /*
+ * Enable loop
*/
- ramp_mode[chn] = 0x03; /*
- * Disable rollover
+ ramp_mode[chn] = 0x03;/*
+ * Disable rollover
*/
}
else
{
if (chn == 0)
- ramp_mode[chn] = 0x04; /*
- * Enable rollover bit
+ ramp_mode[chn] = 0x04; /*
+ * Enable rollover bit
*/
}
@@ -2368,89 +2409,89 @@ play_next_pcm_block (void)
gus_voice_freq (speed);
if (gus_sampling_channels == 1)
- gus_voice_balance (7); /*
- * mono
+ gus_voice_balance (7); /*
+ * mono
*/
else if (chn == 0)
- gus_voice_balance (0); /*
- * left
+ gus_voice_balance (0); /*
+ * left
*/
else
- gus_voice_balance (15); /*
- * right
+ gus_voice_balance (15); /*
+ * right
*/
- if (!pcm_active) /*
- * Voice not started yet
+ if (!pcm_active) /*
+ * Voice not started yet
*/
{
- /*
+ /*
* The playback was not started yet (or there has been a pause).
* Start the voice (again) and ask for a rollover irq at the end of
* this_one block. If this_one one is last of the buffers, use just
* the normal loop with irq.
*/
- gus_voice_off (); /*
- * It could already be running
+ gus_voice_off (); /*
+ * It could already be running
*/
gus_rampoff ();
gus_voice_volume (1530 + (25 * gus_pcm_volume));
gus_ramp_range (65, 1530 + (25 * gus_pcm_volume));
- gus_write_addr (0x0a, dram_loc, is16bits); /*
- * Starting position
+ gus_write_addr (0x0a, dram_loc, is16bits); /*
+ * Starting position
*/
- gus_write_addr (0x02, chn * pcm_banksize, is16bits); /*
- * Loop start
- * location
+ gus_write_addr (0x02, chn * pcm_banksize, is16bits); /*
+ * Loop start
+ * location
*/
if (chn != 0)
gus_write_addr (0x04, pcm_banksize + (pcm_bsize * pcm_nblk),
- is16bits); /*
- * Loop end location
+ is16bits); /*
+ * Loop end location
*/
}
if (chn == 0)
- gus_write_addr (0x04, dram_loc + pcm_datasize[this_one], is16bits); /*
- * Loop
- * end
- * location
+ gus_write_addr (0x04, dram_loc + pcm_datasize[this_one], is16bits); /*
+ * Loop
+ * end
+ * location
*/
else
- mode[chn] |= 0x08; /*
- * Enable loop
+ mode[chn] |= 0x08; /*
+ * Enable loop
*/
if (pcm_datasize[this_one] != pcm_bsize)
{
- /*
- * Incomplete block. Possibly the last one.
+ /*
+ * Incomplete block. Possibly the last one.
*/
if (chn == 0)
{
- mode[chn] &= ~0x08; /*
- * Disable loop
+ mode[chn] &= ~0x08; /*
+ * Disable loop
*/
- mode[chn] |= 0x20; /*
- * Enable loop IRQ
+ mode[chn] |= 0x20;/*
+ * Enable loop IRQ
*/
voices[0].loop_irq_mode = LMODE_PCM_STOP;
- ramp_mode[chn] = 0x03; /*
- * No rollover bit
+ ramp_mode[chn] = 0x03; /*
+ * No rollover bit
*/
}
else
{
- gus_write_addr (0x04, dram_loc + pcm_datasize[this_one], is16bits); /*
- * Loop
- * end
- * location
+ gus_write_addr (0x04, dram_loc + pcm_datasize[this_one], is16bits); /*
+ * Loop
+ * end
+ * location
*/
- mode[chn] &= ~0x08; /*
- * Disable loop
+ mode[chn] &= ~0x08; /*
+ * Disable loop
*/
}
}
@@ -2474,11 +2515,11 @@ static void
gus_transfer_output_block (int dev, unsigned long buf,
int total_count, int intrflag, int chn)
{
- /*
+ /*
* This routine transfers one block of audio data to the DRAM. In mono mode
* it's called just once. When in stereo mode, this_one routine is called
* once for both channels.
- *
+ *
* The left/mono channel data is transferred to the beginning of dram and the
* right data to the area pointed by gus_page_size.
*/
@@ -2505,8 +2546,8 @@ gus_transfer_output_block (int dev, unsigned long buf,
else
this_one = pcm_current_block;
- gus_write8 (0x41, 0); /*
- * Disable GF1 DMA
+ gus_write8 (0x41, 0); /*
+ * Disable GF1 DMA
*/
DMAbuf_start_dma (dev, buf + (chn * count), count, DMA_MODE_WRITE);
@@ -2521,38 +2562,38 @@ gus_transfer_output_block (int dev, unsigned long buf,
address |= (hold_address & 0x000c0000L);
}
- gus_write16 (0x42, (address >> 4) & 0xffff); /*
- * DRAM DMA address
+ gus_write16 (0x42, (address >> 4) & 0xffff); /*
+ * DRAM DMA address
*/
- dma_command = 0x21; /*
- * IRQ enable, DMA start
+ dma_command = 0x21; /*
+ * IRQ enable, DMA start
*/
if (gus_sampling_bits != 8)
- dma_command |= 0x40; /*
- * 16 bit _DATA_
+ dma_command |= 0x40; /*
+ * 16 bit _DATA_
*/
else
- dma_command |= 0x80; /*
- * Invert MSB
+ dma_command |= 0x80; /*
+ * Invert MSB
*/
if (sound_dsp_dmachan[dev] > 3)
- dma_command |= 0x04; /*
- * 16 bit DMA channel
+ dma_command |= 0x04; /*
+ * 16 bit DMA channel
*/
- gus_write8 (0x41, dma_command); /*
- * Kick on
+ gus_write8 (0x41, dma_command); /*
+ * Kick on
*/
- if (chn == (gus_sampling_channels - 1)) /*
- * Last channel
+ if (chn == (gus_sampling_channels - 1)) /*
+ * Last channel
*/
{
- /*
- * Last (right or mono) channel data
+ /*
+ * Last (right or mono) channel data
*/
active_device = GUS_DEV_PCM_DONE;
if (!pcm_active && (pcm_qlen > 2 || count < pcm_bsize))
@@ -2560,7 +2601,7 @@ gus_transfer_output_block (int dev, unsigned long buf,
play_next_pcm_block ();
}
}
- else /*
+ else /*
* * * Left channel data. The right channel
* is * * * transferred after DMA interrupt */
active_device = GUS_DEV_PCM_CONTINUE;
@@ -2590,20 +2631,20 @@ gus_sampling_start_input (int dev, unsigned long buf, int count,
DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
- mode = 0xa0; /*
- * DMA IRQ enable, invert MSB
+ mode = 0xa0; /*
+ * DMA IRQ enable, invert MSB
*/
if (sound_dsp_dmachan[dev] > 3)
- mode |= 0x04; /*
- * 16 bit DMA channel
+ mode |= 0x04; /*
+ * 16 bit DMA channel
*/
if (gus_sampling_channels > 1)
- mode |= 0x02; /*
- * Stereo
+ mode |= 0x02; /*
+ * Stereo
*/
- mode |= 0x01; /*
- * DMA enable
+ mode |= 0x01; /*
+ * DMA enable
*/
gus_write8 (0x49, mode);
@@ -2618,8 +2659,8 @@ gus_sampling_prepare_for_input (int dev, int bsize, int bcount)
rate = (9878400 / (gus_sampling_speed + 2)) / 16;
- gus_write8 (0x48, rate & 0xff); /*
- * Set sampling frequency
+ gus_write8 (0x48, rate & 0xff); /*
+ * Set sampling frequency
*/
if (gus_sampling_bits != 8)
@@ -2722,6 +2763,7 @@ gus_copy_from_user (int dev, char *localbuf, int localoffs,
static struct audio_operations gus_sampling_operations =
{
"Gravis UltraSound",
+ NEEDS_RESTART,
gus_sampling_open,
gus_sampling_close,
gus_sampling_output_block,
@@ -2751,6 +2793,7 @@ guswave_bender (int dev, int voice, int value)
gus_voice_freq (freq);
RESTORE_INTR (flags);
}
+
#endif
static int
@@ -2782,8 +2825,8 @@ guswave_patchmgr (int dev, struct patmgr_info *rec)
while (ptr >= 0 && ptr < free_sample)
{
rec->data.data8[i]++;
- ptr = samples[ptr].key; /*
- * Follow link
+ ptr = samples[ptr].key; /*
+ * Follow link
*/
}
}
@@ -2799,8 +2842,8 @@ guswave_patchmgr (int dev, struct patmgr_info *rec)
while (ptr >= 0 && ptr < free_sample)
{
rec->data.data32[n++] = ptr;
- ptr = samples[ptr].key; /*
- * Follow link
+ ptr = samples[ptr].key; /*
+ * Follow link
*/
}
}
@@ -2821,11 +2864,11 @@ guswave_patchmgr (int dev, struct patmgr_info *rec)
pat = (struct patch_info *) rec->data.data8;
- pat->key = GUS_PATCH; /*
- * Restore patch type
+ pat->key = GUS_PATCH; /*
+ * Restore patch type
*/
- rec->parm1 = sample_ptrs[ptr]; /*
- * DRAM address
+ rec->parm1 = sample_ptrs[ptr]; /*
+ * DRAM address
*/
rec->parm2 = sizeof (struct patch_info);
}
@@ -2842,13 +2885,13 @@ guswave_patchmgr (int dev, struct patmgr_info *rec)
pat = (struct patch_info *) rec->data.data8;
- if (pat->len > samples[ptr].len) /*
- * Cannot expand sample
+ if (pat->len > samples[ptr].len) /*
+ * Cannot expand sample
*/
return RET_ERROR (EINVAL);
- pat->key = samples[ptr].key; /*
- * Ensure the link is correct
+ pat->key = samples[ptr].key; /*
+ * Ensure the link is correct
*/
memcpy ((char *) &samples[ptr], rec->data.data8,
@@ -2859,8 +2902,8 @@ guswave_patchmgr (int dev, struct patmgr_info *rec)
return 0;
break;
- case PM_READ_PATCH: /*
- * Returns a block of wave data from the DRAM
+ case PM_READ_PATCH: /*
+ * Returns a block of wave data from the DRAM
*/
{
int sample = rec->parm1;
@@ -2872,12 +2915,12 @@ guswave_patchmgr (int dev, struct patmgr_info *rec)
return RET_ERROR (EINVAL);
if (offs < 0 || offs >= samples[sample].len)
- return RET_ERROR (EINVAL); /*
- * Invalid offset
+ return RET_ERROR (EINVAL); /*
+ * Invalid offset
*/
- n = samples[sample].len - offs; /*
- * Nr of bytes left
+ n = samples[sample].len - offs; /*
+ * Nr of bytes left
*/
if (l > n)
@@ -2887,25 +2930,25 @@ guswave_patchmgr (int dev, struct patmgr_info *rec)
l = sizeof (rec->data.data8);
if (l <= 0)
- return RET_ERROR (EINVAL); /*
- * Was there a bug?
+ return RET_ERROR (EINVAL); /*
+ * Was there a bug?
*/
- offs += sample_ptrs[sample]; /*
- * Begin offsess + offset to DRAM
+ offs += sample_ptrs[sample]; /*
+ * Begin offsess + offset to DRAM
*/
for (n = 0; n < l; n++)
rec->data.data8[n] = gus_peek (offs++);
- rec->parm1 = n; /*
- * Nr of bytes copied
+ rec->parm1 = n; /*
+ * Nr of bytes copied
*/
}
return 0;
break;
- case PM_WRITE_PATCH: /*
- * Writes a block of wave data to the DRAM
+ case PM_WRITE_PATCH: /*
+ * Writes a block of wave data to the DRAM
*/
{
int sample = rec->parm1;
@@ -2917,12 +2960,12 @@ guswave_patchmgr (int dev, struct patmgr_info *rec)
return RET_ERROR (EINVAL);
if (offs < 0 || offs >= samples[sample].len)
- return RET_ERROR (EINVAL); /*
- * Invalid offset
+ return RET_ERROR (EINVAL); /*
+ * Invalid offset
*/
- n = samples[sample].len - offs; /*
- * Nr of bytes left
+ n = samples[sample].len - offs; /*
+ * Nr of bytes left
*/
if (l > n)
@@ -2932,18 +2975,18 @@ guswave_patchmgr (int dev, struct patmgr_info *rec)
l = sizeof (rec->data.data8);
if (l <= 0)
- return RET_ERROR (EINVAL); /*
- * Was there a bug?
+ return RET_ERROR (EINVAL); /*
+ * Was there a bug?
*/
- offs += sample_ptrs[sample]; /*
- * Begin offsess + offset to DRAM
+ offs += sample_ptrs[sample]; /*
+ * Begin offsess + offset to DRAM
*/
for (n = 0; n < l; n++)
gus_poke (offs++, rec->data.data8[n]);
- rec->parm1 = n; /*
- * Nr of bytes copied
+ rec->parm1 = n; /*
+ * Nr of bytes copied
*/
}
return 0;
@@ -2974,6 +3017,7 @@ static struct synth_operations guswave_operations =
guswave_aftertouch,
guswave_controller,
guswave_panning,
+ guswave_volume_method,
guswave_patchmgr,
#ifdef FUTURE_VERSION
guswave_bender
@@ -2988,7 +3032,7 @@ set_input_volumes (void)
DISABLE_INTR (flags);
-/*
+ /*
* Enable channels having vol > 10%
* Note! bit 0x01 means line in DISABLED while 0x04 means
* mic in ENABLED.
@@ -3000,7 +3044,7 @@ set_input_volumes (void)
if (recording_active)
{
-/*
+ /*
* Disable channel, if not selected for recording
*/
if (!(gus_recmask & SOUND_MASK_LINE))
@@ -3016,8 +3060,8 @@ set_input_volumes (void)
RESTORE_INTR (flags);
}
-static int
-gus_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
+int
+gus_default_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
{
#define MIX_DEVS (SOUND_MASK_MIC|SOUND_MASK_LINE| \
SOUND_MASK_SYNTH|SOUND_MASK_PCM)
@@ -3085,9 +3129,9 @@ gus_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
if (active_device == GUS_DEV_WAVE)
for (voice = 0; voice < nr_voices; voice++)
- dynamic_volume_change (voice); /*
+ dynamic_volume_change (voice); /*
* Apply the new
- * volume
+ * volume
*/
return IOCTL_OUT (arg, gus_wave_volume | (gus_wave_volume << 8));
@@ -3098,8 +3142,8 @@ gus_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
return RET_ERROR (EINVAL);
}
else
- switch (cmd & 0xff) /*
- * Return parameters
+ switch (cmd & 0xff) /*
+ * Return parameters
*/
{
@@ -3149,13 +3193,97 @@ gus_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
static struct mixer_operations gus_mixer_operations =
{
- gus_mixer_ioctl
+ gus_default_mixer_ioctl
};
+static long
+gus_default_mixer_init (long mem_start)
+{
+ if (num_mixers < MAX_MIXER_DEV) /*
+ * Don't install if there is another
+ * mixer
+ */
+ mixer_devs[num_mixers++] = &gus_mixer_operations;
+
+ return mem_start;
+}
+
long
gus_wave_init (long mem_start, int irq, int dma)
{
- printk ("snd4: <Gravis UltraSound %dk>", (int) gus_mem_size / 1024);
+ unsigned long flags;
+ unsigned char val;
+ char *model_num = "2.4";
+ int gus_type = 0x24; /* 2.4 */
+ int mixer_type = 0;
+
+ /*
+ * Try to identify the GUS model.
+ *
+ * Versions < 3.6 don't have the digital ASIC. Try to probe it first.
+ */
+
+ DISABLE_INTR (flags);
+ OUTB (0x20, gus_base + 0x0f);
+ val = INB (gus_base + 0x0f);
+ RESTORE_INTR (flags);
+
+ if (val != 0xff && (val & 0x06)) /* Should be 0x02? */
+ {
+ /*
+ * It has the digital ASIC so the card is at least v3.4.
+ * Next try to detect the true model.
+ */
+
+ val = INB (u_MixSelect);
+
+ /*
+ * Value 255 means pre-3.7 which don't have mixer.
+ * Values 5 thru 9 mean v3.7 which has a ICS2101 mixer.
+ * 10 and above is GUS MAX which has the CS4231 codec/mixer.
+ *
+ * Sorry. No GUS max support yet but it should be available
+ * soon after the SDK for GUS MAX is available.
+ */
+
+ if (val == 255 || val < 5)
+ {
+ model_num = "3.4";
+ gus_type = 0x34;
+ }
+ else if (val < 10)
+ {
+ model_num = "3.7";
+ gus_type = 0x37;
+ mixer_type = ICS2101;
+ }
+ else
+ {
+ model_num = "MAX";
+ gus_type = 0x40;
+ mixer_type = CS4231;
+ }
+ }
+ else
+ {
+ /*
+ * ASIC not detected so the card must be 2.2 or 2.4.
+ * There could still be the 16-bit/mixer daughter card.
+ * It has the same codec/mixer than MAX.
+ * At this time there is no support for it but it will appear soon.
+ */
+ }
+
+
+#ifdef __FreeBSD__
+ printk ("snd4: <Gravis UltraSound %s (%dk)>", model_num, (int) gus_mem_size / 1024);
+#else
+ printk (" <Gravis UltraSound %s (%dk)>", model_num, (int) gus_mem_size / 1024);
+#endif
+
+#ifndef SCO
+ sprintf (gus_info.name, "Gravis UltraSound %s (%dk)", model_num, (int) gus_mem_size / 1024);
+#endif
if (irq < 0 || irq > 15)
{
@@ -3188,18 +3316,28 @@ gus_wave_init (long mem_start, int irq, int dma)
{
dsp_devs[gus_devnum = num_dspdevs++] = &gus_sampling_operations;
sound_dsp_dmachan[gus_devnum] = dma;
- sound_buffcounts[gus_devnum] = DSP_BUFFCOUNT;
+ sound_buffcounts[gus_devnum] = 1;
sound_buffsizes[gus_devnum] = DSP_BUFFSIZE;
sound_dma_automode[gus_devnum] = 0;
}
else
printk ("GUS: Too many PCM devices available\n");
- if (num_mixers < MAX_MIXER_DEV) /*
- * Don't install if there is another
- * mixer
- */
- mixer_devs[num_mixers++] = &gus_mixer_operations;
+ /*
+ * Mixer dependent initialization.
+ */
+
+ switch (mixer_type)
+ {
+ case ICS2101:
+ gus_line_vol=gus_mic_vol=gus_wave_volume = gus_pcm_volume = 100;
+ return ics2101_mixer_init (mem_start);
+
+ case CS4231:
+ /* Available soon */
+ default:
+ return gus_default_mixer_init (mem_start);
+ }
return mem_start;
}
@@ -3215,8 +3353,8 @@ do_loop_irq (int voice)
gus_select_voice (voice);
tmp = gus_read8 (0x00);
- tmp &= ~0x20; /*
- * Disable wave IRQ for this_one voice
+ tmp &= ~0x20; /*
+ * Disable wave IRQ for this_one voice
*/
gus_write8 (0x00, tmp);
@@ -3227,12 +3365,12 @@ do_loop_irq (int voice)
switch (mode)
{
- case LMODE_FINISH: /*
- * Final loop finished, shoot volume down
+ case LMODE_FINISH: /*
+ * Final loop finished, shoot volume down
*/
- if ((gus_read16 (0x09) >> 4) < 100) /*
- * Get current volume
+ if ((gus_read16 (0x09) >> 4) < 100) /*
+ * Get current volume
*/
{
gus_voice_off ();
@@ -3241,18 +3379,18 @@ do_loop_irq (int voice)
break;
}
gus_ramp_range (65, 4065);
- gus_ramp_rate (0, 63); /*
- * Fastest possible rate
+ gus_ramp_rate (0, 63); /*
+ * Fastest possible rate
*/
- gus_rampon (0x20 | 0x40); /*
- * Ramp down, once, irq
+ gus_rampon (0x20 | 0x40); /*
+ * Ramp down, once, irq
*/
voices[voice].volume_irq_mode = VMODE_HALT;
break;
case LMODE_PCM_STOP:
- pcm_active = 0; /*
- * Requires extensive processing
+ pcm_active = 0; /*
+ * Requires extensive processing
*/
case LMODE_PCM:
{
@@ -3265,8 +3403,8 @@ do_loop_irq (int voice)
play_next_pcm_block ();
}
else
- { /*
- * Out of data. Just stop the voice
+ { /*
+ * Out of data. Just stop the voice
*/
gus_voice_off ();
gus_rampoff ();
@@ -3297,8 +3435,8 @@ do_volume_irq (int voice)
gus_select_voice (voice);
tmp = gus_read8 (0x0d);
- tmp &= ~0x20; /*
- * Disable volume ramp IRQ
+ tmp &= ~0x20; /*
+ * Disable volume ramp IRQ
*/
gus_write8 (0x0d, tmp);
@@ -3308,18 +3446,21 @@ do_volume_irq (int voice)
switch (mode)
{
- case VMODE_HALT: /*
- * Decay phase finished
+ case VMODE_HALT: /*
+ * Decay phase finished
*/
+ RESTORE_INTR (flags);
gus_voice_init (voice);
break;
case VMODE_ENVELOPE:
gus_rampoff ();
+ RESTORE_INTR (flags);
step_envelope (voice);
break;
case VMODE_START_NOTE:
+ RESTORE_INTR (flags);
guswave_start_note2 (voices[voice].dev_pending, voice,
voices[voice].note_pending, voices[voice].volume_pending);
if (voices[voice].kill_pending)
@@ -3334,8 +3475,6 @@ do_volume_irq (int voice)
default:;
}
-
- RESTORE_INTR (flags);
}
void
@@ -3348,37 +3487,37 @@ gus_voice_irq (void)
while (1)
{
- src = gus_read8 (0x0f); /*
- * Get source info
+ src = gus_read8 (0x0f); /*
+ * Get source info
*/
voice = src & 0x1f;
src &= 0xc0;
if (src == (0x80 | 0x40))
- return; /*
- * No interrupt
+ return; /*
+ * No interrupt
*/
voice_bit = 1 << voice;
- if (!(src & 0x80)) /*
- * Wave IRQ pending
+ if (!(src & 0x80)) /*
+ * Wave IRQ pending
*/
- if (!(wave_ignore & voice_bit) && voice < nr_voices) /*
+ if (!(wave_ignore & voice_bit) && voice < nr_voices) /*
* Not done
- * yet
+ * yet
*/
{
wave_ignore |= voice_bit;
do_loop_irq (voice);
}
- if (!(src & 0x40)) /*
- * Volume IRQ pending
+ if (!(src & 0x40)) /*
+ * Volume IRQ pending
*/
- if (!(volume_ignore & voice_bit) && voice < nr_voices) /*
+ if (!(volume_ignore & voice_bit) && voice < nr_voices) /*
* Not done
- * yet
+ * yet
*/
{
volume_ignore |= voice_bit;
@@ -3392,11 +3531,11 @@ guswave_dma_irq (void)
{
unsigned char status;
- status = gus_look8 (0x41); /*
- * Get DMA IRQ Status
+ status = gus_look8 (0x41); /*
+ * Get DMA IRQ Status
*/
- if (status & 0x40) /*
- * DMA Irq pending
+ if (status & 0x40) /*
+ * DMA Irq pending
*/
switch (active_device)
{
@@ -3421,11 +3560,11 @@ guswave_dma_irq (void)
default:;
}
- status = gus_look8 (0x49); /*
- * Get Sampling IRQ Status
+ status = gus_look8 (0x49); /*
+ * Get Sampling IRQ Status
*/
- if (status & 0x40) /*
- * Sampling Irq pending
+ if (status & 0x40) /*
+ * Sampling Irq pending
*/
{
DMAbuf_inputintr (gus_devnum);
diff --git a/sys/i386/isa/sound/midibuf.c b/sys/i386/isa/sound/midibuf.c
index 54b7266..7dadb3f 100644
--- a/sys/i386/isa/sound/midibuf.c
+++ b/sys/i386/isa/sound/midibuf.c
@@ -1,12 +1,12 @@
/*
* sound/midibuf.c
- *
+ *
* Device file manager for /dev/midi
- *
+ *
* NOTE! This part of the driver is currently just a stub.
- *
+ *
* 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
@@ -14,7 +14,7 @@
* 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
@@ -26,7 +26,7 @@
* 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 "sound_config.h"
diff --git a/sys/i386/isa/sound/mpu401.c b/sys/i386/isa/sound/mpu401.c
index 449b6be..38ba486 100644
--- a/sys/i386/isa/sound/mpu401.c
+++ b/sys/i386/isa/sound/mpu401.c
@@ -1,12 +1,12 @@
/*
* sound/mpu401.c
- *
+ *
* The low level driver for Roland MPU-401 compatible Midi cards.
- *
+ *
* This version supports just the DUMB UART mode.
- *
+ *
* 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
@@ -14,7 +14,7 @@
* 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
@@ -26,7 +26,7 @@
* 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 "sound_config.h"
@@ -35,7 +35,7 @@
#if !defined(EXCLUDE_MPU401) && !defined(EXCLUDE_MIDI)
-#define DATAPORT (mpu401_base) /* MPU-401 Data I/O Port on IBM */
+#define DATAPORT (mpu401_base)/* MPU-401 Data I/O Port on IBM */
#define COMDPORT (mpu401_base+1) /* MPU-401 Command Port on IBM */
#define STATPORT (mpu401_base+1) /* MPU-401 Status Port on IBM */
@@ -61,58 +61,16 @@ static int my_dev;
static int reset_mpu401 (void);
static void (*midi_input_intr) (int dev, unsigned char data);
-static void
-mpu401_input_loop (void)
-{
- int count;
-
- count = 10;
-
- while (count) /* Not timed out */
- if (input_avail ())
- {
- unsigned char c = mpu401_read ();
-
- count = 100;
-
- if (mpu401_opened & OPEN_READ)
- midi_input_intr (my_dev, c);
- }
- else
- while (!input_avail () && count)
- count--;
-}
-
void
mpuintr (int unit)
{
- if (input_avail ())
- mpu401_input_loop ();
-}
-
-/*
- * It looks like there is no input interrupts in the UART mode. Let's try
- * polling.
- */
-
-static void
-poll_mpu401 (unsigned long dummy)
-{
- unsigned long flags;
-
- DEFINE_TIMER (mpu401_timer, poll_mpu401);
-
- if (!(mpu401_opened & OPEN_READ))
- return; /* No longer required */
-
- DISABLE_INTR (flags);
-
- if (input_avail ())
- mpu401_input_loop ();
-
- ACTIVATE_TIMER (mpu401_timer, poll_mpu401, 1); /* Come back later */
+ while (input_avail ())
+ {
+ unsigned char c = mpu401_read ();
- RESTORE_INTR (flags);
+ if (mpu401_opened & OPEN_READ)
+ midi_input_intr (my_dev, c);
+ }
}
static int
@@ -127,11 +85,10 @@ mpu401_open (int dev, int mode,
return RET_ERROR (EBUSY);
}
- mpu401_input_loop ();
+ mpuintr (0);
midi_input_intr = input;
mpu401_opened = mode;
- poll_mpu401 (0); /* Enable input polling */
return 0;
}
@@ -155,7 +112,7 @@ mpu401_out (int dev, unsigned char midi_byte)
DISABLE_INTR (flags);
if (input_avail ())
- mpu401_input_loop ();
+ mpuintr (0);
RESTORE_INTR (flags);
@@ -250,7 +207,11 @@ attach_mpu401 (long mem_start, struct address_info *hw_config)
RESTORE_INTR (flags);
+#ifdef __FreeBSD__
printk ("snd5: <Roland MPU-401>");
+#else
+ printk (" <Roland MPU-401>");
+#endif
my_dev = num_midis;
mpu401_dev = num_midis;
@@ -291,7 +252,7 @@ reset_mpu401 (void)
mpu401_opened = 0;
if (ok)
- mpu401_input_loop (); /* Flush input before enabling interrupts */
+ mpuintr (0); /* Flush input before enabling interrupts */
RESTORE_INTR (flags);
diff --git a/sys/i386/isa/sound/opl3.c b/sys/i386/isa/sound/opl3.c
index 58327a3..6e3dcca 100644
--- a/sys/i386/isa/sound/opl3.c
+++ b/sys/i386/isa/sound/opl3.c
@@ -1,10 +1,10 @@
/*
* 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
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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, */
@@ -81,6 +81,9 @@ 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;
@@ -168,10 +171,10 @@ 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.
*/
@@ -197,7 +200,7 @@ opl3_detect (int ioaddr)
return 0; /* Should be 0x00 */
}
- opl3_command (ioaddr, TIMER1_REGISTER, 0xff); /* Set timer 1 to 0xff */
+ opl3_command (ioaddr, TIMER1_REGISTER, 0xff); /* Set timer 1 to 0xff */
opl3_command (ioaddr, TIMER_CONTROL_REGISTER,
TIMER2_MASK | TIMER1_START); /* Unmask and start timer 1 */
@@ -305,9 +308,9 @@ char fm_volume_table[128] =
-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 */
+ -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 */
@@ -373,8 +376,8 @@ set_voice_volume (int voice, int volume)
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 */
+ 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 */
@@ -414,7 +417,7 @@ set_voice_volume (int voice, int volume)
calc_vol (&vol4, volume);
break;
- default: /* Why ?? */ ;
+ default:/* Why ?? */ ;
}
opl3_command (map->ioaddr, KSL_LEVEL + map->op[0], vol1);
@@ -747,6 +750,11 @@ 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) \
@@ -851,9 +859,8 @@ opl3_controller (int dev, int voice, int ctrl_num, int value)
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 */
-
+ 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);
break;
@@ -887,6 +894,7 @@ static struct synth_operations opl3_operations =
opl3_aftertouch,
opl3_controller,
opl3_panning,
+ opl3_volume_method,
opl3_patchmgr
};
@@ -895,7 +903,7 @@ opl3_init (long mem_start)
{
int i;
- PERMANENT_MALLOC(struct sbi_instrument *, instrmap,
+ PERMANENT_MALLOC (struct sbi_instrument *, instrmap,
SBFM_MAXINSTR * sizeof (*instrmap), mem_start);
synth_devs[num_synths++] = &opl3_operations;
@@ -903,7 +911,11 @@ opl3_init (long mem_start)
opl3_ok = 1;
if (opl3_enabled)
{
+#ifdef __FreeBSD__
printk ("snd1: <Yamaha OPL-3 FM>");
+#else
+ printk (" <Yamaha OPL-3 FM>");
+#endif
fm_model = 2;
nr_voices = 18;
fm_info.nr_drums = 0;
@@ -925,7 +937,11 @@ opl3_init (long mem_start)
}
else
{
+#ifdef __FreeBSD__
printk ("snd1: <Yamaha 2-OP FM>");
+#else
+ printk (" <Yamaha 2-OP FM>");
+#endif
fm_model = 1;
nr_voices = 9;
fm_info.nr_drums = 0;
diff --git a/sys/i386/isa/sound/pas.h b/sys/i386/isa/sound/pas.h
index 797c8fd..9902e03 100644
--- a/sys/i386/isa/sound/pas.h
+++ b/sys/i386/isa/sound/pas.h
@@ -138,11 +138,11 @@
char I_C_2_PCM_DMA_translate[] = /* R W PCM PCM DMA channel value translations */
{ 4, 1, 2, 3, 0, 5, 6, 7 };
char I_C_3_PCM_IRQ_translate[] = /* R W PCM PCM IRQ level value translation */
- { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 };
+ { 0, 0, 1, 2, 3, 4, 5, 6, 0, 1, 7, 8, 9, 0, 10, 11 };
char E_C_MPU401_IRQ_translate[] = /* R W MIDI MPU401 emulation IRQ value translation */
- { 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x05, 0x06, 0x07 };
+ { 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x05, 0x06, 0x07 };
char E_C_SB_IRQ_translate[] = /* R W PCM SB emulation IRQ translate */
- { 0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x00, 0x28, 0x30, 0x38, 0, 0 };
+ { 0x00, 0x00, 0x08, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x08, 0x28, 0x30, 0x38, 0, 0 };
char E_C_SB_DMA_translate[] = /* R W PCM SB emulation DMA translate */
{ 0x00, 0x40, 0x80, 0xC0, 0, 0, 0, 0 };
char O_M_1_to_card[] = /* R W Control Translate (OM1 & 0x0f) to card type */
diff --git a/sys/i386/isa/sound/pas2_card.c b/sys/i386/isa/sound/pas2_card.c
index c89dd33..a4791e8 100644
--- a/sys/i386/isa/sound/pas2_card.c
+++ b/sys/i386/isa/sound/pas2_card.c
@@ -2,11 +2,11 @@
#define SND_SA_INTERRUPT
/*
* sound/pas2_card.c
- *
+ *
* Detection routine for the Pro Audio Spectrum cards.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -14,7 +14,7 @@
* 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
@@ -26,7 +26,7 @@
* 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 "sound_config.h"
@@ -79,7 +79,7 @@ pasintr (int unused)
int status;
status = pas_read (INTERRUPT_STATUS);
- pas_write (status, INTERRUPT_STATUS); /* Clear interrupt */
+ pas_write (status, INTERRUPT_STATUS); /* Clear interrupt */
if (status & I_S_PCM_SAMPLE_BUFFER_IRQ)
{
@@ -197,7 +197,7 @@ config_pas_hw (struct address_info *hw_config)
}
}
-/*
+ /*
* This fixes the timing problems of the PAS due to the Symphony chipset
* as per Media Vision. Only define this if your PAS doesn't work correctly.
*/
@@ -317,7 +317,11 @@ attach_pas_card (long mem_start, struct address_info *hw_config)
if ((pas_model = O_M_1_to_card[pas_read (OPERATION_MODE_1) & 0x0f]))
{
+#ifdef __FreeBSD__
printk ("snd3: <%s rev %d>", pas_model_names[(int) pas_model], pas_read (BOARD_REV_ID));
+#else
+ printk (" <%s rev %d>", pas_model_names[(int) pas_model], pas_read (BOARD_REV_ID));
+#endif
}
if (config_pas_hw (hw_config))
diff --git a/sys/i386/isa/sound/pas2_midi.c b/sys/i386/isa/sound/pas2_midi.c
index 5620d72..4a07b0b 100644
--- a/sys/i386/isa/sound/pas2_midi.c
+++ b/sys/i386/isa/sound/pas2_midi.c
@@ -1,10 +1,10 @@
/*
* sound/pas2_midi.c
- *
+ *
* The low level driver for the PAS Midi Interface.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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 "sound_config.h"
@@ -79,7 +79,7 @@ pas_midi_open (int dev, int mode,
if (mode == OPEN_READ || mode == OPEN_READWRITE)
{
- ctrl |= M_C_ENA_INPUT_IRQ; /* Enable input */
+ ctrl |= M_C_ENA_INPUT_IRQ;/* Enable input */
input_opened = 1;
}
@@ -122,7 +122,7 @@ dump_to_midi (unsigned char midi_byte)
fifo_space = ((x = pas_read (MIDI_FIFO_STATUS)) >> 4) & 0x0f;
- if (fifo_space == 15 || (fifo_space < 2 && ofifo_bytes > 13)) /* Fifo full */
+ if (fifo_space == 15 || (fifo_space < 2 && ofifo_bytes > 13)) /* Fifo full */
{
return 0; /* Upper layer will call again */
}
@@ -287,7 +287,7 @@ pas_midi_interrupt (void)
ofifo_bytes = 100;
}
- pas_write (stat, MIDI_STATUS); /* Acknowledge interrupts */
+ pas_write (stat, MIDI_STATUS);/* Acknowledge interrupts */
}
#endif
diff --git a/sys/i386/isa/sound/pas2_mixer.c b/sys/i386/isa/sound/pas2_mixer.c
index 0ec6753..fd3e106 100644
--- a/sys/i386/isa/sound/pas2_mixer.c
+++ b/sys/i386/isa/sound/pas2_mixer.c
@@ -2,11 +2,11 @@
/*
* sound/pas2_mixer.c
- *
+ *
* Mixer routines for the Pro Audio Spectrum cards.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -14,7 +14,7 @@
* 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
@@ -26,7 +26,7 @@
* 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 "sound_config.h"
@@ -39,7 +39,7 @@
extern int translat_code;
-static int rec_devices = (SOUND_MASK_MIC); /* Default recording source */
+static int rec_devices = (SOUND_MASK_MIC); /* Default recording source */
static int mode_control = 0;
#define POSSIBLE_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_SPEAKER | SOUND_MASK_LINE | SOUND_MASK_MIC | \
@@ -331,7 +331,7 @@ mixer_get_levels (struct sb_mixer_levels *user_l)
struct sb_mixer_levels l;
l.master.r = ((((levels[SOUND_MIXER_VOLUME] >> 8) & 0x7f) * 15) + 50) / 100; /* Master */
- l.master.l = (((levels[SOUND_MIXER_VOLUME] & 0x7f) * 15) + 50) / 100; /* Master */
+ l.master.l = (((levels[SOUND_MIXER_VOLUME] & 0x7f) * 15) + 50) / 100; /* Master */
l.line.r = ((getmixer (SOUND_MIXER_LINE, P_M_MV508_RIGHT) * 15) + 50) / 100; /* Line */
l.line.l = ((getmixer (SOUND_MIXER_LINE, P_M_MV508_LEFT) * 15) + 50) / 100;
diff --git a/sys/i386/isa/sound/pas2_pcm.c b/sys/i386/isa/sound/pas2_pcm.c
index f8b2238..06742d5 100644
--- a/sys/i386/isa/sound/pas2_pcm.c
+++ b/sys/i386/isa/sound/pas2_pcm.c
@@ -1,11 +1,11 @@
#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
@@ -13,7 +13,7 @@
* 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
@@ -25,7 +25,7 @@
* 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 "sound_config.h"
@@ -100,7 +100,7 @@ pcm_set_channels (int arg)
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 */
+ pcm_set_speed (pcm_speed);/* The speed must be reinitialized */
}
return pcm_channels;
@@ -337,14 +337,15 @@ pas_pcm_prepare_for_output (int dev, int bsize, int bcount)
static struct audio_operations pas_pcm_operations =
{
"Pro Audio Spectrum",
- 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, /* */
+ NOTHING_SPECIAL,
+ 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, /* halt_xfer */
NULL, /* has_output_drained */
NULL /* copy_from_user */
diff --git a/sys/i386/isa/sound/patmgr.c b/sys/i386/isa/sound/patmgr.c
index f5697ae..042d42d 100644
--- a/sys/i386/isa/sound/patmgr.c
+++ b/sys/i386/isa/sound/patmgr.c
@@ -1,10 +1,10 @@
/*
* sound/patmgr.c
- *
+ *
* The patch maneger interface for the /dev/sequencer
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
+ *
*/
#define PATMGR_C
diff --git a/sys/i386/isa/sound/sb16_dsp.c b/sys/i386/isa/sound/sb16_dsp.c
index d85359b..a755712 100644
--- a/sys/i386/isa/sound/sb16_dsp.c
+++ b/sys/i386/isa/sound/sb16_dsp.c
@@ -1,12 +1,12 @@
/*
* 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
@@ -14,7 +14,7 @@
* 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
@@ -26,7 +26,7 @@
* 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)
@@ -40,9 +40,9 @@
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_AUDIO) && !defined(EXCLUDE_SBPRO)
-extern int sbc_base;
+extern int sbc_base, sbc_minor, sbc_major;
-static int sb16_dsp_ok = 0; /* Set to 1 after successful initialization */
+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; */
@@ -74,6 +74,7 @@ int sb_reset_dsp (void);
static struct audio_operations sb16_dsp_operations =
{
"SoundBlaster 16",
+ NOTHING_SPECIAL,
sb16_dsp_open,
sb16_dsp_close,
sb16_dsp_output_block,
@@ -87,7 +88,7 @@ static struct audio_operations sb16_dsp_operations =
NULL
};
-static int
+static int
sb_dsp_command01 (unsigned char val)
{
int i = 1 << 16;
@@ -98,33 +99,32 @@ sb_dsp_command01 (unsigned char val)
return sb_dsp_command (val);
}
-static int
-wait_data_avail (int t)
+static int
+wait_data_avail (unsigned long t)
{
int loopc = 5000000;
- unsigned long tt;
- tt = t + GET_TIME ();
+ t += GET_TIME ();
do
{
if (INB (DSP_DATA_AVAIL) & 0x80)
return 1;
}
- while (--loopc && GET_TIME () < tt);
+ while (--loopc && GET_TIME () < t);
printk ("!data_avail l=%d\n", loopc);
return 0;
}
-static int
+static int
read_dsp (int t)
{
- if (!wait_data_avail (t))
+ if (!wait_data_avail ((unsigned long) t))
return -1;
else
return INB (DSP_READ);
}
-static int
+static int
dsp_ini2 (void)
{
#if 0
@@ -141,6 +141,7 @@ dsp_ini2 (void)
#endif
return 0;
}
+
/*
static char *dsp_getmessage(unsigned char command,int maxn)
{
@@ -148,7 +149,7 @@ dsp_ini2 (void)
int n=0;
sb_dsp_command(command);
- while(n<maxn && wait_data_avail(2)) {
+ while(n<maxn && wait_data_avail(2L)) {
buff[++n]=INB(DSP_READ);
if(!buff[n])
break;
@@ -171,7 +172,7 @@ dsp_ini2 (void)
printk("\n");
}
*/
-static int
+static int
dsp_set_speed (int mode)
{
DEB (printk ("dsp_set_speed(%d)\n", mode));
@@ -186,7 +187,7 @@ dsp_set_speed (int mode)
return mode;
}
-static int
+static int
dsp_set_stereo (int mode)
{
DEB (printk ("dsp_set_stereo(%d)\n", mode));
@@ -196,7 +197,7 @@ dsp_set_stereo (int mode)
return mode;
}
-static int
+static int
dsp_set_bits (int arg)
{
DEB (printk ("dsp_set_bits(%d)\n", arg));
@@ -523,36 +524,24 @@ set_irq_hw (int level)
long
sb16_dsp_init (long mem_start, struct address_info *hw_config)
{
- int i, major, minor;
-
- major = minor = 0;
- sb_dsp_command (0xe1); /* Get version */
-
- for (i = 1000; i; i--)
- {
- if (INB (DSP_DATA_AVAIL) & 0x80)
- { /* wait for Data Ready */
- if (major == 0)
- major = INB (DSP_READ);
- else
- {
- minor = INB (DSP_READ);
- break;
- }
- }
- }
+ if (sbc_major < 4)
+ return mem_start;
#ifndef SCO
- sprintf (sb16_dsp_operations.name, "SoundBlaster 16 %d.%d", major, minor);
+ sprintf (sb16_dsp_operations.name, "SoundBlaster 16 %d.%d", sbc_major, sbc_minor);
#endif
+#ifdef __FreeBSD__
printk ("snd6: <%s>", sb16_dsp_operations.name);
+#else
+ printk (" <%s>", sb16_dsp_operations.name);
+#endif
if (num_dspdevs < MAX_DSP_DEV)
{
dsp_devs[my_dev = num_dspdevs++] = &sb16_dsp_operations;
sound_dsp_dmachan[my_dev] = hw_config->dma;
- sound_buffcounts[my_dev] = DSP_BUFFCOUNT;
+ sound_buffcounts[my_dev] = 1;
sound_buffsizes[my_dev] = DSP_BUFFSIZE;
sound_dma_automode[my_dev] = 1;
}
@@ -576,9 +565,6 @@ sb16_dsp_detect (struct address_info *hw_config)
return 0;
}
- if (sbc_base != hw_config->io_base)
- printk ("Warning! SB16 I/O != SB I/O\n");
-
/* sb_setmixer(OPSW,0xf);
if(sb_getmixer(OPSW)!=0xf)
return 0; */
@@ -586,13 +572,6 @@ sb16_dsp_detect (struct address_info *hw_config)
if (!sb_reset_dsp ())
return 0;
- if (hw_config->irq != sb_config->irq)
- {
- printk ("SB16 Error: Invalid IRQ number %d/%d\n",
- sb_config->irq, hw_config->irq);
- return 0;
- }
-
if (hw_config->dma < 4)
if (hw_config->dma != sb_config->dma)
{
@@ -603,12 +582,12 @@ sb16_dsp_detect (struct address_info *hw_config)
dma16 = hw_config->dma;
dma8 = sb_config->dma;
- set_irq_hw (hw_config->irq);
+ set_irq_hw (sb_config->irq);
sb_setmixer (DMA_NR, (1 << hw_config->dma) | (1 << sb_config->dma));
- DEB (printk ("SoundBlaster 16: IRQ %d DMA %d OK\n", hw_config->irq, hw_config->dma));
+ DEB (printk ("SoundBlaster 16: IRQ %d DMA %d OK\n", sb_config->irq, hw_config->dma));
-/*
+ /*
dsp_showmessage(0xe3,99);
*/
sb16_dsp_ok = 1;
@@ -639,4 +618,5 @@ sb16_dsp_interrupt (int unused)
printk ("SoundBlaster: Unexpected interrupt\n");
}
}
+
#endif
diff --git a/sys/i386/isa/sound/sb16_midi.c b/sys/i386/isa/sound/sb16_midi.c
index f7a61a6..39808c8 100644
--- a/sys/i386/isa/sound/sb16_midi.c
+++ b/sys/i386/isa/sound/sb16_midi.c
@@ -1,10 +1,10 @@
/*
* 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
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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 "sound_config.h"
@@ -58,26 +58,19 @@ static int my_dev;
static int reset_sb16midi (void);
static void (*midi_input_intr) (int dev, unsigned char data);
+extern int sbc_major;
+
static void
sb16midi_input_loop (void)
{
- int count;
-
- count = 10;
-
- while (count) /* Not timed out */
- if (input_avail ())
- {
- unsigned char c = sb16midi_read ();
- count = 100;
+ while (input_avail ())
+ {
+ unsigned char c = sb16midi_read ();
- if (sb16midi_opened & OPEN_READ)
- midi_input_intr (my_dev, c);
- }
- else
- while (!input_avail () && count)
- count--;
+ if (sb16midi_opened & OPEN_READ)
+ midi_input_intr (my_dev, c);
+ }
}
void
@@ -87,31 +80,6 @@ sb16midiintr (int unit)
sb16midi_input_loop ();
}
-/*
- * It looks like there is no input interrupts in the UART mode. Let's try
- * polling.
- */
-
-static void
-poll_sb16midi (unsigned long dummy)
-{
- unsigned long flags;
-
- DEFINE_TIMER (sb16midi_timer, poll_sb16midi);
-
- if (!(sb16midi_opened & OPEN_READ))
- return; /* No longer required */
-
- DISABLE_INTR (flags);
-
- if (input_avail ())
- sb16midi_input_loop ();
-
- ACTIVATE_TIMER (sb16midi_timer, poll_sb16midi, 1); /* Come back later */
-
- RESTORE_INTR (flags);
-}
-
static int
sb16midi_open (int dev, int mode,
void (*input) (int dev, unsigned char data),
@@ -127,7 +95,6 @@ sb16midi_open (int dev, int mode,
midi_input_intr = input;
sb16midi_opened = mode;
- poll_sb16midi (0); /* Enable input polling */
return 0;
}
@@ -245,7 +212,11 @@ attach_sb16midi (long mem_start, struct address_info *hw_config)
RESTORE_INTR (flags);
+#ifdef __FreeBSD__
printk ("snd7: <SoundBlaster MPU-401>");
+#else
+ printk (" <SoundBlaster MPU-401>");
+#endif
my_dev = num_midis;
midi_devs[num_midis++] = &sb16midi_operations;
@@ -299,6 +270,8 @@ probe_sb16midi (struct address_info *hw_config)
int ok = 0;
sb16midi_base = hw_config->io_base;
+ if (sbc_major < 4)
+ return 0; /* SB16 not detected */
if (sb_get_irq () < 0)
return 0;
diff --git a/sys/i386/isa/sound/sb_card.c b/sys/i386/isa/sound/sb_card.c
index ef90b4b..f7588e1 100644
--- a/sys/i386/isa/sound/sb_card.c
+++ b/sys/i386/isa/sound/sb_card.c
@@ -1,10 +1,10 @@
/*
* sound/sb_card.c
- *
+ *
* Detection routine for the SoundBlaster cards.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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 "sound_config.h"
diff --git a/sys/i386/isa/sound/sb_dsp.c b/sys/i386/isa/sound/sb_dsp.c
index 9f0bfb2..17fb4b7 100644
--- a/sys/i386/isa/sound/sb_dsp.c
+++ b/sys/i386/isa/sound/sb_dsp.c
@@ -25,6 +25,10 @@
* 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
+ *
*/
#include "sound_config.h"
@@ -37,6 +41,7 @@
int sbc_base = 0;
static int sbc_irq = 0;
+static int open_mode=0;
/*
* The DSP channel can be used either for input or output. Variable
@@ -49,7 +54,8 @@ static int sbc_irq = 0;
int sb_dsp_ok = 0; /* Set to 1 after successful initialization */
static int midi_disabled = 0;
int sb_dsp_highspeed = 0;
-static int major = 1, minor = 0; /* DSP version */
+int sbc_major = 1;
+int sbc_minor = 0; /* DSP version */
static int dsp_stereo = 0;
static int dsp_current_speed = DSP_DEFAULT_SPEED;
static int sb16 = 0;
@@ -64,7 +70,6 @@ volatile int sb_irq_mode = IMODE_NONE; /* IMODE_INPUT, IMODE_OUTPUT
* or IMODE_NONE */
static volatile int irq_ok = 0;
-int sb_dsp_model = 1; /* 1=SB, 2=SB Pro */
int sb_duplex_midi = 0;
static int my_dev = 0;
@@ -84,7 +89,7 @@ sb_dsp_command (unsigned char val)
int i;
unsigned long limit;
- limit = GET_TIME () + HZ/10; /* The timeout is 0.1 secods */
+ 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
@@ -111,7 +116,7 @@ sb_dsp_command (unsigned char val)
void
sbintr (int unit)
{
- int status, data;
+ int status;
#ifndef EXCLUDE_SBPRO
if (sb16)
@@ -134,7 +139,7 @@ sbintr (int unit)
}
#endif
- status = INB (DSP_DATA_AVAIL); /* Clear interrupt */
+ status = INB (DSP_DATA_AVAIL);/* Clear interrupt */
if (sb_intr_active)
switch (sb_irq_mode)
@@ -156,10 +161,7 @@ sbintr (int unit)
break;
case IMODE_MIDI:
- printk ("+");
- data = INB (DSP_READ);
- printk ("%x", data);
-
+ sb_midi_interrupt (unit);
break;
default:
@@ -234,17 +236,31 @@ dsp_speed (int speed)
{
unsigned char tconst;
unsigned long flags;
+ int max_speed = 44100;
if (speed < 4000)
speed = 4000;
- if (speed > 44100)
- speed = 44100; /* Invalid speed */
+ /*
+ * Older SB models don't support higher speeds than 22050.
+ */
- if (sb_dsp_model == 1 && speed > 22050)
- speed = 22050;
- /* SB Classic doesn't support higher speed */
+ 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 */
if (dsp_stereo && speed > 22050)
speed = 22050;
@@ -285,7 +301,7 @@ dsp_speed (int speed)
tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff;
DISABLE_INTR (flags);
- if (sb_dsp_command (0x40)) /* Set time constant */
+ if (sb_dsp_command (0x40))/* Set time constant */
sb_dsp_command (tconst);
RESTORE_INTR (flags);
@@ -308,7 +324,7 @@ dsp_set_stereo (int mode)
#ifdef EXCLUDE_SBPRO
return 0;
#else
- if (sb_dsp_model < 3 || sb16)
+ if (sbc_major < 3 || sb16)
return 0; /* Sorry no stereo */
if (mode && sb_midi_busy)
@@ -341,11 +357,11 @@ sb_dsp_output_block (int dev, unsigned long buf, int count,
if (sb_dsp_highspeed)
{
DISABLE_INTR (flags);
- if (sb_dsp_command (0x48)) /* High speed size */
+ 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 */
+ sb_dsp_command (0x91);/* High speed 8 bit DAC */
}
else
printk ("SB Error: Unable to start (high speed) DAC\n");
@@ -354,7 +370,7 @@ sb_dsp_output_block (int dev, unsigned long buf, int count,
else
{
DISABLE_INTR (flags);
- if (sb_dsp_command (0x14)) /* 8-bit DAC (DMA) */
+ if (sb_dsp_command (0x14))/* 8-bit DAC (DMA) */
{
sb_dsp_command ((unsigned char) (count & 0xff));
sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
@@ -387,11 +403,11 @@ sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag,
if (sb_dsp_highspeed)
{
DISABLE_INTR (flags);
- if (sb_dsp_command (0x48)) /* High speed size */
+ 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 */
+ sb_dsp_command (0x99);/* High speed 8 bit ADC */
}
else
printk ("SB Error: Unable to start (high speed) ADC\n");
@@ -400,7 +416,7 @@ sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag,
else
{
DISABLE_INTR (flags);
- if (sb_dsp_command (0x24)) /* 8-bit ADC (DMA) */
+ if (sb_dsp_command (0x24))/* 8-bit ADC (DMA) */
{
sb_dsp_command ((unsigned char) (count & 0xff));
sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
@@ -425,7 +441,7 @@ sb_dsp_prepare_for_input (int dev, int bsize, int bcount)
dsp_cleanup ();
dsp_speaker (OFF);
- if (major == 3) /* SB Pro */
+ if (sbc_major == 3) /* SB Pro */
{
if (dsp_stereo)
sb_dsp_command (0xa8);
@@ -445,7 +461,7 @@ sb_dsp_prepare_for_output (int dev, int bsize, int bcount)
dsp_speaker (ON);
#ifndef EXCLUDE_SBPRO
- if (major == 3) /* SB Pro */
+ if (sbc_major == 3) /* SB Pro */
{
sb_mixer_set_stereo (dsp_stereo);
dsp_speed (dsp_current_speed); /* Speed must be recalculated if #channels
@@ -534,6 +550,7 @@ sb_dsp_open (int dev, int mode)
sb_irq_mode = IMODE_NONE;
sb_dsp_busy = 1;
+ open_mode = mode;
return 0;
}
@@ -547,6 +564,7 @@ sb_dsp_close (int dev)
dsp_speaker (OFF);
sb_dsp_busy = 0;
sb_dsp_highspeed = 0;
+ open_mode = 0;
}
static int
@@ -588,7 +606,7 @@ sb_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
case SOUND_PCM_READ_BITS:
if (local)
return 8;
- return IOCTL_OUT (arg, 8); /* Only 8 bits/sample supported */
+ return IOCTL_OUT (arg, 8);/* Only 8 bits/sample supported */
break;
case SOUND_PCM_WRITE_FILTER:
@@ -611,6 +629,7 @@ sb_dsp_reset (int dev)
DISABLE_INTR (flags);
sb_reset_dsp ();
+ dsp_speed (dsp_current_speed);
dsp_cleanup ();
RESTORE_INTR (flags);
@@ -636,9 +655,10 @@ sb_dsp_detect (struct address_info *hw_config)
static char card_name[32] = "SoundBlaster";
#ifndef EXCLUDE_AUDIO
-struct audio_operations sb_dsp_operations =
+static struct audio_operations sb_dsp_operations =
{
"SoundBlaster",
+ NOTHING_SPECIAL,
sb_dsp_open,
sb_dsp_close,
sb_dsp_output_block,
@@ -658,62 +678,77 @@ long
sb_dsp_init (long mem_start, struct address_info *hw_config)
{
int i;
+ int prostat = 0;
- major = minor = 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 (major == 0)
- major = INB (DSP_READ);
+ if (sbc_major == 0)
+ sbc_major = INB (DSP_READ);
else
{
- minor = INB (DSP_READ);
+ sbc_minor = INB (DSP_READ);
break;
}
}
}
- if (major == 2 || major == 3)
+ if (sbc_major == 2 || sbc_major == 3) /* SB 2.0 or SB Pro */
sb_duplex_midi = 1;
- if (major == 4)
+ if (sbc_major == 4)
sb16 = 1;
- sb_dsp_model = major;
-
#ifndef EXCLUDE_SBPRO
- if (major >= 3)
- sb_mixer_init (major);
+ if (sbc_major >= 3 ||
+ (sbc_major == 2 && sbc_minor == 1)) /* Sound Galaxy ??? */
+ prostat = sb_mixer_init (sbc_major);
#endif
#ifndef EXCLUDE_YM3812
- if (major > 3 || (major == 3 && minor > 0)) /* SB Pro2 or later */
- {
- enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);
- }
+ if (sbc_major > 3 ||
+ (sbc_major == 3 && INB (0x388) == 0x00)) /* Non OPL-3 should return 0x06 */
+ enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);
#endif
-#ifndef SCO
- if (major >= 3)
+ if (sbc_major >= 3)
{
+#ifndef SCO
+ if (prostat)
+ {
#ifndef EXCLUDE_AUDIO
- sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", major, minor);
+ sprintf (sb_dsp_operations.name, "Sound Galaxy NX Pro %d.%d", sbc_major, sbc_minor);
+#endif
+ sprintf (card_name, "Sound Galaxy NX Pro %d.%d", sbc_major, sbc_minor);
+ }
+ else
+ {
+#ifndef EXCLUDE_AUDIO
+ sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", sbc_major, sbc_minor);
+#endif
+ sprintf (card_name, "SoundBlaster Pro %d.%d", sbc_major, sbc_minor);
+ }
#endif
- sprintf (card_name, "SoundBlaster Pro %d.%d", major, minor);
}
else
{
+#ifndef SCO
#ifndef EXCLUDE_AUDIO
- sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", major, minor);
+ sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", sbc_major, sbc_minor);
#endif
- sprintf (card_name, "SoundBlaster %d.%d", major, minor);
- }
+ sprintf (card_name, "SoundBlaster %d.%d", sbc_major, sbc_minor);
#endif
+ }
+#ifdef __FreeBSD__
printk ("snd2: <%s>", card_name);
+#else
+ printk (" <%s>", card_name);
+#endif
#ifndef EXCLUDE_AUDIO
#if !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SBPRO)
@@ -734,7 +769,7 @@ sb_dsp_init (long mem_start, struct address_info *hw_config)
#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 (major);
+ sb_midi_init (sbc_major);
#endif
sb_dsp_ok = 1;
diff --git a/sys/i386/isa/sound/sb_midi.c b/sys/i386/isa/sound/sb_midi.c
index 2b0ab52..fed19ab 100644
--- a/sys/i386/isa/sound/sb_midi.c
+++ b/sys/i386/isa/sound/sb_midi.c
@@ -1,10 +1,10 @@
/*
* sound/sb_dsp.c
- *
+ *
* The low level driver for the SoundBlaster DS chips.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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 "sound_config.h"
@@ -49,12 +49,16 @@ extern int sb_midi_busy; /* 1 if the process has output to MIDI */
extern int sb_dsp_busy;
extern int sb_dsp_highspeed;
-extern volatile int sb_irq_mode; /* IMODE_INPUT, IMODE_OUTPUT
+extern volatile int sb_irq_mode;/* IMODE_INPUT, IMODE_OUTPUT
* or IMODE_NONE */
-extern int sb_dsp_model; /* 1=SB, 2=SB Pro */
extern int sb_duplex_midi;
extern int sb_intr_active;
+extern int sbc_base;
+
+static int input_opened = 0;
+static void (*midi_input_intr) (int dev, unsigned char data);
+static int my_dev = 0;
static int
sb_midi_open (int dev, int mode,
@@ -73,7 +77,7 @@ sb_midi_open (int dev, int mode,
if (mode != OPEN_WRITE && !sb_duplex_midi)
{
if (num_midis == 1)
- printk ("SoundBlaster: Midi input not currently supported\n");
+ printk ("SoundBlaster: MIDI input not supported with plain SB\n");
return RET_ERROR (EPERM);
}
@@ -97,6 +101,9 @@ sb_midi_open (int dev, int mode,
sb_reset_dsp ();
+ if (!sb_dsp_command (0xf2)) /* This is undodumented, isn't it */
+ return RET_ERROR (EIO); /* be nice to DSP */
+
if (!sb_dsp_command (0x35))
return RET_ERROR (EIO); /* Enter the UART mode */
sb_intr_active = 1;
@@ -106,6 +113,9 @@ sb_midi_open (int dev, int mode,
sb_reset_dsp ();
return 0; /* IRQ not free */
}
+ input_opened = 1;
+ my_dev = dev;
+ midi_input_intr = input;
}
sb_midi_busy = 1;
@@ -123,6 +133,7 @@ sb_midi_close (int dev)
}
sb_intr_active = 0;
sb_midi_busy = 0;
+ input_opened = 0;
}
static int
@@ -175,6 +186,21 @@ sb_midi_ioctl (int dev, unsigned cmd, unsigned arg)
return RET_ERROR (EPERM);
}
+void
+sb_midi_interrupt (int dummy)
+{
+ unsigned long flags;
+ unsigned char data;
+
+ DISABLE_INTR (flags);
+
+ data = INB (DSP_READ);
+ if (input_opened)
+ midi_input_intr (my_dev, data);
+
+ RESTORE_INTR (flags);
+}
+
static struct midi_operations sb_midi_operations =
{
{"SoundBlaster", 0, 0, SNDCARD_SB},
diff --git a/sys/i386/isa/sound/sb_mixer.c b/sys/i386/isa/sound/sb_mixer.c
index 089a2af..39b97ca 100644
--- a/sys/i386/isa/sound/sb_mixer.c
+++ b/sys/i386/isa/sound/sb_mixer.c
@@ -1,11 +1,11 @@
/*
* sound/sb_mixer.c
- *
+ *
* The low level mixer driver for the SoundBlaster Pro and SB16 cards.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -13,7 +13,7 @@
* 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
@@ -25,7 +25,11 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
+ *
+ * Modified:
+ * Hunyue Yau Jan 6 1994
+ * Added code to support the Sound Galaxy NX Pro mixer.
+ *
*/
#include "sound_config.h"
@@ -87,9 +91,21 @@ sb_mixer_set_stereo (int mode)
| (mode ? STEREO_DAC : MONO_DAC)));
}
+/*
+ * Returns:
+ * 0 No mixer detected.
+ * 1 Only a plain Sound Blaster Pro style mixer detected.
+ * 2 The Sound Galaxy NX Pro mixer detected.
+ */
static int
detect_mixer (void)
{
+#ifdef __SGNXPRO__
+ int oldbass, oldtreble;
+
+#endif
+ int retcode = 1;
+
/*
* Detect the mixer by changing parameters of two volume channels. If the
* values read back match with the values written, the mixer is there (is
@@ -103,7 +119,30 @@ detect_mixer (void)
if (sb_getmixer (VOC_VOL) != 0x33)
return 0;
- return 1;
+#ifdef __SGNXPRO__
+ /* Attempt to detect the SG NX Pro by check for valid bass/treble
+ * registers.
+ */
+ oldbass = sb_getmixer (BASS_LVL);
+ oldtreble = sb_getmixer (TREBLE_LVL);
+
+ sb_setmixer (BASS_LVL, 0xaa);
+ sb_setmixer (TREBLE_LVL, 0x55);
+
+ if ((sb_getmixer (BASS_LVL) != 0xaa) ||
+ (sb_getmixer (TREBLE_LVL) != 0x55))
+ {
+ retcode = 1; /* 1 == Only SB Pro detected */
+ }
+ else
+ retcode = 2; /* 2 == SG NX Pro detected */
+ /* Restore register in either case since SG NX Pro has EEPROM with
+ * 'preferred' values stored.
+ */
+ sb_setmixer (BASS_LVL, oldbass);
+ sb_setmixer (TREBLE_LVL, oldtreble);
+#endif
+ return retcode;
}
static void
@@ -320,13 +359,24 @@ sb_mixer_reset (void)
set_recmask (SOUND_MASK_MIC);
}
-void
+/*
+ * Returns a code depending on whether a SG NX Pro was detected.
+ * 0 == Plain SB 16 or SB Pro
+ * 1 == SG NX Pro detected.
+ *
+ * Used to update message.
+ */
+int
sb_mixer_init (int major_model)
{
+ int mixerstat;
+
sb_setmixer (0x00, 0); /* Reset mixer */
- if (!detect_mixer ())
- return; /* No mixer. Why? */
+ mixerstat = detect_mixer ();
+
+ if (!mixerstat)
+ return 0; /* No mixer. Why? */
mixer_initialized = 1;
mixer_model = major_model;
@@ -335,9 +385,21 @@ sb_mixer_init (int major_model)
{
case 3:
mixer_caps = SOUND_CAP_EXCL_INPUT;
- supported_devices = SBPRO_MIXER_DEVICES;
- supported_rec_devices = SBPRO_RECORDING_DEVICES;
- iomap = &sbpro_mix;
+#ifdef __SGNXPRO__
+ if (mixerstat == 2)
+ { /* A SGNXPRO was detected */
+ supported_devices = SGNXPRO_MIXER_DEVICES;
+ supported_rec_devices = SGNXPRO_RECORDING_DEVICES;
+ iomap = &sgnxpro_mix;
+ }
+ else
+#endif
+ { /* Otherwise plain SB Pro */
+ supported_devices = SBPRO_MIXER_DEVICES;
+ supported_rec_devices = SBPRO_RECORDING_DEVICES;
+ iomap = &sbpro_mix;
+ }
+
break;
case 4:
@@ -349,11 +411,12 @@ sb_mixer_init (int major_model)
default:
printk ("SB Warning: Unsupported mixer type\n");
- return;
+ return 0;
}
mixer_devs[num_mixers++] = &sb_mixer_operations;
sb_mixer_reset ();
+ return (mixerstat == 2);
}
#endif
diff --git a/sys/i386/isa/sound/sb_mixer.h b/sys/i386/isa/sound/sb_mixer.h
index 304af642..4caf773 100644
--- a/sys/i386/isa/sound/sb_mixer.h
+++ b/sys/i386/isa/sound/sb_mixer.h
@@ -24,13 +24,29 @@
* 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 defines for the Sound Galaxy NX Pro mixer.
*
*/
+
#define SBPRO_RECORDING_DEVICES (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD)
+/* Same as SB Pro, unless I find otherwise */
+#define SGNXPRO_RECORDING_DEVICES SBPRO_RECORDING_DEVICES
+
#define SBPRO_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE | SOUND_MASK_MIC | \
SOUND_MASK_CD | SOUND_MASK_VOLUME)
+/* SG NX Pro has treble and bass settings on the mixer. The 'speaker'
+ * channel is the COVOX/DisneySoundSource emulation volume control
+ * on the mixer. It does NOT control speaker volume. Should have own
+ * mask eventually?
+ */
+#define SGNXPRO_MIXER_DEVICES (SBPRO_MIXER_DEVICES|SOUND_MASK_BASS| \
+ SOUND_MASK_TREBLE|SOUND_MASK_SPEAKER )
+
#define SB16_RECORDING_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | SOUND_MASK_MIC | \
SOUND_MASK_CD)
@@ -62,6 +78,13 @@
#define IRQ_STAT 0x82
#define OPSW 0x3c
+/*
+ * Additional registers on the SG NX Pro
+ */
+#define COVOX_VOL 0x42
+#define TREBLE_LVL 0x44
+#define BASS_LVL 0x46
+
#define FREQ_HI (1 << 3)/* Use High-frequency ANFI filters */
#define FREQ_LOW 0 /* Use Low-frequency ANFI filters */
#define FILT_ON 0 /* Yes, 0 to turn it on, 1 for off */
@@ -108,6 +131,23 @@ MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0)
};
+#ifdef __SGNXPRO__
+mixer_tab sgnxpro_mix = {
+MIX_ENT(SOUND_MIXER_VOLUME, 0x22, 7, 4, 0x22, 3, 4),
+MIX_ENT(SOUND_MIXER_BASS, 0x46, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_TREBLE, 0x44, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_SYNTH, 0x26, 7, 4, 0x26, 3, 4),
+MIX_ENT(SOUND_MIXER_PCM, 0x04, 7, 4, 0x04, 3, 4),
+MIX_ENT(SOUND_MIXER_SPEAKER, 0x42, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_LINE, 0x2e, 7, 4, 0x2e, 3, 4),
+MIX_ENT(SOUND_MIXER_MIC, 0x0a, 2, 3, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_CD, 0x28, 7, 4, 0x28, 3, 4),
+MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
+MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0)
+};
+#endif
+
mixer_tab sb16_mix = {
MIX_ENT(SOUND_MIXER_VOLUME, 0x30, 7, 5, 0x31, 7, 5),
MIX_ENT(SOUND_MIXER_BASS, 0x46, 7, 4, 0x47, 7, 4),
diff --git a/sys/i386/isa/sound/sequencer.c b/sys/i386/isa/sound/sequencer.c
index e61e445..9885473 100644
--- a/sys/i386/isa/sound/sequencer.c
+++ b/sys/i386/isa/sound/sequencer.c
@@ -1,10 +1,10 @@
/*
* sound/sequencer.c
- *
+ *
* The sequencer personality manager.
- *
+ *
* Copyright by Hannu Savolainen 1993
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
+ *
*/
#define SEQUENCER_C
@@ -46,7 +46,7 @@ static int midi_opened[MAX_MIDI_DEV] =
static int midi_written[MAX_MIDI_DEV] =
{0};
-unsigned long seq_time = 0; /* Reference point for the timer */
+unsigned long seq_time = 0; /* Reference point for the timer */
#include "tuning.h"
@@ -87,6 +87,9 @@ sequencer_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
{
if (!iqlen)
{
+ if (c != count) /* Some data has been received */
+ return count - c; /* Return what we have */
+
DO_SLEEP (midi_sleeper, midi_sleep_flag, 0);
if (!iqlen)
@@ -327,6 +330,10 @@ extended_event (unsigned char *q)
synth_devs[dev]->controller (dev, q[3], q[4], *(short *) &q[5]);
break;
+ case SEQ_VOLMODE:
+ synth_devs[dev]->volume_method (dev, q[3]);
+ break;
+
default:
return RET_ERROR (EINVAL);
}
@@ -688,7 +695,7 @@ seq_reset (void)
{
midi_outc (i,
(unsigned char) (0xb0 + (chn & 0xff))); /* Channel msg */
- midi_outc (i, 0x7b); /* All notes off */
+ midi_outc (i, 0x7b);/* All notes off */
midi_outc (i, 0); /* Dummy parameter */
}
@@ -1049,7 +1056,7 @@ unsigned long
compute_finetune (unsigned long base_freq, int bend, int range)
{
unsigned long amount;
- int negative, semitones, cents;
+ int negative, semitones, cents, multiplier = 1;
if (!bend)
return base_freq;
@@ -1073,13 +1080,20 @@ compute_finetune (unsigned long base_freq, int bend, int range)
if (bend > range)
bend = range;
- if (bend > 2399)
- bend = 2399;
+ /*
+ if (bend > 2399)
+ bend = 2399;
+ */
+ while (bend > 2399)
+ {
+ multiplier *= 4;
+ bend -= 2400;
+ }
semitones = bend / 100;
cents = bend % 100;
- amount = semitone_tuning[semitones] * cent_tuning[cents] / 10000;
+ amount = semitone_tuning[semitones] * multiplier * cent_tuning[cents] / 10000;
if (negative)
return (base_freq * 10000) / amount; /* Bend down */
diff --git a/sys/i386/isa/sound/sound_calls.h b/sys/i386/isa/sound/sound_calls.h
index 97fb769..abc8200 100644
--- a/sys/i386/isa/sound/sound_calls.h
+++ b/sys/i386/isa/sound/sound_calls.h
@@ -129,12 +129,13 @@ int probe_sb16midi(struct address_info *hw_config);
/* From sb_midi.c */
void sb_midi_init(int model);
+void sb_midi_interrupt(int dummy);
/* From sb_mixer.c */
void sb_setmixer (unsigned int port, unsigned int value);
int sb_getmixer (unsigned int port);
void sb_mixer_set_stereo(int mode);
-void sb_mixer_init(int major_model);
+int sb_mixer_init(int major_model);
/* From opl3.c */
int opl3_detect (int ioaddr);
@@ -181,6 +182,7 @@ unsigned char gus_read8 (int reg);
void gus_write8(int reg, unsigned int data);
void guswave_dma_irq(void);
void gus_delay(void);
+int gus_default_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg);
/* From gus_midi.c */
long gus_midi_init(long mem_start);
@@ -201,3 +203,6 @@ int pmgr_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count);
int pmgr_access(int dev, struct patmgr_info *rec);
int pmgr_inform(int dev, int event, unsigned long parm1, unsigned long parm2,
unsigned long parm3, unsigned long parm4);
+
+/* From ics2101.c */
+long ics2101_mixer_init(long mem_start);
diff --git a/sys/i386/isa/sound/sound_switch.c b/sys/i386/isa/sound/sound_switch.c
index 52120d5..68c7575 100644
--- a/sys/i386/isa/sound/sound_switch.c
+++ b/sys/i386/isa/sound/sound_switch.c
@@ -1,10 +1,10 @@
/*
* 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
@@ -12,7 +12,7 @@
* 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
@@ -24,7 +24,7 @@
* 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 "sound_config.h"
@@ -441,4 +441,5 @@ sound_ioctl_sw (int dev, struct fileinfo *file,
return RET_ERROR (EPERM);
}
+
#endif
OpenPOWER on IntegriCloud