summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authormemberTwo.mb2 <memberTwo.mb2@gmail.com>2008-12-13 11:57:01 +0000
committermemberTwo.mb2 <memberTwo.mb2@gmail.com>2008-12-13 11:57:01 +0000
commit82cd659638c5e1c110c869ffcb58e52ae2d67184 (patch)
treece84bf7ad030d7b791e1a845291bb822a92951c7 /Source/Core
parentd1712f15ca71687ecff0ad823f39726b2e941481 (diff)
Fix time in some games (AC and ZWW at least). Many games doesn't use RTC but TBRs. So a TB offset is initialized at boot with localtime now. There are, indeed, side effects since time is CPU cycle dependent in this case.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1519 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/Src/Timer.cpp13
-rw-r--r--Source/Core/Common/Src/Timer.h1
-rw-r--r--Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp5
-rw-r--r--Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp10
-rw-r--r--Source/Core/Core/Src/HW/SystemTimers.cpp6
5 files changed, 31 insertions, 4 deletions
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(&ltime);
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);