diff --git a/src/Platform_NDS.c b/src/Platform_NDS.c index a9a10dffd..6a3f86bdd 100644 --- a/src/Platform_NDS.c +++ b/src/Platform_NDS.c @@ -56,8 +56,25 @@ cc_bool Platform_ReadonlyFilesystem; /*########################################################################################################################* *------------------------------------------------------Logging/Time-------------------------------------------------------* *#########################################################################################################################*/ -static u32 last_raw; -static u64 base_time; +static uint32_t last_raw; +static uint64_t base_time; + +static uint32_t GetTimerValues(void) { + uint16_t lo = TIMER_DATA(0); + uint16_t hi = TIMER_DATA(1); + + // Lo timer can possibly overflow between reading lo and hi + uint16_t lo_again = TIMER_DATA(0); + uint16_t hi_again = TIMER_DATA(1); + + // Check if lo timer has overflowed + if (lo_again < lo) { + // If so, use known stable timer read values instead + lo = lo_again; + hi = hi_again; + } + return lo | (hi << 16); +} cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) { if (end < beg) return 0; @@ -66,7 +83,7 @@ cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) { } cc_uint64 Stopwatch_Measure(void) { - u32 raw = cpuGetTiming(); + uint32_t raw = GetTimerValues(); // Since counter is only a 32 bit integer, it overflows after a minute or two if (last_raw > 0xF0000000 && raw < 0x10000000) { base_time += 0x100000000ULL; @@ -76,6 +93,20 @@ cc_uint64 Stopwatch_Measure(void) { return base_time + raw; } +static void Stopwatch_Init(void) { + // Turn off both timers + TIMER_CR(0) = 0; + TIMER_CR(1) = 0; + + // Reset timer values to 0 + TIMER_DATA(0) = 0; + TIMER_DATA(1) = 0; + + // Turn on timer 1, with timer 1 incrementing timer 0 on overflow + TIMER_CR(1) = TIMER_CASCADE | TIMER_ENABLE; + TIMER_CR(0) = TIMER_ENABLE; +} + static void LogNocash(const char* msg, int len) { // Can only be up to 120 bytes total char buffer[120]; @@ -588,7 +619,7 @@ void Platform_Init(void) { InitFilesystem(); InitNetworking(); - cpuStartTiming(1); + Stopwatch_Init(); } void Platform_Free(void) { } diff --git a/src/Window_Terminal.c b/src/Window_Terminal.c index af370828e..1ede3c179 100644 --- a/src/Window_Terminal.c +++ b/src/Window_Terminal.c @@ -34,7 +34,7 @@ #define OutputConsole(buf, len) WriteConsoleA(hStdout, buf, len, NULL, NULL) #define BOX_CHAR "\xE2\x96\x84" #else - #define OutputConsole(buf, len) write(STDOUT_FILENO, buf, len) + #define OutputConsole(buf, len) !!write(STDOUT_FILENO, buf, len) #define BOX_CHAR "\xE2\x96\x84" #endif @@ -146,7 +146,7 @@ static void HookTerminal(void) { tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); // https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Normal-tracking-mode - OutputConst(DEC_PM_SET("1049")); // Use Normal Screen Buffer and restore cursor as in DECRC, xterm. + OutputConst(DEC_PM_SET("1049")); OutputConst(CSI "0m"); OutputConst(ERASE_CMD("2")); // Ps = 2 ⇒ Erase All. OutputConst(DEC_PM_SET("1003")); // Ps = 1 0 0 3 ⇒ Use All Motion Mouse Tracking, xterm. See @@ -161,7 +161,7 @@ static void UnhookTerminal(void) { //ioctl(STDIN_FILENO, KDSKBMODE, orig_KB); tcsetattr(STDIN_FILENO, TCSAFLUSH, &tio); - OutputConst(DEC_PM_RESET("1049")); + OutputConst(DEC_PM_RESET("1049")); // Return to Normal Screen Buffer and restore cursor OutputConst(CSI "0m"); OutputConst(ERASE_CMD("2")); // Ps = 2 ⇒ Erase All. OutputConst(DEC_PM_SET("25")); diff --git a/src/gba/Platform_GBA.c b/src/gba/Platform_GBA.c index 8e20f8c22..ec3118236 100644 --- a/src/gba/Platform_GBA.c +++ b/src/gba/Platform_GBA.c @@ -70,12 +70,13 @@ static uint32_t GetTimerValues(void) { uint16_t lo = REG_TMR2_DATA; uint16_t hi = REG_TMR3_DATA; - // Did lo timer possibly overflow between reading lo and hi? + // Lo timer can possibly overflow between reading lo and hi uint16_t lo_again = REG_TMR2_DATA; uint16_t hi_again = REG_TMR3_DATA; + // Check if lo timer has overflowed if (lo_again < lo) { - // If so, use known safe timer read values instead + // If so, use known stable timer read values instead lo = lo_again; hi = hi_again; } diff --git a/src/saturn/Platform_Saturn.c b/src/saturn/Platform_Saturn.c index 627c65413..f555f85fc 100644 --- a/src/saturn/Platform_Saturn.c +++ b/src/saturn/Platform_Saturn.c @@ -91,10 +91,13 @@ void DateTime_CurrentLocal(struct cc_datetime* t) { /*########################################################################################################################* *--------------------------------------------------------Stopwatch--------------------------------------------------------* *#########################################################################################################################*/ -static volatile cc_uint32 overflow_count; +static volatile cc_uint32 overflow_count, wdt_overflows; + +static void wdt_handler(void) { wdt_overflows++; } +static void ovf_handler(void) { overflow_count++; } cc_uint64 Stopwatch_Measure(void) { - return cpu_frt_count_get() + (overflow_count * 65536); + return cpu_frt_count_get() | (overflow_count << 16); } cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) { @@ -105,14 +108,16 @@ cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) { return (delta * 1000) / CPU_FRT_NTSC_320_128_COUNT_1MS; } -static void ovf_handler(void) { overflow_count++; } - static void Stopwatch_Init(void) { //cpu_frt_init(CPU_FRT_CLOCK_DIV_8); cpu_frt_init(CPU_FRT_CLOCK_DIV_128); cpu_frt_ovi_set(ovf_handler); - cpu_frt_interrupt_priority_set(15); + + //pu_wdt_init(CPU_WDT_CLOCK_DIV_4096); + //cpu_wdt_interrupt_priority_set(15); + //cpu_wdt_timer_mode_set(CPU_WDT_MODE_INTERVAL, wdt_handler); + //cpu_wdt_enable(); }