1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-26 15:32:04 +00:00

Takes a shot at an ADB mouse.

This commit is contained in:
Thomas Harte 2021-02-15 20:49:16 -05:00
parent e16d5f33d1
commit fa8236741d
5 changed files with 76 additions and 5 deletions

View File

@ -12,5 +12,51 @@ using namespace Apple::ADB;
Mouse::Mouse(Bus &bus) : ReactiveDevice(bus, 3) {}
void Mouse::perform_command(const Command &) {
void Mouse::perform_command(const Command &command) {
if(command.type == Command::Type::Talk && command.reg == 0) {
// Read current deltas and buttons, thread safely.
auto delta_x = delta_x_.exchange(0);
auto delta_y = delta_y_.exchange(0);
const int buttons = button_flags_;
// Clamp deltas.
delta_x = std::max(std::min(delta_x, int16_t(127)), int16_t(-128));
delta_y = std::max(std::min(delta_y, int16_t(127)), int16_t(-128));
// Figure out what that would look like, and don't respond if there's
// no change to report.
const uint16_t reg0 =
((buttons & 1) ? 0x0000 : 0x8000) |
((buttons & 2) ? 0x0000 : 0x0080) |
uint16_t(delta_x & 0x7f) |
uint16_t((delta_y & 0x7f) << 8);
if(reg0 == last_posted_reg0_) return;
// Post change.
last_posted_reg0_ = reg0;
post_response({uint8_t(reg0 >> 8), uint8_t(reg0)});
}
}
void Mouse::move(int x, int y) {
delta_x_ += int16_t(x);
delta_y_ += int16_t(y);
post_service_request();
}
int Mouse::get_number_of_buttons() {
return 2;
}
void Mouse::set_button_pressed(int index, bool is_pressed) {
if(is_pressed)
button_flags_ |= (1 << index);
else
button_flags_ &= ~(1 << index);
post_service_request();
}
void Mouse::reset_all_buttons() {
button_flags_ = 0;
post_service_request();
}

View File

@ -10,16 +10,26 @@
#define Mouse_hpp
#include "ReactiveDevice.hpp"
#include "../../../Inputs/Mouse.hpp"
namespace Apple {
namespace ADB {
class Mouse: public ReactiveDevice {
class Mouse: public ReactiveDevice, public Inputs::Mouse {
public:
Mouse(Bus &);
private:
void perform_command(const Command &command) override;
void move(int x, int y) override;
int get_number_of_buttons() override;
void set_button_pressed(int index, bool is_pressed) override;
void reset_all_buttons() override;
std::atomic<int16_t> delta_x_, delta_y_;
std::atomic<int> button_flags_ = 0;
uint16_t last_posted_reg0_ = 0;
};
}

View File

@ -125,7 +125,7 @@ void ReactiveDevice::adb_bus_did_observe_event(Bus::Event event, uint8_t value)
phase_ = Phase::AwaitingAttention;
command_ = decode_command(value);
LOG(command_);
// LOG(command_);
// If this command doesn't apply here, but a service request is requested,
// post a service request.

View File

@ -45,10 +45,16 @@ class GLU: public InstructionSet::M50740::PortHandler {
bool get_option_button() const;
void set_vertical_blank(bool);
bool get_vertical_blank() {
return vertical_blank_;
}
Apple::ADB::Keyboard &keyboard() {
return keyboard_;
}
Inputs::Mouse &get_mouse() {
return mouse_;
}
private:
InstructionSet::M50740::Executor executor_;
@ -70,6 +76,8 @@ class GLU: public InstructionSet::M50740::PortHandler {
uint8_t modifier_state_ = 0;
bool vertical_blank_ = false;
// For now, attach only a keyboard and mouse.
Apple::ADB::Mouse mouse_;
Apple::ADB::Keyboard keyboard_;

View File

@ -52,6 +52,7 @@ class ConcreteMachine:
public MachineTypes::ScanProducer,
public MachineTypes::TimedMachine,
public MachineTypes::MappedKeyboardMachine,
public MachineTypes::MouseMachine,
public CPU::MOS6502Esque::BusHandler<uint32_t> {
public:
@ -898,7 +899,9 @@ class ConcreteMachine:
update_interrupts();
const bool is_vertical_blank = video_.last_valid()->get_is_vertical_blank(video_.time_since_flush());
adb_glu_->set_vertical_blank(is_vertical_blank);
if(is_vertical_blank != adb_glu_.last_valid()->get_vertical_blank()) {
adb_glu_->set_vertical_blank(is_vertical_blank);
}
}
return duration;
@ -910,7 +913,7 @@ class ConcreteMachine:
m65816_.set_irq_line(video_.last_valid()->get_interrupt_line() || sound_glu_.get_interrupt_line());
}
// MARK: - Keyboard input.
// MARK: - Input.
KeyboardMapper *get_keyboard_mapper() final {
return &keyboard_mapper_;
}
@ -923,6 +926,10 @@ class ConcreteMachine:
adb_glu_.last_valid()->keyboard().clear_all_keys();
}
Inputs::Mouse &get_mouse() final {
return adb_glu_.last_valid()->get_mouse();
}
private:
CPU::WDC65816::Processor<ConcreteMachine, false> m65816_;
MemoryMap memory_;