mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Introduces the extra level of indirection necessary to make Analyser::Static::Target polymorphic.
This commit is contained in:
parent
21efb32b6f
commit
11abc99ef8
@ -56,16 +56,16 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
|
||||
return acorn_cartridges;
|
||||
}
|
||||
|
||||
void Analyser::Static::Acorn::AddTargets(const Media &media, std::vector<Target> &destination) {
|
||||
Target target;
|
||||
target.machine = Machine::Electron;
|
||||
target.probability = 1.0; // TODO: a proper estimation
|
||||
target.acorn.has_dfs = false;
|
||||
target.acorn.has_adfs = false;
|
||||
target.acorn.should_shift_restart = false;
|
||||
void Analyser::Static::Acorn::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
target->machine = Machine::Electron;
|
||||
target->probability = 1.0; // TODO: a proper estimation
|
||||
target->acorn.has_dfs = false;
|
||||
target->acorn.has_adfs = false;
|
||||
target->acorn.should_shift_restart = false;
|
||||
|
||||
// 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(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
|
||||
// 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);
|
||||
if(dfs_catalogue == nullptr) adfs_catalogue = GetADFSCatalogue(disk);
|
||||
if(dfs_catalogue || adfs_catalogue) {
|
||||
target.media.disks = media.disks;
|
||||
target.acorn.has_dfs = !!dfs_catalogue;
|
||||
target.acorn.has_adfs = !!adfs_catalogue;
|
||||
target->media.disks = media.disks;
|
||||
target->acorn.has_dfs = !!dfs_catalogue;
|
||||
target->acorn.has_adfs = !!adfs_catalogue;
|
||||
|
||||
Catalogue::BootOption bootOption = (dfs_catalogue ?: adfs_catalogue)->bootOption;
|
||||
if(bootOption != Catalogue::BootOption::None)
|
||||
target.acorn.should_shift_restart = true;
|
||||
target->acorn.should_shift_restart = true;
|
||||
else
|
||||
target.loading_command = "*CAT\n";
|
||||
target->loading_command = "*CAT\n";
|
||||
}
|
||||
}
|
||||
|
||||
if(target.media.tapes.size() || target.media.disks.size() || target.media.cartridges.size())
|
||||
destination.push_back(target);
|
||||
if(target->media.tapes.size() || target->media.disks.size() || target->media.cartridges.size())
|
||||
destination.push_back(std::move(target));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace Analyser {
|
||||
namespace Static {
|
||||
namespace Acorn {
|
||||
|
||||
void AddTargets(const Media &media, std::vector<Target> &destination);
|
||||
void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ static std::string RunCommandFor(const Storage::Disk::CPM::File &file) {
|
||||
|
||||
static void InspectCatalogue(
|
||||
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;
|
||||
candidate_files.reserve(catalogue.files.size());
|
||||
@ -95,7 +95,7 @@ static void InspectCatalogue(
|
||||
|
||||
// If there's just one file, run that.
|
||||
if(candidate_files.size() == 1) {
|
||||
target.loading_command = RunCommandFor(*candidate_files[0]);
|
||||
target->loading_command = RunCommandFor(*candidate_files[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ static void InspectCatalogue(
|
||||
}
|
||||
if(basic_files == 1 || implicit_suffixed_files == 1) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -143,17 +143,17 @@ static void InspectCatalogue(
|
||||
if(name_counts.size() == 2) {
|
||||
for(auto &pair : name_counts) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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::Sector *boot_sector = parser.get_sector(0, 0, 0x41);
|
||||
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.
|
||||
if(!matched) {
|
||||
target.loading_command = "|cpm\n";
|
||||
target->loading_command = "|cpm\n";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -177,24 +177,24 @@ static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, An
|
||||
return false;
|
||||
}
|
||||
|
||||
void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector<Target> &destination) {
|
||||
Target target;
|
||||
target.machine = Machine::AmstradCPC;
|
||||
target.probability = 1.0;
|
||||
target.media.disks = media.disks;
|
||||
target.media.tapes = media.tapes;
|
||||
target.media.cartridges = media.cartridges;
|
||||
void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
target->machine = Machine::AmstradCPC;
|
||||
target->probability = 1.0;
|
||||
target->media.disks = media.disks;
|
||||
target->media.tapes = media.tapes;
|
||||
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
|
||||
// enter and responding to the follow-on prompt to press a key, so just type for
|
||||
// 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;
|
||||
data_format.sectors_per_track = 9;
|
||||
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.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) {
|
||||
InspectCatalogue(*data_catalogue, target);
|
||||
} else {
|
||||
if(!CheckBootSector(target.media.disks.front(), target)) {
|
||||
if(!CheckBootSector(target->media.disks.front(), target)) {
|
||||
Storage::Disk::CPM::ParameterBlock system_format;
|
||||
system_format.sectors_per_track = 9;
|
||||
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.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) {
|
||||
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));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace Analyser {
|
||||
namespace Static {
|
||||
namespace AmstradCPC {
|
||||
|
||||
void AddTargets(const Media &media, std::vector<Target> &destination);
|
||||
void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
Target target;
|
||||
target.machine = Machine::Atari2600;
|
||||
target.probability = 1.0;
|
||||
target.media.cartridges = media.cartridges;
|
||||
target.atari.paging_model = Atari2600PagingModel::None;
|
||||
target.atari.uses_superchip = false;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
target->machine = Machine::Atari2600;
|
||||
target->probability = 1.0;
|
||||
target->media.cartridges = media.cartridges;
|
||||
target->atari.paging_model = Atari2600PagingModel::None;
|
||||
target->atari.uses_superchip = false;
|
||||
|
||||
// try to figure out the paging scheme
|
||||
if(!media.cartridges.empty()) {
|
||||
@ -193,9 +193,9 @@ void Analyser::Static::Atari::AddTargets(const Media &media, std::vector<Target>
|
||||
|
||||
if(segments.size() == 1) {
|
||||
const Storage::Cartridge::Cartridge::Segment &segment = segments.front();
|
||||
DeterminePagingForCartridge(target, segment);
|
||||
DeterminePagingForCartridge(*target, segment);
|
||||
}
|
||||
}
|
||||
|
||||
destination.push_back(target);
|
||||
destination.push_back(std::move(target));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace Analyser {
|
||||
namespace Static {
|
||||
namespace Atari {
|
||||
|
||||
void AddTargets(const Media &media, std::vector<Target> &destination);
|
||||
void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -38,17 +38,17 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
|
||||
return vic20_cartridges;
|
||||
}
|
||||
|
||||
void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<Target> &destination) {
|
||||
Target target;
|
||||
target.machine = Machine::Vic20; // TODO: machine estimation
|
||||
target.probability = 1.0; // TODO: a proper estimation
|
||||
void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
target->machine = Machine::Vic20; // TODO: machine estimation
|
||||
target->probability = 1.0; // TODO: a proper estimation
|
||||
|
||||
int device = 0;
|
||||
std::vector<File> files;
|
||||
bool is_disk = false;
|
||||
|
||||
// strip out inappropriate cartridges
|
||||
target.media.cartridges = Vic20CartridgesFrom(media.cartridges);
|
||||
target->media.cartridges = Vic20CartridgesFrom(media.cartridges);
|
||||
|
||||
// check 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()) {
|
||||
is_disk = true;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -67,13 +67,13 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<Tar
|
||||
tape->reset();
|
||||
if(!tape_files.empty()) {
|
||||
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(!files.empty()) {
|
||||
target.vic20.memory_model = Vic20MemoryModel::Unexpanded;
|
||||
target->vic20.memory_model = Vic20MemoryModel::Unexpanded;
|
||||
std::ostringstream string_stream;
|
||||
string_stream << "LOAD\"" << (is_disk ? "*" : "") << "\"," << device << ",";
|
||||
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 << "\nRUN\n";
|
||||
target.loading_command = string_stream.str();
|
||||
target->loading_command = string_stream.str();
|
||||
|
||||
// make a first guess based on loading address
|
||||
switch(files.front().starting_address) {
|
||||
case 0x1001:
|
||||
default: break;
|
||||
case 0x1201:
|
||||
target.vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
|
||||
target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
|
||||
break;
|
||||
case 0x0401:
|
||||
target.vic20.memory_model = Vic20MemoryModel::EightKB;
|
||||
target->vic20.memory_model = Vic20MemoryModel::EightKB;
|
||||
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;
|
||||
// a 3kb expanded machine has 6655 bytes free.
|
||||
if(file_size > 6655)
|
||||
target.vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
|
||||
else if(target.vic20.memory_model == Vic20MemoryModel::Unexpanded && file_size > 3583)
|
||||
target.vic20.memory_model = Vic20MemoryModel::EightKB;
|
||||
target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
|
||||
else if(target->vic20.memory_model == Vic20MemoryModel::Unexpanded && file_size > 3583)
|
||||
target->vic20.memory_model = Vic20MemoryModel::EightKB;
|
||||
}
|
||||
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
|
||||
// region 0x0400 to 0x1000 is touched and this is an unexpanded machine, mark as 3kb.
|
||||
if(starting_address + file_size > 0x2000)
|
||||
target.vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
|
||||
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;
|
||||
else if(target->vic20.memory_model == Vic20MemoryModel::Unexpanded && !(starting_address >= 0x1000 || starting_address+file_size < 0x0400))
|
||||
target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
if(!target.media.tapes.empty() || !target.media.cartridges.empty() || !target.media.disks.empty())
|
||||
destination.push_back(target);
|
||||
if(!target->media.empty())
|
||||
destination.push_back(std::move(target));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace Analyser {
|
||||
namespace Static {
|
||||
namespace Commodore {
|
||||
|
||||
void AddTargets(const Media &media, std::vector<Target> &destination);
|
||||
void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -200,32 +200,32 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
|
||||
return msx_cartridges;
|
||||
}
|
||||
|
||||
void Analyser::Static::MSX::AddTargets(const Media &media, std::vector<Target> &destination) {
|
||||
Target target;
|
||||
void Analyser::Static::MSX::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
|
||||
// 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.
|
||||
for(const auto &tape : media.tapes) {
|
||||
std::vector<File> files_on_tape = GetFiles(tape);
|
||||
if(!files_on_tape.empty()) {
|
||||
switch(files_on_tape.front().type) {
|
||||
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::Binary: target.loading_command = "BLOAD\"CAS:\",R\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::Binary: target->loading_command = "BLOAD\"CAS:\",R\r"; break;
|
||||
default: break;
|
||||
}
|
||||
target.media.tapes.push_back(tape);
|
||||
target->media.tapes.push_back(tape);
|
||||
}
|
||||
}
|
||||
|
||||
// Blindly accept disks for now.
|
||||
target.media.disks = media.disks;
|
||||
target->media.disks = media.disks;
|
||||
|
||||
if(!target.media.empty()) {
|
||||
target.machine = Machine::MSX;
|
||||
target.probability = 1.0;
|
||||
destination.push_back(target);
|
||||
if(!target->media.empty()) {
|
||||
target->machine = Machine::MSX;
|
||||
target->probability = 1.0;
|
||||
destination.push_back(std::move(target));
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace Analyser {
|
||||
namespace Static {
|
||||
namespace MSX {
|
||||
|
||||
void AddTargets(const Media &media, std::vector<Target> &destination);
|
||||
void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -73,10 +73,10 @@ static int Basic11Score(const Analyser::Static::MOS6502::Disassembly &disassembl
|
||||
return Score(disassembly, rom_functions, variable_locations);
|
||||
}
|
||||
|
||||
void Analyser::Static::Oric::AddTargets(const Media &media, std::vector<Target> &destination) {
|
||||
Target target;
|
||||
target.machine = Machine::Oric;
|
||||
target.probability = 1.0;
|
||||
void Analyser::Static::Oric::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
target->machine = Machine::Oric;
|
||||
target->probability = 1.0;
|
||||
|
||||
int basic10_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.loading_command = "CLOAD\"\"\n";
|
||||
target->media.tapes.push_back(tape);
|
||||
target->loading_command = "CLOAD\"\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
// trust that any disk supplied can be handled by the Microdisc. TODO: check.
|
||||
if(!media.disks.empty()) {
|
||||
target.oric.has_microdisc = true;
|
||||
target.media.disks = media.disks;
|
||||
target->oric.has_microdisc = true;
|
||||
target->media.disks = media.disks;
|
||||
} else {
|
||||
target.oric.has_microdisc = false;
|
||||
target->oric.has_microdisc = false;
|
||||
}
|
||||
|
||||
// TODO: really this should add two targets if not all votes agree
|
||||
target.oric.use_atmos_rom = basic11_votes >= basic10_votes;
|
||||
if(target.oric.has_microdisc) target.oric.use_atmos_rom = true;
|
||||
target->oric.use_atmos_rom = basic11_votes >= basic10_votes;
|
||||
if(target->oric.has_microdisc) target->oric.use_atmos_rom = true;
|
||||
|
||||
if(target.media.tapes.size() || target.media.disks.size() || target.media.cartridges.size())
|
||||
destination.push_back(target);
|
||||
if(target->media.tapes.size() || target->media.disks.size() || target->media.cartridges.size())
|
||||
destination.push_back(std::move(target));
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace Analyser {
|
||||
namespace Static {
|
||||
namespace Oric {
|
||||
|
||||
void AddTargets(const Media &media, std::vector<Target> &destination);
|
||||
void AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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("bin", result.cartridges, Cartridge::BinaryDump, TargetPlatform::Atari2600) // BIN
|
||||
Format("cas", result.tapes, Tape::CAS, TargetPlatform::MSX) // CAS
|
||||
Format("cdt", result.tapes, Tape::TZX, TargetPlatform::AmstradCPC) // CDT
|
||||
Format("csw", result.tapes, Tape::CSW, TargetPlatform::AllTape) // CSW
|
||||
Format("cdt", result.tapes, Tape::TZX, TargetPlatform::AmstradCPC) // CDT
|
||||
Format("csw", result.tapes, Tape::CSW, TargetPlatform::AllTape) // CSW
|
||||
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("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);
|
||||
}
|
||||
|
||||
std::vector<Target> Analyser::Static::GetTargets(const char *file_name) {
|
||||
std::vector<Target> targets;
|
||||
std::vector<std::unique_ptr<Target>> Analyser::Static::GetTargets(const char *file_name) {
|
||||
std::vector<std::unique_ptr<Target>> targets;
|
||||
|
||||
// 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.
|
||||
@ -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);
|
||||
|
||||
// Reset any tapes to their initial position
|
||||
for(auto target : targets) {
|
||||
for(auto tape : media.tapes) {
|
||||
for(auto &target : targets) {
|
||||
for(auto &tape : target->media.tapes) {
|
||||
tape->reset();
|
||||
}
|
||||
}
|
||||
|
@ -82,7 +82,10 @@ struct Media {
|
||||
*/
|
||||
struct Target {
|
||||
Machine machine;
|
||||
Media media;
|
||||
|
||||
float probability;
|
||||
std::string loading_command;
|
||||
|
||||
// TODO: this is too C-like a solution; make Target a base class and
|
||||
// turn the following into information held by more specific subclasses.
|
||||
@ -121,9 +124,6 @@ struct Target {
|
||||
MSXCartridgeType cartridge_type;
|
||||
} 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.
|
||||
*/
|
||||
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.
|
||||
|
@ -27,41 +27,41 @@ static std::vector<Storage::Data::ZX8081::File> GetFiles(const std::shared_ptr<S
|
||||
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()) {
|
||||
std::vector<Storage::Data::ZX8081::File> files = GetFiles(media.tapes.front());
|
||||
media.tapes.front()->reset();
|
||||
if(!files.empty()) {
|
||||
Analyser::Static::Target target;
|
||||
target.machine = Machine::ZX8081;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
target->machine = Machine::ZX8081;
|
||||
|
||||
// Guess the machine type from the file only if it isn't already known.
|
||||
switch(potential_platforms & (TargetPlatform::ZX80 | TargetPlatform::ZX81)) {
|
||||
default:
|
||||
target.zx8081.isZX81 = files.front().isZX81;
|
||||
target->zx8081.isZX81 = files.front().isZX81;
|
||||
break;
|
||||
|
||||
case TargetPlatform::ZX80: target.zx8081.isZX81 = false; break;
|
||||
case TargetPlatform::ZX81: target.zx8081.isZX81 = true; break;
|
||||
case TargetPlatform::ZX80: target->zx8081.isZX81 = false; break;
|
||||
case TargetPlatform::ZX81: target->zx8081.isZX81 = true; break;
|
||||
}
|
||||
|
||||
/*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) {
|
||||
target.zx8081.memory_model = ZX8081MemoryModel::SixteenKB;
|
||||
target->zx8081.memory_model = ZX8081MemoryModel::SixteenKB;
|
||||
} 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.
|
||||
if(target.zx8081.isZX81) {
|
||||
target.loading_command = "J\"\"\n";
|
||||
if(target->zx8081.isZX81) {
|
||||
target->loading_command = "J\"\"\n";
|
||||
} else {
|
||||
target.loading_command = "W\n";
|
||||
target->loading_command = "W\n";
|
||||
}
|
||||
|
||||
destination.push_back(target);
|
||||
destination.push_back(std::move(target));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace Analyser {
|
||||
namespace Static {
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -18,16 +18,16 @@
|
||||
|
||||
#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.
|
||||
switch(targets.front().machine) {
|
||||
switch(targets.front()->machine) {
|
||||
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::Electron: return new TypedDynamicMachine<Electron::Machine>(Electron::Machine::Electron());
|
||||
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::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;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ struct DynamicMachine {
|
||||
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.
|
||||
*/
|
||||
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,
|
||||
|
@ -2060,11 +2060,11 @@
|
||||
4B8944E3201967B4007DE474 /* Dynamic */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B8944E4201967B4007DE474 /* ConfidenceSummary.hpp */,
|
||||
4B8944E5201967B4007DE474 /* ConfidenceSource.hpp */,
|
||||
4B8944E6201967B4007DE474 /* ConfidenceCounter.cpp */,
|
||||
4B8944E7201967B4007DE474 /* ConfidenceCounter.hpp */,
|
||||
4B8944E8201967B4007DE474 /* ConfidenceSummary.cpp */,
|
||||
4B8944E7201967B4007DE474 /* ConfidenceCounter.hpp */,
|
||||
4B8944E5201967B4007DE474 /* ConfidenceSource.hpp */,
|
||||
4B8944E4201967B4007DE474 /* ConfidenceSummary.hpp */,
|
||||
);
|
||||
path = Dynamic;
|
||||
sourceTree = "<group>";
|
||||
@ -2090,12 +2090,12 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B8944EC201967B4007DE474 /* Disk.cpp */,
|
||||
4B8944ED201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
4B8944EE201967B4007DE474 /* File.hpp */,
|
||||
4B8944EF201967B4007DE474 /* Tape.hpp */,
|
||||
4B8944F2201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||
4B8944F0201967B4007DE474 /* Tape.cpp */,
|
||||
4B8944F1201967B4007DE474 /* Disk.hpp */,
|
||||
4B8944F2201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||
4B8944EE201967B4007DE474 /* File.hpp */,
|
||||
4B8944ED201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
4B8944EF201967B4007DE474 /* Tape.hpp */,
|
||||
);
|
||||
path = Acorn;
|
||||
sourceTree = "<group>";
|
||||
@ -2103,8 +2103,8 @@
|
||||
4B8944F3201967B4007DE474 /* Atari */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B8944F4201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
4B8944F5201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||
4B8944F4201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
);
|
||||
path = Atari;
|
||||
sourceTree = "<group>";
|
||||
@ -2112,10 +2112,10 @@
|
||||
4B8944F6201967B4007DE474 /* Oric */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B8944FA201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||
4B8944F9201967B4007DE474 /* Tape.cpp */,
|
||||
4B8944F7201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
4B8944F8201967B4007DE474 /* Tape.hpp */,
|
||||
4B8944F9201967B4007DE474 /* Tape.cpp */,
|
||||
4B8944FA201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||
);
|
||||
path = Oric;
|
||||
sourceTree = "<group>";
|
||||
@ -2124,12 +2124,12 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B8944FC201967B4007DE474 /* Disk.cpp */,
|
||||
4B894502201967B4007DE474 /* Disk.hpp */,
|
||||
4B894500201967B4007DE474 /* File.cpp */,
|
||||
4B8944FE201967B4007DE474 /* File.hpp */,
|
||||
4B894503201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||
4B8944FD201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
4B894501201967B4007DE474 /* Tape.cpp */,
|
||||
4B894502201967B4007DE474 /* Disk.hpp */,
|
||||
4B8944FE201967B4007DE474 /* File.hpp */,
|
||||
4B8944FD201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
4B8944FF201967B4007DE474 /* Tape.hpp */,
|
||||
);
|
||||
path = Commodore;
|
||||
@ -2138,8 +2138,8 @@
|
||||
4B894504201967B4007DE474 /* ZX8081 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B894505201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
4B894506201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||
4B894505201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
);
|
||||
path = ZX8081;
|
||||
sourceTree = "<group>";
|
||||
@ -2147,13 +2147,13 @@
|
||||
4B894507201967B4007DE474 /* Disassembler */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B894508201967B4007DE474 /* 6502.hpp */,
|
||||
4B894509201967B4007DE474 /* AddressMapper.hpp */,
|
||||
4B89450A201967B4007DE474 /* Z80.hpp */,
|
||||
4B89450B201967B4007DE474 /* 6502.cpp */,
|
||||
4B89450C201967B4007DE474 /* AddressMapper.cpp */,
|
||||
4B89450D201967B4007DE474 /* Z80.cpp */,
|
||||
4B894508201967B4007DE474 /* 6502.hpp */,
|
||||
4B894509201967B4007DE474 /* AddressMapper.hpp */,
|
||||
4B89450E201967B4007DE474 /* Kernel.hpp */,
|
||||
4B89450A201967B4007DE474 /* Z80.hpp */,
|
||||
);
|
||||
path = Disassembler;
|
||||
sourceTree = "<group>";
|
||||
@ -2161,10 +2161,10 @@
|
||||
4B89450F201967B4007DE474 /* MSX */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B894513201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||
4B894512201967B4007DE474 /* Tape.cpp */,
|
||||
4B894510201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
4B894511201967B4007DE474 /* Tape.hpp */,
|
||||
4B894512201967B4007DE474 /* Tape.cpp */,
|
||||
4B894513201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||
);
|
||||
path = MSX;
|
||||
sourceTree = "<group>";
|
||||
@ -2172,8 +2172,8 @@
|
||||
4B894514201967B4007DE474 /* AmstradCPC */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B894515201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
4B894516201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||
4B894515201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||
);
|
||||
path = AmstradCPC;
|
||||
sourceTree = "<group>";
|
||||
|
@ -63,15 +63,15 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
|
||||
MachineDelegate _machineDelegate;
|
||||
NSLock *_delegateMachineAccessLock;
|
||||
|
||||
std::vector<Analyser::Static::Target> _targets;
|
||||
CSStaticAnalyser *_analyser;
|
||||
std::unique_ptr<Machine::DynamicMachine> _machine;
|
||||
}
|
||||
|
||||
- (instancetype)initWithAnalyser:(CSStaticAnalyser *)result {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
_targets = result.targets;
|
||||
_machine.reset(Machine::MachineForTargets(_targets));
|
||||
_analyser = result;
|
||||
_machine.reset(Machine::MachineForTargets(_analyser.targets));
|
||||
_delegateMachineAccessLock = [[NSLock alloc] init];
|
||||
|
||||
_machineDelegate.machine = self;
|
||||
@ -82,7 +82,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
|
||||
_machine->crt_machine()->set_delegate(&_machineDelegate);
|
||||
CSApplyROMFetcher(*_machine->crt_machine());
|
||||
|
||||
[self applyTarget:_targets.front()];
|
||||
[self applyTarget:*_analyser.targets.front()];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -344,7 +344,7 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
|
||||
|
||||
- (NSString *)userDefaultsPrefix {
|
||||
// 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];
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,6 @@
|
||||
|
||||
@interface CSStaticAnalyser (ResultVector)
|
||||
|
||||
- (std::vector<Analyser::Static::Target> &)targets;
|
||||
- (std::vector<std::unique_ptr<Analyser::Static::Target>> &)targets;
|
||||
|
||||
@end
|
||||
|
@ -17,8 +17,6 @@
|
||||
@property(nonatomic, readonly) NSString *optionsPanelNibName;
|
||||
@property(nonatomic, readonly) NSString *displayName;
|
||||
|
||||
- (void)applyToMachine:(CSMachine *)machine;
|
||||
|
||||
@end
|
||||
|
||||
@interface CSMediaSet : NSObject
|
||||
|
@ -17,7 +17,7 @@
|
||||
#import "Clock_Signal-Swift.h"
|
||||
|
||||
@implementation CSStaticAnalyser {
|
||||
std::vector<Analyser::Static::Target> _targets;
|
||||
std::vector<std::unique_ptr<Analyser::Static::Target>> _targets;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFileAtURL:(NSURL *)url {
|
||||
@ -34,7 +34,7 @@
|
||||
}
|
||||
|
||||
- (NSString *)optionsPanelNibName {
|
||||
switch(_targets.front().machine) {
|
||||
switch(_targets.front()->machine) {
|
||||
case Analyser::Machine::AmstradCPC: return nil;
|
||||
case Analyser::Machine::Atari2600: return @"Atari2600Options";
|
||||
case Analyser::Machine::Electron: return @"QuickLoadCompositeOptions";
|
||||
@ -46,11 +46,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applyToMachine:(CSMachine *)machine {
|
||||
[machine applyTarget:_targets.front()];
|
||||
}
|
||||
|
||||
- (std::vector<Analyser::Static::Target> &)targets {
|
||||
- (std::vector<std::unique_ptr<Analyser::Static::Target>> &)targets {
|
||||
return _targets;
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include "../../StaticAnalyser/StaticAnalyser.hpp"
|
||||
#include "../../Analyser/Static/StaticAnalyser.hpp"
|
||||
#include "../../Machines/Utility/MachineForTarget.hpp"
|
||||
|
||||
#include "../../Machines/ConfigurationTarget.hpp"
|
||||
@ -250,7 +250,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
// 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()) {
|
||||
std::cerr << "Cannot open " << arguments.file_name << std::endl;
|
||||
return -1;
|
||||
@ -353,7 +353,7 @@ int main(int argc, char *argv[]) {
|
||||
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.
|
||||
machine->crt_machine()->setup_output(4.0 / 3.0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user