1
0
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:
Thomas Harte 2017-08-20 11:54:54 -04:00
parent e3f2118757
commit 49285e9caa
7 changed files with 54 additions and 12 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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);
};
}

View File

@ -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;
}

View File

@ -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_;