diff --git a/Components/6526/Implementation/6526Implementation.hpp b/Components/6526/Implementation/6526Implementation.hpp index c1613e31a..3668fd367 100644 --- a/Components/6526/Implementation/6526Implementation.hpp +++ b/Components/6526/Implementation/6526Implementation.hpp @@ -29,6 +29,9 @@ template uint8_t MOS6526::get_port_input() template void MOS6526::posit_interrupt(uint8_t mask) { + if(!mask) { + return; + } interrupt_state_ |= mask; update_interrupts(); } @@ -36,7 +39,7 @@ void MOS6526::posit_interrupt(uint8_t mask) { template void MOS6526::update_interrupts() { if(interrupt_state_ & interrupt_control_) { - interrupt_state_ |= 0x80; + pending_ |= InterruptInOne; } } @@ -237,7 +240,13 @@ void MOS6526::run_for(const HalfCycles half_cycles) { int sub = half_divider_.divide_cycles().template as(); while(sub--) { - // TODO: use CNT potentially to clock timer A. + pending_ <<= 1; + if(pending_ & InterruptNow) { + interrupt_state_ |= 0x80; + } + pending_ &= PendingClearMask; + + // TODO: use CNT potentially to clock timer A, elimiante conditional above. counter_[0].advance(false); counter_[1].advance(counter_[0].hit_zero); posit_interrupt((counter_[0].hit_zero ? 0x01 : 0x00) | (counter_[1].hit_zero ? 0x02 : 0x00)); diff --git a/Components/6526/Implementation/6526Storage.hpp b/Components/6526/Implementation/6526Storage.hpp index cb3d41f9c..e954db88e 100644 --- a/Components/6526/Implementation/6526Storage.hpp +++ b/Components/6526/Implementation/6526Storage.hpp @@ -35,18 +35,15 @@ struct MOS6526Storage { template void set_reload(uint8_t v) { reload = (reload & (0xff00 >> shift)) | uint16_t(v << shift); -// if constexpr (shift == 8) { -// if(!(control&1)) { -// value = reload; -// } -// } + if constexpr (shift == 8) { + if(!(control&1)) { + pending |= ReloadInOne; + } + } } template void set_control(uint8_t v) { - control = v & 0xef; - if(v & 0x10) { - pending |= ReloadInTwo; - } + control = v; } void advance(bool chained_input) { @@ -54,8 +51,9 @@ struct MOS6526Storage { pending <<= 1; - if(hit_zero && pending&(OneShotInOne | OneShotNow)) { - control &= ~1; + if(control & 0x10) { + pending |= ReloadInTwo; + control &= ~0x10; } if((control & 0x01) || chained_input) { @@ -67,7 +65,7 @@ struct MOS6526Storage { if((pending & ReloadNow) || (hit_zero && (pending & ApplyClockInTwo))) { value = reload; - pending &= ~ApplyClockInTwo; + pending &= ~ApplyClockInOne; } pending &= PendingClearMask; @@ -78,6 +76,10 @@ struct MOS6526Storage { } else { hit_zero = false; } + + if(hit_zero && pending&(OneShotInOne | OneShotNow)) { + control &= ~1; + } } private: @@ -96,10 +98,15 @@ struct MOS6526Storage { static constexpr int ApplyClockInOne = 1 << 8; static constexpr int ApplyClockNow = 1 << 9; - static constexpr int PendingClearMask = ~(ReloadNow | OneShotNow); + static constexpr int PendingClearMask = ~(ReloadNow | OneShotNow | ApplyClockNow); bool active_ = false; } counter_[2]; + + static constexpr int InterruptInOne = 1 << 0; + static constexpr int InterruptNow = 1 << 1; + static constexpr int PendingClearMask = ~(InterruptNow); + int pending_ = 0; }; }