mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-19 23:29:05 +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.
|
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef ForceInline_h
|
#ifndef ForceInline_hpp
|
||||||
#define ForceInline_h
|
#define ForceInline_hpp
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define forceinline __attribute__((always_inline)) inline
|
#define forceinline __attribute__((always_inline)) inline
|
@ -6,8 +6,8 @@
|
|||||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef Sleeper_h
|
#ifndef Sleeper_hpp
|
||||||
#define Sleeper_h
|
#define Sleeper_hpp
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A sleeper is any component that sometimes requires a clock but at other times is 'asleep' — i.e. is not doing
|
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 {
|
class SleepObserver {
|
||||||
public:
|
public:
|
||||||
/// Called to inform an observer that the component @c component has either gone to sleep or become awake.
|
/// 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;
|
/// Registers @c observer as the new sleep observer;
|
||||||
void set_sleep_observer(SleepObserver *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:
|
protected:
|
||||||
/// Provided for subclasses; send sleep announcements to the sleep_observer_.
|
/// Provided for subclasses; send sleep announcements to the sleep_observer_.
|
||||||
SleepObserver *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 */
|
#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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
4BB06B211F316A3F00600C7A /* ForceInline.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ForceInline.hpp; sourceTree = "<group>"; };
|
||||||
4BB146C61F49D7D700253439 /* Sleeper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Sleeper.h; 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>"; };
|
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>"; };
|
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>"; };
|
4BB297E51B587D8300A49093 /* start */ = {isa = PBXFileReference; lastKnownFileType = file; path = " start"; sourceTree = "<group>"; };
|
||||||
@ -2280,8 +2280,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
4BF6606A1F281573002CB053 /* ClockReceiver.hpp */,
|
4BF6606A1F281573002CB053 /* ClockReceiver.hpp */,
|
||||||
4BB06B211F316A3F00600C7A /* ForceInline.h */,
|
4BB06B211F316A3F00600C7A /* ForceInline.hpp */,
|
||||||
4BB146C61F49D7D700253439 /* Sleeper.h */,
|
4BB146C61F49D7D700253439 /* Sleeper.hpp */,
|
||||||
);
|
);
|
||||||
name = ClockReceiver;
|
name = ClockReceiver;
|
||||||
path = ../../ClockReceiver;
|
path = ../../ClockReceiver;
|
||||||
|
@ -46,6 +46,14 @@ void Controller::setup_track() {
|
|||||||
get_next_event(offset);
|
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) {
|
void Controller::run_for(const Cycles cycles) {
|
||||||
Time zero(0);
|
Time zero(0);
|
||||||
|
|
||||||
@ -208,6 +216,7 @@ void Controller::step(int direction) {
|
|||||||
|
|
||||||
void Controller::set_motor_on(bool motor_on) {
|
void Controller::set_motor_on(bool motor_on) {
|
||||||
motor_is_on_ = motor_on;
|
motor_is_on_ = motor_on;
|
||||||
|
update_sleep_observer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Controller::get_motor_on() {
|
bool Controller::get_motor_on() {
|
||||||
@ -218,6 +227,8 @@ void Controller::set_drive(std::shared_ptr<Drive> drive) {
|
|||||||
if(drive_ != drive) {
|
if(drive_ != drive) {
|
||||||
invalidate_track();
|
invalidate_track();
|
||||||
drive_ = drive;
|
drive_ = drive;
|
||||||
|
drive->set_sleep_observer(this);
|
||||||
|
update_sleep_observer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,9 @@
|
|||||||
#include "PCMSegment.hpp"
|
#include "PCMSegment.hpp"
|
||||||
#include "PCMPatchedTrack.hpp"
|
#include "PCMPatchedTrack.hpp"
|
||||||
#include "../TimedEventLoop.hpp"
|
#include "../TimedEventLoop.hpp"
|
||||||
|
|
||||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||||
|
#include "../../ClockReceiver/Sleeper.hpp"
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Disk {
|
namespace Disk {
|
||||||
@ -28,7 +30,7 @@ namespace Disk {
|
|||||||
|
|
||||||
TODO: communication of head size and permissible stepping extents, appropriate simulation of gain.
|
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:
|
protected:
|
||||||
/*!
|
/*!
|
||||||
Constructs a @c DiskDrive that will be run at @c clock_rate and runs its PLL at @c clock_rate*clock_rate_multiplier,
|
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();
|
virtual bool get_drive_is_ready();
|
||||||
bool get_drive_is_read_only();
|
bool get_drive_is_read_only();
|
||||||
|
|
||||||
|
bool is_sleeping();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Time bit_length_;
|
Time bit_length_;
|
||||||
int clock_rate_;
|
int clock_rate_;
|
||||||
@ -142,6 +146,8 @@ class Controller: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop
|
|||||||
|
|
||||||
void setup_track();
|
void setup_track();
|
||||||
Time get_time_into_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;
|
disk_ = disk;
|
||||||
track_ = nullptr;
|
track_ = nullptr;
|
||||||
has_disk_ = !!disk_;
|
has_disk_ = !!disk_;
|
||||||
|
update_sleep_observer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Drive::set_disk_with_track(const std::shared_ptr<Track> &track) {
|
void Drive::set_disk_with_track(const std::shared_ptr<Track> &track) {
|
||||||
disk_ = nullptr;
|
disk_ = nullptr;
|
||||||
track_ = track;
|
track_ = track;
|
||||||
has_disk_ = !!track_;
|
has_disk_ = !!track_;
|
||||||
|
update_sleep_observer();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Drive::has_disk() {
|
bool Drive::has_disk() {
|
||||||
return has_disk_;
|
return has_disk_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Drive::is_sleeping() {
|
||||||
|
return !has_disk_;
|
||||||
|
}
|
||||||
|
|
||||||
bool Drive::get_is_track_zero() {
|
bool Drive::get_is_track_zero() {
|
||||||
return head_position_ == 0;
|
return head_position_ == 0;
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,14 @@
|
|||||||
#define Drive_hpp
|
#define Drive_hpp
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "Disk.hpp"
|
#include "Disk.hpp"
|
||||||
|
#include "../../ClockReceiver/Sleeper.hpp"
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Disk {
|
namespace Disk {
|
||||||
|
|
||||||
class Drive {
|
class Drive: public Sleeper {
|
||||||
public:
|
public:
|
||||||
Drive();
|
Drive();
|
||||||
|
|
||||||
@ -70,6 +72,9 @@ class Drive {
|
|||||||
*/
|
*/
|
||||||
bool get_is_ready();
|
bool get_is_ready();
|
||||||
|
|
||||||
|
// As per Sleeper.
|
||||||
|
bool is_sleeping();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Track> track_;
|
std::shared_ptr<Track> track_;
|
||||||
std::shared_ptr<Disk> disk_;
|
std::shared_ptr<Disk> disk_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user