summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/315-5641.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/sound/315-5641.cpp')
-rw-r--r--src/devices/sound/315-5641.cpp61
1 files changed, 56 insertions, 5 deletions
diff --git a/src/devices/sound/315-5641.cpp b/src/devices/sound/315-5641.cpp
index a43f5ad3cd3..defb3cbb9ed 100644
--- a/src/devices/sound/315-5641.cpp
+++ b/src/devices/sound/315-5641.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Angelo Salese
+// copyright-holders:Valley Bell
/* Sega 315-5641 / D77591 / 9442CA010 */
#include "emu.h"
@@ -8,13 +8,17 @@
DEFINE_DEVICE_TYPE(SEGA_315_5641_PCM, sega_315_5641_pcm_device, "315_5641_pcm", "Sega 315-5641 PCM")
sega_315_5641_pcm_device::sega_315_5641_pcm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : upd7756_device(mconfig, SEGA_315_5641_PCM, tag, owner, clock), m_fifo_read(0), m_fifo_write(0)
+ : upd7759_device(mconfig, SEGA_315_5641_PCM, tag, owner, clock)
+ , m_fifocallback(*this)
+ , m_fifo_read(0)
+ , m_fifo_write(0)
{
+ m_md = 0; // enforce "slave" mode
}
void sega_315_5641_pcm_device::device_start()
{
- upd7756_device::device_start();
+ upd7759_device::device_start();
save_item(NAME(m_fifo_data), 0x40);
save_item(NAME(m_fifo_read));
@@ -34,12 +38,17 @@ void sega_315_5641_pcm_device::advance_state()
{
m_fifo_in = m_fifo_data[fiforead];
m_fifo_read = fiforead;
+ if (get_fifo_space() == 0x3F)
+ {
+ m_fifo_empty = true;
+ m_fifocallback(1);
+ }
}
}
break;
}
- upd7756_device::advance_state();
+ upd7759_device::advance_state();
}
@@ -54,9 +63,47 @@ void sega_315_5641_pcm_device::port_w(u8 data)
{
m_fifo_data[m_fifo_write++] = data;
m_fifo_write &= 0x3F;
+ if (m_fifo_empty)
+ {
+ m_fifo_empty = false;
+ m_fifocallback(0);
+ }
+ }
+}
+
+
+void sega_315_5641_pcm_device::fifo_reset_w(u8 data)
+{
+ bool reset = !!(data & 1);
+ if (!m_fifo_reset && reset)
+ {
+ m_fifo_read = 0x3F;
+ m_fifo_write = 0x00;
+ if (m_fifo_empty)
+ m_fifocallback(0);
+ m_fifo_empty = false;
}
+ m_fifo_reset = reset;
}
+void sega_315_5641_pcm_device::internal_start_w(int state)
+{
+ uint8_t oldstart = m_start;
+ uint8_t newstart = (state != 0);
+
+ if (!m_md && m_reset && !oldstart && newstart)
+ {
+ // Somewhere between "Reset Off" and the first sample data,
+ // we need to send a few commands to make the sample stream work.
+ // Doing that when rising the "start" line seems to work fine.
+ port_w(0xFF); // "Last Sample" value (must be >= 0x10)
+ port_w(0x00); // Dummy 1
+ port_w(0x00); // Addr MSB
+ port_w(0x00); // Addr LSB
+ }
+
+ upd7759_device::internal_start_w(state);
+}
uint8_t sega_315_5641_pcm_device::get_fifo_space()
{
@@ -65,8 +112,12 @@ uint8_t sega_315_5641_pcm_device::get_fifo_space()
void sega_315_5641_pcm_device::device_reset()
{
- upd7756_device::device_reset();
+ upd7759_device::device_reset();
m_fifo_read = 0x3F;
m_fifo_write = 0x00;
+ m_fifo_reset = false;
+ if (m_fifo_empty)
+ m_fifocallback(0);
+ m_fifo_empty = false;
}