1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-16 05:27:43 +00:00

Introduces the extra level of indirection necessary to make Analyser::Static::Target polymorphic.

This commit is contained in:
Thomas Harte
2018-01-24 22:35:54 -05:00
parent 21efb32b6f
commit 11abc99ef8
24 changed files with 159 additions and 165 deletions

View File

@@ -56,16 +56,16 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
return acorn_cartridges; return acorn_cartridges;
} }
void Analyser::Static::Acorn::AddTargets(const Media &media, std::vector<Target> &destination) { void Analyser::Static::Acorn::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
Target target; std::unique_ptr<Target> target(new Target);
target.machine = Machine::Electron; target->machine = Machine::Electron;
target.probability = 1.0; // TODO: a proper estimation target->probability = 1.0; // TODO: a proper estimation
target.acorn.has_dfs = false; target->acorn.has_dfs = false;
target.acorn.has_adfs = false; target->acorn.has_adfs = false;
target.acorn.should_shift_restart = false; target->acorn.should_shift_restart = false;
// strip out inappropriate cartridges // strip out inappropriate cartridges
target.media.cartridges = AcornCartridgesFrom(media.cartridges); target->media.cartridges = AcornCartridgesFrom(media.cartridges);
// if there are any tapes, attempt to get data from the first // if there are any tapes, attempt to get data from the first
if(media.tapes.size() > 0) { if(media.tapes.size() > 0) {
@@ -96,9 +96,9 @@ void Analyser::Static::Acorn::AddTargets(const Media &media, std::vector<Target>
// Inspect first file. If it's protected or doesn't look like BASIC // Inspect first file. If it's protected or doesn't look like BASIC
// then the loading command is *RUN. Otherwise it's CHAIN"". // then the loading command is *RUN. Otherwise it's CHAIN"".
target.loading_command = is_basic ? "CHAIN\"\"\n" : "*RUN\n"; target->loading_command = is_basic ? "CHAIN\"\"\n" : "*RUN\n";
target.media.tapes = media.tapes; target->media.tapes = media.tapes;
} }
} }
@@ -108,18 +108,18 @@ void Analyser::Static::Acorn::AddTargets(const Media &media, std::vector<Target>
dfs_catalogue = GetDFSCatalogue(disk); dfs_catalogue = GetDFSCatalogue(disk);
if(dfs_catalogue == nullptr) adfs_catalogue = GetADFSCatalogue(disk); if(dfs_catalogue == nullptr) adfs_catalogue = GetADFSCatalogue(disk);
if(dfs_catalogue || adfs_catalogue) { if(dfs_catalogue || adfs_catalogue) {
target.media.disks = media.disks; target->media.disks = media.disks;
target.acorn.has_dfs = !!dfs_catalogue; target->acorn.has_dfs = !!dfs_catalogue;
target.acorn.has_adfs = !!adfs_catalogue; target->acorn.has_adfs = !!adfs_catalogue;
Catalogue::BootOption bootOption = (dfs_catalogue ?: adfs_catalogue)->bootOption; Catalogue::BootOption bootOption = (dfs_catalogue ?: adfs_catalogue)->bootOption;
if(bootOption != Catalogue::BootOption::None) if(bootOption != Catalogue::BootOption::None)
target.acorn.should_shift_restart = true; target->acorn.should_shift_restart = true;
else else
target.loading_command = "*CAT\n"; target->loading_command = "*CAT\n";
} }
} }
if(target.media.tapes.size() || target.media.disks.size() || target.media.cartridges.size()) if(target->media.tapes.size() || target->media.disks.size() || target->media.cartridges.size())
destination.push_back(target); destination.push_back(std::move(target));
} }

View File

