From c257e7f58d51e64dd68d61eec1d2f23c9776296b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 7 Nov 2016 20:17:06 -0500 Subject: [PATCH] Implemented better sync-to-zero and discovered a header counting bug plus, probably, a misleading representation of gaps in the Oric TAP decoder. --- StaticAnalyser/Oric/Tape.cpp | 4 ++-- Storage/Tape/Formats/OricTAP.cpp | 4 ++-- Storage/Tape/Parsers/Oric.cpp | 36 +++++++++++++++++++++++++------- Storage/Tape/Parsers/Oric.hpp | 2 ++ 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/StaticAnalyser/Oric/Tape.cpp b/StaticAnalyser/Oric/Tape.cpp index 17662734f..155103e29 100644 --- a/StaticAnalyser/Oric/Tape.cpp +++ b/StaticAnalyser/Oric/Tape.cpp @@ -49,7 +49,7 @@ std::list StaticAnalyser::Oric::GetFiles(const std::shared_ptr StaticAnalyser::Oric::GetFiles(const std::shared_ptr= 9 && !next_byte) // advance after the filename-ending NULL byte { _next_phase = Gap; } + _phase_counter++; break; case Gap: @@ -151,7 +151,7 @@ Tape::Pulse OricTAP::virtual_get_next_pulse() case Gap: _bit_count = 13; - pulse.type = Pulse::Zero; + pulse.type = (_phase_counter&1) ? Pulse::Low : Pulse::High; pulse.length.length = 100; return pulse; diff --git a/Storage/Tape/Parsers/Oric.cpp b/Storage/Tape/Parsers/Oric.cpp index aa055794c..1995c11f0 100644 --- a/Storage/Tape/Parsers/Oric.cpp +++ b/Storage/Tape/Parsers/Oric.cpp @@ -12,20 +12,21 @@ using namespace Storage::Tape::Oric; int Parser::get_next_byte(const std::shared_ptr &tape, bool use_fast_encoding) { - _detection_mode = use_fast_encoding ? FastData : SlowData; + _detection_mode = use_fast_encoding ? FastZero : SlowZero; _cycle_length = 0.0f; int result = 0; int bit_count = 0; - while(bit_count < 10 && !tape->is_at_end()) + while(bit_count < 11 && !tape->is_at_end()) { SymbolType symbol = get_next_symbol(tape); if(!bit_count && symbol != SymbolType::Zero) continue; + _detection_mode = use_fast_encoding ? FastData : SlowData; result |= ((symbol == SymbolType::One) ? 1 : 0) << bit_count; bit_count++; } // TODO: check parity? - return tape->is_at_end() ? -1 : (result&0xff); + return tape->is_at_end() ? -1 : ((result >> 1)&0xff); } bool Parser::sync_and_get_encoding_speed(const std::shared_ptr &tape) @@ -49,15 +50,15 @@ void Parser::process_pulse(Storage::Tape::Tape::Pulse pulse) const float length_threshold = 0.0003125f; bool wave_is_high = pulse.type == Storage::Tape::Tape::Pulse::High; - bool did_change = (wave_is_high != _wave_was_high && _cycle_length > 0.0f); - _wave_was_high = wave_is_high; - if(did_change) + if(wave_is_high != _wave_was_high && _cycle_length > 0.0f) { - if(_cycle_length > 2.0 * length_threshold) push_wave(WaveType::Unrecognised); + if(_cycle_length > 2.0 * length_threshold) + push_wave(WaveType::Unrecognised); else push_wave(_cycle_length < length_threshold ? WaveType::Short : WaveType::Long); _cycle_length = 0.0f; } + _wave_was_high = wave_is_high; _cycle_length += pulse.length.get_float(); } @@ -65,6 +66,15 @@ void Parser::inspect_waves(const std::vector &waves) { switch(_detection_mode) { + case FastZero: + if(waves.size() < 2) return; + if(waves[0] == WaveType::Short && waves[1] == WaveType::Long) + { + push_symbol(SymbolType::Zero, 2); + return; + } + break; + case FastData: if(waves.size() < 2) return; if(waves[0] == WaveType::Short && waves[1] != WaveType::Unrecognised) @@ -74,6 +84,18 @@ void Parser::inspect_waves(const std::vector &waves) } break; + case SlowZero: + if(waves.size() < 8) return; + if( + waves[0] == WaveType::Long && waves[1] == WaveType::Long && waves[2] == WaveType::Long && waves[3] == WaveType::Long && + waves[4] == WaveType::Long && waves[5] == WaveType::Long && waves[6] == WaveType::Long && waves[7] == WaveType::Long + ) + { + push_symbol(SymbolType::Zero, 8); + return; + } + break; + case SlowData: #define CHECK_RUN(length, type, symbol) \ if(waves.size() >= length)\ diff --git a/Storage/Tape/Parsers/Oric.hpp b/Storage/Tape/Parsers/Oric.hpp index cb5ffe96b..f4678e3bb 100644 --- a/Storage/Tape/Parsers/Oric.hpp +++ b/Storage/Tape/Parsers/Oric.hpp @@ -35,6 +35,8 @@ class Parser: public Storage::Tape::Parser { enum DetectionMode { FastData, SlowData, + FastZero, + SlowZero, Sync } _detection_mode; bool _wave_was_high;