mirror of
https://github.com/TomHarte/CLK.git
synced 2025-06-18 23:23:35 +00:00
Uses the union of all drive statuses to determine Drive::Controller's preferred clocking.
This commit is contained in:
@ -16,6 +16,7 @@ Controller::Controller(Cycles clock_rate) :
|
|||||||
pll_(100, *this),
|
pll_(100, *this),
|
||||||
empty_drive_(int(clock_rate.as_integral()), 1, 1),
|
empty_drive_(int(clock_rate.as_integral()), 1, 1),
|
||||||
drive_(&empty_drive_) {
|
drive_(&empty_drive_) {
|
||||||
|
empty_drive_.set_clocking_hint_observer(this);
|
||||||
set_expected_bit_length(Time(1));
|
set_expected_bit_length(Time(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,11 +25,24 @@ void Controller::set_component_prefers_clocking(ClockingHint::Source *component,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClockingHint::Preference Controller::preferred_clocking() {
|
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) {
|
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() {
|
Drive &Controller::get_drive() {
|
||||||
@ -77,14 +91,19 @@ void Controller::set_drive(int index_mask) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClockingHint::Preference former_prefernece = preferred_clocking();
|
ClockingHint::Preference former_prefernece = preferred_clocking();
|
||||||
// invalidate_track();
|
|
||||||
|
|
||||||
|
// Stop receiving events from the current drive.
|
||||||
get_drive().set_event_delegate(nullptr);
|
get_drive().set_event_delegate(nullptr);
|
||||||
get_drive().set_clocking_hint_observer(nullptr);
|
|
||||||
|
// TODO: a transfer of writing state, if writing?
|
||||||
|
|
||||||
if(!index_mask) {
|
if(!index_mask) {
|
||||||
drive_ = &empty_drive_;
|
drive_ = &empty_drive_;
|
||||||
} else {
|
} 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;
|
size_t index = 0;
|
||||||
while(!(index_mask&1)) {
|
while(!(index_mask&1)) {
|
||||||
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_event_delegate(this);
|
||||||
get_drive().set_clocking_hint_observer(this);
|
|
||||||
|
|
||||||
if(preferred_clocking() != former_prefernece) {
|
if(preferred_clocking() != former_prefernece) {
|
||||||
update_clocking_observer();
|
update_clocking_observer();
|
||||||
|
@ -55,16 +55,21 @@ class Controller:
|
|||||||
void set_drive(int index_mask);
|
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) {
|
template<typename... Args> size_t emplace_drive(Args&&... args) {
|
||||||
drives_.emplace_back(std::forward<Args>(args)...);
|
drives_.emplace_back(std::forward<Args>(args)...);
|
||||||
|
drives_.back().set_clocking_hint_observer(this);
|
||||||
return drives_.size() - 1;
|
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) {
|
template<typename... Args> size_t emplace_drives(size_t count, Args&&... args) {
|
||||||
while(count--) {
|
while(count--) {
|
||||||
drives_.emplace_back(std::forward<Args>(args)...);
|
drives_.emplace_back(std::forward<Args>(args)...);
|
||||||
|
drives_.back().set_clocking_hint_observer(this);
|
||||||
}
|
}
|
||||||
return drives_.size() - 1;
|
return drives_.size() - 1;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user