mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-25 03:32:01 +00:00
Merge pull request #148 from TomHarte/CSW
Adds support for the CSW file format
This commit is contained in:
commit
6ca712b498
@ -78,8 +78,11 @@ void Tape::process_input_pulse(Storage::Tape::Tape::Pulse pulse) {
|
||||
crossings_[3] = Tape::Unrecognised;
|
||||
if(pulse.type != Storage::Tape::Tape::Pulse::Zero) {
|
||||
float pulse_length = (float)pulse.length.length / (float)pulse.length.clock_rate;
|
||||
if(pulse_length >= 0.35 / 2400.0 && pulse_length < 0.7 / 2400.0) crossings_[3] = Tape::Short;
|
||||
if(pulse_length >= 0.35 / 1200.0 && pulse_length < 0.7 / 1200.0) crossings_[3] = Tape::Long;
|
||||
if(pulse_length >= 0.35 / 2400.0 && pulse_length < 0.7 / 1200.0) {
|
||||
crossings_[3] = pulse_length > 1.0 / 3000.0 ? Tape::Long : Tape::Short;
|
||||
}
|
||||
// if(pulse_length >= 0.35 / 2400.0 && pulse_length < 0.7 / 2400.0) crossings_[3] = Tape::Short;
|
||||
// if(pulse_length >= 0.35 / 1200.0 && pulse_length < 0.7 / 1200.0) crossings_[3] = Tape::Long;
|
||||
}
|
||||
|
||||
if(crossings_[0] == Tape::Long && crossings_[1] == Tape::Long) {
|
||||
|
@ -51,6 +51,7 @@
|
||||
4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */; };
|
||||
4B3BA0D01D318B44005DD7A7 /* MOS6532Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */; };
|
||||
4B3BA0D11D318B44005DD7A7 /* TestMachine6502.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CD1D318B44005DD7A7 /* TestMachine6502.mm */; };
|
||||
4B3BF5B01F146265005B6C36 /* CSW.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BF5AE1F146264005B6C36 /* CSW.cpp */; };
|
||||
4B3F1B461E0388D200DB26EE /* PCMPatchedTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F1B441E0388D200DB26EE /* PCMPatchedTrack.cpp */; };
|
||||
4B44EBF51DC987AF00A7820C /* AllSuiteA.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */; };
|
||||
4B44EBF71DC9883B00A7820C /* 6502_functional_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4B44EBF61DC9883B00A7820C /* 6502_functional_test.bin */; };
|
||||
@ -539,6 +540,8 @@
|
||||
4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MOS6532Bridge.mm; sourceTree = "<group>"; };
|
||||
4B3BA0CC1D318B44005DD7A7 /* TestMachine6502.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestMachine6502.h; sourceTree = "<group>"; };
|
||||
4B3BA0CD1D318B44005DD7A7 /* TestMachine6502.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestMachine6502.mm; sourceTree = "<group>"; };
|
||||
4B3BF5AE1F146264005B6C36 /* CSW.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSW.cpp; sourceTree = "<group>"; };
|
||||
4B3BF5AF1F146264005B6C36 /* CSW.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CSW.hpp; sourceTree = "<group>"; };
|
||||
4B3F1B441E0388D200DB26EE /* PCMPatchedTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMPatchedTrack.cpp; sourceTree = "<group>"; };
|
||||
4B3F1B451E0388D200DB26EE /* PCMPatchedTrack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PCMPatchedTrack.hpp; sourceTree = "<group>"; };
|
||||
4B44EBF41DC987AE00A7820C /* AllSuiteA.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = AllSuiteA.bin; path = AllSuiteA/AllSuiteA.bin; sourceTree = "<group>"; };
|
||||
@ -1394,17 +1397,19 @@
|
||||
4B69FB411C4D941400B5F0AA /* Formats */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B69FB451C4D950F00B5F0AA /* libz.tbd */,
|
||||
4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */,
|
||||
4B69FB431C4D941400B5F0AA /* TapeUEF.hpp */,
|
||||
4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */,
|
||||
4BC91B821D1F160E00884B76 /* CommodoreTAP.hpp */,
|
||||
4B2BFC5D1D613E0200BA3AA9 /* TapePRG.cpp */,
|
||||
4B2BFC5E1D613E0200BA3AA9 /* TapePRG.hpp */,
|
||||
4B3BF5AE1F146264005B6C36 /* CSW.cpp */,
|
||||
4B59199A1DAC6C46005BB85C /* OricTAP.cpp */,
|
||||
4B59199B1DAC6C46005BB85C /* OricTAP.hpp */,
|
||||
4B2BFC5D1D613E0200BA3AA9 /* TapePRG.cpp */,
|
||||
4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */,
|
||||
4B1497861EE4A1DA00CE2596 /* ZX80O81P.cpp */,
|
||||
4BC91B821D1F160E00884B76 /* CommodoreTAP.hpp */,
|
||||
4B3BF5AF1F146264005B6C36 /* CSW.hpp */,
|
||||
4B59199B1DAC6C46005BB85C /* OricTAP.hpp */,
|
||||
4B2BFC5E1D613E0200BA3AA9 /* TapePRG.hpp */,
|
||||
4B69FB431C4D941400B5F0AA /* TapeUEF.hpp */,
|
||||
4B1497871EE4A1DA00CE2596 /* ZX80O81P.hpp */,
|
||||
4B69FB451C4D950F00B5F0AA /* libz.tbd */,
|
||||
);
|
||||
path = Formats;
|
||||
sourceTree = "<group>";
|
||||
@ -2593,6 +2598,7 @@
|
||||
4BD69F941D98760000243FE1 /* AcornADF.cpp in Sources */,
|
||||
4BBF99181C8FBA6F0075DAFB /* TextureTarget.cpp in Sources */,
|
||||
4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */,
|
||||
4B3BF5B01F146265005B6C36 /* CSW.cpp in Sources */,
|
||||
4B2A332A1DB8544D002876E3 /* MemoryFuzzer.cpp in Sources */,
|
||||
4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */,
|
||||
4B2A332F1DB86869002876E3 /* OricOptionsPanel.swift in Sources */,
|
||||
|
@ -141,6 +141,8 @@
|
||||
<string>Electron/BBC Disk Image</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
<key>NSDocumentClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).MachineDocument</string>
|
||||
</dict>
|
||||
@ -155,6 +157,8 @@
|
||||
<string>Disk Image</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
<key>NSDocumentClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).MachineDocument</string>
|
||||
</dict>
|
||||
@ -170,6 +174,8 @@
|
||||
<string>ZX80 Tape Image</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
<key>NSDocumentClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).MachineDocument</string>
|
||||
</dict>
|
||||
@ -185,6 +191,24 @@
|
||||
<string>ZX81 Tape Image</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
<key>NSDocumentClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).MachineDocument</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>csw</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>cassette</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Tape Image</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
<key>NSDocumentClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).MachineDocument</string>
|
||||
</dict>
|
||||
|
@ -75,6 +75,7 @@ void StaticAnalyser::Acorn::AddTargets(
|
||||
if(tapes.size() > 0) {
|
||||
std::shared_ptr<Storage::Tape::Tape> tape = tapes.front();
|
||||
std::list<File> files = GetFiles(tape);
|
||||
tape->reset();
|
||||
|
||||
// continue if there are any files
|
||||
if(files.size()) {
|
||||
|
@ -60,6 +60,8 @@ static std::unique_ptr<File::Chunk> GetNextChunk(const std::shared_ptr<Storage::
|
||||
stored_header_crc = (uint16_t)((stored_header_crc >> 8) | (stored_header_crc << 8));
|
||||
new_chunk->header_crc_matched = stored_header_crc == calculated_header_crc;
|
||||
|
||||
if(!new_chunk->header_crc_matched) return nullptr;
|
||||
|
||||
parser.reset_crc();
|
||||
new_chunk->data.reserve(new_chunk->block_length);
|
||||
for(int c = 0; c < new_chunk->block_length; c++) {
|
||||
|
@ -68,6 +68,7 @@ void StaticAnalyser::Commodore::AddTargets(
|
||||
// check tapes
|
||||
for(auto &tape : tapes) {
|
||||
std::list<File> tape_files = GetFiles(tape);
|
||||
tape->reset();
|
||||
if(tape_files.size()) {
|
||||
files.splice(files.end(), tape_files);
|
||||
target.tapes = tapes;
|
||||
|
@ -84,8 +84,9 @@ void StaticAnalyser::Oric::AddTargets(
|
||||
int basic10_votes = 0;
|
||||
int basic11_votes = 0;
|
||||
|
||||
for(auto tape : tapes) {
|
||||
for(auto &tape : tapes) {
|
||||
std::list<File> tape_files = GetFiles(tape);
|
||||
tape->reset();
|
||||
if(tape_files.size()) {
|
||||
for(auto file : tape_files) {
|
||||
if(file.data_type == File::MachineCode) {
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
// Tapes
|
||||
#include "../Storage/Tape/Formats/CommodoreTAP.hpp"
|
||||
#include "../Storage/Tape/Formats/CSW.hpp"
|
||||
#include "../Storage/Tape/Formats/OricTAP.hpp"
|
||||
#include "../Storage/Tape/Formats/TapePRG.hpp"
|
||||
#include "../Storage/Tape/Formats/TapeUEF.hpp"
|
||||
@ -42,6 +43,8 @@ enum class TargetPlatform: TargetPlatformType {
|
||||
Commodore = 1 << 2,
|
||||
Oric = 1 << 3,
|
||||
ZX8081 = 1 << 4,
|
||||
|
||||
AllTape = Acorn | Commodore | Oric | ZX8081,
|
||||
};
|
||||
|
||||
using namespace StaticAnalyser;
|
||||
@ -94,6 +97,7 @@ std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
|
||||
Format("a26", cartridges, Cartridge::BinaryDump, TargetPlatform::Atari2600) // A26
|
||||
Format("adf", disks, Disk::AcornADF, TargetPlatform::Acorn) // ADF
|
||||
Format("bin", cartridges, Cartridge::BinaryDump, TargetPlatform::Atari2600) // BIN
|
||||
Format("csw", tapes, Tape::CSW, TargetPlatform::AllTape) // CSW
|
||||
Format("d64", disks, Disk::D64, TargetPlatform::Commodore) // D64
|
||||
Format("dsd", disks, Disk::SSD, TargetPlatform::Acorn) // DSD
|
||||
Format("dsk", disks, Disk::OricMFMDSK, TargetPlatform::Oric) // DSK
|
||||
|
@ -35,6 +35,7 @@ void StaticAnalyser::ZX8081::AddTargets(
|
||||
|
||||
if(!tapes.empty()) {
|
||||
std::vector<Storage::Data::ZX8081::File> files = GetFiles(tapes.front());
|
||||
tapes.front()->reset();
|
||||
if(!files.empty()) {
|
||||
StaticAnalyser::Target target;
|
||||
target.machine = Target::ZX8081;
|
||||
|
@ -51,7 +51,7 @@ static std::shared_ptr<File> ZX81FileFromData(const std::vector<uint8_t> &data)
|
||||
// Look for a file name.
|
||||
size_t data_pointer = 0;
|
||||
int c = 11;
|
||||
while(c--) {
|
||||
while(c < data.size() && c--) {
|
||||
if(data[data_pointer] & 0x80) break;
|
||||
data_pointer++;
|
||||
}
|
||||
|
130
Storage/Tape/Formats/CSW.cpp
Normal file
130
Storage/Tape/Formats/CSW.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
//
|
||||
// CSW.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 10/07/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "CSW.hpp"
|
||||
|
||||
using namespace Storage::Tape;
|
||||
|
||||
CSW::CSW(const char *file_name) :
|
||||
Storage::FileHolder(file_name),
|
||||
source_data_pointer_(0) {
|
||||
if(file_stats_.st_size < 0x20) throw ErrorNotCSW;
|
||||
|
||||
// Check signature.
|
||||
char identifier[22];
|
||||
char signature[] = "Compressed Square Wave";
|
||||
fread(identifier, 1, 22, file_);
|
||||
if(memcmp(identifier, signature, strlen(signature))) throw ErrorNotCSW;
|
||||
|
||||
// Check terminating byte.
|
||||
if(fgetc(file_) != 0x1a) throw ErrorNotCSW;
|
||||
|
||||
// Get version file number.
|
||||
uint8_t major_version = (uint8_t)fgetc(file_);
|
||||
uint8_t minor_version = (uint8_t)fgetc(file_);
|
||||
|
||||
// Reject if this is an unknown version.
|
||||
if(major_version > 2 || !major_version || minor_version > 1) throw ErrorNotCSW;
|
||||
|
||||
// The header now diverges based on version.
|
||||
uint32_t number_of_waves = 0;
|
||||
if(major_version == 1) {
|
||||
pulse_.length.clock_rate = fgetc16le();
|
||||
|
||||
if(fgetc(file_) != 1) throw ErrorNotCSW;
|
||||
compression_type_ = RLE;
|
||||
|
||||
pulse_.type = (fgetc(file_) & 1) ? Pulse::High : Pulse::Low;
|
||||
|
||||
fseek(file_, 0x20, SEEK_SET);
|
||||
} else {
|
||||
pulse_.length.clock_rate = fgetc32le();
|
||||
number_of_waves = fgetc32le();
|
||||
switch(fgetc(file_)) {
|
||||
case 1: compression_type_ = RLE; break;
|
||||
case 2: compression_type_ = ZRLE; break;
|
||||
default: throw ErrorNotCSW;
|
||||
}
|
||||
|
||||
pulse_.type = (fgetc(file_) & 1) ? Pulse::High : Pulse::Low;
|
||||
uint8_t extension_length = (uint8_t)fgetc(file_);
|
||||
|
||||
if(file_stats_.st_size < 0x34 + extension_length) throw ErrorNotCSW;
|
||||
fseek(file_, 0x34 + extension_length, SEEK_SET);
|
||||
}
|
||||
|
||||
if(compression_type_ == ZRLE) {
|
||||
source_data_.resize((size_t)number_of_waves);
|
||||
|
||||
std::vector<uint8_t> file_data;
|
||||
size_t remaining_data = (size_t)file_stats_.st_size - (size_t)ftell(file_);
|
||||
file_data.resize(remaining_data);
|
||||
fread(file_data.data(), sizeof(uint8_t), remaining_data, file_);
|
||||
|
||||
uLongf output_length = (uLongf)number_of_waves;
|
||||
uncompress(source_data_.data(), &output_length, file_data.data(), file_data.size());
|
||||
source_data_.resize((size_t)output_length);
|
||||
} else {
|
||||
rle_start_ = ftell(file_);
|
||||
}
|
||||
|
||||
invert_pulse();
|
||||
}
|
||||
|
||||
uint8_t CSW::get_next_byte() {
|
||||
switch(compression_type_) {
|
||||
case RLE: return (uint8_t)fgetc(file_);
|
||||
case ZRLE: {
|
||||
if(source_data_pointer_ == source_data_.size()) return 0xff;
|
||||
uint8_t result = source_data_[source_data_pointer_];
|
||||
source_data_pointer_++;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CSW::get_next_int32le() {
|
||||
switch(compression_type_) {
|
||||
case RLE: return fgetc32le();
|
||||
case ZRLE: {
|
||||
if(source_data_pointer_ > source_data_.size() - 4) return 0xffff;
|
||||
uint32_t result = (uint32_t)(
|
||||
(source_data_[source_data_pointer_ + 0] << 0) |
|
||||
(source_data_[source_data_pointer_ + 1] << 8) |
|
||||
(source_data_[source_data_pointer_ + 2] << 16) |
|
||||
(source_data_[source_data_pointer_ + 3] << 24));
|
||||
source_data_pointer_ += 4;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSW::invert_pulse() {
|
||||
pulse_.type = (pulse_.type == Pulse::High) ? Pulse::Low : Pulse::High;
|
||||
}
|
||||
|
||||
bool CSW::is_at_end() {
|
||||
switch(compression_type_) {
|
||||
case RLE: return (bool)feof(file_);
|
||||
case ZRLE: return source_data_pointer_ == source_data_.size();
|
||||
}
|
||||
}
|
||||
|
||||
void CSW::virtual_reset() {
|
||||
switch(compression_type_) {
|
||||
case RLE: fseek(file_, rle_start_, SEEK_SET); break;
|
||||
case ZRLE: source_data_pointer_ = 0; break;
|
||||
}
|
||||
}
|
||||
|
||||
Tape::Pulse CSW::virtual_get_next_pulse() {
|
||||
invert_pulse();
|
||||
pulse_.length.length = get_next_byte();
|
||||
if(!pulse_.length.length) pulse_.length.length = get_next_int32le();
|
||||
return pulse_;
|
||||
}
|
63
Storage/Tape/Formats/CSW.hpp
Normal file
63
Storage/Tape/Formats/CSW.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// CSW.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 10/07/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef CSW_hpp
|
||||
#define CSW_hpp
|
||||
|
||||
#include "../Tape.hpp"
|
||||
#include "../../FileHolder.hpp"
|
||||
|
||||
#include <zlib.h>
|
||||
#include <vector>
|
||||
|
||||
namespace Storage {
|
||||
namespace Tape {
|
||||
|
||||
/*!
|
||||
Provides a @c Tape containing a CSW tape image, which is a compressed 1-bit sampling.
|
||||
*/
|
||||
class CSW: public Tape, public Storage::FileHolder {
|
||||
public:
|
||||
/*!
|
||||
Constructs a @c CSW containing content from the file with name @c file_name.
|
||||
|
||||
@throws ErrorNotCSW if this file could not be opened and recognised as a valid CSW file.
|
||||
*/
|
||||
CSW(const char *file_name);
|
||||
|
||||
enum {
|
||||
ErrorNotCSW
|
||||
};
|
||||
|
||||
// implemented to satisfy @c Tape
|
||||
bool is_at_end();
|
||||
|
||||
private:
|
||||
void virtual_reset();
|
||||
Pulse virtual_get_next_pulse();
|
||||
|
||||
Pulse pulse_;
|
||||
enum CompressionType {
|
||||
RLE,
|
||||
ZRLE
|
||||
} compression_type_;
|
||||
|
||||
uint8_t get_next_byte();
|
||||
uint32_t get_next_int32le();
|
||||
void invert_pulse();
|
||||
|
||||
std::vector<uint8_t> source_data_;
|
||||
size_t source_data_pointer_;
|
||||
|
||||
long rle_start_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CSW_hpp */
|
@ -24,9 +24,9 @@ namespace Tape {
|
||||
class ZX80O81P: public Tape, public Storage::FileHolder {
|
||||
public:
|
||||
/*!
|
||||
Constructs an @c ZX80O containing content from the file with name @c file_name.
|
||||
Constructs a @c ZX80O containing content from the file with name @c file_name.
|
||||
|
||||
@throws ErrorNotZX80O if this file could not be opened and recognised as a valid ZX80-format .O.
|
||||
@throws ErrorNotZX80O81P if this file could not be opened and recognised as a valid ZX80-format .O.
|
||||
*/
|
||||
ZX80O81P(const char *file_name);
|
||||
|
||||
|
@ -14,27 +14,22 @@ Parser::Parser() :
|
||||
::Storage::Tape::Parser<WaveType, SymbolType>(),
|
||||
crc_(0x1021, 0x0000) {}
|
||||
|
||||
int Parser::get_next_bit(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
int Parser::get_next_bit(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||
SymbolType symbol = get_next_symbol(tape);
|
||||
return (symbol == SymbolType::One) ? 1 : 0;
|
||||
}
|
||||
|
||||
int Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
int Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||
int value = 0;
|
||||
int c = 8;
|
||||
if(get_next_bit(tape))
|
||||
{
|
||||
if(get_next_bit(tape)) {
|
||||
set_error_flag();
|
||||
return -1;
|
||||
}
|
||||
while(c--)
|
||||
{
|
||||
while(c--) {
|
||||
value = (value >> 1) | (get_next_bit(tape) << 7);
|
||||
}
|
||||
if(!get_next_bit(tape))
|
||||
{
|
||||
if(!get_next_bit(tape)) {
|
||||
set_error_flag();
|
||||
return -1;
|
||||
}
|
||||
@ -42,15 +37,13 @@ int Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
return value;
|
||||
}
|
||||
|
||||
int Parser::get_next_short(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
int Parser::get_next_short(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||
int result = get_next_byte(tape);
|
||||
result |= get_next_byte(tape) << 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
int Parser::get_next_word(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
int Parser::get_next_word(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||
int result = get_next_short(tape);
|
||||
result |= get_next_short(tape) << 8;
|
||||
return result;
|
||||
@ -59,28 +52,25 @@ int Parser::get_next_word(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
void Parser::reset_crc() { crc_.reset(); }
|
||||
uint16_t Parser::get_crc() { return crc_.get_value(); }
|
||||
|
||||
void Parser::process_pulse(Storage::Tape::Tape::Pulse pulse)
|
||||
{
|
||||
switch(pulse.type)
|
||||
{
|
||||
void Parser::process_pulse(Storage::Tape::Tape::Pulse pulse) {
|
||||
switch(pulse.type) {
|
||||
default: break;
|
||||
case Storage::Tape::Tape::Pulse::High:
|
||||
case Storage::Tape::Tape::Pulse::Low:
|
||||
float pulse_length = pulse.length.get_float();
|
||||
if(pulse_length >= 0.35 / 2400.0 && pulse_length < 0.7 / 2400.0) { push_wave(WaveType::Short); return; }
|
||||
if(pulse_length >= 0.35 / 1200.0 && pulse_length < 0.7 / 1200.0) { push_wave(WaveType::Long); return; }
|
||||
if(pulse_length >= 0.35 / 2400.0 && pulse_length < 0.7 / 1200.0) {
|
||||
push_wave(pulse_length > 1.0 / 3000.0 ? WaveType::Long : WaveType::Short); return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
push_wave(WaveType::Unrecognised);
|
||||
}
|
||||
|
||||
void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
||||
{
|
||||
void Parser::inspect_waves(const std::vector<WaveType> &waves) {
|
||||
if(waves.size() < 2) return;
|
||||
|
||||
if(waves[0] == WaveType::Long && waves[1] == WaveType::Long)
|
||||
{
|
||||
if(waves[0] == WaveType::Long && waves[1] == WaveType::Long) {
|
||||
push_symbol(SymbolType::Zero, 2);
|
||||
return;
|
||||
}
|
||||
@ -90,8 +80,7 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
||||
if( waves[0] == WaveType::Short &&
|
||||
waves[1] == WaveType::Short &&
|
||||
waves[2] == WaveType::Short &&
|
||||
waves[3] == WaveType::Short)
|
||||
{
|
||||
waves[3] == WaveType::Short) {
|
||||
push_symbol(SymbolType::One, 4);
|
||||
return;
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ class Tape {
|
||||
/// Advances or reverses the tape to the last time before or at @c time from which a pulse starts.
|
||||
virtual void seek(Time &time);
|
||||
|
||||
virtual ~Tape() {};
|
||||
|
||||
private:
|
||||
Time current_time_, next_time_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user