diff options
Diffstat (limited to 'src/devices/sound/315-5641.cpp')
-rw-r--r-- | src/devices/sound/315-5641.cpp | 61 |
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; } |