1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-01 13:58:20 +00:00

Eliminated the PLLParser class. I think the proper abstraction if and when another machine requires PLL-esque parsing is probably to template out the Acorn wiring of a PLL to a Parser, and/or generalise the Acorn shifter. It'll be easier to decide when the time comes.

This commit is contained in:
Thomas Harte 2017-07-16 19:25:26 -04:00
parent 1d3ae31755
commit c2bc34fd87

View File

@ -147,70 +147,6 @@ template <typename WaveType, typename SymbolType> class PulseClassificationParse
std::vector<WaveType> wave_queue_;
};
/**
A partly-abstract base class to help in the authorship of tape format parsers;
provides a phase-locked loop, an overridable hook for deriving when to push
bits to the PLL, a shift register populated by the PLL and a shout-out whenever
the shift register changes. Subclasses are hence intended to push symbols.
*/
template <typename SymbolType> class PLLParser:
public Storage::DigitalPhaseLockedLoop::Delegate,
public Parser<SymbolType> {
public:
/// Instantiates a new parser with the supplied @c tape.
PLLParser(int clock_rate, int clocks_per_bit) :
clock_rate_(clock_rate),
pll_(clocks_per_bit, 15),
input_bit_counter_(0),
input_pattern_(0),
was_high_(false) {
pll_.set_delegate(this);
}
protected:
/*!
The default implementation marks transitions between high and not high with
PLL-pushed bits.
*/
void process_pulse(const Storage::Tape::Tape::Pulse &pulse) {
pll_.run_for_cycles((int)((float)clock_rate_ * pulse.length.get_float()));
bool is_high = pulse.type == Storage::Tape::Tape::Pulse::High;
if(is_high != was_high_) {
pll_.add_pulse();
}
was_high_ = is_high;
}
/*!
Communicates to a subclass that a shift register shifting from left to right and
clocked by the PLL now has value @c value and its running length total is now at @c length bits.
If this function returns true then the running length total is zeroed.
So expected usage is: if there are at least enough bits available to make a meaningful
value, inspect the shifter. If the low bits of the shifter make a meaningful value,
call push_symbol and return true. Otherwise return false.
*/
virtual bool did_update_shifter(int new_value, int length) = 0;
void digital_phase_locked_loop_output_bit(int value) {
input_pattern_ = (input_pattern_ << 1) | value;
input_bit_counter_++;
if(did_update_shifter(input_pattern_, input_bit_counter_)) input_bit_counter_ = 0;
}
private:
Storage::DigitalPhaseLockedLoop pll_;
int clock_rate_;
int input_pattern_;
int input_bit_counter_;
bool was_high_;
};
}
}