1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-29 12:50:28 +00:00

Merge pull request #1286 from TomHarte/CMOSRAM

Adds RAM to the PC RTC.
This commit is contained in:
Thomas Harte 2023-12-25 15:06:28 -05:00 committed by GitHub
commit 35f000f93c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -35,6 +35,9 @@ class RTC {
switch(selected_) { switch(selected_) {
default: default:
if(ram_selected()) {
return ram_[ram_address()];
}
return 0xff; return 0xff;
case 0x00: return bcd(time_date->tm_sec); // Seconds [0-59] case 0x00: return bcd(time_date->tm_sec); // Seconds [0-59]
@ -57,20 +60,38 @@ class RTC {
case 0x09: return bcd(time_date->tm_year % 100); // Year [0-99] case 0x09: return bcd(time_date->tm_year % 100); // Year [0-99]
case 0x32: return bcd(19 + time_date->tm_year / 100); // Century case 0x32: return bcd(19 + time_date->tm_year / 100); // Century
case 0x0a: return statusA_; case 0x0a: return statusA_ & 0x7f; // Exclude the update-in-progress bit.
case 0x0b: return statusB_; case 0x0b: return statusB_;
} }
} }
private: private:
int selected_; std::size_t selected_;
std::array<uint8_t, 50> ram_{};
uint8_t statusA_ = 0x00; uint8_t statusA_ = 0x00;
uint8_t statusB_ = 0x02; uint8_t statusB_ = 0x02;
// Status A.
// b7: update-in-progress.
// b6b4: selects condition of the divider chain (?);
// b3b0: selects rate of the divider chain.
// Status B.
bool disable_updates() const { return statusB_ & 0x80; }
bool periodic_interrupt_enabled() const { return statusB_ & 0x40; }
bool alarm_interrupt_enabled() const { return statusB_ & 0x20; }
bool update_ended_interrupt_enabled() const { return statusB_ & 0x10; }
bool square_wave_enabled() const { return statusB_ & 0x08; }
bool is_decimal() const { return statusB_ & 0x04; } bool is_decimal() const { return statusB_ & 0x04; }
bool is_24hour() const { return statusB_ & 0x02; } bool is_24hour() const { return statusB_ & 0x02; }
bool daylight_savings_enabled() const { return statusB_ & 0x01; }
// Helpers for differentiating RAM accesses from the more meaningful registers.
bool ram_selected() const { return selected_ >= 0xe && selected_ < 0xe + ram_.size(); }
std::size_t ram_address() const { return selected_ - 0xe; }
/// Converts @c input to BCD if BCD mode is enabled; otherwise returns @c input unaltered.
template <typename IntT> template <typename IntT>
uint8_t bcd(IntT input) { uint8_t bcd(IntT input) {
// If calendar is in binary format, don't convert. // If calendar is in binary format, don't convert.
@ -85,9 +106,14 @@ class RTC {
); );
} }
/// Writes @c value to the register @c selected_ .
void write_register(uint8_t value) { void write_register(uint8_t value) {
switch(selected_) { switch(selected_) {
default: break; default:
if(ram_selected()) {
ram_[ram_address()] = value;
}
break;
case 0x0a: statusA_ = value; break; case 0x0a: statusA_ = value; break;
case 0x0b: statusB_ = value; break; case 0x0b: statusB_ = value; break;
} }