diff --git a/Machines/Commodore/Plus4/Plus4.cpp b/Machines/Commodore/Plus4/Plus4.cpp index 852a99474..7832c35d7 100644 --- a/Machines/Commodore/Plus4/Plus4.cpp +++ b/Machines/Commodore/Plus4/Plus4.cpp @@ -8,13 +8,42 @@ #include "Plus4.hpp" +#include "../../MachineTypes.hpp" + +#include "../../../Analyser/Static/Commodore/Target.hpp" + using namespace Commodore::Plus4; +namespace { + +class ConcreteMachine: + public MachineTypes::TimedMachine, + public MachineTypes::ScanProducer, + public Machine { +public: + ConcreteMachine(const Analyser::Static::Commodore::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) { + (void)target; + (void)rom_fetcher; + } + +private: + void set_scan_target(Outputs::Display::ScanTarget *const) final { + } + + Outputs::Display::ScanStatus get_scaled_scan_status() const final { + return {}; + } + + void run_for(const Cycles) final { + } +}; + +} std::unique_ptr Machine::Plus4( const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher ) { - (void)target; - (void)rom_fetcher; - return nullptr; + using Target = Analyser::Static::Commodore::Target; + const Target *const commodore_target = dynamic_cast(target); + return std::make_unique(*commodore_target, rom_fetcher); } diff --git a/Machines/ScanProducer.hpp b/Machines/ScanProducer.hpp index b63649497..73189fcff 100644 --- a/Machines/ScanProducer.hpp +++ b/Machines/ScanProducer.hpp @@ -20,82 +20,82 @@ namespace MachineTypes { by a ScanTarget. */ class ScanProducer { - public: - /*! - Causes the machine to set up its display and, if it has one, speaker. +public: + /*! + Causes the machine to set up its display and, if it has one, speaker. - The @c scan_target will receive all video output; the caller guarantees - that it is non-null. - */ - virtual void set_scan_target(Outputs::Display::ScanTarget *scan_target) = 0; + The @c scan_target will receive all video output; the caller guarantees + that it is non-null. + */ + virtual void set_scan_target(Outputs::Display::ScanTarget *) = 0; - /*! - @returns The current scan status. - */ - virtual Outputs::Display::ScanStatus get_scan_status() const { - // There's an implicit assumption here that anything which produces scans - // is also a timed machine. And, also, that this function will be called infrequently. - const TimedMachine *timed_machine = dynamic_cast(this); - return get_scaled_scan_status() / float(timed_machine->get_clock_rate()); + /*! + @returns The current scan status. + */ + virtual Outputs::Display::ScanStatus get_scan_status() const { + // There's an implicit assumption here that anything which produces scans + // is also a timed machine. And, also, that this function will be called infrequently. + const TimedMachine *timed_machine = dynamic_cast(this); + return get_scaled_scan_status() / float(timed_machine->get_clock_rate()); + } + +protected: + virtual Outputs::Display::ScanStatus get_scaled_scan_status() const { + // This deliberately sets up an infinite loop if the user hasn't + // overridden at least one of this or get_scan_status. + // + // Most likely you want to override this, and let the base class + // throw in a divide-by-clock-rate at the end for you. + return get_scan_status(); + } + + /*! + Maps from Configurable::Display to Outputs::Display::VideoSignal and calls + @c set_display_type with the result. + */ + void set_video_signal_configurable(Configurable::Display type) { + Outputs::Display::DisplayType display_type; + switch(type) { + default: + case Configurable::Display::RGB: + display_type = Outputs::Display::DisplayType::RGB; + break; + case Configurable::Display::SVideo: + display_type = Outputs::Display::DisplayType::SVideo; + break; + case Configurable::Display::CompositeColour: + display_type = Outputs::Display::DisplayType::CompositeColour; + break; + case Configurable::Display::CompositeMonochrome: + display_type = Outputs::Display::DisplayType::CompositeMonochrome; + break; } + set_display_type(display_type); + } - protected: - virtual Outputs::Display::ScanStatus get_scaled_scan_status() const { - // This deliberately sets up an infinite loop if the user hasn't - // overridden at least one of this or get_scan_status. - // - // Most likely you want to override this, and let the base class - // throw in a divide-by-clock-rate at the end for you. - return get_scan_status(); + /*! + Maps back from Outputs::Display::VideoSignal to Configurable::Display, + calling @c get_display_type for the input. + */ + Configurable::Display get_video_signal_configurable() const { + switch(get_display_type()) { + default: + case Outputs::Display::DisplayType::RGB: return Configurable::Display::RGB; + case Outputs::Display::DisplayType::SVideo: return Configurable::Display::SVideo; + case Outputs::Display::DisplayType::CompositeColour: return Configurable::Display::CompositeColour; + case Outputs::Display::DisplayType::CompositeMonochrome: return Configurable::Display::CompositeMonochrome; } + } - /*! - Maps from Configurable::Display to Outputs::Display::VideoSignal and calls - @c set_display_type with the result. - */ - void set_video_signal_configurable(Configurable::Display type) { - Outputs::Display::DisplayType display_type; - switch(type) { - default: - case Configurable::Display::RGB: - display_type = Outputs::Display::DisplayType::RGB; - break; - case Configurable::Display::SVideo: - display_type = Outputs::Display::DisplayType::SVideo; - break; - case Configurable::Display::CompositeColour: - display_type = Outputs::Display::DisplayType::CompositeColour; - break; - case Configurable::Display::CompositeMonochrome: - display_type = Outputs::Display::DisplayType::CompositeMonochrome; - break; - } - set_display_type(display_type); - } + /*! + Sets the display type. + */ + virtual void set_display_type(Outputs::Display::DisplayType) {} - /*! - Maps back from Outputs::Display::VideoSignal to Configurable::Display, - calling @c get_display_type for the input. - */ - Configurable::Display get_video_signal_configurable() const { - switch(get_display_type()) { - default: - case Outputs::Display::DisplayType::RGB: return Configurable::Display::RGB; - case Outputs::Display::DisplayType::SVideo: return Configurable::Display::SVideo; - case Outputs::Display::DisplayType::CompositeColour: return Configurable::Display::CompositeColour; - case Outputs::Display::DisplayType::CompositeMonochrome: return Configurable::Display::CompositeMonochrome; - } - } - - /*! - Sets the display type. - */ - virtual void set_display_type(Outputs::Display::DisplayType) {} - - /*! - Gets the display type. - */ - virtual Outputs::Display::DisplayType get_display_type() const { return Outputs::Display::DisplayType::RGB; } + /*! + Gets the display type. + */ + virtual Outputs::Display::DisplayType get_display_type() const { return Outputs::Display::DisplayType::RGB; } }; } diff --git a/Machines/Utility/MachineForTarget.cpp b/Machines/Utility/MachineForTarget.cpp index 3aea25755..493fffd73 100644 --- a/Machines/Utility/MachineForTarget.cpp +++ b/Machines/Utility/MachineForTarget.cpp @@ -21,6 +21,7 @@ #include "../Atari/2600/Atari2600.hpp" #include "../Atari/ST/AtariST.hpp" #include "../ColecoVision/ColecoVision.hpp" +#include "../Commodore/Plus4/Plus4.hpp" #include "../Commodore/Vic-20/Vic20.hpp" #include "../Enterprise/Enterprise.hpp" #include "../MasterSystem/MasterSystem.hpp" @@ -68,6 +69,7 @@ std::unique_ptr Machine::MachineForTarget(const Analyse Bind(Atari2600) BindD(Atari::ST, AtariST) BindD(Coleco::Vision, ColecoVision) + BindD(Commodore::Plus4, Plus4) BindD(Commodore::Vic20, Vic20) Bind(Electron) Bind(Enterprise) @@ -145,6 +147,7 @@ std::string Machine::ShortNameForTargetMachine(const Analyser::Machine machine) case Analyser::Machine::MasterSystem: return "MasterSystem"; case Analyser::Machine::MSX: return "MSX"; case Analyser::Machine::Oric: return "Oric"; + case Analyser::Machine::Plus4: return "Plus4"; case Analyser::Machine::PCCompatible: return "PCCompatible"; case Analyser::Machine::Vic20: return "Vic20"; case Analyser::Machine::ZX8081: return "ZX8081"; @@ -170,6 +173,7 @@ std::string Machine::LongNameForTargetMachine(Analyser::Machine machine) { case Analyser::Machine::MasterSystem: return "Sega Master System"; case Analyser::Machine::MSX: return "MSX"; case Analyser::Machine::Oric: return "Oric"; + case Analyser::Machine::Plus4: return "Commodore C16+4"; case Analyser::Machine::PCCompatible: return "PC Compatible"; case Analyser::Machine::Vic20: return "Vic 20"; case Analyser::Machine::ZX8081: return "ZX80/81"; @@ -202,6 +206,7 @@ std::vector Machine::AllMachines(Type type, bool long_names) { AddName(Macintosh); AddName(MSX); AddName(Oric); + AddName(Plus4); AddName(PCCompatible); AddName(Vic20); AddName(ZX8081); @@ -230,6 +235,7 @@ std::map> Machine::AllOptionsBy Emplace(MasterSystem, Sega::MasterSystem::Machine); Emplace(MSX, MSX::Machine); Emplace(Oric, Oric::Machine); +// Emplace(Plus4, Commodore::Plus4::Machine); // There are no options yet. Emplace(PCCompatible, PCCompatible::Machine); Emplace(Vic20, Commodore::Vic20::Machine); Emplace(ZX8081, Sinclair::ZX8081::Machine); @@ -258,6 +264,7 @@ std::map> Machine::Target Add(Macintosh); Add(MSX); Add(Oric); + AddMapped(Plus4, Commodore); Add(PCCompatible); AddMapped(Vic20, Commodore); Add(ZX8081);