mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-09 20:25:19 +00:00
Does just a touch of 6526 TOD work.
This commit is contained in:
@@ -9,6 +9,8 @@
|
|||||||
#ifndef _526Storage_h
|
#ifndef _526Storage_h
|
||||||
#define _526Storage_h
|
#define _526Storage_h
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
namespace MOS {
|
namespace MOS {
|
||||||
namespace MOS6526 {
|
namespace MOS6526 {
|
||||||
|
|
||||||
@@ -27,25 +29,95 @@ class TODBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <bool is_8250> class TODStorage {};
|
template <bool is_8250> class TODStorage {};
|
||||||
template <> class TODStorage<false>: public TODBase {
|
|
||||||
public:
|
|
||||||
// TODO.
|
|
||||||
|
|
||||||
template <int byte> void write(uint8_t) {
|
template <> class TODStorage<false>: public TODBase {
|
||||||
printf("6526 TOD clock not implemented\n");
|
private:
|
||||||
|
bool increment_ = true, latched_ = false;
|
||||||
|
int divider_ = 0;
|
||||||
|
std::array<uint8_t, 4> value_;
|
||||||
|
std::array<uint8_t, 4> latch_;
|
||||||
|
std::array<uint8_t, 4> alarm_;
|
||||||
|
|
||||||
|
static constexpr uint8_t masks[4] = {0xf, 0x3f, 0x3f, 0x1f};
|
||||||
|
|
||||||
|
void bcd_increment(uint8_t &value) {
|
||||||
|
++value;
|
||||||
|
if((value&0x0f) > 0x09) value += 0x06;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <int byte> void write(uint8_t v) {
|
||||||
|
if(write_alarm) {
|
||||||
|
alarm_[byte] = v & masks[byte];
|
||||||
|
} else {
|
||||||
|
value_[byte] = v & masks[byte];
|
||||||
|
|
||||||
|
if constexpr (byte == 0) {
|
||||||
|
increment_ = true;
|
||||||
|
}
|
||||||
|
if constexpr (byte == 3) {
|
||||||
|
increment_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int byte> uint8_t read() {
|
template <int byte> uint8_t read() {
|
||||||
printf("6526 TOD clock not implemented\n");
|
if(latched_) {
|
||||||
assert(false);
|
const uint8_t result = latch_[byte];
|
||||||
|
if constexpr (byte == 0) {
|
||||||
|
latched_ = false;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool advance(int) {
|
if constexpr (byte == 3) {
|
||||||
printf("6526 TOD clock not implemented\n");
|
latched_ = true;
|
||||||
assert(false);
|
latch_ = value_;
|
||||||
|
}
|
||||||
|
return value_[byte];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool advance(int count) {
|
||||||
|
if(!increment_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(count--) {
|
||||||
|
// Increment the pre-10ths divider.
|
||||||
|
++divider_;
|
||||||
|
if(divider_ < 5) continue;
|
||||||
|
if(divider_ < 6 && !is_50Hz) continue;
|
||||||
|
divider_ = 0;
|
||||||
|
|
||||||
|
// Increments 10ths of a second. One BCD digit.
|
||||||
|
++value_[0];
|
||||||
|
if(value_[0] < 10) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment seconds. Actual BCD needed from here onwards.
|
||||||
|
bcd_increment(value_[1]);
|
||||||
|
if(value_[1] != 60) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
value_[1] = 0;
|
||||||
|
|
||||||
|
// Increment minutes.
|
||||||
|
bcd_increment(value_[2]);
|
||||||
|
if(value_[2] != 60) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
value_[2] = 0;
|
||||||
|
|
||||||
|
// TODO: increment hours, keeping AM/PM separate?
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // TODO: test against alarm.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> class TODStorage<true>: public TODBase {
|
template <> class TODStorage<true>: public TODBase {
|
||||||
private:
|
private:
|
||||||
uint32_t increment_mask_ = uint32_t(~0);
|
uint32_t increment_mask_ = uint32_t(~0);
|
||||||
|
Reference in New Issue
Block a user