summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/upd934g.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/upd934g.cpp')
-rw-r--r--src/devices/sound/upd934g.cpp74
1 files changed, 36 insertions, 38 deletions
diff --git a/src/devices/sound/upd934g.cpp b/src/devices/sound/upd934g.cpp
index f3321c70d3d..0a4e663c6c0 100644
--- a/src/devices/sound/upd934g.cpp
+++ b/src/devices/sound/upd934g.cpp
@@ -9,13 +9,14 @@
TODO:
- Correct MUTED and ACCENTED (currently just changes volume)
- T1 input
- - 8 channels?
***************************************************************************/
#include "emu.h"
#include "upd934g.h"
+#define VERBOSE (0)
+#include "logmacro.h"
//**************************************************************************
// DEVICE DEFINITIONS
@@ -52,15 +53,12 @@ void upd934g_device::device_start()
m_stream = stream_alloc(0, 4, 20000);
// register for save states
- save_pointer(NAME(m_addr), 16);
+ save_item(NAME(m_addr));
+ save_item(NAME(m_valid));
- for (unsigned i = 0; i < 4; i++)
- {
- save_item(NAME(m_channel[i].pos), i);
- save_item(NAME(m_channel[i].playing), i);
- save_item(NAME(m_channel[i].volume), i);
- save_item(NAME(m_channel[i].effect), i);
- }
+ save_item(STRUCT_MEMBER(m_channel, pos));
+ save_item(STRUCT_MEMBER(m_channel, playing));
+ save_item(STRUCT_MEMBER(m_channel, effect));
save_item(NAME(m_sample));
save_item(NAME(m_ready));
@@ -74,8 +72,15 @@ void upd934g_device::device_reset()
{
m_ready = false;
+ for (unsigned i = 0; i < 16; i++)
+ m_addr[i] = m_valid[i] = 0;
+
for (unsigned i = 0; i < 4; i++)
+ {
+ m_channel[i].pos = 0;
m_channel[i].playing = -1;
+ m_channel[i].effect = 0;
+ }
}
//-------------------------------------------------
@@ -83,34 +88,32 @@ void upd934g_device::device_reset()
// our sound stream
//-------------------------------------------------
-void upd934g_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
+void upd934g_device::sound_stream_update(sound_stream &stream)
{
for (unsigned ch = 0; ch < 4; ch++)
{
if (m_ready && m_channel[ch].playing != -1)
{
- uint16_t end = m_addr[m_channel[ch].playing + 1] - 1;
+ uint16_t end = m_addr[(m_channel[ch].playing + 1) & 0xf] - 1;
- for (unsigned i = 0; i < outputs[ch].samples(); i++)
+ for (unsigned i = 0; i < stream.samples(); i++)
{
- int8_t raw = static_cast<int8_t>(read_byte(m_channel[ch].pos));
+ int16_t raw = static_cast<int8_t>(read_byte(m_channel[ch].pos)) * 4;
// normal, muted, accented
- const double adjust[] = { 0, 0.7, 0.4, 1.0 };
+ // TODO: cps2000 regularly sets effect bits to 0 instead of 2 - are these the same?
+ const double adjust[] = { 0.4, 0.7, 0.4, 1.0 };
raw *= adjust[m_channel[ch].effect];
- outputs[ch].put_int(i, raw * (m_channel[ch].volume + 1), 32768 / 64);
+ stream.put_int(ch, i, raw, 32768 / 64);
if (++m_channel[ch].pos >= end)
{
m_channel[ch].playing = -1;
- outputs[ch].fill(0, i + 1);
break;
}
}
}
- else
- outputs[ch].fill(0);
}
}
@@ -121,32 +124,26 @@ void upd934g_device::sound_stream_update(sound_stream &stream, std::vector<read_
void upd934g_device::write(offs_t offset, uint8_t data)
{
- switch (offset)
+ switch (offset & 3)
{
case 0:
// format of data written here is:
- // 76------ command
+ // 76------ effect
// --5432-- sample number
- // ------10 volume?
+ // ------10 output channel
m_sample = (data >> 2) & 0x0f;
- switch (data >> 6)
+ // don't play a sample unless we're sure it's actually supposed to play:
+ // - all models write this with effect=0 to select which sample to set the address of
+ // - cps2000 writes this with effect=0 to play muted(?) samples
+ // - cps2000 also writes this with effect=1 and sample=f on boot even though there are only 12 valid samples
+ if (m_valid[m_sample])
{
- case 0:
- logerror("CMD STORE ADDRESS sample %x\n", m_sample);
- break;
- case 1:
- case 2:
- case 3:
- logerror("CMD PLAY sample %x (channel %d, effect %d)\n", m_sample, m_sample >> 1, data >> 6);
- if (m_sample < 8)
- {
- m_channel[m_sample >> 1].pos = m_addr[m_sample];
- m_channel[m_sample >> 1].playing = m_sample;
- m_channel[m_sample >> 1].volume = data & 0x03;
- m_channel[m_sample >> 1].effect = data >> 6;
- }
- break;
+ const u8 ch = (data & 3) ^ 2; // effective order seems to be "2, 3, 0, 1"
+ LOG("CMD PLAY sample %x (channel %d, effect %d)\n", m_sample, ch, data >> 6);
+ m_channel[ch].pos = m_addr[m_sample];
+ m_channel[ch].playing = m_sample;
+ m_channel[ch].effect = data >> 6;
}
break;
case 1:
@@ -154,7 +151,8 @@ void upd934g_device::write(offs_t offset, uint8_t data)
break;
case 2:
m_addr[m_sample] = (m_addr[m_sample] & 0x00ff) | (data << 8);
- logerror(" sample %x address = %04x\n", m_sample, m_addr[m_sample]);
+ m_valid[m_sample] = 1;
+ LOG(" sample %x address = %04x\n", m_sample, m_addr[m_sample]);
break;
case 3:
m_ready = true;