diff options
| author | spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> | 2021-11-18 17:25:58 +0100 |
|---|---|---|
| committer | spicyjpeg <88942473+spicyjpeg@users.noreply.github.com> | 2021-11-18 17:25:58 +0100 |
| commit | 853fa4eed241cdd87b8c2d2e60cf755509d9a184 (patch) | |
| tree | 0fbd0201df56b95ff6ca6362692236b7d7e9b5bf /libpsn00b/libc | |
| parent | 619fa016bbc4ddd8d4a670cf3f8aa63617473b2f (diff) | |
| download | psn00bsdk-853fa4eed241cdd87b8c2d2e60cf755509d9a184.tar.gz | |
sprintf improvements, added new _mem_init, GetSystemInfo
Diffstat (limited to 'libpsn00b/libc')
| -rw-r--r-- | libpsn00b/libc/start.c | 42 | ||||
| -rw-r--r-- | libpsn00b/libc/vsprintf.c | 14 |
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; |
