1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Encapsulates machine configuration properties for all remaining platforms.

This commit is contained in:
Thomas Harte 2018-03-09 16:07:29 -05:00
parent 78eaecb29e
commit 89bec2919f
16 changed files with 215 additions and 138 deletions

View File

@ -10,6 +10,7 @@
#include "Disk.hpp"
#include "Tape.hpp"
#include "Target.hpp"
using namespace Analyser::Static::Acorn;
@ -56,13 +57,13 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
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);
target->machine = Machine::Electron;
target->confidence = 0.5; // TODO: a proper estimation
target->acorn.has_dfs = false;
target->acorn.has_adfs = false;
target->acorn.should_shift_restart = false;
target->has_dfs = false;
target->has_adfs = false;
target->should_shift_restart = false;
// strip out inappropriate 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 || adfs_catalogue) {
target->media.disks = media.disks;
target->acorn.has_dfs = !!dfs_catalogue;
target->acorn.has_adfs = !!adfs_catalogue;
target->has_dfs = !!dfs_catalogue;
target->has_adfs = !!adfs_catalogue;
Catalogue::BootOption bootOption = (dfs_catalogue ?: adfs_catalogue)->bootOption;
if(bootOption != Catalogue::BootOption::None)
target->acorn.should_shift_restart = true;
target->should_shift_restart = true;
else
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));
}
}

View 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 */

View File

