mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +00:00
Merge pull request #369 from TomHarte/AnalyserUnion
Encapsulates per-platform analyser result fields.
This commit is contained in:
commit
74dfc80b0f
@ -17,7 +17,7 @@ MultiConfigurationTarget::MultiConfigurationTarget(const std::vector<std::unique
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiConfigurationTarget::configure_as_target(const Analyser::Static::Target &target) {
|
void MultiConfigurationTarget::configure_as_target(const Analyser::Static::Target *target) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MultiConfigurationTarget::insert_media(const Analyser::Static::Media &media) {
|
bool MultiConfigurationTarget::insert_media(const Analyser::Static::Media &media) {
|
||||||
|
@ -29,7 +29,7 @@ struct MultiConfigurationTarget: public ConfigurationTarget::Machine {
|
|||||||
MultiConfigurationTarget(const std::vector<std::unique_ptr<::Machine::DynamicMachine>> &machines);
|
MultiConfigurationTarget(const std::vector<std::unique_ptr<::Machine::DynamicMachine>> &machines);
|
||||||
|
|
||||||
// Below is the standard ConfigurationTarget::Machine interface; see there for documentation.
|
// Below is the standard ConfigurationTarget::Machine interface; see there for documentation.
|
||||||
void configure_as_target(const Analyser::Static::Target &target) override;
|
void configure_as_target(const Analyser::Static::Target *target) override;
|
||||||
bool insert_media(const Analyser::Static::Media &media) override;
|
bool insert_media(const Analyser::Static::Media &media) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "Disk.hpp"
|
#include "Disk.hpp"
|
||||||
#include "Tape.hpp"
|
#include "Tape.hpp"
|
||||||
|
#include "Target.hpp"
|
||||||
|
|
||||||
using namespace Analyser::Static::Acorn;
|
using namespace Analyser::Static::Acorn;
|
||||||
|
|
||||||
@ -56,13 +57,13 @@ 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<std::unique_ptr<Target>> &destination) {
|
void Analyser::Static::Acorn::AddTargets(const Media &media, std::vector<std::unique_ptr<::Analyser::Static::Target>> &destination) {
|
||||||
std::unique_ptr<Target> target(new Target);
|
std::unique_ptr<Target> target(new Target);
|
||||||
target->machine = Machine::Electron;
|
target->machine = Machine::Electron;
|
||||||
target->confidence = 0.5; // TODO: a proper estimation
|
target->confidence = 0.5; // TODO: a proper estimation
|
||||||
target->acorn.has_dfs = false;
|
target->has_dfs = false;
|
||||||
target->acorn.has_adfs = false;
|
target->has_adfs = false;
|
||||||
target->acorn.should_shift_restart = false;
|
target->should_shift_restart = false;
|
||||||
|
|
||||||
// strip out inappropriate cartridges
|
// strip out inappropriate cartridges
|
||||||
target->media.cartridges = AcornCartridgesFrom(media.cartridges);
|
target->media.cartridges = AcornCartridgesFrom(media.cartridges);
|
||||||
@ -109,17 +110,18 @@ void Analyser::Static::Acorn::AddTargets(const Media &media, std::vector<std::un
|
|||||||
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->has_dfs = !!dfs_catalogue;
|
||||||
target->acorn.has_adfs = !!adfs_catalogue;
|
target->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->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(std::move(target));
|
destination.push_back(std::move(target));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
28
Analyser/Static/Acorn/Target.hpp
Normal file
28
Analyser/Static/Acorn/Target.hpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Target.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 09/03/2018.
|
||||||
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Target_h
|
||||||
|
#define Target_h
|
||||||
|
|
||||||
|
#include "../StaticAnalyser.hpp"
|
||||||
|
|
||||||
|
namespace Analyser {
|
||||||
|
namespace Static {
|
||||||
|
namespace Acorn {
|
||||||
|
|
||||||
|
struct Target: public ::Analyser::Static::Target {
|
||||||
|
bool has_adfs;
|
||||||
|
bool has_dfs;
|
||||||
|
bool should_shift_restart;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Target_h */
|
@ -11,6 +11,8 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "Target.hpp"
|
||||||
|
|
||||||
#include "../../../Storage/Disk/Parsers/CPM.hpp"
|
#include "../../../Storage/Disk/Parsers/CPM.hpp"
|
||||||
#include "../../../Storage/Disk/Encodings/MFM/Parser.hpp"
|
#include "../../../Storage/Disk/Encodings/MFM/Parser.hpp"
|
||||||
|
|
||||||
@ -58,7 +60,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,
|
||||||
const std::unique_ptr<Analyser::Static::Target> &target) {
|
const std::unique_ptr<Analyser::Static::AmstradCPC::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());
|
||||||
@ -153,7 +155,7 @@ static void InspectCatalogue(
|
|||||||
target->loading_command = "cat\n";
|
target->loading_command = "cat\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, const std::unique_ptr<Analyser::Static::Target> &target) {
|
static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, const std::unique_ptr<Analyser::Static::AmstradCPC::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()) {
|
||||||
@ -177,7 +179,7 @@ static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, co
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
|
void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector<std::unique_ptr<Analyser::Static::Target>> &destination) {
|
||||||
std::unique_ptr<Target> target(new Target);
|
std::unique_ptr<Target> target(new Target);
|
||||||
target->machine = Machine::AmstradCPC;
|
target->machine = Machine::AmstradCPC;
|
||||||
target->confidence = 0.5;
|
target->confidence = 0.5;
|
||||||
@ -185,7 +187,7 @@ void Analyser::Static::AmstradCPC::AddTargets(const Media &media, std::vector<st
|
|||||||
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->model = Target::Model::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
|
||||||
|
33
Analyser/Static/AmstradCPC/Target.hpp
Normal file
33
Analyser/Static/AmstradCPC/Target.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// Target.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 09/03/2018.
|
||||||
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Target_h
|
||||||
|
#define Target_h
|
||||||
|
|
||||||
|
#include "../StaticAnalyser.hpp"
|
||||||
|
|
||||||
|
namespace Analyser {
|
||||||
|
namespace Static {
|
||||||
|
namespace AmstradCPC {
|
||||||
|
|
||||||
|
struct Target: public ::Analyser::Static::Target {
|
||||||
|
enum class Model {
|
||||||
|
CPC464,
|
||||||
|
CPC664,
|
||||||
|
CPC6128
|
||||||
|
};
|
||||||
|
|
||||||
|
Model model;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* Target_h */
|
@ -8,11 +8,13 @@
|
|||||||
|
|
||||||
#include "StaticAnalyser.hpp"
|
#include "StaticAnalyser.hpp"
|
||||||
|
|
||||||
|
#include "Target.hpp"
|
||||||
|
|
||||||
#include "../Disassembler/6502.hpp"
|
#include "../Disassembler/6502.hpp"
|
||||||
|
|
||||||
using namespace Analyser::Static::Atari;
|
using namespace Analyser::Static::Atari;
|
||||||
|
|
||||||
static void DeterminePagingFor2kCartridge(Analyser::Static::Target &target, const Storage::Cartridge::Cartridge::Segment &segment) {
|
static void DeterminePagingFor2kCartridge(Analyser::Static::Atari::Target &target, const Storage::Cartridge::Cartridge::Segment &segment) {
|
||||||
// if this is a 2kb cartridge then it's definitely either unpaged or a CommaVid
|
// if this is a 2kb cartridge then it's definitely either unpaged or a CommaVid
|
||||||
uint16_t entry_address, break_address;
|
uint16_t entry_address, break_address;
|
||||||
|
|
||||||
@ -46,10 +48,10 @@ static void DeterminePagingFor2kCartridge(Analyser::Static::Target &target, cons
|
|||||||
// caveat: false positives aren't likely to be problematic; a false positive is a 2KB ROM that always addresses
|
// caveat: false positives aren't likely to be problematic; a false positive is a 2KB ROM that always addresses
|
||||||
// itself so as to land in ROM even if mapped as a CommaVid and this code is on the fence as to whether it
|
// itself so as to land in ROM even if mapped as a CommaVid and this code is on the fence as to whether it
|
||||||
// attempts to modify itself but it probably doesn't
|
// attempts to modify itself but it probably doesn't
|
||||||
if(has_wide_area_store) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::CommaVid;
|
if(has_wide_area_store) target.paging_model = Analyser::Static::Atari::Target::PagingModel::CommaVid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DeterminePagingFor8kCartridge(Analyser::Static::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) {
|
static void DeterminePagingFor8kCartridge(Analyser::Static::Atari::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) {
|
||||||
// Activision stack titles have their vectors at the top of the low 4k, not the top, and
|
// Activision stack titles have their vectors at the top of the low 4k, not the top, and
|
||||||
// always list 0xf000 as both vectors; they do not repeat them, and, inexplicably, they all
|
// always list 0xf000 as both vectors; they do not repeat them, and, inexplicably, they all
|
||||||
// issue an SEI as their first instruction (maybe some sort of relic of the development environment?)
|
// issue an SEI as their first instruction (maybe some sort of relic of the development environment?)
|
||||||
@ -58,12 +60,12 @@ static void DeterminePagingFor8kCartridge(Analyser::Static::Target &target, cons
|
|||||||
(segment.data[8191] != 0xf0 || segment.data[8189] != 0xf0 || segment.data[8190] != 0x00 || segment.data[8188] != 0x00) &&
|
(segment.data[8191] != 0xf0 || segment.data[8189] != 0xf0 || segment.data[8190] != 0x00 || segment.data[8188] != 0x00) &&
|
||||||
segment.data[0] == 0x78
|
segment.data[0] == 0x78
|
||||||
) {
|
) {
|
||||||
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::ActivisionStack;
|
target.paging_model = Analyser::Static::Atari::Target::PagingModel::ActivisionStack;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make an assumption that this is the Atari paging model
|
// make an assumption that this is the Atari paging model
|
||||||
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Atari8k;
|
target.paging_model = Analyser::Static::Atari::Target::PagingModel::Atari8k;
|
||||||
|
|
||||||
std::set<uint16_t> internal_accesses;
|
std::set<uint16_t> internal_accesses;
|
||||||
internal_accesses.insert(disassembly.internal_stores.begin(), disassembly.internal_stores.end());
|
internal_accesses.insert(disassembly.internal_stores.begin(), disassembly.internal_stores.end());
|
||||||
@ -83,13 +85,13 @@ static void DeterminePagingFor8kCartridge(Analyser::Static::Target &target, cons
|
|||||||
tigervision_access_count += masked_address == 0x3f;
|
tigervision_access_count += masked_address == 0x3f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(parker_access_count > atari_access_count) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::ParkerBros;
|
if(parker_access_count > atari_access_count) target.paging_model = Analyser::Static::Atari::Target::PagingModel::ParkerBros;
|
||||||
else if(tigervision_access_count > atari_access_count) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Tigervision;
|
else if(tigervision_access_count > atari_access_count) target.paging_model = Analyser::Static::Atari::Target::PagingModel::Tigervision;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DeterminePagingFor16kCartridge(Analyser::Static::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) {
|
static void DeterminePagingFor16kCartridge(Analyser::Static::Atari::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) {
|
||||||
// make an assumption that this is the Atari paging model
|
// make an assumption that this is the Atari paging model
|
||||||
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Atari16k;
|
target.paging_model = Analyser::Static::Atari::Target::PagingModel::Atari16k;
|
||||||
|
|
||||||
std::set<uint16_t> internal_accesses;
|
std::set<uint16_t> internal_accesses;
|
||||||
internal_accesses.insert(disassembly.internal_stores.begin(), disassembly.internal_stores.end());
|
internal_accesses.insert(disassembly.internal_stores.begin(), disassembly.internal_stores.end());
|
||||||
@ -104,17 +106,17 @@ static void DeterminePagingFor16kCartridge(Analyser::Static::Target &target, con
|
|||||||
mnetwork_access_count += masked_address >= 0x1fe0 && masked_address < 0x1ffb;
|
mnetwork_access_count += masked_address >= 0x1fe0 && masked_address < 0x1ffb;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mnetwork_access_count > atari_access_count) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::MNetwork;
|
if(mnetwork_access_count > atari_access_count) target.paging_model = Analyser::Static::Atari::Target::PagingModel::MNetwork;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DeterminePagingFor64kCartridge(Analyser::Static::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) {
|
static void DeterminePagingFor64kCartridge(Analyser::Static::Atari::Target &target, const Storage::Cartridge::Cartridge::Segment &segment, const Analyser::Static::MOS6502::Disassembly &disassembly) {
|
||||||
// make an assumption that this is a Tigervision if there is a write to 3F
|
// make an assumption that this is a Tigervision if there is a write to 3F
|
||||||
target.atari.paging_model =
|
target.paging_model =
|
||||||
(disassembly.external_stores.find(0x3f) != disassembly.external_stores.end()) ?
|
(disassembly.external_stores.find(0x3f) != disassembly.external_stores.end()) ?
|
||||||
Analyser::Static::Atari2600PagingModel::Tigervision : Analyser::Static::Atari2600PagingModel::MegaBoy;
|
Analyser::Static::Atari::Target::PagingModel::Tigervision : Analyser::Static::Atari::Target::PagingModel::MegaBoy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DeterminePagingForCartridge(Analyser::Static::Target &target, const Storage::Cartridge::Cartridge::Segment &segment) {
|
static void DeterminePagingForCartridge(Analyser::Static::Atari::Target &target, const Storage::Cartridge::Cartridge::Segment &segment) {
|
||||||
if(segment.data.size() == 2048) {
|
if(segment.data.size() == 2048) {
|
||||||
DeterminePagingFor2kCartridge(target, segment);
|
DeterminePagingFor2kCartridge(target, segment);
|
||||||
return;
|
return;
|
||||||
@ -138,16 +140,16 @@ static void DeterminePagingForCartridge(Analyser::Static::Target &target, const
|
|||||||
DeterminePagingFor8kCartridge(target, segment, disassembly);
|
DeterminePagingFor8kCartridge(target, segment, disassembly);
|
||||||
break;
|
break;
|
||||||
case 10495:
|
case 10495:
|
||||||
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Pitfall2;
|
target.paging_model = Analyser::Static::Atari::Target::PagingModel::Pitfall2;
|
||||||
break;
|
break;
|
||||||
case 12288:
|
case 12288:
|
||||||
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::CBSRamPlus;
|
target.paging_model = Analyser::Static::Atari::Target::PagingModel::CBSRamPlus;
|
||||||
break;
|
break;
|
||||||
case 16384:
|
case 16384:
|
||||||
DeterminePagingFor16kCartridge(target, segment, disassembly);
|
DeterminePagingFor16kCartridge(target, segment, disassembly);
|
||||||
break;
|
break;
|
||||||
case 32768:
|
case 32768:
|
||||||
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Atari32k;
|
target.paging_model = Analyser::Static::Atari::Target::PagingModel::Atari32k;
|
||||||
break;
|
break;
|
||||||
case 65536:
|
case 65536:
|
||||||
DeterminePagingFor64kCartridge(target, segment, disassembly);
|
DeterminePagingFor64kCartridge(target, segment, disassembly);
|
||||||
@ -159,8 +161,8 @@ static void DeterminePagingForCartridge(Analyser::Static::Target &target, const
|
|||||||
// check for a Super Chip. Atari ROM images [almost] always have the same value stored over RAM
|
// check for a Super Chip. Atari ROM images [almost] always have the same value stored over RAM
|
||||||
// regions; when they don't they at least seem to have the first 128 bytes be the same as the
|
// regions; when they don't they at least seem to have the first 128 bytes be the same as the
|
||||||
// next 128 bytes. So check for that.
|
// next 128 bytes. So check for that.
|
||||||
if( target.atari.paging_model != Analyser::Static::Atari2600PagingModel::CBSRamPlus &&
|
if( target.paging_model != Analyser::Static::Atari::Target::PagingModel::CBSRamPlus &&
|
||||||
target.atari.paging_model != Analyser::Static::Atari2600PagingModel::MNetwork) {
|
target.paging_model != Analyser::Static::Atari::Target::PagingModel::MNetwork) {
|
||||||
bool has_superchip = true;
|
bool has_superchip = true;
|
||||||
for(std::size_t address = 0; address < 128; address++) {
|
for(std::size_t address = 0; address < 128; address++) {
|
||||||
if(segment.data[address] != segment.data[address+128]) {
|
if(segment.data[address] != segment.data[address+128]) {
|
||||||
@ -168,24 +170,24 @@ static void DeterminePagingForCartridge(Analyser::Static::Target &target, const
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
target.atari.uses_superchip = has_superchip;
|
target.uses_superchip = has_superchip;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for a Tigervision or Tigervision-esque scheme
|
// check for a Tigervision or Tigervision-esque scheme
|
||||||
if(target.atari.paging_model == Analyser::Static::Atari2600PagingModel::None && segment.data.size() > 4096) {
|
if(target.paging_model == Analyser::Static::Atari::Target::PagingModel::None && segment.data.size() > 4096) {
|
||||||
bool looks_like_tigervision = disassembly.external_stores.find(0x3f) != disassembly.external_stores.end();
|
bool looks_like_tigervision = disassembly.external_stores.find(0x3f) != disassembly.external_stores.end();
|
||||||
if(looks_like_tigervision) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Tigervision;
|
if(looks_like_tigervision) target.paging_model = Analyser::Static::Atari::Target::PagingModel::Tigervision;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyser::Static::Atari::AddTargets(const Media &media, std::vector<std::unique_ptr<Target>> &destination) {
|
void Analyser::Static::Atari::AddTargets(const Media &media, std::vector<std::unique_ptr<Analyser::Static::Target>> &destination) {
|
||||||
// TODO: sanity checking; is this image really for an Atari 2600?
|
// TODO: sanity checking; is this image really for an Atari 2600?
|
||||||
std::unique_ptr<Target> target(new Target);
|
std::unique_ptr<Analyser::Static::Atari::Target> target(new Analyser::Static::Atari::Target);
|
||||||
target->machine = Machine::Atari2600;
|
target->machine = Machine::Atari2600;
|
||||||
target->confidence = 0.5;
|
target->confidence = 0.5;
|
||||||
target->media.cartridges = media.cartridges;
|
target->media.cartridges = media.cartridges;
|
||||||
target->atari.paging_model = Atari2600PagingModel::None;
|
target->paging_model = Analyser::Static::Atari::Target::PagingModel::None;
|
||||||
target->atari.uses_superchip = false;
|
target->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()) {
|
||||||
|
43
Analyser/Static/Atari/Target.hpp
Normal file
43
Analyser/Static/Atari/Target.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// Target.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 09/03/2018.
|
||||||
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Target_h
|
||||||
|
#define Target_h
|
||||||
|
|
||||||
|
#include "../StaticAnalyser.hpp"
|
||||||
|
|
||||||
|
namespace Analyser {
|
||||||
|
namespace Static {
|
||||||
|
namespace Atari {
|
||||||
|
|
||||||
|
struct Target: public ::Analyser::Static::Target {
|
||||||
|
enum class PagingModel {
|
||||||
|
None,
|
||||||
|
CommaVid,
|
||||||
|
Atari8k,
|
||||||
|
Atari16k,
|
||||||
|
Atari32k,
|
||||||
|
ActivisionStack,
|
||||||
|
ParkerBros,
|
||||||
|
Tigervision,
|
||||||
|
CBSRamPlus,
|
||||||
|
MNetwork,
|
||||||
|
MegaBoy,
|
||||||
|
Pitfall2
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: shouldn't these be properties of the cartridge?
|
||||||
|
PagingModel paging_model;
|
||||||
|
bool uses_superchip;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Target_h */
|
@ -11,6 +11,7 @@
|
|||||||
#include "Disk.hpp"
|
#include "Disk.hpp"
|
||||||
#include "File.hpp"
|
#include "File.hpp"
|
||||||
#include "Tape.hpp"
|
#include "Tape.hpp"
|
||||||
|
#include "Target.hpp"
|
||||||
#include "../../../Storage/Cartridge/Encodings/CommodoreROM.hpp"
|
#include "../../../Storage/Cartridge/Encodings/CommodoreROM.hpp"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -38,7 +39,7 @@ 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<std::unique_ptr<Target>> &destination) {
|
void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<std::unique_ptr<Analyser::Static::Target>> &destination) {
|
||||||
std::unique_ptr<Target> target(new Target);
|
std::unique_ptr<Target> target(new Target);
|
||||||
target->machine = Machine::Vic20; // TODO: machine estimation
|
target->machine = Machine::Vic20; // TODO: machine estimation
|
||||||
target->confidence = 0.5; // TODO: a proper estimation
|
target->confidence = 0.5; // TODO: a proper estimation
|
||||||
@ -73,7 +74,7 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<std
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!files.empty()) {
|
if(!files.empty()) {
|
||||||
target->vic20.memory_model = Vic20MemoryModel::Unexpanded;
|
target->memory_model = Target::MemoryModel::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()) {
|
||||||
@ -89,10 +90,10 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<std
|
|||||||
case 0x1001:
|
case 0x1001:
|
||||||
default: break;
|
default: break;
|
||||||
case 0x1201:
|
case 0x1201:
|
||||||
target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
|
target->memory_model = Target::MemoryModel::ThirtyTwoKB;
|
||||||
break;
|
break;
|
||||||
case 0x0401:
|
case 0x0401:
|
||||||
target->vic20.memory_model = Vic20MemoryModel::EightKB;
|
target->memory_model = Target::MemoryModel::EightKB;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,9 +130,9 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<std
|
|||||||
// 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->memory_model = Target::MemoryModel::ThirtyTwoKB;
|
||||||
else if(target->vic20.memory_model == Vic20MemoryModel::Unexpanded && !(starting_address >= 0x1000 || starting_address+file_size < 0x0400))
|
else if(target->memory_model == Target::MemoryModel::Unexpanded && !(starting_address >= 0x1000 || starting_address+file_size < 0x0400))
|
||||||
target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
|
target->memory_model = Target::MemoryModel::ThirtyTwoKB;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
Analyser/Static/Commodore/Target.hpp
Normal file
33
Analyser/Static/Commodore/Target.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// Target.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 09/03/2018.
|
||||||
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Target_h
|
||||||
|
#define Target_h
|
||||||
|
|
||||||
|
#include "../StaticAnalyser.hpp"
|
||||||
|
|
||||||
|
namespace Analyser {
|
||||||
|
namespace Static {
|
||||||
|
namespace Commodore {
|
||||||
|
|
||||||
|
struct Target: public ::Analyser::Static::Target {
|
||||||
|
enum class MemoryModel {
|
||||||
|
Unexpanded,
|
||||||
|
EightKB,
|
||||||
|
ThirtyTwoKB
|
||||||
|
};
|
||||||
|
|
||||||
|
MemoryModel memory_model;
|
||||||
|
bool has_c1540;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Target_h */
|
@ -9,6 +9,7 @@
|
|||||||
#include "StaticAnalyser.hpp"
|
#include "StaticAnalyser.hpp"
|
||||||
|
|
||||||
#include "Tape.hpp"
|
#include "Tape.hpp"
|
||||||
|
#include "Target.hpp"
|
||||||
#include "../Disassembler/6502.hpp"
|
#include "../Disassembler/6502.hpp"
|
||||||
#include "../Disassembler/AddressMapper.hpp"
|
#include "../Disassembler/AddressMapper.hpp"
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ 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<std::unique_ptr<Target>> &destination) {
|
void Analyser::Static::Oric::AddTargets(const Media &media, std::vector<std::unique_ptr<Analyser::Static::Target>> &destination) {
|
||||||
std::unique_ptr<Target> target(new Target);
|
std::unique_ptr<Target> target(new Target);
|
||||||
target->machine = Machine::Oric;
|
target->machine = Machine::Oric;
|
||||||
target->confidence = 0.5;
|
target->confidence = 0.5;
|
||||||
@ -104,15 +105,15 @@ void Analyser::Static::Oric::AddTargets(const Media &media, std::vector<std::uni
|
|||||||
|
|
||||||
// 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->has_microdisc = true;
|
||||||
target->media.disks = media.disks;
|
target->media.disks = media.disks;
|
||||||
} else {
|
} else {
|
||||||
target->oric.has_microdisc = false;
|
target->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->use_atmos_rom = basic11_votes >= basic10_votes;
|
||||||
if(target->oric.has_microdisc) target->oric.use_atmos_rom = true;
|
if(target->has_microdisc) target->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(std::move(target));
|
destination.push_back(std::move(target));
|
||||||
|
25
Analyser/Static/Oric/Target.hpp
Normal file
25
Analyser/Static/Oric/Target.hpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// Target.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 09/03/2018.
|
||||||
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Target_h
|
||||||
|
#define Target_h
|
||||||
|
|
||||||
|
namespace Analyser {
|
||||||
|
namespace Static {
|
||||||
|
namespace Oric {
|
||||||
|
|
||||||
|
struct Target: public ::Analyser::Static::Target {
|
||||||
|
bool use_atmos_rom;
|
||||||
|
bool has_microdisc;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Target_h */
|
@ -21,39 +21,6 @@
|
|||||||
namespace Analyser {
|
namespace Analyser {
|
||||||
namespace Static {
|
namespace Static {
|
||||||
|
|
||||||
enum class Vic20MemoryModel {
|
|
||||||
Unexpanded,
|
|
||||||
EightKB,
|
|
||||||
ThirtyTwoKB
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class Atari2600PagingModel {
|
|
||||||
None,
|
|
||||||
CommaVid,
|
|
||||||
Atari8k,
|
|
||||||
Atari16k,
|
|
||||||
Atari32k,
|
|
||||||
ActivisionStack,
|
|
||||||
ParkerBros,
|
|
||||||
Tigervision,
|
|
||||||
CBSRamPlus,
|
|
||||||
MNetwork,
|
|
||||||
MegaBoy,
|
|
||||||
Pitfall2
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ZX8081MemoryModel {
|
|
||||||
Unexpanded,
|
|
||||||
SixteenKB,
|
|
||||||
SixtyFourKB
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class AmstradCPCModel {
|
|
||||||
CPC464,
|
|
||||||
CPC664,
|
|
||||||
CPC6128
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
A list of disks, tapes and cartridges.
|
A list of disks, tapes and cartridges.
|
||||||
*/
|
*/
|
||||||
@ -72,45 +39,13 @@ struct Media {
|
|||||||
and instructions on how to launch the software attached, plus a measure of confidence in this target's correctness.
|
and instructions on how to launch the software attached, plus a measure of confidence in this target's correctness.
|
||||||
*/
|
*/
|
||||||
struct Target {
|
struct Target {
|
||||||
|
virtual ~Target() {}
|
||||||
|
|
||||||
Machine machine;
|
Machine machine;
|
||||||
Media media;
|
Media media;
|
||||||
|
|
||||||
float confidence;
|
float confidence;
|
||||||
std::string loading_command;
|
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.
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
bool has_adfs;
|
|
||||||
bool has_dfs;
|
|
||||||
bool should_shift_restart;
|
|
||||||
} acorn;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
Atari2600PagingModel paging_model;
|
|
||||||
bool uses_superchip;
|
|
||||||
} atari;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
bool use_atmos_rom;
|
|
||||||
bool has_microdisc;
|
|
||||||
} oric;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
Vic20MemoryModel memory_model;
|
|
||||||
bool has_c1540;
|
|
||||||
} vic20;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
ZX8081MemoryModel memory_model;
|
|
||||||
bool isZX81;
|
|
||||||
} zx8081;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
AmstradCPCModel model;
|
|
||||||
} amstradcpc;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Target.hpp"
|
||||||
#include "../../../Storage/Tape/Parsers/ZX8081.hpp"
|
#include "../../../Storage/Tape/Parsers/ZX8081.hpp"
|
||||||
|
|
||||||
static std::vector<Storage::Data::ZX8081::File> GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
static std::vector<Storage::Data::ZX8081::File> GetFiles(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
||||||
@ -27,41 +28,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<std::unique_ptr<Target>> &destination, TargetPlatform::IntType potential_platforms) {
|
void Analyser::Static::ZX8081::AddTargets(const Media &media, std::vector<std::unique_ptr<::Analyser::Static::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()) {
|
||||||
std::unique_ptr<Target> target(new Target);
|
Target *target = new Target;
|
||||||
|
destination.push_back(std::unique_ptr<::Analyser::Static::Target>(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->isZX81 = files.front().isZX81;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TargetPlatform::ZX80: target->zx8081.isZX81 = false; break;
|
case TargetPlatform::ZX80: target->isZX81 = false; break;
|
||||||
case TargetPlatform::ZX81: target->zx8081.isZX81 = true; break;
|
case TargetPlatform::ZX81: target->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->memory_model = Target::MemoryModel::SixteenKB;
|
||||||
} else {
|
} else {
|
||||||
target->zx8081.memory_model = ZX8081MemoryModel::Unexpanded;
|
target->memory_model = Target::MemoryModel::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->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(std::move(target));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
Analyser/Static/ZX8081/Target.hpp
Normal file
33
Analyser/Static/ZX8081/Target.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// Target.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 09/03/2018.
|
||||||
|
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Target_h
|
||||||
|
#define Target_h
|
||||||
|
|
||||||
|
#include "../StaticAnalyser.hpp"
|
||||||
|
|
||||||
|
namespace Analyser {
|
||||||
|
namespace Static {
|
||||||
|
namespace ZX8081 {
|
||||||
|
|
||||||
|
struct Target: public ::Analyser::Static::Target {
|
||||||
|
enum class MemoryModel {
|
||||||
|
Unexpanded,
|
||||||
|
SixteenKB,
|
||||||
|
SixtyFourKB
|
||||||
|
};
|
||||||
|
|
||||||
|
MemoryModel memory_model;
|
||||||
|
bool isZX81;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Target_h */
|
@ -29,6 +29,8 @@
|
|||||||
#include "../../ClockReceiver/ForceInline.hpp"
|
#include "../../ClockReceiver/ForceInline.hpp"
|
||||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||||
|
|
||||||
|
#include "../../Analyser/Static/AmstradCPC/Target.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -874,19 +876,21 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The ConfigurationTarget entry point; should configure this meachine as described by @c target.
|
/// The ConfigurationTarget entry point; should configure this meachine as described by @c target.
|
||||||
void configure_as_target(const Analyser::Static::Target &target) override final {
|
void configure_as_target(const Analyser::Static::Target *target) override final {
|
||||||
switch(target.amstradcpc.model) {
|
auto *const cpc_target = dynamic_cast<const Analyser::Static::AmstradCPC::Target *>(target);
|
||||||
case Analyser::Static::AmstradCPCModel::CPC464:
|
|
||||||
|
switch(cpc_target->model) {
|
||||||
|
case Analyser::Static::AmstradCPC::Target::Model::CPC464:
|
||||||
rom_model_ = ROMType::OS464;
|
rom_model_ = ROMType::OS464;
|
||||||
has_128k_ = false;
|
has_128k_ = false;
|
||||||
has_fdc_ = false;
|
has_fdc_ = false;
|
||||||
break;
|
break;
|
||||||
case Analyser::Static::AmstradCPCModel::CPC664:
|
case Analyser::Static::AmstradCPC::Target::Model::CPC664:
|
||||||
rom_model_ = ROMType::OS664;
|
rom_model_ = ROMType::OS664;
|
||||||
has_128k_ = false;
|
has_128k_ = false;
|
||||||
has_fdc_ = true;
|
has_fdc_ = true;
|
||||||
break;
|
break;
|
||||||
case Analyser::Static::AmstradCPCModel::CPC6128:
|
case Analyser::Static::AmstradCPC::Target::Model::CPC6128:
|
||||||
rom_model_ = ROMType::OS6128;
|
rom_model_ = ROMType::OS6128;
|
||||||
has_128k_ = true;
|
has_128k_ = true;
|
||||||
has_fdc_ = true;
|
has_fdc_ = true;
|
||||||
@ -908,11 +912,11 @@ class ConcreteMachine:
|
|||||||
read_pointers_[3] = roms_[upper_rom_].data();
|
read_pointers_[3] = roms_[upper_rom_].data();
|
||||||
|
|
||||||
// Type whatever is required.
|
// Type whatever is required.
|
||||||
if(target.loading_command.length()) {
|
if(target->loading_command.length()) {
|
||||||
type_string(target.loading_command);
|
type_string(target->loading_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_media(target.media);
|
insert_media(target->media);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insert_media(const Analyser::Static::Media &media) override final {
|
bool insert_media(const Analyser::Static::Media &media) override final {
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include "../CRTMachine.hpp"
|
#include "../CRTMachine.hpp"
|
||||||
#include "../JoystickMachine.hpp"
|
#include "../JoystickMachine.hpp"
|
||||||
|
|
||||||
|
#include "../../Analyser/Static/Atari/Target.hpp"
|
||||||
|
|
||||||
#include "Cartridges/Atari8k.hpp"
|
#include "Cartridges/Atari8k.hpp"
|
||||||
#include "Cartridges/Atari16k.hpp"
|
#include "Cartridges/Atari16k.hpp"
|
||||||
#include "Cartridges/Atari32k.hpp"
|
#include "Cartridges/Atari32k.hpp"
|
||||||
@ -89,35 +91,38 @@ class ConcreteMachine:
|
|||||||
close_output();
|
close_output();
|
||||||
}
|
}
|
||||||
|
|
||||||
void configure_as_target(const Analyser::Static::Target &target) override {
|
void configure_as_target(const Analyser::Static::Target *target) override {
|
||||||
const std::vector<uint8_t> &rom = target.media.cartridges.front()->get_segments().front().data;
|
auto *const atari_target = dynamic_cast<const Analyser::Static::Atari::Target *>(target);
|
||||||
switch(target.atari.paging_model) {
|
const std::vector<uint8_t> &rom = target->media.cartridges.front()->get_segments().front().data;
|
||||||
case Analyser::Static::Atari2600PagingModel::ActivisionStack: bus_.reset(new Cartridge::Cartridge<Cartridge::ActivisionStack>(rom)); break;
|
|
||||||
case Analyser::Static::Atari2600PagingModel::CBSRamPlus: bus_.reset(new Cartridge::Cartridge<Cartridge::CBSRAMPlus>(rom)); break;
|
|
||||||
case Analyser::Static::Atari2600PagingModel::CommaVid: bus_.reset(new Cartridge::Cartridge<Cartridge::CommaVid>(rom)); break;
|
|
||||||
case Analyser::Static::Atari2600PagingModel::MegaBoy: bus_.reset(new Cartridge::Cartridge<Cartridge::MegaBoy>(rom)); break;
|
|
||||||
case Analyser::Static::Atari2600PagingModel::MNetwork: bus_.reset(new Cartridge::Cartridge<Cartridge::MNetwork>(rom)); break;
|
|
||||||
case Analyser::Static::Atari2600PagingModel::None: bus_.reset(new Cartridge::Cartridge<Cartridge::Unpaged>(rom)); break;
|
|
||||||
case Analyser::Static::Atari2600PagingModel::ParkerBros: bus_.reset(new Cartridge::Cartridge<Cartridge::ParkerBros>(rom)); break;
|
|
||||||
case Analyser::Static::Atari2600PagingModel::Pitfall2: bus_.reset(new Cartridge::Cartridge<Cartridge::Pitfall2>(rom)); break;
|
|
||||||
case Analyser::Static::Atari2600PagingModel::Tigervision: bus_.reset(new Cartridge::Cartridge<Cartridge::Tigervision>(rom)); break;
|
|
||||||
|
|
||||||
case Analyser::Static::Atari2600PagingModel::Atari8k:
|
using PagingModel = Analyser::Static::Atari::Target::PagingModel;
|
||||||
if(target.atari.uses_superchip) {
|
switch(atari_target->paging_model) {
|
||||||
|
case PagingModel::ActivisionStack: bus_.reset(new Cartridge::Cartridge<Cartridge::ActivisionStack>(rom)); break;
|
||||||
|
case PagingModel::CBSRamPlus: bus_.reset(new Cartridge::Cartridge<Cartridge::CBSRAMPlus>(rom)); break;
|
||||||
|
case PagingModel::CommaVid: bus_.reset(new Cartridge::Cartridge<Cartridge::CommaVid>(rom)); break;
|
||||||
|
case PagingModel::MegaBoy: bus_.reset(new Cartridge::Cartridge<Cartridge::MegaBoy>(rom)); break;
|
||||||
|
case PagingModel::MNetwork: bus_.reset(new Cartridge::Cartridge<Cartridge::MNetwork>(rom)); break;
|
||||||
|
case PagingModel::None: bus_.reset(new Cartridge::Cartridge<Cartridge::Unpaged>(rom)); break;
|
||||||
|
case PagingModel::ParkerBros: bus_.reset(new Cartridge::Cartridge<Cartridge::ParkerBros>(rom)); break;
|
||||||
|
case PagingModel::Pitfall2: bus_.reset(new Cartridge::Cartridge<Cartridge::Pitfall2>(rom)); break;
|
||||||
|
case PagingModel::Tigervision: bus_.reset(new Cartridge::Cartridge<Cartridge::Tigervision>(rom)); break;
|
||||||
|
|
||||||
|
case PagingModel::Atari8k:
|
||||||
|
if(atari_target->uses_superchip) {
|
||||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari8kSuperChip>(rom));
|
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari8kSuperChip>(rom));
|
||||||
} else {
|
} else {
|
||||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari8k>(rom));
|
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari8k>(rom));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Analyser::Static::Atari2600PagingModel::Atari16k:
|
case PagingModel::Atari16k:
|
||||||
if(target.atari.uses_superchip) {
|
if(atari_target->uses_superchip) {
|
||||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari16kSuperChip>(rom));
|
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari16kSuperChip>(rom));
|
||||||
} else {
|
} else {
|
||||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari16k>(rom));
|
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari16k>(rom));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Analyser::Static::Atari2600PagingModel::Atari32k:
|
case PagingModel::Atari32k:
|
||||||
if(target.atari.uses_superchip) {
|
if(atari_target->uses_superchip) {
|
||||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari32kSuperChip>(rom));
|
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari32kSuperChip>(rom));
|
||||||
} else {
|
} else {
|
||||||
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari32k>(rom));
|
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari32k>(rom));
|
||||||
|
@ -150,9 +150,9 @@ class ConcreteMachine:
|
|||||||
z80_.run_for(cycles);
|
z80_.run_for(cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void configure_as_target(const Analyser::Static::Target &target) override {
|
void configure_as_target(const Analyser::Static::Target *target) override {
|
||||||
// Insert the media.
|
// Insert the media.
|
||||||
insert_media(target.media);
|
insert_media(target->media);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insert_media(const Analyser::Static::Media &media) override {
|
bool insert_media(const Analyser::Static::Media &media) override {
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
#include "../../../Configurable/StandardOptions.hpp"
|
#include "../../../Configurable/StandardOptions.hpp"
|
||||||
|
|
||||||
|
#include "../../../Analyser/Static/Commodore/Target.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@ -363,24 +365,26 @@ class ConcreteMachine:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void configure_as_target(const Analyser::Static::Target &target) override final {
|
void configure_as_target(const Analyser::Static::Target *target) override final {
|
||||||
if(target.loading_command.length()) {
|
auto *const commodore_target = dynamic_cast<const Analyser::Static::Commodore::Target *>(target);
|
||||||
type_string(target.loading_command);
|
|
||||||
|
if(target->loading_command.length()) {
|
||||||
|
type_string(target->loading_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(target.vic20.memory_model) {
|
switch(commodore_target->memory_model) {
|
||||||
case Analyser::Static::Vic20MemoryModel::Unexpanded:
|
case Analyser::Static::Commodore::Target::MemoryModel::Unexpanded:
|
||||||
set_memory_size(Default);
|
set_memory_size(Default);
|
||||||
break;
|
break;
|
||||||
case Analyser::Static::Vic20MemoryModel::EightKB:
|
case Analyser::Static::Commodore::Target::MemoryModel::EightKB:
|
||||||
set_memory_size(ThreeKB);
|
set_memory_size(ThreeKB);
|
||||||
break;
|
break;
|
||||||
case Analyser::Static::Vic20MemoryModel::ThirtyTwoKB:
|
case Analyser::Static::Commodore::Target::MemoryModel::ThirtyTwoKB:
|
||||||
set_memory_size(ThirtyTwoKB);
|
set_memory_size(ThirtyTwoKB);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(target.media.disks.size()) {
|
if(target->media.disks.size()) {
|
||||||
// construct the 1540
|
// construct the 1540
|
||||||
c1540_.reset(new ::Commodore::C1540::Machine(Commodore::C1540::Machine::C1540));
|
c1540_.reset(new ::Commodore::C1540::Machine(Commodore::C1540::Machine::C1540));
|
||||||
|
|
||||||
@ -391,7 +395,7 @@ class ConcreteMachine:
|
|||||||
c1540_->set_rom_fetcher(rom_fetcher_);
|
c1540_->set_rom_fetcher(rom_fetcher_);
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_media(target.media);
|
insert_media(target->media);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insert_media(const Analyser::Static::Media &media) override final {
|
bool insert_media(const Analyser::Static::Media &media) override final {
|
||||||
|
@ -23,7 +23,7 @@ namespace ConfigurationTarget {
|
|||||||
class Machine {
|
class Machine {
|
||||||
public:
|
public:
|
||||||
/// Instructs the machine to configure itself as described by @c target and insert the included media.
|
/// Instructs the machine to configure itself as described by @c target and insert the included media.
|
||||||
virtual void configure_as_target(const Analyser::Static::Target &target) = 0;
|
virtual void configure_as_target(const Analyser::Static::Target *target) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Requests that the machine insert @c media as a modification to current state
|
Requests that the machine insert @c media as a modification to current state
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "../../Storage/Tape/Tape.hpp"
|
#include "../../Storage/Tape/Tape.hpp"
|
||||||
|
|
||||||
#include "../Utility/Typer.hpp"
|
#include "../Utility/Typer.hpp"
|
||||||
|
#include "../../Analyser/Static/Acorn/Target.hpp"
|
||||||
|
|
||||||
#include "Interrupts.hpp"
|
#include "Interrupts.hpp"
|
||||||
#include "Keyboard.hpp"
|
#include "Keyboard.hpp"
|
||||||
@ -123,28 +124,30 @@ class ConcreteMachine:
|
|||||||
if(is_holding_shift_) set_key_state(KeyShift, true);
|
if(is_holding_shift_) set_key_state(KeyShift, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void configure_as_target(const Analyser::Static::Target &target) override final {
|
void configure_as_target(const Analyser::Static::Target *target) override final {
|
||||||
if(target.loading_command.length()) {
|
auto *const acorn_target = dynamic_cast<const Analyser::Static::Acorn::Target *>(target);
|
||||||
type_string(target.loading_command);
|
|
||||||
|
if(target->loading_command.length()) {
|
||||||
|
type_string(target->loading_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(target.acorn.should_shift_restart) {
|
if(acorn_target->should_shift_restart) {
|
||||||
shift_restart_counter_ = 1000000;
|
shift_restart_counter_ = 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(target.acorn.has_dfs || target.acorn.has_adfs) {
|
if(acorn_target->has_dfs || acorn_target->has_adfs) {
|
||||||
plus3_.reset(new Plus3);
|
plus3_.reset(new Plus3);
|
||||||
|
|
||||||
if(target.acorn.has_dfs) {
|
if(acorn_target->has_dfs) {
|
||||||
set_rom(ROMSlot0, dfs_, true);
|
set_rom(ROMSlot0, dfs_, true);
|
||||||
}
|
}
|
||||||
if(target.acorn.has_adfs) {
|
if(acorn_target->has_adfs) {
|
||||||
set_rom(ROMSlot4, adfs1_, true);
|
set_rom(ROMSlot4, adfs1_, true);
|
||||||
set_rom(ROMSlot5, adfs2_, true);
|
set_rom(ROMSlot5, adfs2_, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_media(target.media);
|
insert_media(target->media);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insert_media(const Analyser::Static::Media &media) override final {
|
bool insert_media(const Analyser::Static::Media &media) override final {
|
||||||
|
@ -178,20 +178,20 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void configure_as_target(const Analyser::Static::Target &target) override {
|
void configure_as_target(const Analyser::Static::Target *target) override {
|
||||||
// Add a disk cartridge if any disks were supplied.
|
// Add a disk cartridge if any disks were supplied.
|
||||||
if(!target.media.disks.empty()) {
|
if(!target->media.disks.empty()) {
|
||||||
map(2, 0, 0x4000, 0x2000);
|
map(2, 0, 0x4000, 0x2000);
|
||||||
unmap(2, 0x6000, 0x2000);
|
unmap(2, 0x6000, 0x2000);
|
||||||
memory_slots_[2].set_handler(new DiskROM(memory_slots_[2].source));
|
memory_slots_[2].set_handler(new DiskROM(memory_slots_[2].source));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert the media.
|
// Insert the media.
|
||||||
insert_media(target.media);
|
insert_media(target->media);
|
||||||
|
|
||||||
// Type whatever has been requested.
|
// Type whatever has been requested.
|
||||||
if(target.loading_command.length()) {
|
if(target->loading_command.length()) {
|
||||||
type_string(target.loading_command);
|
type_string(target->loading_command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include "../../Configurable/StandardOptions.hpp"
|
#include "../../Configurable/StandardOptions.hpp"
|
||||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||||
|
|
||||||
|
#include "../../Analyser/Static/Oric/Target.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -262,18 +264,20 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// to satisfy ConfigurationTarget::Machine
|
// to satisfy ConfigurationTarget::Machine
|
||||||
void configure_as_target(const Analyser::Static::Target &target) override final {
|
void configure_as_target(const Analyser::Static::Target *target) override final {
|
||||||
if(target.oric.has_microdisc) {
|
auto *const oric_target = dynamic_cast<const Analyser::Static::Oric::Target *>(target);
|
||||||
|
|
||||||
|
if(oric_target->has_microdisc) {
|
||||||
microdisc_is_enabled_ = true;
|
microdisc_is_enabled_ = true;
|
||||||
microdisc_did_change_paging_flags(µdisc_);
|
microdisc_did_change_paging_flags(µdisc_);
|
||||||
microdisc_.set_delegate(this);
|
microdisc_.set_delegate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(target.loading_command.length()) {
|
if(target->loading_command.length()) {
|
||||||
type_string(target.loading_command);
|
type_string(target->loading_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(target.oric.use_atmos_rom) {
|
if(oric_target->use_atmos_rom) {
|
||||||
std::memcpy(rom_, basic11_rom_.data(), std::min(basic11_rom_.size(), sizeof(rom_)));
|
std::memcpy(rom_, basic11_rom_.data(), std::min(basic11_rom_.size(), sizeof(rom_)));
|
||||||
|
|
||||||
is_using_basic11_ = true;
|
is_using_basic11_ = true;
|
||||||
@ -289,7 +293,7 @@ class ConcreteMachine:
|
|||||||
tape_speed_address_ = 0x67;
|
tape_speed_address_ = 0x67;
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_media(target.media);
|
insert_media(target->media);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insert_media(const Analyser::Static::Media &media) override final {
|
bool insert_media(const Analyser::Static::Media &media) override final {
|
||||||
|
@ -22,10 +22,10 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
::Machine::DynamicMachine *MachineForTarget(const Analyser::Static::Target &target, const ROMMachine::ROMFetcher &rom_fetcher, Machine::Error &error) {
|
::Machine::DynamicMachine *MachineForTarget(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher, Machine::Error &error) {
|
||||||
error = Machine::Error::None;
|
error = Machine::Error::None;
|
||||||
::Machine::DynamicMachine *machine = nullptr;
|
::Machine::DynamicMachine *machine = nullptr;
|
||||||
switch(target.machine) {
|
switch(target->machine) {
|
||||||
case Analyser::Machine::AmstradCPC: machine = new Machine::TypedDynamicMachine<AmstradCPC::Machine>(AmstradCPC::Machine::AmstradCPC()); break;
|
case Analyser::Machine::AmstradCPC: machine = new Machine::TypedDynamicMachine<AmstradCPC::Machine>(AmstradCPC::Machine::AmstradCPC()); break;
|
||||||
case Analyser::Machine::Atari2600: machine = new Machine::TypedDynamicMachine<Atari2600::Machine>(Atari2600::Machine::Atari2600()); break;
|
case Analyser::Machine::Atari2600: machine = new Machine::TypedDynamicMachine<Atari2600::Machine>(Atari2600::Machine::Atari2600()); break;
|
||||||
case Analyser::Machine::ColecoVision: machine = new Machine::TypedDynamicMachine<Coleco::Vision::Machine>(Coleco::Vision::Machine::ColecoVision()); break;
|
case Analyser::Machine::ColecoVision: machine = new Machine::TypedDynamicMachine<Coleco::Vision::Machine>(Coleco::Vision::Machine::ColecoVision()); break;
|
||||||
@ -71,7 +71,7 @@ namespace {
|
|||||||
if(targets.size() > 1) {
|
if(targets.size() > 1) {
|
||||||
std::vector<std::unique_ptr<Machine::DynamicMachine>> machines;
|
std::vector<std::unique_ptr<Machine::DynamicMachine>> machines;
|
||||||
for(const auto &target: targets) {
|
for(const auto &target: targets) {
|
||||||
machines.emplace_back(MachineForTarget(*target, rom_fetcher, error));
|
machines.emplace_back(MachineForTarget(target.get(), rom_fetcher, error));
|
||||||
|
|
||||||
// Exit early if any errors have occurred.
|
// Exit early if any errors have occurred.
|
||||||
if(error != Error::None) {
|
if(error != Error::None) {
|
||||||
@ -89,7 +89,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// There's definitely exactly one target.
|
// There's definitely exactly one target.
|
||||||
return MachineForTarget(*targets.front(), rom_fetcher, error);
|
return MachineForTarget(targets.front().get(), rom_fetcher, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Machine::ShortNameForTargetMachine(const Analyser::Machine machine) {
|
std::string Machine::ShortNameForTargetMachine(const Analyser::Machine machine) {
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
|
||||||
|
|
||||||
|
#include "../../Analyser/Static/ZX8081/Target.hpp"
|
||||||
|
|
||||||
#include "Keyboard.hpp"
|
#include "Keyboard.hpp"
|
||||||
#include "Video.hpp"
|
#include "Video.hpp"
|
||||||
|
|
||||||
@ -277,8 +279,9 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
z80_.run_for(cycles);
|
z80_.run_for(cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void configure_as_target(const Analyser::Static::Target &target) override final {
|
void configure_as_target(const Analyser::Static::Target *target) override final {
|
||||||
is_zx81_ = target.zx8081.isZX81;
|
auto *const zx8081_target = dynamic_cast<const Analyser::Static::ZX8081::Target *>(target);
|
||||||
|
is_zx81_ = zx8081_target->isZX81;
|
||||||
if(is_zx81_) {
|
if(is_zx81_) {
|
||||||
rom_ = zx81_rom_;
|
rom_ = zx81_rom_;
|
||||||
tape_trap_address_ = 0x37c;
|
tape_trap_address_ = 0x37c;
|
||||||
@ -298,18 +301,18 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
rom_mask_ = static_cast<uint16_t>(rom_.size() - 1);
|
rom_mask_ = static_cast<uint16_t>(rom_.size() - 1);
|
||||||
|
|
||||||
switch(target.zx8081.memory_model) {
|
switch(zx8081_target->memory_model) {
|
||||||
case Analyser::Static::ZX8081MemoryModel::Unexpanded:
|
case Analyser::Static::ZX8081::Target::MemoryModel::Unexpanded:
|
||||||
ram_.resize(1024);
|
ram_.resize(1024);
|
||||||
ram_base_ = 16384;
|
ram_base_ = 16384;
|
||||||
ram_mask_ = 1023;
|
ram_mask_ = 1023;
|
||||||
break;
|
break;
|
||||||
case Analyser::Static::ZX8081MemoryModel::SixteenKB:
|
case Analyser::Static::ZX8081::Target::MemoryModel::SixteenKB:
|
||||||
ram_.resize(16384);
|
ram_.resize(16384);
|
||||||
ram_base_ = 16384;
|
ram_base_ = 16384;
|
||||||
ram_mask_ = 16383;
|
ram_mask_ = 16383;
|
||||||
break;
|
break;
|
||||||
case Analyser::Static::ZX8081MemoryModel::SixtyFourKB:
|
case Analyser::Static::ZX8081::Target::MemoryModel::SixtyFourKB:
|
||||||
ram_.resize(65536);
|
ram_.resize(65536);
|
||||||
ram_base_ = 8192;
|
ram_base_ = 8192;
|
||||||
ram_mask_ = 65535;
|
ram_mask_ = 65535;
|
||||||
@ -317,11 +320,11 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
Memory::Fuzz(ram_);
|
Memory::Fuzz(ram_);
|
||||||
|
|
||||||
if(target.loading_command.length()) {
|
if(target->loading_command.length()) {
|
||||||
type_string(target.loading_command);
|
type_string(target->loading_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_media(target.media);
|
insert_media(target->media);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insert_media(const Analyser::Static::Media &media) override final {
|
bool insert_media(const Analyser::Static::Media &media) override final {
|
||||||
@ -517,9 +520,11 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
using namespace ZX8081;
|
using namespace ZX8081;
|
||||||
|
|
||||||
// See header; constructs and returns an instance of the ZX80 or 81.
|
// See header; constructs and returns an instance of the ZX80 or 81.
|
||||||
Machine *Machine::ZX8081(const Analyser::Static::Target &target_hint) {
|
Machine *Machine::ZX8081(const Analyser::Static::Target *target_hint) {
|
||||||
|
const Analyser::Static::ZX8081::Target *const hint = dynamic_cast<const Analyser::Static::ZX8081::Target *>(target_hint);
|
||||||
|
|
||||||
// Instantiate the correct type of machine.
|
// Instantiate the correct type of machine.
|
||||||
if(target_hint.zx8081.isZX81)
|
if(hint->isZX81)
|
||||||
return new ZX8081::ConcreteMachine<true>();
|
return new ZX8081::ConcreteMachine<true>();
|
||||||
else
|
else
|
||||||
return new ZX8081::ConcreteMachine<false>();
|
return new ZX8081::ConcreteMachine<false>();
|
||||||
|
@ -21,7 +21,7 @@ class Machine {
|
|||||||
public:
|
public:
|
||||||
virtual ~Machine();
|
virtual ~Machine();
|
||||||
|
|
||||||
static Machine *ZX8081(const Analyser::Static::Target &target_hint);
|
static Machine *ZX8081(const Analyser::Static::Target *target_hint);
|
||||||
|
|
||||||
virtual void set_tape_is_playing(bool is_playing) = 0;
|
virtual void set_tape_is_playing(bool is_playing) = 0;
|
||||||
virtual bool get_tape_is_playing() = 0;
|
virtual bool get_tape_is_playing() = 0;
|
||||||
|
@ -1330,6 +1330,12 @@
|
|||||||
4BD9137D1F311BC5009BCF85 /* i8255.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = i8255.hpp; path = 8255/i8255.hpp; sourceTree = "<group>"; };
|
4BD9137D1F311BC5009BCF85 /* i8255.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = i8255.hpp; path = 8255/i8255.hpp; sourceTree = "<group>"; };
|
||||||
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = "<group>"; };
|
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = "<group>"; };
|
||||||
4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = "<group>"; };
|
4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = "<group>"; };
|
||||||
|
4BE3231220532443006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
|
||||||
|
4BE32313205327D7006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
|
||||||
|
4BE32314205328FF006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
|
||||||
|
4BE3231520532AA7006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
|
||||||
|
4BE3231620532BED006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
|
||||||
|
4BE3231720532CC0006EF799 /* Target.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Target.hpp; sourceTree = "<group>"; };
|
||||||
4BE7C9161E3D397100A5496D /* TIA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TIA.cpp; sourceTree = "<group>"; };
|
4BE7C9161E3D397100A5496D /* TIA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TIA.cpp; sourceTree = "<group>"; };
|
||||||
4BE7C9171E3D397100A5496D /* TIA.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TIA.hpp; sourceTree = "<group>"; };
|
4BE7C9171E3D397100A5496D /* TIA.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TIA.hpp; sourceTree = "<group>"; };
|
||||||
4BE845201F2FF7F100A5EA22 /* CRTC6845.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CRTC6845.hpp; path = 6845/CRTC6845.hpp; sourceTree = "<group>"; };
|
4BE845201F2FF7F100A5EA22 /* CRTC6845.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = CRTC6845.hpp; path = 6845/CRTC6845.hpp; sourceTree = "<group>"; };
|
||||||
@ -2164,6 +2170,7 @@
|
|||||||
4B8944EE201967B4007DE474 /* File.hpp */,
|
4B8944EE201967B4007DE474 /* File.hpp */,
|
||||||
4B8944ED201967B4007DE474 /* StaticAnalyser.hpp */,
|
4B8944ED201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||||
4B8944EF201967B4007DE474 /* Tape.hpp */,
|
4B8944EF201967B4007DE474 /* Tape.hpp */,
|
||||||
|
4BE32313205327D7006EF799 /* Target.hpp */,
|
||||||
);
|
);
|
||||||
path = Acorn;
|
path = Acorn;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2173,6 +2180,7 @@
|
|||||||
children = (
|
children = (
|
||||||
4B8944F5201967B4007DE474 /* StaticAnalyser.cpp */,
|
4B8944F5201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||||
4B8944F4201967B4007DE474 /* StaticAnalyser.hpp */,
|
4B8944F4201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||||
|
4BE3231720532CC0006EF799 /* Target.hpp */,
|
||||||
);
|
);
|
||||||
path = Atari;
|
path = Atari;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2184,6 +2192,7 @@
|
|||||||
4B8944F9201967B4007DE474 /* Tape.cpp */,
|
4B8944F9201967B4007DE474 /* Tape.cpp */,
|
||||||
4B8944F7201967B4007DE474 /* StaticAnalyser.hpp */,
|
4B8944F7201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||||
4B8944F8201967B4007DE474 /* Tape.hpp */,
|
4B8944F8201967B4007DE474 /* Tape.hpp */,
|
||||||
|
4BE3231620532BED006EF799 /* Target.hpp */,
|
||||||
);
|
);
|
||||||
path = Oric;
|
path = Oric;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2199,6 +2208,7 @@
|
|||||||
4B8944FE201967B4007DE474 /* File.hpp */,
|
4B8944FE201967B4007DE474 /* File.hpp */,
|
||||||
4B8944FD201967B4007DE474 /* StaticAnalyser.hpp */,
|
4B8944FD201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||||
4B8944FF201967B4007DE474 /* Tape.hpp */,
|
4B8944FF201967B4007DE474 /* Tape.hpp */,
|
||||||
|
4BE3231520532AA7006EF799 /* Target.hpp */,
|
||||||
);
|
);
|
||||||
path = Commodore;
|
path = Commodore;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2208,6 +2218,7 @@
|
|||||||
children = (
|
children = (
|
||||||
4B894506201967B4007DE474 /* StaticAnalyser.cpp */,
|
4B894506201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||||
4B894505201967B4007DE474 /* StaticAnalyser.hpp */,
|
4B894505201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||||
|
4BE3231220532443006EF799 /* Target.hpp */,
|
||||||
);
|
);
|
||||||
path = ZX8081;
|
path = ZX8081;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2243,6 +2254,7 @@
|
|||||||
children = (
|
children = (
|
||||||
4B894516201967B4007DE474 /* StaticAnalyser.cpp */,
|
4B894516201967B4007DE474 /* StaticAnalyser.cpp */,
|
||||||
4B894515201967B4007DE474 /* StaticAnalyser.hpp */,
|
4B894515201967B4007DE474 /* StaticAnalyser.hpp */,
|
||||||
|
4BE32314205328FF006EF799 /* Target.hpp */,
|
||||||
);
|
);
|
||||||
path = AmstradCPC;
|
path = AmstradCPC;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
Loading…
Reference in New Issue
Block a user