mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 01:31:42 +00:00
Also deploys make_unique/shared to avoid type repetition.
This commit is contained in:
parent
e9318efeb6
commit
05d77d3297
@ -18,7 +18,7 @@ using namespace Analyser::Static::Acorn;
|
|||||||
|
|
||||||
std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetDFSCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk) {
|
std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetDFSCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk) {
|
||||||
// c.f. http://beebwiki.mdfs.net/Acorn_DFS_disc_format
|
// c.f. http://beebwiki.mdfs.net/Acorn_DFS_disc_format
|
||||||
std::unique_ptr<Catalogue> catalogue(new Catalogue);
|
auto catalogue = std::make_unique<Catalogue>();
|
||||||
Storage::Encodings::MFM::Parser parser(false, disk);
|
Storage::Encodings::MFM::Parser parser(false, disk);
|
||||||
|
|
||||||
Storage::Encodings::MFM::Sector *names = parser.get_sector(0, 0, 0);
|
Storage::Encodings::MFM::Sector *names = parser.get_sector(0, 0, 0);
|
||||||
@ -75,7 +75,7 @@ std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetDFSCatalogue(const std::s
|
|||||||
return catalogue;
|
return catalogue;
|
||||||
}
|
}
|
||||||
std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetADFSCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk) {
|
std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetADFSCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk) {
|
||||||
std::unique_ptr<Catalogue> catalogue(new Catalogue);
|
auto catalogue = std::make_unique<Catalogue>();
|
||||||
Storage::Encodings::MFM::Parser parser(true, disk);
|
Storage::Encodings::MFM::Parser parser(true, disk);
|
||||||
|
|
||||||
Storage::Encodings::MFM::Sector *free_space_map_second_half = parser.get_sector(0, 0, 1);
|
Storage::Encodings::MFM::Sector *free_space_map_second_half = parser.get_sector(0, 0, 1);
|
||||||
|
@ -58,7 +58,7 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Machine::Electron;
|
target->machine = Machine::Electron;
|
||||||
target->confidence = 0.5; // TODO: a proper estimation
|
target->confidence = 0.5; // TODO: a proper estimation
|
||||||
target->has_dfs = false;
|
target->has_dfs = false;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
using namespace Analyser::Static::Acorn;
|
using namespace Analyser::Static::Acorn;
|
||||||
|
|
||||||
static std::unique_ptr<File::Chunk> GetNextChunk(const std::shared_ptr<Storage::Tape::Tape> &tape, Storage::Tape::Acorn::Parser &parser) {
|
static std::unique_ptr<File::Chunk> GetNextChunk(const std::shared_ptr<Storage::Tape::Tape> &tape, Storage::Tape::Acorn::Parser &parser) {
|
||||||
std::unique_ptr<File::Chunk> new_chunk(new File::Chunk);
|
auto new_chunk = std::make_unique<File::Chunk>();
|
||||||
int shift_register = 0;
|
int shift_register = 0;
|
||||||
|
|
||||||
// TODO: move this into the parser
|
// TODO: move this into the parser
|
||||||
@ -90,7 +90,7 @@ static std::unique_ptr<File> GetNextFile(std::deque<File::Chunk> &chunks) {
|
|||||||
if(!chunks.size()) return nullptr;
|
if(!chunks.size()) return nullptr;
|
||||||
|
|
||||||
// accumulate chunks for as long as block number is sequential and the end-of-file bit isn't set
|
// accumulate chunks for as long as block number is sequential and the end-of-file bit isn't set
|
||||||
std::unique_ptr<File> file(new File);
|
auto file = std::make_unique<File>();
|
||||||
|
|
||||||
uint16_t block_number = 0;
|
uint16_t block_number = 0;
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, co
|
|||||||
|
|
||||||
Analyser::Static::TargetList Analyser::Static::AmstradCPC::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
Analyser::Static::TargetList Analyser::Static::AmstradCPC::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
||||||
TargetList destination;
|
TargetList destination;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Machine::AmstradCPC;
|
target->machine = Machine::AmstradCPC;
|
||||||
target->confidence = 0.5;
|
target->confidence = 0.5;
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ static void DeterminePagingForCartridge(Target &target, const Storage::Cartridge
|
|||||||
|
|
||||||
Analyser::Static::TargetList Analyser::Static::Atari2600::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
Analyser::Static::TargetList Analyser::Static::Atari2600::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
||||||
// TODO: sanity checking; is this image really for an Atari 2600?
|
// TODO: sanity checking; is this image really for an Atari 2600?
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Machine::Atari2600;
|
target->machine = Machine::Atari2600;
|
||||||
target->confidence = 0.5;
|
target->confidence = 0.5;
|
||||||
target->media.cartridges = media.cartridges;
|
target->media.cartridges = media.cartridges;
|
||||||
|
@ -54,7 +54,7 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
|
|||||||
|
|
||||||
Analyser::Static::TargetList Analyser::Static::Coleco::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
Analyser::Static::TargetList Analyser::Static::Coleco::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
||||||
TargetList targets;
|
TargetList targets;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Machine::ColecoVision;
|
target->machine = Machine::ColecoVision;
|
||||||
target->confidence = 1.0f - 1.0f / 32768.0f;
|
target->confidence = 1.0f - 1.0f / 32768.0f;
|
||||||
target->media.cartridges = ColecoCartridgesFrom(media.cartridges);
|
target->media.cartridges = ColecoCartridgesFrom(media.cartridges);
|
||||||
|
@ -125,7 +125,7 @@ class CommodoreGCRParser: public Storage::Disk::Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Sector> get_next_sector() {
|
std::shared_ptr<Sector> get_next_sector() {
|
||||||
std::shared_ptr<Sector> sector(new Sector);
|
auto sector = std::make_shared<Sector>();
|
||||||
const int max_index_count = index_count_ + 2;
|
const int max_index_count = index_count_ + 2;
|
||||||
|
|
||||||
while(index_count_ < max_index_count) {
|
while(index_count_ < max_index_count) {
|
||||||
|
@ -44,7 +44,7 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
|
|||||||
Analyser::Static::TargetList Analyser::Static::Commodore::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
Analyser::Static::TargetList Analyser::Static::Commodore::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
||||||
TargetList destination;
|
TargetList destination;
|
||||||
|
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Machine::Vic20; // TODO: machine estimation
|
target->machine = Machine::Vic20; // TODO: machine estimation
|
||||||
target->confidence = 0.5; // TODO: a proper estimation
|
target->confidence = 0.5; // TODO: a proper estimation
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ static std::unique_ptr<Analyser::Static::Target> CartridgeTarget(
|
|||||||
output_segments.emplace_back(start_address, segment.data);
|
output_segments.emplace_back(start_address, segment.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Analyser::Static::MSX::Target> target(new Analyser::Static::MSX::Target);
|
auto target = std::make_unique<Analyser::Static::MSX::Target>();
|
||||||
target->machine = Analyser::Machine::MSX;
|
target->machine = Analyser::Machine::MSX;
|
||||||
target->confidence = confidence;
|
target->confidence = confidence;
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ Analyser::Static::TargetList Analyser::Static::MSX::GetTargets(const Media &medi
|
|||||||
std::move(cartridge_targets.begin(), cartridge_targets.end(), std::back_inserter(destination));
|
std::move(cartridge_targets.begin(), cartridge_targets.end(), std::back_inserter(destination));
|
||||||
|
|
||||||
// Consider building a target for disks and/or tapes.
|
// Consider building a target for disks and/or tapes.
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
|
|
||||||
// Check tapes for loadable files.
|
// Check tapes for loadable files.
|
||||||
for(auto &tape : media.tapes) {
|
for(auto &tape : media.tapes) {
|
||||||
|
@ -101,7 +101,7 @@ static bool IsMicrodisc(Storage::Encodings::MFM::Parser &parser) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Analyser::Static::TargetList Analyser::Static::Oric::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
Analyser::Static::TargetList Analyser::Static::Oric::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Machine::Oric;
|
target->machine = Machine::Oric;
|
||||||
target->confidence = 0.5;
|
target->confidence = 0.5;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ Analyser::Static::TargetList Analyser::Static::Sega::GetTargets(const Media &med
|
|||||||
return {};
|
return {};
|
||||||
|
|
||||||
TargetList targets;
|
TargetList targets;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
|
|
||||||
target->machine = Machine::MasterSystem;
|
target->machine = Machine::MasterSystem;
|
||||||
|
|
||||||
|
@ -70,8 +70,8 @@ void AsyncTaskQueue::flush() {
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
dispatch_sync(serial_dispatch_queue_, ^{});
|
dispatch_sync(serial_dispatch_queue_, ^{});
|
||||||
#else
|
#else
|
||||||
std::shared_ptr<std::mutex> flush_mutex(new std::mutex);
|
auto flush_mutex = std::make_shared<std::mutex>();
|
||||||
std::shared_ptr<std::condition_variable> flush_condition(new std::condition_variable);
|
auto flush_condition = std::make_shared<std::condition_variable>();
|
||||||
std::unique_lock<std::mutex> lock(*flush_mutex);
|
std::unique_lock<std::mutex> lock(*flush_mutex);
|
||||||
enqueue([=] () {
|
enqueue([=] () {
|
||||||
std::unique_lock<std::mutex> inner_lock(*flush_mutex);
|
std::unique_lock<std::mutex> inner_lock(*flush_mutex);
|
||||||
|
@ -646,8 +646,7 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void type_string(const std::string &string) override final {
|
void type_string(const std::string &string) override final {
|
||||||
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper());
|
Utility::TypeRecipient::add_typer(string, std::make_unique<CharacterMapper>());
|
||||||
Utility::TypeRecipient::add_typer(string, std::move(mapper));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape) override final {
|
void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape) override final {
|
||||||
|
@ -409,8 +409,7 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void type_string(const std::string &string) override final {
|
void type_string(const std::string &string) override final {
|
||||||
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper());
|
Utility::TypeRecipient::add_typer(string, std::make_unique<CharacterMapper>());
|
||||||
Utility::TypeRecipient::add_typer(string, std::move(mapper));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardMapper *get_keyboard_mapper() override {
|
KeyboardMapper *get_keyboard_mapper() override {
|
||||||
|
@ -336,8 +336,7 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void type_string(const std::string &string) override final {
|
void type_string(const std::string &string) override final {
|
||||||
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper(is_zx81));
|
Utility::TypeRecipient::add_typer(string, std::make_unique<CharacterMapper>(is_zx81));
|
||||||
Utility::TypeRecipient::add_typer(string, std::move(mapper));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Keyboard
|
// MARK: - Keyboard
|
||||||
|
@ -48,7 +48,7 @@ ROMMachine::ROMFetcher CSROMFetcher(std::vector<ROMMachine::ROM> *missing_roms)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::unique_ptr<std::vector<std::uint8_t>> data(new std::vector<std::uint8_t>);
|
auto data = std::make_unique<std::vector<std::uint8_t>>();
|
||||||
*data = fileData.stdVector8;
|
*data = fileData.stdVector8;
|
||||||
results.emplace_back(std::move(data));
|
results.emplace_back(std::move(data));
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
using Target = Analyser::Static::Acorn::Target;
|
using Target = Analyser::Static::Acorn::Target;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Analyser::Machine::Electron;
|
target->machine = Analyser::Machine::Electron;
|
||||||
target->has_dfs = !!dfs;
|
target->has_dfs = !!dfs;
|
||||||
target->has_adfs = !!adfs;
|
target->has_adfs = !!adfs;
|
||||||
@ -58,7 +58,7 @@
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
using Target = Analyser::Static::AmstradCPC::Target;
|
using Target = Analyser::Static::AmstradCPC::Target;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Analyser::Machine::AmstradCPC;
|
target->machine = Analyser::Machine::AmstradCPC;
|
||||||
switch(model) {
|
switch(model) {
|
||||||
case CSMachineCPCModel464: target->model = Analyser::Static::AmstradCPC::Target::Model::CPC464; break;
|
case CSMachineCPCModel464: target->model = Analyser::Static::AmstradCPC::Target::Model::CPC464; break;
|
||||||
@ -74,7 +74,7 @@
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
using Target = Analyser::Static::MSX::Target;
|
using Target = Analyser::Static::MSX::Target;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Analyser::Machine::MSX;
|
target->machine = Analyser::Machine::MSX;
|
||||||
target->has_disk_drive = !!hasDiskDrive;
|
target->has_disk_drive = !!hasDiskDrive;
|
||||||
switch(region) {
|
switch(region) {
|
||||||
@ -91,7 +91,7 @@
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
using Target = Analyser::Static::Oric::Target;
|
using Target = Analyser::Static::Oric::Target;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Analyser::Machine::Oric;
|
target->machine = Analyser::Machine::Oric;
|
||||||
switch(model) {
|
switch(model) {
|
||||||
case CSMachineOricModelOric1: target->rom = Target::ROM::BASIC10; break;
|
case CSMachineOricModelOric1: target->rom = Target::ROM::BASIC10; break;
|
||||||
@ -112,7 +112,7 @@
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
using Target = Analyser::Static::Commodore::Target;
|
using Target = Analyser::Static::Commodore::Target;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Analyser::Machine::Vic20;
|
target->machine = Analyser::Machine::Vic20;
|
||||||
switch(region) {
|
switch(region) {
|
||||||
case CSMachineVic20RegionDanish: target->region = Target::Region::Danish; break;
|
case CSMachineVic20RegionDanish: target->region = Target::Region::Danish; break;
|
||||||
@ -145,7 +145,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
using Target = Analyser::Static::ZX8081::Target;
|
using Target = Analyser::Static::ZX8081::Target;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Analyser::Machine::ZX8081;
|
target->machine = Analyser::Machine::ZX8081;
|
||||||
target->is_ZX81 = false;
|
target->is_ZX81 = false;
|
||||||
target->ZX80_uses_ZX81_ROM = !!useZX81ROM;
|
target->ZX80_uses_ZX81_ROM = !!useZX81ROM;
|
||||||
@ -159,7 +159,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
using Target = Analyser::Static::ZX8081::Target;
|
using Target = Analyser::Static::ZX8081::Target;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Analyser::Machine::ZX8081;
|
target->machine = Analyser::Machine::ZX8081;
|
||||||
target->is_ZX81 = true;
|
target->is_ZX81 = true;
|
||||||
target->memory_model = ZX8081MemoryModelFromSize(memorySize);
|
target->memory_model = ZX8081MemoryModelFromSize(memorySize);
|
||||||
@ -172,7 +172,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
using Target = Analyser::Static::AppleII::Target;
|
using Target = Analyser::Static::AppleII::Target;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Analyser::Machine::AppleII;
|
target->machine = Analyser::Machine::AppleII;
|
||||||
switch(model) {
|
switch(model) {
|
||||||
default: target->model = Target::Model::II; break;
|
default: target->model = Target::Model::II; break;
|
||||||
@ -195,7 +195,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
using Target = Analyser::Static::Macintosh::Target;
|
using Target = Analyser::Static::Macintosh::Target;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Analyser::Machine::Macintosh;
|
target->machine = Analyser::Machine::Macintosh;
|
||||||
|
|
||||||
using Model = Target::Model;
|
using Model = Target::Model;
|
||||||
@ -216,7 +216,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
if(self) {
|
if(self) {
|
||||||
using Target = Analyser::Static::Macintosh::Target;
|
using Target = Analyser::Static::Macintosh::Target;
|
||||||
std::unique_ptr<Target> target(new Target);
|
auto target = std::make_unique<Target>();
|
||||||
target->machine = Analyser::Machine::AtariST;
|
target->machine = Analyser::Machine::AtariST;
|
||||||
_targets.push_back(std::move(target));
|
_targets.push_back(std::move(target));
|
||||||
}
|
}
|
||||||
|
@ -423,7 +423,7 @@ int main(int argc, char *argv[]) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> data(new std::vector<uint8_t>);
|
auto data = std::make_unique<std::vector<uint8_t>>();
|
||||||
|
|
||||||
std::fseek(file, 0, SEEK_END);
|
std::fseek(file, 0, SEEK_END);
|
||||||
data->resize(std::ftell(file));
|
data->resize(std::ftell(file));
|
||||||
|
@ -39,7 +39,7 @@ static std::shared_ptr<File> ZX80FileFromData(const std::vector<uint8_t> &data)
|
|||||||
|
|
||||||
// TODO: check that the line numbers declared above exist (?)
|
// TODO: check that the line numbers declared above exist (?)
|
||||||
|
|
||||||
std::shared_ptr<File> file(new File);
|
auto file = std::make_shared<File>();
|
||||||
file->data = data;
|
file->data = data;
|
||||||
file->isZX81 = false;
|
file->isZX81 = false;
|
||||||
return file;
|
return file;
|
||||||
@ -81,7 +81,7 @@ static std::shared_ptr<File> ZX81FileFromData(const std::vector<uint8_t> &data)
|
|||||||
|
|
||||||
// TODO: check that the line numbers declared above exist (?)
|
// TODO: check that the line numbers declared above exist (?)
|
||||||
|
|
||||||
std::shared_ptr<File> file(new File);
|
auto file = std::make_shared<File>();
|
||||||
file->name = StringFromData(name_data, true);
|
file->name = StringFromData(name_data, true);
|
||||||
file->data = data;
|
file->data = data;
|
||||||
file->isZX81 = true;
|
file->isZX81 = true;
|
||||||
|
@ -20,8 +20,7 @@ Parser::Parser() :
|
|||||||
Advances to the next block on the tape, treating it as a header, then consumes, parses, and returns it.
|
Advances to the next block on the tape, treating it as a header, then consumes, parses, and returns it.
|
||||||
Returns @c nullptr if any wave-encoding level errors are encountered.
|
Returns @c nullptr if any wave-encoding level errors are encountered.
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<Header> Parser::get_next_header(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
std::unique_ptr<Header> Parser::get_next_header(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||||
{
|
|
||||||
return duplicate_match<Header>(
|
return duplicate_match<Header>(
|
||||||
get_next_header_body(tape, true),
|
get_next_header_body(tape, true),
|
||||||
get_next_header_body(tape, false)
|
get_next_header_body(tape, false)
|
||||||
@ -32,8 +31,7 @@ std::unique_ptr<Header> Parser::get_next_header(const std::shared_ptr<Storage::T
|
|||||||
Advances to the next block on the tape, treating it as data, then consumes, parses, and returns it.
|
Advances to the next block on the tape, treating it as data, then consumes, parses, and returns it.
|
||||||
Returns @c nullptr if any wave-encoding level errors are encountered.
|
Returns @c nullptr if any wave-encoding level errors are encountered.
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<Data> Parser::get_next_data(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
std::unique_ptr<Data> Parser::get_next_data(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||||
{
|
|
||||||
return duplicate_match<Data>(
|
return duplicate_match<Data>(
|
||||||
get_next_data_body(tape, true),
|
get_next_data_body(tape, true),
|
||||||
get_next_data_body(tape, false)
|
get_next_data_body(tape, false)
|
||||||
@ -45,8 +43,7 @@ std::unique_ptr<Data> Parser::get_next_data(const std::shared_ptr<Storage::Tape:
|
|||||||
including setting the duplicate_matched flag.
|
including setting the duplicate_matched flag.
|
||||||
*/
|
*/
|
||||||
template<class ObjectType>
|
template<class ObjectType>
|
||||||
std::unique_ptr<ObjectType> Parser::duplicate_match(std::unique_ptr<ObjectType> first_copy, std::unique_ptr<ObjectType> second_copy)
|
std::unique_ptr<ObjectType> Parser::duplicate_match(std::unique_ptr<ObjectType> first_copy, std::unique_ptr<ObjectType> second_copy) {
|
||||||
{
|
|
||||||
// if only one copy was parsed successfully, return it
|
// if only one copy was parsed successfully, return it
|
||||||
if(!first_copy) return second_copy;
|
if(!first_copy) return second_copy;
|
||||||
if(!second_copy) return first_copy;
|
if(!second_copy) return first_copy;
|
||||||
@ -67,9 +64,8 @@ template<class ObjectType>
|
|||||||
return std::move(*copy_to_return);
|
return std::move(*copy_to_return);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Header> Parser::get_next_header_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original)
|
std::unique_ptr<Header> Parser::get_next_header_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original) {
|
||||||
{
|
auto header = std::make_unique<Header>();
|
||||||
std::unique_ptr<Header> header(new Header);
|
|
||||||
reset_error_flag();
|
reset_error_flag();
|
||||||
|
|
||||||
// find and proceed beyond lead-in tone
|
// find and proceed beyond lead-in tone
|
||||||
@ -119,8 +115,7 @@ std::unique_ptr<Header> Parser::get_next_header_body(const std::shared_ptr<Stora
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Header::serialise(uint8_t *target, uint16_t length) {
|
void Header::serialise(uint8_t *target, uint16_t length) {
|
||||||
switch(type)
|
switch(type) {
|
||||||
{
|
|
||||||
default: target[0] = 0xff; break;
|
default: target[0] = 0xff; break;
|
||||||
case Header::RelocatableProgram: target[0] = 0x01; break;
|
case Header::RelocatableProgram: target[0] = 0x01; break;
|
||||||
case Header::DataBlock: target[0] = 0x02; break;
|
case Header::DataBlock: target[0] = 0x02; break;
|
||||||
@ -132,9 +127,8 @@ void Header::serialise(uint8_t *target, uint16_t length) {
|
|||||||
std::memcpy(&target[1], data.data(), 191);
|
std::memcpy(&target[1], data.data(), 191);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Data> Parser::get_next_data_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original)
|
std::unique_ptr<Data> Parser::get_next_data_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original) {
|
||||||
{
|
auto data = std::make_unique<Data>();
|
||||||
std::unique_ptr<Data> data(new Data);
|
|
||||||
reset_error_flag();
|
reset_error_flag();
|
||||||
|
|
||||||
// find and proceed beyond lead-in tone to the next landing zone
|
// find and proceed beyond lead-in tone to the next landing zone
|
||||||
@ -143,8 +137,7 @@ std::unique_ptr<Data> Parser::get_next_data_body(const std::shared_ptr<Storage::
|
|||||||
reset_parity_byte();
|
reset_parity_byte();
|
||||||
|
|
||||||
// accumulate until the next non-word marker is hit
|
// accumulate until the next non-word marker is hit
|
||||||
while(!tape->is_at_end())
|
while(!tape->is_at_end()) {
|
||||||
{
|
|
||||||
SymbolType start_symbol = get_next_symbol(tape);
|
SymbolType start_symbol = get_next_symbol(tape);
|
||||||
if(start_symbol != SymbolType::Word) break;
|
if(start_symbol != SymbolType::Word) break;
|
||||||
data->data.push_back(get_next_byte_contents(tape));
|
data->data.push_back(get_next_byte_contents(tape));
|
||||||
@ -163,19 +156,15 @@ std::unique_ptr<Data> Parser::get_next_data_body(const std::shared_ptr<Storage::
|
|||||||
/*!
|
/*!
|
||||||
Finds and completes the next landing zone.
|
Finds and completes the next landing zone.
|
||||||
*/
|
*/
|
||||||
void Parser::proceed_to_landing_zone(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original)
|
void Parser::proceed_to_landing_zone(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original) {
|
||||||
{
|
|
||||||
uint8_t landing_zone[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
uint8_t landing_zone[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
while(!tape->is_at_end())
|
while(!tape->is_at_end()) {
|
||||||
{
|
|
||||||
memmove(landing_zone, &landing_zone[1], sizeof(uint8_t) * 8);
|
memmove(landing_zone, &landing_zone[1], sizeof(uint8_t) * 8);
|
||||||
landing_zone[8] = get_next_byte(tape);
|
landing_zone[8] = get_next_byte(tape);
|
||||||
|
|
||||||
bool is_landing_zone = true;
|
bool is_landing_zone = true;
|
||||||
for(int c = 0; c < 9; c++)
|
for(int c = 0; c < 9; c++) {
|
||||||
{
|
if(landing_zone[c] != ((is_original ? 0x80 : 0x00) | 0x9) - c) {
|
||||||
if(landing_zone[c] != ((is_original ? 0x80 : 0x00) | 0x9) - c)
|
|
||||||
{
|
|
||||||
is_landing_zone = false;
|
is_landing_zone = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -188,10 +177,8 @@ void Parser::proceed_to_landing_zone(const std::shared_ptr<Storage::Tape::Tape>
|
|||||||
Swallows symbols until it reaches the first instance of the required symbol, swallows that
|
Swallows symbols until it reaches the first instance of the required symbol, swallows that
|
||||||
and returns.
|
and returns.
|
||||||
*/
|
*/
|
||||||
void Parser::proceed_to_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape, SymbolType required_symbol)
|
void Parser::proceed_to_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape, SymbolType required_symbol) {
|
||||||
{
|
while(!tape->is_at_end()) {
|
||||||
while(!tape->is_at_end())
|
|
||||||
{
|
|
||||||
SymbolType symbol = get_next_symbol(tape);
|
SymbolType symbol = get_next_symbol(tape);
|
||||||
if(symbol == required_symbol) return;
|
if(symbol == required_symbol) return;
|
||||||
}
|
}
|
||||||
@ -200,8 +187,7 @@ void Parser::proceed_to_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape,
|
|||||||
/*!
|
/*!
|
||||||
Swallows the next byte; sets the error flag if it is not equal to @c value.
|
Swallows the next byte; sets the error flag if it is not equal to @c value.
|
||||||
*/
|
*/
|
||||||
void Parser::expect_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, uint8_t value)
|
void Parser::expect_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, uint8_t value) {
|
||||||
{
|
|
||||||
uint8_t next_byte = get_next_byte(tape);
|
uint8_t next_byte = get_next_byte(tape);
|
||||||
if(next_byte != value) set_error_flag();
|
if(next_byte != value) set_error_flag();
|
||||||
}
|
}
|
||||||
@ -213,8 +199,7 @@ void Parser::add_parity_byte(uint8_t byte) { parity_byte_ ^= byte; }
|
|||||||
/*!
|
/*!
|
||||||
Proceeds to the next word marker then returns the result of @c get_next_byte_contents.
|
Proceeds to the next word marker then returns the result of @c get_next_byte_contents.
|
||||||
*/
|
*/
|
||||||
uint8_t Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
uint8_t Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||||
{
|
|
||||||
proceed_to_symbol(tape, SymbolType::Word);
|
proceed_to_symbol(tape, SymbolType::Word);
|
||||||
return get_next_byte_contents(tape);
|
return get_next_byte_contents(tape);
|
||||||
}
|
}
|
||||||
@ -224,12 +209,10 @@ uint8_t Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
|||||||
Returns a byte composed of the first eight of those as bits; sets the error flag if any symbol is not
|
Returns a byte composed of the first eight of those as bits; sets the error flag if any symbol is not
|
||||||
::One and not ::Zero, or if the ninth bit is not equal to the odd parity of the other eight.
|
::One and not ::Zero, or if the ninth bit is not equal to the odd parity of the other eight.
|
||||||
*/
|
*/
|
||||||
uint8_t Parser::get_next_byte_contents(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
uint8_t Parser::get_next_byte_contents(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||||
{
|
|
||||||
int byte_plus_parity = 0;
|
int byte_plus_parity = 0;
|
||||||
int c = 9;
|
int c = 9;
|
||||||
while(c--)
|
while(c--) {
|
||||||
{
|
|
||||||
SymbolType next_symbol = get_next_symbol(tape);
|
SymbolType next_symbol = get_next_symbol(tape);
|
||||||
if((next_symbol != SymbolType::One) && (next_symbol != SymbolType::Zero)) set_error_flag();
|
if((next_symbol != SymbolType::One) && (next_symbol != SymbolType::Zero)) set_error_flag();
|
||||||
byte_plus_parity = (byte_plus_parity >> 1) | (((next_symbol == SymbolType::One) ? 1 : 0) << 8);
|
byte_plus_parity = (byte_plus_parity >> 1) | (((next_symbol == SymbolType::One) ? 1 : 0) << 8);
|
||||||
@ -249,8 +232,7 @@ uint8_t Parser::get_next_byte_contents(const std::shared_ptr<Storage::Tape::Tape
|
|||||||
/*!
|
/*!
|
||||||
Returns the result of two consecutive @c get_next_byte calls, arranged in little-endian format.
|
Returns the result of two consecutive @c get_next_byte calls, arranged in little-endian format.
|
||||||
*/
|
*/
|
||||||
uint16_t Parser::get_next_short(const std::shared_ptr<Storage::Tape::Tape> &tape)
|
uint16_t Parser::get_next_short(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||||
{
|
|
||||||
uint16_t value = get_next_byte(tape);
|
uint16_t value = get_next_byte(tape);
|
||||||
value |= get_next_byte(tape) << 8;
|
value |= get_next_byte(tape) << 8;
|
||||||
return value;
|
return value;
|
||||||
@ -261,15 +243,13 @@ uint16_t Parser::get_next_short(const std::shared_ptr<Storage::Tape::Tape> &tape
|
|||||||
indicates a high to low transition, inspects the time since the last transition, to produce
|
indicates a high to low transition, inspects the time since the last transition, to produce
|
||||||
a long, medium, short or unrecognised wave period.
|
a long, medium, short or unrecognised wave period.
|
||||||
*/
|
*/
|
||||||
void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse)
|
void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse) {
|
||||||
{
|
|
||||||
// The Complete Commodore Inner Space Anthology, P 97, gives half-cycle lengths of:
|
// The Complete Commodore Inner Space Anthology, P 97, gives half-cycle lengths of:
|
||||||
// short: 182us => 0.000364s cycle
|
// short: 182us => 0.000364s cycle
|
||||||
// medium: 262us => 0.000524s cycle
|
// medium: 262us => 0.000524s cycle
|
||||||
// long: 342us => 0.000684s cycle
|
// long: 342us => 0.000684s cycle
|
||||||
bool is_high = pulse.type == Storage::Tape::Tape::Pulse::High;
|
bool is_high = pulse.type == Storage::Tape::Tape::Pulse::High;
|
||||||
if(!is_high && previous_was_high_)
|
if(!is_high && previous_was_high_) {
|
||||||
{
|
|
||||||
if(wave_period_ >= 0.000764) push_wave(WaveType::Unrecognised);
|
if(wave_period_ >= 0.000764) push_wave(WaveType::Unrecognised);
|
||||||
else if(wave_period_ >= 0.000604) push_wave(WaveType::Long);
|
else if(wave_period_ >= 0.000604) push_wave(WaveType::Long);
|
||||||
else if(wave_period_ >= 0.000444) push_wave(WaveType::Medium);
|
else if(wave_period_ >= 0.000444) push_wave(WaveType::Medium);
|
||||||
@ -287,36 +267,30 @@ void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse)
|
|||||||
Per the contract with Analyser::Static::TapeParser; produces any of a word marker, an end-of-block marker,
|
Per the contract with Analyser::Static::TapeParser; produces any of a word marker, an end-of-block marker,
|
||||||
a zero, a one or a lead-in symbol based on the currently captured waves.
|
a zero, a one or a lead-in symbol based on the currently captured waves.
|
||||||
*/
|
*/
|
||||||
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.size() < 2) return;
|
||||||
|
|
||||||
if(waves[0] == WaveType::Long && waves[1] == WaveType::Medium)
|
if(waves[0] == WaveType::Long && waves[1] == WaveType::Medium) {
|
||||||
{
|
|
||||||
push_symbol(SymbolType::Word, 2);
|
push_symbol(SymbolType::Word, 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(waves[0] == WaveType::Long && waves[1] == WaveType::Short)
|
if(waves[0] == WaveType::Long && waves[1] == WaveType::Short) {
|
||||||
{
|
|
||||||
push_symbol(SymbolType::EndOfBlock, 2);
|
push_symbol(SymbolType::EndOfBlock, 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(waves[0] == WaveType::Short && waves[1] == WaveType::Medium)
|
if(waves[0] == WaveType::Short && waves[1] == WaveType::Medium) {
|
||||||
{
|
|
||||||
push_symbol(SymbolType::Zero, 2);
|
push_symbol(SymbolType::Zero, 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(waves[0] == WaveType::Medium && waves[1] == WaveType::Short)
|
if(waves[0] == WaveType::Medium && waves[1] == WaveType::Short) {
|
||||||
{
|
|
||||||
push_symbol(SymbolType::One, 2);
|
push_symbol(SymbolType::One, 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(waves[0] == WaveType::Short)
|
if(waves[0] == WaveType::Short) {
|
||||||
{
|
|
||||||
push_symbol(SymbolType::LeadIn, 1);
|
push_symbol(SymbolType::LeadIn, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ std::unique_ptr<Parser::FileSpeed> Parser::find_header(Storage::Tape::BinaryTape
|
|||||||
// To convert to the loop count format used by the MSX BIOS.
|
// To convert to the loop count format used by the MSX BIOS.
|
||||||
uint8_t int_result = static_cast<uint8_t>(total_length / (0.00001145f * 0.75f));
|
uint8_t int_result = static_cast<uint8_t>(total_length / (0.00001145f * 0.75f));
|
||||||
|
|
||||||
std::unique_ptr<FileSpeed> result(new FileSpeed);
|
auto result = std::make_unique<FileSpeed>();
|
||||||
result->minimum_start_bit_duration = int_result;
|
result->minimum_start_bit_duration = int_result;
|
||||||
result->low_high_disrimination_duration = (int_result * 3) >> 2;
|
result->low_high_disrimination_duration = (int_result * 3) >> 2;
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ std::shared_ptr<std::vector<uint8_t>> Parser::get_next_file_data(const std::shar
|
|||||||
if(is_at_end(tape)) return nullptr;
|
if(is_at_end(tape)) return nullptr;
|
||||||
return_symbol(symbol);
|
return_symbol(symbol);
|
||||||
|
|
||||||
std::shared_ptr<std::vector<uint8_t>> result(new std::vector<uint8_t>);
|
auto result = std::make_shared<std::vector<uint8_t>>();
|
||||||
int byte;
|
int byte;
|
||||||
while(!is_at_end(tape)) {
|
while(!is_at_end(tape)) {
|
||||||
byte = get_next_byte(tape);
|
byte = get_next_byte(tape);
|
||||||
|
Loading…
Reference in New Issue
Block a user