mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
60dc9be97b
this updates to 971117 plus a small sb change that was after that release..
263 lines
7.1 KiB
C
263 lines
7.1 KiB
C
/*
|
|
* sound/clones.c
|
|
*
|
|
* init code for enabling clone cards to work in sb/mss emulation.
|
|
*
|
|
* Note -- this code is currently unused!
|
|
*
|
|
* Copyright by Luigi Rizzo - 1997
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met: 1. Redistributions of source code must retain the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer. 2. Redistributions in binary form must reproduce the
|
|
* above copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
|
|
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* This file has been written using information from various sources
|
|
* in the Voxware 3.5 distribution.
|
|
*/
|
|
|
|
#include <i386/isa/snd/sound.h>
|
|
#if NPCM > 0
|
|
|
|
/*
|
|
* Known clones card include:
|
|
*
|
|
* Trix (emulating MSS)
|
|
* MAD16 (emulating MSS)
|
|
* OPTi930 -- same as the OPTi931, but no PnP ?
|
|
*/
|
|
|
|
|
|
#ifdef JAZZ16
|
|
|
|
/*
|
|
* Initialization of a Media Vision ProSonic 16 Soundcard. The function
|
|
* initializes a ProSonic 16 like PROS.EXE does for DOS. It sets the base
|
|
* address, the DMA-channels, interrupts and enables the joystickport.
|
|
*
|
|
* Also used by Jazz 16 (same card, different name)
|
|
*
|
|
* written 1994 by Rainer Vranken E-Mail:
|
|
* rvranken@polaris.informatik.uni-essen.de
|
|
*/
|
|
|
|
#ifdef SM_WAVE
|
|
/*
|
|
* Logitech Soundman Wave detection and initialization by Hannu Savolainen.
|
|
*
|
|
* There is a microcontroller (8031) in the SM Wave card for MIDI emulation.
|
|
* it's located at address MPU_BASE+4. MPU_BASE+7 is a SM Wave specific
|
|
* control register for MC reset, SCSI, OPL4 and DSP (future expansion)
|
|
* address decoding. Otherwise the SM Wave is just a ordinary MV Jazz16 based
|
|
* soundcard.
|
|
*/
|
|
|
|
static void
|
|
smw_putmem(int base, int addr, u_char val)
|
|
{
|
|
u_long s;
|
|
|
|
s = spltty();
|
|
|
|
outb(base + 1, addr & 0xff); /* Low address bits */
|
|
outb(base + 2, addr >> 8); /* High address bits */
|
|
outb(base, val); /* Data */
|
|
|
|
splx(s);
|
|
}
|
|
|
|
static u_char
|
|
smw_getmem(int base, int addr)
|
|
{
|
|
u_long s;
|
|
u_char val;
|
|
|
|
s = spltty();
|
|
|
|
outb(base + 1, addr & 0xff); /* Low address bits */
|
|
outb(base + 2, addr >> 8); /* High address bits */
|
|
val = inb(base); /* Data */
|
|
|
|
splx(s);
|
|
return val;
|
|
}
|
|
|
|
#ifdef SMW_MIDI0001_INCLUDED
|
|
#include </sys/i386/isa/snd/smw-midi0001.h>
|
|
#else
|
|
u_char *smw_ucode = NULL;
|
|
int smw_ucodeLen = 0;
|
|
#endif /* SWM_MIDI0001_INCLUDED */
|
|
|
|
static int
|
|
initialize_smw(int mpu_base)
|
|
{
|
|
|
|
int i, mp_base = mpu_base + 4; /* Microcontroller base */
|
|
u_char control;
|
|
|
|
/*
|
|
* Reset the microcontroller so that the RAM can be accessed
|
|
*/
|
|
|
|
control = inb(mpu_base + 7);
|
|
outb(mpu_base + 7, control | 3); /* Set last two bits to 1 (?) */
|
|
outb(mpu_base + 7, (control & 0xfe) | 2); /* xxxxxxx0 resets the mc */
|
|
DELAY(3000); /* Wait at least 1ms */
|
|
|
|
outb(mpu_base + 7, control & 0xfc); /* xxxxxx00 enables RAM */
|
|
|
|
/*
|
|
* Detect microcontroller by probing the 8k RAM area
|
|
*/
|
|
smw_putmem(mp_base, 0, 0x00);
|
|
smw_putmem(mp_base, 1, 0xff);
|
|
DELAY(10);
|
|
|
|
if (smw_getmem(mp_base, 0) != 0x00 || smw_getmem(mp_base, 1) != 0xff) {
|
|
printf("\nSM Wave: No microcontroller RAM detected (%02x, %02x)\n",
|
|
smw_getmem(mp_base, 0), smw_getmem(mp_base, 1));
|
|
return 0; /* No RAM */
|
|
}
|
|
/*
|
|
* There is RAM so assume it's really a SM Wave
|
|
*/
|
|
|
|
if (smw_ucodeLen > 0) {
|
|
if (smw_ucodeLen != 8192) {
|
|
printf("\nSM Wave: Invalid microcode (MIDI0001.BIN) length\n");
|
|
return 1;
|
|
}
|
|
/*
|
|
* Download microcode
|
|
*/
|
|
|
|
for (i = 0; i < 8192; i++)
|
|
smw_putmem(mp_base, i, smw_ucode[i]);
|
|
|
|
/*
|
|
* Verify microcode
|
|
*/
|
|
|
|
for (i = 0; i < 8192; i++)
|
|
if (smw_getmem(mp_base, i) != smw_ucode[i]) {
|
|
printf("SM Wave: Microcode verification failed\n");
|
|
return 0;
|
|
}
|
|
}
|
|
control = 0;
|
|
#ifdef SMW_SCSI_IRQ
|
|
/*
|
|
* Set the SCSI interrupt (IRQ2/9, IRQ3 or IRQ10). The SCSI interrupt
|
|
* is disabled by default.
|
|
*
|
|
* Btw the Zilog 5380 SCSI controller is located at MPU base + 0x10.
|
|
*/
|
|
{
|
|
static u_char scsi_irq_bits[] =
|
|
{0, 0, 3, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0};
|
|
|
|
control |= scsi_irq_bits[SMW_SCSI_IRQ] << 6;
|
|
}
|
|
#endif
|
|
|
|
#ifdef SMW_OPL4_ENABLE
|
|
/*
|
|
* Make the OPL4 chip visible on the PC bus at 0x380.
|
|
*
|
|
* There is no need to enable this feature since VoxWare doesn't support
|
|
* OPL4 yet. Also there is no RAM in SM Wave so enabling OPL4 is
|
|
* pretty useless.
|
|
*/
|
|
control |= 0x10; /* Uses IRQ12 if bit 0x20 == 0 */
|
|
/* control |= 0x20; Uncomment this if you want to use IRQ7 */
|
|
#endif
|
|
|
|
outb(mpu_base + 7, control | 0x03); /* xxxxxx11 restarts */
|
|
return 1;
|
|
}
|
|
|
|
#endif
|
|
|
|
/*
|
|
* this is only called during the probe. Variables are found in
|
|
* sb_probed.
|
|
*/
|
|
static sbdev_info sb_probed ;
|
|
static int
|
|
initialize_ProSonic16(snddev_info *d)
|
|
{
|
|
int x;
|
|
static u_char int_translat[16] =
|
|
{0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6},
|
|
dma_translat[8] =
|
|
{0, 1, 0, 2, 0, 3, 0, 4};
|
|
|
|
struct address_info *mpu_config;
|
|
|
|
int mpu_base, mpu_irq;
|
|
|
|
if ((mpu_config = NULL)) {
|
|
mpu_base = mpu_config->io_base;
|
|
mpu_irq = mpu_config->irq;
|
|
} else {
|
|
mpu_base = mpu_irq = 0;
|
|
}
|
|
|
|
outb(0x201, 0xAF); /* ProSonic/Jazz16 wakeup */
|
|
DELAY(15000); /* wait at least 10 milliseconds */
|
|
outb(0x201, 0x50);
|
|
outb(0x201, (sb_probed.io_base & 0x70) | ((mpu_base & 0x30) >> 4));
|
|
|
|
if (sb_reset_dsp(sb_probed.io_base)) { /* OK. We have at least a SB */
|
|
|
|
/* Check the version number of ProSonic (I guess) */
|
|
|
|
if (!sb_cmd(sb_probed.io_base, 0xFA))
|
|
return 1;
|
|
if (sb_get_byte(sb_probed.io_base) != 0x12)
|
|
return 1;
|
|
|
|
if (sb_cmd(sb_probed.io_base, 0xFB) && /* set DMA and irq */
|
|
sb_cmd(sb_probed.io_base,
|
|
(dma_translat[JAZZ_DMA16]<<4)|dma_translat[sb_probed.dbuf_out.chan]) &&
|
|
sb_cmd(sb_probed.io_base,
|
|
(int_translat[mpu_irq]<<4)|int_translat[sb_probed.irq])) {
|
|
d->bf_flags |= BD_F_JAZZ16 ;
|
|
if (mpu_base == 0)
|
|
printf("Jazz16: No MPU401 devices configured "
|
|
"- MIDI port not initialized\n");
|
|
|
|
#ifdef SM_WAVE
|
|
if (mpu_base != 0)
|
|
if (initialize_smw(mpu_base))
|
|
d->bf_flags |= BD_F_JAZZ16_2 ;
|
|
#endif
|
|
/* sb_dsp_disable_midi(); */
|
|
}
|
|
return 1; /* There was at least a SB */
|
|
}
|
|
return 0; /* No SB or ProSonic16 detected */
|
|
}
|
|
|
|
#endif /* ifdef JAZZ16 */
|
|
|
|
#endif /* NPCM */
|