From b0370d117c37c2cb51c5ff8a3fd08046e9c69231 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Tue, 1 Jul 2025 07:23:44 +1000 Subject: [PATCH] GBA: Timing semi works now --- src/gba/Platform_GBA.c | 51 ++++++++++++++++++++++++++++++++++++++++-- src/gba/Window_GBA.c | 28 ++--------------------- src/gba/gbadefs.h | 41 +++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 src/gba/gbadefs.h diff --git a/src/gba/Platform_GBA.c b/src/gba/Platform_GBA.c index b79618b4e..8e20f8c22 100644 --- a/src/gba/Platform_GBA.c +++ b/src/gba/Platform_GBA.c @@ -11,6 +11,7 @@ #include #include #include +#include "gbadefs.h" #define OVERRIDE_MEM_FUNCTIONS #include "../_PlatformConsole.h" @@ -65,14 +66,58 @@ void Mem_Free(void* mem) { /*########################################################################################################################* *------------------------------------------------------Logging/Time-------------------------------------------------------* *#########################################################################################################################*/ +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? + uint16_t lo_again = REG_TMR2_DATA; + uint16_t hi_again = REG_TMR3_DATA; + + if (lo_again < lo) { + // If so, use known safe timer read values instead + lo = lo_again; + hi = hi_again; + } + return lo | (hi << 16); +} + +static void Stopwatch_Init(void) { + // Turn off both timers + REG_TMR2_CTRL = 0; + REG_TMR3_CTRL = 0; + + // Reset timer values to 0 + REG_TMR2_DATA = 0; + REG_TMR3_DATA = 0; + + // Turn on timer 3, with timer 3 incrementing timer 2 on overflow + REG_TMR3_CTRL = TMR_CASCADE | TMR_ENABLE; + REG_TMR2_CTRL = TMR_ENABLE; +} + +static uint32_t last_raw; +static uint64_t base_time; + +#define US_PER_SEC 1000000 cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) { if (end < beg) return 0; - return 1000 * 1000 * 2;//end - beg; + cc_uint64 delta = end - beg; + return (delta * US_PER_SEC) / SYS_CLOCK; } cc_uint64 Stopwatch_Measure(void) { - return 1; + uint32_t raw = GetTimerValues(); + // Since counter is only a 32 bit integer, it overflows after a minute or two + // TODO use IRQ instead + // TODO lower frequency ? + if (last_raw > 0xF0000000 && raw < 0x10000000) { + base_time += 0x100000000ULL; + } + + last_raw = raw; + return base_time + raw; } extern int nocash_puts(const char *str); @@ -189,6 +234,7 @@ cc_result File_Length(cc_file file, cc_uint32* len) { *#########################################################################################################################*/ // !!! NOTE: PSP uses cooperative multithreading (not preemptive multithreading) !!! void Thread_Sleep(cc_uint32 milliseconds) { + Stopwatch_Measure(); //swiDelay(8378 * milliseconds); // TODO probably wrong } @@ -280,6 +326,7 @@ void Platform_Init(void) { int size = (int)(heap_end - heap_beg); Platform_Log3("HEAP SIZE: %i bytes (%x -> %x)", &size, &heap_beg, &heap_end); + Stopwatch_Init(); } void Platform_Free(void) { } diff --git a/src/gba/Window_GBA.c b/src/gba/Window_GBA.c index bb613c0ac..4ddc77685 100644 --- a/src/gba/Window_GBA.c +++ b/src/gba/Window_GBA.c @@ -11,35 +11,11 @@ #include "../Camera.h" #include - -typedef volatile uint8_t vu8; -typedef volatile uint16_t vu16; -typedef volatile uint32_t vu32; +#include "gbadefs.h" #define SCREEN_WIDTH 240 #define SCREEN_HEIGHT 160 -#define DCNT_MODE3 0x0003 -#define DCNT_BG2 0x0400 - -#define MEM_IO 0x04000000 -#define MEM_VRAM 0x06000000 - -#define REG_DISPCNT *(vu32*)(MEM_IO + 0x0000) -#define REG_KEYINPUT *(vu16*)(MEM_IO + 0x0130) - -#define KEY_A 0x0001 -#define KEY_B 0x0002 -#define KEY_SELECT 0x0004 -#define KEY_START 0x0008 -#define KEY_RIGHT 0x0010 -#define KEY_LEFT 0x0020 -#define KEY_UP 0x0040 -#define KEY_DOWN 0x0080 -#define KEY_R 0x0100 -#define KEY_L 0x0200 - - /*########################################################################################################################* *------------------------------------------------------General data-------------------------------------------------------* *#########################################################################################################################*/ @@ -47,7 +23,7 @@ struct _DisplayData DisplayInfo; struct cc_window WindowInfo; void Window_PreInit(void) { - REG_DISPCNT = DCNT_MODE3 | DCNT_BG2; + REG_DISP_CTRL = DCTRL_MODE3 | DCTRL_BG2; } void Window_Init(void) { diff --git a/src/gba/gbadefs.h b/src/gba/gbadefs.h new file mode 100644 index 000000000..210f9ca1a --- /dev/null +++ b/src/gba/gbadefs.h @@ -0,0 +1,41 @@ +typedef volatile uint8_t vu8; +typedef volatile uint16_t vu16; +typedef volatile uint32_t vu32; + +#define MEM_IO 0x04000000 +#define MEM_VRAM 0x06000000 + +// Display functionality +#define REG_DISP_CTRL *(vu32*)(MEM_IO + 0x0000) + +#define DCTRL_MODE3 0x0003 +#define DCTRL_BG2 0x0400 + +// Keypad functionality +#define REG_KEYINPUT *(vu16*)(MEM_IO + 0x0130) + +#define KEY_A 0x0001 +#define KEY_B 0x0002 +#define KEY_SELECT 0x0004 +#define KEY_START 0x0008 +#define KEY_RIGHT 0x0010 +#define KEY_LEFT 0x0020 +#define KEY_UP 0x0040 +#define KEY_DOWN 0x0080 +#define KEY_R 0x0100 +#define KEY_L 0x0200 + +// Timer functionality +#define REG_TMR0_DATA *(vu16*)(MEM_IO + 0x0100) // Timer 0 data +#define REG_TMR0_CTRL *(vu16*)(MEM_IO + 0x0102) // Timer 0 control +#define REG_TMR1_DATA *(vu16*)(MEM_IO + 0x0104) // Timer 1 data +#define REG_TMR1_CTRL *(vu16*)(MEM_IO + 0x0106) // Timer 1 control +#define REG_TMR2_DATA *(vu16*)(MEM_IO + 0x0108) // Timer 2 data +#define REG_TMR2_CTRL *(vu16*)(MEM_IO + 0x010A) // Timer 2 control +#define REG_TMR3_DATA *(vu16*)(MEM_IO + 0x010C) // Timer 3 data +#define REG_TMR3_CTRL *(vu16*)(MEM_IO + 0x010E) // Timer 3 control + +#define TMR_CASCADE 0x0004 +#define TMR_ENABLE 0x0080 + +#define SYS_CLOCK 16777216