35 { 0xf, 0x7, 0xf, 0x7, 0xf, 0x3, 0x7, 0xf, 0x3, 0xf, 0x1, 0xf, 0xf},
36 { 0x0, 0x0, 0xf, 0x7, 0xf, 0x3, 0x7, 0xf, 0x3, 0x0, 0x1, 0x3, 0x0},
37 { 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf},
38 { 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf}
42 EmuTime::param time,
const std::string& name)
46 ((name ==
"Real time clock") ? std::string_view(
"rtcmode")
48 "Real Time Clock mode",
RP5C01::EMUTIME,
58 void RP5C01::reset(EmuTime::param time)
80 return peekPort(port);
95 nibble tmp = regs[block * 13 + port];
96 return tmp &
mask[block][port];
102 assert (port <= 0x0f);
105 updateTimeRegs(time);
109 updateTimeRegs(time);
124 updateTimeRegs(time);
126 regs.write(block * 13 + port, value &
mask[block][port]);
133 void RP5C01::initializeTime()
135 time_t
t = time(
nullptr);
136 struct tm *tm = localtime(&
t);
138 seconds = tm->tm_sec;
139 minutes = tm->tm_min;
141 dayWeek = tm->tm_wday;
142 days = tm->tm_mday-1;
144 years = tm->tm_year - 80;
145 leapYear = tm->tm_year % 4;
149 void RP5C01::regs2Time()
162 if (hours >= 20) hours = (hours - 20) + 12;
166 void RP5C01::time2Regs()
168 unsigned hours_ = hours;
171 if (hours >= 12) hours_ = (hours - 12) + 20;
174 regs.write(
TIME_BLOCK * 13 + 0, seconds % 10);
175 regs.write(
TIME_BLOCK * 13 + 1, seconds / 10);
176 regs.write(
TIME_BLOCK * 13 + 2, minutes % 10);
177 regs.write(
TIME_BLOCK * 13 + 3, minutes / 10);
190 static constexpr
int daysInMonth(
int month,
unsigned leapYear)
192 constexpr uint8_t daysInMonths[12] = {
193 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
197 return ((month == 1) && (leapYear == 0)) ? 29 : daysInMonths[month];
200 void RP5C01::updateTimeRegs(EmuTime::param time)
202 if (modeSetting.getEnum() == EMUTIME) {
204 auto elapsed = unsigned(reference.getTicksTill(time));
205 reference.advance(time);
210 ? elapsed : fraction / FREQ;
211 seconds += carrySeconds;
213 ? elapsed : seconds / 60;
214 minutes += carryMinutes;
215 hours += minutes / 60;
216 unsigned carryDays = (testReg &
TEST_DAYS)
217 ? elapsed : hours / 24;
230 dayWeek += carryDays;
231 while (
days >= daysInMonth(
months, leapYear)) {
240 ? elapsed :
unsigned(
months / 12);
242 leapYear += carryYears;
261 void RP5C01::resetAlarm()
263 for (
auto i :
xrange(2, 9)) {
268 template<
typename Archive>
271 ar.serialize(
"reference", reference,
272 "fraction", fraction,
278 "leapYear", leapYear,
283 "resetReg", resetReg);
RP5C01(CommandController &commandController, SRAM ®s, EmuTime::param time, const std::string &name)
const char *const months[12]
const char *const days[7]
This file implemented 3 utility functions:
constexpr nibble TIME_BLOCK
constexpr nibble MODE_TIMERENABLE
uint8_t nibble
4 bit integer
constexpr nibble MODE_REG
constexpr nibble MODE_BLOKSELECT
constexpr nibble RESET_ALARM
constexpr nibble TEST_DAYS
constexpr nibble MODE_ALARMENABLE
constexpr nibble TEST_YEARS
constexpr nibble RESET_REG
constexpr nibble TEST_REG
void serialize(Archive &ar, T &t, unsigned version)
constexpr nibble ALARM_BLOCK
constexpr nibble mask[4][13]
constexpr nibble RESET_FRACTION
constexpr nibble TEST_MINUTES
constexpr nibble TEST_SECONDS
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
TemporaryString tmpStrCat(Ts &&... ts)
constexpr auto xrange(T e)