GBA: Timing semi works now

This commit is contained in:
UnknownShadow200 2025-07-01 07:23:44 +10:00
parent fa2a67fb3b
commit b0370d117c
3 changed files with 92 additions and 28 deletions

View File

@ -11,6 +11,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include "gbadefs.h"
#define OVERRIDE_MEM_FUNCTIONS #define OVERRIDE_MEM_FUNCTIONS
#include "../_PlatformConsole.h" #include "../_PlatformConsole.h"
@ -65,14 +66,58 @@ void Mem_Free(void* mem) {
/*########################################################################################################################* /*########################################################################################################################*
*------------------------------------------------------Logging/Time-------------------------------------------------------* *------------------------------------------------------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) { cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
if (end < beg) return 0; 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) { 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); 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) !!! // !!! NOTE: PSP uses cooperative multithreading (not preemptive multithreading) !!!
void Thread_Sleep(cc_uint32 milliseconds) { void Thread_Sleep(cc_uint32 milliseconds) {
Stopwatch_Measure();
//swiDelay(8378 * milliseconds); // TODO probably wrong //swiDelay(8378 * milliseconds); // TODO probably wrong
} }
@ -280,6 +326,7 @@ void Platform_Init(void) {
int size = (int)(heap_end - heap_beg); int size = (int)(heap_end - heap_beg);
Platform_Log3("HEAP SIZE: %i bytes (%x -> %x)", &size, &heap_beg, &heap_end); Platform_Log3("HEAP SIZE: %i bytes (%x -> %x)", &size, &heap_beg, &heap_end);
Stopwatch_Init();
} }
void Platform_Free(void) { } void Platform_Free(void) { }

View File

@ -11,35 +11,11 @@
#include "../Camera.h" #include "../Camera.h"
#include <stdint.h> #include <stdint.h>
#include "gbadefs.h"
typedef volatile uint8_t vu8;
typedef volatile uint16_t vu16;
typedef volatile uint32_t vu32;
#define SCREEN_WIDTH 240 #define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 160 #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-------------------------------------------------------* *------------------------------------------------------General data-------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
@ -47,7 +23,7 @@ struct _DisplayData DisplayInfo;
struct cc_window WindowInfo; struct cc_window WindowInfo;
void Window_PreInit(void) { void Window_PreInit(void) {
REG_DISPCNT = DCNT_MODE3 | DCNT_BG2; REG_DISP_CTRL = DCTRL_MODE3 | DCTRL_BG2;
} }
void Window_Init(void) { void Window_Init(void) {

41
src/gba/gbadefs.h Normal file
View File

@ -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