]> Chaos Git - corbenik/ctrulib.git/commitdiff
implement gettimeofday
authorDave Murphy <davem@devkitpro.org>
Mon, 23 Feb 2015 17:41:10 +0000 (17:41 +0000)
committerDave Murphy <davem@devkitpro.org>
Mon, 23 Feb 2015 17:41:10 +0000 (17:41 +0000)
libctru/source/os.c
libctru/source/system/initSystem.c

index d0287ad1d7cd74e04aca610f3fae11de71b57294..090eb952c62cbd74d9305a78f759313e686cc9fd 100644 (file)
@@ -2,9 +2,17 @@
 #include <3ds/os.h>
 #include <3ds/svc.h>
 
+#include <sys/time.h>
+#include <reent.h>
 
+#define TICKS_PER_USEC 268.123480
 #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 {
        u64 date_time;
        u64 update_tick;
@@ -19,8 +27,9 @@ static volatile datetime_t* __datetime1 =
        (datetime_t*) 0x1FF81040;
 
 
-u32 osConvertVirtToPhys(u32 vaddr)
-{
+//---------------------------------------------------------------------------------
+u32 osConvertVirtToPhys(u32 vaddr) {
+//---------------------------------------------------------------------------------
        if(vaddr >= 0x14000000 && vaddr < 0x1c000000)
                return vaddr + 0x0c000000; // LINEAR heap
        if(vaddr >= 0x1F000000 && vaddr < 0x1F600000)
@@ -32,15 +41,17 @@ u32 osConvertVirtToPhys(u32 vaddr)
        return 0;
 }
 
-u32 osConvertOldLINEARMemToNew(u32 vaddr)
-{
+//---------------------------------------------------------------------------------
+u32 osConvertOldLINEARMemToNew(u32 vaddr) {
+//---------------------------------------------------------------------------------
        if(vaddr >= 0x30000000 && vaddr < 0x40000000)return vaddr;
        if(vaddr >= 0x14000000 && vaddr < 0x1c000000)return vaddr+=0x1c000000;
        return 0;
 }
 
-// Returns number of milliseconds since 1st Jan 1900 00:00.
-u64 osGetTime() {
+//---------------------------------------------------------------------------------
+static datetime_t getSysTime() {
+//---------------------------------------------------------------------------------
        u32 s1, s2 = *__datetime_selector & 1;
        datetime_t dt;
 
@@ -53,26 +64,64 @@ u64 osGetTime() {
                s2 = *__datetime_selector & 1;
        } while(s2 != s1);
 
-       u64 delta = svcGetSystemTick() - dt.update_tick;
+       return dt;
+}
+
+//---------------------------------------------------------------------------------
+int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz) {
+//---------------------------------------------------------------------------------
+       if (tp != NULL) {
 
-       // Work around the VFP not supporting 64-bit integer <--> floating point conversion
-       double temp = (u32)(delta >> 32);
-       temp *= 0x100000000ULL;
-       temp += (u32)delta;
+               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;
 
-       u32 offset = temp / TICKS_PER_MSEC;
-       return dt.date_time + offset;
+       return dt.date_time + (u32)(u64_to_double(delta)/TICKS_PER_MSEC);
 }
 
+//---------------------------------------------------------------------------------
 u32 osGetFirmVersion() {
+//---------------------------------------------------------------------------------
        return (*(u32*)0x1FF80000) & ~0xFF;
 }
 
+//---------------------------------------------------------------------------------
 u32 osGetKernelVersion() {
+//---------------------------------------------------------------------------------
        return (*(u32*)0x1FF80060) & ~0xFF;
 }
 
+//---------------------------------------------------------------------------------
 const char* osStrError(u32 error) {
+//---------------------------------------------------------------------------------
        switch((error>>26) & 0x3F) {
        case 0:
                return "Success.";
index c14c455cbc3a2014948780d5f7134bd5681bcbb2..4f1c59746bdee0fd013c07659a19d66b2d826ccd 100644 (file)
@@ -1,4 +1,6 @@
 #include <sys/iosupport.h>
+#include <sys/time.h>
+
 #include <string.h>
 #include <3ds/types.h>
 #include <3ds/svc.h>
@@ -14,12 +16,15 @@ void __appInit();
 
 
 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))
 {
 
        // Register newlib exit() syscall
        __syscalls.exit = __ctru_exit;
+    __syscalls.gettod_r = __libctru_gtod;
+
        __system_retAddr = __service_ptr ? retAddr : NULL;
 
        __system_allocateHeaps();