@ -11,6 +11,8 @@
#include <algorithm>
#include <cstring>
#include "Target.hpp"
#include "../../../Storage/Disk/Parsers/CPM.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(
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;
candidate_files.reserve(catalogue.files.size());
@ -153,7 +155,7 @@ static void InspectCatalogue(
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::Sector *boot_sector = parser.get_sector(0, 0, 0x41);
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;
}
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);
target->machine = Machine::AmstradCPC;
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.cartridges = media.cartridges;
target->amstradcpc.model = AmstradCPCModel::CPC6128;
target->model = Target::Model::CPC6128;
if(!target->media.tapes.empty()) {
// Ugliness flows here: assume the CPC isn't smart enough to pause between pressing

View File

@ -8,11 +8,13 @@
#include "StaticAnalyser.hpp"
#include "Target.hpp"
#include "../Disassembler/6502.hpp"
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
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
// 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
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
// 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?)
@ -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[0] == 0x78
) {
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::ActivisionStack;
target.paging_model = Analyser::Static::Atari::Target::PagingModel::ActivisionStack;
return;
}
// 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;
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;
}
if(parker_access_count > atari_access_count) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::ParkerBros;
else if(tigervision_access_count > atari_access_count) target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Tigervision;
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.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
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Atari16k;
target.paging_model = Analyser::Static::Atari::Target::PagingModel::Atari16k;
std::set<uint16_t> internal_accesses;
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;
}
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
target.atari.paging_model =
target.paging_model =
(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) {
DeterminePagingFor2kCartridge(target, segment);
return;
@ -138,16 +140,16 @@ static void DeterminePagingForCartridge(Analyser::Static::Target &target, const
DeterminePagingFor8kCartridge(target, segment, disassembly);
break;
case 10495:
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Pitfall2;
target.paging_model = Analyser::Static::Atari::Target::PagingModel::Pitfall2;
break;
case 12288:
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::CBSRamPlus;
target.paging_model = Analyser::Static::Atari::Target::PagingModel::CBSRamPlus;
break;
case 16384:
DeterminePagingFor16kCartridge(target, segment, disassembly);
break;
case 32768:
target.atari.paging_model = Analyser::Static::Atari2600PagingModel::Atari32k;
target.paging_model = Analyser::Static::Atari::Target::PagingModel::Atari32k;
break;
case 65536:
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
// 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.
if( target.atari.paging_model != Analyser::Static::Atari2600PagingModel::CBSRamPlus &&
target.atari.paging_model != Analyser::Static::Atari2600PagingModel::MNetwork) {
if( target.paging_model != Analyser::Static::Atari::Target::PagingModel::CBSRamPlus &&
target.paging_model != Analyser::Static::Atari::Target::PagingModel::MNetwork) {
bool has_superchip = true;
for(std::size_t address = 0; address < 128; address++) {
if(segment.data[address] != segment.data[address+128]) {
@ -168,24 +170,24 @@ static void DeterminePagingForCartridge(Analyser::Static::Target &target, const
break;
}
}
target.atari.uses_superchip = has_superchip;
target.uses_superchip = has_superchip;
}
// 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();
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?
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->confidence = 0.5;
target->media.cartridges = media.cartridges;
target->atari.paging_model = Atari2600PagingModel::None;
target->atari.uses_superchip = false;
target->paging_model = Analyser::Static::Atari::Target::PagingModel::None;
target->uses_superchip = false;
// try to figure out the paging scheme
if(!media.cartridges.empty()) {

View 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 */

View File

@ -11,6 +11,7 @@
#include "Disk.hpp"
#include "File.hpp"
#include "Tape.hpp"
#include "Target.hpp"
#include "../../../Storage/Cartridge/Encodings/CommodoreROM.hpp"
#include <sstream>
@ -38,7 +39,7 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
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);
target->machine = Machine::Vic20; // TODO: machine 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()) {
target->vic20.memory_model = Vic20MemoryModel::Unexpanded;
target->memory_model = Target::MemoryModel::Unexpanded;
std::ostringstream string_stream;
string_stream << "LOAD\"" << (is_disk ? "*" : "") << "\"," << device << ",";
if(files.front().is_basic()) {
@ -89,10 +90,10 @@ void Analyser::Static::Commodore::AddTargets(const Media &media, std::vector<std
case 0x1001:
default: break;
case 0x1201:
target->vic20.memory_model = Vic20MemoryModel::ThirtyTwoKB;
target->memory_model = Target::MemoryModel::ThirtyTwoKB;
break;
case 0x0401:
target->vic20.memory_model = Vic20MemoryModel::EightKB;
target->memory_model = Target::MemoryModel::EightKB;
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
// 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->memory_model = Target::MemoryModel::ThirtyTwoKB;
else if(target->memory_model == Target::MemoryModel::Unexpanded && !(starting_address >= 0x1000 || starting_address+file_size < 0x0400))
target->memory_model = Target::MemoryModel::ThirtyTwoKB;
// }
}
}

View File

@ -9,6 +9,7 @@
#include "StaticAnalyser.hpp"
#include "Tape.hpp"
#include "Target.hpp"
#include "../Disassembler/6502.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);
}
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);
target->machine = Machine::Oric;
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.
if(!media.disks.empty()) {
target->oric.has_microdisc = true;
target->has_microdisc = true;
target->media.disks = media.disks;
} else {
target->oric.has_microdisc = false;
target->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->use_atmos_rom = basic11_votes >= basic10_votes;
if(target->has_microdisc) target->use_atmos_rom = true;
if(target->media.tapes.size() || target->media.disks.size() || target->media.cartridges.size())
destination.push_back(std::move(target));

View 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 */

View File

@ -21,33 +21,6 @@
namespace Analyser {
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 AmstradCPCModel {
CPC464,
CPC664,
CPC6128
};
/*!
A list of disks, tapes and cartridges.
*/
@ -73,35 +46,6 @@ struct Target {
float confidence;
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 {
AmstradCPCModel model;
} amstradcpc;
};
};
/*!

View File

@ -29,6 +29,8 @@
#include "../../ClockReceiver/ForceInline.hpp"
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
#include "../../Analyser/Static/AmstradCPC/Target.hpp"
#include <cstdint>
#include <vector>
@ -875,18 +877,20 @@ class ConcreteMachine:
/// The ConfigurationTarget entry point; should configure this meachine as described by @c target.
void configure_as_target(const Analyser::Static::Target *target) override final {
switch(target->amstradcpc.model) {
case Analyser::Static::AmstradCPCModel::CPC464:
auto *const cpc_target = dynamic_cast<const Analyser::Static::AmstradCPC::Target *>(target);
switch(cpc_target->model) {
case Analyser::Static::AmstradCPC::Target::Model::CPC464:
rom_model_ = ROMType::OS464;
has_128k_ = false;
has_fdc_ = false;
break;
case Analyser::Static::AmstradCPCModel::CPC664:
case Analyser::Static::AmstradCPC::Target::Model::CPC664:
rom_model_ = ROMType::OS664;
has_128k_ = false;
has_fdc_ = true;
break;
case Analyser::Static::AmstradCPCModel::CPC6128:
case Analyser::Static::AmstradCPC::Target::Model::CPC6128:
rom_model_ = ROMType::OS6128;
has_128k_ = true;
has_fdc_ = true;

View File

@ -15,6 +15,8 @@
#include "../CRTMachine.hpp"
#include "../JoystickMachine.hpp"
#include "../../Analyser/Static/Atari/Target.hpp"
#include "Cartridges/Atari8k.hpp"
#include "Cartridges/Atari16k.hpp"
#include "Cartridges/Atari32k.hpp"
@ -90,34 +92,37 @@ class ConcreteMachine:
}
void configure_as_target(const Analyser::Static::Target *target) override {
auto *const atari_target = dynamic_cast<const Analyser::Static::Atari::Target *>(target);
const std::vector<uint8_t> &rom = target->media.cartridges.front()->get_segments().front().data;
switch(target->atari.paging_model) {
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:
if(target->atari.uses_superchip) {
using PagingModel = Analyser::Static::Atari::Target::PagingModel;
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));
} else {
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari8k>(rom));
}
break;
case Analyser::Static::Atari2600PagingModel::Atari16k:
if(target->atari.uses_superchip) {
case PagingModel::Atari16k:
if(atari_target->uses_superchip) {
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari16kSuperChip>(rom));
} else {
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari16k>(rom));
}
break;
case Analyser::Static::Atari2600PagingModel::Atari32k:
if(target->atari.uses_superchip) {
case PagingModel::Atari32k:
if(atari_target->uses_superchip) {
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari32kSuperChip>(rom));
} else {
bus_.reset(new Cartridge::Cartridge<Cartridge::Atari32k>(rom));

View File

@ -31,6 +31,8 @@
#include "../../../Configurable/StandardOptions.hpp"
#include "../../../Analyser/Static/Commodore/Target.hpp"
#include <algorithm>
#include <cstdint>
@ -364,18 +366,20 @@ class ConcreteMachine:
}
void configure_as_target(const Analyser::Static::Target *target) override final {
auto *const commodore_target = dynamic_cast<const Analyser::Static::Commodore::Target *>(target);
if(target->loading_command.length()) {
type_string(target->loading_command);
}
switch(target->vic20.memory_model) {
case Analyser::Static::Vic20MemoryModel::Unexpanded:
switch(commodore_target->memory_model) {
case Analyser::Static::Commodore::Target::MemoryModel::Unexpanded:
set_memory_size(Default);
break;
case Analyser::Static::Vic20MemoryModel::EightKB:
case Analyser::Static::Commodore::Target::MemoryModel::EightKB:
set_memory_size(ThreeKB);
break;
case Analyser::Static::Vic20MemoryModel::ThirtyTwoKB:
case Analyser::Static::Commodore::Target::MemoryModel::ThirtyTwoKB:
set_memory_size(ThirtyTwoKB);
break;
}

View File

@ -20,6 +20,7 @@
#include "../../Storage/Tape/Tape.hpp"
#include "../Utility/Typer.hpp"
#include "../../Analyser/Static/Acorn/Target.hpp"
#include "Interrupts.hpp"
#include "Keyboard.hpp"
@ -124,21 +125,23 @@ class ConcreteMachine:
}
void configure_as_target(const Analyser::Static::Target *target) override final {
auto *const acorn_target = dynamic_cast<const Analyser::Static::Acorn::Target *>(target);
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;
}
if(target->acorn.has_dfs || target->acorn.has_adfs) {
if(acorn_target->has_dfs || acorn_target->has_adfs) {
plus3_.reset(new Plus3);
if(target->acorn.has_dfs) {
if(acorn_target->has_dfs) {
set_rom(ROMSlot0, dfs_, true);
}
if(target->acorn.has_adfs) {
if(acorn_target->has_adfs) {
set_rom(ROMSlot4, adfs1_, true);
set_rom(ROMSlot5, adfs2_, true);
}

View File

@ -30,6 +30,8 @@
#include "../../Configurable/StandardOptions.hpp"
#include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp"
#include "../../Analyser/Static/Oric/Target.hpp"
#include <cstdint>
#include <memory>
#include <vector>
@ -263,7 +265,9 @@ class ConcreteMachine:
// to satisfy ConfigurationTarget::Machine
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_did_change_paging_flags(&microdisc_);
microdisc_.set_delegate(this);
@ -273,7 +277,7 @@ class ConcreteMachine:
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_)));
is_using_basic11_ = true;

View File

@ -280,8 +280,7 @@ template<bool is_zx81> class ConcreteMachine:
}
void configure_as_target(const Analyser::Static::Target *target) override final {
const Analyser::Static::ZX8081::Target *const zx8081_target =
dynamic_cast<const Analyser::Static::ZX8081::Target *>(target);
auto *const zx8081_target = dynamic_cast<const Analyser::Static::ZX8081::Target *>(target);
is_zx81_ = zx8081_target->isZX81;
if(is_zx81_) {
rom_ = zx81_rom_;

View File

@ -1331,6 +1331,11 @@
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>"; };
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>"; };
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>"; };
@ -2165,6 +2170,7 @@
4B8944EE201967B4007DE474 /* File.hpp */,
4B8944ED201967B4007DE474 /* StaticAnalyser.hpp */,
4B8944EF201967B4007DE474 /* Tape.hpp */,
4BE32313205327D7006EF799 /* Target.hpp */,
);
path = Acorn;
sourceTree = "<group>";
@ -2174,6 +2180,7 @@
children = (
4B8944F5201967B4007DE474 /* StaticAnalyser.cpp */,
4B8944F4201967B4007DE474 /* StaticAnalyser.hpp */,
4BE3231720532CC0006EF799 /* Target.hpp */,
);
path = Atari;
sourceTree = "<group>";
@ -2185,6 +2192,7 @@
4B8944F9201967B4007DE474 /* Tape.cpp */,
4B8944F7201967B4007DE474 /* StaticAnalyser.hpp */,
4B8944F8201967B4007DE474 /* Tape.hpp */,
4BE3231620532BED006EF799 /* Target.hpp */,
);
path = Oric;
sourceTree = "<group>";
@ -2200,6 +2208,7 @@
4B8944FE201967B4007DE474 /* File.hpp */,
4B8944FD201967B4007DE474 /* StaticAnalyser.hpp */,
4B8944FF201967B4007DE474 /* Tape.hpp */,
4BE3231520532AA7006EF799 /* Target.hpp */,
);
path = Commodore;
sourceTree = "<group>";
@ -2245,6 +2254,7 @@
children = (
4B894516201967B4007DE474 /* StaticAnalyser.cpp */,
4B894515201967B4007DE474 /* StaticAnalyser.hpp */,
4BE32314205328FF006EF799 /* Target.hpp */,
);
path = AmstradCPC;
sourceTree = "<group>";