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.cpp90
1 files changed, 45 insertions, 45 deletions
diff --git a/src/devices/sound/upd934g.cpp b/src/devices/sound/upd934g.cpp
index 090fb98d725..0a4e663c6c0 100644
--- a/src/devices/sound/upd934g.cpp
+++ b/src/devices/sound/upd934g.cpp
@@ -7,15 +7,16 @@
Percussion Generator
TODO:
- - Play MUTED and ACCENTED
+ - 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
@@ -35,7 +36,7 @@ DEFINE_DEVICE_TYPE(UPD934G, upd934g_device, "upd934g", "NEC uPD934G")
upd934g_device::upd934g_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, UPD934G, tag, owner, clock),
device_sound_interface(mconfig, *this),
- m_data_cb(*this),
+ device_rom_interface(mconfig, *this),
m_stream(nullptr),
m_sample(0),
m_ready(false)
@@ -49,20 +50,15 @@ upd934g_device::upd934g_device(const machine_config &mconfig, const char *tag, d
void upd934g_device::device_start()
{
// create sound stream
- m_stream = machine().sound().stream_alloc(*this, 0, 4, 20000);
-
- // resolve callbacks
- m_data_cb.resolve_safe(0);
+ 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(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));
@@ -76,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;
+ }
}
//-------------------------------------------------
@@ -85,20 +88,24 @@ void upd934g_device::device_reset()
// our sound stream
//-------------------------------------------------
-void upd934g_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+void upd934g_device::sound_stream_update(sound_stream &stream)
{
for (unsigned ch = 0; ch < 4; ch++)
{
- std::fill(&outputs[ch][0], &outputs[ch][samples], 0);
-
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 < samples; i++)
+ for (unsigned i = 0; i < stream.samples(); i++)
{
- int8_t raw = static_cast<int8_t>(m_data_cb(m_channel[ch].pos));
- outputs[ch][i] = raw * (m_channel[ch].volume + 1) * 64;
+ int16_t raw = static_cast<int8_t>(read_byte(m_channel[ch].pos)) * 4;
+
+ // normal, muted, accented
+ // 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];
+
+ stream.put_int(ch, i, raw, 32768 / 64);
if (++m_channel[ch].pos >= end)
{
@@ -115,36 +122,28 @@ void upd934g_device::sound_stream_update(sound_stream &stream, stream_sample_t *
// INTERFACE
//**************************************************************************
-WRITE8_MEMBER( upd934g_device::write )
+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:
- logerror("CMD PLAY sample %x (channel %d)\n", m_sample, m_sample >> 1);
- 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;
- }
- break;
- case 2:
- logerror("CMD PLAY MUTED sample %x (channel %d)\n", m_sample, m_sample >> 1);
- break;
- case 3:
- logerror("CMD PLAY ACCENTED sample %x (channel %d)\n", m_sample, m_sample >> 1);
- 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:
@@ -152,7 +151,8 @@ WRITE8_MEMBER( upd934g_device::write )
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;