From e8e604dc3c324dd9bdb60329884de8fd3b9c9d43 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 24 Jan 2021 18:07:05 -0500 Subject: [PATCH] Attempts to wire up M50470 and GLU. Resulting in an unexpected interest in R15. Bugs to find, I guess. --- InstructionSets/M50740/Executor.cpp | 46 +++++++++++++++++++++----- InstructionSets/M50740/Executor.hpp | 8 ++++- Machines/Apple/AppleIIgs/ADB.cpp | 51 +++++++++++++++++++++++++++++ Machines/Apple/AppleIIgs/ADB.hpp | 10 +++++- 4 files changed, 105 insertions(+), 10 deletions(-) diff --git a/InstructionSets/M50740/Executor.cpp b/InstructionSets/M50740/Executor.cpp index 09c4fd03b..79c3edbb6 100644 --- a/InstructionSets/M50740/Executor.cpp +++ b/InstructionSets/M50740/Executor.cpp @@ -14,7 +14,11 @@ using namespace InstructionSet::M50740; -Executor::Executor() { +namespace { + constexpr int port_remap[] = {0, 1, 2, 0, 3}; +} + +Executor::Executor(PortHandler &port_handler) : port_handler_(port_handler) { // Cut down the list of all generated performers to those the processor actually uses, and install that // for future referencing by action_for. Decoder decoder; @@ -58,20 +62,22 @@ uint8_t Executor::read(uint16_t address) { // "Port R"; sixteen four-bit ports case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: - printf("TODO: Port R\n"); + printf("TODO: Port R [r %04x]\n", address); return 0xff; // Ports P0–P3. - case 0xe0: case 0xe1: - case 0xe2: case 0xe3: - case 0xe4: case 0xe5: - case 0xe8: case 0xe9: - printf("TODO: Ports P0–P3\n"); + case 0xe0: case 0xe2: + case 0xe4: case 0xe8: + return port_handler_.get_port_input(port_remap[(address - 0xe0) >> 1]); + + case 0xe1: case 0xe3: + case 0xe5: case 0xe9: + printf("TODO: Ports P0–P3 direction [r %04x]\n", address); return 0xff; // Timers. case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: - printf("TODO: Timers\n"); + printf("TODO: Timers [r %04x]\n", address); return 0xff; } } @@ -84,6 +90,30 @@ void Executor::write(uint16_t address, uint8_t value) { } // TODO: all external IO ports. + switch(address) { + default: break; + + // "Port R"; sixteen four-bit ports + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + printf("TODO: Port R [w %04x %02x]\n", address, value); + break; + + // Ports P0–P3. + case 0xe0: case 0xe2: + case 0xe4: case 0xe8: + return port_handler_.set_port_output(port_remap[(address - 0xe0) >> 1], value); + + case 0xe1: case 0xe3: + case 0xe5: case 0xe9: + printf("TODO: Ports P0–P3 direction [w %04x %02x]\n", address, value); + break; + + // Timers. + case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: + printf("TODO: Timers [w %04x %02x]\n", address, value); + break; + } } void Executor::push(uint8_t value) { diff --git a/InstructionSets/M50740/Executor.hpp b/InstructionSets/M50740/Executor.hpp index abec7ae8e..106fe55c9 100644 --- a/InstructionSets/M50740/Executor.hpp +++ b/InstructionSets/M50740/Executor.hpp @@ -23,6 +23,11 @@ namespace M50740 { class Executor; using CachingExecutor = CachingExecutor; +struct PortHandler { + virtual void set_port_output(int port, uint8_t value) = 0; + virtual uint8_t get_port_input(int port) = 0; +}; + /*! Executes M50740 code subject to heavy limitations: @@ -31,7 +36,7 @@ using CachingExecutor = CachingExecutor &rom); void reset(); @@ -138,6 +143,7 @@ class Executor: public CachingExecutor { template inline void perform_interrupt(); Cycles cycles_; + PortHandler &port_handler_; }; } diff --git a/Machines/Apple/AppleIIgs/ADB.cpp b/Machines/Apple/AppleIIgs/ADB.cpp index e3b1c1b55..a81798675 100644 --- a/Machines/Apple/AppleIIgs/ADB.cpp +++ b/Machines/Apple/AppleIIgs/ADB.cpp @@ -8,10 +8,13 @@ #include "ADB.hpp" +#include #include using namespace Apple::IIgs::ADB; +GLU::GLU() : executor_(*this) {} + // MARK: - Configuration. void GLU::set_is_rom03(bool is_rom03) { @@ -219,3 +222,51 @@ void GLU::set_microcontroller_rom(const std::vector &rom) { void GLU::run_for(Cycles cycles) { executor_.run_for(cycles); } + +// MARK: - M50470 port handler + +void GLU::set_port_output(int port, uint8_t value) { + switch(port) { + case 0: + printf("Set R%d: %02x\n", register_address_, value); + registers_[register_address_] = value; + break; + case 1: +// printf("Keyboard write: %02x???\n", value); + break; + case 2: +// printf("ADB data line input: %d???\n", value >> 7); +// printf("IIe keyboard reset line: %d\n", (value >> 6)&1); +// printf("IIgs reset line: %d\n", (value >> 5)&1); +// printf("GLU strobe: %d\n", (value >> 4)&1); + printf("Select GLU register: %d [%02x]\n", value & 0xf, value); + register_address_ = value & 0xf; + break; + case 3: +// printf("IIe KWS: %d\n", (value >> 6)&3); + printf("ADB data line output: %d\n", (value >> 3)&1); + break; + + default: assert(false); + } +} + +uint8_t GLU::get_port_input(int port) { + switch(port) { + case 0: + printf("Get R%d\n", register_address_); + return registers_[register_address_]; + case 1: +// printf("IIe keyboard read\n"); + return 0x06; + case 2: + printf("ADB data line input, etc\n"); + return 0xff; + case 3: +// printf("ADB data line output, etc\n"); + break; + + default: assert(false); + } + return 0xff; +} diff --git a/Machines/Apple/AppleIIgs/ADB.hpp b/Machines/Apple/AppleIIgs/ADB.hpp index 089bdbef8..6d255513c 100644 --- a/Machines/Apple/AppleIIgs/ADB.hpp +++ b/Machines/Apple/AppleIIgs/ADB.hpp @@ -17,8 +17,10 @@ namespace Apple { namespace IIgs { namespace ADB { -class GLU { +class GLU: public InstructionSet::M50740::PortHandler { public: + GLU(); + // Behaviour varies slightly between the controller shipped with ROM01 machines // and that shipped with ROM03 machines; use this to set the desired behaviour. void set_is_rom03(bool); @@ -59,6 +61,12 @@ class GLU { uint8_t read_microcontroller_address(uint16_t); InstructionSet::M50740::Executor executor_; + + void set_port_output(int port, uint8_t value) override; + uint8_t get_port_input(int port) override; + + uint8_t registers_[16]; + uint8_t register_address_; }; }