aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/libc
diff options
context:
space:
mode:
authorspicyjpeg <88942473+spicyjpeg@users.noreply.github.com>2021-11-18 17:25:58 +0100
committerspicyjpeg <88942473+spicyjpeg@users.noreply.github.com>2021-11-18 17:25:58 +0100
commit853fa4eed241cdd87b8c2d2e60cf755509d9a184 (patch)
tree0fbd0201df56b95ff6ca6362692236b7d7e9b5bf /libpsn00b/libc
parent619fa016bbc4ddd8d4a670cf3f8aa63617473b2f (diff)
downloadpsn00bsdk-853fa4eed241cdd87b8c2d2e60cf755509d9a184.tar.gz
sprintf improvements, added new _mem_init, GetSystemInfo
Diffstat (limited to 'libpsn00b/libc')
-rw-r--r--libpsn00b/libc/start.c42
-rw-r--r--libpsn00b/libc/vsprintf.c14
2 files changed, 35 insertions, 21 deletions
diff --git a/libpsn00b/libc/start.c b/libpsn00b/libc/start.c
index c7dbfe5..f190794 100644
--- a/libpsn00b/libc/start.c
+++ b/libpsn00b/libc/start.c
@@ -3,9 +3,9 @@
* (C) 2021 Lameguy64, spicyjpeg - MPL licensed
*/
-#include <sys/types.h>
+#include <stdint.h>
#include <string.h>
-#include <malloc.h>
+#include <stdlib.h>
#define KERNEL_ARG_STRING ((const char *) 0x80000180)
#define KERNEL_RETURN_VALUE ((volatile int *) 0x8000dffc)
@@ -47,13 +47,7 @@ static void _parse_kernel_args() {
}
}
-/* Main */
-
-// How much space at the end of RAM to leave for the stack (instead of using it
-// as heap). By default 128 KB are reserved for the stack, but this constant
-// can be overridden in main.c (or anywhere else) simply by redeclaring it
-// without the weak attribute.
-const int32_t __attribute__((weak)) STACK_MAX_SIZE = 0x20000;
+/* Heap initialization */
// These are defined by the linker script. Note that these are *NOT* pointers,
// they are virtual symbols whose location matches their value. The simplest
@@ -63,6 +57,20 @@ extern uint8_t __bss_start[];
extern uint8_t _end[];
//extern uint8_t _gp[];
+// This function should not be called manually in most cases. It might be
+// useful though to change the stack size and/or reinitialize the heap on
+// systems that have more than 2 MB of RAM (e.g. emulators, devkits, PS1-based
+// arcade boards).
+void _mem_init(size_t ram_size, size_t stack_max_size) {
+ void *exe_end = _end + 4;
+ size_t exe_size = (size_t) exe_end - (size_t) __text_start;
+ size_t ram_used = (0x10000 + exe_size + stack_max_size) & 0xfffffffc;
+
+ InitHeap(exe_end, ram_size - ram_used);
+}
+
+/* Main */
+
extern void (*__CTOR_LIST__[])(void);
extern void (*__DTOR_LIST__[])(void);
@@ -73,24 +81,16 @@ extern int32_t main(int32_t argc, const char* argv[]);
// to overwrite the arg strings in kernel RAM.
void _start(int32_t override_argc, const char **override_argv) {
__asm__ volatile("la $gp, _gp;");
-
- // Mem init assembly function (clears BSS and InitHeap to _end which is
- // not possible to do purely in C because the linker complains about
- // relocation truncated to fit: R_MIPS_GPREL16 against `_end'
- // Workaround is to do it in assembly because la pseudo-op doesn't use
- // stupid gp relative addressing
- //_mem_init();
// Clear BSS 4 bytes at a time. BSS is always aligned to 4 bytes by the
// linker script.
for (uint32_t *i = (uint32_t *) __bss_start; i < (uint32_t *) _end; i++)
*i = 0;
- // Calculate how much RAM is available after the loaded executable and
- // initialize heap accordingly.
- void *exe_end = _end + 4;
- size_t exe_size = (size_t) exe_end - (size_t) __text_start;
- InitHeap(exe_end, 0x1f0000 - (exe_size + STACK_MAX_SIZE) & 0xfffffffc);
+ // Initialize the heap, assuming 2 MB of RAM and reserving 128 KB for the
+ // stack. Note that _mem_init() can be called again in main() to change
+ // these values.
+ _mem_init(0x200000, 0x20000);
if (override_argv) {
__argc = override_argc;
diff --git a/libpsn00b/libc/vsprintf.c b/libpsn00b/libc/vsprintf.c
index 361b24e..0a99dcc 100644
--- a/libpsn00b/libc/vsprintf.c
+++ b/libpsn00b/libc/vsprintf.c
@@ -58,6 +58,15 @@
pad_quantity = (pad_quantity - 1) - last; \
if(pad_quantity < 0) pad_quantity = 0;
+#define calculate_real_padding_bin() \
+ last = 0; \
+ for (x = 0; x < 32; x++) \
+ if((arg >> x) & 1) \
+ last = x; \
+ \
+ pad_quantity = (pad_quantity - 1) - last; \
+ if(pad_quantity < 0) pad_quantity = 0;
+
#define write_padding() \
if(!(flags & SPRINTF_NEGFIELD_FLAG)) \
for(x = 0; x < pad_quantity; x++) \
@@ -703,6 +712,9 @@ int vsnprintf(char *string, unsigned int size, const char *fmt, va_list ap)
//else
// arg = va_arg(ap, unsigned long long);
+ calculate_real_padding_bin();
+ write_padding();
+
for(x=31;x>=0;x--)
{
y = (arg >> x);
@@ -715,6 +727,8 @@ int vsnprintf(char *string, unsigned int size, const char *fmt, va_list ap)
put_in_string(string, ssz, y + '0', string_pos++);
}
+ write_neg_padding();
+
directive_coming = 0;
break;