1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-26 10:29:31 +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:
Thomas Harte 2016-11-06 22:56:38 -05:00
parent 7205c3f82b
commit 80702616ea
5 changed files with 160 additions and 9 deletions

View File

@ -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 */,

View File

@ -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);
}

View 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;
}

View 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 */

View File

@ -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)
{