implement gettimeofday
This commit is contained in:
parent
da57493368
commit
992b23040c
@ -2,9 +2,17 @@
|
|||||||
#include <3ds/os.h>
|
#include <3ds/os.h>
|
||||||
#include <3ds/svc.h>
|
#include <3ds/svc.h>
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <reent.h>
|
||||||
|
|
||||||
|
#define TICKS_PER_USEC 268.123480
|
||||||
#define TICKS_PER_MSEC 268123.480
|
#define TICKS_PER_MSEC 268123.480
|
||||||
|
|
||||||
|
// Work around the VFP not supporting 64-bit integer <--> floating point conversion
|
||||||
|
static inline double u64_to_double(u64 value) {
|
||||||
|
return (((double)(u32)(value >> 32))*0x100000000ULL+(u32)value);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 date_time;
|
u64 date_time;
|
||||||
u64 update_tick;
|
u64 update_tick;
|
||||||
@ -19,8 +27,9 @@ static volatile datetime_t* __datetime1 =
|
|||||||
(datetime_t*) 0x1FF81040;
|
(datetime_t*) 0x1FF81040;
|
||||||
|
|
||||||
|
|
||||||
u32 osConvertVirtToPhys(u32 vaddr)
|
//---------------------------------------------------------------------------------
|
||||||
{
|
u32 osConvertVirtToPhys(u32 vaddr) {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
if(vaddr >= 0x14000000 && vaddr < 0x1c000000)
|
if(vaddr >= 0x14000000 && vaddr < 0x1c000000)
|
||||||
return vaddr + 0x0c000000; // LINEAR heap
|
return vaddr + 0x0c000000; // LINEAR heap
|
||||||
if(vaddr >= 0x1F000000 && vaddr < 0x1F600000)
|
if(vaddr >= 0x1F000000 && vaddr < 0x1F600000)
|
||||||
@ -32,15 +41,17 @@ u32 osConvertVirtToPhys(u32 vaddr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 osConvertOldLINEARMemToNew(u32 vaddr)
|
//---------------------------------------------------------------------------------
|
||||||
{
|
u32 osConvertOldLINEARMemToNew(u32 vaddr) {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
if(vaddr >= 0x30000000 && vaddr < 0x40000000)return vaddr;
|
if(vaddr >= 0x30000000 && vaddr < 0x40000000)return vaddr;
|
||||||
if(vaddr >= 0x14000000 && vaddr < 0x1c000000)return vaddr+=0x1c000000;
|
if(vaddr >= 0x14000000 && vaddr < 0x1c000000)return vaddr+=0x1c000000;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns number of milliseconds since 1st Jan 1900 00:00.
|
//---------------------------------------------------------------------------------
|
||||||
u64 osGetTime() {
|
static datetime_t getSysTime() {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
u32 s1, s2 = *__datetime_selector & 1;
|
u32 s1, s2 = *__datetime_selector & 1;
|
||||||
datetime_t dt;
|
datetime_t dt;
|
||||||
|
|
||||||
@ -53,26 +64,64 @@ u64 osGetTime() {
|
|||||||
s2 = *__datetime_selector & 1;
|
s2 = *__datetime_selector & 1;
|
||||||
} while(s2 != s1);
|
} while(s2 != s1);
|
||||||
|
|
||||||
u64 delta = svcGetSystemTick() - dt.update_tick;
|
return dt;
|
||||||
|
|
||||||
// Work around the VFP not supporting 64-bit integer <--> floating point conversion
|
|
||||||
double temp = (u32)(delta >> 32);
|
|
||||||
temp *= 0x100000000ULL;
|
|
||||||
temp += (u32)delta;
|
|
||||||
|
|
||||||
u32 offset = temp / TICKS_PER_MSEC;
|
|
||||||
return dt.date_time + offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz) {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
if (tp != NULL) {
|
||||||
|
|
||||||
|
datetime_t dt = getSysTime();
|
||||||
|
|
||||||
|
u64 delta = svcGetSystemTick() - dt.update_tick;
|
||||||
|
|
||||||
|
u32 offset = (u32)(u64_to_double(delta)/TICKS_PER_USEC);
|
||||||
|
|
||||||
|
// adjust from 1900 to 1970
|
||||||
|
u64 now = ((dt.date_time - 2208988800000ULL) * 1000) + offset;
|
||||||
|
|
||||||
|
tp->tv_sec = u64_to_double(now)/1000000.0;
|
||||||
|
tp->tv_usec = now - ((tp->tv_sec) * 1000000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tz != NULL) {
|
||||||
|
tz->tz_minuteswest = 0;
|
||||||
|
tz->tz_dsttime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns number of milliseconds since 1st Jan 1900 00:00.
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
u64 osGetTime() {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
datetime_t dt = getSysTime();
|
||||||
|
|
||||||
|
u64 delta = svcGetSystemTick() - dt.update_tick;
|
||||||
|
|
||||||
|
return dt.date_time + (u32)(u64_to_double(delta)/TICKS_PER_MSEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
u32 osGetFirmVersion() {
|
u32 osGetFirmVersion() {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
return (*(u32*)0x1FF80000) & ~0xFF;
|
return (*(u32*)0x1FF80000) & ~0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
u32 osGetKernelVersion() {
|
u32 osGetKernelVersion() {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
return (*(u32*)0x1FF80060) & ~0xFF;
|
return (*(u32*)0x1FF80060) & ~0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
const char* osStrError(u32 error) {
|
const char* osStrError(u32 error) {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
switch((error>>26) & 0x3F) {
|
switch((error>>26) & 0x3F) {
|
||||||
case 0:
|
case 0:
|
||||||
return "Success.";
|
return "Success.";
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include <sys/iosupport.h>
|
#include <sys/iosupport.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <3ds/types.h>
|
#include <3ds/types.h>
|
||||||
#include <3ds/svc.h>
|
#include <3ds/svc.h>
|
||||||
@ -14,12 +16,15 @@ void __appInit();
|
|||||||
|
|
||||||
|
|
||||||
void __ctru_exit(int rc);
|
void __ctru_exit(int rc);
|
||||||
|
int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz);
|
||||||
|
|
||||||
void __attribute__((weak)) __libctru_init(void (*retAddr)(void))
|
void __attribute__((weak)) __libctru_init(void (*retAddr)(void))
|
||||||
{
|
{
|
||||||
|
|
||||||
// Register newlib exit() syscall
|
// Register newlib exit() syscall
|
||||||
__syscalls.exit = __ctru_exit;
|
__syscalls.exit = __ctru_exit;
|
||||||
|
__syscalls.gettod_r = __libctru_gtod;
|
||||||
|
|
||||||
__system_retAddr = __service_ptr ? retAddr : NULL;
|
__system_retAddr = __service_ptr ? retAddr : NULL;
|
||||||
|
|
||||||
__system_allocateHeaps();
|
__system_allocateHeaps();
|
||||||
|
Loading…
Reference in New Issue
Block a user