mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-23 20:29:42 +00:00
Had a quick go at using the Oric parser for static analysis. Found out that synchronisation is lost. Need to investigate.
This commit is contained in:
parent
7205c3f82b
commit
80702616ea
@ -60,6 +60,7 @@
|
||||
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 */; };
|
||||
4B8805FE1DD02552003085B1 /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8805FC1DD02552003085B1 /* Tape.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 */; };
|
||||
@ -508,6 +509,8 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
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; };
|
||||
@ -1770,6 +1773,8 @@
|
||||
children = (
|
||||
4BCF1FA91DADD41B0039D2E7 /* StaticAnalyser.cpp */,
|
||||
4BCF1FAA1DADD41B0039D2E7 /* StaticAnalyser.hpp */,
|
||||
4B8805FC1DD02552003085B1 /* Tape.cpp */,
|
||||
4B8805FD1DD02552003085B1 /* Tape.hpp */,
|
||||
);
|
||||
name = Oric;
|
||||
sourceTree = "<group>";
|
||||
@ -2325,6 +2330,7 @@
|
||||
4B8FE2201DA19D7C0090D3CE /* Atari2600OptionsPanel.swift in Sources */,
|
||||
4B8805F41DCFD22A003085B1 /* Commodore.cpp in Sources */,
|
||||
4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */,
|
||||
4B8805FE1DD02552003085B1 /* Tape.cpp in Sources */,
|
||||
4B9CCDA11DA279CA0098B625 /* Vic20OptionsPanel.swift in Sources */,
|
||||
4B8805F01DCFC99C003085B1 /* Acorn.cpp in Sources */,
|
||||
4B3051301D98ACC600B4FED8 /* Plus3.cpp in Sources */,
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "StaticAnalyser.hpp"
|
||||
|
||||
#include "Tape.hpp"
|
||||
|
||||
using namespace StaticAnalyser::Oric;
|
||||
|
||||
void StaticAnalyser::Oric::AddTargets(
|
||||
@ -16,14 +18,20 @@ void StaticAnalyser::Oric::AddTargets(
|
||||
const std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges,
|
||||
std::list<StaticAnalyser::Target> &destination)
|
||||
{
|
||||
// TODO: any sort of sanity checking at all; at the minute just trust the file type
|
||||
// approximation already performed.
|
||||
Target target;
|
||||
target.machine = Target::Oric;
|
||||
target.probability = 1.0;
|
||||
target.disks = disks;
|
||||
target.tapes = tapes;
|
||||
target.cartridges = cartridges;
|
||||
target.loadingCommand = "CLOAD\"\"\n";
|
||||
destination.push_back(target);
|
||||
|
||||
for(auto tape : tapes)
|
||||
{
|
||||
std::list<File> tape_files = GetFiles(tape);
|
||||
if(tape_files.size())
|
||||
{
|
||||
target.tapes.push_back(tape);
|
||||
target.loadingCommand = "CLOAD\"\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
if(target.tapes.size() || target.disks.size() || target.cartridges.size())
|
||||
destination.push_back(target);
|
||||
}
|
||||
|
95
StaticAnalyser/Oric/Tape.cpp
Normal file
95
StaticAnalyser/Oric/Tape.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
//
|
||||
// Tape.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 06/11/2016.
|
||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Tape.hpp"
|
||||
#include "../../Storage/Tape/Parsers/Oric.hpp"
|
||||
|
||||
using namespace StaticAnalyser::Oric;
|
||||
|
||||
std::list<File> StaticAnalyser::Oric::GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
{
|
||||
std::list<File> files;
|
||||
Storage::Tape::Oric::Parser parser;
|
||||
|
||||
tape->reset();
|
||||
while(!tape->is_at_end())
|
||||
{
|
||||
// sync to next lead-in, check that it's one of three 0x16s
|
||||
bool is_fast = parser.sync_and_get_encoding_speed(tape);
|
||||
int next_bytes[2];
|
||||
next_bytes[0] = parser.get_next_byte(tape, is_fast);
|
||||
next_bytes[1] = parser.get_next_byte(tape, is_fast);
|
||||
|
||||
if(next_bytes[0] != 0x16 || next_bytes[1] != 0x16) continue;
|
||||
|
||||
// get the first byte that isn't a 0x16, check it was a 0x24
|
||||
int byte = 0x16;
|
||||
while(!tape->is_at_end() && byte == 0x16)
|
||||
{
|
||||
byte = parser.get_next_byte(tape, is_fast);
|
||||
}
|
||||
if(byte != 0x24) continue;
|
||||
|
||||
// skip two empty bytes
|
||||
parser.get_next_byte(tape, is_fast);
|
||||
parser.get_next_byte(tape, is_fast);
|
||||
|
||||
// get data and launch types
|
||||
File new_file;
|
||||
switch(parser.get_next_byte(tape, is_fast))
|
||||
{
|
||||
case 0x00: new_file.data_type = File::ProgramType::BASIC; break;
|
||||
case 0x80: new_file.data_type = File::ProgramType::MachineCode; break;
|
||||
default: new_file.data_type = File::ProgramType::None; break;
|
||||
}
|
||||
switch(parser.get_next_byte(tape, is_fast))
|
||||
{
|
||||
case 0x80: new_file.launch_type = File::ProgramType::BASIC; break;
|
||||
case 0xc7: new_file.launch_type = File::ProgramType::MachineCode; break;
|
||||
default: new_file.launch_type = File::ProgramType::None; break;
|
||||
}
|
||||
|
||||
// read end and start addresses
|
||||
new_file.ending_address = (uint16_t)(parser.get_next_byte(tape, is_fast) << 8);
|
||||
new_file.ending_address |= (uint16_t)parser.get_next_byte(tape, is_fast);
|
||||
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);
|
||||
|
||||
// skip an empty bytes
|
||||
parser.get_next_byte(tape, is_fast);
|
||||
|
||||
// read file name, up to 16 characters and null terminated
|
||||
char file_name[17];
|
||||
int name_pos = 0;
|
||||
while(name_pos < 16)
|
||||
{
|
||||
file_name[name_pos] = (char)parser.get_next_byte(tape, is_fast);
|
||||
if(!file_name[name_pos]) break;
|
||||
name_pos++;
|
||||
}
|
||||
file_name[16] = '\0';
|
||||
new_file.name = file_name;
|
||||
|
||||
// read body
|
||||
size_t body_length = new_file.ending_address - new_file.starting_address + 1;
|
||||
new_file.data.reserve(body_length);
|
||||
for(size_t c = 0; c < body_length; c++)
|
||||
{
|
||||
new_file.data.push_back((uint8_t)parser.get_next_byte(tape, is_fast));
|
||||
}
|
||||
|
||||
// only one validation check: was there enough tape?
|
||||
if(!tape->is_at_end())
|
||||
{
|
||||
files.push_back(new_file);
|
||||
}
|
||||
}
|
||||
tape->reset();
|
||||
|
||||
return files;
|
||||
}
|
38
StaticAnalyser/Oric/Tape.hpp
Normal file
38
StaticAnalyser/Oric/Tape.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// Tape.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 06/11/2016.
|
||||
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef StaticAnalyser_Oric_Tape_hpp
|
||||
#define StaticAnalyser_Oric_Tape_hpp
|
||||
|
||||
#include "../../Storage/Tape/Tape.hpp"
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace StaticAnalyser {
|
||||
namespace Oric {
|
||||
|
||||
struct File {
|
||||
std::string name;
|
||||
uint16_t starting_address;
|
||||
uint16_t ending_address;
|
||||
enum ProgramType {
|
||||
BASIC,
|
||||
MachineCode,
|
||||
None
|
||||
};
|
||||
ProgramType data_type, launch_type;
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
|
||||
std::list<File> GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Tape_hpp */
|
@ -25,7 +25,7 @@ int Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, bool
|
||||
bit_count++;
|
||||
}
|
||||
// TODO: check parity?
|
||||
return tape->is_at_end() ? -1 : (result >> 1);
|
||||
return tape->is_at_end() ? -1 : (result&0xff);
|
||||
}
|
||||
|
||||
bool Parser::sync_and_get_encoding_speed(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
||||
@ -141,7 +141,10 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
||||
return;
|
||||
}
|
||||
if(slow_sync_matching_depth < waves.size() && fast_sync_matching_depth < waves.size())
|
||||
remove_waves((int)std::min(slow_sync_matching_depth, fast_sync_matching_depth));
|
||||
{
|
||||
int least_depth = (int)std::min(slow_sync_matching_depth, fast_sync_matching_depth);
|
||||
remove_waves(least_depth ? least_depth : 1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -158,6 +161,7 @@ size_t Parser::pattern_matching_depth(const std::vector<WaveType> &waves, Patter
|
||||
while(depth < waves.size() && pattern->type != WaveType::Unrecognised)
|
||||
{
|
||||
if(waves[depth] != pattern->type) break;
|
||||
depth++;
|
||||
pattern_depth++;
|
||||
if(pattern_depth == pattern->count)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user