mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
Docs: New TODO moved to EMU, old renamed to old_todo Docs: Old coding style is deprecated (old_style.txt) Docs: Removed mention about CubeDocumented and fixed old emails RE: boot.s, proved first asm line (lis instruction parameter) RE: Added PAL and NTSC Boot and IPL IDA files RE: Some work on NTSC IPL (identified many lib calls, including OS, GX) RE: Added EXI Bootrom descrambler by segher RE: GXInit RE: Internal GX lib structures (GXPrivate.h) RE: More details on lomem (OS versions) RE: OSInit and OS.c RE: OSAlloc (heap allocator) RE: Very first code of Metrowerk runtime (__start.c) Docs: Added copy of http://gcdev.narod.ru Source\Utils: Command processor (Cmd.c) Source\Utils: File wrapper Source\Utils: Gekko disasm cleaned up and ported to plain C Source\Utils: Double-linked lists Source\Utils: Ported old Profiler code Source\Utils: String utils
139 lines
4 KiB
Text
139 lines
4 KiB
Text
|
|
Dolphin OS timing initialization
|
|
--------------------------------
|
|
|
|
|
|
BOOTROM:
|
|
=-=-=-=-
|
|
|
|
Bootrom will call __SyncTime() in its main() before gfx menu.
|
|
|
|
|
|
typedef s64 OSTime;
|
|
typedef s32 OSTick;
|
|
|
|
OS timer clock period is 1/12 of Gekko CPU core clock :
|
|
486 mhz / 12 = 40.5 mhz
|
|
|
|
|
|
// update time-base registers by RTC (real-time clock) value
|
|
// RTC is number of seconds, since 01 January 00:00:00 2000 (current epoch)
|
|
void __SyncTime()
|
|
{
|
|
OSTick rtcValue;
|
|
OSSram* sram = __OSLockSram();
|
|
|
|
if( __OSGetRTC(&rtcValue) == TRUE )
|
|
{
|
|
// counterBias can be negative value
|
|
rtcValue += (OSTick)sram->counterBias;
|
|
__OSSetTime( (OSTime)rtcValue * OS_TIMER_CLOCK );
|
|
}
|
|
|
|
__OSUnlockSram(0);
|
|
}
|
|
|
|
// here is SRAM structure
|
|
typedef struct
|
|
{
|
|
u16 checkSum; // SRAM byte checksum (discovered by Costis)
|
|
u16 checkSumInv; // inverted checksum (see YAGCD)
|
|
u32 ead0;
|
|
u32 ead1;
|
|
s32 counterBias; // now we already know meaning of this one too :)
|
|
s8 displayOffsetH; // used by VI library
|
|
u8 ntd;
|
|
u8 language;
|
|
u8 flags;
|
|
u8 dummy[44];
|
|
} SRAM;
|
|
|
|
|
|
OS:
|
|
=-=
|
|
|
|
__OSSetTime is used only in bootrom, to set time-base registers according
|
|
to battery-backed RTC value.
|
|
|
|
|
|
// OS low-memory variable
|
|
OSTime __OSSystemTime AT_ADDRESS(OS_BASE_CACHED | 0x30D8);
|
|
|
|
void __OSSetTime(OSTime newValue)
|
|
{
|
|
BOOL enabled = OSDisableInterrupts();
|
|
|
|
// system time keep its value during soft resets (?)
|
|
__OSSystemTime += newValue - OSGetTime(); // I'm unsure of that
|
|
// 64 bit math is hard to disasm
|
|
|
|
__SetTime(newValue);
|
|
|
|
EXIProbeReset();
|
|
OSRestoreInterrupts(enabled);
|
|
}
|
|
|
|
// use undocumented SPR registers, to set time-base
|
|
// SPR[284] = TBL, to write
|
|
// SPR[285] = TBU, to write
|
|
void __fastcall __SetTime(OSTime time)
|
|
{
|
|
__asm li r5, 0
|
|
__asm mtspr 284, r5 // clear TBL value (to avoid TBU++)
|
|
__asm mtspr 285, r3 // set TBU
|
|
__asm mtspr 284, r4 // set TBL
|
|
__asm blr
|
|
}
|
|
|
|
|
|
Emulation issues : Games dont like real TBR value. At least they work better,
|
|
when TBR is set to 0 before game start. Unemulated TBR is only affect on memcard
|
|
save date, AFAIK.
|
|
|
|
To convert TBR value to real-time I use Windows file time utility :
|
|
|
|
// covert GC time to human-usable time string;
|
|
// example output : "30 Jun 2004 3:06:14:127"
|
|
char * OSTimeFormat(u64 tbr)
|
|
{
|
|
// FILETIME - number of 1/10000000 intervals, since Jan 1 1601
|
|
// GC time - number of 1/40500000 sec intervals, since Jan 1 2000
|
|
// To convert GCTIME -> FILETIME :
|
|
// 1: adjust GCTIME by number of 1/10000000 intervals
|
|
// between Jan 1 1601 and Jan 1 2000.
|
|
// 2: assume X - 1/10000000 sec, Y - 1/40500000 sec,
|
|
// FILETIME = (GCTIME * Y) / X
|
|
|
|
// coversion GCTIME -> FILETIME
|
|
#define MAGIK 0x0713AD7857941000
|
|
f64 x = 1.0 / 10000000.0, y = 1.0 / 40500000.0;
|
|
tbr += MAGIK;
|
|
u64 ft = (u64)( ((f64)(s64)tbr * y) / x );
|
|
FILETIME fileTime; SYSTEMTIME sysTime;
|
|
fileTime.dwHighDateTime = (u32)(ft >> 32);
|
|
fileTime.dwLowDateTime = (u32)(ft & 0x00000000ffffffff);
|
|
FileTimeToSystemTime(&fileTime, &sysTime);
|
|
|
|
// format string
|
|
static char *mnstr[12] =
|
|
{ "Jan", "Feb", "Mar", "Apr",
|
|
"May", "Jun", "Jul", "Aug",
|
|
"Sep", "Oct", "Nov", "Dec"
|
|
};
|
|
static char gcTime[256];
|
|
sprintf( gcTime, "%i %s %i %02i:%02i:%02i:%03i",
|
|
sysTime.wDay, mnstr[sysTime.wMonth - 1], sysTime.wYear,
|
|
sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds );
|
|
return gcTime;
|
|
}
|
|
|
|
Although this conversion is not perfect :O) Play with MAGIK value to find
|
|
suitable bias adjustment.
|
|
|
|
Tell me please, if you find better way to format GC time.
|
|
|
|
|
|
|
|
|
|
Document by org <ogamespec@gmail.com>
|
|
RTC: 11 Dec 2004 :)
|