@@ -15,7 +15,7 @@ namespace Analyser {
namespace Static { namespace Static {
namespace Acorn { namespace Acorn {
void AddTargets(const Media &media, std::vector<Target> &destination); void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
} }
} }

View File

@@ -58,7 +58,7 @@ static std::string RunCommandFor(const Storage::Disk::CPM::File &file) {
static void InspectCatalogue( static void InspectCatalogue(
const Storage::Disk::CPM::Catalogue &catalogue, const Storage::Disk::CPM::Catalogue &catalogue,
Analyser::Static::Target &target) { const std::unique_ptr<Analyser::Static::Target> &target) {
std::vector<const Storage::Disk::CPM::File *> candidate_files; std::vector<const Storage::Disk::CPM::File *> candidate_files;
candidate_files.reserve(catalogue.files.size()); candidate_files.reserve(catalogue.files.size());
@@ -95,7 +95,7 @@ static void InspectCatalogue(
// If there's just one file, run that. // If there's just one file, run that.
if(candidate_files.size() == 1) { if(candidate_files.size() == 1) {
target.loading_command = RunCommandFor(*candidate_files[0]); target->loading_command = RunCommandFor(*candidate_files[0]);
return; return;
} }
@@ -126,7 +126,7 @@ static void InspectCatalogue(
} }
if(basic_files == 1 || implicit_suffixed_files == 1) { if(basic_files == 1 || implicit_suffixed_files == 1) {
std::size_t selected_file = (basic_files == 1) ? last_basic_file : last_implicit_suffixed_file; std::size_t selected_file = (basic_files == 1) ? last_basic_file : last_implicit_suffixed_file;
target.loading_command = RunCommandFor(*candidate_files[selected_file]); target->loading_command = RunCommandFor(*candidate_files[selected_file]);
return; return;
} }
@@ -143,17 +143,17 @@ static void InspectCatalogue(
if(name_counts.size() == 2) { if(name_counts.size() == 2) {
for(auto &pair : name_counts) { for(auto &pair : name_counts) {
if(pair.second == 1) { if(pair.second == 1) {
target.loading_command = RunCommandFor(*candidate_files[indices_by_name[pair.first]]); target->loading_command = RunCommandFor(*candidate_files[indices_by_name[pair.first]]);
return; return;
} }
} }
} }
// Desperation. // Desperation.
target.loading_command = "cat\n"; target->loading_command = "cat\n";
} }
static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, Analyser::Static::Target &target) { static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, const std::unique_ptr<Analyser::Static::Target> &target) {
Storage::Encodings::MFM::Parser parser(true, disk); Storage::Encodings::MFM::Parser parser(true, disk);
Storage::Encodings::MFM::Sector *boot_sector = parser.get_sector(0, 0, 0x41); Storage::Encodings::MFM::Sector *boot_sector = parser.get_sector(0, 0, 0x41);
if(boot_sector != nullptr && !boot_sector->samples.empty()) { if(boot_sector != nullptr && !boot_sector->samples.empty()) {
@@ -169,7 +169,7 @@ static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, An
// This is a system disk, then launch it as though it were CP/M. // This is a system disk, then launch it as though it were CP/M.
if(!matched) { if(!matched) {
target.loading_command = "|cpm\n"; target->loading_command = "|cpm\n";
return true; return true;
} }
} }
@@ -177,24 +177,24 @@ static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, An
return false; return false;
} }
void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector<Target> &destination) { void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
Target target; std::unique_ptr<Target> target(new Target);
target.machine = Machine::AmstradCPC; target->machine = Machine::AmstradCPC;
target.probability = 1.0; target->probability = 1.0;
target.media.disks = media.disks; target->media.disks = media.disks;
target.media.tapes = media.tapes; target->media.tapes = media.tapes;
target.media.cartridges = media.cartridges; target->media.cartridges = media.cartridges;
target.amstradcpc.model = AmstradCPCModel::CPC6128; target->amstradcpc.model = AmstradCPCModel::CPC6128;
if(!target.media.tapes.empty()) { if(!target->media.tapes.empty()) {
// Ugliness flows here: assume the CPC isn't smart enough to pause between pressing // Ugliness flows here: assume the CPC isn't smart enough to pause between pressing
// enter and responding to the follow-on prompt to press a key, so just type for // enter and responding to the follow-on prompt to press a key, so just type for
// a while. Yuck! // a while. Yuck!
target.loading_command = "|tape\nrun\"\n1234567890"; target->loading_command = "|tape\nrun\"\n1234567890";
} }
if(!target.media.disks.empty()) { if(!target->media.disks.empty()) {
Storage::Disk::CPM::ParameterBlock data_format; Storage::Disk::CPM::ParameterBlock data_format;
data_format.sectors_per_track = 9; data_format.sectors_per_track = 9;
data_format.tracks = 40; data_format.tracks = 40;
@@ -203,11 +203,11 @@ void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector<Ta
data_format.catalogue_allocation_bitmap = 0xc000; data_format.catalogue_allocation_bitmap = 0xc000;
data_format.reserved_tracks = 0; data_format.reserved_tracks = 0;
std::unique_ptr<Storage::Disk::CPM::Catalogue> data_catalogue = Storage::Disk::CPM::GetCatalogue(target.media.disks.front(), data_format); std::unique_ptr<Storage::Disk::CPM::Catalogue> data_catalogue = Storage::Disk::CPM::GetCatalogue(target->media.disks.front(), data_format);
if(data_catalogue) { if(data_catalogue) {
InspectCatalogue(*data_catalogue, target); InspectCatalogue(*data_catalogue, target);
} else { } else {
if(!CheckBootSector(target.media.disks.front(), target)) { if(!CheckBootSector(target->media.disks.front(), target)) {
Storage::Disk::CPM::ParameterBlock system_format; Storage::Disk::CPM::ParameterBlock system_format;
system_format.sectors_per_track = 9; system_format.sectors_per_track = 9;
system_format.tracks = 40; system_format.tracks = 40;
@@ -216,7 +216,7 @@ void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector<Ta
system_format.catalogue_allocation_bitmap = 0xc000; system_format.catalogue_allocation_bitmap = 0xc000;
system_format.reserved_tracks = 2; system_format.reserved_tracks = 2;
std::unique_ptr<Storage::Disk::CPM::Catalogue> system_catalogue = Storage::Disk::CPM::GetCatalogue(target.media.disks.front(), system_format); std::unique_ptr<Storage::Disk::CPM::Catalogue> system_catalogue = Storage::Disk::CPM::GetCatalogue(target->media.disks.front(), system_format);
if(system_catalogue) { if(system_catalogue) {
InspectCatalogue(*system_catalogue, target); InspectCatalogue(*system_catalogue, target);
} }
@@ -224,5 +224,5 @@ void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector<Ta
} }
} }
destination.push_back(target); destination.push_back(std::move(target));
} }

View File

@@ -15,7 +15,7 @@ namespace Analyser {
namespace Static { namespace Static {
namespace AmstradCPC { namespace AmstradCPC {
void AddTargets(const Media &media, std::vector<Target> &destination); void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
} }
} }

View File

@@ -178,14 +178,14 @@ static void DeterminePagingForCartridge(Analyser::Static::Target &target, const
} }
} }
void Analyser::Static::Atari::AddTargets(const Media &media, std::vector<Target> &destination) { void Analyser::Static::Atari::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
// TODO: sanity checking; is this image really for an Atari 2600. // TODO: sanity checking; is this image really for an Atari 2600.
Target target; std::unique_ptr<Target> target(new Target);
target.machine = Machine::Atari2600; target->machine = Machine::Atari2600;
target.probability = 1.0; target->probability = 1.0;
target.media.cartridges = media.cartridges; target->media.cartridges = media.cartridges;
target.atari.paging_model = Atari2600PagingModel::None; target->atari.paging_model = Atari2600PagingModel::None;
target.atari.uses_superchip = false; target->atari.uses_superchip = false;
// try to figure out the paging scheme // try to figure out the paging scheme
if(!media.cartridges.empty()) { if(!media.cartridges.empty()) {
@@ -193,9 +193,9 @@ void Analyser::Static::Atari::AddTargets(const Media &media, std::vector<Target>
if(segments.size() == 1) { if(segments.size() == 1) {
const Storage::Cartridge::Cartridge::Segment &segment = segments.front(); const Storage::Cartridge::Cartridge::Segment &segment = segments.front();
DeterminePagingForCartridge(target, segment); DeterminePagingForCartridge(*target, segment);
} }
} }
destination.push_back(target); destination.push_back(std::move(target));
} }

