1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Splits TOD storage by model.

TOD storage will probably end up being a full-on class.
This commit is contained in:
Thomas Harte 2021-08-03 18:50:58 -04:00
parent 34c1cc5693
commit 0245b040b0
3 changed files with 33 additions and 26 deletions

View File

@ -62,6 +62,7 @@ template <typename PortHandlerT, Personality personality> class MOS6526:
private:
PortHandlerT &port_handler_;
TODStorage<personality == Personality::P8250> tod_;
template <int port> void set_port_output();
template <int port> uint8_t get_port_input();

View File

@ -85,10 +85,10 @@ void MOS6526<BusHandlerT, personality>::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<BusHandlerT, personality>::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<BusHandlerT, personality>::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<BusHandlerT, personality>::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<BusHandlerT, personality>::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<BusHandlerT, personality>::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<BusHandlerT, personality>::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 {

View File

@ -12,6 +12,17 @@
namespace MOS {
namespace MOS6526 {
template <bool is_8250> struct TODStorage {};
template <> struct TODStorage<false> {
// TODO.
};
template <> struct TODStorage<true> {
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;