diff --git a/Source/Core/Common/Src/Timer.cpp b/Source/Core/Common/Src/Timer.cpp index 152d664416..6e59ea0a89 100644 --- a/Source/Core/Common/Src/Timer.cpp +++ b/Source/Core/Common/Src/Timer.cpp @@ -96,4 +96,17 @@ u64 Timer::GetTimeSinceJan1970(void) time(<ime); return((u64)ltime); } + +u64 Timer::GetLocalTimeSinceJan1970(void) +{ + time_t sysTime, tzDiff; + struct tm * gmTime; + + time(&sysTime); + // Lazy way to get local time in sec + gmTime = gmtime(&sysTime); + tzDiff = sysTime - mktime(gmTime); + + return (u64)(sysTime + tzDiff); +} } // end of namespace Common diff --git a/Source/Core/Common/Src/Timer.h b/Source/Core/Common/Src/Timer.h index 4be5ab07d1..64791ab38a 100644 --- a/Source/Core/Common/Src/Timer.h +++ b/Source/Core/Common/Src/Timer.h @@ -37,6 +37,7 @@ class Timer static void IncreaseResolution(); static void RestoreResolution(); static u64 GetTimeSinceJan1970(); + static u64 GetLocalTimeSinceJan1970(); public: diff --git a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp index 549a2d4c48..2bf3c04180 100644 --- a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp +++ b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp @@ -161,13 +161,14 @@ void CBoot::EmulatedBIOS(bool _bDebug) // Bus Clock Speed Memory::Write_U32(0x09a7ec80, 0x800000F8); + // CPU Clock Speed Memory::Write_U32(0x1cf7c580, 0x800000FC); // fake the VI Init of the BIOS Memory::Write_U32(Core::g_CoreStartupParameter.bNTSC ? 0 : 1, 0x800000CC); - // preset time - Memory::Write_U32(CEXIIPL::GetGCTime(), 0x800030D8); + // preset time base ticks + Memory::Write_U64( (u64)CEXIIPL::GetGCTime() * (u64)40500000, 0x800030D8); } diff --git a/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp b/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp index 96479d5589..efe4713876 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp @@ -266,6 +266,11 @@ void CEXIIPL::TransferByte(u8& _uByte) u32 CEXIIPL::GetGCTime() { + const u32 cJanuary2000 = 0x386D4380; // Seconds between 1.1.1970 and 1.1.2000 + + // (mb2): I think we can get rid of the IPL bias. + // I know, it's another hack so I let the previous code for a while. +#if 0 // Get SRAM bias u32 Bias; @@ -275,8 +280,11 @@ u32 CEXIIPL::GetGCTime() } // Get the time ... - const u32 cJanuary2000 = 0x386d35a1; // Seconds between 1.1.1970 and 1.1.2000 u64 ltime = Common::Timer::GetTimeSinceJan1970(); return ((u32)ltime - cJanuary2000 - Bias); +#else + u64 ltime = Common::Timer::GetLocalTimeSinceJan1970(); + return ((u32)ltime - cJanuary2000); +#endif } diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index b5e1b10b13..79f1dc60ce 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -25,6 +25,7 @@ #include "../HW/VideoInterface.h" #include "../HW/SerialInterface.h" #include "../HW/CommandProcessor.h" // for DC watchdog hack +#include "../HW/EXI_DeviceIPL.h" #include "../PowerPC/PowerPC.h" #include "../CoreTiming.h" #include "../Core.h" @@ -38,6 +39,7 @@ namespace SystemTimers u32 CPU_CORE_CLOCK = 486000000u; // 486 mhz (its not 485, stop bugging me!) s64 fakeDec; +u64 startTimeBaseTicks; // ratio of TB and Decrementer to clock cycles // With TB clk at 1/4 of BUS clk @@ -160,7 +162,7 @@ void AdvanceCallback(int cyclesExecuted) { fakeDec -= cyclesExecuted; u64 timebase_ticks = CoreTiming::GetTicks() / TIMER_RATIO; //works since we are little endian and TL comes first :) - *(u64*)&TL = timebase_ticks; + *(u64*)&TL = timebase_ticks + startTimeBaseTicks; if (fakeDec >= 0) PowerPC::ppcState.spr[SPR_DEC] = (u32)fakeDec / TIMER_RATIO; } @@ -198,6 +200,8 @@ void Init() DSP_PERIOD = (int)(GetTicksPerSecond() * 0.005f); } Common::Timer::IncreaseResolution(); + // store and convert localtime at boot to timebase ticks + startTimeBaseTicks = (u64)(CPU_CORE_CLOCK / TIMER_RATIO) * (u64)CEXIIPL::GetGCTime(); et_Dec = CoreTiming::RegisterEvent("DecCallback", DecrementerCallback); et_AI = CoreTiming::RegisterEvent("AICallback", AICallback);