From 7302ac05fd8743b8a02e72a2150afc16202db9b3 Mon Sep 17 00:00:00 2001 From: cadmic Date: Sun, 2 Jun 2024 17:12:57 -0700 Subject: [PATCH] Match MSL C IO functions (#156) * Match __va_arg.c * Match libc IO functions * Fix warnings * Fix mq-j symbols --- config/mq-j/symbols.txt | 6 +- configure.py | 18 ++-- include/dolphin/dvd.h | 2 - include/dolphin/exi.h | 4 + include/dolphin/vi/vitypes.h | 1 - libc/ansi_files.h | 30 ------ libc/console_io.h | 7 +- libc/ctype.h | 55 ++++------- libc/file_struc.h | 14 --- libc/stdarg.h | 12 +-- libc/stddef.h | 10 +- libc/stdio.h | 2 - src/dolphin/exi/EXIUart.c | 8 +- src/libc/ansi_files.c | 5 +- src/libc/buffer_io.c | 35 +++++++ src/libc/ctype.c | 181 +++++++++++++++++++++++++++++++++++ src/libc/direct_io.c | 108 +++++++++++++++++++++ src/libc/errno.c | 1 + src/libc/mbstring.c | 15 +++ src/libc/misc_io.c | 1 + src/libc/trigf.c | 2 +- src/libc/uart_console_io.c | 54 +++++++++++ src/libc/wchar_io.c | 27 ++++++ src/runtime/__va_arg.c | 52 ++++++++++ 24 files changed, 523 insertions(+), 127 deletions(-) delete mode 100644 libc/ansi_files.h delete mode 100644 libc/file_struc.h create mode 100644 src/libc/buffer_io.c create mode 100644 src/libc/ctype.c create mode 100644 src/libc/direct_io.c create mode 100644 src/libc/errno.c create mode 100644 src/libc/mbstring.c create mode 100644 src/libc/misc_io.c create mode 100644 src/libc/uart_console_io.c create mode 100644 src/libc/wchar_io.c create mode 100644 src/runtime/__va_arg.c diff --git a/config/mq-j/symbols.txt b/config/mq-j/symbols.txt index c64fb89..e92086f 100644 --- a/config/mq-j/symbols.txt +++ b/config/mq-j/symbols.txt @@ -1726,9 +1726,9 @@ lbl_800D1ED8 = .rodata:0x800D1ED8; // type:object size:0x18 data:4byte __constants = .rodata:0x800D1EF0; // type:object size:0x18 data:4byte lbl_800D1F08 = .rodata:0x800D1F08; // type:object size:0x48 data:double lbl_800D1F50 = .rodata:0x800D1F50; // type:object size:0x40 -lbl_800D1F90 = .rodata:0x800D1F90; // type:object size:0x100 -lbl_800D2090 = .rodata:0x800D2090; // type:object size:0x100 -lbl_800D2190 = .rodata:0x800D2190; // type:object size:0x100 +__ctype_map = .rodata:0x800D1F90; // type:object size:0x100 +__lower_map = .rodata:0x800D2090; // type:object size:0x100 +__upper_map = .rodata:0x800D2190; // type:object size:0x100 @stringBase0 = .rodata:0x800D2290; // type:object size:0xE scope:local data:string_table bp = .rodata:0x800D22A0; // type:object size:0x10 scope:local data:double ...rodata.0 = .rodata:0x800D22A0; // type:label scope:local diff --git a/configure.py b/configure.py index 9f254a2..da8d7be 100755 --- a/configure.py +++ b/configure.py @@ -455,7 +455,7 @@ config.libs = [ "runtime", [ Object(MatchingFor("mq-j", "ce-j", "ce-u"), "runtime/__mem.c"), - Object(NonMatching, "runtime/__va_arg.c"), + Object(MatchingFor("mq-j", "ce-j", "ce-u"), "runtime/__va_arg.c"), Object(MatchingFor("mq-j", "ce-j", "ce-u"), "runtime/global_destructor_chain.c"), Object(MatchingFor("mq-j", "ce-j", "ce-u"), "runtime/runtime.c"), ] @@ -466,22 +466,22 @@ config.libs = [ Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/abort_exit.c"), Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/ansi_files.c"), Object(NonMatching, "libc/ansi_fp.c", extra_cflags=["-inline noauto"]), - Object(NonMatching, "libc/buffer_io.c"), + Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/buffer_io.c"), Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/critical_regions.ppc_eabi.c"), - Object(NonMatching, "libc/ctype.c"), - Object(NonMatching, "libc/direct_io.c"), - Object(NonMatching, "libc/errno.c"), - Object(NonMatching, "libc/mbstring.c", extra_cflags=["-inline noauto"]), + Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/ctype.c"), + Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/direct_io.c"), + Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/errno.c"), + Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/mbstring.c"), Object(NonMatching, "libc/mem.c"), Object(NonMatching, "libc/mem_funcs.c"), - Object(NonMatching, "libc/misc_io.c"), + Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/misc_io.c"), Object(NonMatching, "libc/printf.c"), Object(NonMatching, "libc/scanf.c"), Object(NonMatching, "libc/string.c"), Object(NonMatching, "libc/strtoul.c"), - Object(NonMatching, "libc/uart_console_io.c"), + Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/uart_console_io.c"), Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/float.c"), - Object(NonMatching, "libc/wchar_io.c"), + Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/wchar_io.c"), Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/e_asin.c"), Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/e_pow.c"), Object(MatchingFor("mq-j", "ce-j", "ce-u"), "libc/fminmaxdim.c"), diff --git a/include/dolphin/dvd.h b/include/dolphin/dvd.h index 0f04629..95f3a79 100644 --- a/include/dolphin/dvd.h +++ b/include/dolphin/dvd.h @@ -19,9 +19,7 @@ typedef struct DVDQueue DVDQueue; typedef void (*DVDCallback)(s32 result, DVDFileInfo* fileInfo); typedef void (*DVDCBCallback)(s32 result, DVDCommandBlock* block); -typedef void (*DVDLowCallback)(u32 intType); typedef void (*DVDDoneReadCallback)(s32, DVDFileInfo*); -typedef void (*DVDOptionalCommandChecker)(DVDCommandBlock* block, DVDLowCallback callback); struct DVDCommandBlock { /* 0x00 */ DVDCommandBlock* next; diff --git a/include/dolphin/exi.h b/include/dolphin/exi.h index 8407921..afd0d1a 100644 --- a/include/dolphin/exi.h +++ b/include/dolphin/exi.h @@ -82,4 +82,8 @@ char* EXIGetTypeString(u32 type); u32 EXIClearInterrupts(s32 chan, bool exi, bool tc, bool ext); s32 EXIGetID(s32 channel, u32 device, u32* id); +s32 InitializeUART(u32 baudRate); +s32 ReadUARTN(void* buf, u32 length); +s32 WriteUARTN(const void* buf, u32 len); + #endif diff --git a/include/dolphin/vi/vitypes.h b/include/dolphin/vi/vitypes.h index af7f810..38aec9c 100644 --- a/include/dolphin/vi/vitypes.h +++ b/include/dolphin/vi/vitypes.h @@ -20,7 +20,6 @@ typedef void (*VIRetraceCallback)(u32 retraceCount); typedef void (*VIPositionCallback)(s16 x, s16 y); -typedef void (*VIRetraceCallback)(u32 retraceCount); typedef enum VITVMode { VI_TVMODE_NTSC_INT = 0, // VI_TVMODE(VI_NTSC, VI_INTERLACE) diff --git a/libc/ansi_files.h b/libc/ansi_files.h deleted file mode 100644 index 4a1bafe..0000000 --- a/libc/ansi_files.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _DOLPHIN_ANSI_FILES_H -#define _DOLPHIN_ANSI_FILES_H -#include "stdio.h" - -#ifdef __cplusplus -extern "C" { -#endif // ifdef __cplusplus - -#define set_eof(file) \ - do { \ - (file)->state.io_state = __neutral; \ - (file)->state.eof = 1; \ - (file)->buffer_len = 0; \ - } while (0) - -#define set_error(file) \ - do { \ - (file)->state.error = 1; \ - (file)->buffer_len = 0; \ - } while (0) - -int __flush_buffer(FILE* file, size_t* length); -void __prep_buffer(FILE* file); -int __flush_all(); - -#ifdef __cplusplus -}; -#endif // ifdef __cplusplus - -#endif diff --git a/libc/console_io.h b/libc/console_io.h index 45801b5..59b4cf5 100644 --- a/libc/console_io.h +++ b/libc/console_io.h @@ -1,9 +1,10 @@ #ifndef _CONSOLE_IO #define _CONSOLE_IO -#include "file_struc.h" -#include "stddef.h" +#include "stdio.h" -int __write_console(__file_handle handle, unsigned char* buffer, size_t* count, __idle_proc idle_proc); +extern int __read_console(__file_handle handle, unsigned char* buffer, size_t* count, __idle_proc idle_proc); +extern int __write_console(__file_handle handle, unsigned char* buffer, size_t* count, __idle_proc idle_proc); +extern int __close_console(__file_handle file); #endif // _CONSOLE_IO diff --git a/libc/ctype.h b/libc/ctype.h index 5d009f4..9d6d56f 100644 --- a/libc/ctype.h +++ b/libc/ctype.h @@ -1,12 +1,14 @@ #ifndef _CTYPE_H_ #define _CTYPE_H_ +#include "dolphin/types.h" + // eof.h #define EOF -1L -extern unsigned char __ctype_map[]; -extern unsigned char __lower_map[]; -extern unsigned char __upper_map[]; +extern const u8 __ctype_map[]; +extern const u8 __lower_map[]; +extern const u8 __upper_map[]; #define __control_char 0x01 #define __motion_char 0x02 @@ -23,39 +25,22 @@ extern unsigned char __upper_map[]; #define __printable (__graphic | __space_char) #define __whitespace (__motion_char | __space_char) #define __control (__motion_char | __control_char) -#define __zero_fill(c) ((int)(unsigned char)(c)) +#define __zero_fill(c) ((int)(u8)(c)) -#ifndef _CTYPE_INLINE -#define _CTYPE_INLINE static inline -#endif +static inline int isalnum(int c) { return __ctype_map[__zero_fill(c)] & __alphanumeric; } +static inline int isalpha(int c) { return __ctype_map[__zero_fill(c)] & __letter; } +static inline int iscntrl(int c) { return __ctype_map[__zero_fill(c)] & __control; } +static inline int isdigit(int c) { return __ctype_map[__zero_fill(c)] & __digit; } +static inline int isgraph(int c) { return __ctype_map[__zero_fill(c)] & __graphic; } +static inline int islower(int c) { return __ctype_map[__zero_fill(c)] & __lower_case; } +static inline int isprint(int c) { return __ctype_map[__zero_fill(c)] & __printable; } +static inline int ispunct(int c) { return __ctype_map[__zero_fill(c)] & __punctuation; } +static inline int isspace(int c) { return __ctype_map[__zero_fill(c)] & __whitespace; } +static inline int isupper(int c) { return __ctype_map[__zero_fill(c)] & __upper_case; } +static inline int isxdigit(int c) { return __ctype_map[__zero_fill(c)] & __hex_digit; } +static inline int iswblank(int c) { return ((c == (int)L' ') || (c == (int)L'\t')); } -_CTYPE_INLINE -int isalnum(int c) { return __ctype_map[__zero_fill(c)] & __alphanumeric; } -_CTYPE_INLINE -int isalpha(int c) { return __ctype_map[__zero_fill(c)] & __letter; } -_CTYPE_INLINE -int iscntrl(int c) { return __ctype_map[__zero_fill(c)] & __control; } -_CTYPE_INLINE -int isdigit(int c) { return __ctype_map[__zero_fill(c)] & __digit; } -_CTYPE_INLINE -int isgraph(int c) { return __ctype_map[__zero_fill(c)] & __graphic; } -_CTYPE_INLINE -int islower(int c) { return __ctype_map[__zero_fill(c)] & __lower_case; } -_CTYPE_INLINE -int isprint(int c) { return __ctype_map[__zero_fill(c)] & __printable; } -_CTYPE_INLINE -int ispunct(int c) { return __ctype_map[__zero_fill(c)] & __punctuation; } -_CTYPE_INLINE -int isspace(int c) { return __ctype_map[__zero_fill(c)] & __whitespace; } -_CTYPE_INLINE -int isupper(int c) { return __ctype_map[__zero_fill(c)] & __upper_case; } -_CTYPE_INLINE -int isxdigit(int c) { return __ctype_map[__zero_fill(c)] & __hex_digit; } -_CTYPE_INLINE -int tolower(int c) { return ((c == EOF) ? EOF : ((int)__lower_map[__zero_fill(c)])); } -_CTYPE_INLINE -int toupper(int c) { return ((c == EOF) ? EOF : ((int)__upper_map[__zero_fill(c)])); } -_CTYPE_INLINE -int iswblank(int c) { return ((c == (int)L' ') || (c == (int)L'\t')); } +int toupper(int c); +int tolower(int c); #endif diff --git a/libc/file_struc.h b/libc/file_struc.h deleted file mode 100644 index 57da701..0000000 --- a/libc/file_struc.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _FILE_STRUC -#define _FILE_STRUC - -#include "stddef.h" - -typedef unsigned long __file_handle; -typedef unsigned long fpos_t; - -typedef void (*__idle_proc)(void); -typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __idle_proc idle_proc); -typedef int (*__io_proc)(__file_handle file, unsigned char* buff, size_t* count, __idle_proc idle_proc); -typedef int (*__close_proc)(__file_handle file); - -#endif // _FILE_STRUC diff --git a/libc/stdarg.h b/libc/stdarg.h index d03d626..6ab7b44 100644 --- a/libc/stdarg.h +++ b/libc/stdarg.h @@ -1,7 +1,6 @@ #ifndef _STDARG_H_ #define _STDARG_H_ -#ifdef __MWERKS__ typedef struct { char gpr; char fpr; @@ -11,9 +10,7 @@ typedef struct { } __va_list[1]; typedef __va_list va_list; -#ifndef __MWERKS__ -extern void __builtin_va_info(va_list*); -#endif +extern void __builtin_va_info(void*); void* __va_arg(va_list v_list, unsigned char type); @@ -21,11 +18,4 @@ void* __va_arg(va_list v_list, unsigned char type); #define va_arg(ap, t) (*((t*)__va_arg(ap, _var_arg_typeof(t)))) #define va_end(ap) (void)0 -#else -typedef __builtin_va_list va_list; -#define va_start(v, l) __builtin_va_start(v, l) -#define va_end(v) __builtin_va_end(v) -#define va_arg(v, l) __builtin_va_arg(v, l) -#endif - #endif diff --git a/libc/stddef.h b/libc/stddef.h index 2607edd..bfb0216 100644 --- a/libc/stddef.h +++ b/libc/stddef.h @@ -1,15 +1,9 @@ #ifndef _STDDEF_H_ #define _STDDEF_H_ -#define offsetof(type, member) ((size_t) & (((type*)0)->member)) - -/* These break 1.2.5 */ -// typedef __typeof__(sizeof(0)) size_t; -// typedef __typeof__((char*)0 - (char*)0) ptrdiff_t; typedef unsigned long size_t; typedef long ptrdiff_t; -#ifndef NULL -#define NULL 0L -#endif + +#define offsetof(type, member) ((size_t) & (((type*)0)->member)) #endif diff --git a/libc/stdio.h b/libc/stdio.h index 69193b8..6b0e7fc 100644 --- a/libc/stdio.h +++ b/libc/stdio.h @@ -13,9 +13,7 @@ typedef unsigned long __file_handle; typedef unsigned long fpos_t; -#ifndef __cplusplus typedef unsigned short wchar_t; -#endif enum __io_modes { __read = 1, diff --git a/src/dolphin/exi/EXIUart.c b/src/dolphin/exi/EXIUart.c index 5a625e5..6af3ba2 100644 --- a/src/dolphin/exi/EXIUart.c +++ b/src/dolphin/exi/EXIUart.c @@ -81,7 +81,7 @@ void __OSEnableBarnacle(s32 chan, u32 dev) { } } -u32 InitializeUART(u32 baudRate) { +s32 InitializeUART(u32 baudRate) { if (BarnacleEnabled == EXI_MAGIC) { return 0; } @@ -97,7 +97,7 @@ u32 InitializeUART(u32 baudRate) { } } -u32 ReadUARTN(void* bytes, unsigned long length) { return 4; } +s32 ReadUARTN(void* buf, u32 len) { return 4; } static inline int QueueLength(void) { u32 cmd; @@ -117,7 +117,7 @@ static inline int QueueLength(void) { return 16 - (int)((cmd >> 24) & 0xFF); } -u32 WriteUARTN(const void* buf, unsigned long len) { +s32 WriteUARTN(const void* buf, u32 len) { u32 cmd; #if VERSION > MQ_E bool interrupt; @@ -126,7 +126,7 @@ u32 WriteUARTN(const void* buf, unsigned long len) { long xLen; char* ptr; bool locked; - u32 error; + s32 error; if (Enabled != EXI_MAGIC) { return 2; diff --git a/src/libc/ansi_files.c b/src/libc/ansi_files.c index 0c2538a..197073b 100644 --- a/src/libc/ansi_files.c +++ b/src/libc/ansi_files.c @@ -1,9 +1,6 @@ +#include "console_io.h" #include "stdio.h" -extern int __read_console(__file_handle file, unsigned char* buff, size_t* count, __idle_proc idle_proc); -extern int __write_console(__file_handle file, unsigned char* buff, size_t* count, __idle_proc idle_proc); -extern int __close_console(__file_handle file); - FILE __files[3] = { { 0, diff --git a/src/libc/buffer_io.c b/src/libc/buffer_io.c new file mode 100644 index 0000000..ac16974 --- /dev/null +++ b/src/libc/buffer_io.c @@ -0,0 +1,35 @@ +#include "buffer_io.h" + +int __flush_buffer(FILE* file, size_t* bytes_flushed) { + size_t len; + int res; + + len = file->buffer_ptr - file->buffer; + if (len != 0) { + file->buffer_len = len; + if (file->mode.binary_io) { + (void)(file->mode.binary_io != 0); + } + res = file->write_proc(file->handle, file->buffer, &file->buffer_len, file->idle_proc); + if (bytes_flushed != NULL) { + *bytes_flushed = file->buffer_len; + } + if (res != 0) { + return res; + } + file->position += file->buffer_len; + } + + file->buffer_ptr = file->buffer; + file->buffer_len = file->buffer_size; + file->buffer_len -= file->position & file->buffer_alignment; + file->buffer_pos = file->position; + return 0; +} + +void __prep_buffer(FILE* file) { + file->buffer_ptr = file->buffer; + file->buffer_len = file->buffer_size; + file->buffer_len -= file->position & file->buffer_alignment; + file->buffer_pos = file->position; +} diff --git a/src/libc/ctype.c b/src/libc/ctype.c new file mode 100644 index 0000000..8f8e8f9 --- /dev/null +++ b/src/libc/ctype.c @@ -0,0 +1,181 @@ +#include "ctype.h" +#include "dolphin/types.h" + +const u8 __ctype_map[256] = { + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __motion_char, + __motion_char, + __motion_char, + __motion_char, + __motion_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __control_char, + __space_char, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __hex_digit | __digit, + __hex_digit | __digit, + __hex_digit | __digit, + __hex_digit | __digit, + __hex_digit | __digit, + __hex_digit | __digit, + __hex_digit | __digit, + __hex_digit | __digit, + __hex_digit | __digit, + __hex_digit | __digit, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __hex_digit | __upper_case, + __hex_digit | __upper_case, + __hex_digit | __upper_case, + __hex_digit | __upper_case, + __hex_digit | __upper_case, + __hex_digit | __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __upper_case, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __hex_digit | __lower_case, + __hex_digit | __lower_case, + __hex_digit | __lower_case, + __hex_digit | __lower_case, + __hex_digit | __lower_case, + __hex_digit | __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __lower_case, + __punctuation, + __punctuation, + __punctuation, + __punctuation, + __control_char, +}; + +const u8 __lower_map[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, + 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x5B, 0x5C, 0x5D, 0x5E, + 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, + 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, + 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, + 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, + 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, + 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +const u8 __upper_map[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, + 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, + 0x5F, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, + 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, + 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, + 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, + 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, + 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + +int toupper(int c) { + if (c == EOF) { + return EOF; + } + return __upper_map[c & 0xFF]; +} + +int tolower(int c) { + if (c == EOF) { + return EOF; + } + return __lower_map[c & 0xFF]; +} diff --git a/src/libc/direct_io.c b/src/libc/direct_io.c new file mode 100644 index 0000000..4e9a69c --- /dev/null +++ b/src/libc/direct_io.c @@ -0,0 +1,108 @@ +#include "buffer_io.h" +#include "stdio.h" +#include "string.h" +#include "wchar.h" + +extern void __stdio_atexit(void); + +size_t fwrite(const void* buffer, size_t memb_size, size_t num_memb, FILE* file) { + unsigned char* cur_ptr; + size_t num_bytes, rem_bytes, bytes_written; + int res, buff; + + if (fwide(file, 0) == 0) { + fwide(file, -1); + } + + rem_bytes = memb_size * num_memb; + + if (rem_bytes == 0 || file->state.error || file->mode.file_kind == __closed_file) { + return 0; + } + + if ((int)file->mode.file_kind == __console_file) { + __stdio_atexit(); + } + + buff = (!file->mode.binary_io || (int)file->mode.file_kind == __unavailable_file || file->mode.buffer_mode == 2 || + file->mode.buffer_mode == 1); + + if (file->state.io_state == __neutral && file->mode.io_mode & 2) { + file->state.io_state = __writing; + __prep_buffer(file); + } + + if (file->state.io_state != __writing) { + file->state.error = 1; + file->buffer_len = 0; + return 0; + } + + cur_ptr = (u8*)buffer; + bytes_written = 0; + + if (rem_bytes && (file->buffer_ptr != file->buffer || buff)) { + file->buffer_len = file->buffer_size - (file->buffer_ptr - file->buffer); + + do { + u8* nw = 0; + num_bytes = file->buffer_len; + + if (num_bytes > rem_bytes) { + num_bytes = rem_bytes; + } + + if (num_bytes != 0) { + memcpy(file->buffer_ptr, cur_ptr, num_bytes); + cur_ptr += num_bytes; + bytes_written += num_bytes; + rem_bytes -= num_bytes; + file->buffer_ptr += num_bytes; + file->buffer_len -= num_bytes; + } + + if (file->buffer_len == 0 && (int)file->mode.file_kind == __unavailable_file) { + bytes_written += rem_bytes; + break; + } + if (file->buffer_len == 0 || (int)file->mode.buffer_mode == 0) { + res = __flush_buffer(file, 0); + + if (res != 0) { + file->state.error = 1; + file->buffer_len = 0; + rem_bytes = 0; + break; + } + } + + } while (rem_bytes && buff); + } + + if (rem_bytes && buff == 0) { + u8* save_buf = (u8*)file->buffer; + size_t save_size = file->buffer_size; + + file->buffer = cur_ptr; + file->buffer_size = rem_bytes; + file->buffer_ptr = cur_ptr + rem_bytes; + + if (__flush_buffer(file, &num_bytes) != 0) { + file->state.error = 1; + file->buffer_len = 0; + } + + bytes_written += num_bytes; + + file->buffer = save_buf; + file->buffer_size = save_size; + __prep_buffer(file); + file->buffer_len = 0; + } + + if (file->mode.buffer_mode != 2) { + file->buffer_len = 0; + } + + return (bytes_written + memb_size - 1) / memb_size; +} diff --git a/src/libc/errno.c b/src/libc/errno.c new file mode 100644 index 0000000..6e7bb62 --- /dev/null +++ b/src/libc/errno.c @@ -0,0 +1 @@ +int errno; diff --git a/src/libc/mbstring.c b/src/libc/mbstring.c new file mode 100644 index 0000000..0bc2aa4 --- /dev/null +++ b/src/libc/mbstring.c @@ -0,0 +1,15 @@ +#include "stdlib.h" + +size_t wcstombs(char* dest, const wchar_t* src, size_t max) { + size_t i; + wchar_t c; + + for (i = 0; i < max; i++) { + c = *src++; + *dest++ = (char)c; + if ((char)c == '\0') { + break; + } + } + return i; +} diff --git a/src/libc/misc_io.c b/src/libc/misc_io.c new file mode 100644 index 0000000..f0a410f --- /dev/null +++ b/src/libc/misc_io.c @@ -0,0 +1 @@ +void __stdio_atexit(void) {} diff --git a/src/libc/trigf.c b/src/libc/trigf.c index 2843ca7..0084dfd 100644 --- a/src/libc/trigf.c +++ b/src/libc/trigf.c @@ -87,4 +87,4 @@ void __sinit_trigf_c(void) { __four_over_pi_m1[3] = tmp_float[3]; } -CTORS extern void* const __sinit_trigf_c_reference = __sinit_trigf_c; +CTORS void* const __sinit_trigf_c_reference = __sinit_trigf_c; diff --git a/src/libc/uart_console_io.c b/src/libc/uart_console_io.c new file mode 100644 index 0000000..b401e93 --- /dev/null +++ b/src/libc/uart_console_io.c @@ -0,0 +1,54 @@ +#include "console_io.h" +#include "dolphin/exi.h" +#include "dolphin/types.h" + +int __init_console(void) { + static bool initialized; + int res = 0; + + if (!initialized) { + res = InitializeUART(0xE100); + if (res == 0) { + initialized = true; + } + } + return res; +} + +int __close_console(__file_handle file) { return 0; } + +int __write_console(__file_handle handle, unsigned char* buffer, size_t* count, __idle_proc idle_proc) { + if (__init_console() != 0) { + return 1; + } + + if (WriteUARTN(buffer, *count) != 0) { + *count = 0; + return 1; + } + + return 0; +} + +int __read_console(__file_handle handle, unsigned char* buffer, size_t* count, __idle_proc idle_proc) { + int res; + size_t len; + + if (__init_console() != 0) { + return 1; + } + + len = *count; + res = 0; + *count = 0; + while (*count <= len && res == 0) { + res = ReadUARTN(buffer, 1); + *count += 1; + if (*buffer == '\r') { + break; + } + buffer += 1; + } + + return (res == 0 ? 0 : 1) & 0xFF; +} diff --git a/src/libc/wchar_io.c b/src/libc/wchar_io.c new file mode 100644 index 0000000..7c971f6 --- /dev/null +++ b/src/libc/wchar_io.c @@ -0,0 +1,27 @@ +#include "stdio.h" + +int fwide(FILE* stream, int mode) { + int orientation; + + if (stream->mode.file_kind == __closed_file) { + return 0; + } + + orientation = stream->mode.file_orientation; + switch (orientation) { + case __unoriented: + if (mode > 0) { + stream->mode.file_orientation = __wide_oriented; + } else if (mode < 0) { + stream->mode.file_orientation = __char_oriented; + } + + return mode; + + case __wide_oriented: + return 1; + + case __char_oriented: + return -1; + } +} diff --git a/src/runtime/__va_arg.c b/src/runtime/__va_arg.c new file mode 100644 index 0000000..1f3e98f --- /dev/null +++ b/src/runtime/__va_arg.c @@ -0,0 +1,52 @@ +#include "dolphin/types.h" +#include "stdarg.h" + +void* __va_arg(va_list v_list, unsigned char type) { + char* addr; + char* reg = &v_list->gpr; + s32 g_reg = v_list->gpr; + s32 maxsize = 8; + s32 size = 4; + s32 increment = 1; + s32 even = 0; + s32 fpr_offset = 0; + s32 regsize = 4; + + if (type == 4) { + size = 16; + addr = v_list->input_arg_area; + addr = (char*)(((u32)(addr) + ((size)-1)) & ~((size)-1)); + v_list->input_arg_area = addr + size; + return addr; + } + if (type == 3) { + reg = &v_list->fpr; + g_reg = v_list->fpr; + size = 8; + fpr_offset = 32; + regsize = 8; + } + if (type == 2) { + size = 8; + maxsize--; + if (g_reg & 1) { + even = 1; + } + increment = 2; + } + if (g_reg < maxsize) { + g_reg += even; + addr = v_list->reg_save_area + fpr_offset + (g_reg * regsize); + *reg = g_reg + increment; + } else { + *reg = 8; + addr = v_list->input_arg_area; + addr = (char*)(((u32)(addr) + ((size)-1)) & ~((size)-1)); + v_list->input_arg_area = addr + size; + } + if (type == 0) { + addr = *((char**)addr); + } + + return addr; +}