diff --git a/Makefile b/Makefile index 50ea6b79..7e8f1b50 100755 --- a/Makefile +++ b/Makefile @@ -113,7 +113,7 @@ C_DEFINES := $(foreach d,$(DEFINES),-D$(d)) DEF_INC_CFLAGS := $(foreach i,$(INCLUDE_DIRS),-I$(i)) $(C_DEFINES) ASFLAGS = -mtune=vr4300 -march=vr4300 -mabi=32 $(foreach d,$(DEFINES),--defsym $(d)) -INCLUDE_CFLAGS := -I include -I $(BUILD_DIR) -I src -I . +INCLUDE_CFLAGS := -I include -I $(BUILD_DIR) -I src -I . -I include/libc CFLAGS = -c -Wab,-r4300_mul -non_shared -G 0 -Xcpluscomm -Xfullwarn -signed $(OPT_FLAGS) $(MIPSISET) $(INCLUDE_CFLAGS) $(DEF_INC_CFLAGS) LDFLAGS = undefined_syms.txt -T $(LD_SCRIPT) -Map $(BUILD_DIR)/dkr.map diff --git a/include/libc/math.h b/include/libc/math.h new file mode 100644 index 00000000..8cea459b --- /dev/null +++ b/include/libc/math.h @@ -0,0 +1,13 @@ +#ifndef MATH_H +#define MATH_H + +#define M_PI 3.14159265358979323846 + +float sinf(float); +double sin(double); +float cosf(float); +double cos(double); + +float sqrtf(float); + +#endif diff --git a/include/stdarg.h b/include/libc/stdarg.h similarity index 100% rename from include/stdarg.h rename to include/libc/stdarg.h diff --git a/include/libc/stddef.h b/include/libc/stddef.h new file mode 100644 index 00000000..7e72a7bb --- /dev/null +++ b/include/libc/stddef.h @@ -0,0 +1,10 @@ +#ifndef STDDEF_H +#define STDDEF_H + +#include "PR/ultratypes.h" + +#ifndef offsetof +#define offsetof(st, m) ((size_t)&(((st *)0)->m)) +#endif + +#endif diff --git a/include/libc/stdio.h b/include/libc/stdio.h new file mode 100644 index 00000000..1cd4d0a3 --- /dev/null +++ b/include/libc/stdio.h @@ -0,0 +1,6 @@ +#ifndef STDIO_H +#define STDIO_H + +extern int sprintf(char *s, const char *fmt, ...); + +#endif diff --git a/include/libc/stdlib.h b/include/libc/stdlib.h new file mode 100644 index 00000000..c23b4542 --- /dev/null +++ b/include/libc/stdlib.h @@ -0,0 +1,19 @@ +#ifndef STDLIB_H +#define STDLIB_H + +typedef struct lldiv_t +{ + long long quot; + long long rem; +} lldiv_t; + +typedef struct ldiv_t +{ + long quot; + long rem; +} ldiv_t; + +lldiv_t lldiv(long long num, long long denom); +ldiv_t ldiv(long num, long denom); + +#endif diff --git a/include/libc/string.h b/include/libc/string.h new file mode 100644 index 00000000..183409eb --- /dev/null +++ b/include/libc/string.h @@ -0,0 +1,10 @@ +#ifndef STRING_H +#define STRING_H + +#include "PR/ultratypes.h" + +void *memcpy(void *dst, const void *src, size_t size); +size_t strlen(const char *str); +char *strchr(const char *str, s32 ch); + +#endif diff --git a/lib/asm/non_matchings/unknown_0D43F0/_Printf.s b/lib/asm/non_matchings/unknown_0D43F0/_Printf.s index 19c52165..129032ee 100644 --- a/lib/asm/non_matchings/unknown_0D43F0/_Printf.s +++ b/lib/asm/non_matchings/unknown_0D43F0/_Printf.s @@ -1,12 +1,3 @@ -.rdata -glabel D_800E96C0 -.asciz "hlL" -glabel D_800E96C4 -.asciz " +-#0" -.ascii "\0\0" # padding -glabel D_800E96CC -.word 1, 2, 4, 8, 16, 0 - .text glabel _Printf /* 0D4B10 800D3F10 27BDFF20 */ addiu $sp, $sp, -0xe0 @@ -17,9 +8,9 @@ glabel _Printf /* 0D4B24 800D3F24 AFB40028 */ sw $s4, 0x28($sp) /* 0D4B28 800D3F28 AFB30024 */ sw $s3, 0x24($sp) /* 0D4B2C 800D3F2C AFA700EC */ sw $a3, 0xec($sp) -/* 0D4B30 800D3F30 3C15800E */ lui $s5, %hi(D_800E48E4) # $s5, 0x800e -/* 0D4B34 800D3F34 3C16800F */ lui $s6, %hi(D_800E96C4) # $s6, 0x800f -/* 0D4B38 800D3F38 3C17800E */ lui $s7, %hi(D_800E48C0) # $s7, 0x800e +/* 0D4B30 800D3F30 3C15800E */ lui $s5, %hi(_zeroes) # $s5, 0x800e +/* 0D4B34 800D3F34 3C16800F */ lui $s6, %hi(flags_str) # $s6, 0x800f +/* 0D4B38 800D3F38 3C17800E */ lui $s7, %hi(_spaces) # $s7, 0x800e /* 0D4B3C 800D3F3C 00C03825 */ move $a3, $a2 /* 0D4B40 800D3F40 00A09825 */ move $s3, $a1 /* 0D4B44 800D3F44 0080A025 */ move $s4, $a0 @@ -29,9 +20,9 @@ glabel _Printf /* 0D4B54 800D3F54 AFB00018 */ sw $s0, 0x18($sp) /* 0D4B58 800D3F58 AFA600E8 */ sw $a2, 0xe8($sp) /* 0D4B5C 800D3F5C AFA000D4 */ sw $zero, 0xd4($sp) -/* 0D4B60 800D3F60 26F748C0 */ addiu $s7, %lo(D_800E48C0) # addiu $s7, $s7, 0x48c0 -/* 0D4B64 800D3F64 26D696C4 */ addiu $s6, %lo(D_800E96C4) # addiu $s6, $s6, -0x693c -/* 0D4B68 800D3F68 26B548E4 */ addiu $s5, %lo(D_800E48E4) # addiu $s5, $s5, 0x48e4 +/* 0D4B60 800D3F60 26F748C0 */ addiu $s7, %lo(_spaces) # addiu $s7, $s7, 0x48c0 +/* 0D4B64 800D3F64 26D696C4 */ addiu $s6, %lo(flags_str) # addiu $s6, $s6, -0x693c +/* 0D4B68 800D3F68 26B548E4 */ addiu $s5, %lo(_zeroes) # addiu $s5, $s5, 0x48e4 /* 0D4B6C 800D3F6C 241E000A */ li $fp, 10 .L800D3F70: /* 0D4B70 800D3F70 90F00000 */ lbu $s0, ($a3) @@ -80,9 +71,9 @@ glabel _Printf .L800D4004: /* 0D4C04 800D4004 0216C823 */ subu $t9, $s0, $s6 /* 0D4C08 800D4008 00197080 */ sll $t6, $t9, 2 -/* 0D4C0C 800D400C 3C0F800F */ lui $t7, %hi(D_800E96CC) # $t7, 0x800f +/* 0D4C0C 800D400C 3C0F800F */ lui $t7, %hi(flags_arr) # $t7, 0x800f /* 0D4C10 800D4010 01EE7821 */ addu $t7, $t7, $t6 -/* 0D4C14 800D4014 8DEF96CC */ lw $t7, %lo(D_800E96CC)($t7) +/* 0D4C14 800D4014 8DEF96CC */ lw $t7, %lo(flags_arr)($t7) /* 0D4C18 800D4018 8FB800D8 */ lw $t8, 0xd8($sp) /* 0D4C1C 800D401C 26520001 */ addiu $s2, $s2, 1 /* 0D4C20 800D4020 02C02025 */ move $a0, $s6 @@ -97,7 +88,7 @@ glabel _Printf /* 0D4C40 800D4040 2402002A */ li $v0, 42 /* 0D4C44 800D4044 8FB800EC */ lw $t8, 0xec($sp) /* 0D4C48 800D4048 144E0011 */ bne $v0, $t6, .L800D4090 -/* 0D4C4C 800D404C 3C04800F */ lui $a0, %hi(D_800E96C0) # $a0, 0x800f +/* 0D4C4C 800D404C 3C04800F */ lui $a0, %hi(length_str) # $a0, 0x800f /* 0D4C50 800D4050 270F0003 */ addiu $t7, $t8, 3 /* 0D4C54 800D4054 2401FFFC */ li $at, -4 /* 0D4C58 800D4058 01E1C824 */ and $t9, $t7, $at @@ -192,7 +183,7 @@ glabel _Printf /* 0D4D94 800D4194 8FB900CC */ lw $t9, 0xcc($sp) .L800D4198: /* 0D4D98 800D4198 0C033871 */ jal strchr -/* 0D4D9C 800D419C 248496C0 */ addiu $a0, %lo(D_800E96C0) # addiu $a0, $a0, -0x6940 +/* 0D4D9C 800D419C 248496C0 */ addiu $a0, %lo(length_str) # addiu $a0, $a0, -0x6940 /* 0D4DA0 800D41A0 10400005 */ beqz $v0, .L800D41B8 /* 0D4DA4 800D41A4 27B000A8 */ addiu $s0, $sp, 0xa8 /* 0D4DA8 800D41A8 92590000 */ lbu $t9, ($s2) diff --git a/lib/src/alCopy.c b/lib/src/alCopy.c new file mode 100644 index 00000000..b68d0ebc --- /dev/null +++ b/lib/src/alCopy.c @@ -0,0 +1,9 @@ +/* The comment below is needed for this file to be picked up by generate_ld */ +/* RAM_POS: 0x800D3820 */ + +#include "types.h" +#include "macros.h" + +s32 D_800E48A0[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +GLOBAL_ASM("lib/asm/non_matchings/unknown_0D43F0/alCopy.s") \ No newline at end of file diff --git a/lib/src/printf.c b/lib/src/printf.c new file mode 100644 index 00000000..b03d03a9 --- /dev/null +++ b/lib/src/printf.c @@ -0,0 +1,218 @@ +/* The comment below is needed for this file to be picked up by generate_ld */ +/* RAM_POS: 0x800D38A0 */ + +#include "types.h" +#include "macros.h" +#include "libultra_internal.h" +#include +#include +#include "printf.h" + +const char length_str[] = "hlL"; +const char flags_str[] = " +-#0"; +const u32 flags_arr[] = { FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0 }; +char _spaces[] = " "; +char _zeroes[] = "00000000000000000000000000000000"; + +#ifdef NON_MATCHING +static void _Putfld(printf_struct *a0, va_list *args, u8 type, u8 *buff) { + a0->part1_len = a0->num_leading_zeros = a0->part2_len = a0->num_mid_zeros = a0->part3_len = + a0->num_trailing_zeros = 0; + + switch (type) { + + case 'c': + buff[a0->part1_len++] = va_arg(*args, u32); + break; + + case 'd': + case 'i': + if (a0->length == 'l') { + a0->value.s64 = va_arg(*args, s32); + } else if (a0->length == 'L') { + a0->value.s64 = va_arg(*args, s64); + } else { + a0->value.s64 = va_arg(*args, s32); + } + + if (a0->length == 'h') { + a0->value.s64 = (s16) a0->value.s64; + } + + if (a0->value.s64 < 0) { + buff[a0->part1_len++] = '-'; + } else if (a0->flags & FLAGS_PLUS) { + buff[a0->part1_len++] = '+'; + } else if (a0->flags & FLAGS_SPACE) { + buff[a0->part1_len++] = ' '; + } + + a0->buff = (char *) &buff[a0->part1_len]; + + _Litob(a0, type); + break; + + case 'x': + case 'X': + case 'u': + case 'o': + if (a0->length == 'l') { + a0->value.s64 = va_arg(*args, s32); + } else if (a0->length == 'L') { + a0->value.s64 = va_arg(*args, s64); + } else { + a0->value.s64 = va_arg(*args, s32); + } + + if (a0->length == 'h') { + a0->value.s64 = (u16) a0->value.s64; + } else if (a0->length == 0) { + a0->value.s64 = (u32) a0->value.s64; + } + + if (a0->flags & FLAGS_HASH) { + buff[a0->part1_len++] = '0'; + if (type == 'x' || type == 'X') { + + buff[a0->part1_len++] = type; + } + } + a0->buff = (char *) &buff[a0->part1_len]; + _Litob(a0, type); + break; + + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + //... okay? + a0->value.f64 = a0->length == 'L' ? va_arg(*args, f64) : va_arg(*args, f64); + + if (a0->value.u16 & 0x8000) { + buff[a0->part1_len++] = '-'; + } else { + if (a0->flags & FLAGS_PLUS) { + buff[a0->part1_len++] = '+'; + } else if (a0->flags & FLAGS_SPACE) { + buff[a0->part1_len++] = ' '; + } + } + + a0->buff = (char *) &buff[a0->part1_len]; + _Ldtob(a0, type); + break; + + case 'n': + if (a0->length == 'h') { + *(va_arg(*args, u16 *)) = a0->size; + } else if (a0->length == 'l') { + *va_arg(*args, u32 *) = a0->size; + } else if (a0->length == 'L') { + *va_arg(*args, u64 *) = a0->size; + } else { + *va_arg(*args, u32 *) = a0->size; + } + break; + + case 'p': + a0->value.s64 = (intptr_t) va_arg(*args, void *); + a0->buff = (char *) &buff[a0->part1_len]; + _Litob(a0, 'x'); + break; + + case 's': + a0->buff = va_arg(*args, char *); + a0->part2_len = strlen(a0->buff); + if (a0->precision >= 0 && a0->part2_len > a0->precision) { + a0->part2_len = a0->precision; + } + break; + + case '%': + buff[a0->part1_len++] = '%'; + break; + + default: + buff[a0->part1_len++] = type; + break; + } +} +#else +GLOBAL_ASM("lib/asm/non_matchings/unknown_0D43F0/_Putfld.s") +#endif + +#ifdef NON_MATCHING +s32 _Printf(char *(*prout)(char *, const char *, size_t), char *dst, const char *fmt, va_list args) { + printf_struct sp78; + const u8 *fmt_ptr; + u8 c; + const char *flag_index; + u8 sp4c[0x20]; // probably a buffer? + s32 sp48, sp44, sp40, sp3c, sp38, sp34, sp30, sp2c, sp28, sp24; + sp78.size = 0; + while (TRUE) { + fmt_ptr = (u8 *) fmt; + while ((c = *fmt_ptr++) > 0) { + if (c == '%') { + fmt_ptr--; + break; + } + } + _PROUT(dst, fmt, fmt_ptr - (u8 *) fmt); + if (c == 0) { + return sp78.size; + } + fmt = (char *) ++fmt_ptr; + sp78.flags = 0; + for (; (flag_index = strchr(flags_str, *fmt_ptr)) != NULL; fmt_ptr++) { + sp78.flags |= flags_arr[flag_index - flags_str]; + } + if (*fmt_ptr == '*') { + sp78.width = va_arg(args, s32); + if (sp78.width < 0) { + sp78.width = -sp78.width; + sp78.flags |= FLAGS_MINUS; + } + fmt_ptr++; + } else { + ATOI(sp78.width, fmt_ptr); + } + if (*fmt_ptr != '.') { + sp78.precision = -1; + } else { + fmt_ptr++; + if (*fmt_ptr == '*') { + sp78.precision = va_arg(args, s32); + fmt_ptr++; + } else { + ATOI(sp78.precision, fmt_ptr); + } + } + if (strchr(length_str, *fmt_ptr) != NULL) { + sp78.length = *fmt_ptr++; + } else { + sp78.length = 0; + } + + if (sp78.length == 'l' && *fmt_ptr == 'l') { + sp78.length = 'L'; + fmt_ptr++; + } + _Putfld(&sp78, &args, *fmt_ptr, sp4c); + sp78.width -= sp78.part1_len + sp78.num_leading_zeros + sp78.part2_len + sp78.num_mid_zeros + + sp78.part3_len + sp78.num_trailing_zeros; + _PAD(sp44, sp78.width, sp48, _spaces, !(sp78.flags & FLAGS_MINUS)); + _PROUT(dst, (char *) sp4c, sp78.part1_len); + _PAD(sp3c, sp78.num_leading_zeros, sp40, _zeroes, 1); + _PROUT(dst, sp78.buff, sp78.part2_len); + _PAD(sp34, sp78.num_mid_zeros, sp38, _zeroes, 1); + _PROUT(dst, (char *) (&sp78.buff[sp78.part2_len]), sp78.part3_len) + _PAD(sp2c, sp78.num_trailing_zeros, sp30, _zeroes, 1); + _PAD(sp24, sp78.width, sp28, _spaces, sp78.flags & FLAGS_MINUS); + fmt = (char *) fmt_ptr + 1; + } +} +#else +GLOBAL_ASM("lib/asm/non_matchings/unknown_0D43F0/_Printf.s") +#endif diff --git a/lib/src/printf.h b/lib/src/printf.h new file mode 100644 index 00000000..a60ae22d --- /dev/null +++ b/lib/src/printf.h @@ -0,0 +1,59 @@ +#ifndef _PRINTF_H_ +#define _PRINTF_H_ +#include "types.h" +#include + +typedef struct +{ + union { + /* 00 */ s64 s64; + u64 u64; + f64 f64; + u32 u32; + u16 u16; + } value; + /* 08 */ char *buff; + /* 0c */ s32 part1_len; + /* 10 */ s32 num_leading_zeros; + /* 14 */ s32 part2_len; + /* 18 */ s32 num_mid_zeros; + /* 1c */ s32 part3_len; + /* 20 */ s32 num_trailing_zeros; + /* 24 */ s32 precision; + /* 28 */ s32 width; + /* 2c */ u32 size; + /* 30 */ u32 flags; + /* 34 */ u8 length; +} printf_struct; + +#define ATOI(i, a) \ + for (i = 0; *a >= '0' && *a <= '9'; a++) \ + if (i < 999) \ + i = *a + i * 10 - '0'; +#define _PROUT(dst, fmt, _size) \ + if (_size > 0) { \ + dst = prout(dst, fmt, _size); \ + if (dst != 0) \ + sp78.size += _size; \ + else \ + return sp78.size; \ + } +#define _PAD(i, m, c, src, extracond) \ + if (extracond && m > 0) \ + for (i = m; i > 0; i -= c) { \ + if ((u32) i > 32) \ + c = 32; \ + else \ + c = i; \ + _PROUT(dst, src, c); \ + } + +#define FLAGS_SPACE 1 +#define FLAGS_PLUS 2 +#define FLAGS_MINUS 4 +#define FLAGS_HASH 8 +#define FLAGS_ZERO 16 +s32 _Printf(char *(*prout)(char *, const char *, size_t), char *dst, const char *fmt, va_list args); +void _Litob(printf_struct *args, u8 type); +void _Ldtob(printf_struct *args, u8 type); +#endif diff --git a/lib/src/unknown_0D43F0.c b/lib/src/unknown_0D43F0.c deleted file mode 100644 index af16b492..00000000 --- a/lib/src/unknown_0D43F0.c +++ /dev/null @@ -1,16 +0,0 @@ -/* The comment below is needed for this file to be picked up by generate_ld */ -/* RAM_POS: 0x800D3820 */ - -#include "types.h" -#include "macros.h" - -s32 D_800E48A0[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -GLOBAL_ASM("lib/asm/non_matchings/unknown_0D43F0/alCopy.s") - - -char D_800E48C0[36] = " "; -char D_800E48E4[32] = "00000000000000000000000000000000"; - -GLOBAL_ASM("lib/asm/non_matchings/unknown_0D43F0/_Putfld.s") -GLOBAL_ASM("lib/asm/non_matchings/unknown_0D43F0/_Printf.s") \ No newline at end of file diff --git a/tools/python/generate_ld.py b/tools/python/generate_ld.py index 9d36482d..cb65a750 100644 --- a/tools/python/generate_ld.py +++ b/tools/python/generate_ld.py @@ -21,7 +21,8 @@ DATA_DIR = ROOT_DIR + '/data' BUILD_DIR = 'build/' + VERSION LATE_DATA_FILES = [ - BUILD_DIR + '/lib/src/unknown_0D43F0.o', + BUILD_DIR + '/lib/src/alCopy.o', + BUILD_DIR + '/lib/src/printf.o', BUILD_DIR + '/lib/src/os/osTimer.o', BUILD_DIR + '/lib/src/unknown_0D3020.o' ]