mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Introduces a track to segment decoder.
This will be needed to make formats like G64 and HFE writeable, but probably also will be usable to speed up static analysis.
This commit is contained in:
parent
a295b42497
commit
f789ee4ff0
@ -680,6 +680,7 @@
|
||||
4B8805FA1DCFF807003085B1 /* Oric.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Oric.hpp; path = Parsers/Oric.hpp; sourceTree = "<group>"; };
|
||||
4B8805FC1DD02552003085B1 /* Tape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Tape.cpp; path = ../../StaticAnalyser/Oric/Tape.cpp; sourceTree = "<group>"; };
|
||||
4B8805FD1DD02552003085B1 /* Tape.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Tape.hpp; path = ../../StaticAnalyser/Oric/Tape.hpp; sourceTree = "<group>"; };
|
||||
4B8D287E1F77207100645199 /* TrackSerialiser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TrackSerialiser.hpp; sourceTree = "<group>"; };
|
||||
4B8E4ECD1DCE483D003716C3 /* KeyboardMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = KeyboardMachine.hpp; sourceTree = "<group>"; };
|
||||
4B8FE2141DA19D5F0090D3CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/Atari2600Options.xib"; sourceTree = SOURCE_ROOT; };
|
||||
4B8FE2161DA19D5F0090D3CE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/MachineDocument.xib"; sourceTree = SOURCE_ROOT; };
|
||||
@ -1415,6 +1416,7 @@
|
||||
4B4518771F75E91800926311 /* UnformattedTrack.cpp */,
|
||||
4B4518781F75E91800926311 /* UnformattedTrack.hpp */,
|
||||
4B4518881F75ECB100926311 /* Track.hpp */,
|
||||
4B8D287E1F77207100645199 /* TrackSerialiser.hpp */,
|
||||
);
|
||||
path = Track;
|
||||
sourceTree = "<group>";
|
||||
|
71
Storage/Disk/Track/TrackSerialiser.hpp
Normal file
71
Storage/Disk/Track/TrackSerialiser.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
//
|
||||
// TrackSerialiser.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 23/09/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef TrackSerialiser_h
|
||||
#define TrackSerialiser_h
|
||||
|
||||
#include "../DPLL/DigitalPhaseLockedLoop.hpp"
|
||||
|
||||
namespace Storage {
|
||||
namespace Disk {
|
||||
|
||||
/*!
|
||||
Instantiates a PLL with a target bit length of @c length_of_a_bit and provides a complete
|
||||
serialisation of @c track, starting from the index hole.
|
||||
|
||||
This feature is offered for the benefit of various parts of the code that need to make
|
||||
sense of a track **other than emulation**, as it renders a one-off image of the track,
|
||||
which can be inaccurate. However there are many occasions where a single rendering is
|
||||
desireable — e.g. file formats that apply that constraint, or static analysis prior to
|
||||
emulation launch, which works with broad strokes.
|
||||
|
||||
@param track The track to serialise.
|
||||
@param length_of_a_bit The expected length of a single bit, as a proportion of the
|
||||
track length.
|
||||
*/
|
||||
template <typename T> PCMSegment track_serialisation(T &track, Time length_of_a_bit) {
|
||||
DigitalPhaseLockedLoop pll(100, 16);
|
||||
|
||||
struct ResultAccumulator: public DigitalPhaseLockedLoop::Delegate {
|
||||
PCMSegment result;
|
||||
void digital_phase_locked_loop_output_bit(int value) {
|
||||
result.data.resize(1 + (result.number_of_bits >> 3));
|
||||
if(value) result.data[result.number_of_bits >> 3] |= 0x80 >> (result.number_of_bits & 7);
|
||||
result.number_of_bits++;
|
||||
}
|
||||
} result_accumulator;
|
||||
pll.set_delegate(&result_accumulator);
|
||||
result_accumulator.result.number_of_bits = 0;
|
||||
result_accumulator.result.length_of_a_bit = length_of_a_bit;
|
||||
|
||||
Time length_multiplier = Time(100*length_of_a_bit.clock_rate, length_of_a_bit.length);
|
||||
length_multiplier.simplify();
|
||||
|
||||
// start at the index hole
|
||||
track.seek_to(Time(0));
|
||||
|
||||
// grab events until the next index hole
|
||||
Time time_error = Time(0);
|
||||
while(true) {
|
||||
Track::Event next_event = track.get_next_event();
|
||||
if(next_event.type == Track::Event::IndexHole) break;
|
||||
|
||||
Time extended_length = next_event.length * length_multiplier + time_error;
|
||||
time_error.clock_rate = extended_length.clock_rate;
|
||||
time_error.length = extended_length.length % extended_length.clock_rate;
|
||||
pll.run_for(Cycles((int)extended_length.get_unsigned_int()));
|
||||
pll.add_pulse();
|
||||
}
|
||||
|
||||
return result_accumulator.result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* TrackSerialiser_h */
|
Loading…
Reference in New Issue
Block a user