View File

@@ -15,7 +15,7 @@ namespace Analyser {
namespace Static { namespace Static {
namespace Atari { namespace Atari {
void AddTargets(const Media &media, std::vector<Target> &destination); void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
} }
} }

View File

@@ -38,17 +38,17 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
return vic20_cartridges; return vic20_cartridges;
} }
void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<Target> &destination) { void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
Target target; std::unique_ptr<Target> target(new Target);
target.machine = Machine::Vic20; // TODO: machine estimation target->machine = Machine::Vic20; // TODO: machine estimation
target.probability = 1.0; // TODO: a proper estimation target->probability = 1.0; // TODO: a proper estimation
int device = 0; int device = 0;
std::vector<File> files; std::vector<File> files;
bool is_disk = false; bool is_disk = false;
// strip out inappropriate cartridges // strip out inappropriate cartridges
target.media.cartridges = Vic20CartridgesFrom(media.cartridges); target->media.cartridges = Vic20CartridgesFrom(media.cartridges);
// check disks // check disks
for(auto &disk : media.disks) { for(auto &disk : media.disks) {
@@ -56,7 +56,7 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<Tar
if(!disk_files.empty()) { if(!disk_files.empty()) {
is_disk = true; is_disk = true;
files.insert(files.end(), disk_files.begin(), disk_files.end()); files.insert(files.end(), disk_files.begin(), disk_files.end());
target.media.disks.push_back(disk); target->media.disks.push_back(disk);
if(!device) device = 8; if(!device) device = 8;
} }
} }
@@ -67,13 +67,13 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<Tar
tape->reset(); tape->reset();
if(!tape_files.empty()) { if(!tape_files.empty()) {
files.insert(files.end(), tape_files.begin(), tape_files.end()); files.insert(files.end(), tape_files.begin(), tape_files.end());
target.media.tapes.push_back(tape); target->media.tapes.push_back(tape);
if(!device) device = 1; if(!device) device = 1;
} }
} }
if(!files.empty()) { if(!files.empty()) {
target.vic20.memory_model = Vic20MemoryModel::Unexpanded; target->vic20.memory_model = Vic20MemoryModel::Unexpanded;
std::ostringstream string_stream; std::ostringstream string_stream;
string_stream << "LOAD\"" << (is_disk ? "*" : "") << "\"," << device << ","; string_stream << "LOAD\"" << (is_disk ? "*" : "") << "\"," << device << ",";
if(files.front().is_basic()) { if(files.front().is_basic()) {
@@ -82,17 +82,17 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<Tar
string_stream << "1"; string_stream << "1";
} }
string_stream << "\nRUN\n"; string_stream << "\nRUN\n";
target.loading_command = string_stream.str(); target->loading_command = string_stream.str();
// make a first guess based on loading address // make a first guess based on loading address
switch(files.front().starting_address) { switch(files.front().starting_address) {
case 0x1001: case 0x1001:
default: break; default: break;
case 0x1201: case 0x1201:
target.vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB; target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
break; break;
case 0x0401: case 0x0401:
target.vic20.memory_model = Vic20MemoryModel::EightKB; target->vic20.memory_model = Vic20MemoryModel::EightKB;
break; break;
} }
@@ -108,9 +108,9 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<Tar
// An unexpanded machine has 3583 bytes free for BASIC; // An unexpanded machine has 3583 bytes free for BASIC;
// a 3kb expanded machine has 6655 bytes free. // a 3kb expanded machine has 6655 bytes free.
if(file_size > 6655) if(file_size > 6655)
target.vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB; target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
else if(target.vic20.memory_model == Vic20MemoryModel::Unexpanded && file_size > 3583) else if(target->vic20.memory_model == Vic20MemoryModel::Unexpanded && file_size > 3583)
target.vic20.memory_model = Vic20MemoryModel::EightKB; target->vic20.memory_model = Vic20MemoryModel::EightKB;
} }
else else
{*/ {*/
@@ -129,13 +129,13 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<Tar
// If anything above the 8kb mark is touched, mark as a 32kb machine; otherwise if the // If anything above the 8kb mark is touched, mark as a 32kb machine; otherwise if the
// region 0x0400 to 0x1000 is touched and this is an unexpanded machine, mark as 3kb. // region 0x0400 to 0x1000 is touched and this is an unexpanded machine, mark as 3kb.
if(starting_address + file_size > 0x2000) if(starting_address + file_size > 0x2000)
target.vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB; target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
else if(target.vic20.memory_model == Vic20MemoryModel::Unexpanded && !(starting_address >= 0x1000 || starting_address+file_size < 0x0400)) else if(target->vic20.memory_model == Vic20MemoryModel::Unexpanded && !(starting_address >= 0x1000 || starting_address+file_size < 0x0400))
target.vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB; target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
// } // }
} }
} }
if(!target.media.tapes.empty() || !target.media.cartridges.empty() || !target.media.disks.empty()) if(!target->media.empty())
destination.push_back(target); destination.push_back(std::move(target));
} }

View File

