summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/k053260.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/k053260.cpp')
-rw-r--r--src/devices/sound/k053260.cpp75
1 files changed, 47 insertions, 28 deletions
diff --git a/src/devices/sound/k053260.cpp b/src/devices/sound/k053260.cpp
index ccb7142d945..cdae8a4abee 100644
--- a/src/devices/sound/k053260.cpp
+++ b/src/devices/sound/k053260.cpp
@@ -49,7 +49,6 @@
converting to fractional sample position; fixed ADPCM
decoding bugs; added documentation.
-
*********************************************************/
#include "emu.h"
@@ -70,7 +69,8 @@ DEFINE_DEVICE_TYPE(K053260, k053260_device, "k053260", "K053260 KDSC")
// Pan multipliers. Set according to integer angles in degrees, amusingly.
// Exact precision hard to know, the floating point-ish output format makes
// comparisons iffy. So we used a 1.16 format.
-const int k053260_device::pan_mul[8][2] = {
+const int k053260_device::pan_mul[8][2] =
+{
{ 0, 0 }, // No sound for pan 0
{ 65536, 0 }, // 0 degrees
{ 59870, 26656 }, // 24 degrees
@@ -113,9 +113,6 @@ k053260_device::k053260_device(const machine_config &mconfig, const char *tag, d
void k053260_device::device_start()
{
- m_sh1_cb.resolve_safe();
- m_sh2_cb.resolve_safe();
-
m_stream = stream_alloc(0, 2, clock() / CLOCKS_PER_SAMPLE);
/* register with the save state system */
@@ -152,16 +149,17 @@ void k053260_device::device_reset()
attotime period = attotime::from_ticks(16, clock());
m_timer->adjust(period, 0, period);
- for (auto & elem : m_voice)
- elem.voice_reset();
+ for (auto & voice : m_voice)
+ voice.voice_reset();
}
//-------------------------------------------------
-// rom_bank_updated - the rom bank has changed
+// rom_bank_pre_change - refresh the stream if the
+// ROM banking changes
//-------------------------------------------------
-void k053260_device::rom_bank_updated()
+void k053260_device::rom_bank_pre_change()
{
m_stream->update();
}
@@ -169,11 +167,12 @@ void k053260_device::rom_bank_updated()
TIMER_CALLBACK_MEMBER(k053260_device::update_state_outputs)
{
- switch(m_timer_state) {
- case 0: m_sh1_cb(ASSERT_LINE); break;
- case 1: m_sh1_cb(CLEAR_LINE); break;
- case 2: m_sh2_cb(ASSERT_LINE); break;
- case 3: m_sh2_cb(CLEAR_LINE); break;
+ switch (m_timer_state)
+ {
+ case 0: m_sh1_cb(ASSERT_LINE); break;
+ case 1: m_sh1_cb(CLEAR_LINE); break;
+ case 2: m_sh2_cb(ASSERT_LINE); break;
+ case 3: m_sh2_cb(CLEAR_LINE); break;
}
m_timer_state = (m_timer_state+1) & 3;
}
@@ -248,15 +247,17 @@ void k053260_device::write(offs_t offset, u8 data)
// 0x04 through 0x07 seem to be unused
- case 0x28: // key on/off
+ case 0x28: // key on/off and reverse
{
u8 rising_edge = data & ~m_keyon;
for (int i = 0; i < 4; i++)
{
- if (rising_edge & (1 << i))
+ m_voice[i].set_reverse(BIT(data, i | 4));
+
+ if (BIT(rising_edge, i))
m_voice[i].key_on();
- else if (!(data & (1 << i)))
+ else if (!BIT(data, i))
m_voice[i].key_off();
}
m_keyon = data;
@@ -266,10 +267,10 @@ void k053260_device::write(offs_t offset, u8 data)
// 0x29 is a read register
case 0x2a: // loop and pcm/adpcm select
- for (auto & elem : m_voice)
+ for (int i = 0; i < 4; i++)
{
- elem.set_loop_kadpcm(data);
- data >>= 1;
+ m_voice[i].set_loop(BIT(data, i));
+ m_voice[i].set_kadpcm(BIT(data, i | 4));
}
break;
@@ -312,7 +313,7 @@ void k053260_device::sound_stream_update(sound_stream &stream, std::vector<read_
{
if (m_mode & 2)
{
- for ( int j = 0; j < outputs[0].samples(); j++ )
+ for (int j = 0; j < outputs[0].samples(); j++)
{
s32 buffer[2] = {0, 0};
@@ -354,6 +355,7 @@ void k053260_device::KDSC_Voice::voice_start(int index)
m_device.save_item(NAME(m_pan), index);
m_device.save_item(NAME(m_loop), index);
m_device.save_item(NAME(m_kadpcm), index);
+ m_device.save_item(NAME(m_reverse), index);
}
void k053260_device::KDSC_Voice::voice_reset()
@@ -369,6 +371,7 @@ void k053260_device::KDSC_Voice::voice_reset()
m_pan = 0;
m_loop = false;
m_kadpcm = false;
+ m_reverse = false;
update_pan_volume();
}
@@ -403,10 +406,19 @@ void k053260_device::KDSC_Voice::set_register(offs_t offset, u8 data)
}
}
-void k053260_device::KDSC_Voice::set_loop_kadpcm(u8 data)
+void k053260_device::KDSC_Voice::set_loop(int state)
{
- m_loop = BIT(data, 0);
- m_kadpcm = BIT(data, 4);
+ m_loop = bool(state);
+}
+
+void k053260_device::KDSC_Voice::set_kadpcm(int state)
+{
+ m_kadpcm = bool(state);
+}
+
+void k053260_device::KDSC_Voice::set_reverse(int state)
+{
+ m_reverse = bool(state);
}
void k053260_device::KDSC_Voice::set_pan(u8 data)
@@ -427,8 +439,15 @@ void k053260_device::KDSC_Voice::key_on()
m_counter = 0x1000 - CLOCKS_PER_SAMPLE; // force update on next sound_stream_update
m_output = 0;
m_playing = true;
- if (LOG) m_device.logerror("K053260: start = %06x, length = %06x, pitch = %04x, vol = %02x:%x, loop = %s, %s\n",
- m_start, m_length, m_pitch, m_volume, m_pan, m_loop ? "yes" : "no", m_kadpcm ? "KADPCM" : "PCM" );
+
+ if (LOG)
+ {
+ m_device.logerror("K053260: start = %06x, length = %06x, pitch = %04x, vol = %02x:%x, loop = %s, reverse = %s, %s\n",
+ m_start, m_length, m_pitch, m_volume, m_pan,
+ m_loop ? "yes" : "no",
+ m_reverse ? "yes" : "no",
+ m_kadpcm ? "KADPCM" : "PCM");
+ }
}
void k053260_device::KDSC_Voice::key_off()
@@ -446,7 +465,7 @@ void k053260_device::KDSC_Voice::play(s32 *outputs)
{
m_counter = m_counter - 0x1000 + m_pitch;
- u32 bytepos = ++m_position >> ( m_kadpcm ? 1 : 0 );
+ u32 bytepos = ++m_position >> (m_kadpcm ? 1 : 0);
/*
Yes, _pre_increment. Playback must start 1 byte position after the
start address written to the register, or else ADPCM sounds will
@@ -470,7 +489,7 @@ void k053260_device::KDSC_Voice::play(s32 *outputs)
}
}
- u8 romdata = m_device.read_byte(m_start + bytepos);
+ u8 romdata = m_device.read_byte(m_start + (m_reverse ? -bytepos : +bytepos));
if (m_kadpcm)
{