summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ariedlmayer@gmail.com>2025-07-25 23:06:22 -0400
committer AJR <ariedlmayer@gmail.com>2025-07-25 23:06:22 -0400
commitf663de7076d33ff3ad28fc4ebf963974f2cc80d8 (patch)
tree261dcb0b406daf9a014cf51a9fea83ecc6b74588
parentfda3d4f99eb4c868c77bf21650372bc72b8e6ca6 (diff)
pokey: Synchronize on SOD output transitions during serial transmission
-rw-r--r--src/devices/sound/pokey.cpp31
-rw-r--r--src/devices/sound/pokey.h2
2 files changed, 22 insertions, 11 deletions
diff --git a/src/devices/sound/pokey.cpp b/src/devices/sound/pokey.cpp
index 77c75c1bd44..0aea0ded433 100644
--- a/src/devices/sound/pokey.cpp
+++ b/src/devices/sound/pokey.cpp
@@ -107,7 +107,7 @@
#define VERBOSE_IRQ (1U << 5)
#define VERBOSE_SERIN (1U << 6)
#define VERBOSE_SEROUT (1U << 7)
-#define VERBOSE (0)
+#define VERBOSE (VERBOSE_SERIN | VERBOSE_SEROUT)
#include "logmacro.h"
@@ -216,6 +216,7 @@ pokey_device::pokey_device(const machine_config &mconfig, const char *tag, devic
m_output_type(LEGACY_LINEAR),
m_serout_ready_timer(nullptr),
m_serout_complete_timer(nullptr),
+ m_serout_bit_timer(nullptr),
m_serin_ready_timer(nullptr)
{
}
@@ -303,6 +304,7 @@ void pokey_device::device_start()
m_serout_ready_timer = timer_alloc(FUNC(pokey_device::serout_ready_irq), this);
m_serout_complete_timer = timer_alloc(FUNC(pokey_device::serout_complete_irq), this);
+ m_serout_bit_timer = timer_alloc(FUNC(pokey_device::serout_transmit_bit), this);
m_serin_ready_timer = timer_alloc(FUNC(pokey_device::serin_ready_irq), this);
save_item(STRUCT_MEMBER(m_channel, m_borrow_cnt));
@@ -412,6 +414,10 @@ void pokey_device::device_clock_changed()
TIMER_CALLBACK_MEMBER(pokey_device::serout_ready_irq)
{
+ if (!(m_SKCTL & SK_TWOTONE))
+ m_sod_w_cb(0);
+ m_oclk_w_cb(1);
+
m_IRQST &= ~IRQ_SEROC;
if (m_IRQEN & IRQ_SEROR)
{
@@ -423,6 +429,9 @@ TIMER_CALLBACK_MEMBER(pokey_device::serout_ready_irq)
TIMER_CALLBACK_MEMBER(pokey_device::serout_complete_irq)
{
+ if (!(m_SKCTL & SK_TWOTONE) && (m_SKCTL & SK_BREAK))
+ m_sod_w_cb(0);
+
// Completion flag is set regardless of IRQEN
m_IRQST |= IRQ_SEROC;
if (m_IRQEN & IRQ_SEROC)
@@ -432,6 +441,13 @@ TIMER_CALLBACK_MEMBER(pokey_device::serout_complete_irq)
}
}
+TIMER_CALLBACK_MEMBER(pokey_device::serout_transmit_bit)
+{
+ if (!(m_SKCTL & SK_TWOTONE))
+ m_sod_w_cb(m_serout_shift & 1);
+ m_oclk_w_cb(1);
+}
+
TIMER_CALLBACK_MEMBER(pokey_device::serin_ready_irq)
{
// Check stop bit for framing error
@@ -1242,27 +1258,20 @@ void pokey_device::process_serout()
{
// Output start bit and reload the shift register
LOG_SEROUT("SEROUT transmitting start bit of %02x @ %s\n", m_SEROUT, machine().time().to_string());
- if (!(m_SKCTL & SK_TWOTONE))
- m_sod_w_cb(0);
- m_oclk_w_cb(1);
m_serout_shift = (m_SEROUT << 1) | (1 << 9);
m_serout_full = false;
m_serout_ready_timer->adjust(attotime::zero);
}
else
- {
- if (!(m_SKCTL & SK_TWOTONE) && (m_SKCTL & SK_BREAK))
- m_sod_w_cb(0);
m_serout_complete_timer->adjust(attotime::zero);
- }
}
else
{
+ bool last_sod = m_serout_shift & 1;
m_serout_shift >>= 1;
LOG_SEROUT("SEROUT transmitting %d bit @ %s\n", m_serout_shift & 1, machine().time().to_string());
- if (!(m_SKCTL & SK_TWOTONE))
- m_sod_w_cb(m_serout_shift & 1);
- m_oclk_w_cb(1);
+ if (last_sod != (m_serout_shift & 1))
+ m_serout_bit_timer->adjust(attotime::zero);
}
}
diff --git a/src/devices/sound/pokey.h b/src/devices/sound/pokey.h
index bc6b2596d38..5d3ed4e8225 100644
--- a/src/devices/sound/pokey.h
+++ b/src/devices/sound/pokey.h
@@ -192,6 +192,7 @@ protected:
TIMER_CALLBACK_MEMBER(serout_ready_irq);
TIMER_CALLBACK_MEMBER(serout_complete_irq);
+ TIMER_CALLBACK_MEMBER(serout_transmit_bit);
TIMER_CALLBACK_MEMBER(serin_ready_irq);
TIMER_CALLBACK_MEMBER(sync_write);
TIMER_CALLBACK_MEMBER(sync_pot);
@@ -320,6 +321,7 @@ private:
emu_timer *m_serout_ready_timer;
emu_timer *m_serout_complete_timer;
+ emu_timer *m_serout_bit_timer;
emu_timer *m_serin_ready_timer;
};