1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-11 15:49:38 +00:00

Route +4 software into a non-functional +4.

This commit is contained in:
Thomas Harte 2024-12-06 15:17:49 -05:00
parent c14a4515ce
commit 9fcb634510
3 changed files with 108 additions and 72 deletions

View File

@ -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> 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<const Target *>(target);
return std::make_unique<ConcreteMachine>(*commodore_target, rom_fetcher);
}

View File

@ -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<const TimedMachine *>(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<const TimedMachine *>(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; }
};
}

View File

@ -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::DynamicMachine> 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<std::string> 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<std::string, std::unique_ptr<Reflection::Struct>> 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<std::string, std::unique_ptr<Analyser::Static::Target>> Machine::Target
Add(Macintosh);
Add(MSX);
Add(Oric);
AddMapped(Plus4, Commodore);
Add(PCCompatible);
AddMapped(Vic20, Commodore);
Add(ZX8081);