From 77df4095aa879981e3a3f5c21f167b2d0691ed62 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Tue, 17 May 2022 10:13:11 +0200 Subject: diexec: optionally resynchronize to the implicit clock domain on clock frequency change (#9726) apple3: resync on clock change to keep the correct phase relationship with the diskiii --- src/devices/cpu/nec/v5x.cpp | 2 +- src/devices/cpu/nec/v5x.h | 2 +- src/emu/device.cpp | 10 +++++----- src/emu/device.h | 11 ++++++----- src/emu/diexec.cpp | 6 +++++- src/emu/diexec.h | 2 +- src/mame/machine/apple3.cpp | 2 +- 7 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/devices/cpu/nec/v5x.cpp b/src/devices/cpu/nec/v5x.cpp index 8ce9a18ad1e..9faeed6bfd9 100644 --- a/src/devices/cpu/nec/v5x.cpp +++ b/src/devices/cpu/nec/v5x.cpp @@ -132,7 +132,7 @@ void device_v5x_interface::TCKS_w(u8 data) tcu_clock_update(); } -void device_v5x_interface::interface_clock_changed() +void device_v5x_interface::interface_clock_changed(bool sync_on_new_clock_domain) { tcu_clock_update(); } diff --git a/src/devices/cpu/nec/v5x.h b/src/devices/cpu/nec/v5x.h index f82c50223e0..23fcdc265a9 100644 --- a/src/devices/cpu/nec/v5x.h +++ b/src/devices/cpu/nec/v5x.h @@ -50,7 +50,7 @@ protected: virtual void interface_post_start() override; virtual void interface_pre_reset() override; virtual void interface_post_load() override; - virtual void interface_clock_changed() override; + virtual void interface_clock_changed(bool sync_on_new_clock_domain) override; void v5x_set_input(int inputnum, int state); void v5x_add_mconfig(machine_config &config); diff --git a/src/emu/device.cpp b/src/emu/device.cpp index 90441ceebd8..6a4b0d4b685 100644 --- a/src/emu/device.cpp +++ b/src/emu/device.cpp @@ -365,7 +365,7 @@ void device_t::reset() // unscaled clock //------------------------------------------------- -void device_t::set_unscaled_clock(u32 clock) +void device_t::set_unscaled_clock(u32 clock, bool sync_on_new_clock_domain) { // do nothing if no actual change if (clock == m_unscaled_clock) @@ -381,7 +381,7 @@ void device_t::set_unscaled_clock(u32 clock) // if the device has already started, make sure it knows about the new clock if (m_started) - notify_clock_changed(); + notify_clock_changed(sync_on_new_clock_domain); } @@ -716,11 +716,11 @@ void device_t::post_load() // that the clock has changed //------------------------------------------------- -void device_t::notify_clock_changed() +void device_t::notify_clock_changed(bool sync_on_new_clock_domain) { // first notify interfaces for (device_interface &intf : interfaces()) - intf.interface_clock_changed(); + intf.interface_clock_changed(sync_on_new_clock_domain); // then notify the device device_clock_changed(); @@ -1202,7 +1202,7 @@ void device_interface::interface_post_load() // implementation //------------------------------------------------- -void device_interface::interface_clock_changed() +void device_interface::interface_clock_changed(bool sync_on_new_clock_domain) { // do nothing by default } diff --git a/src/emu/device.h b/src/emu/device.h index 9b97f21c8ea..4ea1a940320 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -696,9 +696,10 @@ public: // clock/timing accessors u32 clock() const { return m_clock; } u32 unscaled_clock() const { return m_unscaled_clock; } - void set_unscaled_clock(u32 clock); - void set_unscaled_clock(const XTAL &xtal) { set_unscaled_clock(xtal.value()); } - void set_unscaled_clock_int(u32 clock) { set_unscaled_clock(clock); } // non-overloaded name because binding to overloads is ugly + void set_unscaled_clock(u32 clock, bool sync_on_new_clock_domain = false); + void set_unscaled_clock(const XTAL &xtal, bool sync_on_new_clock_domain = false) { set_unscaled_clock(xtal.value(), sync_on_new_clock_domain); } + void set_unscaled_clock_int(u32 clock) { set_unscaled_clock(clock, false); } // non-overloaded name because binding to overloads is ugly + void set_unscaled_clock_int_sync(u32 clock) { set_unscaled_clock(clock, true); } // non-overloaded name because binding to overloads is ugly double clock_scale() const { return m_clock_scale; } void set_clock_scale(double clockscale); attotime clocks_to_attotime(u64 clocks) const noexcept; @@ -834,7 +835,7 @@ protected: void debug_setup(); void pre_save(); void post_load(); - void notify_clock_changed(); + void notify_clock_changed(bool sync_on_new_clock_domain = false); finder_base *register_auto_finder(finder_base &autodev); void register_callback(devcb_base &callback); @@ -1182,7 +1183,7 @@ public: /// \sa interface_pre_save device_t::device_post_load virtual void interface_post_load() ATTR_COLD; - virtual void interface_clock_changed(); + virtual void interface_clock_changed(bool sync_on_new_clock_domain); virtual void interface_debug_setup(); private: diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp index 1ff53672470..0e9074fe3b2 100644 --- a/src/emu/diexec.cpp +++ b/src/emu/diexec.cpp @@ -475,7 +475,7 @@ void device_execute_interface::interface_post_reset() // information for this device //------------------------------------------------- -void device_execute_interface::interface_clock_changed() +void device_execute_interface::interface_clock_changed(bool sync_on_new_clock_domain) { // a clock of zero disables the device if (device().clock() == 0) @@ -492,6 +492,10 @@ void device_execute_interface::interface_clock_changed() m_cycles_per_second = clocks_to_cycles(device().clock()); m_attoseconds_per_cycle = HZ_TO_ATTOSECONDS(m_cycles_per_second); + // resynchronize the localtime to the clock domain when asked to + if (sync_on_new_clock_domain) + m_localtime = attotime::from_ticks(m_localtime.as_ticks(device().clock())+1, device().clock()); + // update the device's divisor s64 attos = m_attoseconds_per_cycle; m_divshift = 0; diff --git a/src/emu/diexec.h b/src/emu/diexec.h index 065248a9046..1490c20389d 100644 --- a/src/emu/diexec.h +++ b/src/emu/diexec.h @@ -216,7 +216,7 @@ protected: virtual void interface_post_start() override; virtual void interface_pre_reset() override; virtual void interface_post_reset() override; - virtual void interface_clock_changed() override; + virtual void interface_clock_changed(bool sync_on_new_clock_domain) override; // for use by devcpu for now... int current_input_state(unsigned i) const { return m_input[i].m_curstate; } diff --git a/src/mame/machine/apple3.cpp b/src/mame/machine/apple3.cpp index 447ab6290c4..d3467664e76 100644 --- a/src/mame/machine/apple3.cpp +++ b/src/mame/machine/apple3.cpp @@ -532,7 +532,7 @@ void apple3_state::apple3_update_memory() logerror("apple3_update_memory(): via_0_b=0x%02x via_1_a=0x0x%02x\n", m_via_0_b, m_via_1_a); } - m_maincpu->set_unscaled_clock(((m_via_0_a & ENV_SLOWSPEED) ? APPLE2_CLOCK : (14.318181_MHz_XTAL / 7))); + m_maincpu->set_unscaled_clock(((m_via_0_a & ENV_SLOWSPEED) ? APPLE2_CLOCK : (14.318181_MHz_XTAL / 7)), true); /* bank 2 (0100-01FF) */ if (!(m_via_0_a & ENV_STACK1XX)) -- cgit v1.2.3