mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Made an attempt to consolidate what I learnt of Oric encoding while building this hastily and untidily directly into the Oric implementation.
(while adding support for the slow tape encoding mode)
This commit is contained in:
parent
353c1c8ea3
commit
d1ef2f7c63
@ -59,6 +59,7 @@
|
||||
4B8805F01DCFC99C003085B1 /* Acorn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805EE1DCFC99C003085B1 /* Acorn.cpp */; };
|
||||
4B8805F41DCFD22A003085B1 /* Commodore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F21DCFD22A003085B1 /* Commodore.cpp */; };
|
||||
4B8805F71DCFF6C9003085B1 /* Commodore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F51DCFF6C9003085B1 /* Commodore.cpp */; };
|
||||
4B8805FB1DCFF807003085B1 /* Oric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805F91DCFF807003085B1 /* Oric.cpp */; };
|
||||
4B8FE21B1DA19D5F0090D3CE /* Atari2600Options.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B8FE2131DA19D5F0090D3CE /* Atari2600Options.xib */; };
|
||||
4B8FE21C1DA19D5F0090D3CE /* MachineDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B8FE2151DA19D5F0090D3CE /* MachineDocument.xib */; };
|
||||
4B8FE21D1DA19D5F0090D3CE /* ElectronOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B8FE2171DA19D5F0090D3CE /* ElectronOptions.xib */; };
|
||||
@ -505,6 +506,8 @@
|
||||
4B8805F31DCFD22A003085B1 /* Commodore.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Commodore.hpp; path = Parsers/Commodore.hpp; sourceTree = "<group>"; };
|
||||
4B8805F51DCFF6C9003085B1 /* Commodore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Commodore.cpp; path = Data/Commodore.cpp; sourceTree = "<group>"; };
|
||||
4B8805F61DCFF6C9003085B1 /* Commodore.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Commodore.hpp; path = Data/Commodore.hpp; sourceTree = "<group>"; };
|
||||
4B8805F91DCFF807003085B1 /* Oric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Oric.cpp; path = Parsers/Oric.cpp; sourceTree = "<group>"; };
|
||||
4B8805FA1DCFF807003085B1 /* Oric.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Oric.hpp; path = Parsers/Oric.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; };
|
||||
@ -1205,6 +1208,8 @@
|
||||
4B8805EF1DCFC99C003085B1 /* Acorn.hpp */,
|
||||
4B8805F21DCFD22A003085B1 /* Commodore.cpp */,
|
||||
4B8805F31DCFD22A003085B1 /* Commodore.hpp */,
|
||||
4B8805F91DCFF807003085B1 /* Oric.cpp */,
|
||||
4B8805FA1DCFF807003085B1 /* Oric.hpp */,
|
||||
);
|
||||
name = Parsers;
|
||||
sourceTree = "<group>";
|
||||
@ -2330,6 +2335,7 @@
|
||||
4B4C83701D4F623200CD541F /* D64.cpp in Sources */,
|
||||
4B14145B1B58879D00E04248 /* CPU6502.cpp in Sources */,
|
||||
4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */,
|
||||
4B8805FB1DCFF807003085B1 /* Oric.cpp in Sources */,
|
||||
4BEE0A701D72496600532C7B /* PRG.cpp in Sources */,
|
||||
4B8FE2271DA1DE2D0090D3CE /* NSBundle+DataResource.m in Sources */,
|
||||
4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */,
|
||||
|
80
Storage/Tape/Parsers/Oric.cpp
Normal file
80
Storage/Tape/Parsers/Oric.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
//
|
||||
// Oric.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 06/11/2016.
|
||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Oric.hpp"
|
||||
|
||||
using namespace Storage::Tape::Oric;
|
||||
|
||||
int Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, bool use_fast_encoding)
|
||||
{
|
||||
_use_fast_encoding = use_fast_encoding;
|
||||
_cycle_length = 0.0f;
|
||||
|
||||
int result = 0;
|
||||
int bit_count = 0;
|
||||
while(bit_count < 10 && !tape->is_at_end())
|
||||
{
|
||||
SymbolType symbol = get_next_symbol(tape);
|
||||
if(!bit_count && symbol != SymbolType::Zero) continue;
|
||||
result |= ((symbol == SymbolType::One) ? 1 : 0) << bit_count;
|
||||
bit_count++;
|
||||
}
|
||||
// TODO: check parity
|
||||
return tape->is_at_end() ? -1 : (result >> 1);
|
||||
}
|
||||
|
||||
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);
|
||||
_cycle_length += pulse.length.get_float();
|
||||
if(did_change)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
||||
{
|
||||
if(_use_fast_encoding)
|
||||
{
|
||||
if(waves.size() < 2) return;
|
||||
if(waves[0] == WaveType::Long && waves[1] != WaveType::Unrecognised)
|
||||
{
|
||||
push_symbol((waves[1] == WaveType::Long) ? SymbolType::Zero : SymbolType::One, 2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(waves.size() < 16) return;
|
||||
#define CHECK_RUN(length, type, symbol) \
|
||||
if(waves.size() >= length)\
|
||||
{\
|
||||
size_t c;\
|
||||
for(c = 0; c < length; c++) if(waves[c] != type) break;\
|
||||
if(c == length)\
|
||||
{\
|
||||
push_symbol(symbol, 8);\
|
||||
return;\
|
||||
}\
|
||||
}
|
||||
|
||||
CHECK_RUN(8, WaveType::Long, SymbolType::Zero);
|
||||
CHECK_RUN(16, WaveType::Short, SymbolType::One);
|
||||
#undef CHECK_RUN
|
||||
}
|
||||
|
||||
remove_waves(1);
|
||||
}
|
44
Storage/Tape/Parsers/Oric.hpp
Normal file
44
Storage/Tape/Parsers/Oric.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// Oric.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 06/11/2016.
|
||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef Storage_Tape_Parsers_Oric_hpp
|
||||
#define Storage_Tape_Parsers_Oric_hpp
|
||||
|
||||
#include "TapeParser.hpp"
|
||||
|
||||
namespace Storage {
|
||||
namespace Tape {
|
||||
namespace Oric {
|
||||
|
||||
enum class WaveType {
|
||||
Short, Long, Unrecognised
|
||||
};
|
||||
|
||||
enum class SymbolType {
|
||||
One, Zero
|
||||
};
|
||||
|
||||
class Parser: public Storage::Tape::Parser<WaveType, SymbolType> {
|
||||
public:
|
||||
int get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, bool use_fast_encoding);
|
||||
|
||||
private:
|
||||
void process_pulse(Storage::Tape::Tape::Pulse pulse);
|
||||
void inspect_waves(const std::vector<WaveType> &waves);
|
||||
|
||||
bool _use_fast_encoding;
|
||||
bool _wave_was_high;
|
||||
float _cycle_length;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Oric_hpp */
|
Loading…
Reference in New Issue
Block a user