mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-05 10:28:58 +00:00
Implemented better sync-to-zero and discovered a header counting bug plus, probably, a misleading representation of gaps in the Oric TAP decoder.
This commit is contained in:
parent
80702616ea
commit
c257e7f58d
@ -49,7 +49,7 @@ std::list<File> StaticAnalyser::Oric::GetFiles(const std::shared_ptr<Storage::Ta
|
|||||||
}
|
}
|
||||||
switch(parser.get_next_byte(tape, is_fast))
|
switch(parser.get_next_byte(tape, is_fast))
|
||||||
{
|
{
|
||||||
case 0x80: new_file.launch_type = File::ProgramType::BASIC; break;
|
case 0x80: new_file.launch_type = File::ProgramType::BASIC; break;
|
||||||
case 0xc7: new_file.launch_type = File::ProgramType::MachineCode; break;
|
case 0xc7: new_file.launch_type = File::ProgramType::MachineCode; break;
|
||||||
default: new_file.launch_type = File::ProgramType::None; break;
|
default: new_file.launch_type = File::ProgramType::None; break;
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ std::list<File> StaticAnalyser::Oric::GetFiles(const std::shared_ptr<Storage::Ta
|
|||||||
new_file.starting_address = (uint16_t)(parser.get_next_byte(tape, is_fast) << 8);
|
new_file.starting_address = (uint16_t)(parser.get_next_byte(tape, is_fast) << 8);
|
||||||
new_file.starting_address |= (uint16_t)parser.get_next_byte(tape, is_fast);
|
new_file.starting_address |= (uint16_t)parser.get_next_byte(tape, is_fast);
|
||||||
|
|
||||||
// skip an empty bytes
|
// skip an empty byte
|
||||||
parser.get_next_byte(tape, is_fast);
|
parser.get_next_byte(tape, is_fast);
|
||||||
|
|
||||||
// read file name, up to 16 characters and null terminated
|
// read file name, up to 16 characters and null terminated
|
||||||
|
@ -93,11 +93,11 @@ Tape::Pulse OricTAP::virtual_get_next_pulse()
|
|||||||
if(_phase_counter == 6) _data_start_address = (uint16_t)(next_byte << 8);
|
if(_phase_counter == 6) _data_start_address = (uint16_t)(next_byte << 8);
|
||||||
if(_phase_counter == 7) _data_start_address |= next_byte;
|
if(_phase_counter == 7) _data_start_address |= next_byte;
|
||||||
|
|
||||||
_phase_counter++;
|
|
||||||
if(_phase_counter >= 9 && !next_byte) // advance after the filename-ending NULL byte
|
if(_phase_counter >= 9 && !next_byte) // advance after the filename-ending NULL byte
|
||||||
{
|
{
|
||||||
_next_phase = Gap;
|
_next_phase = Gap;
|
||||||
}
|
}
|
||||||
|
_phase_counter++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Gap:
|
case Gap:
|
||||||
@ -151,7 +151,7 @@ Tape::Pulse OricTAP::virtual_get_next_pulse()
|
|||||||
|
|
||||||
case Gap:
|
case Gap:
|
||||||
_bit_count = 13;
|
_bit_count = 13;
|
||||||
pulse.type = Pulse::Zero;
|
pulse.type = (_phase_counter&1) ? Pulse::Low : Pulse::High;
|
||||||
pulse.length.length = 100;
|
pulse.length.length = 100;
|
||||||
return pulse;
|
return pulse;
|
||||||
|
|
||||||
|
@ -12,20 +12,21 @@ using namespace Storage::Tape::Oric;
|
|||||||
|
|
||||||
int Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, bool use_fast_encoding)
|
int Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, bool use_fast_encoding)
|
||||||
{
|
{
|
||||||
_detection_mode = use_fast_encoding ? FastData : SlowData;
|
_detection_mode = use_fast_encoding ? FastZero : SlowZero;
|
||||||
_cycle_length = 0.0f;
|
_cycle_length = 0.0f;
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int bit_count = 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);
|
SymbolType symbol = get_next_symbol(tape);
|
||||||
if(!bit_count && symbol != SymbolType::Zero) continue;
|
if(!bit_count && symbol != SymbolType::Zero) continue;
|
||||||
|
_detection_mode = use_fast_encoding ? FastData : SlowData;
|
||||||
result |= ((symbol == SymbolType::One) ? 1 : 0) << bit_count;
|
result |= ((symbol == SymbolType::One) ? 1 : 0) << bit_count;
|
||||||
bit_count++;
|
bit_count++;
|
||||||
}
|
}
|
||||||
// TODO: check parity?
|
// 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<Storage::Tape::Tape> &tape)
|
bool Parser::sync_and_get_encoding_speed(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||||
@ -49,15 +50,15 @@ void Parser::process_pulse(Storage::Tape::Tape::Pulse pulse)
|
|||||||
const float length_threshold = 0.0003125f;
|
const float length_threshold = 0.0003125f;
|
||||||
|
|
||||||
bool wave_is_high = pulse.type == Storage::Tape::Tape::Pulse::High;
|
bool wave_is_high = pulse.type == Storage::Tape::Tape::Pulse::High;
|
||||||
bool did_change = (wave_is_high != _wave_was_high && _cycle_length > 0.0f);
|
if(wave_is_high != _wave_was_high && _cycle_length > 0.0f)
|
||||||
_wave_was_high = wave_is_high;
|
|
||||||
if(did_change)
|
|
||||||
{
|
{
|
||||||
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);
|
else push_wave(_cycle_length < length_threshold ? WaveType::Short : WaveType::Long);
|
||||||
|
|
||||||
_cycle_length = 0.0f;
|
_cycle_length = 0.0f;
|
||||||
}
|
}
|
||||||
|
_wave_was_high = wave_is_high;
|
||||||
_cycle_length += pulse.length.get_float();
|
_cycle_length += pulse.length.get_float();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +66,15 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
|||||||
{
|
{
|
||||||
switch(_detection_mode)
|
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:
|
case FastData:
|
||||||
if(waves.size() < 2) return;
|
if(waves.size() < 2) return;
|
||||||
if(waves[0] == WaveType::Short && waves[1] != WaveType::Unrecognised)
|
if(waves[0] == WaveType::Short && waves[1] != WaveType::Unrecognised)
|
||||||
@ -74,6 +84,18 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case SlowData:
|
||||||
#define CHECK_RUN(length, type, symbol) \
|
#define CHECK_RUN(length, type, symbol) \
|
||||||
if(waves.size() >= length)\
|
if(waves.size() >= length)\
|
||||||
|
@ -35,6 +35,8 @@ class Parser: public Storage::Tape::Parser<WaveType, SymbolType> {
|
|||||||
enum DetectionMode {
|
enum DetectionMode {
|
||||||
FastData,
|
FastData,
|
||||||
SlowData,
|
SlowData,
|
||||||
|
FastZero,
|
||||||
|
SlowZero,
|
||||||
Sync
|
Sync
|
||||||
} _detection_mode;
|
} _detection_mode;
|
||||||
bool _wave_was_high;
|
bool _wave_was_high;
|
||||||
|
Loading…
Reference in New Issue
Block a user