diff --git a/Components/6526/6526.hpp b/Components/6526/6526.hpp index 7366565a5..6d5fc1b5d 100644 --- a/Components/6526/6526.hpp +++ b/Components/6526/6526.hpp @@ -62,6 +62,7 @@ template class MOS6526: private: PortHandlerT &port_handler_; + TODStorage tod_; template void set_port_output(); template uint8_t get_port_input(); diff --git a/Components/6526/Implementation/6526Implementation.hpp b/Components/6526/Implementation/6526Implementation.hpp index 0c35d24de..0bd776db4 100644 --- a/Components/6526/Implementation/6526Implementation.hpp +++ b/Components/6526/Implementation/6526Implementation.hpp @@ -85,10 +85,10 @@ void MOS6526::write(int address, uint8_t value) { case 8: if constexpr (personality == Personality::P8250) { if(counter_[1].control & 0x80) { - tod_alarm_ = (tod_alarm_ & 0xffff00) | uint32_t(value); + tod_.alarm = (tod_.alarm & 0xffff00) | uint32_t(value); } else { - tod_ = (tod_ & 0xffff00) | uint32_t(value); - tod_increment_mask_ = uint32_t(~0); + tod_.value = (tod_.value & 0xffff00) | uint32_t(value); + tod_.increment_mask = uint32_t(~0); } } else { printf("6526 TOD clock not implemented\n"); @@ -98,10 +98,10 @@ void MOS6526::write(int address, uint8_t value) { case 9: if constexpr (personality == Personality::P8250) { if(counter_[1].control & 0x80) { - tod_alarm_ = (tod_alarm_ & 0xff00ff) | uint32_t(value << 8); + tod_.alarm = (tod_.alarm & 0xff00ff) | uint32_t(value << 8); } else { - tod_ = (tod_ & 0xff00ff) | uint32_t(value << 8); - tod_increment_mask_ = 0; + tod_.value = (tod_.value & 0xff00ff) | uint32_t(value << 8); + tod_.increment_mask = 0; } } else { printf("6526 TOD clock not implemented\n"); @@ -111,10 +111,10 @@ void MOS6526::write(int address, uint8_t value) { case 10: if constexpr (personality == Personality::P8250) { if(counter_[1].control & 0x80) { - tod_alarm_ = (tod_alarm_ & 0x00ffff) | uint32_t(value << 16); + tod_.alarm = (tod_.alarm & 0x00ffff) | uint32_t(value << 16); } else { - tod_ = (tod_ & 0x00ffff) | uint32_t(value << 16); - tod_increment_mask_ = 0; + tod_.value = (tod_.value & 0x00ffff) | uint32_t(value << 16); + tod_.increment_mask = 0; } } else { printf("6526 TOD clock not implemented\n"); @@ -183,12 +183,12 @@ uint8_t MOS6526::read(int address) { // 8250: Latch on MSB. Unlatch on LSB. Read raw if not latched. case 8: if constexpr (personality == Personality::P8250) { - if(tod_latch_) { - const uint8_t result = tod_latch_ & 0xff; - tod_latch_ = 0; + if(tod_.latch) { + const uint8_t result = tod_.latch & 0xff; + tod_.latch = 0; return result; } else { - return tod_ & 0xff; + return tod_.value & 0xff; } } else { printf("6526 TOD clock not implemented\n"); @@ -197,10 +197,10 @@ uint8_t MOS6526::read(int address) { break; case 9: if constexpr (personality == Personality::P8250) { - if(tod_latch_) { - return (tod_latch_ >> 8) & 0xff; + if(tod_.latch) { + return (tod_.latch >> 8) & 0xff; } else { - return (tod_ >> 8) & 0xff; + return (tod_.value >> 8) & 0xff; } } else { printf("6526 TOD clock not implemented\n"); @@ -209,8 +209,8 @@ uint8_t MOS6526::read(int address) { break; case 10: if constexpr (personality == Personality::P8250) { - tod_latch_ = tod_ | 0xff00'0000; - return (tod_ >> 16) & 0xff; + tod_.latch = tod_.value | 0xff00'0000; + return (tod_.value >> 16) & 0xff; } else { printf("6526 TOD clock not implemented\n"); assert(false); @@ -263,9 +263,9 @@ void MOS6526::advance_tod(int count) { if constexpr(personality == Personality::P8250) { // The 8250 uses a simple binary counter to replace the // 6526's time-of-day clock. So this is easy. - const uint32_t distance_to_alarm_ = (tod_alarm_ - tod_) & 0xffffff; - tod_ += uint32_t(count) & tod_increment_mask_; - if(distance_to_alarm_ <= uint32_t(count)) { + const uint32_t distance_to_alarm = (tod_.alarm - tod_.value) & 0xffffff; + tod_.value += uint32_t(count) & tod_.increment_mask; + if(distance_to_alarm <= uint32_t(count)) { posit_interrupt(0x04); } } else { diff --git a/Components/6526/Implementation/6526Storage.hpp b/Components/6526/Implementation/6526Storage.hpp index 6386d76ac..5e7f5c596 100644 --- a/Components/6526/Implementation/6526Storage.hpp +++ b/Components/6526/Implementation/6526Storage.hpp @@ -12,6 +12,17 @@ namespace MOS { namespace MOS6526 { +template struct TODStorage {}; +template <> struct TODStorage { + // TODO. +}; +template <> struct TODStorage { + uint32_t increment_mask = uint32_t(~0); + uint32_t latch = 0; + uint32_t value = 0; + uint32_t alarm = 0; +}; + struct MOS6526Storage { HalfCycles half_divider_; @@ -21,11 +32,6 @@ struct MOS6526Storage { uint8_t interrupt_control_ = 0; uint8_t interrupt_state_ = 0; - uint32_t tod_increment_mask_ = uint32_t(~0); - uint32_t tod_latch_ = 0; - uint32_t tod_ = 0; - uint32_t tod_alarm_ = 0; - struct Counter { uint16_t reload = 0; uint16_t value = 0;