diff --git a/Components/1770/1770.cpp b/Components/1770/1770.cpp index 00f6220b6..081cf3956 100644 --- a/Components/1770/1770.cpp +++ b/Components/1770/1770.cpp @@ -769,16 +769,18 @@ void WD1770::posit_event(int new_event_type) { } void WD1770::update_status(std::function updater) { + const Status old_status = status_; + if(delegate_) { - Status old_status = status_; updater(status_); const bool did_change = (status_.busy != old_status.busy) || (status_.data_request != old_status.data_request) || (status_.interrupt_request != old_status.interrupt_request); if(did_change) delegate_->wd1770_did_change_output(this); - } - else updater(status_); + } else updater(status_); + + if(status_.busy != old_status.busy) update_clocking_observer(); } void WD1770::set_head_load_request(bool head_load) {} @@ -788,3 +790,8 @@ void WD1770::set_head_loaded(bool head_loaded) { head_is_loaded_ = head_loaded; if(head_loaded) posit_event(static_cast(Event1770::HeadLoad)); } + +ClockingHint::Preference WD1770::preferred_clocking() { + if(status_.busy) return ClockingHint::Preference::RealTime; + return Storage::Disk::MFMController::preferred_clocking(); +} diff --git a/Components/1770/1770.hpp b/Components/1770/1770.hpp index 04a71a09a..35e349b10 100644 --- a/Components/1770/1770.hpp +++ b/Components/1770/1770.hpp @@ -73,6 +73,8 @@ class WD1770: public Storage::Disk::MFMController { }; inline void set_delegate(Delegate *delegate) { delegate_ = delegate; } + ClockingHint::Preference preferred_clocking() final; + protected: virtual void set_head_load_request(bool head_load); virtual void set_motor_on(bool motor_on); diff --git a/Machines/AtariST/AtariST.cpp b/Machines/AtariST/AtariST.cpp index 338ea7283..a18de827e 100644 --- a/Machines/AtariST/AtariST.cpp +++ b/Machines/AtariST/AtariST.cpp @@ -279,6 +279,7 @@ class ConcreteMachine: keyboard_acia_->set_clocking_hint_observer(this); ikbd_.set_clocking_hint_observer(this); mfp_->set_clocking_hint_observer(this); + dma_->set_clocking_hint_observer(this); mfp_->set_interrupt_delegate(this); dma_->set_interrupt_delegate(this); @@ -658,6 +659,7 @@ class ConcreteMachine: (midi_acia_.last_valid()->preferred_clocking() != ClockingHint::Preference::RealTime); keyboard_needs_clock_ = ikbd_.preferred_clocking() != ClockingHint::Preference::None; mfp_is_realtime_ = mfp_.last_valid()->preferred_clocking() == ClockingHint::Preference::RealTime; + dma_is_realtime_ = dma_.last_valid()->preferred_clocking() == ClockingHint::Preference::RealTime; } // MARK: - GPIP input. diff --git a/Machines/AtariST/DMAController.cpp b/Machines/AtariST/DMAController.cpp index 45522f4dd..46ba8865e 100644 --- a/Machines/AtariST/DMAController.cpp +++ b/Machines/AtariST/DMAController.cpp @@ -14,6 +14,7 @@ using namespace Atari::ST; DMAController::DMAController() { fdc_.set_delegate(this); + fdc_.set_clocking_hint_observer(this); } uint16_t DMAController::read(int address) { @@ -100,3 +101,11 @@ void DMAController::set_interrupt_delegate(InterruptDelegate *delegate) { bool DMAController::get_interrupt_line() { return interrupt_line_; } + +void DMAController::set_component_prefers_clocking(ClockingHint::Source *, ClockingHint::Preference) { + update_clocking_observer(); +} + +ClockingHint::Preference DMAController::preferred_clocking() { + return (fdc_.preferred_clocking() == ClockingHint::Preference::None) ? ClockingHint::Preference::None : ClockingHint::Preference::RealTime; +} diff --git a/Machines/AtariST/DMAController.hpp b/Machines/AtariST/DMAController.hpp index 59cacdd3b..cbedc18ed 100644 --- a/Machines/AtariST/DMAController.hpp +++ b/Machines/AtariST/DMAController.hpp @@ -13,12 +13,13 @@ #include #include "../../ClockReceiver/ClockReceiver.hpp" +#include "../../ClockReceiver/ClockingHintSource.hpp" #include "../../Components/1770/1770.hpp" namespace Atari { namespace ST { -class DMAController: public WD::WD1770::Delegate { +class DMAController: public WD::WD1770::Delegate, public ClockingHint::Source, public ClockingHint::Observer { public: DMAController(); @@ -33,6 +34,9 @@ class DMAController: public WD::WD1770::Delegate { }; void set_interrupt_delegate(InterruptDelegate *delegate); + // ClockingHint::Source. + ClockingHint::Preference preferred_clocking() final; + private: HalfCycles running_time_; struct WD1772: public WD::WD1770 { @@ -59,6 +63,8 @@ class DMAController: public WD::WD1770::Delegate { InterruptDelegate *interrupt_delegate_ = nullptr; bool interrupt_line_ = false; + + void set_component_prefers_clocking(ClockingHint::Source *, ClockingHint::Preference) final; }; }