mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-12 15:31:09 +00:00
Converted the DPLL and disk controller classes to be ClockReceiver
s.
This commit is contained in:
parent
b82bef95f3
commit
b3ae920746
@ -40,7 +40,7 @@ class DigitalPhaseLockedLoopDelegate: public Storage::DigitalPhaseLockedLoop::De
|
||||
}
|
||||
|
||||
- (void)runForCycles:(NSUInteger)cycles {
|
||||
_digitalPhaseLockedLoop->run_for_cycles((unsigned int)cycles);
|
||||
_digitalPhaseLockedLoop->run_for(Cycles((int)cycles));
|
||||
}
|
||||
|
||||
- (void)addPulse {
|
||||
|
@ -20,9 +20,9 @@ DigitalPhaseLockedLoop::DigitalPhaseLockedLoop(int clocks_per_bit, size_t length
|
||||
offset_history_(length_of_history, 0),
|
||||
offset_(0) {}
|
||||
|
||||
void DigitalPhaseLockedLoop::run_for_cycles(int number_of_cycles) {
|
||||
offset_ += number_of_cycles;
|
||||
phase_ += number_of_cycles;
|
||||
void DigitalPhaseLockedLoop::run_for(const Cycles &cycles) {
|
||||
offset_ += cycles.as_int();
|
||||
phase_ += cycles.as_int();
|
||||
if(phase_ >= window_length_) {
|
||||
int windows_crossed = phase_ / window_length_;
|
||||
|
||||
|
@ -11,10 +11,11 @@
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "../../Components/ClockReceiver.hpp"
|
||||
|
||||
namespace Storage {
|
||||
|
||||
class DigitalPhaseLockedLoop {
|
||||
class DigitalPhaseLockedLoop: public ClockReceiver<DigitalPhaseLockedLoop> {
|
||||
public:
|
||||
/*!
|
||||
Instantiates a @c DigitalPhaseLockedLoop.
|
||||
@ -29,7 +30,7 @@ class DigitalPhaseLockedLoop {
|
||||
|
||||
@c number_of_cycles The time to run the loop for.
|
||||
*/
|
||||
void run_for_cycles(int number_of_cycles);
|
||||
void run_for(const Cycles &cycles);
|
||||
|
||||
/*!
|
||||
Announces a pulse at the current time.
|
||||
|
@ -11,17 +11,17 @@
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
||||
Controller::Controller(unsigned int clock_rate, unsigned int clock_rate_multiplier, unsigned int revolutions_per_minute) :
|
||||
Controller::Controller(int clock_rate, int clock_rate_multiplier, int revolutions_per_minute) :
|
||||
clock_rate_(clock_rate * clock_rate_multiplier),
|
||||
clock_rate_multiplier_(clock_rate_multiplier),
|
||||
rotational_multiplier_(60u, revolutions_per_minute),
|
||||
rotational_multiplier_(60, revolutions_per_minute),
|
||||
|
||||
cycles_since_index_hole_(0),
|
||||
motor_is_on_(false),
|
||||
|
||||
is_reading_(true),
|
||||
|
||||
TimedEventLoop(clock_rate * clock_rate_multiplier) {
|
||||
TimedEventLoop((unsigned int)(clock_rate * clock_rate_multiplier)) {
|
||||
// seed this class with a PLL, any PLL, so that it's safe to assume non-nullptr later
|
||||
Time one(1);
|
||||
set_expected_bit_length(one);
|
||||
@ -40,13 +40,13 @@ void Controller::setup_track() {
|
||||
get_next_event(offset);
|
||||
}
|
||||
|
||||
void Controller::run_for_cycles(int number_of_cycles) {
|
||||
void Controller::run_for(const Cycles &cycles) {
|
||||
Time zero(0);
|
||||
|
||||
if(drive_ && drive_->has_disk() && motor_is_on_) {
|
||||
if(!track_) setup_track();
|
||||
|
||||
number_of_cycles *= clock_rate_multiplier_;
|
||||
int number_of_cycles = clock_rate_multiplier_ * cycles.as_int();
|
||||
while(number_of_cycles) {
|
||||
int cycles_until_next_event = (int)get_cycles_until_next_event();
|
||||
int cycles_to_run_for = std::min(cycles_until_next_event, number_of_cycles);
|
||||
@ -60,7 +60,7 @@ void Controller::run_for_cycles(int number_of_cycles) {
|
||||
|
||||
number_of_cycles -= cycles_to_run_for;
|
||||
if(is_reading_) {
|
||||
pll_->run_for_cycles(cycles_to_run_for);
|
||||
pll_->run_for(Cycles(cycles_to_run_for));
|
||||
} else {
|
||||
if(cycles_until_bits_written_ > zero) {
|
||||
Storage::Time cycles_to_run_for_time(cycles_to_run_for);
|
||||
@ -171,7 +171,7 @@ void Controller::set_expected_bit_length(Time bit_length) {
|
||||
}
|
||||
|
||||
void Controller::digital_phase_locked_loop_output_bit(int value) {
|
||||
process_input_bit(value, cycles_since_index_hole_);
|
||||
process_input_bit(value, (unsigned int)cycles_since_index_hole_);
|
||||
}
|
||||
|
||||
#pragma mark - Drive actions
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "PCMSegment.hpp"
|
||||
#include "PCMPatchedTrack.hpp"
|
||||
#include "../TimedEventLoop.hpp"
|
||||
#include "../../Components/ClockReceiver.hpp"
|
||||
|
||||
namespace Storage {
|
||||
namespace Disk {
|
||||
@ -27,13 +28,13 @@ 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 ClockReceiver<Controller>, public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop {
|
||||
protected:
|
||||
/*!
|
||||
Constructs a @c DiskDrive that will be run at @c clock_rate and runs its PLL at @c clock_rate*clock_rate_multiplier,
|
||||
spinning inserted disks at @c revolutions_per_minute.
|
||||
*/
|
||||
Controller(unsigned int clock_rate, unsigned int clock_rate_multiplier, unsigned int revolutions_per_minute);
|
||||
Controller(int clock_rate, int clock_rate_multiplier, int revolutions_per_minute);
|
||||
|
||||
/*!
|
||||
Communicates to the PLL the expected length of a bit as a fraction of a second.
|
||||
@ -43,7 +44,7 @@ class Controller: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop
|
||||
/*!
|
||||
Advances the drive by @c number_of_cycles cycles.
|
||||
*/
|
||||
void run_for_cycles(int number_of_cycles);
|
||||
void run_for(const Cycles &cycles);
|
||||
|
||||
/*!
|
||||
Sets the current drive.
|
||||
@ -113,14 +114,14 @@ class Controller: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop
|
||||
|
||||
private:
|
||||
Time bit_length_;
|
||||
unsigned int clock_rate_;
|
||||
unsigned int clock_rate_multiplier_;
|
||||
int clock_rate_;
|
||||
int clock_rate_multiplier_;
|
||||
Time rotational_multiplier_;
|
||||
|
||||
std::shared_ptr<DigitalPhaseLockedLoop> pll_;
|
||||
std::shared_ptr<Drive> drive_;
|
||||
std::shared_ptr<Track> track_;
|
||||
unsigned int cycles_since_index_hole_;
|
||||
int cycles_since_index_hole_;
|
||||
|
||||
inline void get_next_event(const Time &duration_already_passed);
|
||||
Track::Event current_event_;
|
||||
|
@ -74,7 +74,7 @@ Shifter::Shifter() :
|
||||
}
|
||||
|
||||
void Shifter::process_pulse(const Storage::Tape::Tape::Pulse &pulse) {
|
||||
pll_.run_for_cycles((int)((float)PLLClockRate * pulse.length.get_float()));
|
||||
pll_.run_for(Cycles((int)((float)PLLClockRate * pulse.length.get_float())));
|
||||
|
||||
bool is_high = pulse.type == Storage::Tape::Tape::Pulse::High;
|
||||
if(is_high != was_high_) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user