mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Switch to a non-macro route for startup declarations.
This commit is contained in:
parent
a128247ef5
commit
b15a083a15
@ -23,14 +23,16 @@ struct ElectronTarget: public ::Analyser::Static::Target, public Reflection::Str
|
||||
bool should_shift_restart = false;
|
||||
std::string loading_command;
|
||||
|
||||
ElectronTarget() : Analyser::Static::Target(Machine::Electron) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(has_pres_adfs);
|
||||
DeclareField(has_acorn_adfs);
|
||||
DeclareField(has_dfs);
|
||||
DeclareField(has_ap6_rom);
|
||||
DeclareField(has_sideways_ram);
|
||||
}
|
||||
ElectronTarget() : Analyser::Static::Target(Machine::Electron) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<ElectronTarget>;
|
||||
void declare_fields() {
|
||||
DeclareField(has_pres_adfs);
|
||||
DeclareField(has_acorn_adfs);
|
||||
DeclareField(has_dfs);
|
||||
DeclareField(has_ap6_rom);
|
||||
DeclareField(has_sideways_ram);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -28,13 +28,15 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
ChipRAM chip_ram = ChipRAM::FiveHundredAndTwelveKilobytes;
|
||||
FastRAM fast_ram = FastRAM::EightMegabytes;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::Amiga) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(fast_ram);
|
||||
DeclareField(chip_ram);
|
||||
AnnounceEnum(FastRAM);
|
||||
AnnounceEnum(ChipRAM);
|
||||
}
|
||||
Target() : Analyser::Static::Target(Machine::Amiga) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(fast_ram);
|
||||
DeclareField(chip_ram);
|
||||
AnnounceEnum(FastRAM);
|
||||
AnnounceEnum(ChipRAM);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -26,13 +26,15 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
// This is used internally for testing; it therefore isn't exposed reflectively.
|
||||
bool catch_ssm_codes = false;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::AmstradCPC) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(model);
|
||||
DeclareField(crtc_type);
|
||||
AnnounceEnum(Model);
|
||||
AnnounceEnum(CRTCType);
|
||||
}
|
||||
Target() : Analyser::Static::Target(Machine::AmstradCPC) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(model);
|
||||
DeclareField(crtc_type);
|
||||
AnnounceEnum(Model);
|
||||
AnnounceEnum(CRTCType);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -36,17 +36,19 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
SCSIController scsi_controller = SCSIController::None;
|
||||
bool has_mockingboard = true;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::AppleII) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(model);
|
||||
DeclareField(disk_controller);
|
||||
DeclareField(scsi_controller);
|
||||
DeclareField(has_mockingboard);
|
||||
Target() : Analyser::Static::Target(Machine::AppleII) {}
|
||||
|
||||
AnnounceEnum(Model);
|
||||
AnnounceEnum(DiskController);
|
||||
AnnounceEnum(SCSIController);
|
||||
}
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(model);
|
||||
DeclareField(disk_controller);
|
||||
DeclareField(scsi_controller);
|
||||
DeclareField(has_mockingboard);
|
||||
|
||||
AnnounceEnum(Model);
|
||||
AnnounceEnum(DiskController);
|
||||
AnnounceEnum(SCSIController);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -29,13 +29,15 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
Model model = Model::ROM01;
|
||||
MemoryModel memory_model = MemoryModel::EightMB;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::AppleIIgs) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(model);
|
||||
DeclareField(memory_model);
|
||||
AnnounceEnum(Model);
|
||||
AnnounceEnum(MemoryModel);
|
||||
}
|
||||
Target() : Analyser::Static::Target(Machine::AppleIIgs) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(model);
|
||||
DeclareField(memory_model);
|
||||
AnnounceEnum(Model);
|
||||
AnnounceEnum(MemoryModel);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -20,11 +20,13 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
FourMegabytes);
|
||||
MemorySize memory_size = MemorySize::OneMegabyte;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::AtariST) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(memory_size);
|
||||
AnnounceEnum(MemorySize);
|
||||
}
|
||||
Target() : Analyser::Static::Target(Machine::AtariST) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(memory_size);
|
||||
AnnounceEnum(MemorySize);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -171,8 +171,8 @@ private:
|
||||
|
||||
std::vector<File> Analyser::Static::Commodore::GetFiles(const std::shared_ptr<Storage::Disk::Disk> &disk) {
|
||||
std::vector<File> files;
|
||||
CommodoreGCRParser parser;
|
||||
parser.set_disk(disk);
|
||||
auto parser = std::make_unique<CommodoreGCRParser>();
|
||||
parser->set_disk(disk);
|
||||
|
||||
// Assemble directory.
|
||||
std::vector<uint8_t> directory;
|
||||
@ -180,7 +180,7 @@ std::vector<File> Analyser::Static::Commodore::GetFiles(const std::shared_ptr<St
|
||||
uint8_t next_sector = 1;
|
||||
directory.reserve(20 * 1024); // Probably more than plenty.
|
||||
while(true) {
|
||||
auto sector = parser.sector(next_track, next_sector);
|
||||
auto sector = parser->sector(next_track, next_sector);
|
||||
if(!sector) break;
|
||||
directory.insert(directory.end(), sector->data.begin(), sector->data.end());
|
||||
next_track = sector->data[0];
|
||||
@ -222,7 +222,7 @@ std::vector<File> Analyser::Static::Commodore::GetFiles(const std::shared_ptr<St
|
||||
|
||||
bool is_first_sector = true;
|
||||
while(next_track) {
|
||||
auto sector = parser.sector(next_track, next_sector);
|
||||
auto sector = parser->sector(next_track, next_sector);
|
||||
if(!sector) break;
|
||||
|
||||
next_track = sector->data[0];
|
||||
|
@ -57,7 +57,8 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
Target() : Analyser::Static::Target(Machine::Vic20) {}
|
||||
|
||||
private:
|
||||
BEGIN_DECLARATIONS
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(enabled_ram.bank0);
|
||||
DeclareField(enabled_ram.bank1);
|
||||
DeclareField(enabled_ram.bank2);
|
||||
@ -66,7 +67,7 @@ private:
|
||||
DeclareField(region);
|
||||
DeclareField(has_c1540);
|
||||
AnnounceEnum(Region);
|
||||
END_DECLARATIONS
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -30,20 +30,22 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
Speed speed = Speed::FourMHz;
|
||||
std::string loading_command;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::Enterprise) {
|
||||
if(needs_declare()) {
|
||||
AnnounceEnum(Model);
|
||||
AnnounceEnum(EXOSVersion);
|
||||
AnnounceEnum(BASICVersion);
|
||||
AnnounceEnum(DOS);
|
||||
AnnounceEnum(Speed);
|
||||
Target() : Analyser::Static::Target(Machine::Enterprise) {}
|
||||
|
||||
DeclareField(model);
|
||||
DeclareField(exos_version);
|
||||
DeclareField(basic_version);
|
||||
DeclareField(dos);
|
||||
DeclareField(speed);
|
||||
}
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
AnnounceEnum(Model);
|
||||
AnnounceEnum(EXOSVersion);
|
||||
AnnounceEnum(BASICVersion);
|
||||
AnnounceEnum(DOS);
|
||||
AnnounceEnum(Speed);
|
||||
|
||||
DeclareField(model);
|
||||
DeclareField(exos_version);
|
||||
DeclareField(basic_version);
|
||||
DeclareField(dos);
|
||||
DeclareField(speed);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -33,15 +33,17 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl<
|
||||
);
|
||||
Region region = Region::USA;
|
||||
|
||||
Target(): Analyser::Static::Target(Machine::MSX) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(has_disk_drive);
|
||||
DeclareField(has_msx_music);
|
||||
DeclareField(region);
|
||||
AnnounceEnum(Region);
|
||||
DeclareField(model);
|
||||
AnnounceEnum(Model);
|
||||
}
|
||||
Target(): Analyser::Static::Target(Machine::MSX) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(has_disk_drive);
|
||||
DeclareField(has_msx_music);
|
||||
DeclareField(region);
|
||||
AnnounceEnum(Region);
|
||||
DeclareField(model);
|
||||
AnnounceEnum(Model);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -18,12 +18,13 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
ReflectableEnum(Model, Mac128k, Mac512k, Mac512ke, MacPlus);
|
||||
Model model = Model::MacPlus;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::Macintosh) {
|
||||
// Boilerplate for declaring fields and potential values.
|
||||
if(needs_declare()) {
|
||||
DeclareField(model);
|
||||
AnnounceEnum(Model);
|
||||
}
|
||||
Target() : Analyser::Static::Target(Machine::Macintosh) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(model);
|
||||
AnnounceEnum(Model);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -41,15 +41,17 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
std::string loading_command;
|
||||
bool should_start_jasmin = false;
|
||||
|
||||
Target(): Analyser::Static::Target(Machine::Oric) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(rom);
|
||||
DeclareField(disk_interface);
|
||||
DeclareField(processor);
|
||||
AnnounceEnum(ROM);
|
||||
AnnounceEnum(DiskInterface);
|
||||
AnnounceEnum(Processor);
|
||||
}
|
||||
Target(): Analyser::Static::Target(Machine::Oric) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(rom);
|
||||
DeclareField(disk_interface);
|
||||
DeclareField(processor);
|
||||
AnnounceEnum(ROM);
|
||||
AnnounceEnum(DiskInterface);
|
||||
AnnounceEnum(Processor);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -24,13 +24,15 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
Fast);
|
||||
Speed speed = Speed::Fast;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::PCCompatible) {
|
||||
if(needs_declare()) {
|
||||
AnnounceEnum(VideoAdaptor);
|
||||
AnnounceEnum(Speed);
|
||||
DeclareField(adaptor);
|
||||
DeclareField(speed);
|
||||
}
|
||||
Target() : Analyser::Static::Target(Machine::PCCompatible) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
AnnounceEnum(VideoAdaptor);
|
||||
AnnounceEnum(Speed);
|
||||
DeclareField(adaptor);
|
||||
DeclareField(speed);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -37,11 +37,13 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
||||
Region region = Region::Japan;
|
||||
PagingScheme paging_scheme = PagingScheme::Sega;
|
||||
|
||||
Target() : Analyser::Static::Target(Machine::MasterSystem) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(region);
|
||||
AnnounceEnum(Region);
|
||||
}
|
||||
Target() : Analyser::Static::Target(Machine::MasterSystem) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(region);
|
||||
AnnounceEnum(Region);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -27,13 +27,15 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl<
|
||||
bool ZX80_uses_ZX81_ROM = false;
|
||||
std::string loading_command;
|
||||
|
||||
Target(): Analyser::Static::Target(Machine::ZX8081) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(memory_model);
|
||||
DeclareField(is_ZX81);
|
||||
DeclareField(ZX80_uses_ZX81_ROM);
|
||||
AnnounceEnum(MemoryModel);
|
||||
}
|
||||
Target(): Analyser::Static::Target(Machine::ZX8081) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(memory_model);
|
||||
DeclareField(is_ZX81);
|
||||
DeclareField(ZX80_uses_ZX81_ROM);
|
||||
AnnounceEnum(MemoryModel);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -27,11 +27,13 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl<
|
||||
Model model = Model::Plus2;
|
||||
bool should_hold_enter = false;
|
||||
|
||||
Target(): Analyser::Static::Target(Machine::ZXSpectrum) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(model);
|
||||
AnnounceEnum(Model);
|
||||
}
|
||||
Target(): Analyser::Static::Target(Machine::ZXSpectrum) {}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<Target>;
|
||||
void declare_fields() {
|
||||
DeclareField(model);
|
||||
AnnounceEnum(Model);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -223,13 +223,6 @@ struct State: public Reflection::StructImpl<State> {
|
||||
|
||||
// TODO: all audio-production thread state.
|
||||
|
||||
State() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(registers);
|
||||
DeclareField(selected_register);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename AY> void apply(AY &target) {
|
||||
// Establish emulator-thread state
|
||||
for(uint8_t c = 0; c < 16; c++) {
|
||||
@ -238,6 +231,13 @@ struct State: public Reflection::StructImpl<State> {
|
||||
}
|
||||
target.select_register(selected_register);
|
||||
}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<State>;
|
||||
void declare_fields() {
|
||||
DeclareField(registers);
|
||||
DeclareField(selected_register);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,24 +17,25 @@
|
||||
|
||||
namespace Archimedes {
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> Archimedes(
|
||||
const Analyser::Static::Target *target,
|
||||
const ROMMachine::ROMFetcher &rom_fetcher
|
||||
);
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> Archimedes(
|
||||
const Analyser::Static::Target *target,
|
||||
const ROMMachine::ROMFetcher &rom_fetcher
|
||||
);
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
|
||||
if(needs_declare()) {
|
||||
declare_quickload_option();
|
||||
}
|
||||
}
|
||||
};
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_quickload_option();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -23,28 +23,31 @@ namespace Electron {
|
||||
@discussion An instance of Electron::Machine represents the current state of an
|
||||
Acorn Electron.
|
||||
*/
|
||||
class Machine {
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
/// Creates and returns an Electron.
|
||||
static std::unique_ptr<Machine> Electron(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
|
||||
/// Defines the runtime options available for an Electron.
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
/// Creates and returns an Electron.
|
||||
static std::unique_ptr<Machine> Electron(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
/// Defines the runtime options available for an Electron.
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
|
||||
if(needs_declare()) {
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, Configurable::Display::CompositeMonochrome, -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, Configurable::Display::CompositeMonochrome, -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -15,12 +15,11 @@
|
||||
|
||||
namespace Amiga {
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
/// Creates and returns an Amiga.
|
||||
static std::unique_ptr<Machine> Amiga(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
/// Creates and returns an Amiga.
|
||||
static std::unique_ptr<Machine> Amiga(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -20,41 +20,44 @@ namespace AmstradCPC {
|
||||
/*!
|
||||
Models an Amstrad CPC.
|
||||
*/
|
||||
class Machine {
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
/// Creates and returns an Amstrad CPC.
|
||||
static std::unique_ptr<Machine> AmstradCPC(
|
||||
const Analyser::Static::Target *target,
|
||||
const ROMMachine::ROMFetcher &rom_fetcher
|
||||
);
|
||||
|
||||
/// Defines the runtime options available for an Amstrad CPC.
|
||||
class Options:
|
||||
public Reflection::StructImpl<Options>,
|
||||
public Configurable::DisplayOption<Options>,
|
||||
public Configurable::QuickloadOption<Options>
|
||||
{
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(Configurable::Display::RGB),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
/// Creates and returns an Amstrad CPC.
|
||||
static std::unique_ptr<Machine> AmstradCPC(
|
||||
const Analyser::Static::Target *target,
|
||||
const ROMMachine::ROMFetcher &rom_fetcher
|
||||
);
|
||||
private:
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
|
||||
/// Defines the runtime options available for an Amstrad CPC.
|
||||
class Options:
|
||||
public Reflection::StructImpl<Options>,
|
||||
public Configurable::DisplayOption<Options>,
|
||||
public Configurable::QuickloadOption<Options>
|
||||
{
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(Configurable::Display::RGB),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly)
|
||||
{
|
||||
if(needs_declare()) {
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
struct SSMDelegate {
|
||||
virtual void perform(uint16_t) = 0;
|
||||
};
|
||||
virtual void set_ssm_delegate(SSMDelegate *) = 0;
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
};
|
||||
|
||||
struct SSMDelegate {
|
||||
virtual void perform(uint16_t) = 0;
|
||||
};
|
||||
virtual void set_ssm_delegate(SSMDelegate *) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,27 +17,30 @@
|
||||
|
||||
namespace Apple::II {
|
||||
|
||||
class Machine {
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
/// Creates and returns an AppleII.
|
||||
static std::unique_ptr<Machine> AppleII(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
||||
/// Defines the runtime options available for an Apple II.
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
bool use_square_pixels = false;
|
||||
|
||||
/// Creates and returns an AppleII.
|
||||
static std::unique_ptr<Machine> AppleII(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
Options(Configurable::OptionsType) :
|
||||
Configurable::DisplayOption<Options>(Configurable::Display::CompositeColour) {}
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
/// Defines the runtime options available for an Apple II.
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
bool use_square_pixels = false;
|
||||
|
||||
Options(Configurable::OptionsType) : Configurable::DisplayOption<Options>(Configurable::Display::CompositeColour) {
|
||||
if(needs_declare()) {
|
||||
DeclareField(use_square_pixels);
|
||||
declare_display_option();
|
||||
limit_enum(&output, Configurable::Display::CompositeMonochrome, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
DeclareField(use_square_pixels);
|
||||
declare_display_option();
|
||||
limit_enum(&output, Configurable::Display::CompositeMonochrome, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,12 +17,11 @@
|
||||
|
||||
namespace Apple::IIgs {
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
/// Creates and returns an AppleIIgs.
|
||||
static std::unique_ptr<Machine> AppleIIgs(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
/// Creates and returns an AppleIIgs.
|
||||
static std::unique_ptr<Machine> AppleIIgs(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -15,23 +15,25 @@
|
||||
|
||||
namespace Apple::Macintosh {
|
||||
|
||||
class Machine {
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
/// Creates and returns a Macintosh.
|
||||
static std::unique_ptr<Machine> Macintosh(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickbootOption<Options> {
|
||||
friend Configurable::QuickbootOption<Options>;
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::QuickbootOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
/// Creates and returns a Macintosh.
|
||||
static std::unique_ptr<Machine> Macintosh(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickbootOption<Options> {
|
||||
friend Configurable::QuickbootOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::QuickbootOption<Options>(type == Configurable::OptionsType::UserFriendly) {
|
||||
if(needs_declare()) {
|
||||
declare_quickboot_option();
|
||||
}
|
||||
}
|
||||
};
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_quickboot_option();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -21,8 +21,7 @@ namespace Atari2600 {
|
||||
/*!
|
||||
Models an Atari 2600.
|
||||
*/
|
||||
class Machine {
|
||||
public:
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
/// Creates and returns an Atari 2600 on the heap.
|
||||
|
@ -17,23 +17,27 @@
|
||||
|
||||
namespace Atari::ST {
|
||||
|
||||
class Machine {
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
static std::unique_ptr<Machine> AtariST(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
Options(Configurable::OptionsType type) : Configurable::DisplayOption<Options>(
|
||||
type == Configurable::OptionsType::UserFriendly ?
|
||||
Configurable::Display::RGB : Configurable::Display::CompositeColour) {}
|
||||
|
||||
static std::unique_ptr<Machine> AtariST(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) : Configurable::DisplayOption<Options>(
|
||||
type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour) {
|
||||
if(needs_declare()) {
|
||||
declare_display_option();
|
||||
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_display_option();
|
||||
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,22 +17,26 @@
|
||||
|
||||
namespace Coleco::Vision {
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> ColecoVision(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> ColecoVision(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::SVideo : Configurable::Display::CompositeColour) {
|
||||
if(needs_declare()) {
|
||||
declare_display_option();
|
||||
limit_enum(&output, Configurable::Display::SVideo, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
|
||||
Configurable::Display::SVideo : Configurable::Display::CompositeColour) {}
|
||||
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_display_option();
|
||||
limit_enum(&output, Configurable::Display::SVideo, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -15,8 +15,7 @@
|
||||
|
||||
namespace Commodore::Plus4 {
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
static std::unique_ptr<Machine> Plus4(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
@ -20,26 +20,34 @@ namespace Commodore::Vic20 {
|
||||
/// @returns The options available for a Vic-20.
|
||||
std::unique_ptr<Reflection::Struct> get_options();
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
/// Creates and returns a Vic-20.
|
||||
static std::unique_ptr<Machine> Vic20(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
|
||||
class Options:
|
||||
public Reflection::StructImpl<Options>,
|
||||
public Configurable::DisplayOption<Options>,
|
||||
public Configurable::QuickloadOption<Options>
|
||||
{
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::SVideo : Configurable::Display::CompositeColour),
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
|
||||
Configurable::Display::SVideo : Configurable::Display::CompositeColour),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
|
||||
if(needs_declare()) {
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
limit_enum(&output, Configurable::Display::SVideo, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
}
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
limit_enum(&output, Configurable::Display::SVideo, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -23,23 +23,26 @@ namespace Enterprise {
|
||||
@discussion An instance of Enterprise::Machine represents the current state of an
|
||||
Elan Enterprise.
|
||||
*/
|
||||
class Machine {
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> Enterprise(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
||||
/// Defines the runtime options available for an Enterprise.
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> Enterprise(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour) {}
|
||||
|
||||
/// Defines the runtime options available for an Enterprise.
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour) {
|
||||
if(needs_declare()) {
|
||||
declare_display_option();
|
||||
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, Configurable::Display::CompositeMonochrome, -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_display_option();
|
||||
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, Configurable::Display::CompositeMonochrome, -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -17,24 +17,31 @@
|
||||
|
||||
namespace MSX {
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> MSX(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> MSX(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
|
||||
if(needs_declare()) {
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
}
|
||||
}
|
||||
};
|
||||
class Options:
|
||||
public Reflection::StructImpl<Options>,
|
||||
public Configurable::DisplayOption<Options>,
|
||||
public Configurable::QuickloadOption<Options>
|
||||
{
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,21 +17,25 @@
|
||||
|
||||
namespace Sega::MasterSystem {
|
||||
|
||||
class Machine {
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> MasterSystem(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> MasterSystem(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour) {
|
||||
if(needs_declare()) {
|
||||
declare_display_option();
|
||||
}
|
||||
}
|
||||
};
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
|
||||
Configurable::Display::RGB : Configurable::Display::CompositeColour) {}
|
||||
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_display_option();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -20,26 +20,32 @@ namespace Oric {
|
||||
/*!
|
||||
Models an Oric 1/Atmos with or without a Microdisc.
|
||||
*/
|
||||
class Machine {
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> Oric(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
||||
class Options:
|
||||
public Reflection::StructImpl<Options>,
|
||||
public Configurable::DisplayOption<Options>,
|
||||
public Configurable::QuickloadOption<Options>
|
||||
{
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ?
|
||||
Configurable::Display::RGB : Configurable::Display::CompositeColour),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
/// Creates and returns an Oric.
|
||||
static std::unique_ptr<Machine> Oric(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly) {
|
||||
if(needs_declare()) {
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
}
|
||||
}
|
||||
};
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,32 +18,34 @@ namespace PCCompatible {
|
||||
/*!
|
||||
Models a PC compatible.
|
||||
*/
|
||||
class Machine {
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
|
||||
/// Creates and returns a PC Compatible.
|
||||
static std::unique_ptr<Machine> PCCompatible(
|
||||
const Analyser::Static::Target *target,
|
||||
const ROMMachine::ROMFetcher &rom_fetcher
|
||||
);
|
||||
|
||||
/// Defines the runtime options [sometimes] available for a PC.
|
||||
class Options:
|
||||
public Reflection::StructImpl<Options>,
|
||||
public Configurable::DisplayOption<Options>
|
||||
{
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
Options(Configurable::OptionsType) :
|
||||
Configurable::DisplayOption<Options>(Configurable::Display::RGB) {}
|
||||
|
||||
/// Creates and returns a PC Compatible.
|
||||
static std::unique_ptr<Machine> PCCompatible(
|
||||
const Analyser::Static::Target *target,
|
||||
const ROMMachine::ROMFetcher &rom_fetcher
|
||||
);
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
/// Defines the runtime options [sometimes] available for a PC.
|
||||
class Options:
|
||||
public Reflection::StructImpl<Options>,
|
||||
public Configurable::DisplayOption<Options>
|
||||
{
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
public:
|
||||
Options(Configurable::OptionsType) :
|
||||
Configurable::DisplayOption<Options>(Configurable::Display::RGB)
|
||||
{
|
||||
if(needs_declare()) {
|
||||
declare_display_option();
|
||||
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
declare_display_option();
|
||||
limit_enum(&output, Configurable::Display::RGB, Configurable::Display::CompositeColour, -1);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,31 +18,32 @@
|
||||
namespace Sinclair::ZX8081 {
|
||||
|
||||
/// The ZX80/81 machine.
|
||||
class Machine {
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> ZX8081(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
|
||||
virtual void set_tape_is_playing(bool is_playing) = 0;
|
||||
virtual bool get_tape_is_playing() = 0;
|
||||
|
||||
/// Defines the runtime options available for a ZX80/81.
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> ZX8081(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
bool automatic_tape_motor_control = true;
|
||||
|
||||
virtual void set_tape_is_playing(bool is_playing) = 0;
|
||||
virtual bool get_tape_is_playing() = 0;
|
||||
Options(Configurable::OptionsType type):
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly),
|
||||
automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
/// Defines the runtime options available for a ZX80/81.
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::QuickloadOption<Options> {
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
bool automatic_tape_motor_control = true;
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
Options(Configurable::OptionsType type):
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly),
|
||||
automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly) {
|
||||
|
||||
// Declare fields if necessary.
|
||||
if(needs_declare()) {
|
||||
DeclareField(automatic_tape_motor_control);
|
||||
declare_quickload_option();
|
||||
}
|
||||
}
|
||||
};
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
DeclareField(automatic_tape_motor_control);
|
||||
declare_quickload_option();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -32,15 +32,15 @@ struct State: public Reflection::StructImpl<State> {
|
||||
// Meaningful for the +2a and +3 only.
|
||||
uint8_t last_1ffd = 0;
|
||||
|
||||
State() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(z80);
|
||||
DeclareField(video);
|
||||
DeclareField(ram);
|
||||
DeclareField(last_7ffd);
|
||||
DeclareField(last_1ffd);
|
||||
DeclareField(ay);
|
||||
}
|
||||
private:
|
||||
friend Reflection::StructImpl<State>;
|
||||
void declare_fields() {
|
||||
DeclareField(z80);
|
||||
DeclareField(video);
|
||||
DeclareField(ram);
|
||||
DeclareField(last_7ffd);
|
||||
DeclareField(last_1ffd);
|
||||
DeclareField(ay);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -455,15 +455,7 @@ struct State: public Reflection::StructImpl<State> {
|
||||
int flash_counter = 0;
|
||||
bool is_alternate_line = false;
|
||||
|
||||
State() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(border_colour);
|
||||
DeclareField(half_cycles_since_interrupt);
|
||||
DeclareField(flash);
|
||||
DeclareField(flash_counter);
|
||||
DeclareField(is_alternate_line);
|
||||
}
|
||||
}
|
||||
State() {}
|
||||
|
||||
template <typename Video> State(const Video &source) : State() {
|
||||
border_colour = source.border_byte_;
|
||||
@ -480,6 +472,16 @@ struct State: public Reflection::StructImpl<State> {
|
||||
target.is_alternate_line_ = is_alternate_line;
|
||||
target.set_time_since_interrupt(HalfCycles(half_cycles_since_interrupt));
|
||||
}
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<State>;
|
||||
void declare_fields() {
|
||||
DeclareField(border_colour);
|
||||
DeclareField(half_cycles_since_interrupt);
|
||||
DeclareField(flash);
|
||||
DeclareField(flash_counter);
|
||||
DeclareField(is_alternate_line);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,32 +17,38 @@
|
||||
|
||||
namespace Sinclair::ZXSpectrum {
|
||||
|
||||
class Machine {
|
||||
struct Machine {
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> ZXSpectrum(const Analyser::Static::Target *, const ROMMachine::ROMFetcher &);
|
||||
|
||||
virtual void set_tape_is_playing(bool is_playing) = 0;
|
||||
virtual bool get_tape_is_playing() = 0;
|
||||
|
||||
class Options:
|
||||
public Reflection::StructImpl<Options>,
|
||||
public Configurable::DisplayOption<Options>,
|
||||
public Configurable::QuickloadOption<Options>
|
||||
{
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
virtual ~Machine() = default;
|
||||
static std::unique_ptr<Machine> ZXSpectrum(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
||||
bool automatic_tape_motor_control = true;
|
||||
|
||||
virtual void set_tape_is_playing(bool is_playing) = 0;
|
||||
virtual bool get_tape_is_playing() = 0;
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly),
|
||||
automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
class Options: public Reflection::StructImpl<Options>, public Configurable::DisplayOption<Options>, public Configurable::QuickloadOption<Options> {
|
||||
friend Configurable::DisplayOption<Options>;
|
||||
friend Configurable::QuickloadOption<Options>;
|
||||
public:
|
||||
bool automatic_tape_motor_control = true;
|
||||
private:
|
||||
Options() : Options(Configurable::OptionsType::UserFriendly) {}
|
||||
|
||||
Options(Configurable::OptionsType type) :
|
||||
Configurable::DisplayOption<Options>(type == Configurable::OptionsType::UserFriendly ? Configurable::Display::RGB : Configurable::Display::CompositeColour),
|
||||
Configurable::QuickloadOption<Options>(type == Configurable::OptionsType::UserFriendly),
|
||||
automatic_tape_motor_control(type == Configurable::OptionsType::UserFriendly)
|
||||
{
|
||||
if(needs_declare()) {
|
||||
DeclareField(automatic_tape_motor_control);
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
}
|
||||
}
|
||||
};
|
||||
friend Reflection::StructImpl<Options>;
|
||||
void declare_fields() {
|
||||
DeclareField(automatic_tape_motor_control);
|
||||
declare_display_option();
|
||||
declare_quickload_option();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -83,43 +83,35 @@ void State::apply(ProcessorBase &target) {
|
||||
}
|
||||
|
||||
// Boilerplate follows here, to establish 'reflection'.
|
||||
State::State() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(registers);
|
||||
DeclareField(execution_state);
|
||||
DeclareField(inputs);
|
||||
}
|
||||
void State::declare_fields() {
|
||||
DeclareField(registers);
|
||||
DeclareField(execution_state);
|
||||
DeclareField(inputs);
|
||||
}
|
||||
|
||||
State::Registers::Registers() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(program_counter);
|
||||
DeclareField(stack_pointer);
|
||||
DeclareField(flags);
|
||||
DeclareField(a);
|
||||
DeclareField(x);
|
||||
DeclareField(y);
|
||||
}
|
||||
void State::Registers::declare_fields() {
|
||||
DeclareField(program_counter);
|
||||
DeclareField(stack_pointer);
|
||||
DeclareField(flags);
|
||||
DeclareField(a);
|
||||
DeclareField(x);
|
||||
DeclareField(y);
|
||||
}
|
||||
|
||||
State::ExecutionState::ExecutionState() {
|
||||
if(needs_declare()) {
|
||||
AnnounceEnum(Phase);
|
||||
DeclareField(phase);
|
||||
DeclareField(micro_program);
|
||||
DeclareField(micro_program_offset);
|
||||
DeclareField(operation);
|
||||
DeclareField(operand);
|
||||
DeclareField(address);
|
||||
DeclareField(next_address);
|
||||
}
|
||||
void State::ExecutionState::declare_fields() {
|
||||
AnnounceEnum(Phase);
|
||||
DeclareField(phase);
|
||||
DeclareField(micro_program);
|
||||
DeclareField(micro_program_offset);
|
||||
DeclareField(operation);
|
||||
DeclareField(operand);
|
||||
DeclareField(address);
|
||||
DeclareField(next_address);
|
||||
}
|
||||
|
||||
State::Inputs::Inputs() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(ready);
|
||||
DeclareField(irq);
|
||||
DeclareField(nmi);
|
||||
DeclareField(reset);
|
||||
}
|
||||
void State::Inputs::declare_fields() {
|
||||
DeclareField(ready);
|
||||
DeclareField(irq);
|
||||
DeclareField(nmi);
|
||||
DeclareField(reset);
|
||||
}
|
||||
|
@ -31,7 +31,9 @@ struct State: public Reflection::StructImpl<State> {
|
||||
uint8_t flags;
|
||||
uint8_t a, x, y;
|
||||
|
||||
Registers();
|
||||
private:
|
||||
friend Reflection::StructImpl<Registers>;
|
||||
void declare_fields();
|
||||
} registers;
|
||||
|
||||
/*!
|
||||
@ -44,7 +46,9 @@ struct State: public Reflection::StructImpl<State> {
|
||||
bool nmi;
|
||||
bool reset;
|
||||
|
||||
Inputs();
|
||||
private:
|
||||
friend Reflection::StructImpl<Inputs>;
|
||||
void declare_fields();
|
||||
} inputs;
|
||||
|
||||
/*!
|
||||
@ -74,17 +78,22 @@ struct State: public Reflection::StructImpl<State> {
|
||||
uint8_t operation, operand;
|
||||
uint16_t address, next_address;
|
||||
|
||||
ExecutionState();
|
||||
private:
|
||||
friend Reflection::StructImpl<ExecutionState>;
|
||||
void declare_fields();
|
||||
} execution_state;
|
||||
|
||||
/// Default constructor; makes no guarantees as to field values beyond those given above.
|
||||
State();
|
||||
State() {}
|
||||
|
||||
/// Instantiates a new State based on the processor @c src.
|
||||
State(const ProcessorBase &src);
|
||||
State(const ProcessorBase &);
|
||||
|
||||
/// Applies this state to @c target.
|
||||
void apply(ProcessorBase &target);
|
||||
void apply(ProcessorBase &);
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<State>;
|
||||
void declare_fields();
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -164,62 +164,54 @@ void State::apply(ProcessorBase &target) {
|
||||
}
|
||||
|
||||
// Boilerplate follows here, to establish 'reflection'.
|
||||
State::State() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(registers);
|
||||
DeclareField(execution_state);
|
||||
DeclareField(inputs);
|
||||
}
|
||||
void State::declare_fields() {
|
||||
DeclareField(registers);
|
||||
DeclareField(execution_state);
|
||||
DeclareField(inputs);
|
||||
}
|
||||
|
||||
State::Registers::Registers() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(a);
|
||||
DeclareField(flags);
|
||||
DeclareField(bc);
|
||||
DeclareField(de);
|
||||
DeclareField(hl);
|
||||
DeclareField(af_dash); // TODO: is there any disadvantage to declaring these for reflective
|
||||
DeclareField(bc_dash); // purposes as AF', BC', etc?
|
||||
DeclareField(de_dash);
|
||||
DeclareField(hl_dash);
|
||||
DeclareField(ix);
|
||||
DeclareField(iy);
|
||||
DeclareField(ir);
|
||||
DeclareField(program_counter);
|
||||
DeclareField(stack_pointer);
|
||||
DeclareField(interrupt_mode);
|
||||
DeclareField(iff1);
|
||||
DeclareField(iff2);
|
||||
DeclareField(memptr);
|
||||
}
|
||||
void State::Registers::declare_fields() {
|
||||
DeclareField(a);
|
||||
DeclareField(flags);
|
||||
DeclareField(bc);
|
||||
DeclareField(de);
|
||||
DeclareField(hl);
|
||||
DeclareField(af_dash); // TODO: is there any disadvantage to declaring these for reflective
|
||||
DeclareField(bc_dash); // purposes as AF', BC', etc?
|
||||
DeclareField(de_dash);
|
||||
DeclareField(hl_dash);
|
||||
DeclareField(ix);
|
||||
DeclareField(iy);
|
||||
DeclareField(ir);
|
||||
DeclareField(program_counter);
|
||||
DeclareField(stack_pointer);
|
||||
DeclareField(interrupt_mode);
|
||||
DeclareField(iff1);
|
||||
DeclareField(iff2);
|
||||
DeclareField(memptr);
|
||||
}
|
||||
|
||||
State::ExecutionState::ExecutionState() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(is_halted);
|
||||
DeclareField(requests);
|
||||
DeclareField(last_requests);
|
||||
DeclareField(temp8);
|
||||
DeclareField(operation);
|
||||
DeclareField(temp16);
|
||||
DeclareField(flag_adjustment_history);
|
||||
DeclareField(pc_increment);
|
||||
DeclareField(refresh_address);
|
||||
void State::ExecutionState::declare_fields() {
|
||||
DeclareField(is_halted);
|
||||
DeclareField(requests);
|
||||
DeclareField(last_requests);
|
||||
DeclareField(temp8);
|
||||
DeclareField(operation);
|
||||
DeclareField(temp16);
|
||||
DeclareField(flag_adjustment_history);
|
||||
DeclareField(pc_increment);
|
||||
DeclareField(refresh_address);
|
||||
|
||||
AnnounceEnum(Phase);
|
||||
DeclareField(phase);
|
||||
DeclareField(half_cycles_into_step);
|
||||
DeclareField(steps_into_phase);
|
||||
DeclareField(instruction_page);
|
||||
}
|
||||
AnnounceEnum(Phase);
|
||||
DeclareField(phase);
|
||||
DeclareField(half_cycles_into_step);
|
||||
DeclareField(steps_into_phase);
|
||||
DeclareField(instruction_page);
|
||||
}
|
||||
|
||||
State::Inputs::Inputs() {
|
||||
if(needs_declare()) {
|
||||
DeclareField(irq);
|
||||
DeclareField(nmi);
|
||||
DeclareField(bus_request);
|
||||
DeclareField(wait);
|
||||
}
|
||||
void State::Inputs::declare_fields() {
|
||||
DeclareField(irq);
|
||||
DeclareField(nmi);
|
||||
DeclareField(bus_request);
|
||||
DeclareField(wait);
|
||||
}
|
||||
|
@ -37,7 +37,9 @@ struct State: public Reflection::StructImpl<State> {
|
||||
int interrupt_mode;
|
||||
bool iff1, iff2;
|
||||
|
||||
Registers();
|
||||
private:
|
||||
friend Reflection::StructImpl<Registers>;
|
||||
void declare_fields();
|
||||
} registers;
|
||||
|
||||
/*!
|
||||
@ -50,7 +52,9 @@ struct State: public Reflection::StructImpl<State> {
|
||||
bool bus_request = false;
|
||||
bool wait = false;
|
||||
|
||||
Inputs();
|
||||
private:
|
||||
friend Reflection::StructImpl<Inputs>;
|
||||
void declare_fields();
|
||||
} inputs;
|
||||
|
||||
/*!
|
||||
@ -80,17 +84,22 @@ struct State: public Reflection::StructImpl<State> {
|
||||
int steps_into_phase = 0;
|
||||
uint16_t instruction_page = 0;
|
||||
|
||||
ExecutionState();
|
||||
private:
|
||||
friend Reflection::StructImpl<ExecutionState>;
|
||||
void declare_fields();
|
||||
} execution_state;
|
||||
|
||||
/// Default constructor; makes no guarantees as to field values beyond those given above.
|
||||
State();
|
||||
State() {}
|
||||
|
||||
/// Instantiates a new State based on the processor @c src.
|
||||
State(const ProcessorBase &src);
|
||||
|
||||
/// Applies this state to @c target.
|
||||
void apply(ProcessorBase &target);
|
||||
|
||||
private:
|
||||
friend Reflection::StructImpl<State>;
|
||||
void declare_fields();
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -27,12 +27,6 @@ namespace Reflection {
|
||||
|
||||
#define DeclareField(Name) declare(&Name, #Name)
|
||||
|
||||
#define BEGIN_DECLARATIONS void declare_fields() {
|
||||
#define END_DECLARATIONS } \
|
||||
struct Declarer { Declarer() { Target t; t.declare_fields(); } }; \
|
||||
static Declarer declarer;
|
||||
|
||||
|
||||
struct Struct {
|
||||
virtual std::vector<std::string> all_keys() const = 0;
|
||||
virtual const std::type_info *type_of(const std::string &name) const = 0;
|
||||
@ -248,9 +242,8 @@ protected:
|
||||
declare_field(&field1, "field1");
|
||||
declare_field(&field2, "field2");
|
||||
|
||||
Fields are registered in class storage. So callers can use needs_declare()
|
||||
to determine whether a class of this type has already established the
|
||||
reflective fields.
|
||||
They should provide a default constructor and implement the method
|
||||
declare_fields() to perform all declarations.
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -303,13 +296,6 @@ protected:
|
||||
permitted_enum_values_.emplace(name, permitted_values);
|
||||
}
|
||||
|
||||
/*!
|
||||
@returns @c true if this subclass of @c Struct has not yet declared any fields.
|
||||
*/
|
||||
bool needs_declare() const {
|
||||
return contents_.empty();
|
||||
}
|
||||
|
||||
/*!
|
||||
Performs a reverse lookup from field to name.
|
||||
*/
|
||||
@ -358,6 +344,15 @@ private:
|
||||
};
|
||||
static inline std::unordered_map<std::string, Field> contents_;
|
||||
static inline std::unordered_map<std::string, std::vector<bool>> permitted_enum_values_;
|
||||
|
||||
// Ensure fields are declared at startup.
|
||||
struct Declarer {
|
||||
Declarer() {
|
||||
Owner o;
|
||||
o.declare_fields();
|
||||
}
|
||||
};
|
||||
static Declarer declarer;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user