mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-25 03:32:01 +00:00
Attempted to implement Sleeper in Drive and therefore in DiskController. Also corrected a couple of nonconformant file names.
This commit is contained in:
parent
e3f2118757
commit
49285e9caa
@ -6,8 +6,8 @@
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef ForceInline_h
|
||||
#define ForceInline_h
|
||||
#ifndef ForceInline_hpp
|
||||
#define ForceInline_hpp
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define forceinline __attribute__((always_inline)) inline
|
@ -6,8 +6,8 @@
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Sleeper_h
|
||||
#define Sleeper_h
|
||||
#ifndef Sleeper_hpp
|
||||
#define Sleeper_hpp
|
||||
|
||||
/*!
|
||||
A sleeper is any component that sometimes requires a clock but at other times is 'asleep' — i.e. is not doing
|
||||
@ -30,17 +30,31 @@ class Sleeper {
|
||||
class SleepObserver {
|
||||
public:
|
||||
/// Called to inform an observer that the component @c component has either gone to sleep or become awake.
|
||||
void set_component_is_sleeping(void *component, bool is_sleeping) = 0;
|
||||
virtual void set_component_is_sleeping(void *component, bool is_sleeping) = 0;
|
||||
};
|
||||
|
||||
/// Registers @c observer as the new sleep observer;
|
||||
void set_sleep_observer(SleepObserver *observer) {
|
||||
sleep_observer_ = delegate;
|
||||
sleep_observer_ = observer;
|
||||
}
|
||||
|
||||
/// @returns @c true if the component is currently sleeping; @c false otherwise.
|
||||
virtual bool is_sleeping() = 0;
|
||||
|
||||
protected:
|
||||
/// Provided for subclasses; send sleep announcements to the sleep_observer_.
|
||||
SleepObserver *sleep_observer_;
|
||||
|
||||
/*!
|
||||
Provided for subclasses; call this whenever is_sleeping might have changed, and the observer will be notified,
|
||||
if one exists.
|
||||
|
||||
@c is_sleeping will be called only if there is an observer.
|
||||
*/
|
||||
void update_sleep_observer() {
|
||||
if(!sleep_observer_) return;
|
||||
sleep_observer_->set_component_is_sleeping(this, is_sleeping());
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* Sleeper_h */
|
@ -677,8 +677,8 @@
|
||||
4BACC5B01F3DFF7C0037C015 /* CharacterMapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CharacterMapper.hpp; path = AmstradCPC/CharacterMapper.hpp; sourceTree = "<group>"; };
|
||||
4BAD9B941F43D7E900724854 /* UnformattedTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnformattedTrack.cpp; sourceTree = "<group>"; };
|
||||
4BAD9B951F43D7E900724854 /* UnformattedTrack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = UnformattedTrack.hpp; sourceTree = "<group>"; };
|
||||
4BB06B211F316A3F00600C7A /* ForceInline.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ForceInline.h; sourceTree = "<group>"; };
|
||||
4BB146C61F49D7D700253439 /* Sleeper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Sleeper.h; sourceTree = "<group>"; };
|
||||
4BB06B211F316A3F00600C7A /* ForceInline.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ForceInline.hpp; sourceTree = "<group>"; };
|
||||
4BB146C61F49D7D700253439 /* Sleeper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Sleeper.hpp; sourceTree = "<group>"; };
|
||||
4BB17D4C1ED7909F00ABD1E1 /* tests.expected.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = tests.expected.json; path = FUSE/tests.expected.json; sourceTree = "<group>"; };
|
||||
4BB17D4D1ED7909F00ABD1E1 /* tests.in.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = tests.in.json; path = FUSE/tests.in.json; sourceTree = "<group>"; };
|
||||
4BB297E51B587D8300A49093 /* start */ = {isa = PBXFileReference; lastKnownFileType = file; path = " start"; sourceTree = "<group>"; };
|
||||
@ -2280,8 +2280,8 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4BF6606A1F281573002CB053 /* ClockReceiver.hpp */,
|
||||
4BB06B211F316A3F00600C7A /* ForceInline.h */,
|
||||
4BB146C61F49D7D700253439 /* Sleeper.h */,
|
||||
4BB06B211F316A3F00600C7A /* ForceInline.hpp */,
|
||||
4BB146C61F49D7D700253439 /* Sleeper.hpp */,
|
||||
);
|
||||
name = ClockReceiver;
|
||||
path = ../../ClockReceiver;
|
||||
|
@ -46,6 +46,14 @@ void Controller::setup_track() {
|
||||
get_next_event(offset);
|
||||
}
|
||||
|
||||
void Controller::set_component_is_sleeping(void *component, bool is_sleeping) {
|
||||
update_sleep_observer();
|
||||
}
|
||||
|
||||
bool Controller::is_sleeping() {
|
||||
return !(drive_ && drive_->has_disk() && motor_is_on_);
|
||||
}
|
||||
|
||||
void Controller::run_for(const Cycles cycles) {
|
||||
Time zero(0);
|
||||
|
||||
@ -208,6 +216,7 @@ void Controller::step(int direction) {
|
||||
|
||||
void Controller::set_motor_on(bool motor_on) {
|
||||
motor_is_on_ = motor_on;
|
||||
update_sleep_observer();
|
||||
}
|
||||
|
||||
bool Controller::get_motor_on() {
|
||||
@ -218,6 +227,8 @@ void Controller::set_drive(std::shared_ptr<Drive> drive) {
|
||||
if(drive_ != drive) {
|
||||
invalidate_track();
|
||||
drive_ = drive;
|
||||
drive->set_sleep_observer(this);
|
||||
update_sleep_observer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,9 @@
|
||||
#include "PCMSegment.hpp"
|
||||
#include "PCMPatchedTrack.hpp"
|
||||
#include "../TimedEventLoop.hpp"
|
||||
|
||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||
#include "../../ClockReceiver/Sleeper.hpp"
|
||||
|
||||
namespace Storage {
|
||||
namespace Disk {
|
||||
@ -28,7 +30,7 @@ namespace Disk {
|
||||
|
||||
TODO: communication of head size and permissible stepping extents, appropriate simulation of gain.
|
||||
*/
|
||||
class Controller: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop {
|
||||
class Controller: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop, public Sleeper, public Sleeper::SleepObserver {
|
||||
protected:
|
||||
/*!
|
||||
Constructs a @c DiskDrive that will be run at @c clock_rate and runs its PLL at @c clock_rate*clock_rate_multiplier,
|
||||
@ -116,6 +118,8 @@ class Controller: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop
|
||||
virtual bool get_drive_is_ready();
|
||||
bool get_drive_is_read_only();
|
||||
|
||||
bool is_sleeping();
|
||||
|
||||
private:
|
||||
Time bit_length_;
|
||||
int clock_rate_;
|
||||
@ -142,6 +146,8 @@ class Controller: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop
|
||||
|
||||
void setup_track();
|
||||
Time get_time_into_track();
|
||||
|
||||
void set_component_is_sleeping(void *component, bool is_sleeping);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,18 +18,24 @@ void Drive::set_disk(const std::shared_ptr<Disk> &disk) {
|
||||
disk_ = disk;
|
||||
track_ = nullptr;
|
||||
has_disk_ = !!disk_;
|
||||
update_sleep_observer();
|
||||
}
|
||||
|
||||
void Drive::set_disk_with_track(const std::shared_ptr<Track> &track) {
|
||||
disk_ = nullptr;
|
||||
track_ = track;
|
||||
has_disk_ = !!track_;
|
||||
update_sleep_observer();
|
||||
}
|
||||
|
||||
bool Drive::has_disk() {
|
||||
return has_disk_;
|
||||
}
|
||||
|
||||
bool Drive::is_sleeping() {
|
||||
return !has_disk_;
|
||||
}
|
||||
|
||||
bool Drive::get_is_track_zero() {
|
||||
return head_position_ == 0;
|
||||
}
|
||||
|
@ -10,12 +10,14 @@
|
||||
#define Drive_hpp
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "Disk.hpp"
|
||||
#include "../../ClockReceiver/Sleeper.hpp"
|
||||
|
||||
namespace Storage {
|
||||
namespace Disk {
|
||||
|
||||
class Drive {
|
||||
class Drive: public Sleeper {
|
||||
public:
|
||||
Drive();
|
||||
|
||||
@ -70,6 +72,9 @@ class Drive {
|
||||
*/
|
||||
bool get_is_ready();
|
||||
|
||||
// As per Sleeper.
|
||||
bool is_sleeping();
|
||||
|
||||
private:
|
||||
std::shared_ptr<Track> track_;
|
||||
std::shared_ptr<Disk> disk_;
|
||||
|
Loading…
Reference in New Issue
Block a user