From 5a25a81d46317a8e535ae59315627031b858265a Mon Sep 17 00:00:00 2001 From: hap Date: Tue, 12 Mar 2024 23:08:01 +0100 Subject: sp0256: remove reset lrq timer workaround that was added there for odyssey2 killer bees. Bad luck: everything o2 works same as before except turtlesu, instead of failing to detect The Voice only sometimes, now it happens more commonly. Not due to the removed timer, but actually the stream updates before accessing I/O which should be more accurate. --- src/devices/bus/odyssey2/voice.cpp | 15 ++++-- src/devices/bus/odyssey2/voice.h | 1 + src/devices/sound/okim6588.cpp | 4 +- src/devices/sound/sp0256.cpp | 93 ++++++++++++++++---------------------- src/devices/sound/sp0256.h | 3 -- 5 files changed, 55 insertions(+), 61 deletions(-) diff --git a/src/devices/bus/odyssey2/voice.cpp b/src/devices/bus/odyssey2/voice.cpp index 78507a92ab7..43f4e30377b 100644 --- a/src/devices/bus/odyssey2/voice.cpp +++ b/src/devices/bus/odyssey2/voice.cpp @@ -14,6 +14,7 @@ that (European) cartridges using extra I/O won't work on it. TODO: - bees sound at level complete "MORE MORE MORE CHK CHK CHK" should be more rapid +- turtlesu usually doesn't detect the voice cartridge ******************************************************************************/ @@ -37,6 +38,7 @@ o2_voice_device::o2_voice_device(const machine_config &mconfig, const char *tag, void o2_voice_device::device_start() { save_item(NAME(m_control)); + save_item(NAME(m_reset)); } void o2_voice_device::cart_init() @@ -99,11 +101,16 @@ void o2_voice_device::io_write(offs_t offset, u8 data) { if (offset & 0x80 && ~m_control & 0x10) { - // A0-A6: SP0256B A1-A7 (A8 to GND) // D5: 7474 to SP0256B reset - if (data & 0x20) - m_speech->ald_w(offset & 0x7f); - else + bool reset = !(data & 0x20); + if (reset) m_speech->reset(); + else if (!m_reset) + { + // A0-A6: SP0256B A1-A7 (A8 to GND) + m_speech->ald_w(offset & 0x7f); + } + + m_reset = reset; } } diff --git a/src/devices/bus/odyssey2/voice.h b/src/devices/bus/odyssey2/voice.h index a125b282d66..1d48f7c48d4 100644 --- a/src/devices/bus/odyssey2/voice.h +++ b/src/devices/bus/odyssey2/voice.h @@ -51,6 +51,7 @@ private: required_device m_subslot; u8 m_control = 0; + bool m_reset = false; }; diff --git a/src/devices/sound/okim6588.cpp b/src/devices/sound/okim6588.cpp index 84b1a9a3033..de12b18664b 100644 --- a/src/devices/sound/okim6588.cpp +++ b/src/devices/sound/okim6588.cpp @@ -136,7 +136,9 @@ s16 okim6588_device::get_adpcm_sample(u8 data) void okim6588_device::reset_adpcm() { - m_stream->update(); + if (machine().time() > attotime::zero) + m_stream->update(); + m_adpcm_data = 0; m_adpcm.reset(); } diff --git a/src/devices/sound/sp0256.cpp b/src/devices/sound/sp0256.cpp index 237904be94a..b142c3b57a7 100644 --- a/src/devices/sound/sp0256.cpp +++ b/src/devices/sound/sp0256.cpp @@ -58,7 +58,6 @@ sp0256_device::sp0256_device(const machine_config &mconfig, const char *tag, dev , m_drq_cb(*this) , m_sby_cb(*this) , m_scratch() - , m_lrq_timer(nullptr) { } @@ -70,6 +69,7 @@ void sp0256_device::device_start() { m_drq_cb(1); m_sby_cb(1); + m_sby_line = 1; m_stream = stream_alloc(0, 1, clock() / CLOCK_DIVIDER); @@ -91,7 +91,7 @@ void sp0256_device::device_start() /* -------------------------------------------------------------------- */ m_halted = 1; m_filt.rpt = -1; - m_lrq = 0x8000; + m_lrq = 1; m_page = 0x1000 << 3; m_silent = 1; @@ -103,8 +103,6 @@ void sp0256_device::device_start() // TODO: because of this, check if the bitrev functions are even used anywhere else // bitrevbuff(m_rom, 0, 0xffff); - m_lrq_timer = timer_alloc(FUNC(sp0256_device::set_lrq_timer_proc), this); - // save device variables save_item(NAME(m_sby_line)); save_item(NAME(m_cur_len)); @@ -123,6 +121,7 @@ void sp0256_device::device_start() save_item(NAME(m_fifo_tail)); save_item(NAME(m_fifo_bitp)); save_item(NAME(m_fifo)); + // save filter variables save_item(NAME(m_filt.rpt)); save_item(NAME(m_filt.cnt)); @@ -143,6 +142,9 @@ void sp0256_device::device_start() void sp0256_device::device_reset() { + if (machine().time() > attotime::zero) + m_stream->update(); + // reset FIFO and SP0256 m_fifo_head = m_fifo_tail = m_fifo_bitp = 0; @@ -150,10 +152,10 @@ void sp0256_device::device_reset() m_halted = 1; m_filt.rpt = -1; m_filt.rng = 1; - m_lrq = 0x8000; - m_ald = 0x0000; - m_pc = 0x0000; - m_stack = 0x0000; + m_lrq = 1; + m_ald = 0; + m_pc = 0; + m_stack = 0; m_fifo_sel = 0; m_mode = 0; m_page = 0x1000 << 3; @@ -161,9 +163,6 @@ void sp0256_device::device_reset() m_sby_line = 0; m_drq_cb(1); SET_SBY(1); - - m_lrq = 0; - m_lrq_timer->adjust(attotime::from_ticks(50, m_clock)); } @@ -727,7 +726,7 @@ void sp0256_device::bitrevbuff(uint8_t *buffer, unsigned int start, unsigned int /* ======================================================================== */ /* SP0256_GETB -- Get up to 8 bits at the current PC. */ /* ======================================================================== */ -uint32_t sp0256_device::getb( int len ) +uint32_t sp0256_device::getb(int len) { uint32_t data; uint32_t d0, d1; @@ -756,7 +755,8 @@ uint32_t sp0256_device::getb( int len ) m_fifo_tail++; m_fifo_bitp -= 10; } - } else + } + else { /* ---------------------------------------------------------------- */ /* Figure out which ROMs are being fetched into, and grab two */ @@ -789,8 +789,8 @@ uint32_t sp0256_device::getb( int len ) /* ======================================================================== */ void sp0256_device::micro() { - uint8_t immed4; - uint8_t opcode; + uint8_t immed4; + uint8_t opcode; uint16_t cr; int ctrl_xfer; int repeat; @@ -810,7 +810,7 @@ void sp0256_device::micro() m_pc = m_ald | (0x1000 << 3); m_fifo_sel = 0; m_halted = 0; - m_lrq = 0x8000; + m_lrq = 1; m_ald = 0; for (i = 0; i < 16; i++) m_filt.r[i] = 0; @@ -823,7 +823,7 @@ void sp0256_device::micro() if (m_halted) { m_filt.rpt = 1; - m_lrq = 0x8000; + m_lrq = 1; m_ald = 0; for (i = 0; i < 16; i++) m_filt.r[i] = 0; @@ -864,10 +864,12 @@ void sp0256_device::micro() if (immed4) /* SETPAGE */ { m_page = bitrev32(immed4) >> 13; - } else + } + /* -------------------------------------------------------- */ /* Otherwise, this is an RTS / HLT. */ /* -------------------------------------------------------- */ + else { uint32_t btrg; @@ -887,7 +889,8 @@ void sp0256_device::micro() m_halted = 1; m_pc = 0; ctrl_xfer = 1; - } else + } + else { m_pc = btrg; ctrl_xfer = 1; @@ -904,7 +907,7 @@ void sp0256_device::micro() case 0xE: case 0xD: { - int btrg; + uint32_t btrg; /* -------------------------------------------------------- */ /* Figure out our branch target. */ @@ -1140,6 +1143,8 @@ void sp0256_device::micro() void sp0256_device::ald_w(uint8_t data) { + m_stream->update(); + /* ---------------------------------------------------------------- */ /* Drop writes to the ALD register if we're busy. */ /* ---------------------------------------------------------------- */ @@ -1155,66 +1160,59 @@ void sp0256_device::ald_w(uint8_t data) /* get the new PC address. */ /* ---------------------------------------------------------------- */ m_lrq = 0; - m_ald = (0xff & data) << 4; + m_ald = data << 4; m_drq_cb(0); SET_SBY(0); - - return; } int sp0256_device::lrq_r() { - // force stream update m_stream->update(); - - return m_lrq == 0x8000; + return m_lrq; } int sp0256_device::sby_r() { - // TODO: force stream update?? - + m_stream->update(); return m_sby_line; } uint16_t sp0256_device::spb640_r(offs_t offset) { + m_stream->update(); + offset &= 1; + /* -------------------------------------------------------------------- */ /* Offset 0 returns the SP0256 LRQ status on bit 15. */ /* -------------------------------------------------------------------- */ if (offset == 0) { - return m_lrq; + return m_lrq << 15; } /* -------------------------------------------------------------------- */ /* Offset 1 returns the SPB640 FIFO full status on bit 15. */ /* -------------------------------------------------------------------- */ - if (offset == 1) + else { return (m_fifo_head - m_fifo_tail) >= 64 ? 0x8000 : 0; } - - /* -------------------------------------------------------------------- */ - /* Just return 255 for all other addresses in our range. */ - /* -------------------------------------------------------------------- */ - return 0x00ff; } void sp0256_device::spb640_w(offs_t offset, uint16_t data) { + m_stream->update(); + offset &= 1; + if (offset == 0) { ald_w(data & 0xff); - return; } - - if (offset == 1) + else { /* ---------------------------------------------------------------- */ /* If Bit 10 is set, reset the FIFO, and SP0256. */ /* ---------------------------------------------------------------- */ - if (data & 0x400) { m_fifo_head = m_fifo_tail = m_fifo_bitp = 0; @@ -1234,13 +1232,10 @@ void sp0256_device::spb640_w(offs_t offset, uint16_t data) /* ---------------------------------------------------------------- */ /* FIFO up the lower 10 bits of the data. */ /* ---------------------------------------------------------------- */ - LOG("spb640: WR_FIFO %.3X %d.%d %d\n", data & 0x3ff, m_fifo_tail, m_fifo_bitp, m_fifo_head); m_fifo[m_fifo_head++ & 63] = data & 0x3ff; - - return; } } @@ -1251,11 +1246,6 @@ void sp0256_device::set_clock(int clock) } -TIMER_CALLBACK_MEMBER(sp0256_device::set_lrq_timer_proc) -{ - m_lrq = 0x8000; -} - //------------------------------------------------- // sound_stream_update - handle a stream update //------------------------------------------------- @@ -1264,7 +1254,6 @@ void sp0256_device::sound_stream_update(sound_stream &stream, std::vector output.samples()) break; - length = output.samples() - output_index; + int length = output.samples() - output_index; /* ---------------------------------------------------------------- */ /* Process the current set of filter coefficients as long as the */ /* repeat count holds up and we have room in our scratch buffer. */ /* ---------------------------------------------------------------- */ - did_samp = 0; - //old_idx = m_sc_head; + int did_samp = 0; if (length > 0) do { int do_samp; @@ -1322,7 +1309,7 @@ void sp0256_device::sound_stream_update(sound_stream &stream, std::vector