aboutsummaryrefslogtreecommitdiff
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
parent619fa016bbc4ddd8d4a670cf3f8aa63617473b2f (diff)
downloadpsn00bsdk-853fa4eed241cdd87b8c2d2e60cf755509d9a184.tar.gz
sprintf improvements, added new _mem_init, GetSystemInfo
-rw-r--r--libpsn00b/include/psxapi.h32
-rw-r--r--libpsn00b/libc/start.c42
-rw-r--r--libpsn00b/libc/vsprintf.c14
-rw-r--r--libpsn00b/psxapi/sys/getsysteminfo.s10
4 files changed, 77 insertions, 21 deletions
diff --git a/libpsn00b/include/psxapi.h b/libpsn00b/include/psxapi.h
index 9e92568..ec0dfea 100644
--- a/libpsn00b/include/psxapi.h
+++ b/libpsn00b/include/psxapi.h
@@ -32,6 +32,35 @@
#define RCntMdFR 0x0000
#define RCntMdGATE 0x0010
+typedef struct { // Thread control block
+ int status;
+ int mode;
+ union {
+ unsigned int reg[37];
+ struct {
+ unsigned int zero, at;
+ unsigned int v0, v1;
+ unsigned int a0, a1, a2, a3;
+ unsigned int t0, t1, t2, t3, t4, t5, t6, t7;
+ unsigned int s0, s1, s2, s3, s4, s5, s6, s7;
+ unsigned int t8, t9;
+ unsigned int k0, k1;
+ unsigned int gp, sp, fp, ra;
+
+ unsigned int cop0r14;
+ unsigned int hi;
+ unsigned int lo;
+ unsigned int cop0r12;
+ unsigned int cop0r13;
+ };
+ };
+ int _reserved[9];
+} TCB;
+
+typedef struct { // Process control block
+ TCB *thread;
+} PCB;
+
typedef struct { // Device control block
char *name;
int flags;
@@ -182,6 +211,9 @@ void ChangeClearRCnt(int t, int m);
int Exec(struct EXEC *exec, int argc, char **argv);
void FlushCache(void);
+// Misc functions
+int GetSystemInfo(int index);
+
void _boot(void);
#ifdef __cplusplus
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;
diff --git a/libpsn00b/psxapi/sys/getsysteminfo.s b/libpsn00b/psxapi/sys/getsysteminfo.s
new file mode 100644
index 0000000..60c1d43
--- /dev/null
+++ b/libpsn00b/psxapi/sys/getsysteminfo.s
@@ -0,0 +1,10 @@
+.set noreorder
+
+.section .text
+
+.global GetSystemInfo
+.type GetSystemInfo, @function
+GetSystemInfo:
+ addiu $t2, $0, 0xa0
+ jr $t2
+ addiu $t1, $0, 0xb4 \ No newline at end of file