1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-29 12:50:28 +00:00

Took some small steps towards having a disk drive that at least can select a track and pump relevant events into a PLL.

This commit is contained in:
Thomas Harte 2016-07-29 07:31:02 -04:00
parent 0e581c7607
commit f984de42a3
3 changed files with 74 additions and 18 deletions

View File

@ -13,17 +13,21 @@ using namespace Storage;
DiskDrive::DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute) : DiskDrive::DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute) :
_clock_rate(clock_rate), _clock_rate(clock_rate),
_revolutions_per_minute(revolutions_per_minute), _revolutions_per_minute(revolutions_per_minute),
_head_position(0) {} _head_position(0),
TimedEventLoop(clock_rate)
{}
void DiskDrive::set_expected_bit_length(Time bit_length) void DiskDrive::set_expected_bit_length(Time bit_length)
{ {
_bit_length = bit_length; _bit_length = bit_length;
// _pll.reset(new DigitalPhaseLockedLoop();
} }
void DiskDrive::set_disk(std::shared_ptr<Disk> disk) void DiskDrive::set_disk(std::shared_ptr<Disk> disk)
{ {
_disk = disk; _disk = disk;
// _track.reset(); set_track();
} }
bool DiskDrive::has_disk() bool DiskDrive::has_disk()
@ -39,21 +43,65 @@ bool DiskDrive::get_is_track_zero()
void DiskDrive::step(int direction) void DiskDrive::step(int direction)
{ {
_head_position = std::max(_head_position + direction, 0); _head_position = std::max(_head_position + direction, 0);
_track = _disk->get_track_at_position((unsigned int)_head_position); set_track();
} }
void DiskDrive::digital_phase_locked_loop_output_bit(int value) void DiskDrive::set_track()
{ {
process_input_bit(value, _cycles_since_index_hole); _track = _disk->get_track_at_position((unsigned int)_head_position);
reset_timer();
get_next_event();
} }
void DiskDrive::run_for_cycles(unsigned int number_of_cycles) void DiskDrive::run_for_cycles(unsigned int number_of_cycles)
{ {
if(has_disk()) if(has_disk())
{ {
while(number_of_cycles--) _cycles_since_index_hole += number_of_cycles;
{ TimedEventLoop::run_for_cycles(number_of_cycles);
}
}
#pragma mark - Track timed event loop
void DiskDrive::get_next_event()
{
if(_track)
_current_event = _track->get_next_event();
else
{
_current_event.length.length = 1;
_current_event.length.clock_rate = 1;
_current_event.type = Track::Event::IndexHole;
} }
// divide interval, which is in terms of a rotation of the disk, by rotation speed, and
// convert it into revolutions per second
Time event_interval = _current_event.length;
event_interval.length *= 60;
event_interval.clock_rate *= _revolutions_per_minute;
event_interval.simplify();
set_next_event_time_interval(event_interval);
} }
void DiskDrive::process_next_event()
{
switch(_current_event.type)
{
case Track::Event::FluxTransition:
_pll->add_pulse();
break;
case Track::Event::IndexHole:
_cycles_since_index_hole = 0;
process_index_hole();
break;
}
get_next_event();
}
#pragma mark - PLL delegate
void DiskDrive::digital_phase_locked_loop_output_bit(int value)
{
process_input_bit(value, _cycles_since_index_hole);
} }

View File

@ -11,11 +11,11 @@
#include "Disk.hpp" #include "Disk.hpp"
#include "DigitalPhaseLockedLoop.hpp" #include "DigitalPhaseLockedLoop.hpp"
#include "../../SignalProcessing/Stepper.hpp" #include "../TimedEventLoop.hpp"
namespace Storage { namespace Storage {
class DiskDrive: public DigitalPhaseLockedLoop::Delegate { class DiskDrive: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop {
public: public:
DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute); DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute);
@ -37,6 +37,9 @@ class DiskDrive: public DigitalPhaseLockedLoop::Delegate {
virtual void process_input_bit(int value, unsigned int cycles_since_index_hole) = 0; virtual void process_input_bit(int value, unsigned int cycles_since_index_hole) = 0;
virtual void process_index_hole() = 0; virtual void process_index_hole() = 0;
// for TimedEventLoop
virtual void process_next_event();
private: private:
Time _bit_length; Time _bit_length;
unsigned int _clock_rate; unsigned int _clock_rate;
@ -47,14 +50,10 @@ class DiskDrive: public DigitalPhaseLockedLoop::Delegate {
std::shared_ptr<Track> _track; std::shared_ptr<Track> _track;
int _head_position; int _head_position;
unsigned int _cycles_since_index_hole; unsigned int _cycles_since_index_hole;
void set_track();
void install_track(); inline void get_next_event();
Track::Event _current_event;
struct {
Track::Event current_event;
std::unique_ptr<SignalProcessing::Stepper> pulse_stepper;
uint32_t time_into_pulse;
} _input;
}; };
} }

View File

@ -9,10 +9,19 @@
#ifndef Storage_hpp #ifndef Storage_hpp
#define Storage_hpp #define Storage_hpp
#include "../NumberTheory/Factors.hpp"
namespace Storage { namespace Storage {
struct Time { struct Time {
unsigned int length, clock_rate; unsigned int length, clock_rate;
inline void simplify()
{
unsigned int common_divisor = NumberTheory::greatest_common_divisor(length, clock_rate);
length /= common_divisor;
clock_rate /= common_divisor;
}
}; };
} }