mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-22 12:33:29 +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:
parent
0e581c7607
commit
f984de42a3
@ -13,17 +13,21 @@ using namespace Storage;
|
||||
DiskDrive::DiskDrive(unsigned int clock_rate, unsigned int revolutions_per_minute) :
|
||||
_clock_rate(clock_rate),
|
||||
_revolutions_per_minute(revolutions_per_minute),
|
||||
_head_position(0) {}
|
||||
_head_position(0),
|
||||
|
||||
TimedEventLoop(clock_rate)
|
||||
{}
|
||||
|
||||
void DiskDrive::set_expected_bit_length(Time bit_length)
|
||||
{
|
||||
_bit_length = bit_length;
|
||||
// _pll.reset(new DigitalPhaseLockedLoop();
|
||||
}
|
||||
|
||||
void DiskDrive::set_disk(std::shared_ptr<Disk> disk)
|
||||
{
|
||||
_disk = disk;
|
||||
// _track.reset();
|
||||
set_track();
|
||||
}
|
||||
|
||||
bool DiskDrive::has_disk()
|
||||
@ -39,21 +43,65 @@ bool DiskDrive::get_is_track_zero()
|
||||
void DiskDrive::step(int direction)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -11,11 +11,11 @@
|
||||
|
||||
#include "Disk.hpp"
|
||||
#include "DigitalPhaseLockedLoop.hpp"
|
||||
#include "../../SignalProcessing/Stepper.hpp"
|
||||
#include "../TimedEventLoop.hpp"
|
||||
|
||||
namespace Storage {
|
||||
|
||||
class DiskDrive: public DigitalPhaseLockedLoop::Delegate {
|
||||
class DiskDrive: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop {
|
||||
public:
|
||||
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_index_hole() = 0;
|
||||
|
||||
// for TimedEventLoop
|
||||
virtual void process_next_event();
|
||||
|
||||
private:
|
||||
Time _bit_length;
|
||||
unsigned int _clock_rate;
|
||||
@ -47,14 +50,10 @@ class DiskDrive: public DigitalPhaseLockedLoop::Delegate {
|
||||
std::shared_ptr<Track> _track;
|
||||
int _head_position;
|
||||
unsigned int _cycles_since_index_hole;
|
||||
void set_track();
|
||||
|
||||
void install_track();
|
||||
|
||||
struct {
|
||||
Track::Event current_event;
|
||||
std::unique_ptr<SignalProcessing::Stepper> pulse_stepper;
|
||||
uint32_t time_into_pulse;
|
||||
} _input;
|
||||
inline void get_next_event();
|
||||
Track::Event _current_event;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -9,10 +9,19 @@
|
||||
#ifndef Storage_hpp
|
||||
#define Storage_hpp
|
||||
|
||||
#include "../NumberTheory/Factors.hpp"
|
||||
|
||||
namespace Storage {
|
||||
|
||||
struct Time {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user