mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-03 15:29:45 +00:00
Add SSM code capture to CPC.
This commit is contained in:
parent
63737c09aa
commit
f742266177
@ -20,6 +20,9 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl<Ta
|
|||||||
Model model = Model::CPC464;
|
Model model = Model::CPC464;
|
||||||
std::string loading_command;
|
std::string loading_command;
|
||||||
|
|
||||||
|
// This is used internally for testing; it therefore isn't exposed reflectively.
|
||||||
|
bool catch_ssm_codes = false;
|
||||||
|
|
||||||
Target() : Analyser::Static::Target(Machine::AmstradCPC) {
|
Target() : Analyser::Static::Target(Machine::AmstradCPC) {
|
||||||
if(needs_declare()) {
|
if(needs_declare()) {
|
||||||
DeclareField(model);
|
DeclareField(model);
|
||||||
|
@ -752,7 +752,8 @@ class i8255PortHandler : public Intel::i8255::PortHandler {
|
|||||||
/*!
|
/*!
|
||||||
The actual Amstrad CPC implementation; tying the 8255, 6845 and AY to the Z80.
|
The actual Amstrad CPC implementation; tying the 8255, 6845 and AY to the Z80.
|
||||||
*/
|
*/
|
||||||
template <bool has_fdc> class ConcreteMachine:
|
template <bool has_fdc, bool catches_ssm>
|
||||||
|
class ConcreteMachine:
|
||||||
public MachineTypes::ScanProducer,
|
public MachineTypes::ScanProducer,
|
||||||
public MachineTypes::AudioProducer,
|
public MachineTypes::AudioProducer,
|
||||||
public MachineTypes::TimedMachine,
|
public MachineTypes::TimedMachine,
|
||||||
@ -942,6 +943,19 @@ template <bool has_fdc> class ConcreteMachine:
|
|||||||
*cycle.value = 0xc9;
|
*cycle.value = 0xc9;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if constexpr (catches_ssm) {
|
||||||
|
ssm_code_ = (ssm_code_ << 8) | read_pointers_[address >> 14][address & 16383];
|
||||||
|
if((ssm_code_ & 0xff00ff00) == 0xed00ed00) {
|
||||||
|
if(ssm_delegate_) {
|
||||||
|
ssm_delegate_->perform(
|
||||||
|
uint16_t(
|
||||||
|
(ssm_code_ & 0xff) | ((ssm_code_ >> 8) & 0xff00)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
ssm_code_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
|
|
||||||
case CPU::Z80::PartialMachineCycle::Read:
|
case CPU::Z80::PartialMachineCycle::Read:
|
||||||
@ -1115,6 +1129,10 @@ template <bool has_fdc> class ConcreteMachine:
|
|||||||
tape_player_is_sleeping_ = tape_player_.preferred_clocking() == ClockingHint::Preference::None;
|
tape_player_is_sleeping_ = tape_player_.preferred_clocking() == ClockingHint::Preference::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_ssm_delegate(SSMDelegate *delegate) final {
|
||||||
|
ssm_delegate_ = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Keyboard
|
// MARK: - Keyboard
|
||||||
void type_string(const std::string &string) final {
|
void type_string(const std::string &string) final {
|
||||||
Utility::TypeRecipient<CharacterMapper>::add_typer(string);
|
Utility::TypeRecipient<CharacterMapper>::add_typer(string);
|
||||||
@ -1276,6 +1294,9 @@ template <bool has_fdc> class ConcreteMachine:
|
|||||||
KeyboardState key_state_;
|
KeyboardState key_state_;
|
||||||
AmstradCPC::KeyboardMapper keyboard_mapper_;
|
AmstradCPC::KeyboardMapper keyboard_mapper_;
|
||||||
|
|
||||||
|
SSMDelegate *ssm_delegate_ = nullptr;
|
||||||
|
uint32_t ssm_code_ = 0;
|
||||||
|
|
||||||
bool has_run_ = false;
|
bool has_run_ = false;
|
||||||
uint8_t ram_[128 * 1024];
|
uint8_t ram_[128 * 1024];
|
||||||
};
|
};
|
||||||
@ -1284,12 +1305,26 @@ template <bool has_fdc> class ConcreteMachine:
|
|||||||
|
|
||||||
using namespace AmstradCPC;
|
using namespace AmstradCPC;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <bool catch_ssm>
|
||||||
|
std::unique_ptr<Machine> machine(const Analyser::Static::AmstradCPC::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) {
|
||||||
|
using Model = Analyser::Static::AmstradCPC::Target::Model;
|
||||||
|
switch(target.model) {
|
||||||
|
default: return std::make_unique<AmstradCPC::ConcreteMachine<true, catch_ssm>>(target, rom_fetcher);
|
||||||
|
case Model::CPC464: return std::make_unique<AmstradCPC::ConcreteMachine<false, catch_ssm>>(target, rom_fetcher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// See header; constructs and returns an instance of the Amstrad CPC.
|
// See header; constructs and returns an instance of the Amstrad CPC.
|
||||||
std::unique_ptr<Machine> Machine::AmstradCPC(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) {
|
std::unique_ptr<Machine> Machine::AmstradCPC(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher) {
|
||||||
using Target = Analyser::Static::AmstradCPC::Target;
|
using Target = Analyser::Static::AmstradCPC::Target;
|
||||||
const Target *const cpc_target = dynamic_cast<const Target *>(target);
|
const Target *const cpc_target = dynamic_cast<const Target *>(target);
|
||||||
switch(cpc_target->model) {
|
if(cpc_target->catch_ssm_codes) {
|
||||||
default: return std::make_unique<AmstradCPC::ConcreteMachine<true>>(*cpc_target, rom_fetcher);
|
return machine<true>(*cpc_target, rom_fetcher);
|
||||||
case Target::Model::CPC464: return std::make_unique<AmstradCPC::ConcreteMachine<false>>(*cpc_target, rom_fetcher);
|
} else {
|
||||||
|
return machine<false>(*cpc_target, rom_fetcher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,10 @@ class Machine {
|
|||||||
virtual ~Machine() = default;
|
virtual ~Machine() = default;
|
||||||
|
|
||||||
/// Creates and returns an Amstrad CPC.
|
/// Creates and returns an Amstrad CPC.
|
||||||
static std::unique_ptr<Machine> AmstradCPC(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher);
|
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.
|
/// Defines the runtime options available for an Amstrad CPC.
|
||||||
class Options:
|
class Options:
|
||||||
@ -47,6 +50,11 @@ class Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SSMDelegate {
|
||||||
|
virtual void perform(uint16_t) = 0;
|
||||||
|
};
|
||||||
|
virtual void set_ssm_delegate(SSMDelegate *) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,6 @@ using namespace Storage::Automation;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct CSLTest {
|
|
||||||
CSLTest() {
|
|
||||||
CSL::parse("/Users/thomasharte/Downloads/Shaker_CSL/MODULE A/SHAKE26A-4.CSL");
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
CSLTest test;
|
|
||||||
|
|
||||||
bool append_typed(std::vector<Storage::Automation::CSL::KeyEvent> &down, std::vector<Storage::Automation::CSL::KeyEvent> &up, std::istringstream &stream) {
|
bool append_typed(std::vector<Storage::Automation::CSL::KeyEvent> &down, std::vector<Storage::Automation::CSL::KeyEvent> &up, std::istringstream &stream) {
|
||||||
const auto press = [&](uint16_t key) {
|
const auto press = [&](uint16_t key) {
|
||||||
CSL::KeyEvent event;
|
CSL::KeyEvent event;
|
||||||
|
Loading…
Reference in New Issue
Block a user