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:
commit
c906dc3c0a
@ -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();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user