n64: add rtc.cpp and implement rtc timestamp

このコミットが含まれているのは:
LuigiBlood 2022-09-02 14:04:54 +02:00 committed by Luke Usher
コミット c46beaff32
4個のファイルの変更72行の追加8行の削除

ファイルの表示

@ -4,6 +4,7 @@ namespace ares::Nintendo64 {
DD dd;
#include "controller.cpp"
#include "rtc.cpp"
#include "io.cpp"
#include "debugger.cpp"
#include "serialization.cpp"
@ -23,7 +24,7 @@ auto DD::load(Node::Object parent) -> void {
c2s.allocate(0x400);
ds.allocate(0x100);
ms.allocate(0x40);
rtc.allocate(0x8);
rtc.allocate(0x10);
// TODO: Detect correct CIC from ipl rom
if(auto fp = system.pak->read("64dd.ipl.rom")) {
@ -60,9 +61,7 @@ auto DD::connect() -> void {
fd = pak->read("program.disk");
if(!fd) return disconnect();
if(auto fp = system.pak->read("time.rtc")) {
rtc.load(fp);
}
rtcLoad();
}
auto DD::disconnect() -> void {
@ -73,9 +72,7 @@ auto DD::disconnect() -> void {
}
auto DD::save() -> void {
if(auto fp = system.pak->write("time.rtc")) {
rtc.save(fp);
}
rtcSave();
}
auto DD::power(bool reset) -> void {

ファイルの表示

@ -46,6 +46,12 @@ struct DD : Memory::IO<DD> {
//controller.cpp
auto command(n16 command) -> void;
//rtc.cpp
auto rtcLoad() -> void;
auto rtcSave() -> void;
auto rtcTick(u32 offset) -> void;
auto rtcTickSecond() -> void;
//io.cpp
auto readWord(u32 address) -> u32;
auto writeWord(u32 address, u32 data) -> void;

61
ares/n64/dd/rtc.cpp ノーマルファイル
ファイルの表示

@ -0,0 +1,61 @@
auto DD::rtcLoad() -> void {
if(auto fp = system.pak->read("time.rtc")) {
rtc.load(fp);
}
n64 timestamp = 0;
for(auto n : range(8)) timestamp.byte(n) = rtc.read<Byte>(8 + n);
if(!~timestamp) return; //new save file
timestamp = time(0) - timestamp;
while(timestamp--) rtcTickSecond();
}
auto DD::rtcSave() -> void {
n64 timestamp = time(0);
for(auto n : range(8)) rtc.write<Byte>(8 + n, timestamp.byte(n));
if(auto fp = system.pak->write("time.rtc")) {
rtc.save(fp);
}
}
auto DD::rtcTick(u32 offset) -> void {
u8 n = rtc.read<Byte>(offset);
if((++n & 0xf) > 9) n = (n & 0xf0) + 0x10;
if((n & 0xf0) > 0x90) n = 0;
rtc.write<Byte>(offset, n);
}
auto DD::rtcTickSecond() -> void {
//second
rtcTick(5);
if(rtc.read<Byte>(5) < 0x60) return;
rtc.write<Byte>(5, 0);
//minute
rtcTick(4);
if(rtc.read<Byte>(4) < 0x60) return;
rtc.write<Byte>(4, 0);
//hour
rtcTick(3);
if(rtc.read<Byte>(3) < 0x24) return;
rtc.write<Byte>(3, 0);
//day
u32 daysInMonth[12] = {0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31};
if(rtc.read<Byte>(0) && !(BCD::decode(rtc.read<Byte>(0)) % 4)) daysInMonth[1]++;
rtcTick(2);
if(rtc.read<Byte>(2) <= daysInMonth[BCD::decode(rtc.read<Byte>(1))-1]) return;
rtc.write<Byte>(2, 1);
//month
rtcTick(1);
if(rtc.read<Byte>(1) < 0x12) return;
rtc.write<Byte>(1, 1);
//year
rtcTick(0);
}

ファイルの表示

@ -14,7 +14,7 @@ auto Nintendo64DD::load(string location) -> bool {
pak->append("pif.pal.rom", Resource::Nintendo64::PIFPAL );
pak->append("pif.sm5.rom", Resource::Nintendo64::PIFSM5 );
pak->append("64dd.ipl.rom", bios);
pak->append("time.rtc", 0x8);
pak->append("time.rtc", 0x10);
if(auto fp = pak->write("time.rtc")) {
for(auto address : range(fp->size())) fp->write(0xff);