1
0
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 ClockReceivers.

This commit is contained in:
Thomas Harte 2017-07-24 21:04:47 -04:00
parent b82bef95f3
commit b3ae920746
6 changed files with 22 additions and 20 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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_) {