From c284b340033a4cd54b9d845403c4a31cf792e982 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 13 Feb 2021 17:53:40 -0500 Subject: [PATCH] Resolves inability of ADB microcontroller to read its own ROM (!) --- InstructionSets/M50740/Executor.cpp | 12 ++++++++++-- Machines/Apple/ADB/Mouse.cpp | 22 ++-------------------- Machines/Apple/ADB/Mouse.hpp | 5 +---- Machines/Apple/ADB/ReactiveDevice.cpp | 27 ++++++++++++++++++++++++++- Machines/Apple/ADB/ReactiveDevice.hpp | 9 ++++++++- 5 files changed, 47 insertions(+), 28 deletions(-) diff --git a/InstructionSets/M50740/Executor.cpp b/InstructionSets/M50740/Executor.cpp index 449fab886..c0b1c554b 100644 --- a/InstructionSets/M50740/Executor.cpp +++ b/InstructionSets/M50740/Executor.cpp @@ -38,7 +38,9 @@ Executor::Executor(PortHandler &port_handler) : port_handler_(port_handler) { } } + // Fuzz RAM; then set anything that may be replaced by ROM to FF. Memory::Fuzz(memory_); + memset(&memory_[0x100], 0xff, memory_.size() - 0x100); } void Executor::set_rom(const std::vector &rom) { @@ -63,8 +65,8 @@ void Executor::reset() { uint8_t Executor::read(uint16_t address) { address &= 0x1fff; - // Deal with a RAM access quickly. - if(address < 0x60) return memory_[address]; + // Deal with RAM and ROM accesses quickly. + if(address < 0x60 || address >= 0x100) return memory_[address]; port_handler_.run_ports_for(cycles_since_port_handler_.flush()); switch(address) { @@ -118,6 +120,12 @@ void Executor::write(uint16_t address, uint8_t value) { return; } + // ROM 'writes' are almost as easy (albeit unexpected). + if(address >= 0x100) { + LOG("Attempted ROM write of " << PADHEX(2) << value << " to " << PADHEX(4) << address); + return; + } + // Push time to the port handler. port_handler_.run_ports_for(cycles_since_port_handler_.flush()); diff --git a/Machines/Apple/ADB/Mouse.cpp b/Machines/Apple/ADB/Mouse.cpp index 49c8e2e89..af3bec90d 100644 --- a/Machines/Apple/ADB/Mouse.cpp +++ b/Machines/Apple/ADB/Mouse.cpp @@ -8,27 +8,9 @@ #include "Mouse.hpp" -#define LOG_PREFIX "[Mouse] " -#include "../../../Outputs/Log.hpp" - using namespace Apple::ADB; -Mouse::Mouse(Bus &bus) : ReactiveDevice(bus) {} +Mouse::Mouse(Bus &bus) : ReactiveDevice(bus, 3) {} -void Mouse::adb_bus_did_observe_event(Bus::Event event, uint8_t value) { - if(!next_is_command_ && event != Bus::Event::Attention) { - return; - } - - if(next_is_command_ && event == Bus::Event::Byte) { - next_is_command_ = false; - - const auto command = decode_command(value); - LOG(command); - if(command.device != 3) { - return; - } - } else if(event == Bus::Event::Attention) { - next_is_command_ = true; - } +void Mouse::perform_command(const Command &) { } diff --git a/Machines/Apple/ADB/Mouse.hpp b/Machines/Apple/ADB/Mouse.hpp index 5749d1cb4..ebbd0cbb9 100644 --- a/Machines/Apple/ADB/Mouse.hpp +++ b/Machines/Apple/ADB/Mouse.hpp @@ -18,10 +18,7 @@ class Mouse: public ReactiveDevice { public: Mouse(Bus &); - void adb_bus_did_observe_event(Bus::Event event, uint8_t value) override; - - private: - bool next_is_command_ = false; + void perform_command(const Command &command) override; }; } diff --git a/Machines/Apple/ADB/ReactiveDevice.cpp b/Machines/Apple/ADB/ReactiveDevice.cpp index b21fe45d4..2c402bfb3 100644 --- a/Machines/Apple/ADB/ReactiveDevice.cpp +++ b/Machines/Apple/ADB/ReactiveDevice.cpp @@ -8,9 +8,15 @@ #include "ReactiveDevice.hpp" +#define LOG_PREFIX "[ADB device] " +#include "../../../Outputs/Log.hpp" + using namespace Apple::ADB; -ReactiveDevice::ReactiveDevice(Apple::ADB::Bus &bus) : bus_(bus), device_id_(bus.add_device(this)) {} +ReactiveDevice::ReactiveDevice(Apple::ADB::Bus &bus, uint8_t adb_device_id) : + bus_(bus), + device_id_(bus.add_device(this)), + adb_device_id_(adb_device_id) {} void ReactiveDevice::post_response(const std::vector &&response) { response_ = std::move(response); @@ -53,3 +59,22 @@ void ReactiveDevice::advance_state(double microseconds) { constexpr double low_periods[] = {66, 33}; bus_.set_device_output(device_id_, microseconds_at_bit_ > low_periods[bit]); } + +void ReactiveDevice::adb_bus_did_observe_event(Bus::Event event, uint8_t value) { + if(!next_is_command_ && event != Bus::Event::Attention) { + return; + } + + if(next_is_command_ && event == Bus::Event::Byte) { + next_is_command_ = false; + + const auto command = decode_command(value); + LOG(command); + if(command.device == adb_device_id_) { + // TODO: handle fixed commands here (like register 3?) + perform_command(command); + } + } else if(event == Bus::Event::Attention) { + next_is_command_ = true; + } +} diff --git a/Machines/Apple/ADB/ReactiveDevice.hpp b/Machines/Apple/ADB/ReactiveDevice.hpp index ab7ade2c6..67e96ddf0 100644 --- a/Machines/Apple/ADB/ReactiveDevice.hpp +++ b/Machines/Apple/ADB/ReactiveDevice.hpp @@ -19,10 +19,14 @@ namespace ADB { class ReactiveDevice: public Bus::Device { protected: - ReactiveDevice(Bus &bus); + ReactiveDevice(Bus &bus, uint8_t adb_device_id); void post_response(const std::vector &&response); + virtual void perform_command(const Command &command) = 0; + + private: void advance_state(double microseconds) override; + void adb_bus_did_observe_event(Bus::Event event, uint8_t value) override; private: Bus &bus_; @@ -31,6 +35,9 @@ class ReactiveDevice: public Bus::Device { std::vector response_; int bit_offset_ = 0; double microseconds_at_bit_ = 0; + + bool next_is_command_ = false; + uint8_t adb_device_id_; }; }