@@ -15,7 +15,7 @@ namespace Analyser {
namespace Static { namespace Static {
namespace Commodore { namespace Commodore {
void AddTargets(const Media &media, std::vector<Target> &destination); void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
} }
} }

View File

@@ -200,32 +200,32 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
return msx_cartridges; return msx_cartridges;
} }
void Analyser::Static::MSX::AddTargets(const Media &media, std::vector<Target> &destination) { void Analyser::Static::MSX::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
Target target; std::unique_ptr<Target> target(new Target);
// Obtain only those cartridges which it looks like an MSX would understand. // Obtain only those cartridges which it looks like an MSX would understand.
target.media.cartridges = MSXCartridgesFrom(media.cartridges, target); target->media.cartridges = MSXCartridgesFrom(media.cartridges, *target);
// Check tapes for loadable files. // Check tapes for loadable files.
for(const auto &tape : media.tapes) { for(const auto &tape : media.tapes) {
std::vector<File> files_on_tape = GetFiles(tape); std::vector<File> files_on_tape = GetFiles(tape);
if(!files_on_tape.empty()) { if(!files_on_tape.empty()) {
switch(files_on_tape.front().type) { switch(files_on_tape.front().type) {
case File::Type::ASCII: target.loading_command = "RUN\"CAS:\r"; break; case File::Type::ASCII: target->loading_command = "RUN\"CAS:\r"; break;
case File::Type::TokenisedBASIC: target.loading_command = "CLOAD\rRUN\r"; break; case File::Type::TokenisedBASIC: target->loading_command = "CLOAD\rRUN\r"; break;
case File::Type::Binary: target.loading_command = "BLOAD\"CAS:\",R\r"; break; case File::Type::Binary: target->loading_command = "BLOAD\"CAS:\",R\r"; break;
default: break; default: break;
} }
target.media.tapes.push_back(tape); target->media.tapes.push_back(tape);
} }
} }
// Blindly accept disks for now. // Blindly accept disks for now.
target.media.disks = media.disks; target->media.disks = media.disks;
if(!target.media.empty()) { if(!target->media.empty()) {
target.machine = Machine::MSX; target->machine = Machine::MSX;
target.probability = 1.0; target->probability = 1.0;
destination.push_back(target); destination.push_back(std::move(target));
} }
} }

View File

@@ -15,7 +15,7 @@ namespace Analyser {
namespace Static { namespace Static {
namespace MSX { namespace MSX {
void AddTargets(const Media &media, std::vector<Target> &destination); void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
} }
} }

View File

@@ -73,10 +73,10 @@ static int Basic11Score(const Analyser::Static::MOS6502::Disassembly &disassembl
return Score(disassembly, rom_functions, variable_locations); return Score(disassembly, rom_functions, variable_locations);
} }
void Analyser::Static::Oric::AddTargets(const Media &media, std::vector<Target> &destination) { void Analyser::Static::Oric::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
Target target; std::unique_ptr<Target> target(new Target);
target.machine = Machine::Oric; target->machine = Machine::Oric;
target.probability = 1.0; target->probability = 1.0;
int basic10_votes = 0; int basic10_votes = 0;
int basic11_votes = 0; int basic11_votes = 0;
@@ -97,23 +97,23 @@ void Analyser::Static::Oric::AddTargets(const Media &media, std::vector<Target>
} }
} }
target.media.tapes.push_back(tape); target->media.tapes.push_back(tape);
target.loading_command = "CLOAD\"\"\n"; target->loading_command = "CLOAD\"\"\n";
} }
} }
// trust that any disk supplied can be handled by the Microdisc. TODO: check. // trust that any disk supplied can be handled by the Microdisc. TODO: check.
if(!media.disks.empty()) { if(!media.disks.empty()) {
target.oric.has_microdisc = true; target->oric.has_microdisc = true;
target.media.disks = media.disks; target->media.disks = media.disks;
} else { } else {
target.oric.has_microdisc = false; target->oric.has_microdisc = false;
} }
// TODO: really this should add two targets if not all votes agree // TODO: really this should add two targets if not all votes agree
target.oric.use_atmos_rom = basic11_votes >= basic10_votes; target->oric.use_atmos_rom = basic11_votes >= basic10_votes;
if(target.oric.has_microdisc) target.oric.use_atmos_rom = true; if(target->oric.has_microdisc) target->oric.use_atmos_rom = true;
if(target.media.tapes.size() || target.media.disks.size() || target.media.cartridges.size()) if(target->media.tapes.size() || target->media.disks.size() || target->media.cartridges.size())
destination.push_back(target); destination.push_back(std::move(target));
} }

View File

