1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 01:31:42 +00:00

Merge pull request #935 from TomHarte/OricJoystick

Adds Altai-style joystick support for the Oric.
This commit is contained in:
Thomas Harte 2021-04-29 20:15:42 -04:00 committed by GitHub
commit c906dc3c0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -40,6 +40,45 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
namespace {
/*!
Provides an Altai-style joystick.
*/
class Joystick: public Inputs::ConcreteJoystick {
public:
Joystick() :
ConcreteJoystick({
Input(Input::Up),
Input(Input::Down),
Input(Input::Left),
Input(Input::Right),
Input(Input::Fire)
}) {}
void did_set_input(const Input &digital_input, bool is_active) final {
#define APPLY(b) if(is_active) state_ &= ~b; else state_ |= b;
switch(digital_input.type) {
default: return;
case Input::Right: APPLY(0x02); break;
case Input::Left: APPLY(0x01); break;
case Input::Down: APPLY(0x08); break;
case Input::Up: APPLY(0x10); break;
case Input::Fire: APPLY(0x20); break;
}
#undef APPLY
}
uint8_t get_state() {
return state_;
}
private:
uint8_t state_ = 0xff;
};
}
namespace Oric { namespace Oric {
using DiskInterface = Analyser::Static::Oric::Target::DiskInterface; using DiskInterface = Analyser::Static::Oric::Target::DiskInterface;
@ -140,7 +179,12 @@ class TapePlayer: public Storage::Tape::BinaryTapePlayer {
class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler { class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler {
public: public:
VIAPortHandler(Concurrency::DeferringAsyncTaskQueue &audio_queue, AY &ay8910, Speaker &speaker, TapePlayer &tape_player, Keyboard &keyboard) : VIAPortHandler(Concurrency::DeferringAsyncTaskQueue &audio_queue, AY &ay8910, Speaker &speaker, TapePlayer &tape_player, Keyboard &keyboard) :
audio_queue_(audio_queue), ay8910_(ay8910), speaker_(speaker), tape_player_(tape_player), keyboard_(keyboard) {} audio_queue_(audio_queue), ay8910_(ay8910), speaker_(speaker), tape_player_(tape_player), keyboard_(keyboard)
{
// Attach a couple of joysticks.
joysticks_.emplace_back(new Joystick);
joysticks_.emplace_back(new Joystick);
}
/*! /*!
Reponds to the 6522's control line output change signal; on an Oric A2 is connected to Reponds to the 6522's control line output change signal; on an Oric A2 is connected to
@ -165,6 +209,7 @@ class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler {
} else { } else {
update_ay(); update_ay();
ay8910_.set_data_input(value); ay8910_.set_data_input(value);
porta_output_ = value;
} }
} }
@ -176,7 +221,10 @@ class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler {
uint8_t column = ay8910_.get_port_output(false) ^ 0xff; uint8_t column = ay8910_.get_port_output(false) ^ 0xff;
return keyboard_.query_column(column) ? 0x08 : 0x00; return keyboard_.query_column(column) ? 0x08 : 0x00;
} else { } else {
return ay8910_.get_data_output(); uint8_t result = ay8910_.get_data_output();
if(porta_output_ & 0x40) result &= static_cast<Joystick *>(joysticks_[0].get())->get_state();
if(porta_output_ & 0x80) result &= static_cast<Joystick *>(joysticks_[1].get())->get_state();
return result;
} }
} }
@ -193,12 +241,17 @@ class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler {
audio_queue_.perform(); audio_queue_.perform();
} }
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() {
return joysticks_;
}
private: private:
void update_ay() { void update_ay() {
speaker_.run_for(audio_queue_, cycles_since_ay_update_.flush<Cycles>()); speaker_.run_for(audio_queue_, cycles_since_ay_update_.flush<Cycles>());
} }
bool ay_bdir_ = false; bool ay_bdir_ = false;
bool ay_bc1_ = false; bool ay_bc1_ = false;
uint8_t porta_output_ = 0xff;
HalfCycles cycles_since_ay_update_; HalfCycles cycles_since_ay_update_;
Concurrency::DeferringAsyncTaskQueue &audio_queue_; Concurrency::DeferringAsyncTaskQueue &audio_queue_;
@ -206,12 +259,15 @@ class VIAPortHandler: public MOS::MOS6522::IRQDelegatePortHandler {
Speaker &speaker_; Speaker &speaker_;
TapePlayer &tape_player_; TapePlayer &tape_player_;
Keyboard &keyboard_; Keyboard &keyboard_;
std::vector<std::unique_ptr<Inputs::Joystick>> joysticks_;
}; };
template <Analyser::Static::Oric::Target::DiskInterface disk_interface, CPU::MOS6502Esque::Type processor_type> class ConcreteMachine: template <Analyser::Static::Oric::Target::DiskInterface disk_interface, CPU::MOS6502Esque::Type processor_type> class ConcreteMachine:
public MachineTypes::TimedMachine, public MachineTypes::TimedMachine,
public MachineTypes::ScanProducer, public MachineTypes::ScanProducer,
public MachineTypes::AudioProducer, public MachineTypes::AudioProducer,
public MachineTypes::JoystickMachine,
public MachineTypes::MediaTarget, public MachineTypes::MediaTarget,
public MachineTypes::MappedKeyboardMachine, public MachineTypes::MappedKeyboardMachine,
public Configurable::Device, public Configurable::Device,
@ -731,8 +787,13 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface, CPU::MOS
} }
} }
// MARK - typing // MARK: - typing
std::unique_ptr<Utility::StringSerialiser> string_serialiser_; std::unique_ptr<Utility::StringSerialiser> string_serialiser_;
// MARK: - Joysticks
const std::vector<std::unique_ptr<Inputs::Joystick>> &get_joysticks() override {
return via_port_handler_.get_joysticks();
}
}; };
} }