From 15d97d90f60953d9701716a33fe3303a305c2e14 Mon Sep 17 00:00:00 2001 From: AJR Date: Thu, 7 Nov 2019 18:23:39 -0500 Subject: st2204: Improve timer synchronization (nw) --- src/devices/cpu/m6502/st2204.cpp | 28 ++++++++++++++++------------ src/devices/cpu/m6502/st2204.h | 1 + src/devices/cpu/m6502/st2xxx.cpp | 7 ++++++- src/devices/cpu/m6502/st2xxx.h | 1 + 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/devices/cpu/m6502/st2204.cpp b/src/devices/cpu/m6502/st2204.cpp index 9e192dd5fff..b56d4482336 100644 --- a/src/devices/cpu/m6502/st2204.cpp +++ b/src/devices/cpu/m6502/st2204.cpp @@ -264,6 +264,12 @@ TIMER_CALLBACK_MEMBER(st2204_device::t0_interrupt) m_t0_timer->adjust(cycles_to_attotime((256 - m_tcntr[0]) * tclk_pres_div(m_tmode[0] & 0x07))); } +void st2204_device::t0_start() +{ + u32 div = tclk_pres_div(m_tmode[0] & 0x07); + m_t0_timer->adjust(cycles_to_attotime((255 - m_tcntr[0]) * div + div - (pres_count() & (div - 1)))); +} + u8 st2204_device::t0m_r() { return m_tmode[0]; @@ -271,20 +277,18 @@ u8 st2204_device::t0m_r() void st2204_device::t0m_w(u8 data) { - if ((data & 0x27) != (m_tmode[0] & 0x27) && (m_prs & 0x60) == 0x40) + u8 t0m_old = std::exchange(m_tmode[0], data & 0x37); + + if ((data & 0x27) != (t0m_old & 0x27) && (m_prs & 0x60) == 0x40) { // forced update m_tcntr[0] = t0c_r(); + if (BIT(data, 5)) - { - u32 div = tclk_pres_div(data & 0x07); - m_t0_timer->adjust(cycles_to_attotime((255 - m_tcntr[0]) * div) + cycles_to_attotime(div - (m_pres_base & (div - 1)))); - } - else if (BIT(m_tmode[0], 5)) + t0_start(); + else if (BIT(t0m_old, 5)) m_t0_timer->adjust(attotime::never); } - - m_tmode[0] = data & 0x37; } u8 st2204_device::t0c_r() @@ -294,7 +298,7 @@ u8 st2204_device::t0c_r() else { u32 div = tclk_pres_div(m_tmode[0] & 0x07); - return 256 - std::max((attotime_to_cycles(m_t0_timer->remaining()) + div - 1) / div, u64(1)); + return 255 - u8(attotime_to_cycles(m_t0_timer->remaining()) / div); } } @@ -302,7 +306,7 @@ void st2204_device::t0c_w(u8 data) { m_tcntr[0] = m_tload[0] = data; if ((m_prs & 0x60) == 0x40 && BIT(m_tmode[0], 5)) - m_t0_timer->adjust(cycles_to_attotime((256 - data) * tclk_pres_div(m_tmode[0] & 0x07))); + t0_start(); } u8 st2204_device::t1m_r() @@ -327,8 +331,8 @@ void st2204_device::t1c_w(u8 data) void st2204_device::st2xxx_tclk_start() { - u32 div = tclk_pres_div(m_tmode[0] & 0x07); - m_t0_timer->adjust(cycles_to_attotime((255 - m_tcntr[0]) * div) + cycles_to_attotime(div - (m_pres_base & (div - 1)))); + if (BIT(m_tmode[0], 5)) + t0_start(); } void st2204_device::st2xxx_tclk_stop() diff --git a/src/devices/cpu/m6502/st2204.h b/src/devices/cpu/m6502/st2204.h index 4dd7d9e7bec..46c071d3c9b 100644 --- a/src/devices/cpu/m6502/st2204.h +++ b/src/devices/cpu/m6502/st2204.h @@ -73,6 +73,7 @@ private: u8 pmcr_r(); void pmcr_w(u8 data); TIMER_CALLBACK_MEMBER(t0_interrupt); + void t0_start(); u8 t0m_r(); void t0m_w(u8 data); u8 t0c_r(); diff --git a/src/devices/cpu/m6502/st2xxx.cpp b/src/devices/cpu/m6502/st2xxx.cpp index 12bcf3920a7..51a6a6094c6 100644 --- a/src/devices/cpu/m6502/st2xxx.cpp +++ b/src/devices/cpu/m6502/st2xxx.cpp @@ -396,9 +396,14 @@ u32 st2xxx_device::tclk_pres_div(u8 mode) const return 0x8000 >> (mode * 2); } +u16 st2xxx_device::pres_count() const +{ + return (m_pres_base + ((m_prs & 0x60) == 0x40 ? attotime_to_cycles(machine().time() - m_pres_started) : 0)); +} + u8 st2xxx_device::prs_r() { - return (m_pres_base + ((m_prs & 0x60) == 0x40 ? attotime_to_cycles(machine().time() - m_pres_started) : 0)) & 0xff; + return pres_count() & 0xff; } void st2xxx_device::prs_w(u8 data) diff --git a/src/devices/cpu/m6502/st2xxx.h b/src/devices/cpu/m6502/st2xxx.h index be33598a3e1..cc6be615e35 100644 --- a/src/devices/cpu/m6502/st2xxx.h +++ b/src/devices/cpu/m6502/st2xxx.h @@ -168,6 +168,7 @@ protected: void btclr_all_w(u8 data); u32 tclk_pres_div(u8 mode) const; + u16 pres_count() const; u8 prs_r(); void prs_w(u8 data); -- cgit v1.2.3