@@ -15,7 +15,7 @@ namespace Analyser {
namespace Static { namespace Static {
namespace Oric { namespace Oric {
void AddTargets(const Media &media, std::vector<Target> &destination); void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
} }
} }

View File

@@ -88,8 +88,8 @@ static Media GetMediaAndPlatforms(const char *file_name, TargetPlatform::IntType
Format("adf", result.disks, Disk::DiskImageHolder<Storage::Disk::AcornADF>, TargetPlatform::Acorn) // ADF Format("adf", result.disks, Disk::DiskImageHolder<Storage::Disk::AcornADF>, TargetPlatform::Acorn) // ADF
Format("bin", result.cartridges, Cartridge::BinaryDump, TargetPlatform::Atari2600) // BIN Format("bin", result.cartridges, Cartridge::BinaryDump, TargetPlatform::Atari2600) // BIN
Format("cas", result.tapes, Tape::CAS, TargetPlatform::MSX) // CAS Format("cas", result.tapes, Tape::CAS, TargetPlatform::MSX) // CAS
Format("cdt", result.tapes, Tape::TZX, TargetPlatform::AmstradCPC) // CDT Format("cdt", result.tapes, Tape::TZX, TargetPlatform::AmstradCPC) // CDT
Format("csw", result.tapes, Tape::CSW, TargetPlatform::AllTape) // CSW Format("csw", result.tapes, Tape::CSW, TargetPlatform::AllTape) // CSW
Format("d64", result.disks, Disk::DiskImageHolder<Storage::Disk::D64>, TargetPlatform::Commodore) // D64 Format("d64", result.disks, Disk::DiskImageHolder<Storage::Disk::D64>, TargetPlatform::Commodore) // D64
Format("dmk", result.disks, Disk::DiskImageHolder<Storage::Disk::DMK>, TargetPlatform::MSX) // DMK Format("dmk", result.disks, Disk::DiskImageHolder<Storage::Disk::DMK>, TargetPlatform::MSX) // DMK
Format("dsd", result.disks, Disk::DiskImageHolder<Storage::Disk::SSD>, TargetPlatform::Acorn) // DSD Format("dsd", result.disks, Disk::DiskImageHolder<Storage::Disk::SSD>, TargetPlatform::Acorn) // DSD
@@ -139,8 +139,8 @@ Media Analyser::Static::GetMedia(const char *file_name) {
return GetMediaAndPlatforms(file_name, throwaway); return GetMediaAndPlatforms(file_name, throwaway);
} }
std::vector<Target> Analyser::Static::GetTargets(const char *file_name) { std::vector<std::unique_ptr<Target>> Analyser::Static::GetTargets(const char *file_name) {
std::vector<Target> targets; std::vector<std::unique_ptr<Target>> targets;
// Collect all disks, tapes and ROMs as can be extrapolated from this file, forming the // Collect all disks, tapes and ROMs as can be extrapolated from this file, forming the
// union of all platforms this file might be a target for. // union of all platforms this file might be a target for.
@@ -158,8 +158,8 @@ std::vector<Target> Analyser::Static::GetTargets(const char *file_name) {
if(potential_platforms & TargetPlatform::ZX8081) ZX8081::AddTargets(media, targets, potential_platforms); if(potential_platforms & TargetPlatform::ZX8081) ZX8081::AddTargets(media, targets, potential_platforms);
// Reset any tapes to their initial position // Reset any tapes to their initial position
for(auto target : targets) { for(auto &target : targets) {
for(auto tape : media.tapes) { for(auto &tape : target->media.tapes) {
tape->reset(); tape->reset();
} }
} }

View File

@@ -82,7 +82,10 @@ struct Media {
*/ */
struct Target { struct Target {
Machine machine; Machine machine;
Media media;
float probability; float probability;
std::string loading_command;
// TODO: this is too C-like a solution; make Target a base class and // TODO: this is too C-like a solution; make Target a base class and
// turn the following into information held by more specific subclasses. // turn the following into information held by more specific subclasses.
@@ -121,9 +124,6 @@ struct Target {
MSXCartridgeType cartridge_type; MSXCartridgeType cartridge_type;
} msx; } msx;
}; };
std::string loading_command;
Media media;
}; };
/*! /*!
@@ -131,7 +131,7 @@ struct Target {
@returns The list of potential targets, sorted from most to least probable. @returns The list of potential targets, sorted from most to least probable.
*/ */
std::vector<Target> GetTargets(const char *file_name); std::vector<std::unique_ptr<Target>> GetTargets(const char *file_name);
/*! /*!
Inspects the supplied file and determines the media included. Inspects the supplied file and determines the media included.

View File

@@ -27,41 +27,41 @@ static std::vector<Storage::Data::ZX8081::File> GetFiles(const std::shared_ptr<S
return files; return files;
} }
void Analyser::Static::ZX8081::AddTargets(const Media &media, std::vector<Target> &destination, TargetPlatform::IntType potential_platforms) { void Analyser::Static::ZX8081::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination, TargetPlatform::IntType potential_platforms) {
if(!media.tapes.empty()) { if(!media.tapes.empty()) {
std::vector<Storage::Data::ZX8081::File> files = GetFiles(media.tapes.front()); std::vector<Storage::Data::ZX8081::File> files = GetFiles(media.tapes.front());
media.tapes.front()->reset(); media.tapes.front()->reset();
if(!files.empty()) { if(!files.empty()) {
Analyser::Static::Target target; std::unique_ptr<Target> target(new Target);
target.machine = Machine::ZX8081; target->machine = Machine::ZX8081;
// Guess the machine type from the file only if it isn't already known. // Guess the machine type from the file only if it isn't already known.
switch(potential_platforms & (TargetPlatform::ZX80 | TargetPlatform::ZX81)) { switch(potential_platforms & (TargetPlatform::ZX80 | TargetPlatform::ZX81)) {
default: default:
target.zx8081.isZX81 = files.front().isZX81; target->zx8081.isZX81 = files.front().isZX81;
break; break;
case TargetPlatform::ZX80: target.zx8081.isZX81 = false; break; case TargetPlatform::ZX80: target->zx8081.isZX81 = false; break;
case TargetPlatform::ZX81: target.zx8081.isZX81 = true; break; case TargetPlatform::ZX81: target->zx8081.isZX81 = true; break;
} }
/*if(files.front().data.size() > 16384) { /*if(files.front().data.size() > 16384) {
target.zx8081.memory_model = ZX8081MemoryModel::SixtyFourKB; target->zx8081.memory_model = ZX8081MemoryModel::SixtyFourKB;
} else*/ if(files.front().data.size() > 1024) { } else*/ if(files.front().data.size() > 1024) {
target.zx8081.memory_model = ZX8081MemoryModel::SixteenKB; target->zx8081.memory_model = ZX8081MemoryModel::SixteenKB;
} else { } else {
target.zx8081.memory_model = ZX8081MemoryModel::Unexpanded; target->zx8081.memory_model = ZX8081MemoryModel::Unexpanded;
} }
target.media.tapes = media.tapes; target->media.tapes = media.tapes;
// TODO: how to run software once loaded? Might require a BASIC detokeniser. // TODO: how to run software once loaded? Might require a BASIC detokeniser.
if(target.zx8081.isZX81) { if(target->zx8081.isZX81) {
target.loading_command = "J\"\"\n"; target->loading_command = "J\"\"\n";
} else { } else {
target.loading_command = "W\n"; target->loading_command = "W\n";
} }
destination.push_back(target); destination.push_back(std::move(target));
} }
} }
} }

