mirror of
https://github.com/TomHarte/CLK.git
synced 2026-04-21 02:17:08 +00:00
Commutes Sleeper to ClockingHint::Source, making state more granular.
This commit is contained in:
@@ -43,7 +43,6 @@ class WD1770: public Storage::Disk::MFMController {
|
||||
|
||||
/// Runs the controller for @c number_of_cycles cycles.
|
||||
void run_for(const Cycles cycles);
|
||||
using Storage::Disk::Controller::run_for;
|
||||
|
||||
enum Flag: uint8_t {
|
||||
NotReady = 0x80,
|
||||
|
||||
@@ -83,8 +83,10 @@ i8272::i8272(BusHandler &bus_handler, Cycles clock_rate) :
|
||||
posit_event(static_cast<int>(Event8272::CommandByte));
|
||||
}
|
||||
|
||||
bool i8272::is_sleeping() {
|
||||
return is_sleeping_ && Storage::Disk::MFMController::is_sleeping();
|
||||
ClockingHint::Preference i8272::preferred_clocking() {
|
||||
const auto mfm_controller_preferred_clocking = Storage::Disk::MFMController::preferred_clocking();
|
||||
if(mfm_controller_preferred_clocking != ClockingHint::Preference::None) return mfm_controller_preferred_clocking;
|
||||
return is_sleeping_ ? ClockingHint::Preference::None : ClockingHint::Preference::JustInTime;
|
||||
}
|
||||
|
||||
void i8272::run_for(Cycles cycles) {
|
||||
@@ -159,7 +161,7 @@ void i8272::run_for(Cycles cycles) {
|
||||
}
|
||||
|
||||
is_sleeping_ = !delay_time_ && !drives_seeking_ && !head_timers_running_;
|
||||
if(is_sleeping_) update_sleep_observer();
|
||||
if(is_sleeping_) update_clocking_observer();
|
||||
}
|
||||
|
||||
void i8272::set_register(int address, uint8_t value) {
|
||||
@@ -198,7 +200,7 @@ uint8_t i8272::get_register(int address) {
|
||||
|
||||
#define MS_TO_CYCLES(x) x * 8000
|
||||
#define WAIT_FOR_EVENT(mask) resume_point_ = __LINE__; interesting_event_mask_ = static_cast<int>(mask); return; case __LINE__:
|
||||
#define WAIT_FOR_TIME(ms) resume_point_ = __LINE__; interesting_event_mask_ = static_cast<int>(Event8272::Timer); delay_time_ = MS_TO_CYCLES(ms); is_sleeping_ = false; update_sleep_observer(); case __LINE__: if(delay_time_) return;
|
||||
#define WAIT_FOR_TIME(ms) resume_point_ = __LINE__; interesting_event_mask_ = static_cast<int>(Event8272::Timer); delay_time_ = MS_TO_CYCLES(ms); is_sleeping_ = false; update_clocking_observer(); case __LINE__: if(delay_time_) return;
|
||||
|
||||
#define PASTE(x, y) x##y
|
||||
#define CONCAT(x, y) PASTE(x, y)
|
||||
@@ -257,7 +259,7 @@ uint8_t i8272::get_register(int address) {
|
||||
if(drives_[active_drive_].head_unload_delay[active_head_] == 0) { \
|
||||
head_timers_running_++; \
|
||||
is_sleeping_ = false; \
|
||||
update_sleep_observer(); \
|
||||
update_clocking_observer(); \
|
||||
} \
|
||||
drives_[active_drive_].head_unload_delay[active_head_] = MS_TO_CYCLES(head_unload_time_);\
|
||||
}
|
||||
@@ -720,7 +722,7 @@ void i8272::posit_event(int event_type) {
|
||||
if(drives_[drive].phase != Drive::Seeking) {
|
||||
drives_seeking_++;
|
||||
is_sleeping_ = false;
|
||||
update_sleep_observer();
|
||||
update_clocking_observer();
|
||||
}
|
||||
|
||||
// Set currently seeking, with a step to occur right now (yes, it sounds like jamming these
|
||||
|
||||
@@ -39,7 +39,7 @@ class i8272: public Storage::Disk::MFMController {
|
||||
void set_dma_acknowledge(bool dack);
|
||||
void set_terminal_count(bool tc);
|
||||
|
||||
bool is_sleeping();
|
||||
ClockingHint::Preference preferred_clocking() override;
|
||||
|
||||
protected:
|
||||
virtual void select_drive(int number) = 0;
|
||||
@@ -67,7 +67,7 @@ class i8272: public Storage::Disk::MFMController {
|
||||
ResultEmpty = (1 << 5),
|
||||
NoLongerReady = (1 << 6)
|
||||
};
|
||||
void posit_event(int type);
|
||||
void posit_event(int type) override;
|
||||
int interesting_event_mask_ = static_cast<int>(Event8272::CommandByte);
|
||||
int resume_point_ = 0;
|
||||
bool is_access_command_ = false;
|
||||
|
||||
@@ -23,8 +23,8 @@ DiskII::DiskII() :
|
||||
inputs_(input_command),
|
||||
drives_{{2045454, 300, 1}, {2045454, 300, 1}}
|
||||
{
|
||||
drives_[0].set_sleep_observer(this);
|
||||
drives_[1].set_sleep_observer(this);
|
||||
drives_[0].set_clocking_hint_observer(this);
|
||||
drives_[1].set_clocking_hint_observer(this);
|
||||
drives_[active_drive_].set_event_delegate(this);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ void DiskII::select_drive(int drive) {
|
||||
}
|
||||
|
||||
void DiskII::run_for(const Cycles cycles) {
|
||||
if(is_sleeping()) return;
|
||||
if(preferred_clocking() == ClockingHint::Preference::None) return;
|
||||
|
||||
if(!controller_can_sleep_) {
|
||||
int integer_cycles = cycles.as_int();
|
||||
@@ -137,7 +137,7 @@ void DiskII::set_controller_can_sleep() {
|
||||
(shift_register_ == (is_write_protected() ? 0xff : 0x00))
|
||||
);
|
||||
if(controller_could_sleep != controller_can_sleep_)
|
||||
update_sleep_observer();
|
||||
update_clocking_observer();
|
||||
}
|
||||
|
||||
bool DiskII::is_write_protected() {
|
||||
@@ -199,14 +199,14 @@ void DiskII::process_event(const Storage::Disk::Track::Event &event) {
|
||||
}
|
||||
}
|
||||
|
||||
void DiskII::set_component_is_sleeping(Sleeper *component, bool is_sleeping) {
|
||||
drive_is_sleeping_[0] = drives_[0].is_sleeping();
|
||||
drive_is_sleeping_[1] = drives_[1].is_sleeping();
|
||||
update_sleep_observer();
|
||||
void DiskII::set_component_prefers_clocking(ClockingHint::Source *component, ClockingHint::Preference preference) {
|
||||
drive_is_sleeping_[0] = drives_[0].preferred_clocking() == ClockingHint::Preference::None;
|
||||
drive_is_sleeping_[1] = drives_[1].preferred_clocking() == ClockingHint::Preference::None;
|
||||
update_clocking_observer();
|
||||
}
|
||||
|
||||
bool DiskII::is_sleeping() {
|
||||
return controller_can_sleep_ && drive_is_sleeping_[0] && drive_is_sleeping_[1];
|
||||
ClockingHint::Preference DiskII::preferred_clocking() {
|
||||
return (controller_can_sleep_ && drive_is_sleeping_[0] && drive_is_sleeping_[1]) ? ClockingHint::Preference::None : ClockingHint::Preference::RealTime;
|
||||
}
|
||||
|
||||
void DiskII::set_data_input(uint8_t input) {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#define DiskII_hpp
|
||||
|
||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||
#include "../../ClockReceiver/Sleeper.hpp"
|
||||
#include "../../ClockReceiver/ClockingHintSource.hpp"
|
||||
|
||||
#include "../../Storage/Disk/Disk.hpp"
|
||||
#include "../../Storage/Disk/Drive.hpp"
|
||||
@@ -28,8 +28,8 @@ namespace Apple {
|
||||
*/
|
||||
class DiskII:
|
||||
public Storage::Disk::Drive::EventDelegate,
|
||||
public Sleeper::SleepObserver,
|
||||
public Sleeper {
|
||||
public ClockingHint::Source,
|
||||
public ClockingHint::Observer {
|
||||
public:
|
||||
DiskII();
|
||||
|
||||
@@ -76,7 +76,7 @@ class DiskII:
|
||||
void set_disk(const std::shared_ptr<Storage::Disk::Disk> &disk, int drive);
|
||||
|
||||
// As per Sleeper.
|
||||
bool is_sleeping() override;
|
||||
ClockingHint::Preference preferred_clocking() override;
|
||||
|
||||
// The Disk II functions as a potential target for @c Activity::Sources.
|
||||
void set_activity_observer(Activity::Observer *observer);
|
||||
@@ -95,7 +95,7 @@ class DiskII:
|
||||
|
||||
uint8_t trigger_address(int address, uint8_t value);
|
||||
void process_event(const Storage::Disk::Track::Event &event) override;
|
||||
void set_component_is_sleeping(Sleeper *component, bool is_sleeping) override;
|
||||
void set_component_prefers_clocking(ClockingHint::Source *component, ClockingHint::Preference preference) override;
|
||||
|
||||
uint8_t state_ = 0;
|
||||
uint8_t inputs_ = 0;
|
||||
|
||||
Reference in New Issue
Block a user