From 2a1d9bc8e4f40d3eb960d1e4e8c210683d7fa131 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 20 Mar 2026 16:41:03 -0400 Subject: [PATCH] Try: storage is in control register, but is not writeable. --- Components/6821/6821.hpp | 35 ++++++++++++++++++----------------- Processors/6809/6809.hpp | 5 ++++- Processors/6809/Registers.hpp | 3 +-- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/Components/6821/6821.hpp b/Components/6821/6821.hpp index d1d1a224a..f4a7f9fa5 100644 --- a/Components/6821/6821.hpp +++ b/Components/6821/6821.hpp @@ -36,7 +36,8 @@ public: static constexpr int port = bool(address & RS1Mask); if constexpr (address & RS0Mask) { - ports_[port].control = value; + static constexpr auto IRQMask = IRQ1 | IRQ2; + ports_[port].control = (ports_[port].control & IRQMask) | (value & ~IRQMask); } else { if(ports_[port].control & Flag::DataVisible) { ports_[port].data = value; @@ -56,18 +57,17 @@ public: uint8_t read() { static constexpr int port = (address >> 1) & 1; if constexpr(address & 1) { - return ports_[port].control; + const auto result = ports_[port].control; + ports_[port].clear_irq(); + update_interrupts(); + return result; } else { if(ports_[port].control & Flag::DataVisible) { - const uint8_t result = ports_[port].input(port_handler_.template input()); - ports_[port].clear_irq(); - update_interrupts(); - return result; + return ports_[port].input(port_handler_.template input()); } else { return ports_[port].direction; } } - return 0; } void refresh() const { @@ -99,7 +99,7 @@ public: // to interrupt output. static constexpr int direction = is_irq2 ? IRQ2Direction : IRQ1Direction; if(value != bool(ports_[port].control & direction)) { - ports_[port].template apply_irq(); + ports_[port].apply_irq(is_irq2 ? Flag::IRQ2 : Flag::IRQ1); update_interrupts(); } } @@ -126,21 +126,24 @@ private: uint8_t data = 0; uint8_t direction = 0; // Per bit: 0 = input; 1 = output. - template - void apply_irq() { + void apply_irq(const uint8_t mask) { control |= mask; - irq_ |= - (mask == IRQ1 && control & EnableIRQ1) || - (mask == IRQ2 && ((control & (EnableIRQ2 | C2IsOutput)) == EnableIRQ2)); } void clear_irq() { - irq_ = false; control &= ~(IRQ1 | IRQ2); } bool irq() const { - return irq_; + static constexpr auto IRQ1Value = EnableIRQ1 | IRQ1; + static constexpr auto IRQ1Mask = IRQ1Value; + + static constexpr auto IRQ2Value = EnableIRQ2 | IRQ2; + static constexpr auto IRQ2Mask = IRQ2Value | C2IsOutput; + + return + ((control & IRQ1Mask) == IRQ1Value) || + ((control & IRQ2Mask) == IRQ2Value); } mutable uint8_t previous_output = 0x00; @@ -150,8 +153,6 @@ private: uint8_t input(const uint8_t bus) const { return (data & direction) | (bus & ~direction); } - private: - bool irq_ = false; } ports_[2]; template diff --git a/Processors/6809/6809.hpp b/Processors/6809/6809.hpp index 262e074dc..e6846a92f 100644 --- a/Processors/6809/6809.hpp +++ b/Processors/6809/6809.hpp @@ -400,6 +400,9 @@ struct Processor { } if(exceptions_) { + // Avoid potential accidental detection of SWIs on the interrupt paths. + operation_.operation = Operation::None; + if(exceptions_ & Exception::Halt) { goto halt; } @@ -795,7 +798,7 @@ struct Processor { goto exception; nmi_irq: - internal_cycles(2); + internal_cycles(2); // TODO: is this when interrupts are acknowledged? goto exception; exception: diff --git a/Processors/6809/Registers.hpp b/Processors/6809/Registers.hpp index 644644cc4..dc7ae5ddd 100644 --- a/Processors/6809/Registers.hpp +++ b/Processors/6809/Registers.hpp @@ -347,6 +347,7 @@ struct IndexedAddressDecoder { } switch(suffix()) { using enum FormSuffix; + default: // For invalid suffixes. case NoOffset: return 0; case Offset8bit: return 1; @@ -366,8 +367,6 @@ struct IndexedAddressDecoder { case Offset16bitFromPC: return 4; case Extended: return 1; - - default:__builtin_unreachable(); } }