mirror of
https://github.com/ares-emulator/ares.git
synced 2026-10-11 22:39:55 +00:00
Align semantic of all RTC implementations:
* Initialize using the PC localtime * Handle backward time warp by ignoring it
This commit is contained in:
committed by
Luke Usher
parent
dee49f55ae
commit
af4cbb04f0
@@ -10,7 +10,21 @@ namespace ares {
|
||||
auto S3511A::load() -> void {
|
||||
n64 timestamp = 0;
|
||||
for(auto n : range(8)) timestamp.byte(n) = data[8 + n];
|
||||
if(!timestamp || !(timestamp + 1)) return initRegs(false); //new save file
|
||||
if(!timestamp || !(timestamp + 1)) { //new save file
|
||||
time_t t = time(0);
|
||||
struct tm tmm = *localtime(&t);
|
||||
year() = BCD::encode(tmm.tm_year % 100);
|
||||
month() = BCD::encode(tmm.tm_mon + 1);
|
||||
day() = BCD::encode(tmm.tm_mday);
|
||||
weekday() = tmm.tm_wday;
|
||||
hour() = BCD::encode(tmm.tm_hour);
|
||||
minute() = BCD::encode(tmm.tm_min);
|
||||
second() = BCD::encode(tmm.tm_sec);
|
||||
status() = 0x82;
|
||||
alarmHour() = 0x00;
|
||||
alarmMinute() = 0x80;
|
||||
return;
|
||||
}
|
||||
|
||||
if(status() & 0x15) {
|
||||
//these status bits are always 0; reset state on invalid status.
|
||||
@@ -18,9 +32,10 @@ auto S3511A::load() -> void {
|
||||
return;
|
||||
}
|
||||
|
||||
timestamp = time(0) - timestamp;
|
||||
//prevent insurmountable slowdown by limiting skips to 5 years
|
||||
if(timestamp < 60*60*24*365*5) {
|
||||
time_t now = time(0);
|
||||
time_t saved = (time_t)timestamp;
|
||||
if(now > saved) {
|
||||
timestamp = now - saved;
|
||||
while(timestamp--) tickSecond();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,13 +26,25 @@ struct MBC3 : Interface {
|
||||
for(u32 index : range(8)) {
|
||||
timestamp.byte(index) = rtc[5 + index];
|
||||
}
|
||||
n64 diff = chrono::timestamp() - timestamp;
|
||||
if(diff < 32 * 365 * 24 * 60 * 60) {
|
||||
while(diff >= 24 * 60 * 60) { tickDay(); diff -= 24 * 60 * 60; }
|
||||
while(diff >= 60 * 60) { tickHour(); diff -= 60 * 60; }
|
||||
while(diff >= 60) { tickMinute(); diff -= 60; }
|
||||
while(diff) { tickSecond(); diff -= 1; }
|
||||
if(!timestamp || !(timestamp + 1)) {
|
||||
time_t t = time(0);
|
||||
struct tm tmm = *localtime(&t);
|
||||
io.rtc.second = tmm.tm_sec;
|
||||
io.rtc.minute = tmm.tm_min;
|
||||
io.rtc.hour = tmm.tm_hour;
|
||||
io.rtc.day = (n9)((t / 86400) % 512);
|
||||
io.rtc.halt = 0;
|
||||
io.rtc.dayCarry = 0;
|
||||
return;
|
||||
}
|
||||
time_t now = chrono::timestamp();
|
||||
time_t saved = (time_t)timestamp;
|
||||
if(now <= saved) return;
|
||||
n64 diff = now - saved;
|
||||
while(diff >= 24 * 60 * 60) { tickDay(); diff -= 24 * 60 * 60; }
|
||||
while(diff >= 60 * 60) { tickHour(); diff -= 60 * 60; }
|
||||
while(diff >= 60) { tickMinute(); diff -= 60; }
|
||||
while(diff) { tickSecond(); diff -= 1; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,13 +33,26 @@ struct TAMA : Interface {
|
||||
for(u32 index : range(8)) {
|
||||
timestamp.byte(index) = rtc[7 + index];
|
||||
}
|
||||
n64 diff = chrono::timestamp() - timestamp;
|
||||
if(diff < 32 * 365 * 24 * 60 * 60) {
|
||||
while(diff >= 24 * 60 * 60) { tickDay(); diff -= 24 * 60 * 60; }
|
||||
while(diff >= 60 * 60) { tickHour(); diff -= 60 * 60; }
|
||||
while(diff >= 60) { tickMinute(); diff -= 60; }
|
||||
while(diff) { tickSecond(); diff -= 1; }
|
||||
if(!timestamp || !(timestamp + 1)) {
|
||||
time_t t = time(0);
|
||||
struct tm tmm = *localtime(&t);
|
||||
io.rtc.year = tmm.tm_year % 100;
|
||||
io.rtc.month = tmm.tm_mon + 1;
|
||||
io.rtc.day = tmm.tm_mday;
|
||||
io.rtc.hour = tmm.tm_hour;
|
||||
io.rtc.minute = tmm.tm_min;
|
||||
io.rtc.second = tmm.tm_sec;
|
||||
io.rtc.meridian = tmm.tm_hour >= 12;
|
||||
return;
|
||||
}
|
||||
time_t now = chrono::timestamp();
|
||||
time_t saved = (time_t)timestamp;
|
||||
if(now <= saved) return;
|
||||
n64 diff = now - saved;
|
||||
while(diff >= 24 * 60 * 60) { tickDay(); diff -= 24 * 60 * 60; }
|
||||
while(diff >= 60 * 60) { tickHour(); diff -= 60 * 60; }
|
||||
while(diff >= 60) { tickMinute(); diff -= 60; }
|
||||
while(diff) { tickSecond(); diff -= 1; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
-8
@@ -7,7 +7,20 @@ auto DD::RTC::load() -> void {
|
||||
//byte 0 to 7 = raw rtc time (last updated, only 6 bytes are used)
|
||||
n64 check = 0;
|
||||
for(auto n : range(8)) check.byte(n) = ram.read<Byte>(n);
|
||||
if(!~check) return; //new save file
|
||||
//byte 8 to 15 = timestamp of when the last save was made
|
||||
n64 timestamp = 0;
|
||||
for(auto n : range(8)) timestamp.byte(n) = ram.read<Byte>(8 + n);
|
||||
if(!~check || !~timestamp) { //new save file
|
||||
time_t t = time(0);
|
||||
struct tm tmm = *localtime(&t);
|
||||
ram.write<Byte>(0, BCD::encode(tmm.tm_year % 100));
|
||||
ram.write<Byte>(1, BCD::encode(tmm.tm_mon + 1));
|
||||
ram.write<Byte>(2, BCD::encode(tmm.tm_mday));
|
||||
ram.write<Byte>(3, BCD::encode(tmm.tm_hour));
|
||||
ram.write<Byte>(4, BCD::encode(tmm.tm_min));
|
||||
ram.write<Byte>(5, BCD::encode(tmm.tm_sec));
|
||||
return;
|
||||
}
|
||||
|
||||
//check for invalid time info, if invalid, set time info to something invalid and ignore the rest
|
||||
if (!valid()) {
|
||||
@@ -15,14 +28,13 @@ auto DD::RTC::load() -> void {
|
||||
return;
|
||||
}
|
||||
|
||||
//byte 8 to 15 = timestamp of when the last save was made
|
||||
n64 timestamp = 0;
|
||||
for(auto n : range(8)) timestamp.byte(n) = ram.read<Byte>(8 + n);
|
||||
if(!~timestamp) return; //new save file
|
||||
|
||||
//update based on the amount of time that has passed since the last save
|
||||
timestamp = time(0) - timestamp;
|
||||
while(timestamp--) tickSecond();
|
||||
time_t now = time(0);
|
||||
time_t saved = (time_t)timestamp;
|
||||
if(now > saved) {
|
||||
timestamp = now - saved;
|
||||
while(timestamp--) tickSecond();
|
||||
}
|
||||
}
|
||||
|
||||
auto DD::RTC::reset() -> void {
|
||||
|
||||
@@ -155,7 +155,16 @@ auto EpsonRTC::load(const n8* data) -> void {
|
||||
timestamp |= (n64)(data[8 + byte]) << (byte * 8);
|
||||
}
|
||||
|
||||
n64 diff = (n64)time(0) - timestamp;
|
||||
if(!timestamp || !(timestamp + 1)) {
|
||||
synchronize(time(0));
|
||||
return;
|
||||
}
|
||||
|
||||
time_t now = time(0);
|
||||
time_t saved = (time_t)timestamp;
|
||||
if(now <= saved) return;
|
||||
|
||||
n64 diff = now - saved;
|
||||
while(diff >= 60 * 60 * 24) { tickDay(); diff -= 60 * 60 * 24; }
|
||||
while(diff >= 60 * 60) { tickHour(); diff -= 60 * 60; }
|
||||
while(diff >= 60) { tickMinute(); diff -= 60; }
|
||||
|
||||
@@ -46,7 +46,16 @@ auto SharpRTC::load(const n8* data) -> void {
|
||||
timestamp |= (n64)(data[8 + byte]) << (byte * 8);
|
||||
}
|
||||
|
||||
n64 diff = (n64)time(0) - timestamp;
|
||||
if(!timestamp || !(timestamp + 1)) {
|
||||
synchronize(time(0));
|
||||
return;
|
||||
}
|
||||
|
||||
time_t now = time(0);
|
||||
time_t saved = (time_t)timestamp;
|
||||
if(now <= saved) return;
|
||||
|
||||
n64 diff = now - saved;
|
||||
while(diff >= 60 * 60 * 24) { tickDay(); diff -= 60 * 60 * 24; }
|
||||
while(diff >= 60 * 60) { tickHour(); diff -= 60 * 60; }
|
||||
while(diff >= 60) { tickMinute(); diff -= 60; }
|
||||
|
||||
@@ -3,7 +3,21 @@
|
||||
auto Cartridge::RTC::load() -> void {
|
||||
n64 timestamp = 0;
|
||||
for(auto n : range(8)) timestamp.byte(n) = ram.read(8 + n);
|
||||
if(!timestamp || !(timestamp + 1)) return; //new save file
|
||||
if(!timestamp || !(timestamp + 1)) { //new save file
|
||||
time_t t = time(0);
|
||||
struct tm tmm = *localtime(&t);
|
||||
year() = BCD::encode(tmm.tm_year % 100);
|
||||
month() = BCD::encode(tmm.tm_mon + 1);
|
||||
day() = BCD::encode(tmm.tm_mday);
|
||||
weekday() = tmm.tm_wday;
|
||||
hour() = BCD::encode(tmm.tm_hour);
|
||||
minute() = BCD::encode(tmm.tm_min);
|
||||
second() = BCD::encode(tmm.tm_sec);
|
||||
status() = 0x82;
|
||||
alarmHour() = 0x00;
|
||||
alarmMinute() = 0x80;
|
||||
return;
|
||||
}
|
||||
|
||||
if(status() & 0x15) {
|
||||
// These status bits are always 0; reset state on invalid status.
|
||||
@@ -11,9 +25,10 @@ auto Cartridge::RTC::load() -> void {
|
||||
return;
|
||||
}
|
||||
|
||||
timestamp = time(0) - timestamp;
|
||||
// prevent insurmountable slowdown by limiting skips to 5 years
|
||||
if(timestamp < 60*60*24*365*5) {
|
||||
time_t now = time(0);
|
||||
time_t saved = (time_t)timestamp;
|
||||
if(now > saved) {
|
||||
timestamp = now - saved;
|
||||
while(timestamp--) tickSecond();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user