1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +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;
}
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));
}

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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("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();
}
}

View File

@ -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.

View File

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

View File

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

View File

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

View File

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

View File

@ -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>";

View File

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

View File

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

View File

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

View File

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

View File

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