diff --git a/src/sdk/Makefile.am b/src/sdk/Makefile.am index 7ca8b245..9dc02ad7 100644 --- a/src/sdk/Makefile.am +++ b/src/sdk/Makefile.am @@ -31,7 +31,7 @@ INETHELPER_OBJS = pspSdkLoadInetModules.o pspSdkInetInit.o pspSdkInetTerm.o MULT_SRCS = modulemgr_patches.c inethelper.c MULT_OBJS = $(MODULEMGR_PATCHES_OBJS) $(INETHELPER_OBJS) -libpspsdk_a_SOURCES = query_mod.c loadmodule.c fixup.c threadutils.c interrupt.S k1set.S fpu.S $(MULT_SRCS) +libpspsdk_a_SOURCES = query_mod.c loadmodule.c fixup.c threadutils.c memory.c interrupt.S k1set.S fpu.S $(MULT_SRCS) libpspsdk_a_LIBADD = $(MULT_OBJS) $(MODULEMGR_PATCHES_OBJS): modulemgr_patches.c diff --git a/src/sdk/memory.c b/src/sdk/memory.c new file mode 100644 index 00000000..00b3a694 --- /dev/null +++ b/src/sdk/memory.c @@ -0,0 +1,100 @@ +/* + * PSP Software Development Kit - https://github.com/pspdev + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * memory.c - Code to get accurate reporting of available (video) memory. + * + * Copyright (c) 2023 Ivy Bowling + * + */ + +#include +#include +#include + +static u32 _pspSdkGetMaxLineareMemorySize(void) +{ + u32 size, blocksize; + u8 *ram; + + size = 0; + blocksize = 1024 * 1024; // 1 kB + + while (blocksize) + { + /* Increase the size by the block */ + size += blocksize; + ram = (u8*) malloc(size); + + if (!ram) + { + size -= blocksize; + blocksize >>= 1; + } + else + { + free(ram); + } + } + + return size; +} + +SceSize pspSdkTotalFreeUserMemSize(void) +{ + u8 **ram, **temp; + u32 size, count, x; + + ram = NULL; + size = count = 0; + + int intc = pspSdkDisableInterrupts(); + + while (1) + { + /* Check entry size */ + if (!(count % 10)) + { + /* Allocate more entries if needed */ + temp = (u8**) realloc(ram, sizeof(u8*) * (count + 10)); + + if (!temp) + break; + + /* Update entries and their size */ + ram = temp; + size += (sizeof(u8*) * 10); + } + + x = _pspSdkGetMaxLineareMemorySize(); + + if (!x) + break; + + /* Try to do the memory allocation */ + ram[count] = (u8*) malloc(x); + + if (!ram[count]) + break; + + size += x; + count++; + } + + /* Free everything we've allocated */ + if (ram) + { + for (x = 0; x < count; x++) + { + free(ram[x]); + } + + free(ram); + } + + pspSdkEnableInterrupts(intc); + + /* Amount we were able to allocate before running out, in bytes. */ + return size; +} \ No newline at end of file diff --git a/src/sdk/pspsdk.h b/src/sdk/pspsdk.h index e267ba2b..b70029be 100644 --- a/src/sdk/pspsdk.h +++ b/src/sdk/pspsdk.h @@ -286,6 +286,17 @@ unsigned int pspSdkGetK1(void); */ void pspSdkDisableFPUExceptions(void); +/** + * Gets the amount of memory available in the user partition(s). + * + * @note This is not to be confused with sceKernelTotalFreeMemSize, which + * rather contradictorily only returns the amount of memory free in the + * kernel memory partition. + * + * @return The amount of user memory available, in bytes. + */ +SceSize pspSdkTotalFreeUserMemSize(void); + /**@}*/ #ifdef __cplusplus