View File

@@ -16,7 +16,7 @@ namespace Analyser {
namespace Static { namespace Static {
namespace ZX8081 { namespace ZX8081 {
void AddTargets(const Media &media, std::vector<Target> &destination, TargetPlatform::IntType potential_platforms); void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination, TargetPlatform::IntType potential_platforms);
} }
} }

View File

@@ -18,16 +18,16 @@
#include "TypedDynamicMachine.hpp" #include "TypedDynamicMachine.hpp"
::Machine::DynamicMachine *::Machine::MachineForTargets(const std::vector<Analyser::Static::Target> &targets) { ::Machine::DynamicMachine *::Machine::MachineForTargets(const std::vector<std::unique_ptr<Analyser::Static::Target>> &targets) {
// TODO: deal with target lists containing more than one machine. // TODO: deal with target lists containing more than one machine.
switch(targets.front().machine) { switch(targets.front()->machine) {
case Analyser::Machine::AmstradCPC: return new TypedDynamicMachine<AmstradCPC::Machine>(AmstradCPC::Machine::AmstradCPC()); case Analyser::Machine::AmstradCPC: return new TypedDynamicMachine<AmstradCPC::Machine>(AmstradCPC::Machine::AmstradCPC());
case Analyser::Machine::Atari2600: return new TypedDynamicMachine<Atari2600::Machine>(Atari2600::Machine::Atari2600()); case Analyser::Machine::Atari2600: return new TypedDynamicMachine<Atari2600::Machine>(Atari2600::Machine::Atari2600());
case Analyser::Machine::Electron: return new TypedDynamicMachine<Electron::Machine>(Electron::Machine::Electron()); case Analyser::Machine::Electron: return new TypedDynamicMachine<Electron::Machine>(Electron::Machine::Electron());
case Analyser::Machine::MSX: return new TypedDynamicMachine<MSX::Machine>(MSX::Machine::MSX()); case Analyser::Machine::MSX: return new TypedDynamicMachine<MSX::Machine>(MSX::Machine::MSX());
case Analyser::Machine::Oric: return new TypedDynamicMachine<Oric::Machine>(Oric::Machine::Oric()); case Analyser::Machine::Oric: return new TypedDynamicMachine<Oric::Machine>(Oric::Machine::Oric());
case Analyser::Machine::Vic20: return new TypedDynamicMachine<Commodore::Vic20::Machine>(Commodore::Vic20::Machine::Vic20()); case Analyser::Machine::Vic20: return new TypedDynamicMachine<Commodore::Vic20::Machine>(Commodore::Vic20::Machine::Vic20());
case Analyser::Machine::ZX8081: return new TypedDynamicMachine<ZX8081::Machine>(ZX8081::Machine::ZX8081(targets.front())); case Analyser::Machine::ZX8081: return new TypedDynamicMachine<ZX8081::Machine>(ZX8081::Machine::ZX8081(*targets.front()));
default: return nullptr; default: return nullptr;
} }

View File

@@ -42,7 +42,7 @@ struct DynamicMachine {
receive the supplied static analyser result. The machine has been allocated receive the supplied static analyser result. The machine has been allocated
on the heap. It is the caller's responsibility to delete the class when finished. on the heap. It is the caller's responsibility to delete the class when finished.
*/ */
DynamicMachine *MachineForTargets(const std::vector<Analyser::Static::Target> &target); DynamicMachine *MachineForTargets(const std::vector<std::unique_ptr<Analyser::Static::Target>> &targets);
/*! /*!
Returns a short string name for the machine identified by the target, Returns a short string name for the machine identified by the target,

View File

@@ -2060,11 +2060,11 @@
4B8944E3201967B4007DE474 /* Dynamic */ = { 4B8944E3201967B4007DE474 /* Dynamic */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B8944E4201967B4007DE474 /* ConfidenceSummary.hpp */,
4B8944E5201967B4007DE474 /* ConfidenceSource.hpp */,
4B8944E6201967B4007DE474 /* ConfidenceCounter.cpp */, 4B8944E6201967B4007DE474 /* ConfidenceCounter.cpp */,
4B8944E7201967B4007DE474 /* ConfidenceCounter.hpp */,
4B8944E8201967B4007DE474 /* ConfidenceSummary.cpp */, 4B8944E8201967B4007DE474 /* ConfidenceSummary.cpp */,
4B8944E7201967B4007DE474 /* ConfidenceCounter.hpp */,
4B8944E5201967B4007DE474 /* ConfidenceSource.hpp */,
4B8944E4201967B4007DE474 /* ConfidenceSummary.hpp */,
); );
path = Dynamic; path = Dynamic;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -2090,12 +2090,12 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B8944EC201967B4007DE474 /* Disk.cpp */, 4B8944EC201967B4007DE474 /* Disk.cpp */,
4B8944ED201967B4007DE474 /* StaticAnalyser.hpp */, 4B8944F2201967B4007DE474 /* StaticAnalyser.cpp */,
4B8944EE201967B4007DE474 /* File.hpp */,
4B8944EF201967B4007DE474 /* Tape.hpp */,
4B8944F0201967B4007DE474 /* Tape.cpp */, 4B8944F0201967B4007DE474 /* Tape.cpp */,
4B8944F1201967B4007DE474 /* Disk.hpp */, 4B8944F1201967B4007DE474 /* Disk.hpp */,
4B8944F2201967B4007DE474 /* StaticAnalyser.cpp */, 4B8944EE201967B4007DE474 /* File.hpp */,
4B8944ED201967B4007DE474 /* StaticAnalyser.hpp */,
4B8944EF201967B4007DE474 /* Tape.hpp */,
); );
path = Acorn; path = Acorn;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -2103,8 +2103,8 @@
4B8944F3201967B4007DE474 /* Atari */ = { 4B8944F3201967B4007DE474 /* Atari */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B8944F4201967B4007DE474 /* StaticAnalyser.hpp */,
4B8944F5201967B4007DE474 /* StaticAnalyser.cpp */, 4B8944F5201967B4007DE474 /* StaticAnalyser.cpp */,
4B8944F4201967B4007DE474 /* StaticAnalyser.hpp */,
); );
path = Atari; path = Atari;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -2112,10 +2112,10 @@
4B8944F6201967B4007DE474 /* Oric */ = { 4B8944F6201967B4007DE474 /* Oric */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B8944FA201967B4007DE474 /* StaticAnalyser.cpp */,
4B8944F9201967B4007DE474 /* Tape.cpp */,
4B8944F7201967B4007DE474 /* StaticAnalyser.hpp */, 4B8944F7201967B4007DE474 /* StaticAnalyser.hpp */,
4B8944F8201967B4007DE474 /* Tape.hpp */, 4B8944F8201967B4007DE474 /* Tape.hpp */,
4B8944F9201967B4007DE474 /* Tape.cpp */,
4B8944FA201967B4007DE474 /* StaticAnalyser.cpp */,
); );
path = Oric; path = Oric;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -2124,12 +2124,12 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B8944FC201967B4007DE474 /* Disk.cpp */, 4B8944FC201967B4007DE474 /* Disk.cpp */,
4B894502201967B4007DE474 /* Disk.hpp */,
4B894500201967B4007DE474 /* File.cpp */, 4B894500201967B4007DE474 /* File.cpp */,
4B8944FE201967B4007DE474 /* File.hpp */,
4B894503201967B4007DE474 /* StaticAnalyser.cpp */, 4B894503201967B4007DE474 /* StaticAnalyser.cpp */,
4B8944FD201967B4007DE474 /* StaticAnalyser.hpp */,
4B894501201967B4007DE474 /* Tape.cpp */, 4B894501201967B4007DE474 /* Tape.cpp */,
4B894502201967B4007DE474 /* Disk.hpp */,
4B8944FE201967B4007DE474 /* File.hpp */,
4B8944FD201967B4007DE474 /* StaticAnalyser.hpp */,
4B8944FF201967B4007DE474 /* Tape.hpp */, 4B8944FF201967B4007DE474 /* Tape.hpp */,
); );
path = Commodore; path = Commodore;
@@ -2138,8 +2138,8 @@
4B894504201967B4007DE474 /* ZX8081 */ = { 4B894504201967B4007DE474 /* ZX8081 */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B894505201967B4007DE474 /* StaticAnalyser.hpp */,
4B894506201967B4007DE474 /* StaticAnalyser.cpp */, 4B894506201967B4007DE474 /* StaticAnalyser.cpp */,
4B894505201967B4007DE474 /* StaticAnalyser.hpp */,
); );
path = ZX8081; path = ZX8081;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -2147,13 +2147,13 @@
4B894507201967B4007DE474 /* Disassembler */ = { 4B894507201967B4007DE474 /* Disassembler */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B894508201967B4007DE474 /* 6502.hpp */,
4B894509201967B4007DE474 /* AddressMapper.hpp */,
4B89450A201967B4007DE474 /* Z80.hpp */,
4B89450B201967B4007DE474 /* 6502.cpp */, 4B89450B201967B4007DE474 /* 6502.cpp */,
4B89450C201967B4007DE474 /* AddressMapper.cpp */, 4B89450C201967B4007DE474 /* AddressMapper.cpp */,
4B89450D201967B4007DE474 /* Z80.cpp */, 4B89450D201967B4007DE474 /* Z80.cpp */,
4B894508201967B4007DE474 /* 6502.hpp */,
4B894509201967B4007DE474 /* AddressMapper.hpp */,
4B89450E201967B4007DE474 /* Kernel.hpp */, 4B89450E201967B4007DE474 /* Kernel.hpp */,
4B89450A201967B4007DE474 /* Z80.hpp */,
); );
path = Disassembler; path = Disassembler;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -2161,10 +2161,10 @@
4B89450F201967B4007DE474 /* MSX */ = { 4B89450F201967B4007DE474 /* MSX */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B894513201967B4007DE474 /* StaticAnalyser.cpp */,
4B894512201967B4007DE474 /* Tape.cpp */,
4B894510201967B4007DE474 /* StaticAnalyser.hpp */, 4B894510201967B4007DE474 /* StaticAnalyser.hpp */,
4B894511201967B4007DE474 /* Tape.hpp */, 4B894511201967B4007DE474 /* Tape.hpp */,
4B894512201967B4007DE474 /* Tape.cpp */,
4B894513201967B4007DE474 /* StaticAnalyser.cpp */,
); );
path = MSX; path = MSX;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -2172,8 +2172,8 @@
4B894514201967B4007DE474 /* AmstradCPC */ = { 4B894514201967B4007DE474 /* AmstradCPC */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B894515201967B4007DE474 /* StaticAnalyser.hpp */,
4B894516201967B4007DE474 /* StaticAnalyser.cpp */, 4B894516201967B4007DE474 /* StaticAnalyser.cpp */,
4B894515201967B4007DE474 /* StaticAnalyser.hpp */,
); );
path = AmstradCPC; path = AmstradCPC;
sourceTree = "<group>"; sourceTree = "<group>";

