mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
-elan_eu3a05: Added OKI ADPCM decoding. [Ryan Holtz]
This commit is contained in:
parent
2edd256065
commit
db51c22b5f
@ -8,11 +8,11 @@
|
||||
|
||||
DEFINE_DEVICE_TYPE(ELAN_EU3A05_SOUND, elan_eu3a05_sound_device, "elan_eu3a05sound", "Elan EU3A05 / EU3A14 Sound")
|
||||
|
||||
#define LOG_AUDIO (1U << 0)
|
||||
#define LOG_AUDIO (1U << 1)
|
||||
|
||||
#define LOG_ALL (LOG_AUDIO)
|
||||
|
||||
#define VERBOSE (0)
|
||||
#define VERBOSE (0)
|
||||
#include "logmacro.h"
|
||||
|
||||
|
||||
@ -76,6 +76,7 @@ void elan_eu3a05_sound_device::device_reset()
|
||||
m_sound_byte_address[i] = 0;
|
||||
m_sound_byte_len[i] = 0;
|
||||
m_sound_current_nib_pos[i] = 0;
|
||||
m_adpcm[i].reset();
|
||||
}
|
||||
|
||||
m_isstopped = 0x3f;
|
||||
@ -99,10 +100,13 @@ void elan_eu3a05_sound_device::sound_stream_update(sound_stream &stream, stream_
|
||||
// reset the output stream
|
||||
memset(outputs[0], 0, samples * sizeof(*outputs[0]));
|
||||
|
||||
int volume = m_volumes[0] | (m_volumes[1] << 8);
|
||||
|
||||
int outpos = 0;
|
||||
// loop while we still have samples to generate
|
||||
while (samples-- != 0)
|
||||
{
|
||||
int total = 0;
|
||||
for (int channel = 0; channel < 6; channel++)
|
||||
{
|
||||
if (!((m_isstopped >> channel) & 1))
|
||||
@ -114,19 +118,18 @@ void elan_eu3a05_sound_device::sound_stream_update(sound_stream &stream, stream_
|
||||
int nibble = m_space_read_cb(readoffset);
|
||||
|
||||
nibble = nibble >> ((m_sound_current_nib_pos[channel] & 1) ? 0 : 4);
|
||||
nibble &= 0x0f;
|
||||
uint16_t decoded = (uint16_t)m_adpcm[channel].clock(nibble & 0xf);
|
||||
decoded = (decoded * ((volume >> (channel * 2)) & 3)) / 3;
|
||||
decoded <<= 4;
|
||||
|
||||
// it's actually some form of ADPCM? but apparently NOT the OKI ADPCM
|
||||
if (nibble & 0x08)
|
||||
nibble -= 0x10;
|
||||
|
||||
outputs[0][outpos] += nibble * 0x100;
|
||||
total += (int32_t)(int16_t)decoded - 0x8000;
|
||||
|
||||
m_sound_current_nib_pos[channel]++;
|
||||
|
||||
if (m_sound_current_nib_pos[channel] >= m_sound_byte_len[channel] * 2)
|
||||
{
|
||||
m_sound_current_nib_pos[channel] = 0;
|
||||
m_adpcm[channel].reset();
|
||||
m_isstopped |= (1 << channel);
|
||||
|
||||
// maybe, seems to match the system IRQ mask when the sound interrupts are enabled?
|
||||
@ -139,6 +142,7 @@ void elan_eu3a05_sound_device::sound_stream_update(sound_stream &stream, stream_
|
||||
//LOGMASKED( LOG_AUDIO, "m_isstopped %02x channel %d is NOT active %08x %06x\n", m_isstopped, channel, m_sound_byte_address[channel], m_sound_current_nib_pos[channel]);
|
||||
}
|
||||
}
|
||||
outputs[0][outpos] = total / 6;
|
||||
outpos++;
|
||||
}
|
||||
}
|
||||
@ -313,8 +317,12 @@ void elan_eu3a05_sound_device::handle_sound_trigger(int which)
|
||||
|
||||
if (m_isstopped & (1 << which)) // golden tee will repeatedly try to start the music on the title screen (although could depend on a status read first?)
|
||||
{
|
||||
m_sound_current_nib_pos[which] = 0;
|
||||
m_isstopped &= ~(1 << which);
|
||||
if (m_sound_byte_len[which])
|
||||
{
|
||||
m_sound_current_nib_pos[which] = 0;
|
||||
m_isstopped &= ~(1 << which);
|
||||
m_adpcm[which].reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,21 +337,50 @@ READ8_MEMBER(elan_eu3a05_sound_device::elan_eu3a05_50a8_r)
|
||||
|
||||
READ8_MEMBER(elan_eu3a05_sound_device::elan_eu3a05_sound_volume_r)
|
||||
{
|
||||
LOGMASKED( LOG_AUDIO, "%s: sound_volume_r (offset %d, data %02x)\n", machine().describe_context(), offset, m_volumes[offset]);
|
||||
return m_volumes[offset];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(elan_eu3a05_sound_device::elan_eu3a05_sound_volume_w)
|
||||
{
|
||||
m_stream->update();
|
||||
|
||||
LOGMASKED( LOG_AUDIO, "%s: sound_volume_w (offset %d, data %02x)\n", machine().describe_context(), offset, data);
|
||||
m_volumes[offset] = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(elan_eu3a05_sound_device::read_unmapped)
|
||||
{
|
||||
logerror("%s: elan_eu3a05_sound_device::read_unmapped (offset %02x)\n", machine().describe_context(), offset);
|
||||
LOGMASKED( LOG_AUDIO, "%s: elan_eu3a05_sound_device::read_unmapped (offset %02x)\n", machine().describe_context(), offset);
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(elan_eu3a05_sound_device::write_unmapped)
|
||||
{
|
||||
logerror("%s: elan_eu3a05_sound_device::write_unmapped (offset %02x) (data %02x)\n", machine().describe_context(), offset, data);
|
||||
LOGMASKED( LOG_AUDIO, "%s: elan_eu3a05_sound_device::write_unmapped (offset %02x) (data %02x)\n", machine().describe_context(), offset, data);
|
||||
}
|
||||
|
||||
READ8_MEMBER(elan_eu3a05_sound_device::reg50a4_r)
|
||||
{
|
||||
LOGMASKED( LOG_AUDIO, "%s: reg50a4_r (unknown) (data %02x)\n", machine().describe_context(), m_50a4);
|
||||
return m_50a4;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(elan_eu3a05_sound_device::reg50a4_w)
|
||||
{
|
||||
LOGMASKED( LOG_AUDIO, "%s: reg50a4_w (unknown) (data %02x)\n", machine().describe_context(), data);
|
||||
m_50a4 = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(elan_eu3a05_sound_device::reg50a9_r)
|
||||
{
|
||||
LOGMASKED( LOG_AUDIO, "%s: reg50a9_r (IRQ mask?) (data %02x)\n", machine().describe_context(), m_50a9);
|
||||
return m_50a9;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(elan_eu3a05_sound_device::reg50a9_w)
|
||||
{
|
||||
LOGMASKED( LOG_AUDIO, "%s: reg50a4_w (IRQ mask?) (data %02x)\n", machine().describe_context(), data);
|
||||
m_50a9 = data;
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#ifndef MAME_AUDIO_ELAN_EU3A05_H
|
||||
#define MAME_AUDIO_ELAN_EU3A05_H
|
||||
|
||||
#include "sound/okiadpcm.h"
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
@ -40,6 +41,7 @@ private:
|
||||
uint32_t m_sound_byte_address[6];
|
||||
uint32_t m_sound_byte_len[6];
|
||||
uint32_t m_sound_current_nib_pos[6];
|
||||
oki_adpcm_state m_adpcm[6];
|
||||
|
||||
uint8_t m_sound_trigger;
|
||||
uint8_t m_sound_unk;
|
||||
@ -68,10 +70,10 @@ private:
|
||||
|
||||
DECLARE_READ8_MEMBER(elan_eu3a05_50a8_r);
|
||||
|
||||
DECLARE_READ8_MEMBER(reg50a4_r) { return m_50a4; }
|
||||
DECLARE_WRITE8_MEMBER(reg50a4_w) { m_50a4 = data; }
|
||||
DECLARE_READ8_MEMBER(reg50a9_r) { return m_50a9; }
|
||||
DECLARE_WRITE8_MEMBER(reg50a9_w) { m_50a9 = data; }
|
||||
DECLARE_READ8_MEMBER(reg50a4_r);
|
||||
DECLARE_WRITE8_MEMBER(reg50a4_w);
|
||||
DECLARE_READ8_MEMBER(reg50a9_r);
|
||||
DECLARE_WRITE8_MEMBER(reg50a9_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(elan_eu3a05_sound_volume_r);
|
||||
DECLARE_WRITE8_MEMBER(elan_eu3a05_sound_volume_w);
|
||||
|
Loading…
Reference in New Issue
Block a user