From 76467477dfc4997a1ef372abbf3f902edbefc059 Mon Sep 17 00:00:00 2001 From: sozud <122322823+sozud@users.noreply.github.com> Date: Thu, 5 Sep 2024 17:38:09 -0700 Subject: [PATCH] Match counter --- build.py | 7 ++++ src/api/counter.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/api/counter.c diff --git a/build.py b/build.py index a031254..25f31ee 100644 --- a/build.py +++ b/build.py @@ -253,6 +253,13 @@ def build_35(): add_lib_263(gs_srcs, "build/3.5/gs", "./psy-q/3.5/PSX/LIB/LIBGS.LIB", "-DVERSION=35", "3.5") + api_srcs = [ + 'src/api/counter.c' + ] + + add_lib_263(api_srcs, "build/3.5/api", "./psy-q/3.5/PSX/LIB/LIBAPI.LIB", "-DVERSION=35", "3.5") + + def build_36(): snd_srcs = [ # 'src/snd/next.c', diff --git a/src/api/counter.c b/src/api/counter.c new file mode 100644 index 0000000..d989c81 --- /dev/null +++ b/src/api/counter.c @@ -0,0 +1,82 @@ +#include "../types.h" + +typedef struct { + u16 rootCounter; + s16 unk2; + s16 mode; + s16 : 16; + s16 target; + s32 : 32; +} Counter; + +// https://psx-spx.consoledev.net/timers/ +static volatile s32 *_interrupt_status_register = 0x1F801070; + +static volatile Counter* _counters = 0x1F801100; + +static volatile s32 _interrupt_status_masks[4] = { + 0x00000010, + 0x00000020, + 0x00000040, + 0x00000001 +}; + +s32 SetRCnt(s32 spec, s16 target, s32 flags) { + s32 i = spec & 0xFFFF; + s32 final_mode = 0x48; + if (i >= 3) { + return 0; + } + _counters[i].mode = 0; + _counters[i].target = target; + + if (i < 2u) { + if (flags & 0x10) { + final_mode = 0x49; + } + if (!(flags & 1)) { + final_mode |= 0x100; + } + } else if (i == 2u) { // nb: `else` is redundant here + if (!(flags & 1)) { + final_mode = 0x248; + } + } + if ((flags & 0x1000) != 0) { + final_mode |= 0x10; + } + + _counters[i].mode = final_mode; + return 1; +} + +long GetRCnt(long spec) { + s32 i = spec & 0xFFFF; + if (i >= 3) { + return 0; + } + return _counters[i].rootCounter; +} + +s32 StartRCnt(s32 spec) { + s32 i = spec & 0xFFFF; + long* mask = _interrupt_status_masks; + _interrupt_status_register[1] |= mask[i]; + return i < 3; +} + +long StopRCnt(long spec) { + s32 i = spec & 0xFFFF; + long* mask = _interrupt_status_masks; + _interrupt_status_register[1] &= ~mask[i]; + return 1; +} + +long ResetRCnt(long spec) { + s32 i = spec & 0xFFFF; + if (i >= 3) { + return 0; + } + _counters[i].rootCounter = 0; + return 1; +} \ No newline at end of file