Skip to content

Instantly share code, notes, and snippets.

@TuxSH
Last active May 12, 2020 20:34
Show Gist options
  • Save TuxSH/5ab04ac60254dafefbb4f4c4831180f6 to your computer and use it in GitHub Desktop.
Save TuxSH/5ab04ac60254dafefbb4f4c4831180f6 to your computer and use it in GitHub Desktop.
3DS time management
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