Try: storage is in control register, but is not writeable.

This commit is contained in:
Thomas Harte committed 2026-03-20 16:41:03 -04:00
1 parent 3913a2c9d3
commit 2a1d9bc8e4
3 files changed
+23 -20

No files matched your search

+18 -17
View File
@@ -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<Port(port)>());
ports_[port].clear_irq();
update_interrupts();
return result;
return ports_[port].input(port_handler_.template input<Port(port)>());
} 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<is_irq2 ? Flag::IRQ2 : Flag::IRQ1>();
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 <uint8_t mask>
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 <Port port>
+4 -1
View File
@@ -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:
+1 -2
View File
@@ -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();
}
}