View File

@@ -63,15 +63,15 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
MachineDelegate _machineDelegate; MachineDelegate _machineDelegate;
NSLock *_delegateMachineAccessLock; NSLock *_delegateMachineAccessLock;
std::vector<Analyser::Static::Target> _targets; CSStaticAnalyser *_analyser;
std::unique_ptr<Machine::DynamicMachine> _machine; std::unique_ptr<Machine::DynamicMachine> _machine;
} }
- (instancetype)initWithAnalyser:(CSStaticAnalyser *)result { - (instancetype)initWithAnalyser:(CSStaticAnalyser *)result {
self = [super init]; self = [super init];
if(self) { if(self) {
_targets = result.targets; _analyser = result;
_machine.reset(Machine::MachineForTargets(_targets)); _machine.reset(Machine::MachineForTargets(_analyser.targets));
_delegateMachineAccessLock = [[NSLock alloc] init]; _delegateMachineAccessLock = [[NSLock alloc] init];
_machineDelegate.machine = self; _machineDelegate.machine = self;
@@ -82,7 +82,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
_machine->crt_machine()->set_delegate(&_machineDelegate); _machine->crt_machine()->set_delegate(&_machineDelegate);
CSApplyROMFetcher(*_machine->crt_machine()); CSApplyROMFetcher(*_machine->crt_machine());
[self applyTarget:_targets.front()]; [self applyTarget:*_analyser.targets.front()];
} }
return self; return self;
} }
@@ -344,7 +344,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
- (NSString *)userDefaultsPrefix { - (NSString *)userDefaultsPrefix {
// Assumes that the first machine in the targets list is the source of user defaults. // Assumes that the first machine in the targets list is the source of user defaults.
std::string name = Machine::ShortNameForTargetMachine(_targets.front().machine); std::string name = Machine::ShortNameForTargetMachine(_analyser.targets.front()->machine);
return [[NSString stringWithUTF8String:name.c_str()] lowercaseString]; return [[NSString stringWithUTF8String:name.c_str()] lowercaseString];
} }

