Last active
May 12, 2020 20:34
-
-
Save TuxSH/5ab04ac60254dafefbb4f4c4831180f6 to your computer and use it in GitHub Desktop.
3DS time management
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void ModeControlManager::RecaculateSharedTimeOnWakeup(void) | |
{ | |
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND] | |
TimeDateUpdater::RecalculateSharedTime(g_p_timeDateUpdater); | |
sub_1026A4(off_10E484, v0, v1, v2); // TODO, has to do with sleep/wakeup and another singleton | |
// | |
} | |
void __fastcall sub_102868(TimeDateUpdater *this) | |
{ | |
s64 sharedTime; // [sp+0h] [bp-30h] | |
s64 result; // [sp+8h] [bp-28h] | |
s64 ms; // [sp+10h] [bp-20h] | |
s64 msSinceY2k; // [sp+18h] [bp-18h] | |
s64 systemTick; // [sp+20h] [bp-10h] | |
systemTick = 0LL; | |
msSinceY2k = 0LL; | |
TimeDateUpdater::GetRtcTimeMsSinceY2k(this, &msSinceY2k, &systemTick); | |
cfgGetUserTimeOffset(&ms); | |
this->userTimeOffset = ms; | |
ms = msSinceY2k; | |
AddTimeOffsetMsWithNs(&result, &ms, &this->userTimeOffset); | |
ParseSharedTimeGetNsSinceY2k(&sharedTime); | |
if ( MsToGregorianYearY2k(&sharedTime) == 2000 && MsToGregorianYearY2k(&result) == 2099 ) | |
ChangeYearInTimestampY2k(&ms, &sharedTime, 2100);// dead code? | |
if ( result >= sharedTime ) | |
TimeDateUpdater::ResetSharedDateTimeWithRtc(g_p_timeDateUpdater);// why use another pointer that points to &*this????? | |
else | |
TimeDateUpdater::UpdateSharedDateTime(g_p_timeDateUpdater); | |
} | |
void __fastcall ParseSharedTimeGetNsSinceY2k(s64 *timestamp1900Ns) | |
{ | |
s64 *v1; // r4 | |
s64 v2; // r0 | |
s64 v3; // [sp+0h] [bp-18h] | |
s64 ns; // [sp+8h] [bp-10h] | |
v1 = timestamp1900Ns; | |
v2 = ParseSharedTimeSince1900(); | |
MsToNs(&ns, v2); | |
v3 = ns; | |
AddTimeOffsetMsWithNs(v1, &g_timestampOf1900SinceY2K, &v3); | |
} | |
/////////////////////////////////////////////////////////////////////// | |
s64 ParseSharedTimeSince1900(void) | |
{ | |
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND] | |
ms2000_0 = j_DateToMsSinceY2K(&tmpDate1, 2000, 1, 1, 0, 0, 0, 0); | |
DateDiffToNs(&tmp, ms2000_0, &g_timestampOf1900SinceY2K);// timestamp of 1900 since 2000 (negative) | |
val = tmp; | |
msSince1900 = NsToMs(&val); | |
ms2000 = j_DateToMsSinceY2K(&tmpDate2, 2000, 1, 1, 0, 0, 0, 0); | |
ms2100 = j_DateToMsSinceY2K(&tmpDate1, 2100, 1, 1, 0, 0, 0, 0); | |
DateDiffToNs(&tmp, ms2100, ms2000); | |
val = tmp; | |
centuryInMs = NsToMs(&val); | |
newSystemTick = 0LL; | |
oldSystemTick = 0LL; | |
ReadSharedDateTime(&newSystemTick, &outMsSince1900, &oldSystemTick, &systemTickRate, &leapHour); | |
sharedTimeElapsedMs = RatioConvertTruncate(newSystemTick - oldSystemTick, 1000, systemTickRate);// (delta(ticks)/rate) * 1000 | |
newMsSince1900 = sharedTimeElapsedMs + outMsSince1900; | |
v20 = 0; | |
HIDWORD(tmp) = &v15; | |
v16 = 0; | |
v15 = 0; | |
remHour = 3600000 - sharedTimeElapsedMs; | |
v18 = -(HIDWORD(sharedTimeElapsedMs) + ((unsigned int)sharedTimeElapsedMs > 3600000)); | |
if ( ((unsigned int)(3600000 - sharedTimeElapsedMs) > 0) | |
- (HIDWORD(sharedTimeElapsedMs) | |
+ ((unsigned int)sharedTimeElapsedMs > 3600000)) <= 0 ) | |
v7 = (s32 *)HIDWORD(tmp); // 0? | |
else | |
v7 = &remHour; | |
return (RatioConvertTruncate(leapHour, *v7, 3600000) + newMsSince1900 - msSince1900) % centuryInMs + msSince1900;// add (remaining msecs to next hour)*leapHours | |
} | |
//////////////////////////////////////////////////////////////////////////////////// | |
// Dead code, possibly? | |
void __fastcall ChangeYearInTimestampY2k(s64 *msTimeStampY2kWithNewYear, s64 *msTimestampY2k, s32 yr) | |
{ | |
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND] | |
resultMs = msTimeStampY2kWithNewYear; | |
v12 = msTimestampY2k; | |
day = MsToDayY2K(*msTimestampY2k); | |
JulianDayToGregorianDateFromY2k(0, &month, &dayofmonth, day); | |
ms = ExtractMsFromTimestamp(msTimestampY2k); | |
seconds = ExtractSecondsFromTimestamp(msTimestampY2k); | |
minutes = ExtractMinutesFromTimestamp(msTimestampY2k); | |
hrs = ExtractHoursFromTimestamp(msTimestampY2k); | |
DateToMsSinceY2K(resultMs, yr, month, dayofmonth, hrs, minutes, seconds, ms); | |
} | |
///////////////////////////////////////////////////////// | |
void __fastcall TimeDateUpdater::ResetSharedDateTimeWithRtc(TimeDateUpdater *this) | |
{ | |
s64 time1900; // r0 | |
s64 systemTick; // [sp+0h] [bp-30h] | |
s64 timeOff; // [sp+8h] [bp-28h] | |
s64 msSinceY2k; // [sp+10h] [bp-20h] | |
s64 val; // [sp+18h] [bp-18h] | |
s64 result; // [sp+20h] [bp-10h] | |
systemTick = 0LL; | |
msSinceY2k = 0LL; | |
TimeDateUpdater::GetRtcTimeMsSinceY2k(this, &msSinceY2k, &systemTick); | |
SystemTickToNs(&timeOff, &systemTick); | |
this->lastUpdatedSystemMs = timeOff; | |
cfgGetUserTimeOffset(&timeOff); | |
this->userTimeOffset = timeOff; | |
cfgGetUseTimeOffset2(&timeOff); | |
this->settingsTimeOffset = timeOff; | |
timeOff = msSinceY2k; | |
AddTimeOffsetMsWithNs(&result, &timeOff, &this->userTimeOffset);// rtc+timeoffset | |
DateDiffToNs(&timeOff, &result, &g_timestampOf1900SinceY2K);// convert to base year 1900 | |
val = timeOff; | |
time1900 = NsToMs(&val); | |
ResetSharedDateTime(time1900, systemTick); | |
ModeControlManager::InformProcess9Rtc(p_g_ModeControlManager); // does nothing on nfirm | |
} | |
void __fastcall ResetSharedDateTime(s64 time1900, s64 systemTick) | |
{ | |
DATETIME_SELECTOR = 0; | |
WriteSharedDateTime(time1900, systemTick, 268111856LL, 0LL); | |
} | |
//////////////////////////////////////////////////////////////// | |
void __fastcall TimeDateUpdater::UpdateSharedDateTime(TimeDateUpdater *this) | |
{ | |
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND] | |
systemTickFromMcuSysmodule = 0LL; | |
timeMs = 0LL; | |
TimeDateUpdater::GetRtcTimeMsSinceY2k(this, &timeMs, &systemTickFromMcuSysmodule); | |
SystemTickToNs(&ms, &systemTickFromMcuSysmodule); | |
sub64_(&result, &ms, &this->lastUpdatedSystemMs); | |
b = result; | |
MsToNs(&ns, 3600000LL); | |
a = ns; | |
sub64_(&remainingMsInHour, &a, &b); | |
if ( NsToMs(&remainingMsInHour) <= 36000 ) // 1/100th of an hour | |
{ | |
this->lastUpdatedSystemMs = ms; | |
AddTimeOffsetMsWithNs(&result, &timeMs, &this->userTimeOffset); | |
endMs = result; | |
DateDiffToNs(&ns, &endMs, &g_timestampOf1900SinceY2K); | |
b = ns; | |
newMsWithUserOffset = NsToMs(&b); | |
UpdateSharedTime(newMsWithUserOffset, systemTickFromMcuSysmodule); | |
ModeControlManager::InformProcess9Rtc(p_g_ModeControlManager); | |
} | |
} | |
///////////////////////////// | |
void __fastcall UpdateSharedTime(s64 newMsSince1900FromRtcAndUserOffset, s64 systemTickFromMcuSysmodule) | |
{ | |
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND] | |
v26 = newMsSince1900FromRtcAndUserOffset; | |
ParseSharedTimeGetNsSinceY2k(&parsedSharedTimestamp); | |
outCurrentSystemTick = 0; | |
v17 = 0; | |
outSharedSystemTick = 0LL; | |
ReadSharedDateTime(&outCurrentSystemTick, &msSince1900, &outSharedSystemTick, &tickToNsRate, &leapHours); | |
MsToNs(&v11, newMsSince1900FromRtcAndUserOffset); | |
ns = v11; | |
val = g_timestampOf1900SinceY2K; | |
v3 = *IncrementMsCounterWithNs(&val, &ns); | |
if ( v3 < *j_DateToMsSinceY2K(&resultMs, 2100, 1, 1, 0, 0, 0, 0) ) | |
{ | |
DateDiffToNs(&leapHourCount, &parsedSharedTimestamp, &g_timestampOf1900SinceY2K); | |
val = leapHourCount; | |
pNewAdjTime1900 = &val; | |
} | |
else | |
{ | |
v4 = j_DateToMsSinceY2K(&v25, 2000, 1, 1, 0, 0, 0, 0); | |
v5 = j_DateToMsSinceY2K(&v24, 2100, 1, 1, 0, 0, 0, 0); | |
DateDiffToNs(&resultNs, v5, v4); | |
leapHourCount = resultNs; | |
IncrementMsCounterWithNs(&parsedSharedTimestamp, &leapHourCount);// add a century?? | |
// bug? I believe they should subtract a century instead. | |
DateDiffToNs(&val, &parsedSharedTimestamp, &g_timestampOf1900SinceY2K); | |
leapHourCount = val; | |
pNewAdjTime1900 = &leapHourCount; | |
} | |
v7 = NsToMs(pNewAdjTime1900) - newMsSince1900FromRtcAndUserOffset; | |
LODWORD(v11) = v7; | |
LODWORD(v7) = systemTickFromMcuSysmodule; | |
v8 = HIDWORD(v7); | |
HIDWORD(v7) = HIDWORD(systemTickFromMcuSysmodule); | |
v9 = RatioConvertTruncate( // newSysClockRate = (delta(systicks) / delta(rtc_ms)) * 1000 | |
// | |
// So many rounding errors, :vomit: | |
v7 - outSharedSystemTick, | |
1000, | |
(signed int)newMsSince1900FromRtcAndUserOffset - (signed int)msSince1900); | |
if ( newMsSince1900FromRtcAndUserOffset < msSince1900 ) | |
{ | |
v10 = 0; | |
v9 = 268111856LL; // SYSCLOCK_ARM11 | |
v8 = 0; | |
LODWORD(v11) = 0; | |
} | |
else | |
{ | |
v10 = v11; | |
} | |
WriteSharedDateTime(newMsSince1900FromRtcAndUserOffset, systemTickFromMcuSysmodule, v9, __PAIR__(v8, v10)); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment