mirror of
https://github.com/TomHarte/CLK.git
synced 2025-03-13 18:31:04 +00:00
Uses the union of all drive statuses to determine Drive::Controller's preferred clocking.
This commit is contained in:
parent
452e281009
commit
3cb6bbf771
@ -16,6 +16,7 @@ Controller::Controller(Cycles clock_rate) :
|
||||
pll_(100, *this),
|
||||
empty_drive_(int(clock_rate.as_integral()), 1, 1),
|
||||
drive_(&empty_drive_) {
|
||||
empty_drive_.set_clocking_hint_observer(this);
|
||||
set_expected_bit_length(Time(1));
|
||||
}
|
||||
|
||||
@ -24,11 +25,24 @@ void Controller::set_component_prefers_clocking(ClockingHint::Source *component,
|
||||
}
|
||||
|
||||
ClockingHint::Preference Controller::preferred_clocking() {
|
||||
return (!drive_ || (drive_->preferred_clocking() == ClockingHint::Preference::None)) ? ClockingHint::Preference::None : ClockingHint::Preference::RealTime;
|
||||
// Nominate RealTime clocking if any drive currently wants any clocking whatsoever.
|
||||
// Otherwise, ::None will do.
|
||||
for(auto &drive: drives_) {
|
||||
if(drive.preferred_clocking() != ClockingHint::Preference::None) {
|
||||
return ClockingHint::Preference::RealTime;
|
||||
}
|
||||
}
|
||||
if(empty_drive_.preferred_clocking() != ClockingHint::Preference::None) {
|
||||
return ClockingHint::Preference::RealTime;
|
||||
}
|
||||
return ClockingHint::Preference::None;
|
||||
}
|
||||
|
||||
void Controller::run_for(const Cycles cycles) {
|
||||
if(drive_) drive_->run_for(cycles);
|
||||
for(auto &drive: drives_) {
|
||||
drive.run_for(cycles);
|
||||
}
|
||||
empty_drive_.run_for(cycles);
|
||||
}
|
||||
|
||||
Drive &Controller::get_drive() {
|
||||
@ -77,14 +91,19 @@ void Controller::set_drive(int index_mask) {
|
||||
}
|
||||
|
||||
ClockingHint::Preference former_prefernece = preferred_clocking();
|
||||
// invalidate_track();
|
||||
|
||||
// Stop receiving events from the current drive.
|
||||
get_drive().set_event_delegate(nullptr);
|
||||
get_drive().set_clocking_hint_observer(nullptr);
|
||||
|
||||
// TODO: a transfer of writing state, if writing?
|
||||
|
||||
if(!index_mask) {
|
||||
drive_ = &empty_drive_;
|
||||
} else {
|
||||
// TEMPORARY FIX: connect up only the first selected drive.
|
||||
// TODO: at least merge events if multiple drives are selected. Some computers have
|
||||
// controllers that allow this, with usually meaningless results as far as I can
|
||||
// imagine. But the limit of an emulator shouldn't be the author's imagination.
|
||||
size_t index = 0;
|
||||
while(!(index_mask&1)) {
|
||||
index_mask >>= 1;
|
||||
@ -94,7 +113,6 @@ void Controller::set_drive(int index_mask) {
|
||||
}
|
||||
|
||||
get_drive().set_event_delegate(this);
|
||||
get_drive().set_clocking_hint_observer(this);
|
||||
|
||||
if(preferred_clocking() != former_prefernece) {
|
||||
update_clocking_observer();
|
||||
|
@ -55,16 +55,21 @@ class Controller:
|
||||
void set_drive(int index_mask);
|
||||
|
||||
/*!
|
||||
Adds a new drive to the attached list, returning its index.
|
||||
Adds a new drive to the drive list, returning its index.
|
||||
*/
|
||||
template<typename... Args> size_t emplace_drive(Args&&... args) {
|
||||
drives_.emplace_back(std::forward<Args>(args)...);
|
||||
drives_.back().set_clocking_hint_observer(this);
|
||||
return drives_.size() - 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds @c count new drives to the drive list, returning the index of the final one added.
|
||||
*/
|
||||
template<typename... Args> size_t emplace_drives(size_t count, Args&&... args) {
|
||||
while(count--) {
|
||||
drives_.emplace_back(std::forward<Args>(args)...);
|
||||
drives_.back().set_clocking_hint_observer(this);
|
||||
}
|
||||
return drives_.size() - 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user