View File

@@ -10,6 +10,6 @@
@interface CSStaticAnalyser (ResultVector) @interface CSStaticAnalyser (ResultVector)
- (std::vector<Analyser::Static::Target> &)targets; - (std::vector<std::unique_ptr<Analyser::Static::Target>> &)targets;
@end @end

View File

@@ -17,8 +17,6 @@
@property(nonatomic, readonly) NSString *optionsPanelNibName; @property(nonatomic, readonly) NSString *optionsPanelNibName;
@property(nonatomic, readonly) NSString *displayName; @property(nonatomic, readonly) NSString *displayName;
- (void)applyToMachine:(CSMachine *)machine;
@end @end
@interface CSMediaSet : NSObject @interface CSMediaSet : NSObject

View File

@@ -17,7 +17,7 @@
#import "Clock_Signal-Swift.h" #import "Clock_Signal-Swift.h"
@implementation CSStaticAnalyser { @implementation CSStaticAnalyser {
std::vector<Analyser::Static::Target> _targets; std::vector<std::unique_ptr<Analyser::Static::Target>> _targets;
} }
- (instancetype)initWithFileAtURL:(NSURL *)url { - (instancetype)initWithFileAtURL:(NSURL *)url {
@@ -34,7 +34,7 @@
} }
- (NSString *)optionsPanelNibName { - (NSString *)optionsPanelNibName {
switch(_targets.front().machine) { switch(_targets.front()->machine) {
case Analyser::Machine::AmstradCPC: return nil; case Analyser::Machine::AmstradCPC: return nil;
case Analyser::Machine::Atari2600: return @"Atari2600Options"; case Analyser::Machine::Atari2600: return @"Atari2600Options";
case Analyser::Machine::Electron: return @"QuickLoadCompositeOptions"; case Analyser::Machine::Electron: return @"QuickLoadCompositeOptions";
@@ -46,11 +46,7 @@
} }
} }
- (void)applyToMachine:(CSMachine *)machine { - (std::vector<std::unique_ptr<Analyser::Static::Target>> &)targets {
[machine applyTarget:_targets.front()];
}
- (std::vector<Analyser::Static::Target> &)targets {
return _targets; return _targets;
} }

View File

@@ -13,7 +13,7 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "../../StaticAnalyser/StaticAnalyser.hpp" #include "../../Analyser/Static/StaticAnalyser.hpp"
#include "../../Machines/Utility/MachineForTarget.hpp" #include "../../Machines/Utility/MachineForTarget.hpp"
#include "../../Machines/ConfigurationTarget.hpp" #include "../../Machines/ConfigurationTarget.hpp"
@@ -250,7 +250,7 @@ int main(int argc, char *argv[]) {
} }
// Determine the machine for the supplied file. // Determine the machine for the supplied file.
std::vector<Analyser::Static::Target> targets = Analyser::Static::GetTargets(arguments.file_name.c_str()); std::vector<std::unique_ptr<Analyser::Static::Target>> targets = Analyser::Static::GetTargets(arguments.file_name.c_str());
if(targets.empty()) { if(targets.empty()) {
std::cerr << "Cannot open " << arguments.file_name << std::endl; std::cerr << "Cannot open " << arguments.file_name << std::endl;
return -1; return -1;
@@ -353,7 +353,7 @@ int main(int argc, char *argv[]) {
return -1; return -1;
} }
machine->configuration_target()->configure_as_target(targets.front()); machine->configuration_target()->configure_as_target(*targets.front());
// Setup output, assuming a CRT machine for now, and prepare a best-effort updater. // Setup output, assuming a CRT machine for now, and prepare a best-effort updater.
machine->crt_machine()->setup_output(4.0 / 3.0); machine->crt_machine()->setup_output(4.0 / 3.0);