diff --git a/configure.py b/configure.py index 8f1608937..3aad0ac72 100644 --- a/configure.py +++ b/configure.py @@ -249,6 +249,32 @@ "-inline auto", ] +cflags_msl_gc13_runtime = [ + *cflags_base, + "-use_lmw_stmw on", + "-str reuse,pool,readonly", + "-common off", + "-inline deferred,auto", + "-char signed", + "-lang=c", +] + +cflags_msl_runtime_c = [ + *cflags_base, + "-use_lmw_stmw on", + "-str reuse,pool,readonly", + "-common off", + "-inline deferred,auto", + "-fp_contract off", + "-char signed", + "-lang=c", +] + +cflags_msl_runtime_cpp = [ + *cflags_runtime, + "-lang=c++", +] + # dolphin library flags cflags_dolphin = [ *cflags_base, @@ -841,66 +867,96 @@ def MatchingFor(*versions): "Runtime.PPCEABI.H", [], [ - Object(NonMatching, "Runtime/__mem.c", extra_cflags=["-inline on, deferred"]), + Object(Matching, "Runtime/__mem.c"), Object(Matching, "Runtime/__va_arg.c"), - Object(NonMatching, "Runtime/global_destructor_chain.c"), - Object(NonMatching, "Runtime/New.cp"), - Object(NonMatching, "Runtime/NMWException.cp"), + Object(Matching, "Runtime/global_destructor_chain.c"), + Object( + Matching, + "Runtime/New.cp", + mw_version="GC/2.6", + cflags=[ + flag + for flag in cflags_runtime + if flag not in ("-RTTI off", "-Cpp_exceptions off", "-inline auto", "-str reuse,pool,readonly") + ] + + ["-Cpp_exceptions on", "-RTTI on", "-inline auto,deferred", "-str reuse,nopool,readonly"], + ), + Object( + Matching, + "Runtime/NMWException.cp", + mw_version="GC/2.0p1", + cflags=[ + flag + for flag in cflags_runtime + if flag not in ("-RTTI off", "-Cpp_exceptions off") + ] + + ["-Cpp_exceptions on", "-RTTI on", "-inline auto,deferred"], + ), Object(Matching, "Runtime/CPlusLibPPC.cp"), - Object(NonMatching, "Runtime/ptmf.c"), - Object(NonMatching, "Runtime/runtime.c"), - Object(NonMatching, "Runtime/__init_cpp_exceptions.cpp"), - Object(NonMatching, "Runtime/Gecko_ExceptionPPC.cp"), - Object(NonMatching, "Runtime/GCN_mem_alloc.c"), + Object(Matching, "Runtime/ptmf.c"), + Object(Matching, "Runtime/runtime.c"), + Object(Matching, "Runtime/__init_cpp_exceptions.cpp"), + Object( + Matching, + "Runtime/Gecko_ExceptionPPC.cp", + cflags=[ + flag + for flag in cflags_runtime + if flag not in ("-RTTI off", "-Cpp_exceptions off", "-str reuse,pool,readonly") + ] + + ["-Cpp_exceptions on", "-RTTI on", "-str reuse,nopool,readonly"], + extab_padding=[0x02, 0x55], + ), + Object(Matching, "Runtime/GCN_mem_alloc.c", extra_cflags=["-str reuse,nopool,readonly"]), ] ), mslLib( "MSL_C.PPCEABI.H", ["-str pool", "-opt level=0, peephole, schedule, nospace", "-inline off", "-sym on"], [ - Object(NonMatching, "MSL_C/PPC_EABI/abort_exit.c"), - Object(NonMatching, "MSL_C/MSL_Common/alloc.c"), - Object(NonMatching, "MSL_C/MSL_Common/ansi_files.c"), - Object(NonMatching, "MSL_C/MSL_Common_Embedded/ansi_fp.c"), - Object(NonMatching, "MSL_C/MSL_Common/arith.c"), - Object(NonMatching, "MSL_C/MSL_Common/bsearch.c"), - Object(NonMatching, "MSL_C/MSL_Common/buffer_io.c"), + Object(Matching, "MSL_C/PPC_EABI/abort_exit.c", cflags=cflags_runtime), + Object(Matching, "MSL_C/MSL_Common/alloc.c", cflags=cflags_msl_runtime_c), + Object(Matching, "MSL_C/MSL_Common/ansi_files.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), + Object(Matching, "MSL_C/MSL_Common_Embedded/ansi_fp.c", cflags=cflags_msl_runtime_c), + Object(Matching, "MSL_C/MSL_Common/arith.c", cflags=cflags_runtime), + Object(Matching, "MSL_C/MSL_Common/bsearch.c"), + Object(Matching, "MSL_C/MSL_Common/buffer_io.c", cflags=cflags_runtime), Object(Matching, "MSL_C/PPC_EABI/critical_regions.gamecube.c"), - Object(NonMatching, "MSL_C/MSL_Common/ctype.c"), - Object(NonMatching, "MSL_C/MSL_Common/direct_io.c"), + Object(Matching, "MSL_C/MSL_Common/ctype.c", cflags=cflags_runtime), + Object(Matching, "MSL_C/MSL_Common/direct_io.c", cflags=cflags_runtime), Object(Matching, "MSL_C/MSL_Common/errno.c"), - Object(NonMatching, "MSL_C/MSL_Common/file_io.c"), - Object(NonMatching, "MSL_C/MSL_Common/FILE_POS.C"), - Object(NonMatching, "MSL_C/MSL_Common/locale.c"), - Object(NonMatching, "MSL_C/MSL_Common/mbstring.c"), - Object(NonMatching, "MSL_C/MSL_Common/mem.c"), - Object(NonMatching, "MSL_C/MSL_Common/mem_funcs.c"), - Object(NonMatching, "MSL_C/MSL_Common/misc_io.c"), - Object(NonMatching, "MSL_C/MSL_Common/printf.c"), - Object(NonMatching, "MSL_C/MSL_Common/qsort.c"), - Object(NonMatching, "MSL_C/MSL_Common/rand.c"), - Object(NonMatching, "MSL_C/MSL_Common/scanf.c"), - Object(NonMatching, "MSL_C/MSL_Common/signal.c"), - Object(NonMatching, "MSL_C/MSL_Common/string.c"), - Object(NonMatching, "MSL_C/MSL_Common/strtold.c"), - Object(NonMatching, "MSL_C/MSL_Common/strtoul.c"), - Object(NonMatching, "MSL_C/MSL_Common/float.c"), - Object(NonMatching, "MSL_C/MSL_Common/char_io.c"), - Object(NonMatching, "MSL_C/MSL_Common/wchar_io.c"), - Object(NonMatching, "MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c") + Object(Matching, "MSL_C/MSL_Common/file_io.c", cflags=cflags_msl_runtime_c + ["-D_MSL_WIDE_CHAR"]), + Object(Matching, "MSL_C/MSL_Common/FILE_POS.C", cflags=cflags_msl_runtime_cpp), + Object(Matching, "MSL_C/MSL_Common/locale.c"), + Object(Matching, "MSL_C/MSL_Common/mbstring.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), + Object(Matching, "MSL_C/MSL_Common/mem.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), + Object(Matching, "MSL_C/MSL_Common/mem_funcs.c", cflags=cflags_runtime), + Object(Matching, "MSL_C/MSL_Common/misc_io.c", cflags=cflags_runtime), + Object(Matching, "MSL_C/MSL_Common/printf.c", mw_version="GC/2.0p1", cflags=cflags_msl_runtime_c), + Object(Matching, "MSL_C/MSL_Common/qsort.c", cflags=cflags_msl_runtime_c), + Object(Matching, "MSL_C/MSL_Common/rand.c", cflags=cflags_runtime), + Object(Matching, "MSL_C/MSL_Common/scanf.c", cflags=cflags_runtime + ["-inline deferred"]), + Object(Matching, "MSL_C/MSL_Common/signal.c", cflags=cflags_msl_gc13_runtime), + Object(Matching, "MSL_C/MSL_Common/string.c", cflags=cflags_runtime), + Object(Matching, "MSL_C/MSL_Common/strtold.c", cflags=cflags_msl_runtime_c), + Object(Matching, "MSL_C/MSL_Common/strtoul.c", cflags=cflags_runtime), + Object(Matching, "MSL_C/MSL_Common/float.c"), + Object(Matching, "MSL_C/MSL_Common/char_io.c", cflags=cflags_runtime), + Object(Matching, "MSL_C/MSL_Common/wchar_io.c", cflags=cflags_runtime), + Object(Matching, "MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c", cflags=cflags_runtime) ] ), mslLib( "fdlibm.PPCEABI.H", [], [ - Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c"), - Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_atan2.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_exp.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_fmod.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_log.c"), - Object(NonMatching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c"), + Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/e_rem_pio2.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/k_cos.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/k_rem_pio2.c"), @@ -923,52 +979,57 @@ def MatchingFor(*versions): Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_fmod.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_log.c"), Object(Matching, "MSL_C/MSL_Common_Embedded/Math/Double_precision/w_pow.c"), - Object(NonMatching, "MSL_C/PPC_EABI/math_ppc.c"), + Object(Matching, "MSL_C/PPC_EABI/math_ppc.c"), ] ), trkLib( "TRK_MINNOW_DOLPHIN", [ - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mainloop.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubevent.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubassrt.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubinit.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msg.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msgbuf.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/serpoll.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/dispatch.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msghndlr.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/support.c"), + Object(Matching, "debugger/embedded/MetroTRK/Portable/mainloop.c"), + Object(Matching, "debugger/embedded/MetroTRK/Portable/nubevent.c"), + Object(Matching, "debugger/embedded/MetroTRK/Portable/nubassrt.c"), + Object(Matching, "debugger/embedded/MetroTRK/Portable/nubinit.c", extra_cflags=["-sdata 0", "-sdata2 0"]), + Object(Matching, "debugger/embedded/MetroTRK/Portable/msg.c", mw_version="GC/1.3", cflags=cflags_trk), + Object(Matching, "debugger/embedded/MetroTRK/Portable/msgbuf.c", mw_version="GC/1.3", cflags=cflags_trk), + Object(Matching, "debugger/embedded/MetroTRK/Portable/serpoll.c", extra_cflags=["-sdata 0", "-sdata2 0"]), + Object(Matching, "debugger/embedded/MetroTRK/Portable/dispatch.c", extra_cflags=["-sdata 0", "-sdata2 0"]), + Object(Matching, "debugger/embedded/MetroTRK/Portable/msghndlr.c", mw_version="GC/2.6", cflags=cflags_trk), + Object(Matching, "debugger/embedded/MetroTRK/Portable/support.c"), Object(Matching, "debugger/embedded/MetroTRK/Portable/mutex_TRK.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/notify.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/main_TRK.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mem_TRK.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/string_TRK.c"), + Object(Matching, "debugger/embedded/MetroTRK/Portable/notify.c"), + Object(Matching, "debugger/embedded/MetroTRK/Portable/main_TRK.c", extra_cflags=["-sdata 0", "-sdata2 0"]), + Object(Matching, "debugger/embedded/MetroTRK/Portable/mem_TRK.c"), + Object(Matching, "debugger/embedded/MetroTRK/Portable/string_TRK.c"), Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), - Object(NonMatching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c"), + Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/__exception.s"), + Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c", mw_version="GC/2.6", cflags=[*cflags_trk, "-gccinc", "-common off"]), Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.s"), Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/usr_put.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c"), + Object(Matching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c", mw_version="GC/2.6", cflags=cflags_trk), + Object(Matching, "debugger/embedded/MetroTRK/Os/dolphin/usr_put.c"), + Object(Matching, "debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c", mw_version="GC/2.6", cflags=cflags_trk), Object(Matching, "debugger/embedded/MetroTRK/Os/dolphin/targcont.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/target_options.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Export/mslsupp.c"), + Object(Matching, "debugger/embedded/MetroTRK/Os/dolphin/target_options.c", extra_cflags=["-sdata 0", "-sdata2 0"]), + Object(Matching, "debugger/embedded/MetroTRK/Os/dolphin/UDP_Stubs.c"), + Object( + Matching, + "debugger/embedded/MetroTRK/Export/mslsupp.c", + mw_version="GC/2.6", + cflags=cflags_trk, + ), - Object(NonMatching, "gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c"), - Object(NonMatching, "gamedev/cust_connection/utils/common/CircleBuffer.c"), - Object(NonMatching, "gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c"), - Object(NonMatching, "gamedev/cust_connection/utils/common/MWTrace.c"), - Object(NonMatching, "gamedev/cust_connection/utils/gc/MWCriticalSection_gc.cpp"), + Object(Matching, "gamedev/cust_connection/cc/exi2/GCN/EXI2_DDH_GCN/main.c"), + Object(Matching, "gamedev/cust_connection/utils/common/CircleBuffer.c"), + Object(Matching, "gamedev/cust_connection/cc/exi2/GCN/EXI2_GDEV_GCN/main.c"), + Object(Matching, "gamedev/cust_connection/utils/common/MWTrace.c"), + Object(Matching, "gamedev/cust_connection/utils/gc/MWCriticalSection_gc.cpp"), ] ), mslLib( "MSL_C.PPCEABI.bare.H", [], [ - Object(NonMatching, "MSL_C/MSL_Common/extras.c") + Object(Matching, "MSL_C/MSL_Common/extras.c") ] ), RenderWareLib( @@ -1176,6 +1237,9 @@ def link_order_callback(module_id: int, objects: List[str]) -> List[str]: ProgressCategory("bink", "Bink SDK"), ] config.progress_each_module = args.verbose +config.progress_report_args = [ + "--deduplicate", +] if args.mode == "configure": # Write build.ninja and objdiff.json diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h index 1ded27ed9..ffd2d443c 100644 --- a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h @@ -11,7 +11,7 @@ extern "C" { int fseek(FILE *stream, fpos_t offset, int whence); int _fseek(FILE *stream, fpos_t offset, int whence); int ftell(FILE *stream); - int _ftell(FILE *stream); + fpos_t _ftell(FILE *stream); #ifdef __cplusplus }; diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h index d649b4936..6b4d6f9cf 100644 --- a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h @@ -4,7 +4,9 @@ #include "types.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" +FILE* fopen(const char* filename, const char* mode); int fclose(FILE* file); int fflush(FILE* file); +int __get_file_modes(const char* mode, file_modes* modes); #endif diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h index d44317150..a286ff755 100644 --- a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h @@ -60,6 +60,7 @@ MATH_INLINE int __fpclassifyf(f32 x) return 4; } +#ifndef MATH_API_SKIP_FPCLASSIFYD MATH_INLINE int __fpclassifyd(f64 x) { switch (__HI(x) & 0x7ff00000) @@ -83,6 +84,7 @@ MATH_INLINE int __fpclassifyd(f64 x) } return 4; } +#endif #define fpclassify(x) \ ((sizeof(x) == sizeof(float)) ? __fpclassifyf((float)(x)) : __fpclassifyd((double)(x))) diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h index 7ef4118f9..52fc544d0 100644 --- a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h @@ -1,8 +1,11 @@ #ifndef _MSL_MATH_API_H #define _MSL_MATH_API_H +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" + extern void (*__stdio_exit)(void); +void clearerr(FILE* stream); void __stdio_atexit(); #endif diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h index ce88b029b..f36e4dc6c 100644 --- a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MSL_C/MSL_Common/printf.h @@ -5,7 +5,7 @@ #include "PowerPC_EABI_Support/MSL_C/MSL_Common/file_struc.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" -void printf(const char*, ...); +int printf(const char*, ...); // printf_s int fprintf(FILE*, const char* format, ...); // fprintf_s diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/Portable/mem_TRK.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/Portable/mem_TRK.h new file mode 100644 index 000000000..7a21801a1 --- /dev/null +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/Portable/mem_TRK.h @@ -0,0 +1,17 @@ +#ifndef METROTRK_PORTABLE_MEM_TRK_H +#define METROTRK_PORTABLE_MEM_TRK_H + +#include "dolphin/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void* TRK_memset(void* dst, int val, size_t n); +void* TRK_memcpy(void* dst, const void* src, size_t n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h index 4bb4788f7..7a533bd57 100644 --- a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/MetroTRK/trk.h @@ -166,7 +166,6 @@ void MWTRACE(u8, char*, ...); //////// SUPPORT FUNCTIONS ///////// DSError TRKRequestSend(); -u32 TRKAccessFile(u32, u32, u32*, u8*); //////////////////////////////////// ///// SERIAL POLLING FUNCTIONS ///// diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h index 692055e35..a4b2d42c1 100644 --- a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/NMWException.h @@ -2,7 +2,7 @@ #define _NMWEXCEPTION #include "types.h" -#include "exception" //#include +#include "PowerPC_EABI_Support/Runtime/exception.h" #ifdef __cplusplus extern "C" { @@ -20,12 +20,22 @@ typedef struct CatchInfo { void* stacktop; } CatchInfo; +typedef struct DestructorChain { + struct DestructorChain* next; + void* destructor; + void* object; +} DestructorChain; + +struct __eti_init_info; + void __unregister_fragment(int fragmentID); -// struct __eti_init_info* info -int __register_fragment(void* info, char* TOC); +int __register_fragment(struct __eti_init_info* info, char* TOC); void* __register_global_object(void* object, void* destructor, void* regmem); void __destroy_global_chain(void); extern char __throw_catch_compare(const char* throwtype, const char* catchtype, s32* offset_result); +extern void __end__catch(CatchInfo* catchinfo); +extern void __throw(char* throwtype, void* location, void* dtor); +extern void __unexpected(CatchInfo* catchinfo); #ifdef __cplusplus } diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/New.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/New.h new file mode 100644 index 000000000..a36a92e1a --- /dev/null +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/New.h @@ -0,0 +1 @@ +void operator delete(void* arg0) throw(); diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h index 198d2b446..f9ccf7e8f 100644 --- a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/__mem.h @@ -1,16 +1,18 @@ -#ifndef RUNTIME_MEM_H -#define RUNTIME_MEM_H -#include "macros.h" -#include "types.h" +#ifndef _RUNTIME_MEM_H +#define _RUNTIME_MEM_H + +#include "stddef.h" + #ifdef __cplusplus extern "C" { #endif -DECL_SECTION(".init") void* memcpy(void* dest, const void* src, size_t n); -DECL_SECTION(".init") void __fill_mem(void* dest, int val, size_t count); -DECL_SECTION(".init") void* memset(void* dest, int val, size_t count); +__declspec(section ".init") void* memset(void* dest, int val, size_t count); +__declspec(section ".init") void __fill_mem(void* dest, int val, size_t count); +__declspec(section ".init") void* memcpy(void* dest, const void* src, size_t n); #ifdef __cplusplus } #endif + #endif diff --git a/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/exception.h b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/exception.h new file mode 100644 index 000000000..dad23d18f --- /dev/null +++ b/src/PowerPC_EABI_Support/include/PowerPC_EABI_Support/Runtime/exception.h @@ -0,0 +1,53 @@ +#ifndef _EXCEPTION +#define _EXCEPTION + +#ifdef __cplusplus + +namespace std { + +class exception { +public: + exception() {} + virtual ~exception() {} + virtual const char* what() const { return "exception"; } +}; + +class bad_exception : public exception { +public: + bad_exception() {} + virtual ~bad_exception() {} + virtual const char* what() const { return "bad_exception"; } +}; + +typedef void (*unexpected_handler)(); +unexpected_handler set_unexpected(unexpected_handler handler); +void unexpected(); + +typedef void (*terminate_handler)(); +terminate_handler set_terminate(terminate_handler handler); +void terminate(); + +} // namespace std + +using std::exception; +using std::bad_exception; +using std::terminate; +using std::terminate_handler; +using std::set_terminate; +using std::unexpected; +using std::unexpected_handler; +using std::set_unexpected; + +#else + +typedef void (*unexpected_handler)(); +unexpected_handler set_unexpected(unexpected_handler handler); +void unexpected(); + +typedef void (*terminate_handler)(); +terminate_handler set_terminate(terminate_handler handler); +void terminate(); + +#endif // __cplusplus + +#endif diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C index 5abd23c4c..e3750387b 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C @@ -13,7 +13,7 @@ #define SEEK_CUR (1) #define SEEK_END (2) -int _ftell(FILE* file) +inline fpos_t _ftell(FILE* file) { int charsInUndoBuffer = 0; int position; @@ -49,14 +49,15 @@ int _ftell(FILE* file) return (position); } -int ftell(FILE* stream) +int fseek(FILE* stream, fpos_t offset, int whence) { - int retval; - + fpos_t start; + int code; + start = offset; __begin_critical_region(stdin_access); - retval = (long)_ftell(stream); + code = _fseek(stream, start, whence); // 0 if successful, -1 if error __end_critical_region(stdin_access); - return retval; + return code; } int _fseek(FILE* file, fpos_t offset, int whence) @@ -132,13 +133,12 @@ int _fseek(FILE* file, fpos_t offset, int whence) return 0; } -int fseek(FILE* stream, fpos_t offset, int whence) +int ftell(FILE* stream) { - fpos_t start; - int code; - start = offset; + int retval; + __begin_critical_region(stdin_access); - code = _fseek(stream, start, whence); // 0 if successful, -1 if error + retval = (long)_ftell(stream); __end_critical_region(stdin_access); - return code; + return retval; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c index e3dae74c4..e74fc428b 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/alloc.c @@ -1,5 +1,21 @@ #include "PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include + +#define Block_link msl_alloc_Block_link +#define Block_report msl_alloc_Block_report +#define SubBlock_report msl_alloc_SubBlock_report +#define link msl_alloc_link +#define __init_pool_obj msl_alloc___init_pool_obj +#define __report_on_pool_heap msl_alloc___report_on_pool_heap +#define __report_on_heap msl_alloc___report_on_heap +#define __msize msl_alloc___msize +#define __pool_alloc_clear msl_alloc___pool_alloc_clear +#define malloc msl_alloc_malloc +#define free msl_alloc_free +#define calloc msl_alloc_calloc +#define __pool_free_all msl_alloc___pool_free_all +#define __malloc_free_all msl_alloc___malloc_free_all typedef struct Block { @@ -93,11 +109,13 @@ typedef struct mem_pool_obj } mem_pool_obj; -mem_pool_obj __malloc_pool; -static int initialized = 0; - static SubBlock* SubBlock_merge_prev(SubBlock*, SubBlock**); static void SubBlock_merge_next(SubBlock*, SubBlock**); +static void SubBlock_construct(SubBlock*, unsigned long, Block*, int, int); +static SubBlock* SubBlock_split(SubBlock*, unsigned long); +static void FixBlock_construct(FixBlock*, FixBlock*, FixBlock*, unsigned long, FixSubBlock*, unsigned long); +static void Block_unlink(Block*, SubBlock*); +void Block_link(Block*, SubBlock*); static const unsigned long fix_pool_sizes[] = { 4, 12, 20, 36, 52, 68 }; @@ -134,14 +152,154 @@ static const unsigned long fix_pool_sizes[] = { 4, 12, 20, 36, 52, 68 }; (_sb = (SubBlock*)((char*)(ths) + 16)), \ SubBlock_is_free(_sb) && SubBlock_size(_sb) == Block_size((ths)) - 24 -void Block_construct(void) +#define FORCE_DONT_INLINE \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0; \ + (void*)0 + +void Block_construct(Block* ths, unsigned long size) +{ + SubBlock* sb = (SubBlock*)((char*)ths + sizeof(Block)); + + ths->size = size | 3; + *(unsigned long*)((char*)ths + size - 8) = ths->size; + sb->block = (Block*)((unsigned long)ths | 1); + sb->size = size - 24; + *(unsigned long*)((char*)sb + (size - 24) - sizeof(unsigned long)) = size - 24; + ths->max_size = size - 24; + Block_start(ths) = 0; + + Block_link(ths, sb); +} + +static void Block_unlink(Block* block, SubBlock* sb) { - // UNUSED FUNCTION + SubBlock** st; + unsigned long tag; + unsigned long tag_size; + + tag = sb->size; + sb->size = tag | 2; + tag_size = tag & ~7; + *(unsigned long*)((char*)sb + tag_size) |= 4; + + st = &Block_start(block); + if (*st == sb) + { + *st = sb->next; + } + if (*st == sb) + { + *st = 0; + block->max_size = 0; + } + else + { + sb->next->prev = sb->prev; + sb->prev->next = sb->next; + } } -void Block_subBlock(void) +SubBlock* Block_subBlock(Block* ths, unsigned long size) { - // UNUSED FUNCTION + SubBlock* sb; + SubBlock* start; + unsigned long sb_size; + unsigned long max_size; + + start = Block_start(ths); + if (start == 0) + { + ths->max_size = 0; + return 0; + } + + sb = start; + sb_size = SubBlock_size(sb); + max_size = sb_size; + + while (sb_size < size) + { + sb = sb->next; + sb_size = SubBlock_size(sb); + if (max_size < sb_size) + { + max_size = sb_size; + } + if (sb == start) + { + ths->max_size = max_size; + return 0; + } + } + + if (sb_size - size >= 0x50) + { + SubBlock_split(sb, size); + } + + Block_start(ths) = sb->next; + Block_unlink(ths, sb); + + return sb; } void Block_link(Block* ths, SubBlock* sb) @@ -170,24 +328,54 @@ void Block_link(Block* ths, SubBlock* sb) ths->max_size = SubBlock_size(*st); } -void Block_unlink(void) -{ - // UNUSED FUNCTION -} - void Block_report(void) { // UNUSED FUNCTION } -void SubBlock_construct(void) +static void SubBlock_construct(SubBlock* ths, unsigned long size, Block* bp, int prev_alloc, int this_alloc) { - // UNUSED FUNCTION + ths->block = (Block*)((unsigned long)bp | 0x1); + ths->size = size; + if (prev_alloc) + { + ths->size |= 0x4; + } + if (this_alloc) + { + ths->size |= 0x2; + *(unsigned long*)((char*)ths + size) |= 0x4; + } + else + { + *(unsigned long*)((char*)ths + size - sizeof(unsigned long)) = size; + } } -void SubBlock_split(void) +static SubBlock* SubBlock_split(SubBlock* ths, unsigned long sz) { - // UNUSED FUNCTION + unsigned long origsize; + int isfree; + int isprevalloc; + SubBlock* np; + Block* bp; + + origsize = SubBlock_size(ths); + isfree = SubBlock_is_free(ths); + isprevalloc = ths->size & 0x04; + np = (SubBlock*)((char*)ths + sz); + bp = SubBlock_block(ths); + + SubBlock_construct(ths, sz, bp, isprevalloc, !isfree); + SubBlock_construct(np, origsize - sz, bp, !isfree, !isfree); + if (isfree) + { + np->next = ths->next; + np->next->prev = np; + np->prev = ths; + ths->next = np; + } + return np; } static SubBlock* SubBlock_merge_prev(SubBlock* ths, SubBlock** start) @@ -289,19 +477,133 @@ static Block* __unlink(__mem_pool_obj* pool_obj, Block* bp) return result; } -void link_new_block(void) +Block* link_new_block(__mem_pool_obj* pool_obj, unsigned long size) { - // UNUSED FUNCTION + Block* block; + + size = (size + 0x1f) & ~7; + if (size < 0x10000) + { + size = 0x10000; + } + + block = (Block*)__sys_alloc(size); + if (block == 0) + { + return 0; + } + + Block_construct(block, size); + + if (pool_obj->start_ != 0) + { + block->prev = pool_obj->start_->prev; + block->prev->next = block; + block->next = pool_obj->start_; + pool_obj->start_->prev = block; + pool_obj->start_ = block; + } + else + { + pool_obj->start_ = block; + block->prev = block; + block->next = block; + } + + return block; } -void allocate_from_var_pools(void) +void* allocate_from_var_pools(__mem_pool_obj* pool_obj, unsigned long size) { - // UNUSED FUNCTION + Block* bp; + SubBlock* sb; + + size = (size + 0xf) & ~7; + if (size < 0x50) + { + size = 0x50; + } + + bp = pool_obj->start_ != 0 ? pool_obj->start_ : link_new_block(pool_obj, size); + + if (bp == 0) + { + return 0; + } + + do + { + if (size <= bp->max_size) + { + sb = Block_subBlock(bp, size); + if (sb != 0) + { + pool_obj->start_ = bp; + goto done; + } + } + + bp = bp->next; + } while (bp != pool_obj->start_); + + bp = link_new_block(pool_obj, size); + if (bp == 0) + { + return 0; + } + + sb = Block_subBlock(bp, size); +done: + return (char*)sb + 8; } -void soft_allocate_from_var_pools(void) +void* soft_allocate_from_var_pools(Block** start_ptr, unsigned long size, unsigned long* max_free_size) { - // UNUSED FUNCTION + Block* bp; + SubBlock* sb; + + size = (size + 0xf) & ~7; + if (size < 0x50) + { + size = 0x50; + } + + *max_free_size = 0; + bp = *start_ptr; + + if (bp == 0) + { + return 0; + } + + do + { + if (size <= bp->max_size) + { + sb = Block_subBlock(bp, size); + if (sb != 0) + { + *start_ptr = bp; + goto found; + } + } + + if (bp->max_size > 8) + { + unsigned long free_size = bp->max_size - 8; + if (*max_free_size < free_size) + { + *max_free_size = free_size; + } + } + + bp = bp->next; + } while (bp != *start_ptr); + + return 0; + +found: + return (char*)sb + 8; } static void deallocate_from_var_pools(__mem_pool_obj* pool_obj, void* ptr) @@ -319,9 +621,37 @@ static void deallocate_from_var_pools(__mem_pool_obj* pool_obj, void* ptr) } } -void FixBlock_construct(void) +static void FixBlock_construct( + FixBlock* ths, FixBlock* prev, FixBlock* next, unsigned long index, FixSubBlock* chunk, unsigned long chunk_size +) { - // UNUSED FUNCTION + unsigned long fixSubBlock_size; + unsigned long n; + unsigned long k; + + ths->prev_ = prev; + ths->next_ = next; + prev->next_ = ths; + next->prev_ = ths; + ths->client_size_ = fix_pool_sizes[index]; + fixSubBlock_size = fix_pool_sizes[index] + 4; + n = chunk_size / fixSubBlock_size; + { + char* p = (char*)chunk; + char* np; + + for (k = 0; k < n - 1; k++) + { + np = p + fixSubBlock_size; + ((FixSubBlock*)p)->block_ = ths; + ((FixSubBlock*)p)->next_ = (FixSubBlock*)np; + p = np; + } + ((FixSubBlock*)p)->block_ = ths; + ((FixSubBlock*)p)->next_ = 0; + } + ths->start_ = (FixSubBlock*)((char*)ths + 0x14); + ths->n_allocated_ = 0; } void __init_pool_obj(__mem_pool* pool_obj) @@ -342,9 +672,87 @@ static __mem_pool* get_malloc_pool(void) return &protopool; } -void allocate_from_fixed_pools(void) +void* allocate_from_fixed_pools(__mem_pool_obj* pool_obj, unsigned long size) { - // UNUSED FUNCTION + unsigned long i = 0; + FixStart* fs; + + while (size > fix_pool_sizes[i]) + { + ++i; + } + + fs = &pool_obj->fix_start[i]; + + if ((fs->head_ == 0) || (fs->head_->start_ == 0)) + { + const unsigned long* pool_sizes = fix_pool_sizes; + unsigned long n = 0xFEC / (pool_sizes[i] + 4); + unsigned long max_n; + void* block; + unsigned long max_free_size; + unsigned long msize; + + if (n > 0x100) + { + n = 0x100; + } + + max_n = n; + + while (n >= 10) + { + block = soft_allocate_from_var_pools(&pool_obj->start_, n * (pool_sizes[i] + 4) + 0x14, &max_free_size); + if (block != 0) + { + break; + } + + if (max_free_size > 0x14) + { + n = (max_free_size - 0x14) / (pool_sizes[i] + 4); + } + else + { + n = 0; + } + } + + if ((block == 0) && (n < max_n)) + { + block = allocate_from_var_pools(pool_obj, max_n * (pool_sizes[i] + 4) + 0x14); + if (block == 0) + { + return 0; + } + } + + msize = __msize_inline(block); + + if (fs->head_ == 0) + { + fs->head_ = (FixBlock*)block; + fs->tail_ = (FixBlock*)block; + } + + FixBlock_construct((FixBlock*)block, fs->tail_, fs->head_, i, (FixSubBlock*)((char*)block + 0x14), msize - 0x14); + fs->head_ = (FixBlock*)block; + } + + { + FixSubBlock* p = fs->head_->start_; + + fs->head_->start_ = p->next_; + ++fs->head_->n_allocated_; + + if (fs->head_->start_ == 0) + { + fs->head_ = fs->head_->next_; + fs->tail_ = fs->tail_->next_; + } + + return (char*)p + 4; + } } void deallocate_from_fixed_pools(__mem_pool_obj* pool_obj, void* ptr, unsigned long size) @@ -429,9 +837,24 @@ void __msize(void) // UNUSED FUNCTION } -void __pool_alloc(void) +void* __pool_alloc(__mem_pool* pool, unsigned long size) { - // UNUSED FUNCTION + if (size == 0) + { + return 0; + } + + if (size > (unsigned long)-0x31) + { + return 0; + } + + if (size <= 68) + { + return allocate_from_fixed_pools((__mem_pool_obj*)pool, size); + } + + return allocate_from_var_pools((__mem_pool_obj*)pool, size); } void __pool_free(__mem_pool* pool, void* ptr) @@ -457,9 +880,77 @@ void __pool_free(__mem_pool* pool, void* ptr) } } -void __pool_realloc(void) +void* __pool_realloc(__mem_pool* pool, void* ptr, unsigned long size) { - // UNUSED FUNCTION + unsigned long current_size; + unsigned long sz; + SubBlock* sb; + void* newptr; + + if (ptr == 0) + { + return __pool_alloc(pool, size); + } + if (size == 0) + { + __pool_free(pool, ptr); + return 0; + } + + current_size = __msize_inline(ptr); + if (size > current_size) + { + if (classify(ptr)) + { + if (size > (unsigned long)-0x31) + { + return 0; + } + + sz = (size + 0xF) & ~7; + if (sz < 0x50) + { + sz = 0x50; + } + + sb = SubBlock_from_pointer(ptr); + SubBlock_merge_next(sb, &Block_start(SubBlock_block(sb))); + if (SubBlock_size(sb) >= sz) + { + if (SubBlock_size(sb) - sz >= 0x50) + { + Block_link(SubBlock_block(sb), SubBlock_split(sb, sz)); + } + return ptr; + } + } + + newptr = __pool_alloc(pool, size); + if (newptr == 0) + { + return 0; + } + memcpy(newptr, ptr, current_size); + __pool_free(pool, ptr); + return newptr; + } + + if (classify(ptr)) + { + size = (size + 0xF) & ~7; + if (size < 0x50) + { + size = 0x50; + } + + sb = SubBlock_from_pointer(ptr); + if (SubBlock_size(sb) - size >= 0x50) + { + Block_link(SubBlock_block(sb), SubBlock_split(sb, size)); + } + } + + return ptr; } void __pool_alloc_clear(void) @@ -479,9 +970,15 @@ void free(void* ptr) __end_critical_region(malloc_pool_access); } -void realloc(void) +void* realloc(void* ptr, size_t size) { - // UNUSED FUNCTION + void* block; + + __begin_critical_region(malloc_pool_access); + block = __pool_realloc(get_malloc_pool(), ptr, size); + __end_critical_region(malloc_pool_access); + + return block; } void calloc(void) @@ -497,4 +994,4 @@ void __pool_free_all(void) void __malloc_free_all(void) { // UNUSED FUNCTION -} \ No newline at end of file +} diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c index 7f4b4708b..98787d7fd 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ansi_files.c @@ -1,15 +1,30 @@ #include "types.h" +#include "string.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#ifndef _IONBF +#define _IONBF 0 +#endif + +#ifndef _IOFBF +#define _IOFBF 2 +#endif + static char stdin_buff[0x100]; static char stdout_buff[0x100]; static char stderr_buff[0x100]; -extern void fclose(FILE*); extern int __read_console(u32, char*, u32*, void*); extern int __write_console(u32, char*, u32*, void*); extern int __close_console(u32); +extern int __position_file(__file_handle file, fpos_t* position, int mode, __ref_con ref_con); +extern int __read_file(__file_handle file, char* buff, size_t* count, __ref_con ref_con); +extern int __write_file(__file_handle file, char* buff, size_t* count, __ref_con ref_con); +extern int __close_file(__file_handle file); +extern int setvbuf(FILE* file, char* buffer, int mode, size_t size); // clang-format off FILE __files[4] = @@ -113,6 +128,64 @@ FILE __files[4] = }; // clang-format on +FILE* __find_unopened_file(void) +{ + FILE* result; + FILE* prev; + FILE* file = __files[2].mNextFile; + + while (file != NULL) { + if (file->mMode.file_kind == __closed_file) { + return file; + } + prev = file; + file = file->mNextFile; + } + + result = (FILE*)malloc(sizeof(FILE)); + if (result == NULL) { + result = NULL; + } else { + memset(result, 0, sizeof(FILE)); + result->mIsDynamicallyAllocated = 1; + prev->mNextFile = result; + return result; + } + + return result; +} + +void __init_file(FILE* file, file_modes mode, unsigned char* buffer, unsigned long buffer_size) +{ + file->mHandle = 0; + file->mMode = mode; + + file->mState.io_state = __neutral; + file->mState.free_buffer = 0; + file->mState.eof = 0; + file->mState.error = 0; + + file->mPosition = 0; + + if (buffer_size != 0) { + setvbuf(file, (char*)buffer, _IOFBF, buffer_size); + } else { + setvbuf(file, NULL, _IONBF, 0); + } + + file->mBufferPtr = file->mBuffer; + file->mBufferLength = 0; + + if (file->mMode.file_kind == __disk_file) { + file->positionFunc = __position_file; + file->readFunc = __read_file; + file->writeFunc = __write_file; + file->closeFunc = __close_file; + } + + file->ref_con = NULL; +} + void __close_all() { FILE* p = &__files[0]; @@ -157,3 +230,26 @@ u32 __flush_all() }; return retval; } + +int __flush_line_buffered_output_files(void) +{ + int result = 0; + FILE* file = &__files[0]; + unsigned char* file_bytes; + unsigned short mode_bits; + + while (file != NULL) { + file_bytes = (unsigned char*)file; + mode_bits = *(unsigned short*)(file_bytes + 4); + if ((((mode_bits >> 6) & 7) != 0) && (((file_bytes[4] >> 1) & 1) != 0) && + (((file_bytes[8] & 0xE0) >> 5) == 1u)) { + if (fflush(file) != 0) { + result = -1; + } + } + + file = file->mNextFile; + } + + return result; +} diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c index fd9e3667a..165c98899 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/arith.c @@ -1,11 +1,14 @@ -#include "PowerPC_EABI_Support/MSL_C/MSL_Common/arith.h" +#include "types.h" -long abs(long x) +typedef struct { - if (x < 0) - return -x; - else - return x; + int quot; + int rem; +} div_t; + +int abs(int n) +{ + return ((n >> 31) ^ n) - (n >> 31); } long labs(long x) diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c index 9e3ed8afb..a2e37df25 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/buffer_io.c @@ -3,51 +3,158 @@ #endif #include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/alloc.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/file_io.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" #include "types.h" -void __convert_from_newlines(char *buffer, size_t *length) +#ifndef _IONBF +#define _IONBF 0 +#endif + +#ifndef _IOLBF +#define _IOLBF 1 +#endif + +#ifndef _IOFBF +#define _IOFBF 2 +#endif + +enum __io_results { __no_io_error, __io_error, __io_EOF }; + +void* malloc(size_t size); +int __load_buffer(FILE* file, size_t* bytes_loaded, int mode); +int __flush_buffer(FILE* file, size_t* bytes_flushed); +void __prep_buffer(FILE* file); + +inline void __convert_from_newlines(char* buffer, size_t* length) {} +inline void __prep_buffer_inline(FILE* file) { - return; + file->mBufferPtr = file->mBuffer; + file->mBufferLength = file->mBufferSize; + file->mBufferLength -= file->mPosition & file->mBufferAlignment; + file->mBufferPosition = file->mPosition; } -void __convert_to_newlines() +int setvbuf(FILE* file, char* buffer, int mode, size_t size) { - // UNUSED + unsigned char* file_bytes; + unsigned short mode_bits; + int io_mode; + + file_bytes = (unsigned char*)file; + mode_bits = *(unsigned short*)(file_bytes + 4); + io_mode = (mode_bits >> 6) & 7; + + if (mode == _IONBF) { + fflush(file); + } + + if (file->mState.io_state != __neutral || io_mode == 0) { + return -1; + } + + if (mode != _IONBF && mode != _IOLBF && mode != _IOFBF) { + return -1; + } + + if (file->mBuffer != NULL && file->mState.free_buffer != 0) { + free(file->mBuffer); + } + + __begin_critical_region(2); + + file->mMode.buffer_mode = mode; + file->mState.free_buffer = 0; + file->mBuffer = (char*)&file->mCharBuffer; + file->mBufferPtr = (char*)&file->mCharBuffer; + file->mBufferSize = 1; + file->mBufferLength = 0; + file->mBufferAlignment = 0; + + if (mode == _IONBF || size < 1) { + *file->mBufferPtr = 0; + __end_critical_region(2); + return 0; + } + + if (buffer == NULL) { + buffer = (char*)malloc(size); + if (buffer == NULL) { + __end_critical_region(2); + return -1; + } + file->mState.free_buffer = 1; + } + + file->mBuffer = buffer; + file->mBufferPtr = file->mBuffer; + file->mBufferSize = size; + file->mBufferAlignment = 0; + + __end_critical_region(2); + return 0; } -void __prep_buffer(FILE *file) +int __flush_buffer(FILE* file, size_t* bytes_flushed) { - file->mBufferPtr = file->mBuffer; - file->mBufferLength = file->mBufferSize; - file->mBufferLength = file->mBufferLength - (file->mPosition & file->mBufferAlignment); - file->mBufferPosition = file->mPosition; - return; + size_t buffer_len; + int ioresult; + + buffer_len = file->mBufferPtr - file->mBuffer; + + if (buffer_len) { + file->mBufferLength = buffer_len; + + if (!file->mMode.binary_io) + __convert_from_newlines(file->mBuffer, (size_t*)&file->mBufferLength); + + ioresult = file->writeFunc(file->mHandle, file->mBuffer, (size_t*)&file->mBufferLength, file->ref_con); + + if (bytes_flushed) + *bytes_flushed = file->mBufferLength; + + if (ioresult) + return ioresult; + + file->mPosition += file->mBufferLength; + } + + __prep_buffer_inline(file); + + return __no_io_error; +} + +int __load_buffer(FILE* file, size_t* bytes_loaded, int mode) +{ + int ioresult; + + __prep_buffer_inline(file); + + if (mode == 1) { + file->mBufferLength = file->mBufferSize; + } + + ioresult = file->readFunc(file->mHandle, file->mBuffer, &file->mBufferLength, file->ref_con); + + if (ioresult == __io_EOF) { + file->mBufferLength = 0; + } + + if (bytes_loaded != NULL) { + *bytes_loaded = file->mBufferLength; + } + + if (ioresult != __no_io_error) { + return ioresult; + } + + file->mPosition += file->mBufferLength; + + return __no_io_error; } -int __flush_buffer(FILE *file, size_t *length) +void __prep_buffer(FILE* file) { - size_t bufferLen; - int writeCode; - char binmode; - - bufferLen = file->mBufferPtr - file->mBuffer; - if (bufferLen) { - file->mBufferLength = bufferLen; - - if (file->mMode.binary_io == 0) { - __convert_from_newlines(file->mBuffer, &file->mBufferLength); - } - - writeCode = file->writeFunc(file->mHandle, file->mBuffer, &file->mBufferLength, file->ref_con); - if (length) { - *length = file->mBufferLength; - } - if (writeCode) { - return writeCode; - } - file->mPosition += file->mBufferLength; - } - - __prep_buffer(file); - return 0; + __prep_buffer_inline(file); } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/char_io.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/char_io.c index a960f8103..c6efe8dc7 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/char_io.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/char_io.c @@ -1,115 +1,224 @@ +#include "types.h" + +#ifndef _MSL_WIDE_CHAR +#define _MSL_WIDE_CHAR +#endif + +#include "stdio.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/char_io.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h" -// int __put_char(int c, FILE* stream) -// { -// int ret; - -// int file_kind = stream->file_mode.file_kind; -// stream->buffer_length = 0; - -// if (stream->file_state.error != 0 || file_kind == __closed_file) -// { -// return -1; -// } - -// if (file_kind == __console_file) -// { -// __stdio_atexit(); -// } - -// if (stream->file_state.io_state == __neutral && (stream->file_mode.io_mode & __write)) -// { -// if ((stream->file_mode.io_mode & __append) && fseek(stream, 0, 2) != 0) -// { -// return 0; -// } - -// stream->file_state.io_state = __writing; -// __prep_buffer(stream); -// } - -// if (stream->file_state.io_state != __writing) -// { -// stream->file_state.error = 1; -// ret = -1; -// stream->buffer_length = 0; -// } -// else if ((stream->file_mode.buffer_mode == 2 || -// stream->buffer_size == -// (unsigned int)stream->buffer_ptr - (unsigned int)stream->buffer) && -// __flush_buffer(stream, NULL) != 0) -// { -// stream->file_state.error = 1; -// ret = -1; -// stream->buffer_length = 0; -// } -// else -// { -// stream->buffer_length--; -// *stream->buffer_ptr++ = c; - -// if (stream->file_mode.buffer_mode != 2) -// { -// if ((stream->file_mode.buffer_mode == 0 || c == 10) && -// __flush_buffer(stream, NULL) != 0) -// { -// stream->file_state.error = 1; -// ret = -1; -// stream->buffer_length = 0; -// goto exit; -// } -// stream->buffer_length = 0; -// } - -// ret = c & 0xFF; -// } - -// exit: -// return ret; -// } - -// int fputs(const char* s, FILE* stream) -// { -// char c; -// int var_r3; -// unsigned long len; -// int ret = 0; - -// __begin_critical_region(stdin_access); -// while (c = *s++, c != 0) -// { -// if (fwide(stream, -1) >= 0) -// { -// var_r3 = -1; -// } -// else -// { -// len = stream->buffer_length; -// stream->buffer_length = len - 1; - -// if (len != 0) -// { -// char* buf = (char*)stream->buffer_ptr; -// stream->buffer_ptr++; - -// *buf = var_r3 = c & 0xFF; -// } -// else -// { -// var_r3 = __put_char(c, stream); -// } -// } - -// if (var_r3 == -1) -// { -// ret = -1; -// break; -// } -// } -// __end_critical_region(stdin_access); - -// return ret; -// } \ No newline at end of file +#ifndef EOF +#define EOF (-1) +#endif + +enum __io_modes { + __read = 1, + __write = 2, + __append = 4 +}; + +enum __io_results { + __no_io_error, + __io_error, + __io_EOF +}; + +int __load_buffer(FILE* file, size_t* bytes_loaded, int mode); + +int fputs(const char* s, FILE* stream) +{ + char c; + int var_r3; + unsigned long len; + int ret = 0; + + __begin_critical_region(stdin_access); + while (c = *s++, c != 0) { + if (fwide(stream, -1) >= 0) { + var_r3 = -1; + } else { + len = stream->mBufferLength; + stream->mBufferLength = len - 1; + + if (len != 0) { + char* buffer; + + buffer = stream->mBufferPtr; + stream->mBufferPtr++; + *buffer = var_r3 = c & 0xFF; + } else { + var_r3 = __put_char(c, stream); + } + } + + if (var_r3 == -1) { + ret = -1; + break; + } + } + __end_critical_region(stdin_access); + + return ret; +} + +int __put_char(int c, FILE* stream) +{ + int ret; + int file_kind = stream->mMode.file_kind; + stream->mBufferLength = 0; + + if (stream->mState.error != 0 || file_kind == __closed_file) { + return -1; + } + + if (file_kind == __console_file) { + __stdio_atexit(); + } + + if (stream->mState.io_state == __neutral) { + int io_mode = stream->mMode.io_mode; + + if (io_mode & __write) { + if ((io_mode & __append) && fseek(stream, 0, 2) != 0) { + return 0; + } + + stream->mState.io_state = __writing; + __prep_buffer(stream); + } + } + + if (stream->mState.io_state != __writing) { + stream->mState.error = 1; + ret = -1; + stream->mBufferLength = 0; + } else if ((stream->mMode.buffer_mode == 2 || + stream->mBufferSize == + (unsigned int)stream->mBufferPtr - (unsigned int)stream->mBuffer) && + __flush_buffer(stream, NULL) != 0) + { + stream->mState.error = 1; + ret = -1; + stream->mBufferLength = 0; + } else { + stream->mBufferLength--; + *stream->mBufferPtr++ = c; + + if (stream->mMode.buffer_mode != 2) { + if ((stream->mMode.buffer_mode == 0 || c == 10) && + __flush_buffer(stream, NULL) != 0) + { + stream->mState.error = 1; + ret = -1; + stream->mBufferLength = 0; + goto exit; + } + stream->mBufferLength = 0; + } + + ret = c & 0xFF; + } + +exit: + return ret; +} + +char* fgets(char* s, int n, FILE* file) +{ + char* ptr; + int c; + + ptr = s; + if (--n < 0) { + return NULL; + } + + __begin_critical_region(stdin_access); + + if (n != 0) { + do { + if (fwide(file, -1) >= 0) { + c = EOF; + } else { + unsigned long length; + + length = file->mBufferLength; + file->mBufferLength = length - 1; + + if (length != 0) { + unsigned char* buffer; + + buffer = (unsigned char*)file->mBufferPtr; + file->mBufferPtr = (char*)(buffer + 1); + c = *buffer; + } else { + file->mBufferLength = 0; + + if (file->mState.error != 0 || file->mMode.file_kind == __closed_file) { + c = EOF; + } else { + int io_state; + + io_state = file->mState.io_state; + if (io_state == __writing || !(file->mMode.io_mode & __read)) { + file->mState.error = 1; + file->mBufferLength = 0; + c = EOF; + } else if (io_state >= __rereading) { + file->mState.io_state = io_state - 1; + if (io_state == __rereading) { + file->mBufferLength = file->mBufferLength2; + } + c = ((unsigned char*)file)[io_state + 0xC]; + } else { + int load_result; + + file->mState.io_state = __reading; + load_result = __load_buffer(file, NULL, 0); + if (load_result != __no_io_error || file->mBufferLength == 0) { + if (load_result == __io_error) { + file->mState.error = 1; + file->mBufferLength = 0; + } else { + file->mState.io_state = __neutral; + file->mState.eof = 1; + file->mBufferLength = 0; + } + c = EOF; + } else { + unsigned long next_length; + unsigned char* next_buffer; + + next_length = file->mBufferLength; + file->mBufferLength = next_length - 1; + next_buffer = (unsigned char*)file->mBufferPtr; + file->mBufferPtr = (char*)(next_buffer + 1); + c = *next_buffer; + } + } + } + } + } + + if (c == EOF) { + if (file->mState.eof != 0 && ptr != s) { + break; + } + + __end_critical_region(stdin_access); + return NULL; + } + + *ptr++ = c; + } while (c != '\n' && --n); + } + + __end_critical_region(stdin_access); + *ptr = 0; + + return s; +} diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c index bc673a86d..fc1e29246 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/ctype.c @@ -1,40 +1,37 @@ #include "ctype.h" -#include "types.h" -#define octrl 0x01 -#define omotn 0x02 -#define ospac 0x04 -#define opunc 0x08 -#define odigi 0x10 -#define ohexd 0x20 -#define olowc 0x40 -#define ouppc 0x80 -#define odhex ohexd | odigi -#define ouhex ohexd | ouppc -#define olhex ohexd | olowc +#define ctrl __control_char +#define motn __motion_char +#define spac __space_char +#define punc __punctuation +#define digi __digit +#define hexd __hex_digit +#define lowc __lower_case +#define uppc __upper_case +#define dhex (hexd | digi) +#define uhex (hexd | uppc) +#define lhex (hexd | lowc) unsigned char __ctype_map[256] = { - octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, omotn, omotn, omotn, omotn, - omotn, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, octrl, - octrl, octrl, octrl, octrl, octrl, octrl, ospac, opunc, opunc, opunc, opunc, opunc, opunc, - opunc, opunc, opunc, opunc, opunc, opunc, opunc, opunc, opunc, odhex, odhex, odhex, odhex, - odhex, odhex, odhex, odhex, odhex, odhex, opunc, opunc, opunc, opunc, opunc, opunc, opunc, - ouhex, ouhex, ouhex, ouhex, ouhex, ouhex, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, - ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, ouppc, - opunc, opunc, opunc, opunc, opunc, opunc, olhex, olhex, olhex, olhex, olhex, olhex, olowc, - olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, olowc, - olowc, olowc, olowc, olowc, olowc, olowc, opunc, opunc, opunc, opunc, octrl + ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, motn, motn, motn, motn, motn, ctrl, ctrl, + ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, + spac, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, + dhex, dhex, dhex, dhex, dhex, dhex, dhex, dhex, dhex, dhex, punc, punc, punc, punc, punc, punc, + punc, uhex, uhex, uhex, uhex, uhex, uhex, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, + uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, punc, punc, punc, punc, punc, + punc, lhex, lhex, lhex, lhex, lhex, lhex, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, + lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, punc, punc, punc, punc, ctrl, }; unsigned char __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, + ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\', ']', '^', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 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, @@ -48,12 +45,12 @@ unsigned char __lower_map[256] = { unsigned char __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, + ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', + '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', 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, @@ -64,74 +61,16 @@ unsigned char __upper_map[256] = { 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, }; -void isalnum(void) -{ - // UNUSED FUNCTION -} - -int isalpha(int c) -{ - return (int)(__ctype_map[(u8)c] & __letter); -} - -void iscntrl(void) -{ - // UNUSED FUNCTION -} - -BOOL isdigit(int c) -{ - { - return (int)(__ctype_map[(u8)c] & __digit); - } -} - -void isgraph(void) -{ - // UNUSED FUNCTION -} - -BOOL islower(unsigned char c) -{ - return __ctype_map[c] & olowc; -} - -// void isprint(void) -// { -// // UNUSED FUNCTION -// } - -void ispunct(void) -{ - // UNUSED FUNCTION -} - -int isspace(int c) -{ - return (int)(__ctype_map[(u8)c] & __whitespace); -} - -BOOL isupper(int c) -{ - return (int)(__ctype_map[(u8)c] & __upper_case); -} - -BOOL isxdigit(int c) -{ - return (int)(__ctype_map[(u8)c] & __hex_digit); -} - int tolower(int c) { - return (c == -1 ? -1 : (int)__lower_map[(u8)c]); -} + if (c == -1) { + return 0xffffffff; + } -int toupper(int c) -{ - return (c == -1 ? -1 : (int)__upper_map[(u8)c]); + return (unsigned int)__lower_map[c & 0xff]; } -void iswblank(void) +__declspec(weak) int isprint(int c) { - // UNUSED FUNCTION + return __ctype_map[c & 0xff] & __printable; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c index 4364c3533..2f6fd3195 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/direct_io.c @@ -10,27 +10,40 @@ #include "PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" -void fread(void) -{ - // UNUSED FUNCTION -} - - -void __fread(void) -{ - // UNUSED FUNCTION -} +#ifndef _IONBF +#define _IONBF 0 +#endif -size_t fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) -{ - size_t retval; +#ifndef _IOLBF +#define _IOLBF 1 +#endif - __begin_critical_region(stdin_access); - retval = __fwrite(pPtr, memb_size, num_memb, pFile); - __end_critical_region(stdin_access); +#ifndef _IOFBF +#define _IOFBF 2 +#endif - return retval; -} +#define set_error(file) \ + do { \ + (file)->mState.error = 1; \ + (file)->mBufferLength = 0; \ + } while (0) + +enum __io_modes { + __read = 1, + __write = 2, + __append = 4 +}; + +enum __io_results { + __no_io_error, + __io_error, + __io_EOF +}; + +int __flush_line_buffered_output_files(void); +int __load_buffer(FILE* file, size_t* bytes_loaded, int alignment); +size_t __fread(void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile); +size_t __fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile); size_t __fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) { @@ -44,34 +57,35 @@ size_t __fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile rem_bytes = memb_size * num_memb; - if (rem_bytes == 0 || pFile->mState.error || pFile->mMode.file_kind == 0) { + if (rem_bytes == 0 || pFile->mState.error || pFile->mMode.file_kind == __closed_file) { return 0; } - if (pFile->mMode.file_kind == 2) { + if (pFile->mMode.file_kind == __console_file) { __stdio_atexit(); } - buff = (!pFile->mMode.binary_io || pFile->mMode.buffer_mode == 2 || pFile->mMode.buffer_mode == 1); + buff = !pFile->mMode.binary_io || pFile->mMode.buffer_mode == _IOFBF || pFile->mMode.buffer_mode == _IOLBF; - if (pFile->mState.io_state == 0 && pFile->mMode.io_mode & 2) { - if (pFile->mMode.io_mode & 4) { - if (fseek(pFile, 0, 2)) { - return 0; + if (pFile->mState.io_state == __neutral) { + if (pFile->mMode.io_mode & __write) { + if (pFile->mMode.io_mode & __append) { + if (fseek(pFile, 0, 2)) { + return 0; + } } - } - pFile->mState.io_state = 1; - __prep_buffer(pFile); + pFile->mState.io_state = __writing; + __prep_buffer(pFile); + } } - if (pFile->mState.io_state != 1) { - pFile->mState.error = 1; - pFile->mBufferLength = 0; + if (pFile->mState.io_state != __writing) { + set_error(pFile); return 0; } - cur_ptr = (unsigned char*)pPtr; + cur_ptr = (unsigned char*)pPtr; bytes_written = 0; if (rem_bytes && (pFile->mBufferPtr != pFile->mBuffer || buff)) { @@ -79,65 +93,221 @@ size_t __fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile do { unsigned char* nw = 0; - num_bytes = pFile->mBufferLength; + num_bytes = pFile->mBufferLength; if (num_bytes > rem_bytes) { num_bytes = rem_bytes; } - if (pFile->mMode.buffer_mode == 1 && num_bytes) { + if (pFile->mMode.buffer_mode == _IOLBF && num_bytes) { if ((nw = (unsigned char*)__memrchr(cur_ptr, '\n', num_bytes)) != 0) { num_bytes = nw + 1 - cur_ptr; } } - if (num_bytes != 0) { + if (num_bytes) { memcpy(pFile->mBufferPtr, cur_ptr, num_bytes); + cur_ptr += num_bytes; bytes_written += num_bytes; rem_bytes -= num_bytes; + pFile->mBufferPtr += num_bytes; pFile->mBufferLength -= num_bytes; } - if (pFile->mBufferLength == 0 || nw != 0 || (!pFile->mMode.buffer_mode)) { + if (pFile->mBufferLength == 0 || nw != 0 || pFile->mMode.buffer_mode == _IONBF) { res = __flush_buffer(pFile, 0); - - if (res != 0) { - pFile->mState.error = 1; - pFile->mBufferLength = 0; - rem_bytes = 0; + if (res != __no_io_error) { + set_error(pFile); + rem_bytes = 0; break; } } - } while (rem_bytes && buff); } - if (rem_bytes && buff == 0) { + if (rem_bytes && !buff) { unsigned char* save_buf = (unsigned char*)pFile->mBuffer; - size_t save_size = pFile->mBufferSize; + size_t save_size = pFile->mBufferSize; - pFile->mBuffer = (char*)cur_ptr; + pFile->mBuffer = (char*)cur_ptr; pFile->mBufferSize = rem_bytes; - pFile->mBufferPtr = (char*)cur_ptr + rem_bytes; + pFile->mBufferPtr = (char*)cur_ptr + rem_bytes; - if (__flush_buffer(pFile, &num_bytes) != 0) { - pFile->mState.error = 1; - pFile->mBufferLength = 0; + if (__flush_buffer(pFile, &num_bytes) != __no_io_error) { + set_error(pFile); } bytes_written += num_bytes; - pFile->mBuffer = (char*)save_buf; + pFile->mBuffer = (char*)save_buf; pFile->mBufferSize = save_size; + __prep_buffer(pFile); pFile->mBufferLength = 0; } - if (pFile->mMode.buffer_mode != 2) { + if (pFile->mMode.buffer_mode != _IOFBF) { pFile->mBufferLength = 0; } return (bytes_written + memb_size - 1) / memb_size; } + +size_t fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) +{ + size_t retval; + + __begin_critical_region(stdin_access); + retval = __fwrite(pPtr, memb_size, num_memb, pFile); + __end_critical_region(stdin_access); + + return retval; +} + +size_t __fread(void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) +{ + int always_buffer, ioresult; + unsigned char* cur_ptr; + size_t num_bytes, rem_bytes, bytes_read; + + if (fwide(pFile, 0) == 0) { + fwide(pFile, -1); + } + + rem_bytes = memb_size * num_memb; + + if (rem_bytes == 0 || pFile->mState.error || pFile->mMode.file_kind == __closed_file) { + return 0; + } + + always_buffer = 1; + if (pFile->mMode.binary_io && pFile->mMode.buffer_mode != _IOFBF) { + always_buffer = 0; + } + + if (pFile->mState.io_state == __neutral) { + if (pFile->mMode.io_mode & __read) { + pFile->mState.io_state = __reading; + pFile->mBufferLength = 0; + } + } + + if (pFile->mState.io_state < __reading) { + set_error(pFile); + return 0; + } + + if (pFile->mMode.buffer_mode & _IOLBF) { + if (__flush_line_buffered_output_files()) { + set_error(pFile); + return 0; + } + } + + cur_ptr = (unsigned char*)pPtr; + bytes_read = 0; + + if (rem_bytes && pFile->mState.io_state >= __rereading) { + do { + if (fwide(pFile, 0) == 1) { + bytes_read += 2; + rem_bytes -= 2; + *(wchar_t*)cur_ptr = pFile->mUngetcWideBuffer[pFile->mState.io_state - __rereading]; + cur_ptr += 2; + } else { + bytes_read += 1; + rem_bytes -= 1; + *cur_ptr = pFile->mUngetcBuffer[pFile->mState.io_state - __rereading]; + cur_ptr += 1; + } + + pFile->mState.io_state = pFile->mState.io_state - 1; + if (rem_bytes == 0) { + break; + } + } while (pFile->mState.io_state >= __rereading); + + if (pFile->mState.io_state == __reading) { + pFile->mBufferLength = pFile->mBufferLength2; + } + } + + if (rem_bytes != 0 && (pFile->mBufferLength || always_buffer)) { + do { + if (pFile->mBufferLength == 0) { + ioresult = __load_buffer(pFile, 0, 0); + if (ioresult != __no_io_error) { + if (ioresult == __io_error) { + pFile->mState.error = 1; + pFile->mBufferLength = 0; + } else { + pFile->mState.io_state = __neutral; + pFile->mState.eof = 1; + pFile->mBufferLength = 0; + } + rem_bytes = 0; + break; + } + } + + num_bytes = pFile->mBufferLength; + if (num_bytes > rem_bytes) { + num_bytes = rem_bytes; + } + + memcpy(cur_ptr, pFile->mBufferPtr, num_bytes); + + rem_bytes -= num_bytes; + cur_ptr += num_bytes; + bytes_read += num_bytes; + pFile->mBufferPtr += num_bytes; + pFile->mBufferLength -= num_bytes; + + if (rem_bytes == 0) { + break; + } + } while (always_buffer); + } + + if (rem_bytes != 0 && !always_buffer) { + unsigned char* save_buf = (unsigned char*)pFile->mBuffer; + size_t save_size = pFile->mBufferSize; + + pFile->mBuffer = (char*)cur_ptr; + pFile->mBufferSize = rem_bytes; + + ioresult = __load_buffer(pFile, &num_bytes, 1); + if (ioresult != __no_io_error) { + if (ioresult == __io_error) { + pFile->mState.error = 1; + pFile->mBufferLength = 0; + } else { + pFile->mState.io_state = __neutral; + pFile->mState.eof = 1; + pFile->mBufferLength = 0; + } + } + + bytes_read += num_bytes; + pFile->mBuffer = (char*)save_buf; + pFile->mBufferSize = save_size; + + __prep_buffer(pFile); + pFile->mBufferLength = 0; + } + + return bytes_read / memb_size; +} + +size_t fread(void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) +{ + size_t retval; + + __begin_critical_region(stdin_access); + retval = __fread(pPtr, memb_size, num_memb, pFile); + __end_critical_region(stdin_access); + + return retval; +} diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c index 6e056b18c..d73c401ef 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/extras.c @@ -1,401 +1,47 @@ #include "types.h" #include "ctype.h" -void strdup(void) +int strcmpi(const char* str1, const char* str2) { - // UNUSED FUNCTION -} - -void _strdup(void) -{ - // UNUSED FUNCTION -} - -void strlwr(void) -{ - // UNUSED FUNCTION -} - -void _strlwr(void) -{ - // UNUSED FUNCTION -} - -void ultoa(void) -{ - // UNUSED FUNCTION -} - -void _ultoa(void) -{ - // UNUSED FUNCTION -} + char a_var; + char b_var; -void gcvt(void) -{ - // UNUSED FUNCTION -} - -void _gcvt(void) -{ - // UNUSED FUNCTION -} + do { + b_var = _tolower(*str1++); + a_var = _tolower(*str2++); -void heapmin(void) -{ - // UNUSED FUNCTION -} + if (b_var < a_var) { + return -1; + } + if (b_var > a_var) { + return 1; + } + } while (b_var != 0); -void _heapmin(void) -{ - // UNUSED FUNCTION + return 0; } int stricmp(char* param_1, char* param_2) { - s8 a_var; - s8 b_var; - - do { - a_var = *param_1; - param_1++; - b_var = _tolower(a_var); - - a_var = *param_2; - param_2++; - a_var = _tolower(a_var); - - if (b_var < a_var) { - return -1; - } - if (b_var > a_var) { - return 1; - } - } while (b_var != 0); - return 0; -} - -void _stricmp(void) -{ - // UNUSED FUNCTION -} - -int strnicmp(const char *s1, const char *s2, int n) -{ - return __msl_strnicmp(s1, s2, n); -} - -void _strnicmp(void) -{ - // UNUSED FUNCTION -} - -void strupr(void) -{ - // UNUSED FUNCTION -} - -void _strupr(void) -{ - // UNUSED FUNCTION -} - -void strdate(void) -{ - // UNUSED FUNCTION -} - -void _strdate(void) -{ - // UNUSED FUNCTION -} - -void strset(void) -{ - // UNUSED FUNCTION -} - -void _strset(void) -{ - // UNUSED FUNCTION -} - -void strnset(void) -{ - // UNUSED FUNCTION -} - -void _strnset(void) -{ - // UNUSED FUNCTION -} - -void strspnp(void) -{ - // UNUSED FUNCTION -} - -void _strspnp(void) -{ - // UNUSED FUNCTION -} - -void strncasecmp(void) -{ - // UNUSED FUNCTION -} - -void _strncasecmp(void) -{ - // UNUSED FUNCTION -} - -void strcmpi(void) -{ - // UNUSED FUNCTION -} - -void _strcmpi(void) -{ - // UNUSED FUNCTION -} - -void strncmpi(void) -{ - // UNUSED FUNCTION -} - -void _strncmpi(void) -{ - // UNUSED FUNCTION -} - -void strcasecmp(void) -{ - // UNUSED FUNCTION -} - -void _strcasecmp(void) -{ - // UNUSED FUNCTION -} - -void _stricoll(void) -{ - // UNUSED FUNCTION -} - -void _strncoll(void) -{ - // UNUSED FUNCTION -} - -void _strnicoll(void) -{ - // UNUSED FUNCTION -} - -void stricoll(void) -{ - // UNUSED FUNCTION -} - -void strncoll(void) -{ - // UNUSED FUNCTION -} - -void strnicoll(void) -{ - // UNUSED FUNCTION -} - -void itoa(void) -{ - // UNUSED FUNCTION -} - -void _itoa(void) -{ - // UNUSED FUNCTION -} - -void strrev(void) -{ - // UNUSED FUNCTION -} - -void _strrev(void) -{ - // UNUSED FUNCTION -} - -void filelength(void) -{ - // UNUSED FUNCTION -} - -void _filelength(void) -{ - // UNUSED FUNCTION -} - -void chsize(void) -{ - // UNUSED FUNCTION -} + s8 a_var; + s8 b_var; -void _chsize(void) -{ - // UNUSED FUNCTION -} + do { + a_var = *param_1; + param_1++; + b_var = _tolower(a_var); -void wtoi(void) -{ - // UNUSED FUNCTION -} + a_var = *param_2; + param_2++; + a_var = _tolower(a_var); -void _wtoi(void) -{ - // UNUSED FUNCTION -} + if (b_var < a_var) { + return -1; + } + if (b_var > a_var) { + return 1; + } + } while (b_var != 0); -void wcslwr(void) -{ - // UNUSED FUNCTION -} - -void _wcslwr(void) -{ - // UNUSED FUNCTION -} - -void wcsupr(void) -{ - // UNUSED FUNCTION -} - -void _wcsupr(void) -{ - // UNUSED FUNCTION -} - -void wcsicmp(void) -{ - // UNUSED FUNCTION -} - -void _wcsicmp(void) -{ - // UNUSED FUNCTION -} - -void wcsnicmp(void) -{ - // UNUSED FUNCTION -} - -void _wcsnicmp(void) -{ - // UNUSED FUNCTION -} - -void wcsrev(void) -{ - // UNUSED FUNCTION -} - -void _wcsrev(void) -{ - // UNUSED FUNCTION -} - -void wcsset(void) -{ - // UNUSED FUNCTION -} - -void _wcsset(void) -{ - // UNUSED FUNCTION -} - -void wcsnset(void) -{ - // UNUSED FUNCTION -} - -void _wcsnset(void) -{ - // UNUSED FUNCTION -} - -void wcsspnp(void) -{ - // UNUSED FUNCTION -} - -void _wcsspnp(void) -{ - // UNUSED FUNCTION -} - -void wcsdup(void) -{ - // UNUSED FUNCTION -} - -void _wcsdup(void) -{ - // UNUSED FUNCTION -} - -void wstrrev(void) -{ - // UNUSED FUNCTION -} - -void _wstrrev(void) -{ - // UNUSED FUNCTION -} - -void _wcsicoll(void) -{ - // UNUSED FUNCTION -} - -void _wcsncoll(void) -{ - // UNUSED FUNCTION -} - -void _wcsnicoll(void) -{ - // UNUSED FUNCTION -} - -void wcsicoll(void) -{ - // UNUSED FUNCTION -} - -void wcsncoll(void) -{ - // UNUSED FUNCTION -} - -void wcsnicoll(void) -{ - // UNUSED FUNCTION -} - -void itow(void) -{ - // UNUSED FUNCTION -} - -void _itow(void) -{ - // UNUSED FUNCTION + return 0; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c index c28e5ca4d..121015d8c 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c @@ -1,77 +1,255 @@ #include "types.h" #include "string.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/FILE_POS.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h" -int fclose(FILE* file) +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +enum __open_modes { __must_exist, __create_if_necessary, __create_or_truncate }; +enum __io_modes { __read = 1, __write = 2, __read_write = 3, __append = 4 }; +enum __io_results { __no_io_error, __io_error, __io_EOF }; + +extern FILE* __find_unopened_file(void); +extern void __init_file(FILE* file, file_modes mode, unsigned char* buffer, unsigned long buffer_size); +extern int __open_file(const char* name, file_modes mode, __file_handle* handle); + +inline static FILE* freopen(const char* name, const char* mode, FILE* file) { - int flush_result, close_result; + file_modes modes; + u32 pos; + + __stdio_atexit(); + + if (!file) { + return NULL; + } + + if (file && file->mMode.file_kind != __closed_file) { + if (file == NULL) { + __flush_all(); + } + else if (file->mState.error == 0 && file->mMode.file_kind != __closed_file) { + if (file->mMode.io_mode != 1) { + if (file->mState.io_state >= 3) { + file->mState.io_state = 2; + } - if (file == NULL) - return (-1); - if (file->mMode.file_kind == __closed_file) - return (0); + if (file->mState.io_state == 2) { + file->mBufferLength = 0; + } - flush_result = fflush(file); + if (file->mState.io_state != 1) { + file->mState.io_state = 0; + } + else { + if (file->mMode.file_kind != __disk_file || (pos = ftell(file)) < 0) { + pos = 0; + } - close_result = (*file->closeFunc)(file->mHandle); + if (__flush_buffer(file, 0) != 0) { + file->mState.error = 1; + file->mBufferLength = 0; + } + else { + file->mState.io_state = 0; + file->mPosition = pos; + file->mBufferLength = 0; + } + } + } + } - file->mMode.file_kind = __closed_file; - file->mHandle = 0; + (*file->closeFunc)(file->mHandle); + file->mMode.file_kind = __closed_file; + file->mHandle = 0; - if (file->mState.free_buffer) - free(file->mBuffer); - return ((flush_result || close_result) ? -1 : 0); + if (file->mState.free_buffer) { + free(file->mBuffer); + } + } + clearerr(file); + + if (!__get_file_modes(mode, &modes)) { + return NULL; + } + + __init_file(file, modes, 0, 0x1000); + + if (__open_file(name, modes, &file->mHandle)) { + file->mMode.file_kind = __closed_file; + if (file->mState.free_buffer) { + free(file->mBuffer); + } + return NULL; + } + + if (modes.io_mode & __append) { + fseek(file, 0, SEEK_END); + } + + return file; +} + +int fclose(FILE* file) +{ + int flush_result, close_result; + + if (file == NULL) + return (-1); + if (file->mMode.file_kind == __closed_file) + return (0); + + flush_result = fflush(file); + close_result = (*file->closeFunc)(file->mHandle); + + file->mMode.file_kind = __closed_file; + file->mHandle = 0; + + if (file->mState.free_buffer) + free(file->mBuffer); + return ((flush_result || close_result) ? -1 : 0); } int fflush(FILE* file) { - u32 pos; + u32 pos; - if (file == NULL) - { - return __flush_all(); - } + if (file == NULL) + { + return __flush_all(); + } - if (file->mState.error != 0 || file->mMode.file_kind == __closed_file) - { - return -1; - } + if (file->mState.error != 0 || file->mMode.file_kind == __closed_file) + { + return -1; + } - if (file->mMode.io_mode == 1) - { - return 0; - } + if (file->mMode.io_mode == 1) + { + return 0; + } - if (file->mState.io_state >= 3) - { - file->mState.io_state = 2; - } + if (file->mState.io_state >= 3) + { + file->mState.io_state = 2; + } - if (file->mState.io_state == 2) - { - file->mBufferLength = 0; - } + if (file->mState.io_state == 2) + { + file->mBufferLength = 0; + } - if (file->mState.io_state != 1) - { - file->mState.io_state = 0; - return 0; - } + if (file->mState.io_state != 1) + { + file->mState.io_state = 0; + return 0; + } - if (file->mMode.file_kind != __disk_file || (pos = ftell(file)) < 0) - pos = 0; + if (file->mMode.file_kind != __disk_file || (pos = ftell(file)) < 0) + pos = 0; - if (__flush_buffer(file, 0) != 0) - { - file->mState.error = 1; - file->mBufferLength = 0; - return -1; - } + if (__flush_buffer(file, 0) != 0) + { + file->mState.error = 1; + file->mBufferLength = 0; + return -1; + } - file->mState.io_state = 0; - file->mPosition = pos; - file->mBufferLength = 0; - return 0; + file->mState.io_state = 0; + file->mPosition = pos; + file->mBufferLength = 0; + return 0; +} + +FILE* fopen(const char* name, const char* mode) +{ + FILE* file; + + __begin_critical_region(stdin_access); + file = freopen(name, mode, __find_unopened_file()); + __end_critical_region(stdin_access); + + return file; +} + +int __get_file_modes(const char* mode, file_modes* modes) +{ + const char* mode_ptr; + signed char mode_char; + int mode_str; + unsigned char open_mode; + int io_mode; + + modes->file_kind = __disk_file; + mode_char = mode[0]; + mode_str = mode_char; +#ifdef _MSL_WIDE_CHAR + modes->file_orientation = __unoriented; +#endif + modes->binary_io = 0; + + switch (mode_str) + { + case 'r': + open_mode = __must_exist; + break; + case 'w': + open_mode = __create_or_truncate; + break; + case 'a': + open_mode = __create_if_necessary; + break; + default: + return 0; + } + + modes->open_mode = open_mode; + mode_ptr = mode + 1; + + switch (*mode_ptr++) + { + case 'b': + modes->binary_io = 1; + if (*mode_ptr == '+') { + mode_str = (mode_str << 8) | '+'; + } + break; + case '+': + mode_str = (mode_str << 8) | '+'; + if (*mode_ptr == 'b') { + modes->binary_io = 1; + } + break; + } + + switch (mode_str) + { + case 'r': + io_mode = __read; + break; + case 'w': + io_mode = __write; + break; + case 'a': + io_mode = __write | __append; + break; + case 'r+': + io_mode = __read_write; + break; + case 'w+': + io_mode = __read_write; + break; + case 'a+': + io_mode = __read_write | __append; + break; + } + + modes->io_mode = io_mode; + return 1; } int __msl_strnicmp(const char* s1, const char* s2, int n) diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c index 1aa55ea34..b202a457b 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c @@ -1,8 +1,7 @@ long __float_nan[] = { 0x7FFFFFFF }; long __float_huge[] = { 0x7F800000 }; +long __double_min[] = { 0x00100000, 0 }; long __double_max[] = { 0x7FEFFFFF, 0xFFFFFFFF }; long __double_huge[] = { 0x7FF00000, 0 }; long __extended_min[] = { 0x00100000, 0 }; long __extended_max[] = { 0x7FEFFFFF, 0xFFFFFFFF }; -long __float_max[] = { 0x7F7FFFFF }; -long __float_epsilon[] = { 0x34000000 }; diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c index ae40b6f31..81c1684a8 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mbstring.c @@ -1,260 +1,173 @@ #include "PowerPC_EABI_Support/MSL_C/MSL_Common/mbstring.h" - -void mblen(void) -{ - // UNUSED FUNCTION -} +#include "string.h" static int is_utf8_complete(const char* s, size_t n) { - if (n == 0) { // must have more than zero characters - return -1; - } - - if (s[0] == 0x00) { // first char is 0 - return 0; - } - - if ((s[0] & 0x80) == 0x00) { - return (1); - } else if ((s[0] & 0xe0) == 0xc0) { - if (n >= 2) { - if ((*(s + 1) & 0x80) == 0x80) { - return 2; - } - return -1; - } - return -2; - } else if ((s[0] & 0xf0) == 0xe0) { - if (n >= 3) { - if ((s[1] & 0x80) == 0x80) { - if ((s[2] & 0x80) == 0x80) { - return 3; - } - } - return -1; - } else if ((n == 2 && ((s[1] & 0x80) == 0x80)) || n == 1) { - return -2; - } - return -1; - } else { - return (-1); - } -} - -static int utf8_to_unicode(wchar_t *pwc, const char *s, size_t n) -{ - int number_of_bytes; - int isUTF8; - char *source; - u16 result_chr = 0; - - if (!s) - { - return 0; - } - - if (n <= 0) - { - return -1; - } - - number_of_bytes = is_utf8_complete(s, n); - if (number_of_bytes < 0) - { - return -1; - } - - source = (char *)s; - switch (number_of_bytes) - { - case 3: - result_chr |= (*source++ & 0x0f); - result_chr <<= 6; - case 2: - result_chr |= (*source++ & 0x3f); - result_chr <<= 6; - case 1: - result_chr |= (*source++ & 0x7f); - } - - if (result_chr == 0) - { - isUTF8 = 0; - } - else if (result_chr < 0x00000080) - { - isUTF8 = 1; - } - else if (result_chr < 0x00000800) - { - isUTF8 = 2; - } - else - { - isUTF8 = 3; - } - - if (isUTF8 != number_of_bytes) - { - return -1; - } - if (pwc) - { - *pwc = result_chr; - } - - return number_of_bytes; + if (n == 0) { + return -1; + } + + if (s[0] == 0x00) { + return 0; + } + + if ((s[0] & 0x80) == 0x00) { + return 1; + } else if ((s[0] & 0xe0) == 0xc0) { + if (n >= 2) { + if ((*(s + 1) & 0x80) == 0x80) { + return 2; + } + return -1; + } + return -2; + } else if ((s[0] & 0xf0) == 0xe0) { + if (n >= 3) { + if ((s[1] & 0x80) == 0x80) { + if ((s[2] & 0x80) == 0x80) { + return 3; + } + } + return -1; + } else if ((n == 2 && ((s[1] & 0x80) == 0x80)) || n == 1) { + return -2; + } + return -1; + } else { + return -1; + } } -int mbtowc(wchar_t *pwc, const char *s, size_t n) { return utf8_to_unicode(pwc, s, n); } - -inline static int unicode_to_UTF8(char* s, wchar_t wchar) -{ - int number_of_bytes; - wchar_t wide_char; - char* target_ptr; - char first_byte_mark[4] = { 0x00, 0x00, 0xc0, 0xe0 }; - - if (!s) - return (0); - - wide_char = wchar; - if (wide_char < 0x0080) - number_of_bytes = 1; - else if (wide_char < 0x0800) - number_of_bytes = 2; - else - number_of_bytes = 3; - - target_ptr = s + number_of_bytes; - - switch (number_of_bytes) { - case 3: - *--target_ptr = (wide_char & 0x003f) | 0x80; - wide_char >>= 6; - case 2: - *--target_ptr = (wide_char & 0x003f) | 0x80; - wide_char >>= 6; - case 1: - *--target_ptr = wide_char | first_byte_mark[number_of_bytes]; - } - - return number_of_bytes; -} - -inline int wctomb(char* s, wchar_t wchar) { return (unicode_to_UTF8(s, wchar)); } - inline int mbstowcs(wchar_t* pwc, const char* s, size_t n) { - u32 result_chr; - int number_of_bytes = 0; - int isUTF8; - char* source; - - if (!s) { - number_of_bytes = 0; - return (number_of_bytes); - } - - if (n <= 0) { - number_of_bytes = -1; - return (number_of_bytes); - } - - isUTF8 = is_utf8_complete(s, n); - if (isUTF8 < 0) { - number_of_bytes = -1; - return number_of_bytes; - } - - source = (char*)s; - switch (isUTF8) { - case 3: - result_chr = (*source & 0x1f); - source++; - number_of_bytes = (result_chr << 6) & 0x3C0; - case 2: - result_chr = number_of_bytes | (*source & 0x3f); - source++; - number_of_bytes = (result_chr << 6) & 0xFFC0; - case 1: - result_chr = number_of_bytes | (*source & 0x7f); - source++; - number_of_bytes = result_chr & 0xFFFF; - } - - result_chr = number_of_bytes & 0xFFFF; - - if (!(result_chr)) { - result_chr = 0; - } else if (result_chr < 0x00000080) { - result_chr = 1; - } else if (result_chr < 0x00000800) { - result_chr = 2; - } else { - result_chr = 3; - } - - if ((int)result_chr != isUTF8) { - number_of_bytes = -1; - return (number_of_bytes); - } - if (pwc) { - *pwc = number_of_bytes; - } - return isUTF8; + u32 result_chr; + int number_of_bytes = 0; + int isUTF8; + char* source; + + if (!s) { + number_of_bytes = 0; + return number_of_bytes; + } + + if (n <= 0) { + number_of_bytes = -1; + return number_of_bytes; + } + + isUTF8 = is_utf8_complete(s, n); + if (isUTF8 < 0) { + number_of_bytes = -1; + return number_of_bytes; + } + + source = (char*)s; + switch (isUTF8) { + case 3: + result_chr = (*source & 0x1f); + source++; + number_of_bytes = (result_chr << 6) & 0x3C0; + case 2: + result_chr = number_of_bytes | (*source & 0x3f); + source++; + number_of_bytes = (result_chr << 6) & 0xFFC0; + case 1: + result_chr = number_of_bytes | (*source & 0x7f); + source++; + number_of_bytes = result_chr & 0xFFFF; + } + + result_chr = number_of_bytes & 0xFFFF; + + if (!(result_chr)) { + result_chr = 0; + } else if (result_chr < 0x00000080) { + result_chr = 1; + } else if (result_chr < 0x00000800) { + result_chr = 2; + } else { + result_chr = 3; + } + + if ((int)result_chr != isUTF8) { + number_of_bytes = -1; + return number_of_bytes; + } + if (pwc) { + *pwc = number_of_bytes; + } + return isUTF8; } -size_t wcstombs(char* s, const wchar_t* pwcs, size_t n) +int mbtowc(wchar_t* pwc, const char* s, size_t n) { - int chars_written = 0; - int result; - char temp[3]; - wchar_t* source; - - if (!s || !pwcs) - return (0); - - source = (wchar_t*)pwcs; - while (chars_written <= n) { - if (!*source) { - *(s + chars_written) = '\0'; - break; - } else { - result = wctomb(temp, *source++); - if ((chars_written + result) <= n) { - strncpy(s + chars_written, temp, result); - chars_written += result; - } else - break; - } - } - - return chars_written; -} - -void mbrlen(void) -{ - // UNUSED FUNCTION + return mbstowcs(pwc, s, n); } -void mbrtowc(void) +static inline int unicode_to_UTF8(char* s, wchar_t wchar) { - // UNUSED FUNCTION + int number_of_bytes; + wchar_t wide_char; + char* target_ptr; + char first_byte_mark[4] = { 0x00, 0x00, 0xc0, 0xe0 }; + + if (!s) { + return 0; + } + + wide_char = wchar; + if (wide_char < 0x0080) + number_of_bytes = 1; + else if (wide_char < 0x0800) + number_of_bytes = 2; + else + number_of_bytes = 3; + + target_ptr = s + number_of_bytes; + + switch (number_of_bytes) { + case 3: + *--target_ptr = (wide_char & 0x003f) | 0x80; + wide_char >>= 6; + case 2: + *--target_ptr = (wide_char & 0x003f) | 0x80; + wide_char >>= 6; + case 1: + *--target_ptr = wide_char | first_byte_mark[number_of_bytes]; + } + + return number_of_bytes; } -void wcrtomb(void) +inline int wctomb(char* s, wchar_t wchar) { - // UNUSED FUNCTION + return unicode_to_UTF8(s, wchar); } -void mbsrtowcs(void) -{ - // UNUSED FUNCTION -} - -void wcsrtombs(void) +size_t wcstombs(char* s, const wchar_t* pwcs, size_t n) { - // UNUSED FUNCTION + int chars_written = 0; + int result; + char temp[3]; + wchar_t* source; + + if (!s || !pwcs) + return (0); + + source = (wchar_t*)pwcs; + while (chars_written <= n) { + if (!*source) { + *(s + chars_written) = '\0'; + break; + } else { + result = wctomb(temp, *source++); + if ((chars_written + result) <= n) { + strncpy(s + chars_written, temp, result); + chars_written += result; + } else + break; + } + } + + return chars_written; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c index e5a397182..1574ac2b2 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem.c @@ -1,105 +1,75 @@ #include "types.h" -#include "mem.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/mem_funcs.h" -void *memmove(void *dst, const void *src, size_t len) +void* memmove(void* dst, const void* src, size_t n) { - const char *csrc; - char *cdst; + const char* csrc; + char* cdst; + int reverse = (unsigned int)src < (unsigned int)dst; - int reverse = (u32)src < (u32)dst; + if (n >= 32) { + if (((unsigned int)dst ^ (unsigned int)src) & 3) { + if (!reverse) { + __copy_longs_unaligned(dst, src, n); + } else { + __copy_longs_rev_unaligned(dst, src, n); + } + } else { + if (!reverse) { + __copy_longs_aligned(dst, src, n); + } else { + __copy_longs_rev_aligned(dst, src, n); + } + } - if (len >= 32) - { - if (((int)dst ^ (int)src) & 3) - { - if (!reverse) - { - __copy_longs_unaligned(dst, src, len); - } - else - { - __copy_longs_rev_unaligned(dst, src, len); - } - } - else - { - if (!reverse) - { - __copy_longs_aligned(dst, src, len); - } - else - { - __copy_longs_rev_aligned(dst, src, len); - } - } + return dst; + } else { + if (!reverse) { + for (csrc = (const char*)src - 1, cdst = (char*)dst - 1, n++; --n;) { + *++cdst = *++csrc; + } + } else { + for (csrc = (const char*)src + n, cdst = (char*)dst + n, n++; --n;) { + *--cdst = *--csrc; + } + } + } - return dst; - } - else - { - if (!reverse) - { - for (csrc = (const char *)src - 1, cdst = (char *)dst - 1, len++; --len;) - { - *++cdst = *++csrc; - } - } - else - { - for (csrc = (const char *)src + len, cdst = (char *)dst + len, len++; --len;) - { - *--cdst = *--csrc; - } - } - } - - return dst; + return dst; } -void *memchr(const void *src, int val, size_t n) +void* memchr(const void* ptr, int ch, size_t count) { - const u8 *p; - u32 v = val & 0xFF; + const unsigned char* p; + unsigned long v = (ch & 0xFF); - for (p = (u8 *)src - 1, n++; --n;) - { - if ((*++p & 0xFF) == v) - { - return (void *)p; - } - } + for (p = (unsigned char*)ptr - 1, count++; --count;) + if ((*++p & 0xFF) == v) + return (void*)p; - return NULL; + return NULL; } -void *__memrchr(const void *src, int val, size_t n) +void* __memrchr(const void* ptr, int ch, size_t count) { - const u8 *p; - u32 v = val & 0xFF; + const unsigned char* p; + unsigned long v = (ch & 0xFF); - for (p = (u8 *)src + n, n++; --n;) - { - if (*--p == v) - { - return (void *)p; - } - } + for (p = (unsigned char*)ptr + count, count++; --count;) + if (*--p == v) + return (void*)p; - return NULL; + return NULL; } -int memcmp(const void *src1, const void *src2, size_t n) +int memcmp(const void* lhs, const void* rhs, size_t count) { - const u8 *p1; - const u8 *p2; + const unsigned char* p1; + const unsigned char* p2; - for (p1 = (const u8 *)src1 - 1, p2 = (const u8 *)src2 - 1, n++; --n;) - { - if (*++p1 != *++p2) - { - return (*p1 < *p2) ? -1 : 1; - } - } + for (p1 = (const unsigned char*)lhs - 1, p2 = (const unsigned char*)rhs - 1, count++; --count;) + if (*++p1 != *++p2) + return ((*p1 < *p2) ? -1 : +1); - return 0; + return 0; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c index bfa043e1e..6f9398fa1 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/mem_funcs.c @@ -5,213 +5,203 @@ #define srcLongPtr ((unsigned long*)pSrc) #define destLongPtr ((unsigned long*)pDest) -void __copy_mem(void) -{ - // UNUSED FUNCTION -} - -void __move_mem(void) -{ - // UNUSED FUNCTION -} - -void __copy_longs_aligned(void* pDest, const void* pSrc, unsigned long len) -{ - unsigned long i = (-(unsigned long)pDest) & 3; - srcCharPtr = ((unsigned char*)pSrc) - 1; - destCharPtr = ((unsigned char*)pDest) - 1; - - if (i != 0) { - len -= i; - - do { - *++(destCharPtr) = *++(srcCharPtr); - } while (--i); - } - - srcLongPtr = ((unsigned long*)(srcCharPtr + 1)) - 1; - destLongPtr = ((unsigned long*)(destCharPtr + 1)) - 1; - - i = len >> 5; - - if (i != 0) { - do { - *++(destLongPtr) = *++(srcLongPtr); - *++(destLongPtr) = *++(srcLongPtr); - *++(destLongPtr) = *++(srcLongPtr); - *++(destLongPtr) = *++(srcLongPtr); - *++(destLongPtr) = *++(srcLongPtr); - *++(destLongPtr) = *++(srcLongPtr); - *++(destLongPtr) = *++(srcLongPtr); - *++(destLongPtr) = *++(srcLongPtr); - } while (--i); - } - - i = (len & 31) >> 2; - - if (i != 0) { - do { - *++(destLongPtr) = *++(srcLongPtr); - } while (--i); - } - - srcCharPtr = ((unsigned char*)(srcLongPtr + 1)) - 1; - destCharPtr = ((unsigned char*)(destLongPtr + 1)) - 1; - - len &= 3; - - if (len != 0) { - do - *++(destCharPtr) = *++(srcCharPtr); - while (--len); - } -} - -void __copy_longs_rev_aligned(void* pDest, const void* pSrc, unsigned long len) +void __copy_longs_rev_unaligned(void* pDest, const void* pSrc, unsigned long len) { - unsigned long i; - srcCharPtr = ((unsigned char*)pSrc) + len; - destCharPtr = ((unsigned char*)pDest) + len; - i = ((unsigned long)destCharPtr) & 3; - - if (i != 0) { - len -= i; - - do { - *--destCharPtr = *--srcCharPtr; - } while (--i); - } - - i = len >> 5; - - if (i != 0) { - do { - *--destLongPtr = *--srcLongPtr; - *--destLongPtr = *--srcLongPtr; - *--destLongPtr = *--srcLongPtr; - *--destLongPtr = *--srcLongPtr; - *--destLongPtr = *--srcLongPtr; - *--destLongPtr = *--srcLongPtr; - *--destLongPtr = *--srcLongPtr; - *--destLongPtr = *--srcLongPtr; - } while (--i); - } - - i = (len & 31) >> 2; - - if (i != 0) { - do { - *--destLongPtr = *--srcLongPtr; - } while (--i); - } - - len &= 3; - - if (len != 0) { - do { - *--destCharPtr = *--srcCharPtr; - } while (--len); - } + unsigned long i, v1, v2; + unsigned int src, ls, rs; + + srcCharPtr = ((unsigned char*)pSrc) + len; + destCharPtr = ((unsigned char*)pDest) + len; + i = ((unsigned long)pDest) & 3; + + if (i != 0) { + len -= i; + + do { + *--destCharPtr = *--srcCharPtr; + } while (--i); + } + + src = ((unsigned int)(srcCharPtr)) & 3; + ls = src << 3; + rs = 32 - ls; + + srcCharPtr += 4 - src; + + i = len >> 3; + v1 = *--srcLongPtr; + + do { + v2 = *--srcLongPtr; + *--destLongPtr = (v2 << ls) | (v1 >> rs); + v1 = *--srcLongPtr; + *--destLongPtr = (v1 << ls) | (v2 >> rs); + } while (--i); + + if (len & 4) { + v2 = *--srcLongPtr; + *--destLongPtr = (v2 << ls) | (v1 >> rs); + } + + len &= 3; + + if (len != 0) { + srcCharPtr += src; + do { + *--destCharPtr = *--srcCharPtr; + } while (--len); + } } void __copy_longs_unaligned(void* pDest, const void* pSrc, unsigned long len) { - unsigned long i, v1, v2; - unsigned int src, ls, rs; + unsigned long i, v1, v2; + unsigned int src, ls, rs; - i = (-(unsigned long)pDest) & 3; - srcCharPtr = ((unsigned char*)pSrc) - 1; - destCharPtr = ((unsigned char*)pDest) - 1; + i = (-(unsigned long)pDest) & 3; + srcCharPtr = ((unsigned char*)pSrc) - 1; + destCharPtr = ((unsigned char*)pDest) - 1; - if (i != 0) { - len -= i; + if (i != 0) { + len -= i; - do { - *++destCharPtr = *++srcCharPtr; - } while (--i); - } + do { + *++destCharPtr = *++srcCharPtr; + } while (--i); + } - src = ((unsigned int)(srcCharPtr + 1)) & 3; - ls = src << 3; - rs = 32 - ls; + src = ((unsigned int)(srcCharPtr + 1)) & 3; + ls = src << 3; + rs = 32 - ls; - srcCharPtr -= src; + srcCharPtr -= src; - srcLongPtr = ((unsigned long*)(srcCharPtr + 1)) - 1; - destLongPtr = ((unsigned long*)(destCharPtr + 1)) - 1; + srcLongPtr = ((unsigned long*)(srcCharPtr + 1)) - 1; + destLongPtr = ((unsigned long*)(destCharPtr + 1)) - 1; - i = len >> 3; - v1 = *++srcLongPtr; + i = len >> 3; + v1 = *++srcLongPtr; - do { - v2 = *++srcLongPtr; - *++destLongPtr = (v1 << ls) | (v2 >> rs); - v1 = *++srcLongPtr; - *++destLongPtr = (v2 << ls) | (v1 >> rs); - } while (--i); + do { + v2 = *++srcLongPtr; + *++destLongPtr = (v1 << ls) | (v2 >> rs); + v1 = *++srcLongPtr; + *++destLongPtr = (v2 << ls) | (v1 >> rs); + } while (--i); - if (len & 4) { - v2 = *++srcLongPtr; - *++destLongPtr = (v1 << ls) | (v2 >> rs); - } + if (len & 4) { + v2 = *++srcLongPtr; + *++destLongPtr = (v1 << ls) | (v2 >> rs); + } - srcCharPtr = ((unsigned char*)(srcLongPtr + 1)) - 1; - destCharPtr = ((unsigned char*)(destLongPtr + 1)) - 1; + srcCharPtr = ((unsigned char*)(srcLongPtr + 1)) - 1; + destCharPtr = ((unsigned char*)(destLongPtr + 1)) - 1; - len &= 3; + len &= 3; - if (len != 0) { - srcCharPtr -= 4 - src; - do { - *++destCharPtr = *++srcCharPtr; - } while (--len); - } + if (len != 0) { + srcCharPtr -= 4 - src; + do { + *++destCharPtr = *++srcCharPtr; + } while (--len); + } } -void __copy_longs_rev_unaligned(void* pDest, const void* pSrc, unsigned long len) +void __copy_longs_rev_aligned(void* pDest, const void* pSrc, unsigned long len) +{ + unsigned long i; + srcCharPtr = ((unsigned char*)pSrc) + len; + destCharPtr = ((unsigned char*)pDest) + len; + i = ((unsigned long)destCharPtr) & 3; + + if (i != 0) { + len -= i; + + do { + *--destCharPtr = *--srcCharPtr; + } while (--i); + } + + i = len >> 5; + + if (i != 0) { + do { + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + *--destLongPtr = *--srcLongPtr; + } while (--i); + } + + i = (len & 31) >> 2; + + if (i != 0) { + do { + *--destLongPtr = *--srcLongPtr; + } while (--i); + } + + len &= 3; + + if (len != 0) { + do { + *--destCharPtr = *--srcCharPtr; + } while (--len); + } +} + +void __copy_longs_aligned(void* pDest, const void* pSrc, unsigned long len) { - unsigned long i, v1, v2; - unsigned int src, ls, rs; - - srcCharPtr = ((unsigned char*)pSrc) + len; - destCharPtr = ((unsigned char*)pDest) + len; - i = ((unsigned long)pDest) & 3; - - if (i != 0) { - len -= i; - - do { - *--destCharPtr = *--srcCharPtr; - } while (--i); - } - - src = ((unsigned int)(srcCharPtr)) & 3; - ls = src << 3; - rs = 32 - ls; - - srcCharPtr += 4 - src; - - i = len >> 3; - v1 = *--srcLongPtr; - - do { - v2 = *--srcLongPtr; - *--destLongPtr = (v2 << ls) | (v1 >> rs); - v1 = *--srcLongPtr; - *--destLongPtr = (v1 << ls) | (v2 >> rs); - } while (--i); - - if (len & 4) { - v2 = *--srcLongPtr; - *--destLongPtr = (v2 << ls) | (v1 >> rs); - } - - len &= 3; - - if (len != 0) { - srcCharPtr += src; - do { - *--destCharPtr = *--srcCharPtr; - } while (--len); - } + unsigned long i = (-(unsigned long)pDest) & 3; + srcCharPtr = ((unsigned char*)pSrc) - 1; + destCharPtr = ((unsigned char*)pDest) - 1; + + if (i != 0) { + len -= i; + + do { + *++(destCharPtr) = *++(srcCharPtr); + } while (--i); + } + + srcLongPtr = ((unsigned long*)(srcCharPtr + 1)) - 1; + destLongPtr = ((unsigned long*)(destCharPtr + 1)) - 1; + + i = len >> 5; + + if (i != 0) { + do { + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + *++(destLongPtr) = *++(srcLongPtr); + } while (--i); + } + + i = (len & 31) >> 2; + + if (i != 0) { + do { + *++(destLongPtr) = *++(srcLongPtr); + } while (--i); + } + + srcCharPtr = ((unsigned char*)(srcLongPtr + 1)) - 1; + destCharPtr = ((unsigned char*)(destLongPtr + 1)) - 1; + + len &= 3; + + if (len != 0) { + do + *++(destCharPtr) = *++(srcCharPtr); + while (--len); + } } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c index dc4b05c1e..3c324f5c3 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c @@ -1,25 +1,18 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h" + extern void (*__stdio_exit)(void); extern void __close_all(void); -void clearerr(void) -{ - // UNUSED FUNCTION -} - -void feof(void) -{ - // UNUSED FUNCTION -} +void __stdio_atexit(void) { __stdio_exit = __close_all; } -void ferror(void) +int feof(FILE* stream) { - // UNUSED FUNCTION + return stream->mState.eof; } -void perror(void) +void clearerr(FILE* stream) { - // UNUSED FUNCTION + stream->mState.eof = 0; + stream->mState.error = 0; } - -void __stdio_atexit(void) { __stdio_exit = __close_all; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c index 039757e64..a5fa349dc 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/printf.c @@ -9,7 +9,7 @@ #include "string.h" #include "stdio.h" #include "stdlib.h" - +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h" #define TARGET_FLOAT_BITS 64 #define TARGET_FLOAT_BYTES (TARGET_FLOAT_BITS / 8) #define TARGET_FLOAT_MAX_EXP LDBL_MAX_EXP @@ -62,10 +62,13 @@ static const char* parse_format(const char* format_string, va_list* arg, print_f f.field_width = 0; f.precision = 0; - if ((c = *++s) == '%') { + c = *(volatile const unsigned char*)(format_string + 1); + ++s; + c = (signed char)c; + if (c == '%') { f.conversion_char = c; *format = f; - return ((const char*)s + 1); + return s + 1; } for (;;) { @@ -111,7 +114,7 @@ static const char* parse_format(const char* format_string, va_list* arg, print_f c = *++s; } else { - while (isdigit(c)) { + while (__ctype_map[(unsigned char)c] & __digit) { f.field_width = (f.field_width * 10) + (c - '0'); c = *++s; } @@ -133,7 +136,7 @@ static const char* parse_format(const char* format_string, va_list* arg, print_f c = *++s; } else { - while (isdigit(c)) { + while (__ctype_map[(unsigned char)c] & __digit) { f.precision = (f.precision * 10) + (c - '0'); c = *++s; } @@ -530,7 +533,8 @@ static char* double2hex(long double num, char* buff, print_format format) } return p; - } else if (*dec.sig.text == 'N') { + } + else if (*dec.sig.text == 'N') { if (*(char*)&num & 0x80) { p = buff - 5; if (format.conversion_char == 'A') @@ -701,14 +705,14 @@ static char* float2str(long double num, char* buff, print_format format) if (num < 0) { p = buff - 5; - if (isupper(format.conversion_char)) { + if (__ctype_map[format.conversion_char] & __upper_case) { strcpy(p, "-INF"); } else { strcpy(p, "-inf"); } } else { p = buff - 4; - if (isupper(format.conversion_char)) { + if (__ctype_map[format.conversion_char] & __upper_case) { strcpy(p, "INF"); } else { strcpy(p, "inf"); @@ -721,14 +725,14 @@ static char* float2str(long double num, char* buff, print_format format) if (dec.sign) { p = buff - 5; - if (isupper(format.conversion_char)) { + if (__ctype_map[format.conversion_char] & __upper_case) { strcpy(p, "-NAN"); } else { strcpy(p, "-nan"); } } else { p = buff - 4; - if (isupper(format.conversion_char)) { + if (__ctype_map[format.conversion_char] & __upper_case) { strcpy(p, "NAN"); } else { strcpy(p, "nan"); @@ -1157,12 +1161,12 @@ static int __pformatter(void* (*WriteProc)(void*, const char*, size_t), void* Wr return chars_written; } -static void* __FileWrite(void* pFile, const char* pBuffer, size_t char_num) +void* __FileWrite(void* pFile, const char* pBuffer, size_t char_num) { return (fwrite(pBuffer, 1, char_num, (FILE*)pFile) == char_num ? pFile : 0); } -static void* __StringWrite(void* pCtrl, const char* pBuffer, size_t char_num) +void* __StringWrite(void* pCtrl, const char* pBuffer, size_t char_num) { size_t chars; __OutStrCtrl* ctrl = (__OutStrCtrl*)pCtrl; @@ -1174,9 +1178,25 @@ static void* __StringWrite(void* pCtrl, const char* pBuffer, size_t char_num) return (void*)1; } -void printf(const char* format, ...) +int printf(const char* format, ...) { - // UNUSED FUNCTION + int ret; + + if (fwide(stdout, -1) >= 0) { + return -1; + } + + __begin_critical_region(stdin_access); + + { + va_list args; + va_start(args, format); + ret = __pformatter(&__FileWrite, (void*)stdout, format, args); + va_end(args); + } + + __end_critical_region(stdin_access); + return ret; } int fprintf(FILE* file, const char* format, ...) @@ -1211,12 +1231,7 @@ int vprintf(const char* pFormat, va_list arg) return ret; } -void vfprintf(void) -{ - // UNUSED FUNCTION -} - -int vsnprintf(char* s, size_t n, const char* format, va_list arg) +static inline int vsnprintf(char* s, size_t n, const char* format, va_list arg) { int end; __OutStrCtrl osc; @@ -1235,13 +1250,6 @@ int vsnprintf(char* s, size_t n, const char* format, va_list arg) int vsprintf(char* s, const char* format, va_list arg) { return vsnprintf(s, 0xFFFFFFFF, format, arg); } -int snprintf(char* s, size_t n, const char* format, ...) -{ - va_list args; - va_start(args, format); - return vsnprintf(s, n, format, args); -} - int sprintf(char* s, const char* format, ...) { va_list args; diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/qsort.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/qsort.c new file mode 100644 index 000000000..cfbb25e2e --- /dev/null +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/qsort.c @@ -0,0 +1,78 @@ +#include + +typedef int (*_compare_function)(const void*, const void*); + +#define table_ptr(i) (((char*)table_base) + (member_size * ((i)-1))) + +#define swap(dst, src, cnt) \ + do { \ + char* p; \ + char* q; \ + size_t n = cnt; \ + unsigned long tmp; \ + \ + for (p = (char*)src - 1, q = (char*)dst - 1, n++; --n;) { \ + tmp = *++q; \ + *q = *++p; \ + *p = tmp; \ + } \ + } while (0) + +void qsort(void* table_base, size_t num_members, size_t member_size, _compare_function compare_members) { + size_t l, r, j; + char* lp; + char* rp; + char* ip; + char* jp; + char* kp; + + if (num_members < 2) { + return; + } + + r = num_members; + l = (r / 2) + 1; + + lp = table_ptr(l); + rp = table_ptr(r); + + for (;;) { + if (l > 1) { + l--; + lp -= member_size; + } else { + swap(lp, rp, member_size); + + if (--r == 1) { + return; + } + + rp -= member_size; + } + + j = l; + jp = table_ptr(j); + + while (j * 2 <= r) { + j *= 2; + + ip = jp; + jp = table_ptr(j); + + if (j < r) { + kp = jp + member_size; + + if (compare_members(jp, kp) < 0) { + j++; + jp = kp; + } + } + + if (compare_members(ip, jp) < 0) { + swap(ip, jp, member_size); + } else { + break; + } + } + } +} diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c index f6ed2b702..dd0fa156f 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c @@ -2,13 +2,7 @@ static u32 next = 1; -int rand() +int rand(void) { - next = next * 1103515245 + 12345; - return ((next >> 16) & 0x7fff); -} - -void srand(u32 seed) -{ - next = seed; + return ((next = next * 1103515245 + 12345) >> 16) & 0x7fff; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c index 1393de9ed..ecb7d1fa7 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/scanf.c @@ -3,6 +3,8 @@ #include "ctype.h" #include "stdio.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/stdio_api.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/strtold.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/strtoul.h" typedef long long intmax_t; @@ -52,13 +54,13 @@ static const char* parse_format(const char* format_string, scan_format* format) c = *++s; } - if (isdigit(c)) { + if (_isdigit(c)) { f.field_width = 0; do { f.field_width = (f.field_width * 10) + (c - '0'); c = *++s; - } while (isdigit(c)); + } while (_isdigit(c)); if (f.field_width == 0) { f.conversion_char = 0xFF; @@ -260,12 +262,12 @@ static int __sformatter(int (*ReadProc)(void*, int, int), void* ReadProcArg, con conversions = 0; while (!terminate && (format_char = *format_ptr) != 0) { - if (isspace(format_char)) { + if (_isspace(format_char)) { do { format_char = *++format_ptr; - } while (isspace(format_char)); + } while (_isspace(format_char)); - while (isspace(c = (*ReadProc)(ReadProcArg, 0, __GetAChar))) + while (_isspace(c = (*ReadProc)(ReadProcArg, 0, __GetAChar))) ++chars_read; (*ReadProc)(ReadProcArg, c, __UngetAChar); @@ -478,7 +480,7 @@ static int __sformatter(int (*ReadProc)(void*, int, int), void* ReadProcArg, con conversions++; break; case '%': - while (isspace(c = (*ReadProc)(ReadProcArg, 0, __GetAChar))) + while (_isspace(c = (*ReadProc)(ReadProcArg, 0, __GetAChar))) chars_read++; if (c != '%') { @@ -490,7 +492,7 @@ static int __sformatter(int (*ReadProc)(void*, int, int), void* ReadProcArg, con break; case 's': c = (*ReadProc)(ReadProcArg, 0, __GetAChar); - while (isspace(c)) { + while (_isspace(c)) { chars_read++; c = (*ReadProc)(ReadProcArg, 0, __GetAChar); } @@ -579,11 +581,6 @@ static int __sformatter(int (*ReadProc)(void*, int, int), void* ReadProcArg, con return items_assigned; } -void __FileRead(void) -{ - // UNUSED FUNCTION -} - int __StringRead(void* pPtr, int ch, int act) { char ret; @@ -617,32 +614,12 @@ int __StringRead(void* pPtr, int ch, int act) return 0; } -void fscanf(void) -{ - // UNUSED FUNCTION -} - -void vscanf(void) -{ - // UNUSED FUNCTION -} - -void scanf(void) -{ - // UNUSED FUNCTION -} - -void vfscanf(void) -{ - // UNUSED FUNCTION -} - inline int isspace_string(const char* s) { int i = 0; while (s[i] != '\0') { - if (!isspace(s[i++])) + if (!_isspace(s[i++])) return 0; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c index 22584b4f5..50e342e81 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/signal.c @@ -36,4 +36,4 @@ int raise(int sig) (*signal_func)(sig); return 0; -} \ No newline at end of file +} diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c index d70c70bbc..593ff502f 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c @@ -1,306 +1,376 @@ -#include "types.h" -//#define K1 0x80808080 -//#define K2 0xFEFEFEFF - -size_t(strlen)(const char* str) +#include "string.h" +#include "stddef.h" + +#define K1 0x80808080 +#define K2 0xFEFEFEFF + +const unsigned char strtok_delimiter_table_init[32] = { 0 }; + +static const char msl_string_table_1[] = "\0" + "Argument list too long\0" + "Permission denied\0" + "Resource temporarily unavailable\0" + "Bad file descriptor\0" + "Device busy\0" + "No child processes\0" + "Resource deadlock avoided\0" + "Numerical argument out of domain\0" + "File exists\0" + "Bad address\0" + "File too large\0" + "File Position Error\0" + "Wide character encoding error\0" + "Interrupted system call\0" + "Invalid argument\0" + "Input/output error\0" + "Is a directory\0" + "Too many open files\0" + "Too many links\0" + "File name too long\0" + "Too many open files in system\0" + "Operation not supported by device\0" + "No such file or directory\0" + "No error detected\0" + "Exec format error\0" + "No locks available\0" + "Cannot allocate memory\0" + "No space left on device\0" + "Function not implemented\0" + "Not a directory\0" + "Directory not empty\0" + "Inappropriate ioctl for device\0" + "Device not configured\0" + "Operation not permitted\0" + "Broken pipe\0" + "Result too large\0" + "Read-only file system\0" + "Signal error\0" + "Illegal seek\0" + "No such process\0" + "Unknown error\0" + "Cross-device link\0" + "Unknown Error (%d)"; + +char* strtok_null = (char*)msl_string_table_1; +char* strtok_ptr = (char*)msl_string_table_1; + +char* strstr(const char* str, const char* pat) { - size_t len = -1; - u8* p = (u8*)str - 1; - - do - len++; - while (*++p); - return (len); -} - -char*(strcpy)(char* dst, const char* src) -{ - register u8 *destb, *fromb; - register u32 w, t, align; + const unsigned char* s1 = (const unsigned char*)str - 1; + const unsigned char* p1 = (const unsigned char*)pat - 1; + unsigned long firstc, c1, c2; - u32 K1, K2; + if ((pat == 0) || (!(firstc = *++p1))) { + return (char*)str; + } - fromb = (u8*)src; - destb = (u8*)dst; + while (c1 = *++s1) { + if (c1 == firstc) { + const unsigned char* s2 = s1 - 1; + const unsigned char* p2 = p1 - 1; - if ((align = ((int)fromb & 3)) != ((int)destb & 3)) { - goto bytecopy; - } + while ((c1 = *++s2) == (c2 = *++p2) && c1) + ; - if (align) { - if ((*destb = *fromb) == 0) - return (dst); - for (align = 3 - align; align; align--) { - if ((*(++destb) = *(++fromb)) == 0) - return (dst); - } - ++destb; - ++fromb; - } + if (!c2) + return (char*)s1; + } + } - w = *((int*)(fromb)); + return NULL; +} - K2 = 0xFEFEFEFF; - t = w + K2; +char* strtok(char* str, const char* delim) +{ + unsigned char delimiter_table[32]; + int ch; + unsigned char* p; + char* tokenStart; + + ((unsigned int*)delimiter_table)[0] = ((const unsigned int*)strtok_delimiter_table_init)[0]; + ((unsigned int*)delimiter_table)[1] = ((const unsigned int*)strtok_delimiter_table_init)[1]; + ((unsigned int*)delimiter_table)[2] = ((const unsigned int*)strtok_delimiter_table_init)[2]; + ((unsigned int*)delimiter_table)[3] = ((const unsigned int*)strtok_delimiter_table_init)[3]; + ((unsigned int*)delimiter_table)[4] = ((const unsigned int*)strtok_delimiter_table_init)[4]; + ((unsigned int*)delimiter_table)[5] = ((const unsigned int*)strtok_delimiter_table_init)[5]; + ((unsigned int*)delimiter_table)[6] = ((const unsigned int*)strtok_delimiter_table_init)[6]; + ((unsigned int*)delimiter_table)[7] = ((const unsigned int*)strtok_delimiter_table_init)[7]; + + if (str != NULL) { + strtok_ptr = str; + } - K1 = 0x80808080; + p = (unsigned char*)delim - 1; + while ((ch = *++p) != '\0') { + delimiter_table[(ch & 0xFF) >> 3] |= 1 << (ch & 7); + } - t &= K1; - if (t) - goto bytecopy; - --((int*)(destb)); + p = (unsigned char*)strtok_ptr - 1; + while ((ch = *++p) != '\0') { + if ((delimiter_table[(ch & 0xFF) >> 3] & (1 << (ch & 7))) == 0) { + break; + } + } - do { - *(++((int*)(destb))) = w; - w = *(++((int*)(fromb))); + if (ch == '\0') { + strtok_ptr = strtok_null; + return NULL; + } - t = w + K2; - t &= K1; - if (t) - goto adjust; - } while (1); + tokenStart = (char*)p; + while ((ch = *++p) != '\0') { + if ((delimiter_table[(ch & 0xFF) >> 3] & (1 << (ch & 7))) != 0) { + break; + } + } -adjust: - ++((int*)(destb)); -bytecopy: - if ((*destb = *fromb) == 0) - return dst; - do { - if ((*(++destb) = *(++fromb)) == 0) - return dst; - } while (1); - - return dst; -} + if (ch == '\0') { + strtok_ptr = strtok_null; + } else { + strtok_ptr = (char*)(p + 1); + *p = '\0'; + } -char* strncpy(char* dst, const char* src, size_t n) -{ - const unsigned char* p = (const unsigned char*)src - 1; - unsigned char* q = (unsigned char*)dst - 1; - unsigned char zero = 0; - - n++; - - while (--n) - if (!(*++q = *++p)) { - while (--n) - *++q = 0; - break; - } - return (dst); + return tokenStart; } -char* strcat(char* dst, const char* src) +char* strchr(const char* str, int c) { - const u8* p = (u8*)src - 1; - u8* q = (u8*)dst - 1; - - while (*++q) - ; - - q--; + const unsigned char* p = (unsigned char*)str - 1; + unsigned long chr = (c & 0xFF); - while (*++q = *++p) - ; + unsigned long ch; + while (ch = *++p) { + if (ch == chr) { + return (char*)p; + } + } - return (dst); + return chr ? NULL : (char*)p; } -void strncat(void) +int strncmp(const char* str1, const char* str2, size_t n) { - // UNUSED FUNCTION + const unsigned char* p1 = (unsigned char*)str1 - 1; + const unsigned char* p2 = (unsigned char*)str2 - 1; + unsigned long c1, c2; + + n++; + + while (--n) + if ((c1 = *++p1) != (c2 = *++p2)) + return (c1 - c2); + else if (!c1) + break; + return 0; } int strcmp(const char* str1, const char* str2) { - // bless metrowerks for this implementation - - register u8* left = (u8*)str1; - register u8* right = (u8*)str2; - u32 align, l1, r1, x; - - u32 K1, K2; - - l1 = *left; - r1 = *right; - if (l1 - r1) { - return (l1 - r1); - } - - if ((align = ((int)left & 3)) != ((int)right & 3)) { - goto bytecopy; - } - if (align) { - if (l1 == 0) { - return 0; - } - for (align = 3 - align; align; align--) { - l1 = *(++left); - r1 = *(++right); - if (l1 - r1) { - return (l1 - r1); - } - if (l1 == 0) { - return 0; - } - } - left++; - right++; - } - - l1 = *(int*)left; - r1 = *(int*)right; - - K1 = 0x80808080; - K2 = 0xFEFEFEFF; - - x = l1 + K2; - if (x & K1) { - goto adjust; - } - while (l1 == r1) { - l1 = *(++((int*)(left))); - r1 = *(++((int*)(right))); - x = l1 + K2; - if (x & K1) { - goto adjust; - } - } - if (l1 > r1) - return 1; - return -1; + register unsigned char* left = (unsigned char*)str1; + register unsigned char* right = (unsigned char*)str2; + unsigned long align, l1, r1, x; + + l1 = *left; + r1 = *right; + if (l1 - r1) { + return l1 - r1; + } + + if ((align = ((int)left & 3)) != ((int)right & 3)) { + goto bytecopy; + } + + if (align) { + if (l1 == 0) { + return 0; + } + for (align = 3 - align; align; align--) { + l1 = *(++left); + r1 = *(++right); + if (l1 - r1) { + return l1 - r1; + } + if (l1 == 0) { + return 0; + } + } + left++; + right++; + } + + l1 = *(int*)left; + r1 = *(int*)right; + x = l1 + K2; + if (x & K1) { + goto adjust; + } + + while (l1 == r1) { + l1 = *(++((int*)(left))); + r1 = *(++((int*)(right))); + x = l1 + K2; + if (x & K1) { + goto adjust; + } + } + + if (l1 > r1) { + return 1; + } + return -1; adjust: - l1 = *left; - r1 = *right; - if (l1 - r1) { - return (l1 - r1); - } + l1 = *left; + r1 = *right; + if (l1 - r1) { + return l1 - r1; + } + bytecopy: - if (l1 == 0) { - return 0; - } - do { - l1 = *(++left); - r1 = *(++right); - if (l1 - r1) { - return (l1 - r1); - } - if (l1 == 0) { - return 0; - } - } while (1); -} + if (l1 == 0) { + return 0; + } -int strncmp(const char* str1, const char* str2, size_t n) -{ - const u8* p1 = (u8*)str1 - 1; - const u8* p2 = (u8*)str2 - 1; - u32 c1, c2; - - n++; - - while (--n) - if ((c1 = *++p1) != (c2 = *++p2)) - return (c1 - c2); - else if (!c1) - break; - return 0; + do { + l1 = *(++left); + r1 = *(++right); + if (l1 - r1) { + return l1 - r1; + } + if (l1 == 0) { + return 0; + } + } while (1); } -char* strchr(const char* str, int chr) +char* strncat(char* dst, const char* src, size_t n) { - const u8* p = (u8*)str - 1; - u32 c = (chr & 0xFF); - u32 ch; + const unsigned char* srcPtr = (const unsigned char*)src - 1; + unsigned char* dstPtr = (unsigned char*)dst - 1; - while (ch = *++p) - if (ch == c) - return ((char*)p); + while (*++dstPtr) { + } - return (c ? 0 : (char*)p); -} + --dstPtr; + n++; + while (--n) { + if (!(*++dstPtr = *++srcPtr)) { + --dstPtr; + break; + } + } -void strcoll(void) -{ - // UNUSED FUNCTION + *++dstPtr = 0; + return dst; } -void strxfrm(void) +char* strcat(char* dst, const char* src) { - // UNUSED FUNCTION -} + const unsigned char* p = (const unsigned char*)src - 1; + unsigned char* q = (unsigned char*)dst - 1; -char* strrchr(const char* str, int chr) -{ - const u8* p = (u8*)str - 1; - const u8* q = 0; - u32 c = (chr & 0xFF); - u32 ch; + while (*++q) + ; - while (ch = *++p) - if (ch == c) - q = p; + q--; - if (q) - return ((char*)q); + while (*++q = *++p) + ; - return (c ? 0 : (char*)p); + return dst; } -void strpbrk(void) +char* strncpy(char* dst, const char* src, size_t n) { - // UNUSED FUNCTION -} + const unsigned char* p = (const unsigned char*)src - 1; + unsigned char* q = (unsigned char*)dst - 1; + + n++; + while (--n) { + if (!(*++q = *++p)) { + while (--n) { + *++q = 0; + } + break; + } + } -void strspn(void) -{ - // UNUSED FUNCTION + return dst; } -void strcspn(void) +char* strcpy(char* dst, const char* src) { - // UNUSED FUNCTION -} + register unsigned char *destb, *fromb; + register unsigned long w, t, align; -void strtok(void) -{ - // UNUSED FUNCTION -} + fromb = (unsigned char*)src; + destb = (unsigned char*)dst; -char* strstr(const char *str, const char *pat) { - unsigned char* s1 = (unsigned char*)str - 1; - unsigned char* p1 = (unsigned char*)pat - 1; - unsigned long firstc, c1, c2; + if ((align = ((int)fromb & 3)) != ((int)destb & 3)) { + goto bytecopy; + } - if ((pat == 0) || (!(firstc = *++p1))) { - return ((char*)str); + if (align) { + if ((*destb = *fromb) == 0) { + return dst; + } + + for (align = 3 - align; align; align--) { + if ((*(++destb) = *(++fromb)) == 0) { + return dst; + } + } + ++destb; + ++fromb; } - while (c1 = *++s1) { - if (c1 == firstc) { - const unsigned char* s2 = s1 - 1; - const unsigned char* p2 = p1 - 1; + w = *((int*)(fromb)); - while ((c1 = *++s2) == (c2 = *++p2) && c1) { + t = w + K2; - } + t &= K1; + if (t) { + goto bytecopy; + } + --((int*)(destb)); - if (!c2) { - return ((char*)s1); - } + do { + *(++((int*)(destb))) = w; + w = *(++((int*)(fromb))); + + t = w + K2; + t &= K1; + if (t) { + goto adjust; } + } while (1); + +adjust: + ++((int*)(destb)); + +bytecopy: + if ((*destb = *fromb) == 0) { + return dst; } - return NULL; -} + do { + if ((*(++destb) = *(++fromb)) == 0) { + return dst; + } + } while (1); -void strerror(void) -{ - // UNUSED FUNCTION + return dst; } -void __strerror(void) +size_t strlen(const char* str) { - // UNUSED FUNCTION + size_t len = -1; + unsigned char* p = (unsigned char*)str - 1; + + do { + len++; + } while (*++p); + + return len; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c index 20072c860..5672b295f 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtold.c @@ -7,6 +7,7 @@ #include "ctype.h" #include "math.h" #include "mem.h" +#include "float.h" #include "limits.h" #define TARGET_FLOAT_BITS 64 @@ -63,6 +64,16 @@ enum hex_scan_states #define fetch() (count++, (*ReadProc)(ReadProcArg, 0, __GetAChar)) #define unfetch(c) (*ReadProc)(ReadProcArg, c, __UngetAChar) +extern int __double_min[]; + +typedef struct +{ + double value; +} ZeroHolder; + +static const ZeroHolder gCommonZero; +static const ZeroHolder gHexZero; + long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, int* overflow) { @@ -101,7 +112,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea switch (scan_state) { case start: - if (isspace(c)) + if (_isspace(c)) { c = fetch(); count--; @@ -109,7 +120,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; } - switch (toupper(c)) + switch (_toupper(c)) { case '-': sig_negative = 1; @@ -139,7 +150,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea int i = 1; char model[] = "INFINITY"; - while ((i < 8) && (toupper(c) == model[i])) + while ((i < 8) && (_toupper(c) == model[i])) { i++; c = fetch(); @@ -172,7 +183,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea int i = 1, j = 0; char model[] = "NAN("; char nan_arg[32] = ""; - while ((i < 4) && (toupper(c) == model[i])) + while ((i < 4) && (_toupper(c) == model[i])) { i++; c = fetch(); @@ -182,7 +193,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea { if (i == 4) { - while ((j < 32) && (isdigit(c) || isalpha(c))) + while ((j < 32) && (_isdigit(c) || _isalpha(c))) { nan_arg[j++] = c; c = fetch(); @@ -226,7 +237,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea c = fetch(); break; } - if (!isdigit(c)) + if (!_isdigit(c)) { scan_state = failure; break; @@ -235,7 +246,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea if (c == '0') { c = fetch(); - if (toupper(c) == 'X') + if (_toupper(c) == 'X') { scan_state = hex_state; hex_scan_state = hex_start; @@ -261,7 +272,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; case int_digit_loop: - if (!isdigit(c)) + if (!_isdigit(c)) { if (c == dot) { @@ -287,7 +298,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; case frac_start: - if (!isdigit(c)) + if (!_isdigit(c)) { scan_state = failure; break; @@ -297,7 +308,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; case frac_digit_loop: - if (!isdigit(c)) + if (!_isdigit(c)) { scan_state = sig_end; break; @@ -316,7 +327,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; case sig_end: - if (toupper(c) == 'E') + if (_toupper(c) == 'E') { scan_state = exp_start; c = fetch(); @@ -340,7 +351,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; case leading_exp_digit: - if (!isdigit(c)) + if (!_isdigit(c)) { scan_state = failure; break; @@ -367,7 +378,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; case exp_digit_loop: - if (!isdigit(c)) + if (!_isdigit(c)) { scan_state = finished; break; @@ -407,7 +418,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; case hex_int_digit_loop: - if (!isxdigit(c)) + if (!_isxdigit(c)) { if (c == dot) { @@ -425,7 +436,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea { intdigits++; uch = *(chptr + NibbleIndex / 2); - ui = toupper(c); + ui = _toupper(c); if (ui >= 'A') { @@ -459,7 +470,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; case hex_frac_digit_loop: - if (!isxdigit(c)) + if (!_isxdigit(c)) { hex_scan_state = hex_sig_end; break; @@ -468,7 +479,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea if (NibbleIndex < 17) { uch = *(chptr + NibbleIndex / 2); - ui = toupper(c); + ui = _toupper(c); if (ui >= 'A') { @@ -500,7 +511,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; case hex_sig_end: - if (toupper(c) == 'P') + if (_toupper(c) == 'P') { hex_scan_state = hex_exp_start; exp_digits++; @@ -530,7 +541,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea break; case hex_leading_exp_digit: - if (!isdigit(c)) + if (!_isdigit(c)) { scan_state = failure; break; @@ -547,7 +558,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea hex_scan_state = hex_exp_digit_loop; break; case hex_exp_digit_loop: - if (!isdigit(c)) + if (!_isdigit(c)) { scan_state = finished; break; @@ -618,7 +629,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea { if (exp_negative) { - return 0.0; + return gCommonZero.value; } else { @@ -630,7 +641,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea result = __dec2num(&d); - if (result != 0.0 && result < LDBL_MIN) + if (gCommonZero.value != result && result < LDBL_MIN) { *overflow = 1; } @@ -651,7 +662,7 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea { unsigned long long* uptr = (unsigned long long*)&result; - if (result) + if (result != gHexZero.value) { if (expsign) { @@ -669,10 +680,10 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea *(short*)(&result) |= ((exponent + 1023) << 4); *chars_scanned = spaces + sign_detected + NibbleIndex + 1 + exp_digits; - if (result != 0.0 && result < LDBL_MIN) + if (gCommonZero.value != result && result < LDBL_MIN) { *overflow = 1; - result = 0.0; + result = gCommonZero.value; } else if (result > LDBL_MAX) { @@ -686,18 +697,33 @@ long double __strtold(int max_width, int (*ReadProc)(void*, int, int), void* Rea } else { - result = 0.0; + result = gCommonZero.value; } return result; } } -void strtold(void) +double atof(const char* str) { - // UNUSED FUNCTION -} + double value, abs_value; + int overflow, count; -void strtod(void) -{ - // UNUSED FUNCTION + __InStrCtrl isc; + isc.NextChar = (char*)str; + isc.NullCharDetected = 0; + + value = __strtold(INT_MAX, &__StringRead, (void*)&isc, &count, &overflow); + abs_value = fabs(value); + + if (overflow || + (gCommonZero.value != value && + (abs_value < *(double*)__double_min || abs_value > *(double*)__double_max))) + { + errno = ERANGE; + } + + return value; } + +static const ZeroHolder gCommonZero = { 0.0 }; +static const ZeroHolder gHexZero = { 0.0 }; diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c index 5019f7213..7e307a5f2 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/strtoul.c @@ -20,13 +20,41 @@ enum scan_states { #define unfetch(c) (*ReadProc)(ReadProcArg, c, __UngetAChar) unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, int* negative, - int* overflow) + int* overflow); +unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, + int* negative, int* overflow); + +int atoi(const char* str) +{ + unsigned long uvalue; + int svalue; + int overflow, negative, count; + + __InStrCtrl isc; + isc.NextChar = (char*)str; + isc.NullCharDetected = 0; + + uvalue = __strtoul(10, 0x7FFFFFFF, &__StringRead, (void*)&isc, &count, &negative, &overflow); + + if (overflow || (!negative && uvalue > INT_MAX) || (negative && uvalue > -INT_MIN)) { + svalue = (negative ? -INT_MIN : INT_MAX); + errno = ERANGE; + } else { + svalue = (negative ? (int)-uvalue : (int)uvalue); + } + + return svalue; +} + +unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, + int* negative, int* overflow) { int scan_state = start; int count = 0; int spaces = 0; - unsigned long value = 0; - unsigned long value_max = 0; + unsigned long long value = 0; + unsigned long long value_max = 0; + unsigned long long ullmax = ULLONG_MAX; int c; *negative = *overflow = 0; @@ -38,13 +66,13 @@ unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int } if (base != 0) { - value_max = ULONG_MAX / base; + value_max = ullmax / base; } while (count <= max_width && c != -1 && !final_state(scan_state)) { switch (scan_state) { case start: - if (isspace(c)) { + if (_isspace(c)) { c = fetch(); count--; spaces++; @@ -95,10 +123,10 @@ unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int } if (!value_max) { - value_max = ULONG_MAX / base; + value_max = ullmax / base; } - if (isdigit(c)) { + if (_isdigit(c)) { if ((c -= '0') >= base) { if (scan_state == digit_loop) { scan_state = finished; @@ -109,7 +137,7 @@ unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int c += '0'; break; } - } else if (!isalpha(c) || (toupper(c) - 'A' + 10) >= base) { + } else if (!_isalpha(c) || (_toupper(c) - 'A' + 10) >= base) { if (scan_state == digit_loop) { scan_state = finished; } else { @@ -118,7 +146,7 @@ unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int break; } else { - c = toupper(c) - 'A' + 10; + c = _toupper(c) - 'A' + 10; } if (value > value_max) { @@ -127,7 +155,7 @@ unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int value *= base; - if (c > (ULONG_MAX - value)) { + if (c > (ullmax - value)) { *overflow = 1; } @@ -149,15 +177,14 @@ unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int return value; } -unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, - int* negative, int* overflow) +unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int), void* ReadProcArg, int* chars_scanned, int* negative, + int* overflow) { - int scan_state = start; - int count = 0; - int spaces = 0; - unsigned long long value = 0; - unsigned long long value_max = 0; - unsigned long long ullmax = ULLONG_MAX; + int scan_state = start; + int count = 0; + int spaces = 0; + unsigned long value = 0; + unsigned long value_max = 0; int c; *negative = *overflow = 0; @@ -169,13 +196,13 @@ unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, in } if (base != 0) { - value_max = ullmax / base; + value_max = ULONG_MAX / base; } while (count <= max_width && c != -1 && !final_state(scan_state)) { switch (scan_state) { case start: - if (isspace(c)) { + if (_isspace(c)) { c = fetch(); count--; spaces++; @@ -226,10 +253,10 @@ unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, in } if (!value_max) { - value_max = ullmax / base; + value_max = ULONG_MAX / base; } - if (isdigit(c)) { + if (_isdigit(c)) { if ((c -= '0') >= base) { if (scan_state == digit_loop) { scan_state = finished; @@ -240,7 +267,7 @@ unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, in c += '0'; break; } - } else if (!isalpha(c) || (toupper(c) - 'A' + 10) >= base) { + } else if (!_isalpha(c) || (_toupper(c) - 'A' + 10) >= base) { if (scan_state == digit_loop) { scan_state = finished; } else { @@ -249,7 +276,7 @@ unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, in break; } else { - c = toupper(c) - 'A' + 10; + c = _toupper(c) - 'A' + 10; } if (value > value_max) { @@ -258,7 +285,7 @@ unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, in value *= base; - if (c > (ullmax - value)) { + if (c > (ULONG_MAX - value)) { *overflow = 1; } @@ -280,74 +307,3 @@ unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, in unfetch(c); return value; } - -unsigned long strtoul(const char* str, char** end, int base) -{ - unsigned long value; - int count, negative, overflow; - - __InStrCtrl isc; - isc.NextChar = (char*)str; - isc.NullCharDetected = 0; - - value = __strtoul(base, 0x7FFFFFFF, &__StringRead, (void*)&isc, &count, &negative, &overflow); - - if (end) { - *end = (char*)str + count; - } - - if (overflow) { - value = ULONG_MAX; - errno = 0x22; - } else if (negative) { - value = -value; - } - - return value; -} - -void strtoull(void) -{ - // UNUSED FUNCTION -} - -long strtol(const char* str, char** end, int base) -{ - unsigned long uvalue; - long svalue; - int count, negative, overflow; - - __InStrCtrl isc; - isc.NextChar = (char*)str; - isc.NullCharDetected = 0; - - uvalue = __strtoul(base, 0x7FFFFFFF, &__StringRead, (void*)&isc, &count, &negative, &overflow); - - if (end) { - *end = (char*)str + count; - } - - if (overflow || (!negative && uvalue > LONG_MAX) || (negative && uvalue > -LONG_MIN)) { - svalue = (negative ? -LONG_MIN : LONG_MAX); - errno = ERANGE; - } else { - svalue = (negative ? (long)-uvalue : (long)uvalue); - } - - return svalue; -} - -void strtoll(void) -{ - // UNUSED FUNCTION -} - -int atoi(const char* str) -{ - // UNUSED FUNCTION -} - -void atol(void) -{ - // UNUSED FUNCTION -} diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c index 67a8ab47f..2b619808d 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/wchar_io.c @@ -1,83 +1,26 @@ -#include "types.h" - #ifndef _MSL_WIDE_CHAR #define _MSL_WIDE_CHAR #endif -#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" - -void putwc(void) -{ - // UNUSED FUNCTION -} - -void putwchar(void) -{ - // UNUSED FUNCTION -} - -void fputwc(void) -{ - // UNUSED FUNCTION -} - -void getwc(void) -{ - // UNUSED FUNCTION -} - -void getwchar(void) -{ - // UNUSED FUNCTION -} - -void fgetwc(void) -{ - // UNUSED FUNCTION -} - -void ungetwc(void) -{ - // UNUSED FUNCTION -} - -void fputws(void) -{ - // UNUSED FUNCTION -} - -void fgetws(void) -{ - // UNUSED FUNCTION -} - -int fwide(FILE* stream, int mode) -{ - int res; - int orientation; - - if (stream == NULL || stream->mMode.file_kind == __closed_file) - return 0; - - orientation = stream->mMode.file_orientation; - switch (orientation) - { - case __unoriented: - if (mode > 0) - stream->mMode.file_orientation = __wide_oriented; - else if (mode < 0) - stream->mMode.file_orientation = __char_oriented; - - res = mode; - break; - - case __wide_oriented: - res = 1; - break; - - case __char_oriented: - res = -1; - break; - } - return res; +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/wchar_io.h" + +int fwide(FILE* file, int mode) +{ + if (!file || file->mMode.file_kind == __closed_file) { + return 0; + } + + switch (file->mMode.file_orientation) { + case __unoriented: + if (mode > 0) { + file->mMode.file_orientation = __wide_oriented; + } else if (mode < 0) { + file->mMode.file_orientation = __char_oriented; + } + return mode; + case __wide_oriented: + return 1; + case __char_oriented: + return -1; + } } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c index 1bbd7a6e3..d025f287c 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_acos.c @@ -57,6 +57,25 @@ qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ +static inline double local_sqrt(double x) +{ + if (x > 0.0) { + double guess = __frsqrte(x); + + guess = 0.5 * guess * (3.0 - guess * guess * x); + guess = 0.5 * guess * (3.0 - guess * guess * x); + guess = 0.5 * guess * (3.0 - guess * guess * x); + guess = 0.5 * guess * (3.0 - guess * guess * x); + return x * guess; + } else if (x == 0.0) { + return 0.0; + } else if (x) { + return NAN; + } + + return *(float*)__float_huge; +} + #ifdef __STDC__ double __ieee754_acos(double x) #else @@ -86,13 +105,13 @@ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ z = (one+x)*0.5; p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - s = sqrt(z); + s = local_sqrt(z); r = p/q; w = r*s-pio2_lo; return pi - 2.0*(s+w); } else { /* x > 0.5 */ z = (one-x)*0.5; - s = sqrt(z); + s = local_sqrt(z); df = s; __LO(df) = 0; c = (z-df*df)/(s+df); @@ -102,4 +121,4 @@ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ w = r*s+c; return 2.0*(df+w); } -} \ No newline at end of file +} diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c index 40d8aaa60..c21588f5e 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_asin.c @@ -66,6 +66,25 @@ static double qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ +static inline double local_sqrt(double x) +{ + if (x > 0.0) { + double guess = __frsqrte(x); + + guess = 0.5 * guess * (3.0 - guess * guess * x); + guess = 0.5 * guess * (3.0 - guess * guess * x); + guess = 0.5 * guess * (3.0 - guess * guess * x); + guess = 0.5 * guess * (3.0 - guess * guess * x); + return x * guess; + } else if (x == 0.0) { + return 0.0; + } else if (x) { + return NAN; + } + + return *(float*)__float_huge; +} + #ifdef __STDC__ double __ieee754_asin(double x) #else @@ -97,7 +116,7 @@ double __ieee754_asin(x) double x; t = w * 0.5; p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5))))); q = one + t * (qS1 + t * (qS2 + t * (qS3 + t * qS4))); - s = sqrt(t); + s = local_sqrt(t); if (ix >= 0x3FEF3333) { /* if |x| > 0.975 */ w = p / q; t = pio2_hi - (2.0 * (s + s * w) - pio2_lo); diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c index 5f9af1132..6b6b8dfb3 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/Math/Double_precision/e_pow.c @@ -154,6 +154,25 @@ ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ +static inline double local_sqrt(double x) +{ + if (x > 0.0) { + double guess = __frsqrte(x); + + guess = 0.5 * guess * (3.0 - guess * guess * x); + guess = 0.5 * guess * (3.0 - guess * guess * x); + guess = 0.5 * guess * (3.0 - guess * guess * x); + guess = 0.5 * guess * (3.0 - guess * guess * x); + return x * guess; + } else if (x == 0.0) { + return 0.0; + } else if (x) { + return NAN; + } + + return *(float*)__float_huge; +} + #ifdef __STDC__ double __ieee754_pow(double x, double y) #else @@ -227,7 +246,7 @@ double __ieee754_pow(x, y) double x, y; return x * x; /* y is 2 */ if (hy == 0x3fe00000) { /* y is 0.5 */ if (hx >= 0) /* x >= +0 */ - return sqrt(x); + return local_sqrt(x); } } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c index 1cb1d9c57..6d2ecbde6 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/ansi_fp.c @@ -2,13 +2,13 @@ #include "ctype.h" #include "limits.h" -static int __count_trailing_zerol(unsigned long x) +static int __count_trailing_zerol(u32 x) { int result = 0; - int bits_not_checked = sizeof(unsigned long) * CHAR_BIT; + int bits_not_checked = sizeof(u32) * CHAR_BIT; int n = bits_not_checked / 2; int mask_size = n; - unsigned long mask = (~0UL) >> (bits_not_checked - n); + u32 mask = (~0UL) >> (bits_not_checked - n); while (bits_not_checked) { if (!(x & mask)) { @@ -31,15 +31,15 @@ static int __count_trailing_zerol(unsigned long x) return result; } -static int __count_trailing_zero(double x) +static int __count_trailing_zero(f64 x) { - unsigned long* l = (unsigned long*)&x; + u32* l = (u32*)&x; if (l[1] != 0) { return __count_trailing_zerol(l[1]); } - return (int)(sizeof(unsigned long) * CHAR_BIT + __count_trailing_zerol(l[0] | 0x00100000)); + return (int)(sizeof(u32) * CHAR_BIT + __count_trailing_zerol(l[0] | 0x00100000)); } static int __must_round(const decimal* d, int digits) @@ -92,18 +92,14 @@ static void __dorounddecup(decimal* d, int digits) static void __rounddec(decimal* d, int digits) { - int unkBool; - if (digits <= 0 || digits >= d->sig.length) - return; - - unkBool = __must_round(d, digits); - d->sig.length = digits; + if (digits > 0 && digits < d->sig.length) { + int unkBool = __must_round(d, digits); + d->sig.length = digits; - if (unkBool >= 0) { - __dorounddecup(d, digits); + if (unkBool >= 0) { + __dorounddecup(d, digits); + } } - - } void __ull2dec(decimal* result, u64 val) @@ -174,7 +170,7 @@ void __timesdec(decimal* result, const decimal* x, const decimal* y) if (l > t) l = t; - for (; l > 0; --l, ++jp, --kp) { + for (; l > 0; l--, jp++, kp--) { accumulator += *jp * *kp; } @@ -182,14 +178,14 @@ void __timesdec(decimal* result, const decimal* x, const decimal* y) accumulator /= 10; } - result->exp = (short)(x->exp + y->exp); + result->exp = (s16)(x->exp + y->exp); if (accumulator) { *--ip = (u8)(accumulator); result->exp++; } - for (i = 0; i < SIGDIGLEN && ip < ep; ++i, ++ip) { + for (i = 0; i < SIGDIGLEN && ip < ep; i++, ip++) { result->sig.text[i] = *ip; } result->sig.length = (u8)(i); @@ -209,7 +205,7 @@ void __timesdec(decimal* result, const decimal* x, const decimal* y) } } -void __str2dec(decimal* d, const char* s, short exp) +void __str2dec(decimal* d, const char* s, s16 exp) { int i; @@ -243,7 +239,7 @@ void __str2dec(decimal* d, const char* s, short exp) } } -void __two_exp(decimal* result, long exp) +void __two_exp(decimal* result, s32 exp) { switch (exp) { case -64: @@ -516,9 +512,9 @@ void __minus_dec(decimal* z, const decimal* x, const decimal* y) z->sig.length = (u8)(i - ib + 1); } -void __num2dec_internal(decimal* d, double x) +void __num2dec_internal(decimal* d, f64 x) { - s8 sign = (s8)(signbit(x) != 0); + signed char sign = (signed char)(signbit(x) != 0); if (x == 0) { d->sign = sign; @@ -532,7 +528,7 @@ void __num2dec_internal(decimal* d, double x) d->sign = sign; d->exp = 0; d->sig.length = 1; - d->sig.text[0] = fpclassify(x) == 1 ? 'N' : 'I'; + d->sig.text[0] = isnan(x) ? 'N' : 'I'; return; } @@ -542,22 +538,22 @@ void __num2dec_internal(decimal* d, double x) { int exp; - double frac = frexp(x, &exp); + double frac = frexp(x, &exp); long num_bits_extract = DBL_MANT_DIG - __count_trailing_zero(frac); double integer; decimal int_d, pow2_d; __two_exp(&pow2_d, exp - num_bits_extract); frac = modf(ldexp(frac, num_bits_extract), &integer); - __ull2dec(&int_d, (u64)integer); + __ull2dec(&int_d, (unsigned long long)integer); __timesdec(d, &int_d, &pow2_d); d->sign = sign; } } -void __num2dec(const decform* form, double x, decimal* d) +void __num2dec(const decform* form, f64 x, decimal* d) { - short digits = form->digits; + s16 digits = form->digits; int i; __num2dec_internal(d, x); @@ -582,7 +578,7 @@ void __num2dec(const decform* form, double x, decimal* d) } } -double __dec2num(const decimal* d) +f64 __dec2num(const decimal* d) { if (d->sig.length <= 0) { return copysign(0.0, d->sign == 0 ? 1.0 : -1.0); @@ -592,9 +588,9 @@ double __dec2num(const decimal* d) case '0': return copysign(0.0, d->sign == 0 ? 1.0 : -1.0); case 'I': - return copysign((double)INFINITY, d->sign == 0 ? 1.0 : -1.0); + return copysign((f64)INFINITY, d->sign == 0 ? 1.0 : -1.0); case 'N': { - double result; + f64 result; u64* ll = (u64*)&result; *ll = 0x7FF0000000000000; @@ -604,7 +600,7 @@ double __dec2num(const decimal* d) if (d->sig.length == 1) *ll |= 0x8000000000000; else { - unsigned char* p = (unsigned char*)&result + 1; + u8* p = (u8*)&result + 1; int placed_non_zero = 0; int low = 1; int i; @@ -613,12 +609,12 @@ double __dec2num(const decimal* d) e = 14; for (i = 1; i < e; ++i) { - unsigned char c = d->sig.text[i]; + u8 c = d->sig.text[i]; - if (isdigit(c)) { + if (_isdigit(c)) { c -= '0'; } else { - c = (unsigned char)(tolower(c) - 'a' + 10); + c = (u8)(_tolower(c) - 'a' + 10); } if (c != 0) { @@ -628,7 +624,7 @@ double __dec2num(const decimal* d) if (low) { *p++ |= c; } else { - *p = (unsigned char)(c << 4); + *p = (u8)(c << 4); } low = !low; @@ -644,12 +640,12 @@ double __dec2num(const decimal* d) } { - static double pow_10[8] = { 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8 }; + static f64 pow_10[8] = { 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8 }; decimal dec = *d; u8* i = dec.sig.text; u8* e = i + dec.sig.length; - double first_guess; + f64 first_guess; int exponent; for (; i < e; ++i) @@ -663,7 +659,7 @@ double __dec2num(const decimal* d) while (i < e) { u32 ival = 0; int j; - double temp1, temp2; + f64 temp1, temp2; int ndig = (int)(e - i) % 8; if (ndig == 0) @@ -745,8 +741,8 @@ double __dec2num(const decimal* d) } } else { decimal feedback2, difflow, diffhigh; - double next_guess = first_guess; - unsigned long long* ull = (unsigned long long*)&next_guess; + double next_guess = first_guess; + u64* ull = (u64*)&next_guess; --*ull; __num2dec_internal(&feedback2, next_guess); @@ -762,7 +758,7 @@ double __dec2num(const decimal* d) __minus_dec(&diffhigh, &feedback1, &dec); if (__equals_dec(&difflow, &diffhigh)) { - if (*(unsigned long long*)&first_guess & 1) { + if (*(u64*)&first_guess & 1) { first_guess = next_guess; } } else if (__less_dec(&difflow, &diffhigh)) { diff --git a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c index 9d427a732..385f1154b 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c @@ -1,57 +1,34 @@ #include "types.h" s32 InitializeUART(u32); /* extern */ -s32 OSGetConsoleType(); /* extern */ s32 WriteUARTN(s32, s32); /* extern */ s32 __TRK_write_console(s32, s32, s32*, s32); /* extern */ -BOOL __write_console(s32 arg0, s32 arg1, s32* arg2, s32 arg3) -{ - - if ((OSGetConsoleType() & 0x20000000) == 0) { - if (__init_uart_console() != 0) { - return TRUE; - } - if (WriteUARTN(arg1, *arg2) != 0) { - *arg2 = 0; - return TRUE; - } - } - __TRK_write_console(arg0, arg1, arg2, arg3); - return FALSE; -} +static BOOL initialized; -int __close_console() +int __close_console(void) { return 0; } -int __init_uart_console(void) +BOOL __write_console(s32 arg0, s32 arg1, s32* arg2, s32 arg3) { - static BOOL initialized; - int ret = 0; - - if (initialized == 0) { - ret = InitializeUART(0xE100); - if (ret == 0) { - initialized = 1; - } - } + s32 ret; - return ret; -} + ret = 0; + if ((initialized == FALSE) && ((ret = InitializeUART(0xE100)) == 0)) { + initialized = TRUE; + } -void __delete_file(void) -{ - // UNUSED FUNCTION -} + if (ret != 0) { + return TRUE; + } -void __rename_file(void) -{ - // UNUSED FUNCTION -} + if (WriteUARTN(arg1, *arg2) != 0) { + *arg2 = 0; + return TRUE; + } -void __temp_file_name(void) -{ - // UNUSED FUNCTION + __TRK_write_console(arg0, arg1, arg2, arg3); + return FALSE; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c b/src/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c index 4da38d45f..50f95c266 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/abort_exit.c @@ -14,61 +14,63 @@ int __aborting; static void (*__atexit_funcs[64])(void); -void abort(void) -{ - raise(1); - __aborting = 1; - __begin_critical_region(atexit_funcs_access); - - while (__atexit_curr_func > 0) - __atexit_funcs[--__atexit_curr_func](); - - __end_critical_region(atexit_funcs_access); - __kill_critical_regions(); - - if (__console_exit != NULL) - { - __console_exit(); - __console_exit = NULL; - } - - _ExitProcess(); -} - void exit(int status) { - int i; void (**dtor)(void); - if (!__aborting) - { + if (!__aborting) { __begin_critical_region(atexit_funcs_access); __end_critical_region(atexit_funcs_access); __destroy_global_chain(); dtor = _dtors; - while (*dtor != NULL) - { + while (*dtor != NULL) { (*dtor)(); dtor++; } - if (__stdio_exit != NULL) - { + if (__stdio_exit != NULL) { __stdio_exit(); __stdio_exit = NULL; } } __begin_critical_region(atexit_funcs_access); - while (__atexit_curr_func > 0) - __atexit_funcs[--__atexit_curr_func](); + dtor = __atexit_funcs; + while (__atexit_curr_func > 0) { + __atexit_curr_func--; + dtor[__atexit_curr_func](); + } + + __end_critical_region(atexit_funcs_access); + __kill_critical_regions(); + + if (__console_exit != NULL) { + __console_exit(); + __console_exit = NULL; + } + + _ExitProcess(); +} + +void abort(void) +{ + void (**func)(void); + + raise(1); + __aborting = 1; + __begin_critical_region(atexit_funcs_access); + + func = __atexit_funcs; + while (__atexit_curr_func > 0) { + __atexit_curr_func--; + func[__atexit_curr_func](); + } __end_critical_region(atexit_funcs_access); __kill_critical_regions(); - if (__console_exit != NULL) - { + if (__console_exit != NULL) { __console_exit(); __console_exit = NULL; } diff --git a/src/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c b/src/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c index d8b2edb5e..d4241e037 100644 --- a/src/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c +++ b/src/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c @@ -1,4 +1,5 @@ #define MATH_INLINE +#define MATH_API_SKIP_FPCLASSIFYD #include "PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h" #include "fdlibm.h" diff --git a/src/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c b/src/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c index 8bd49fcdf..4b797ff44 100644 --- a/src/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c +++ b/src/PowerPC_EABI_Support/src/Runtime/GCN_mem_alloc.c @@ -1,7 +1,7 @@ #include "types.h" #include "Dolphin/os.h" -static void InitDefaultHeap() +inline static void InitDefaultHeap(void) { void* arenaLo; void* arenaHi; @@ -22,15 +22,20 @@ static void InitDefaultHeap() OSSetArenaLo(arenaLo = arenaHi); } -// unused -void __sys_alloc() +__declspec(weak) extern void __sys_free(void* ptr) { + if (__OSCurrHeap == -1) { + InitDefaultHeap(); + } + + OSFreeToHeap(__OSCurrHeap, ptr); } -__declspec(weak) extern void __sys_free(void* ptr) +__declspec(weak) extern void* __sys_alloc(u32 size) { if (__OSCurrHeap == -1) { InitDefaultHeap(); } - OSFreeToHeap(__OSCurrHeap, ptr); + + return OSAllocFromHeap(__OSCurrHeap, size); } diff --git a/src/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp b/src/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp index 293c10010..fca4389f3 100644 --- a/src/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp +++ b/src/PowerPC_EABI_Support/src/Runtime/Gecko_ExceptionPPC.cp @@ -3,6 +3,7 @@ #include "PowerPC_EABI_Support/Runtime/NMWException.h" #include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" +#pragma force_active on #define RETURN_ADDRESS 4 @@ -69,45 +70,12 @@ typedef struct ActionIterator { long current_R31; } ActionIterator; -#define MAXFRAGMENTS 32 +#define MAXFRAGMENTS 1 static ProcessInfo fragmentinfo[MAXFRAGMENTS]; typedef void (*DeleteFunc)(void *); - - -//Likely a fakematch -#pragma schedule once -int __register_fragment(struct __eti_init_info* info, char* TOC){ - - ProcessInfo* f = fragmentinfo; - int i; - - for(i = 0; i < MAXFRAGMENTS; i++, f++){ - if(f->active == 0){ - f->exception_info = info; - f->TOC = TOC; - f->active = 1; - return i; - } - } - - return -1; -} -#pragma schedule twice - -void __unregister_fragment(int fragmentID){ - ProcessInfo* f; - - if(fragmentID >= 0 && fragmentID < MAXFRAGMENTS){ - f = &fragmentinfo[fragmentID]; - f->exception_info = 0; - f->TOC = 0; - f->active = 0; - } -} - -static int ExPPC_FindExceptionFragment(char* returnaddr, FragmentInfo* frag) +static inline int ExPPC_FindExceptionFragment(char* returnaddr, FragmentInfo* frag) { ProcessInfo* f; int i; @@ -137,68 +105,7 @@ static int ExPPC_FindExceptionFragment(char* returnaddr, FragmentInfo* frag) return 0; } - -static void ExPPC_FindExceptionRecord(char* returnaddr, MWExceptionInfo* info){ - FragmentInfo* fragment; - FragmentInfo frag; - ExceptionTableIndex *exceptionindex,*p; - unsigned long returnoffset; - long i,m,n; - - info->exception_record=0; - info->action_pointer=0; - - if ((ExPPC_FindExceptionFragment(returnaddr, &frag)) == 0) return; - fragment = &frag; - - info->code_section = fragment->code_start; - info->data_section = fragment->data_start; - info->TOC = fragment->TOC; - - returnoffset = returnaddr-fragment->code_start; - exceptionindex = fragment->exception_start; - for(i = 0, n = fragment->exception_end-fragment->exception_start;;){ - if(i > n) return; - p = &exceptionindex[m = (i+n)/2]; - - if(returnoffset < p->functionoffset){ - n = m - 1; - }else if(returnoffset > p->functionoffset + ETI_GetFunctionSize(p->eti_field)){ - i = m + 1; - }else break; - } - info->current_function = fragment->code_start + p->functionoffset; - info->exception_record = ETI_GetDirectStore(p->eti_field) ? (ExceptionTableSmall*)(&p->exceptionoffset) : (ExceptionTableSmall*)(fragment->data_start + p->exceptionoffset); - - returnoffset -= p->functionoffset; - - if (ET_IsLargeTable(info->exception_record->et_field)){ - ExceptionTableLarge* etl = (ExceptionTableLarge*)info->exception_record; - ExceptionRangeLarge* erl; - - for(erl = etl->ranges; erl->start != 0; erl++){ - unsigned long range_end = erl->start + (erl->size * 4); - - if (erl->start <= returnoffset && range_end >= returnoffset){ - info->action_pointer = (char*)etl + erl->action; - break; - } - } - }else{ - ExceptionTableSmall* ets = (ExceptionTableSmall*)info->exception_record; - ExceptionRangeSmall* ers; - - for(ers = ets->ranges; ers->start != 0; ers++){ - if(ers->start <= returnoffset && ers->end >= returnoffset){ - info->action_pointer = (char*)ets + ers->action; - break; - } - } - - } -} - -static long ExPPC_PopR31(char *SP,MWExceptionInfo *info){ +static inline long ExPPC_PopR31(char *SP,MWExceptionInfo *info){ double* FPR_save_area; long* GPR_save_area; int saved_GPRs, saved_FPRs; @@ -211,7 +118,7 @@ static long ExPPC_PopR31(char *SP,MWExceptionInfo *info){ return GPR_save_area[-1]; } -static exaction_type ExPPC_CurrentAction(const ActionIterator* iter){ +static inline exaction_type ExPPC_CurrentAction(const ActionIterator* iter){ if(iter->info.action_pointer == 0){ return EXACTION_ENDOFLIST; } @@ -219,136 +126,11 @@ static exaction_type ExPPC_CurrentAction(const ActionIterator* iter){ return ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; } -static exaction_type ExPPC_NextAction(ActionIterator* iter){ - exaction_type action; - - for(;;){ - if(iter->info.action_pointer == 0 || ((action = ((ex_destroylocal*)iter->info.action_pointer)->action) & EXACTION_ENDBIT) != 0){ - char* return_addr, *callers_SP; - - callers_SP = *(char**)iter->current_SP; - - if(ET_GetSavedGPRs(iter->info.exception_record->et_field)){ - iter->current_R31 = ExPPC_PopR31(callers_SP, &iter->info); - } - - return_addr = *(char**)(callers_SP + RETURN_ADDRESS); - - ExPPC_FindExceptionRecord(return_addr, &iter->info); - - if(iter->info.exception_record == 0){ - std::terminate(); - } - - iter->current_SP = callers_SP; - iter->current_FP = (ET_GetHasFramePtr(iter->info.exception_record->et_field)) ? (char*)iter->current_R31 : iter->current_SP; - - if(iter->info.action_pointer == 0) continue; - }else{ - switch(action){ - case EXACTION_DESTROYLOCAL: - iter->info.action_pointer += sizeof(ex_destroylocal); - break; - case EXACTION_DESTROYLOCALCOND: - iter->info.action_pointer += sizeof(ex_destroylocalcond); - break; - case EXACTION_DESTROYLOCALPOINTER: - iter->info.action_pointer += sizeof(ex_destroylocalpointer); - break; - case EXACTION_DESTROYLOCALARRAY: - iter->info.action_pointer += sizeof(ex_destroylocalarray); - break; - case EXACTION_DESTROYBASE: - case EXACTION_DESTROYMEMBER: - iter->info.action_pointer += sizeof(ex_destroymember); - break; - case EXACTION_DESTROYMEMBERCOND: - iter->info.action_pointer += sizeof(ex_destroymembercond); - break; - case EXACTION_DESTROYMEMBERARRAY: - iter->info.action_pointer += sizeof(ex_destroymemberarray); - break; - case EXACTION_DELETEPOINTER: - iter->info.action_pointer += sizeof(ex_deletepointer); - break; - case EXACTION_DELETEPOINTERCOND: - iter->info.action_pointer += sizeof(ex_deletepointercond); - break; - case EXACTION_CATCHBLOCK: - iter->info.action_pointer += sizeof(ex_catchblock); - break; - case EXACTION_CATCHBLOCK_32: - iter->info.action_pointer += sizeof(ex_catchblock_32); - break; - case EXACTION_ACTIVECATCHBLOCK: - iter->info.action_pointer += sizeof(ex_activecatchblock); - break; - case EXACTION_SPECIFICATION: - iter->info.action_pointer += sizeof(ex_specification) + ((ex_specification*)iter->info.action_pointer)->specs * sizeof(void*); - break; - default: - std::terminate(); - } - } - - action = ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; - - if(action == EXACTION_BRANCH){ - iter->info.action_pointer = ((char*)iter->info.exception_record) + ((ex_branch*)iter->info.action_pointer)->target; - action = ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; - } - return action; - } -} - -static char* ExPPC_PopStackFrame(ThrowContext* context, MWExceptionInfo* info){ - char *SP, *callers_SP; - double* FPR_save_area; - long* GPR_save_area; - int saved_GPRs, saved_FPRs; - GeckoFPRContext* Vector_save_area; - int i, j; - - SP = context->SP; - callers_SP = *(char**)SP; - saved_FPRs = ET_GetSavedFPRs(info->exception_record->et_field); - - if(ET_HasElfVector(info->exception_record->et_field)){ - Vector_save_area = (GeckoFPRContext *)(callers_SP - saved_FPRs*16); - FPR_save_area = (double*)Vector_save_area; - }else{ - FPR_save_area = (double*)(callers_SP - saved_FPRs*8); - } - - if (ET_HasElfVector(info->exception_record->et_field)){ - for(i = 32 - saved_FPRs, j = 0; i < 32; ++i, ++j){ - context->FPR[i].v.f[0] = Vector_save_area[j].v.f[0]; - context->FPR[i].v.f[1] = Vector_save_area[j].v.f[1]; - context->FPR[i].d = Vector_save_area[j].d; - } - }else{ - for(i = 32 - saved_FPRs, j = 0; i < 32; ++i, ++j){ - context->FPR[i].d = FPR_save_area[j]; - } - } - - saved_GPRs = ET_GetSavedGPRs(info->exception_record->et_field); - GPR_save_area = (long*)FPR_save_area; - GPR_save_area -= saved_GPRs; - - for(i = 32 - saved_GPRs, j = 0; i < 32; ++i, ++j){ - context->GPR[i] = GPR_save_area[j]; - } - - context->SP = callers_SP; - return *(char**)(callers_SP + RETURN_ADDRESS); -} - -static void ExPPC_DestroyLocal(ThrowContext* context, const ex_destroylocal* ex){ +static inline void ExPPC_DestroyLocal(ThrowContext* context, const ex_destroylocal* ex){ DTORCALL_COMPLETE(ex->dtor, context->FP + ex->local); } -static void ExPPC_DestroyLocalCond(ThrowContext* context, const ex_destroylocalcond* ex){ +static inline void ExPPC_DestroyLocalCond(ThrowContext* context, const ex_destroylocalcond* ex){ int cond = ex_destroylocalcond_GetRegCond(ex->dlc_field) ? (local_cond_type)context->GPR[ex->cond] : *(local_cond_type*)(context->FP + ex->cond); if(cond){ @@ -356,13 +138,13 @@ static void ExPPC_DestroyLocalCond(ThrowContext* context, const ex_destroylocalc } } -static void ExPPC_DestroyLocalPointer(ThrowContext* context, const ex_destroylocalpointer* ex){ +static inline void ExPPC_DestroyLocalPointer(ThrowContext* context, const ex_destroylocalpointer* ex){ void *pointer = ex_destroylocalpointer_GetRegPointer(ex->dlp_field) ? (void*)context->GPR[ex->pointer] : *(void**)(context->FP + ex->pointer); DTORCALL_COMPLETE(ex->dtor, pointer); } -static void ExPPC_DestroyLocalArray(ThrowContext* context, const ex_destroylocalarray* ex){ +static inline void ExPPC_DestroyLocalArray(ThrowContext* context, const ex_destroylocalarray* ex){ char* ptr = context->FP + ex->localarray; long n = ex->elements; long size = ex->element_size; @@ -373,19 +155,19 @@ static void ExPPC_DestroyLocalArray(ThrowContext* context, const ex_destroylocal } } -static void ExPPC_DestroyMember(ThrowContext* context, const ex_destroymember* ex){ +static inline void ExPPC_DestroyMember(ThrowContext* context, const ex_destroymember* ex){ char *objectptr = ex_destroymember_GetRegPointer(ex->dm_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); DTORCALL_COMPLETE(ex->dtor,objectptr + ex->offset); } -static void ExPPC_DestroyBase(ThrowContext* context, const ex_destroymember* ex){ +static inline void ExPPC_DestroyBase(ThrowContext* context, const ex_destroymember* ex){ char* objectptr = ex_destroymember_GetRegPointer(ex->dm_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); DTORCALL_PARTIAL(ex->dtor,objectptr + ex->offset); } -static void ExPPC_DestroyMemberCond(ThrowContext* context, const ex_destroymembercond* ex){ +static inline void ExPPC_DestroyMemberCond(ThrowContext* context, const ex_destroymembercond* ex){ char* objectptr = ex_destroymembercond_GetRegPointer(ex->dmc_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); int cond = ex_destroymembercond_GetRegCond(ex->dmc_field) ? (vbase_ctor_arg_type)context->GPR[ex->cond] : *(vbase_ctor_arg_type*)(context->FP + ex->cond); @@ -394,7 +176,7 @@ static void ExPPC_DestroyMemberCond(ThrowContext* context, const ex_destroymembe } } -static void ExPPC_DestroyMemberArray(ThrowContext* context, const ex_destroymemberarray* ex){ +static inline void ExPPC_DestroyMemberArray(ThrowContext* context, const ex_destroymemberarray* ex){ char* ptr = ex_destroymemberarray_GetRegPointer(ex->dma_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); long n = ex->elements; long size = ex->element_size; @@ -407,13 +189,13 @@ static void ExPPC_DestroyMemberArray(ThrowContext* context, const ex_destroymemb } } -static void ExPPC_DeletePointer(ThrowContext* context, const ex_deletepointer* ex){ +static inline void ExPPC_DeletePointer(ThrowContext* context, const ex_deletepointer* ex){ char* objectptr = ex_deletepointer_GetRegPointer(ex->dp_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); ((DeleteFunc)ex->deletefunc)(objectptr); } -static void ExPPC_DeletePointerCond(ThrowContext* context, const ex_deletepointercond* ex){ +static inline void ExPPC_DeletePointerCond(ThrowContext* context, const ex_deletepointercond* ex){ char* objectptr = ex_deletepointercond_GetRegPointer(ex->dpc_field) ? (char*)context->GPR[ex->objectptr] : *(char**)(context->FP + ex->objectptr); int cond = ex_deletepointercond_GetRegCond(ex->dpc_field) ? (local_cond_type)context->GPR[ex->cond] : *(local_cond_type*)(context->FP+ex->cond); @@ -422,129 +204,30 @@ static void ExPPC_DeletePointerCond(ThrowContext* context, const ex_deletepointe } } -static void ExPPC_UnwindStack(ThrowContext* context, MWExceptionInfo* info, void* catcher){ - exaction_type action; +static inline int ExPPC_IsInSpecification(char* extype, ex_specification* spec){ + long i, offset; - #pragma exception_terminate + for(i = 0; i < spec->specs; i++){ + if(__throw_catch_compare(extype, spec->spec[i], &offset)) return 1; + } - for(;;){ - if(info->action_pointer == 0){ - char* return_addr; - - return_addr = ExPPC_PopStackFrame(context, info); - ExPPC_FindExceptionRecord(return_addr, info); + return 0; +} - if(info->exception_record == 0){ - std::terminate(); - } +// Forward declarations +static void ExPPC_FindExceptionRecord(char* returnaddr, MWExceptionInfo* info); +static void ExPPC_ThrowHandler(ThrowContext* context); +static void ExPPC_UnwindStack(ThrowContext* context, MWExceptionInfo* info, void* catcher); +static char* ExPPC_PopStackFrame(ThrowContext* context, MWExceptionInfo* info); +static exaction_type ExPPC_NextAction(ActionIterator* iter); - context->FP = (ET_GetHasFramePtr(info->exception_record->et_field)) ? (char*)context->GPR[31] : context->SP; - continue; - } +static asm void ExPPC_LongJump(register ThrowContext* context, register void* newRTOC, register void* newPC){ + nofralloc - action = ((ex_destroylocal*)info->action_pointer)->action; - - switch(action & EXACTION_MASK){ - case EXACTION_BRANCH: - info->action_pointer = ((char*)info->exception_record) + ((ex_branch*)info->action_pointer)->target; - break; - case EXACTION_DESTROYLOCAL: - ExPPC_DestroyLocal(context, (ex_destroylocal*)info->action_pointer); - info->action_pointer += sizeof(ex_destroylocal); - break; - case EXACTION_DESTROYLOCALCOND: - ExPPC_DestroyLocalCond(context, (ex_destroylocalcond*)info->action_pointer); - info->action_pointer += sizeof(ex_destroylocalcond); - break; - case EXACTION_DESTROYLOCALPOINTER: - ExPPC_DestroyLocalPointer(context, (ex_destroylocalpointer*)info->action_pointer); - info->action_pointer += sizeof(ex_destroylocalpointer); - break; - case EXACTION_DESTROYLOCALARRAY: - ExPPC_DestroyLocalArray(context, (ex_destroylocalarray*)info->action_pointer); - info->action_pointer += sizeof(ex_destroylocalarray); - break; - case EXACTION_DESTROYBASE: - ExPPC_DestroyBase(context, (ex_destroymember*)info->action_pointer); - info->action_pointer += sizeof(ex_destroymember); - break; - case EXACTION_DESTROYMEMBER: - ExPPC_DestroyMember(context, (ex_destroymember*)info->action_pointer); - info->action_pointer += sizeof(ex_destroymember); - break; - case EXACTION_DESTROYMEMBERCOND: - ExPPC_DestroyMemberCond(context, (ex_destroymembercond*)info->action_pointer); - info->action_pointer += sizeof(ex_destroymembercond); - break; - case EXACTION_DESTROYMEMBERARRAY: - ExPPC_DestroyMemberArray(context, (ex_destroymemberarray*)info->action_pointer); - info->action_pointer += sizeof(ex_destroymemberarray); - break; - case EXACTION_DELETEPOINTER: - ExPPC_DeletePointer(context, (ex_deletepointer*)info->action_pointer); - info->action_pointer += sizeof(ex_deletepointer); - break; - case EXACTION_DELETEPOINTERCOND: - ExPPC_DeletePointerCond(context, (ex_deletepointercond*)info->action_pointer); - info->action_pointer += sizeof(ex_deletepointercond); - break; - case EXACTION_CATCHBLOCK: - if(catcher == (void *)info->action_pointer) return; - info->action_pointer += sizeof(ex_catchblock); - break; - case EXACTION_CATCHBLOCK_32: - if(catcher == (void *)info->action_pointer) return; - info->action_pointer += sizeof(ex_catchblock_32); - break; - case EXACTION_ACTIVECATCHBLOCK: - { - CatchInfo* catchinfo; - - catchinfo = (CatchInfo*)(context->FP + ((ex_activecatchblock*)info->action_pointer)->cinfo_ref); - - if (catchinfo->dtor){ - if (context->location == catchinfo->location){ - context->dtor = catchinfo->dtor; - }else{ - DTORCALL_COMPLETE(catchinfo->dtor, catchinfo->location); - } - } - info->action_pointer += sizeof(ex_activecatchblock); - } - break; - case EXACTION_SPECIFICATION: - if(catcher == (void*)info->action_pointer) return; - info->action_pointer += sizeof(ex_specification) + ((ex_specification*)info->action_pointer)->specs * sizeof(void*); - break; - default: - std::terminate(); - } - - if(action & EXACTION_ENDBIT) info->action_pointer = 0; - } -} - -static int ExPPC_IsInSpecification(char* extype, ex_specification* spec){ - long i, offset; - - for(i = 0; i < spec->specs; i++){ - if(__throw_catch_compare(extype, spec->spec[i], &offset)) return 1; - } - - return 0; -} - -//unused -extern void __unexpected(CatchInfo* catchinfo){ -} - -static asm void ExPPC_LongJump(register ThrowContext* context, register void* newRTOC, register void* newPC){ - nofralloc - - mr r8, newPC - mr RTOC, newRTOC - lwz r0, context->CR - mtcrf 255, r0 + mr r8, newPC + mr RTOC, newRTOC + lwz r0, context->CR + mtcrf 255, r0 lmw r13, context->GPR[13] @@ -629,7 +312,115 @@ static asm void ExPPC_LongJump(register ThrowContext* context, register void* ne blr } -static void ExPPC_HandleUnexpected(ThrowContext* context, MWExceptionInfo* info, ex_specification* unexp){ +asm void __throw(char* throwtype, void* location, void* dtor){ + ThrowContext throwcontext; + + fralloc + + stmw r13, throwcontext.GPR[13] + + stfd fp14, throwcontext.FPR[14].d + la r3, throwcontext.FPR[14].v + psq_stx fp14, 0, r3,0,0 + + stfd fp15, throwcontext.FPR[15].d + la r3, throwcontext.FPR[15].v + psq_stx fp15, 0, r3, 0, 0 + + stfd fp16, throwcontext.FPR[16].d + la r3, throwcontext.FPR[16].v + psq_stx fp16, 0, r3, 0, 0 + + stfd fp17, throwcontext.FPR[17].d + la r3, throwcontext.FPR[17].v + psq_stx fp17, 0, r3, 0, 0 + + stfd fp18, throwcontext.FPR[18].d + la r3, throwcontext.FPR[18].v + psq_stx fp18, 0, r3, 0, 0 + + stfd fp19, throwcontext.FPR[19].d + la r3, throwcontext.FPR[19].v + psq_stx fp19, 0, r3, 0, 0 + + stfd fp20, throwcontext.FPR[20].d + la r3, throwcontext.FPR[20].v + psq_stx fp20, 0, r3, 0, 0 + + stfd fp21, throwcontext.FPR[21].d + la r3, throwcontext.FPR[21].v + psq_stx fp21, 0, r3, 0, 0 + + stfd fp22, throwcontext.FPR[22].d + la r3, throwcontext.FPR[22].v + psq_stx fp22, 0, r3, 0, 0 + + stfd fp23, throwcontext.FPR[23].d + la r3, throwcontext.FPR[23].v + psq_stx fp23, 0, r3, 0, 0 + + stfd fp24, throwcontext.FPR[24].d + la r3, throwcontext.FPR[24].v + psq_stx fp24, 0, r3, 0, 0 + + stfd fp25, throwcontext.FPR[25].d + la r3, throwcontext.FPR[25].v + psq_stx fp25, 0, r3, 0, 0 + + stfd fp26, throwcontext.FPR[26].d + la r3, throwcontext.FPR[26].v + psq_stx fp26, 0, r3, 0, 0 + + stfd fp27, throwcontext.FPR[27].d + la r3, throwcontext.FPR[27].v + psq_stx fp27, 0, r3, 0, 0 + + stfd fp28, throwcontext.FPR[28].d + la r3, throwcontext.FPR[28].v + psq_stx fp28, 0, r3, 0, 0 + + stfd fp29, throwcontext.FPR[29].d + la r3, throwcontext.FPR[29].v + psq_stx fp29, 0, r3, 0, 0 + + stfd fp30, throwcontext.FPR[30].d + la r3, throwcontext.FPR[30].v + psq_stx fp30, 0, r3, 0, 0 + + stfd fp31, throwcontext.FPR[31].d + la r3, throwcontext.FPR[31].v + psq_stx fp31, 0, r3, 0, 0 + + + mfcr r3 + stw r3, throwcontext.CR; + + lwz r3, 0(sp) + lwz r4, RETURN_ADDRESS(r3) + stw r3, throwcontext.SP; + stw r3, throwcontext.throwSP; + stw r4, throwcontext.returnaddr; + + lwz r3,throwtype + stw r3, throwcontext.throwtype + lwz r3,location + stw r3, throwcontext.location + lwz r3,dtor + stw r3, throwcontext.dtor + la r3, throwcontext + bl ExPPC_ThrowHandler + nop + frfree + blr +} + +void __end__catch(CatchInfo* catchinfo){ + if (catchinfo->location && catchinfo->dtor) { + DTORCALL_COMPLETE(catchinfo->dtor, catchinfo->location); + } +} + +static inline void ExPPC_HandleUnexpected(ThrowContext* context, MWExceptionInfo* info, ex_specification* unexp){ CatchInfo* catchinfo; #pragma exception_terminate @@ -784,108 +575,341 @@ static void ExPPC_ThrowHandler(ThrowContext* context){ } } -asm void __throw(char* throwtype, void* location, void* dtor){ - ThrowContext throwcontext; - - fralloc - - stmw r13, throwcontext.GPR[13] - - stfd fp14, throwcontext.FPR[14].d - la r3, throwcontext.FPR[14].v - psq_stx fp14, 0, r3,0,0 +extern void __unexpected(CatchInfo* catchinfo){ + ex_specification* unexp = (ex_specification*)catchinfo->stacktop; - stfd fp15, throwcontext.FPR[15].d - la r3, throwcontext.FPR[15].v - psq_stx fp15, 0, r3, 0, 0 +#pragma exception_magic - stfd fp16, throwcontext.FPR[16].d - la r3, throwcontext.FPR[16].v - psq_stx fp16, 0, r3, 0, 0 + try { + std::unexpected(); + } catch (...) { + if (ExPPC_IsInSpecification((char*)((CatchInfo*)&__exception_magic)->typeinfo, unexp)) { + throw; + } + if (ExPPC_IsInSpecification("!bad_exception!!", unexp)) { + throw std::bad_exception(); + } + if (ExPPC_IsInSpecification("!std::bad_exception!!", unexp)) { + throw std::bad_exception(); + } + } + std::terminate(); +} - stfd fp17, throwcontext.FPR[17].d - la r3, throwcontext.FPR[17].v - psq_stx fp17, 0, r3, 0, 0 +static void ExPPC_UnwindStack(ThrowContext* context, MWExceptionInfo* info, void* catcher){ + exaction_type action; - stfd fp18, throwcontext.FPR[18].d - la r3, throwcontext.FPR[18].v - psq_stx fp18, 0, r3, 0, 0 + #pragma exception_terminate - stfd fp19, throwcontext.FPR[19].d - la r3, throwcontext.FPR[19].v - psq_stx fp19, 0, r3, 0, 0 + for(;;){ + if(info->action_pointer == 0){ + char* return_addr; + + return_addr = ExPPC_PopStackFrame(context, info); + ExPPC_FindExceptionRecord(return_addr, info); - stfd fp20, throwcontext.FPR[20].d - la r3, throwcontext.FPR[20].v - psq_stx fp20, 0, r3, 0, 0 + if(info->exception_record == 0){ + std::terminate(); + } - stfd fp21, throwcontext.FPR[21].d - la r3, throwcontext.FPR[21].v - psq_stx fp21, 0, r3, 0, 0 + context->FP = (ET_GetHasFramePtr(info->exception_record->et_field)) ? (char*)context->GPR[31] : context->SP; + continue; + } - stfd fp22, throwcontext.FPR[22].d - la r3, throwcontext.FPR[22].v - psq_stx fp22, 0, r3, 0, 0 + action = ((ex_destroylocal*)info->action_pointer)->action; - stfd fp23, throwcontext.FPR[23].d - la r3, throwcontext.FPR[23].v - psq_stx fp23, 0, r3, 0, 0 + switch(action & EXACTION_MASK){ + case EXACTION_BRANCH: + info->action_pointer = ((char*)info->exception_record) + ((ex_branch*)info->action_pointer)->target; + break; + case EXACTION_DESTROYLOCAL: + ExPPC_DestroyLocal(context, (ex_destroylocal*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocal); + break; + case EXACTION_DESTROYLOCALCOND: + ExPPC_DestroyLocalCond(context, (ex_destroylocalcond*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocalcond); + break; + case EXACTION_DESTROYLOCALPOINTER: + ExPPC_DestroyLocalPointer(context, (ex_destroylocalpointer*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocalpointer); + break; + case EXACTION_DESTROYLOCALARRAY: + ExPPC_DestroyLocalArray(context, (ex_destroylocalarray*)info->action_pointer); + info->action_pointer += sizeof(ex_destroylocalarray); + break; + case EXACTION_DESTROYBASE: + ExPPC_DestroyBase(context, (ex_destroymember*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymember); + break; + case EXACTION_DESTROYMEMBER: + ExPPC_DestroyMember(context, (ex_destroymember*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymember); + break; + case EXACTION_DESTROYMEMBERCOND: + ExPPC_DestroyMemberCond(context, (ex_destroymembercond*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymembercond); + break; + case EXACTION_DESTROYMEMBERARRAY: + ExPPC_DestroyMemberArray(context, (ex_destroymemberarray*)info->action_pointer); + info->action_pointer += sizeof(ex_destroymemberarray); + break; + case EXACTION_DELETEPOINTER: + ExPPC_DeletePointer(context, (ex_deletepointer*)info->action_pointer); + info->action_pointer += sizeof(ex_deletepointer); + break; + case EXACTION_DELETEPOINTERCOND: + ExPPC_DeletePointerCond(context, (ex_deletepointercond*)info->action_pointer); + info->action_pointer += sizeof(ex_deletepointercond); + break; + case EXACTION_CATCHBLOCK: + if(catcher == (void *)info->action_pointer) return; + info->action_pointer += sizeof(ex_catchblock); + break; + case EXACTION_CATCHBLOCK_32: + if(catcher == (void *)info->action_pointer) return; + info->action_pointer += sizeof(ex_catchblock_32); + break; + case EXACTION_ACTIVECATCHBLOCK: + { + CatchInfo* catchinfo; - stfd fp24, throwcontext.FPR[24].d - la r3, throwcontext.FPR[24].v - psq_stx fp24, 0, r3, 0, 0 + catchinfo = (CatchInfo*)(context->FP + ((ex_activecatchblock*)info->action_pointer)->cinfo_ref); + + if (catchinfo->dtor){ + if (context->location == catchinfo->location){ + context->dtor = catchinfo->dtor; + }else{ + DTORCALL_COMPLETE(catchinfo->dtor, catchinfo->location); + } + } + info->action_pointer += sizeof(ex_activecatchblock); + } + break; + case EXACTION_SPECIFICATION: + if(catcher == (void*)info->action_pointer) return; + info->action_pointer += sizeof(ex_specification) + ((ex_specification*)info->action_pointer)->specs * sizeof(void*); + break; + default: + std::terminate(); + } - stfd fp25, throwcontext.FPR[25].d - la r3, throwcontext.FPR[25].v - psq_stx fp25, 0, r3, 0, 0 + if(action & EXACTION_ENDBIT) info->action_pointer = 0; + } +} - stfd fp26, throwcontext.FPR[26].d - la r3, throwcontext.FPR[26].v - psq_stx fp26, 0, r3, 0, 0 +static char* ExPPC_PopStackFrame(ThrowContext* context, MWExceptionInfo* info){ + char *SP, *callers_SP; + double* FPR_save_area; + long* GPR_save_area; + int saved_GPRs, saved_FPRs; + GeckoFPRContext* Vector_save_area; + int i, j; + + SP = context->SP; + callers_SP = *(char**)SP; + saved_FPRs = ET_GetSavedFPRs(info->exception_record->et_field); - stfd fp27, throwcontext.FPR[27].d - la r3, throwcontext.FPR[27].v - psq_stx fp27, 0, r3, 0, 0 + if(ET_HasElfVector(info->exception_record->et_field)){ + Vector_save_area = (GeckoFPRContext *)(callers_SP - saved_FPRs*16); + FPR_save_area = (double*)Vector_save_area; + }else{ + FPR_save_area = (double*)(callers_SP - saved_FPRs*8); + } - stfd fp28, throwcontext.FPR[28].d - la r3, throwcontext.FPR[28].v - psq_stx fp28, 0, r3, 0, 0 + if (ET_HasElfVector(info->exception_record->et_field)){ + for(i = 32 - saved_FPRs, j = 0; i < 32; ++i, ++j){ + context->FPR[i].v.f[0] = Vector_save_area[j].v.f[0]; + context->FPR[i].v.f[1] = Vector_save_area[j].v.f[1]; + context->FPR[i].d = Vector_save_area[j].d; + } + }else{ + for(i = 32 - saved_FPRs, j = 0; i < 32; ++i, ++j){ + context->FPR[i].d = FPR_save_area[j]; + } + } - stfd fp29, throwcontext.FPR[29].d - la r3, throwcontext.FPR[29].v - psq_stx fp29, 0, r3, 0, 0 + saved_GPRs = ET_GetSavedGPRs(info->exception_record->et_field); + GPR_save_area = (long*)FPR_save_area; + GPR_save_area -= saved_GPRs; - stfd fp30, throwcontext.FPR[30].d - la r3, throwcontext.FPR[30].v - psq_stx fp30, 0, r3, 0, 0 + for(i = 32 - saved_GPRs, j = 0; i < 32; ++i, ++j){ + context->GPR[i] = GPR_save_area[j]; + } - stfd fp31, throwcontext.FPR[31].d - la r3, throwcontext.FPR[31].v - psq_stx fp31, 0, r3, 0, 0 + context->SP = callers_SP; + return *(char**)(callers_SP + RETURN_ADDRESS); +} +static exaction_type ExPPC_NextAction(ActionIterator* iter){ + exaction_type action; - mfcr r3 - stw r3, throwcontext.CR; + for(;;){ + if(iter->info.action_pointer == 0 || ((action = ((ex_destroylocal*)iter->info.action_pointer)->action) & EXACTION_ENDBIT) != 0){ + char* return_addr, *callers_SP; + + callers_SP = *(char**)iter->current_SP; - lwz r3, 0(sp) - lwz r4, RETURN_ADDRESS(r3) - stw r3, throwcontext.SP; - stw r3, throwcontext.throwSP; - stw r4, throwcontext.returnaddr; + if(ET_GetSavedGPRs(iter->info.exception_record->et_field)){ + iter->current_R31 = ExPPC_PopR31(callers_SP, &iter->info); + } - lwz r3,throwtype - stw r3, throwcontext.throwtype - lwz r3,location - stw r3, throwcontext.location - lwz r3,dtor - stw r3, throwcontext.dtor - la r3, throwcontext - bl ExPPC_ThrowHandler - nop - frfree - blr + return_addr = *(char**)(callers_SP + RETURN_ADDRESS); + + ExPPC_FindExceptionRecord(return_addr, &iter->info); + + if(iter->info.exception_record == 0){ + std::terminate(); + } + + iter->current_SP = callers_SP; + iter->current_FP = (ET_GetHasFramePtr(iter->info.exception_record->et_field)) ? (char*)iter->current_R31 : iter->current_SP; + + if(iter->info.action_pointer == 0) continue; + }else{ + switch(action){ + case EXACTION_DESTROYLOCAL: + iter->info.action_pointer += sizeof(ex_destroylocal); + break; + case EXACTION_DESTROYLOCALCOND: + iter->info.action_pointer += sizeof(ex_destroylocalcond); + break; + case EXACTION_DESTROYLOCALPOINTER: + iter->info.action_pointer += sizeof(ex_destroylocalpointer); + break; + case EXACTION_DESTROYLOCALARRAY: + iter->info.action_pointer += sizeof(ex_destroylocalarray); + break; + case EXACTION_DESTROYBASE: + case EXACTION_DESTROYMEMBER: + iter->info.action_pointer += sizeof(ex_destroymember); + break; + case EXACTION_DESTROYMEMBERCOND: + iter->info.action_pointer += sizeof(ex_destroymembercond); + break; + case EXACTION_DESTROYMEMBERARRAY: + iter->info.action_pointer += sizeof(ex_destroymemberarray); + break; + case EXACTION_DELETEPOINTER: + iter->info.action_pointer += sizeof(ex_deletepointer); + break; + case EXACTION_DELETEPOINTERCOND: + iter->info.action_pointer += sizeof(ex_deletepointercond); + break; + case EXACTION_CATCHBLOCK: + iter->info.action_pointer += sizeof(ex_catchblock); + break; + case EXACTION_CATCHBLOCK_32: + iter->info.action_pointer += sizeof(ex_catchblock_32); + break; + case EXACTION_ACTIVECATCHBLOCK: + iter->info.action_pointer += sizeof(ex_activecatchblock); + break; + case EXACTION_SPECIFICATION: + iter->info.action_pointer += sizeof(ex_specification) + ((ex_specification*)iter->info.action_pointer)->specs * sizeof(void*); + break; + default: + std::terminate(); + } + } + + action = ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; + + if(action == EXACTION_BRANCH){ + iter->info.action_pointer = ((char*)iter->info.exception_record) + ((ex_branch*)iter->info.action_pointer)->target; + action = ((ex_destroylocal*)iter->info.action_pointer)->action & EXACTION_MASK; + } + return action; + } } -//unused -void __end__catch(CatchInfo* catchinfo){ +static void ExPPC_FindExceptionRecord(char* returnaddr, MWExceptionInfo* info){ + FragmentInfo* fragment; + FragmentInfo frag; + ExceptionTableIndex *exceptionindex,*p; + unsigned long returnoffset; + long i,m,n; + + info->exception_record=0; + info->action_pointer=0; + + if ((ExPPC_FindExceptionFragment(returnaddr, &frag)) == 0) return; + fragment = &frag; + + info->code_section = fragment->code_start; + info->data_section = fragment->data_start; + info->TOC = fragment->TOC; + + returnoffset = returnaddr-fragment->code_start; + exceptionindex = fragment->exception_start; + for(i = 0, n = fragment->exception_end-fragment->exception_start;;){ + if(i > n) return; + p = &exceptionindex[m = (i+n)/2]; + + if(returnoffset < p->functionoffset){ + n = m - 1; + }else if(returnoffset > p->functionoffset + ETI_GetFunctionSize(p->eti_field)){ + i = m + 1; + }else break; + } + info->current_function = fragment->code_start + p->functionoffset; + info->exception_record = ETI_GetDirectStore(p->eti_field) ? (ExceptionTableSmall*)(&p->exceptionoffset) : (ExceptionTableSmall*)(fragment->data_start + p->exceptionoffset); + + returnoffset -= p->functionoffset; + + if (ET_IsLargeTable(info->exception_record->et_field)){ + ExceptionTableLarge* etl = (ExceptionTableLarge*)info->exception_record; + ExceptionRangeLarge* erl; + + for(erl = etl->ranges; erl->start != 0; erl++){ + unsigned long range_end = erl->start + (erl->size * 4); + + if (erl->start <= returnoffset && range_end >= returnoffset){ + info->action_pointer = (char*)etl + erl->action; + break; + } + } + }else{ + ExceptionTableSmall* ets = (ExceptionTableSmall*)info->exception_record; + ExceptionRangeSmall* ers; + + for(ers = ets->ranges; ers->start != 0; ers++){ + if(ers->start <= returnoffset && ers->end >= returnoffset){ + info->action_pointer = (char*)ets + ers->action; + break; + } + } + + } +} + +void __unregister_fragment(int fragmentID){ + ProcessInfo* f; + + if(fragmentID >= 0 && fragmentID < MAXFRAGMENTS){ + f = &fragmentinfo[fragmentID]; + f->exception_info = 0; + f->TOC = 0; + f->active = 0; + } } + +//Likely a fakematch +#pragma schedule once +int __register_fragment(struct __eti_init_info* info, char* TOC){ + + ProcessInfo* f = fragmentinfo; + int i; + + for(i = 0; i < MAXFRAGMENTS; i++, f++){ + if(f->active == 0){ + f->exception_info = info; + f->TOC = TOC; + f->active = 1; + return i; + } + } + + return -1; +} +#pragma schedule twice diff --git a/src/PowerPC_EABI_Support/src/Runtime/NMWException.cp b/src/PowerPC_EABI_Support/src/Runtime/NMWException.cp index bef12ad6c..22cbc7a6b 100644 --- a/src/PowerPC_EABI_Support/src/Runtime/NMWException.cp +++ b/src/PowerPC_EABI_Support/src/Runtime/NMWException.cp @@ -10,52 +10,143 @@ extern "C" namespace std { + static void dthandler(); + + static terminate_handler thandler = dthandler; + + static void duhandler(); + + static unexpected_handler uhandler = duhandler; + + extern void terminate(); + extern void unexpected(); + static void dthandler() { abort(); } - terminate_handler thandler = dthandler; - static void duhandler() { - terminate(); + thandler(); } - unexpected_handler uhandler = duhandler; - extern void terminate() { thandler(); - } + } - extern void unexpected() { + extern void unexpected() + { uhandler(); } } extern "C" char __throw_catch_compare(const char* throwtype, const char* catchtype, s32* offset_result) { - return 0; -} + const char* cptr1; + const char* cptr2; -extern "C" void *__construct_new_array(void *block, ConstructorDestructor ctor, ConstructorDestructor dtor_arg, size_t size, size_t n) -{ - return 0 ; + *offset_result = 0; + + if ((cptr2 = catchtype) == 0) { + return true; + } + + cptr1 = throwtype; + + if (*cptr2 == 'P') { + cptr2++; + if (*cptr2 == 'C') { + cptr2++; + } + if (*cptr2 == 'V') { + cptr2++; + } + if (*cptr2 == 'v') { + if (*cptr1 == 'P' || *cptr1 == '*') { + return true; + } + } + cptr2 = catchtype; + } + + switch (*cptr1) { + case '*': + case '!': + if (*cptr1++ != *cptr2++) { + return false; + } + for (;;) { + if (*cptr1 == *cptr2++) { + if (*cptr1++ == '!') { + s32 offset; + + for (offset = 0; *cptr1 != '!'; ) { + offset = offset * 10 + *cptr1++ - '0'; + } + *offset_result = offset; + return true; + } + } else { + while (*cptr1++ != '!') {} + while (*cptr1++ != '!') {} + if (*cptr1 == 0) { + return false; + } + + cptr2 = catchtype + 1; + } + } + return false; + } + + while ((*cptr1 == 'P' || *cptr1 == 'R') && *cptr1 == *cptr2) { + cptr1++; + cptr2++; + + if (*cptr2 == 'C') { + if (*cptr1 == 'C') { + cptr1++; + } + cptr2++; + } + if (*cptr1 == 'C') { + return false; + } + + if (*cptr2 == 'V') { + if (*cptr1 == 'V') { + cptr1++; + } + cptr2++; + } + if (*cptr1 == 'V') { + return false; + } + } + + for (; *cptr1 == *cptr2; cptr1++, cptr2++) { + if (*cptr1 == 0) { + return true; + } + } + + return false; } class __partial_array_destructor { private: - void *p; + void* p; size_t size; size_t n; - void *dtor; + ConstructorDestructor dtor; public: size_t i; - __partial_array_destructor(void *array, size_t elementsize, size_t nelements, void *destructor) + __partial_array_destructor(void* array, size_t elementsize, size_t nelements, ConstructorDestructor destructor) { p = array; size = elementsize; @@ -64,14 +155,12 @@ public: i = n; } - ~__partial_array_destructor() + inline ~__partial_array_destructor() { - char *ptr; + char* ptr; - if (i < n && dtor) - { - for (ptr = (char *)p + size * i; i > 0; i--) - { + if (i < n && dtor) { + for (ptr = (char*)p + size * i; i > 0; i--) { ptr -= size; DTORCALL_COMPLETE(dtor, ptr); } @@ -79,13 +168,12 @@ public: } }; - -extern "C" void __construct_array(void *ptr, void *ctor, void *dtor, size_t size, size_t n) -{ - -} - -extern "C" void __destroy_arr(void *block, ConstructorDestructor *dtor, size_t size, size_t n) +extern "C" void __construct_array(void* ptr, ConstructorDestructor ctor, ConstructorDestructor dtor, size_t size, size_t n) { + __partial_array_destructor pad(ptr, size, n, dtor); + char* p; + for (pad.i = 0, p = (char*)ptr; pad.i < n; pad.i++, p += size) { + CTORCALL_COMPLETE(ctor, p); + } } diff --git a/src/PowerPC_EABI_Support/src/Runtime/New.cp b/src/PowerPC_EABI_Support/src/Runtime/New.cp index e5e2d5986..64d051382 100644 --- a/src/PowerPC_EABI_Support/src/Runtime/New.cp +++ b/src/PowerPC_EABI_Support/src/Runtime/New.cp @@ -1,5 +1,28 @@ -#include "PowerPC_EABI_Support/Runtime/Gecko_ExceptionPPC.h" -#include "PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h" -#include "PowerPC_EABI_Support/Runtime/NMWException.h" -#include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" +#include "PowerPC_EABI_Support/Runtime/New.h" +namespace std +{ +class exception +{ +public: + exception() {} + virtual ~exception() {} + virtual const char* what() const; +}; + +__declspec(weak) const char* exception::what() const +{ + return "exception"; +} +} + +extern "C" { +void free(void*); +} + +__declspec(weak) void operator delete(void* arg0) throw() +{ + if (arg0 != 0) { + free(arg0); + } +} diff --git a/src/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp b/src/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp index 617b7374d..23638e5cf 100644 --- a/src/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp +++ b/src/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp @@ -3,16 +3,20 @@ #include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" #include "PowerPC_EABI_Support/Runtime/__init_cpp_exceptions.h" +#ifdef __MWERKS__ +#undef __declspec +#endif + static int fragmentID = -2; extern char *GetR2() ; -void __init_cpp_exceptions() -{ - if ((s32)fragmentID == -2) { - char* R2 = GetR2(); - fragmentID = __register_fragment(&_eti_init_info, R2); - } +// clang-format off +asm char* GetR2() +{ + nofralloc + mr r3, r2 + blr } // clang-format on @@ -24,14 +28,14 @@ void __fini_cpp_exceptions() } } -// clang-format off -asm char* GetR2() -{ - nofralloc - mr r3, r2 - blr +void __init_cpp_exceptions() +{ + if ((s32)fragmentID == -2) { + char* R2 = GetR2(); + fragmentID = __register_fragment(_eti_init_info, R2); + } } __declspec(section ".ctors") extern void* const __init_cpp_exceptions_reference = __init_cpp_exceptions; __declspec(section ".dtors") extern void* const __destroy_global_chain_reference = __destroy_global_chain; -__declspec(section ".dtors") extern void* const __fini_cpp_exceptions_reference = __fini_cpp_exceptions; \ No newline at end of file +__declspec(section ".dtors") extern void* const __fini_cpp_exceptions_reference = __fini_cpp_exceptions; diff --git a/src/PowerPC_EABI_Support/src/Runtime/__mem.c b/src/PowerPC_EABI_Support/src/Runtime/__mem.c index a9a4a5a67..78cf24824 100644 --- a/src/PowerPC_EABI_Support/src/Runtime/__mem.c +++ b/src/PowerPC_EABI_Support/src/Runtime/__mem.c @@ -1,103 +1,88 @@ -#include -#include +#include "PowerPC_EABI_Support/Runtime/__mem.h" -void* memset(void* dst, int c, size_t n) +__declspec(section ".init") void* memset(void* dst, int val, size_t n) { - __fill_mem(dst, c, n); - return dst; + __fill_mem(dst, val, n); + + return (dst); } -void __fill_mem(void* dst, int c, size_t n) +__declspec(section ".init") void __fill_mem(void* dst, int val, unsigned long n) { - u8* cdest; - u32* idest; - u32 i; - u32 cval; + unsigned long v = (unsigned char)val; + unsigned long i; - cval = (u8)c; - cdest = (u8*)dst - 1; + ((unsigned char*)dst) = ((unsigned char*)dst) - 1; if (n >= 32) { - i = ~(u32)cdest & 3; - if (i != 0) + i = (~(unsigned long)dst) & 3; + + if (i) { - n = n - i; + n -= i; + do - { - *(++cdest) = (u8)cval; - } while (--i); - } - if (cval != 0) - { - cval = cval << 24 | cval << 16 | cval << 8 | cval; + *++(((unsigned char*)dst)) = v; + while (--i); } - idest = (u32*)(cdest - 3); + if (v) + v |= v << 24 | v << 16 | v << 8; + + ((unsigned long*)dst) = ((unsigned long*)(((unsigned char*)dst) + 1)) - 1; + i = n >> 5; - if (i != 0) - { + + if (i) do { - idest[1] = cval; // 4 - idest[2] = cval; // 8 - idest[3] = cval; // c - idest[4] = cval; // 10 - idest[5] = cval; // 14 - idest[6] = cval; // 18 - idest[7] = cval; // 1c - *(idest += 8) = cval; // 20 + *++(((unsigned long*)dst)) = v; + *++(((unsigned long*)dst)) = v; + *++(((unsigned long*)dst)) = v; + *++(((unsigned long*)dst)) = v; + *++(((unsigned long*)dst)) = v; + *++(((unsigned long*)dst)) = v; + *++(((unsigned long*)dst)) = v; + *++(((unsigned long*)dst)) = v; } while (--i); - } - i = (n >> 2) & 7; + i = (n & 31) >> 2; - if (i != 0) - { + if (i) do - { - *++idest = cval; - } while (--i); - } + *++(((unsigned long*)dst)) = v; + while (--i); + + ((unsigned char*)dst) = ((unsigned char*)(((unsigned long*)dst) + 1)) - 1; - cdest = (u8*)idest + 3; n &= 3; } - if (n != 0) - { + + if (n) do - { - *++cdest = (u8)cval; - } while (--n); - } + *++(((unsigned char*)dst)) = v; + while (--n); + + return; } -void* memcpy(void* dst, const void* src, size_t n) +__declspec(section ".init") void* memcpy(void* dst, const void* src, size_t n) { - u8* __src; - u8* __dst; - int i; + const char* p; + char* q; + int rev = ((unsigned long)src < (unsigned long)dst); - if (src >= dst) + if (!rev) { - __src = ((u8*)src) - 1; - __dst = ((u8*)dst) - 1; - i = n + 1; - while (--i) - { - *((u8*)++__dst) = *((u8*)++__src); - } - return dst; + for (p = (const char*)src - 1, q = (char*)dst - 1, n++; --n;) + *++q = *++p; } else { - __src = ((u8*)src) + n; - __dst = ((u8*)dst) + n; - i = n + 1; - while (--i) - { - *((u8*)--__dst) = *((u8*)--__src); - } - return dst; + for (p = (const char*)src + n, q = (char*)dst + n, n++; --n;) + *--q = *--p; } + + return (dst); } diff --git a/src/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c b/src/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c index b09b0fa2a..349210f76 100644 --- a/src/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c +++ b/src/PowerPC_EABI_Support/src/Runtime/global_destructor_chain.c @@ -1,6 +1,10 @@ #include "PowerPC_EABI_Support/Runtime/global_destructor_chain.h" #include "PowerPC_EABI_Support/Runtime/MWCPlusPlusLib.h" +#ifdef __MWERKS__ +#undef __declspec +#endif + DestructorChain* __global_destructor_chain; void __destroy_global_chain(void) diff --git a/src/PowerPC_EABI_Support/src/Runtime/runtime.c b/src/PowerPC_EABI_Support/src/Runtime/runtime.c index 94da236b7..eb61686e8 100644 --- a/src/PowerPC_EABI_Support/src/Runtime/runtime.c +++ b/src/PowerPC_EABI_Support/src/Runtime/runtime.c @@ -789,6 +789,7 @@ asm void __cvt_ull_dbl(void) asm void __cvt_sll_flt(void) { + nofralloc; stwu r1, -0x10(r1); clrrwi.r5, r3, 31; beq L_802BA62C; @@ -837,7 +838,6 @@ L_802BA6B4:; lfd f1, 0x8(r1); frsp f1, f1; addi r1, r1, 0x10; - frfree; // Build error said to add this blr } @@ -968,4 +968,4 @@ end:; #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/src/dolphin/src/os/OS.c b/src/dolphin/src/os/OS.c index 626561042..a9a1d292e 100644 --- a/src/dolphin/src/os/OS.c +++ b/src/dolphin/src/os/OS.c @@ -8,7 +8,7 @@ extern OSTime __OSGetSystemTime(); static const char* __OSVersion = "<< Dolphin SDK - OS\trelease build: Apr 17 2003 12:33:06 (0x2301) >>"; // needs to be "<< Dolphin SDK - DSP\trelease build: Apr 17 2003 12:34:16 (0x2301) >>"? -extern char _db_stack_end[]; +extern char _stack_addr[]; #define OS_BI2_DEBUG_ADDRESS 0x800000F4 #define DEBUGFLAG_ADDR 0x800030E8 @@ -270,19 +270,19 @@ void OSInit(void) // set up bottom of heap (ArenaLo) // grab address from BootInfo if it exists, otherwise use default __ArenaLo - OSSetArenaLo((BootInfo->arenaLo == NULL) ? __ArenaLo : BootInfo->arenaLo); + OSSetArenaLo((BootInfo->arenaLo == NULL) ? &__ArenaLo : BootInfo->arenaLo); // if the input arenaLo is null, and debug flag location exists (and flag is < 2), // set arenaLo to just past the end of the db stack if ((BootInfo->arenaLo == NULL) && (BI2DebugFlag != 0) && (*BI2DebugFlag < 2)) { - debugArenaLo = (char*)(((u32)_db_stack_end + 0x1f) & ~0x1f); + debugArenaLo = (void*)(((u32)(char*)&_stack_addr + 0x1f) & ~0x1f); OSSetArenaLo(debugArenaLo); } // set up top of heap (ArenaHi) // grab address from BootInfo if it exists, otherwise use default __ArenaHi - OSSetArenaHi((BootInfo->arenaHi == NULL) ? __ArenaHi : BootInfo->arenaHi); + OSSetArenaHi((BootInfo->arenaHi == NULL) ? &__ArenaHi : BootInfo->arenaHi); // OS INIT AND REPORT // // initialise a whole bunch of OS stuff diff --git a/src/dolphin/src/os/OSThread.c b/src/dolphin/src/os/OSThread.c index 2d2adf809..bb6b509ef 100644 --- a/src/dolphin/src/os/OSThread.c +++ b/src/dolphin/src/os/OSThread.c @@ -20,8 +20,8 @@ static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) { } -extern u8 _stack_addr[]; -extern u8 _stack_end[]; +DECL_SECTION(".init") extern char _stack_addr[]; +DECL_SECTION(".init") extern char _stack_end[]; #define AddTail(queue, thread, link) \ do \ @@ -119,8 +119,8 @@ void __OSThreadInit() OSClearContext(&thread->context); OSSetCurrentContext(&thread->context); - thread->stackBase = (void*)_stack_addr; - thread->stackEnd = (void*)_stack_end; + thread->stackBase = (u8*)&_stack_addr; + thread->stackEnd = (u32*)&_stack_end; *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; OSSetCurrentThread(thread); diff --git a/src/dolphin/src/os/init/__ppc_eabi_init.cpp b/src/dolphin/src/os/init/__ppc_eabi_init.cpp index 6f5b2765a..70806d049 100644 --- a/src/dolphin/src/os/init/__ppc_eabi_init.cpp +++ b/src/dolphin/src/os/init/__ppc_eabi_init.cpp @@ -15,8 +15,10 @@ __declspec(section ".dtors") extern voidfunctionptr _dtors[]; static void __init_cpp(void); +#pragma section code_type ".init" + // clang-format off -__declspec(section ".init") asm void __init_hardware(void) +asm void __init_hardware(void) { // clang-format off nofralloc mfmsr r0 @@ -30,7 +32,7 @@ __declspec(section ".init") asm void __init_hardware(void) blr } -__declspec(section ".init") asm void __flush_cache(void *address, unsigned int size) +asm void __flush_cache(void *address, unsigned int size) { // clang-format off nofralloc lis r5, 0xffff @@ -50,6 +52,8 @@ __declspec(section ".init") asm void __flush_cache(void *address, unsigned int s } // clang-format on +#pragma section code_type + void __init_user(void) { __init_cpp(); diff --git a/src/dolphin/src/os/init/__start.c b/src/dolphin/src/os/init/__start.c index 184665aee..dda75ec53 100644 --- a/src/dolphin/src/os/init/__start.c +++ b/src/dolphin/src/os/init/__start.c @@ -2,26 +2,27 @@ #include "PowerPC_EABI_Support/Runtime/__ppc_eabi_linker.h" #include "PowerPC_EABI_Support/MetroTRK/dolphin_trk.h" -void __check_pad3(void) +#ifdef __MWERKS__ +#undef __declspec +#endif + +#define SECTION_INIT __declspec(section ".init") + +#pragma section code_type ".init" + +SECTION_INIT void __check_pad3(void) { if ((Pad3Button & 0x0eef) == 0x0eef) { OSResetSystem(OS_RESET_RESTART, 0, FALSE); } - return; } -void __set_debug_bba(void) -{ - Debug_BBA = 1; -} +SECTION_INIT void __set_debug_bba(void) { Debug_BBA = 1; } -u8 __get_debug_bba(void) -{ - return Debug_BBA; -} +SECTION_INIT u8 __get_debug_bba(void) { return Debug_BBA; } -__declspec(weak) asm void __start(void) +SECTION_INIT __declspec(weak) asm void __start(void) { // clang-format off nofralloc @@ -137,25 +138,7 @@ __declspec(weak) asm void __start(void) // clang-format on } -__declspec(section ".init") inline void __copy_rom_section(void* dst, const void* src, - unsigned long size) -{ - if (size && (dst != src)) - { - memcpy(dst, src, size); - __flush_cache(dst, size); - } -} - -__declspec(section ".init") inline void __init_bss_section(void* dst, unsigned long size) -{ - if (size) - { - memset(dst, 0, size); - } -} - -asm static void __init_registers(void) +SECTION_INIT asm void __init_registers(void) { // clang-format off nofralloc @@ -194,11 +177,28 @@ asm static void __init_registers(void) ori r2, r2, _SDA2_BASE_@l lis r13, _SDA_BASE_@h ori r13, r13, _SDA_BASE_@l - blr + blr // clang-format on } -void __init_data(void) +inline static void __copy_rom_section(void* dst, const void* src, u32 size) +{ + if (size && (dst != src)) + { + memcpy(dst, src, size); + __flush_cache(dst, size); + } +} + +inline static void __init_bss_section(void* dst, u32 size) +{ + if (size) + { + memset(dst, 0, size); + } +} + +SECTION_INIT void __init_data(void) { __rom_copy_info* dci; __bss_init_info* bii; @@ -222,6 +222,7 @@ void __init_data(void) } } +#pragma section code_type ".text" __declspec(weak) void InitMetroTRK_BBA(void) { return; diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c b/src/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c index cfe60633e..0fd3ae5f7 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Export/mslsupp.c @@ -1,48 +1,97 @@ -#include -#include "runtime_libs\debugger\embedded\MetroTRK\Os\dolphin\target_options.h" -#include "runtime_libs\debugger\embedded\MetroTRK\Processor\ppc\Export\targsupp.h" - -DSIOResult __read_file(u32 handle, u8* buffer, size_t* count, void* ref_con); -DSIOResult __write_file(u32 handle, u8* buffer, size_t* count, void* ref_con); -DSIOResult __close_file(u32 handle, u8* buffer, size_t* count, void* ref_con); -DSIOResult __access_file(u32 handle, u8* buffer, size_t* count, void* ref_con, - MessageCommandID cmd); - -/* 80372258-80372314 36CB98 00BC+00 0/0 1/0 0/0 .text __read_console */ -DSIOResult __read_console(u32 handle, u8* buffer, size_t* count, void* ref_con) +#include "PowerPC_EABI_Support/MetroTRK/trk.h" +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/ansi_files.h" +#include "runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.h" +#include "runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.h" + +int __read_console(__file_handle file, char* buffer, size_t* count, __ref_con ref_con) { + size_t countTemp; + u32 result; + if (GetUseSerialIO() == 0) { return DS_IOError; } - return __read_file(DS_Stdin, buffer, count, ref_con); + + if (GetTRKConnected() == DS_NoError) + { + return DS_IOError; + } + + countTemp = *count; + result = TRKAccessFile(DSMSG_ReadFile, DS_Stdin, &countTemp, (u8*)buffer); + *count = countTemp; + + switch ((u8)result) + { + case DS_IONoError: + return DS_IONoError; + case DS_IOEOF: + return DS_IOEOF; + } + + return DS_IOError; } -/* 8037219C-80372258 36CADC 00BC+00 0/0 1/1 0/0 .text __TRK_write_console */ -DSIOResult __TRK_write_console(u32 handle, u8* buffer, size_t* count, void* ref_con) +int __TRK_write_console(__file_handle file, char* buffer, size_t* count, __ref_con ref_con) { + size_t countTemp; + u32 result; + if (GetUseSerialIO() == 0) { return DS_IOError; } - return __write_file(DS_Stdout, buffer, count, ref_con); -} -static DSIOResult __read_file(u32 handle, u8* buffer, size_t* count, void* ref_con) -{ - return __access_file(handle, buffer, count, ref_con, DSMSG_ReadFile); + if (GetTRKConnected() == DS_NoError) + { + return DS_IOError; + } + + countTemp = *count; + result = TRKAccessFile(DSMSG_WriteFile, DS_Stdout, &countTemp, (u8*)buffer); + *count = countTemp; + + switch ((u8)result) + { + case DS_IONoError: + return DS_IONoError; + case DS_IOEOF: + return DS_IOEOF; + } + + return DS_IOError; } -static DSIOResult __write_file(u32 handle, u8* buffer, size_t* count, void* ref_con) +int __read_file(__file_handle file, char* buffer, size_t* count, __ref_con ref_con) { - return __access_file(handle, buffer, count, ref_con, DSMSG_WriteFile); + size_t countTemp; + u32 result; + + if (GetTRKConnected() == DS_NoError) + { + return DS_IOError; + } + + countTemp = *count; + result = TRKAccessFile(DSMSG_ReadFile, file, &countTemp, (u8*)buffer); + *count = countTemp; + + switch ((u8)result) + { + case DS_IONoError: + return DS_IONoError; + case DS_IOEOF: + return DS_IOEOF; + } + + return DS_IOError; } -static DSIOResult __access_file(u32 handle, u8* buffer, size_t* count, void* ref_con, - MessageCommandID cmd) +int __write_file(__file_handle file, char* buffer, size_t* count, __ref_con ref_con) { size_t countTemp; - u32 r0; + u32 result; if (GetTRKConnected() == DS_NoError) { @@ -50,10 +99,10 @@ static DSIOResult __access_file(u32 handle, u8* buffer, size_t* count, void* ref } countTemp = *count; - r0 = TRKAccessFile(cmd, handle, &countTemp, buffer); + result = TRKAccessFile(DSMSG_WriteFile, file, &countTemp, (u8*)buffer); *count = countTemp; - switch ((u8)r0) + switch ((u8)result) { case DS_IONoError: return DS_IONoError; @@ -62,4 +111,134 @@ static DSIOResult __access_file(u32 handle, u8* buffer, size_t* count, void* ref } return DS_IOError; -} \ No newline at end of file +} + +int __open_file(const char* name, file_modes mode, __file_handle* handle) +{ + const u8* modeBytes; + u32 result; + u32 binaryIO; + u32 ioMode; + u32 openMode; + u32 trkMode; + + if (GetTRKConnected() == DS_NoError) + { + return DS_IOError; + } + + modeBytes = (const u8*)&mode; + trkMode = 0; + openMode = mode.open_mode; + ioMode = mode.io_mode; + binaryIO = (modeBytes[1] >> 3) & 0x01; + + switch (openMode) + { + case 0: + trkMode |= 0x01; + break; + case 2: + trkMode |= 0x02; + break; + case 1: + trkMode |= 0x04; + break; + } + + switch (ioMode) + { + case 1: + trkMode |= 0x01; + break; + case 2: + trkMode |= 0x02; + break; + case 6: + trkMode |= 0x04; + break; + case 3: + trkMode |= 0x12; + break; + case 7: + trkMode |= 0x07; + break; + } + + if (binaryIO == 1) + { + trkMode = (trkMode | 0x08) & 0xFF; + } + + result = TRKOpenFile(DSMSG_OpenFile, (u32)name, (u8)trkMode, (u8*)handle); + + switch ((u8)result) + { + case DS_IONoError: + return DS_IONoError; + case DS_IOEOF: + return DS_IOEOF; + } + + return DS_IOError; +} + +int __close_file(__file_handle file) +{ + u32 result; + + if (GetTRKConnected() == DS_NoError) + { + return DS_IOError; + } + + result = TRKCloseFile(DSMSG_CloseFile, file); + + switch ((u8)result) + { + case DS_IONoError: + return DS_IONoError; + case DS_IOEOF: + return DS_IOEOF; + } + + return DS_IOError; +} + +int __position_file(__file_handle file, fpos_t* position, int mode, __ref_con ref_con) +{ + u32 modeConverted; + u32 result; + + modeConverted = 0; + + if (GetTRKConnected() == DS_NoError) + { + return DS_IOError; + } + + if (mode == 0) + { + modeConverted = 0; + } + else if (mode == 1) + { + modeConverted = 1; + } + else if (mode == 2) + { + modeConverted = 2; + } + + result = TRKPositionFile(DSMSG_PositionFile, file, position, (u8)modeConverted); + + switch ((u8)result) + { + case DS_IONoError: + return DS_IONoError; + case DS_IOEOF: + return DS_IOEOF; + } + + return DS_IOError; +} diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c b/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c index f690ba9f7..861ea393e 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk.c @@ -3,7 +3,6 @@ #define EXCEPTIONMASK_ADDR 0x80000044 static u32 lc_base; -extern u32 _db_stack_addr; static u32 TRK_ISR_OFFSETS[15] = { PPC_SystemReset, PPC_MachineCheck, @@ -21,10 +20,12 @@ static u32 TRK_ISR_OFFSETS[15] = { PPC_SystemReset, PPC_SystemManagementInterrupt, PPC_ThermalManagementInterrupt }; -void __TRK_reset() +#pragma section code_type ".init" +void __TRK_reset(void) { __TRK_copy_vectors(); } +#pragma section code_type /* * --INFO-- @@ -66,8 +67,8 @@ ASM void InitMetroTRK() mtspr 0x3f2, r0 mtspr 0x3f5, r0 //Restore stack pointer - lis r1, _db_stack_addr@h - ori r1, r1, _db_stack_addr@l + lis r1, 0x803D + ori r1, r1, 0x9A50 mr r3, r5 bl InitMetroTRKCommTable //Initialize comm table /* @@ -118,6 +119,11 @@ u32 TRKTargetTranslate(u32 param_0) } } + if ((param_0 >= 0x7E000000) && (param_0 <= 0x80000000)) + { + return param_0; + } + return param_0 & 0x3FFFFFFF | 0x80000000; } @@ -126,7 +132,7 @@ u32 TRKTargetTranslate(u32 param_0) * Address: 8021FF5C * Size: 000060 */ -void TRK_copy_vector(u32 offset) +static inline void TRK_copy_vector(u32 offset) { void* destPtr = (void*)TRKTargetTranslate(offset); TRK_memcpy(destPtr, gTRKInterruptVectorTable + offset, 0x100); @@ -138,7 +144,7 @@ void TRK_copy_vector(u32 offset) * Address: 8021FFBC * Size: 000094 */ -void __TRK_copy_vectors(void) +static inline void __TRK_copy_vectors(void) { int i; u32 mask; diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c b/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c index 1b2bc2771..a9585542f 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/dolphin_trk_glue.c @@ -1,16 +1,27 @@ #include "PowerPC_EABI_Support/MetroTRK/trk.h" #include "Dolphin/db.h" +#include "dolphin/amc/AmcExi2Comm.h" +#include "dolphin/base/PPCArch.h" #define BUFF_LEN 4362 -u8 gWriteBuf[BUFF_LEN]; -u8 gReadBuf[BUFF_LEN]; +extern int Hu_IsStub(void); +extern int AMC_IsStub(void); +extern void DBInitInterrupts(void); +extern u32 DBQueryData(void); +extern BOOL DBRead(u32* buffer, s32 count); +extern BOOL DBWrite(const void* src, u32 size); +extern void DBOpen(void); +extern void DBClose(void); + +static u8 gWriteBuf[BUFF_LEN] ATTRIBUTE_ALIGN(4); +static u8 gReadBuf[BUFF_LEN] ATTRIBUTE_ALIGN(4); s32 _MetroTRK_Has_Framing; -s32 gReadCount; -s32 gReadPos; -s32 gWritePos; +static s32 gReadCount; +static s32 gReadPos; +static s32 gWritePos; -DBCommTable gDBCommTable = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; +DBCommTable gDBCommTable ATTRIBUTE_ALIGN(8) = {}; /* * --INFO-- @@ -70,49 +81,42 @@ void TRKEXICallBack(__OSInterrupt param_0, OSContext* ctx) TRKLoadContext(ctx, 0x500); } -// int InitMetroTRKCommTable(int hwId) -// { -// int result; +int InitMetroTRKCommTable(int hwId) +{ + int result; -// if (hwId == HARDWARE_GDEV) { -// result = Hu_IsStub(); + if (hwId == HARDWARE_GDEV) { + OSReport("MetroTRK : Set to GDEV hardware\n"); + result = Hu_IsStub(); -// gDBCommTable.initialize_func = (DBCommInitFunc)DBInitComm; -// gDBCommTable.init_interrupts_func = (DBCommFunc)DBInitInterrupts; -// gDBCommTable.peek_func = (DBCommFunc)DBQueryData; -// gDBCommTable.read_func = (DBCommReadFunc)DBRead; -// gDBCommTable.write_func = (DBCommWriteFunc)DBWrite; -// gDBCommTable.open_func = (DBCommFunc)DBOpen; -// gDBCommTable.close_func = (DBCommFunc)DBClose; -// } else { -// result = AMC_IsStub(); + gDBCommTable.initialize_func = (DBCommInitFunc)DBInitComm; + gDBCommTable.init_interrupts_func = (DBCommFunc)DBInitInterrupts; + gDBCommTable.peek_func = (DBCommFunc)DBQueryData; + gDBCommTable.read_func = (DBCommReadFunc)DBRead; + gDBCommTable.write_func = (DBCommWriteFunc)DBWrite; + gDBCommTable.open_func = (DBCommFunc)DBOpen; + gDBCommTable.close_func = (DBCommFunc)DBClose; + } else { + OSReport("MetroTRK : Set to AMC DDH hardware\n"); + result = AMC_IsStub(); -// gDBCommTable.initialize_func = (DBCommInitFunc)EXI2_Init; -// gDBCommTable.init_interrupts_func = (DBCommFunc)EXI2_EnableInterrupts; -// gDBCommTable.peek_func = (DBCommFunc)EXI2_Poll; -// gDBCommTable.read_func = (DBCommReadFunc)EXI2_ReadN; -// gDBCommTable.write_func = (DBCommWriteFunc)EXI2_WriteN; -// gDBCommTable.open_func = (DBCommFunc)EXI2_Reserve; -// gDBCommTable.close_func = (DBCommFunc)EXI2_Unreserve; -// } + gDBCommTable.initialize_func = (DBCommInitFunc)EXI2_Init; + gDBCommTable.init_interrupts_func = (DBCommFunc)EXI2_EnableInterrupts; + gDBCommTable.peek_func = (DBCommFunc)EXI2_Poll; + gDBCommTable.read_func = (DBCommReadFunc)EXI2_ReadN; + gDBCommTable.write_func = (DBCommWriteFunc)EXI2_WriteN; + gDBCommTable.open_func = (DBCommFunc)EXI2_Reserve; + gDBCommTable.close_func = (DBCommFunc)EXI2_Unreserve; + } -// return result; -// } + return result; +} /* * --INFO-- * Address: 80220608 * Size: 000004 */ -void TRKUARTInterruptHandler(void) -{ -} - -/* - * --INFO-- - * Address: 8022060C - * Size: 000040 - */ DSError TRKInitializeIntDrivenUART(u32 param_0, u32 param_1, u32 param_2, volatile u8** param_3) { gDBCommTable.initialize_func(param_3, TRKEXICallBack); @@ -134,7 +138,7 @@ void EnableEXI2Interrupts(void) * Address: 8022067C * Size: 000030 */ -int TRKPollUART(void) +static inline int TRKPollUART(void) { return gDBCommTable.peek_func(); } @@ -144,7 +148,7 @@ int TRKPollUART(void) * Address: 802206AC * Size: 000044 */ -UARTError TRKReadUARTN(void* bytes, u32 length) +static inline UARTError TRKReadUARTN(void* bytes, u32 length) { int readErr = gDBCommTable.read_func(bytes, length); return readErr == 0 ? 0 : -1; @@ -155,7 +159,7 @@ UARTError TRKReadUARTN(void* bytes, u32 length) * Address: 802206F0 * Size: 000044 */ -UARTError TRKWriteUARTN(const void* bytes, u32 length) +static inline UARTError TRKWriteUARTN(const void* bytes, u32 length) { int writeErr = gDBCommTable.write_func(bytes, length); return writeErr == 0 ? 0 : -1; @@ -255,5 +259,25 @@ void UnreserveEXI2Port(void) */ void TRK_board_display(char* str) { - OSReport(str); + OSReport("%s\n", str); +} + +DSError InitializeProgramEndTrap(void) +{ + static const u32 EndofProgramInstruction = 'END'; + u8* endOfProgramInstructionBytes = (u8*)&EndofProgramInstruction; + u8* ppcHaltPtr = (u8*)PPCHalt; + + TRK_memcpy(ppcHaltPtr + 4, endOfProgramInstructionBytes, 4); + ICInvalidateRange(ppcHaltPtr + 4, 4); + DCFlushRange(ppcHaltPtr + 4, 4); +} + +/* + * --INFO-- + * Address: 80220608 + * Size: 000004 + */ +void TRKUARTInterruptHandler(void) +{ } diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.c b/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.c index e69de29bb..b59ffb5fd 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/target_options.c @@ -0,0 +1,13 @@ +#include "PowerPC_EABI_Support/MetroTRK/trk.h" + +static u8 bUseSerialIO ATTRIBUTE_ALIGN(8); + +u8 GetUseSerialIO(void) +{ + return bUseSerialIO; +} + +void SetUseSerialIO(u8 sio) +{ + bUseSerialIO = sio; +} diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c b/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c index 084bd755e..8988c7557 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Os/dolphin/usr_put.c @@ -1,55 +1,5 @@ #include "PowerPC_EABI_Support/MetroTRK/trk.h" -/* - * --INFO-- - * Address: ........ - * Size: 000038 - */ -void usr_putchar_serial(void) -{ - // UNUSED FUNCTION -} - -/* - * --INFO-- - * Address: ........ - * Size: 000050 - */ -BOOL usr_puts_serial(const char* msg) -{ - // UNUSED FUNCTION -} - -/* - * --INFO-- - * Address: ........ - * Size: 000004 - */ -void usr_put_initialize_ram(void) -{ - // UNUSED FUNCTION -} - -/* - * --INFO-- - * Address: ........ - * Size: 000008 - */ -void usr_putchar_ram(void) -{ - // UNUSED FUNCTION -} - -/* - * --INFO-- - * Address: ........ - * Size: 000044 - */ -void usr_puts_ram(void) -{ - // UNUSED FUNCTION -} - /* * --INFO-- * Address: 8021CEDC @@ -62,79 +12,25 @@ void usr_put_initialize(void) /* * --INFO-- * Address: ........ - * Size: 000008 - */ -void usr_putchar(void) -{ - // UNUSED FUNCTION -} - -/* - * --INFO-- - * Address: ........ - * Size: 000008 - */ -void usr_puts(void) -{ - // UNUSED FUNCTION -} - -/* - * --INFO-- - * Address: ........ - * Size: 000024 - */ -void __do_putchar(void) -{ - // UNUSED FUNCTION -} - -/* - * --INFO-- - * Address: ........ - * Size: 000020 + * Size: 000050 */ -void __do_puts(void) +BOOL usr_puts_serial(const char* msg) { - // UNUSED FUNCTION -} + BOOL connect_ = FALSE; + char c; + char buf[2]; -/* - * --INFO-- - * Address: ........ - * Size: 0001B8 - */ -void __do_puthex32(void) -{ - // UNUSED FUNCTION -} + while (!connect_ && (c = *msg++) != '\0') { + BOOL connect = GetTRKConnected(); -/* - * --INFO-- - * Address: ........ - * Size: 0000CC - */ -void __do_puthex8(void) -{ - // UNUSED FUNCTION -} + buf[0] = c; + buf[1] = '\0'; -/* - * --INFO-- - * Address: ........ - * Size: 000098 - */ -void __do_puthex4(void) -{ - // UNUSED FUNCTION -} + SetTRKConnected(FALSE); + OSReport(buf); -/* - * --INFO-- - * Address: ........ - * Size: 000068 - */ -void __do_puthex2(void) -{ - // UNUSED FUNCTION + SetTRKConnected(connect); + connect_ = FALSE; + } + return connect_; } diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c index cc766cb34..62ccbacfe 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/dispatch.c @@ -11,50 +11,68 @@ struct DispatchEntry gTRKDispatchTable[33] = { { &TRKDoSupportMask }, { &TRKDoCPUType }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoReadMemory }, { &TRKDoWriteMemory }, { &TRKDoReadRegisters }, { &TRKDoWriteRegisters }, - { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoFlushCache }, { &TRKDoUnsupported }, { &TRKDoContinue }, + { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoFlushCache }, { &TRKDoSetOption }, { &TRKDoContinue }, { &TRKDoStep }, { &TRKDoStop }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported }, }; /* * --INFO-- - * Address: 8021CEE0 - * Size: 000014 - */ -DSError TRKInitializeDispatcher() -{ - gTRKDispatchTableSize = 32; - return DS_NoError; -} - -/* - * --INFO-- - * Address: ........ - * Size: 0000A0 + * Address: 8021CEF4 + * Size: 000084 */ -DSError TRKOverrideDispatch(TRKBuffer* buffer) +asm DSError TRKDispatchMessage(TRKBuffer* buffer) { - return DS_NoError; + nofralloc + stwu r1, -0x20(r1) + mflr r0 + li r4, 0x0 + stw r0, 0x24(r1) + stw r31, 0x1C(r1) + li r31, 0x500 + stw r30, 0x18(r1) + mr r30, r3 + bl TRKSetBufferPosition + mr r3, r30 + addi r4, r1, 0x8 + bl TRKReadBuffer1_ui8 + lis r3, gTRKDispatchTableSize@ha + lbz r4, 0x8(r1) + lwz r0, gTRKDispatchTableSize@l(r3) + clrlwi r3, r4, 24 + cmplw r3, r0 + bge dispatch_done + lis r3, gTRKDispatchTable@ha + clrlslwi r0, r4, 24, 2 + addi r4, r3, gTRKDispatchTable@l + mr r3, r30 + lwzx r12, r4, r0 + mtctr r12 + bctrl + mr r31, r3 - // UNUSED FUNCTION +dispatch_done: + lwz r0, 0x24(r1) + mr r3, r31 + lwz r31, 0x1C(r1) + lwz r30, 0x18(r1) + mtlr r0 + addi r1, r1, 0x20 + blr } /* * --INFO-- - * Address: 8021CEF4 - * Size: 000084 + * Address: 8021CEE0 + * Size: 000018 */ -DSError TRKDispatchMessage(TRKBuffer* buffer) +asm DSError TRKInitializeDispatcher(void) { - DSError error; - u8 command; - - error = DS_DispatchError; - TRKSetBufferPosition(buffer, 0); - TRKReadBuffer1_ui8(buffer, &command); - command &= 0xFF; - if (command < gTRKDispatchTableSize) { - error = gTRKDispatchTable[command].fn(buffer); - } - return error; + nofralloc + lis r3, gTRKDispatchTableSize@ha + li r0, 0x20 + addi r4, r3, gTRKDispatchTableSize@l + li r3, 0x0 + stw r0, 0x0(r4) + blr } diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c index 59da56194..655f7fa69 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c @@ -1,6 +1,6 @@ #include "PowerPC_EABI_Support/MetroTRK/trk.h" -static DSError TRK_mainError; +static DSError TRK_mainError ATTRIBUTE_ALIGN(8); /* * --INFO-- diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c index b3796184a..db7afc7ed 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/mainloop.c @@ -1,76 +1,92 @@ #include "PowerPC_EABI_Support/MetroTRK/trk.h" -extern TRKEventQueue gTRKEventQueue; -extern TRKState gTRKState; - -void TRKHandleRequestEvent(TRKEvent* event) +asm void TRKNubMainLoop(void) { - TRKBuffer* buffer = TRKGetBuffer(event->msgBufID); - TRKDispatchMessage(buffer); -} + nofralloc + stwu r1, -0x20(r1) + mflr r0 + stw r0, 0x24(r1) + stw r31, 0x1c(r1) + li r31, 0x0 + stw r30, 0x18(r1) + li r30, 0x0 + b loop_test -void TRKHandleSupportEvent(TRKEvent* event) -{ - TRKTargetSupportRequest(); -} +loop_start: + addi r3, r1, 0x8 + bl TRKGetNextEvent + cmpwi r3, 0x0 + beq no_event + lbz r0, 0x8(r1) + li r30, 0x0 + cmpwi r0, 0x2 + beq request_event + bge ge_two + cmpwi r0, 0x0 + beq event_done + bge shutdown_event + b event_done -void TRKIdle() -{ - if (TRKTargetStopped() == FALSE) - { - TRKTargetContinue(); - } -} +ge_two: + cmpwi r0, 0x5 + beq support_event + bge event_done + b interrupt_event -void TRKNubMainLoop(void) -{ - TRKEvent event; - BOOL isShutdownRequested; - BOOL isNewInput; +request_event: + lwz r3, 0x10(r1) + bl TRKGetBuffer + bl TRKDispatchMessage + b event_done - isShutdownRequested = FALSE; - isNewInput = FALSE; - while (isShutdownRequested == FALSE) - { - if (TRKGetNextEvent(&event) != FALSE) - { - isNewInput = FALSE; +shutdown_event: + li r31, 0x1 + b event_done - switch (event.eventType) - { - case NUBEVENT_Null: - break; +interrupt_event: + addi r3, r1, 0x8 + bl TRKTargetInterrupt + b event_done - case NUBEVENT_Request: - TRKHandleRequestEvent(&event); - break; +support_event: + bl TRKTargetSupportRequest - case NUBEVENT_Shutdown: - isShutdownRequested = TRUE; - break; +event_done: + addi r3, r1, 0x8 + bl TRKDestructEvent + b loop_test - case NUBEVENT_Breakpoint: - case NUBEVENT_Exception: - TRKTargetInterrupt(&event); - break; +no_event: + cmpwi r30, 0x0 + beq poll_input + lis r3, gTRKInputPendingPtr@ha + addi r3, r3, gTRKInputPendingPtr@l + lwz r3, 0x0(r3) + lbz r0, 0x0(r3) + cmplwi r0, 0x0 + beq idle - case NUBEVENT_Support: - TRKHandleSupportEvent(&event); - break; - } +poll_input: + li r30, 0x1 + bl TRKGetInput + b loop_test - TRKDestructEvent(&event); - continue; - } +idle: + bl TRKTargetStopped + cmpwi r3, 0x0 + bne finish_idle + bl TRKTargetContinue - if ((isNewInput == FALSE) || (*(u8*)gTRKInputPendingPtr != '\0')) - { - isNewInput = TRUE; - TRKGetInput(); - continue; - } +finish_idle: + li r30, 0x0 - TRKIdle(); - isNewInput = FALSE; - } +loop_test: + cmpwi r31, 0x0 + beq loop_start + lwz r0, 0x24(r1) + lwz r31, 0x1c(r1) + lwz r30, 0x18(r1) + mtlr r0 + addi r1, r1, 0x20 + blr } diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c index 29ead0b78..68ceda637 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/mem_TRK.c @@ -1,8 +1,14 @@ -#include "PowerPC_EABI_Support/MetroTRK/trk.h" +#include "PowerPC_EABI_Support/MetroTRK/Portable/mem_TRK.h" static void TRK_fill_mem(void* dest, int val, size_t count); -void* TRK_memcpy(void* dest, const void* src, size_t count) +__declspec(section ".init") void* TRK_memset(void* dest, int val, size_t count) +{ + TRK_fill_mem(dest, val, count); + return dest; +} + +__declspec(section ".init") void* TRK_memcpy(void* dest, const void* src, size_t count) { u8* s = (u8*)src - 1; u8* d = (u8*)dest - 1; @@ -13,11 +19,7 @@ void* TRK_memcpy(void* dest, const void* src, size_t count) { *++d = *++s; } -} -void* TRK_memset(void* dest, int val, size_t count) -{ - TRK_fill_mem(dest, val, count); return dest; } diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c index 29533094d..a293dd790 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msg.c @@ -1,5 +1,8 @@ #include "PowerPC_EABI_Support/MetroTRK/trk.h" +UARTError WriteUART1(s8 arg0); +UARTError WriteUARTFlush(void); + /* * --INFO-- * Address: ........ @@ -25,9 +28,59 @@ void TRKMessageGet(void) /* * --INFO-- * Address: 8021C4A4 - * Size: 000028 + * Size: 0001DC */ -DSError TRKMessageSend(TRKBuffer* param_1) +DSError TRKMessageSend(TRKBuffer* msg) { - return TRKWriteUARTN(param_1->data, param_1->length); + u8 var_r30; + u8 var_r28; + u8 var_r28_2; + s32 var_r3; + s32 i; + + var_r30 = 0; + for (i = 0; i < msg->length; i++) { + var_r30 = var_r30 + msg->data[i]; + } + var_r30 = var_r30 ^ 0xFF; + var_r3 = WriteUART1(0x7E); + if (var_r3 == 0) { + for (i = 0; i < msg->length; i++) { + var_r28 = msg->data[i]; + if (var_r28 == 0x7E || var_r28 == 0x7D) { + var_r3 = WriteUART1(0x7D); + var_r28 ^= 0x20; + if (var_r3 != 0) { + break; + } + } + var_r3 = WriteUART1(var_r28); + if (var_r3 != 0) { + break; + } + } + } + if (var_r3 == 0) { + var_r28_2 = var_r30; + for (i = 0; i < 1; i++) { + if (var_r28_2 == 0x7E || var_r28_2 == 0x7D) { + var_r3 = WriteUART1(0x7D); + var_r28_2 ^= 0x20; + if (var_r3 != 0) { + break; + } + } + var_r3 = WriteUART1(var_r28_2); + if (var_r3 != 0) { + break; + } + } + } + if (var_r3 == 0) { + var_r3 = WriteUART1(0x7E); + } + if (var_r3 == 0) { + var_r3 = WriteUARTFlush(); + } + return var_r3; } diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c index cce3a6339..18876a590 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c @@ -37,16 +37,17 @@ DSError TRKInitializeMessageBuffers(void) */ DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg) { + TRKBuffer* buf; DSError error = DS_NoMessageBufferAvailable; int i; *outMsg = NULL; for (i = 0; i < 3; i++) { - TRKBuffer* buf = TRKGetBuffer(i); + buf = TRKGetBuffer(i); TRKAcquireMutex(buf); if (!buf->isInUse) { - TRKResetBuffer(buf, 1); + TRKResetBuffer(buf, TRUE); TRKSetBufferUsed(buf, TRUE); error = DS_NoError; *outMsg = buf; @@ -56,6 +57,10 @@ DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg) TRKReleaseMutex(buf); } + if (error == DS_NoMessageBufferAvailable) { + usr_puts_serial("ERROR : No buffer available\n"); + } + return error; } @@ -206,20 +211,35 @@ DSError TRKReadBuffer(TRKBuffer* msg, void* data, size_t length) DSError TRKAppendBuffer1_ui16(TRKBuffer* buffer, const u16 data) { u8* bigEndianData; - u8* byteData; u8 swapBuffer[sizeof(data)]; + DSError error; + u32 length; if (gTRKBigEndian) { bigEndianData = (u8*)&data; } else { - byteData = (u8*)&data; bigEndianData = swapBuffer; - bigEndianData[0] = byteData[1]; - bigEndianData[1] = byteData[0]; + bigEndianData[0] = ((u8*)&data)[1]; + bigEndianData[1] = ((u8*)&data)[0]; + } + + length = sizeof(data); + error = DS_NoError; + if (0x880 - buffer->position < length) { + error = DS_MessageBufferOverflow; + length = 0x880 - buffer->position; + } + + if (length == 1) { + buffer->data[buffer->position] = bigEndianData[0]; + } else { + TRK_memcpy(buffer->data + buffer->position, bigEndianData, length); } - return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data)); + buffer->position += length; + buffer->length = buffer->position; + return error; } /* @@ -230,22 +250,37 @@ DSError TRKAppendBuffer1_ui16(TRKBuffer* buffer, const u16 data) DSError TRKAppendBuffer1_ui32(TRKBuffer* buffer, const u32 data) { u8* bigEndianData; - u8* byteData; u8 swapBuffer[sizeof(data)]; + DSError error; + u32 length; if (gTRKBigEndian) { bigEndianData = (u8*)&data; } else { - byteData = (u8*)&data; bigEndianData = swapBuffer; - bigEndianData[0] = byteData[3]; - bigEndianData[1] = byteData[2]; - bigEndianData[2] = byteData[1]; - bigEndianData[3] = byteData[0]; + bigEndianData[0] = ((u8*)&data)[3]; + bigEndianData[1] = ((u8*)&data)[2]; + bigEndianData[2] = ((u8*)&data)[1]; + bigEndianData[3] = ((u8*)&data)[0]; + } + + length = sizeof(data); + error = DS_NoError; + if (0x880 - buffer->position < length) { + error = DS_MessageBufferOverflow; + length = 0x880 - buffer->position; + } + + if (length == 1) { + buffer->data[buffer->position] = bigEndianData[0]; + } else { + TRK_memcpy(buffer->data + buffer->position, bigEndianData, length); } - return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data)); + buffer->position += length; + buffer->length = buffer->position; + return error; } /* * --INFO-- @@ -255,25 +290,40 @@ DSError TRKAppendBuffer1_ui32(TRKBuffer* buffer, const u32 data) DSError TRKAppendBuffer1_ui64(TRKBuffer* buffer, const u64 data) { u8* bigEndianData; - u8* byteData; u8 swapBuffer[sizeof(data)]; + DSError error; + u32 length; if (gTRKBigEndian) { bigEndianData = (u8*)&data; } else { - byteData = (u8*)&data; bigEndianData = swapBuffer; - bigEndianData[0] = byteData[7]; - bigEndianData[1] = byteData[6]; - bigEndianData[2] = byteData[5]; - bigEndianData[3] = byteData[4]; - bigEndianData[4] = byteData[3]; - bigEndianData[5] = byteData[2]; - bigEndianData[6] = byteData[1]; - bigEndianData[7] = byteData[0]; + bigEndianData[0] = ((u8*)&data)[7]; + bigEndianData[1] = ((u8*)&data)[6]; + bigEndianData[2] = ((u8*)&data)[5]; + bigEndianData[3] = ((u8*)&data)[4]; + bigEndianData[4] = ((u8*)&data)[3]; + bigEndianData[5] = ((u8*)&data)[2]; + bigEndianData[6] = ((u8*)&data)[1]; + bigEndianData[7] = ((u8*)&data)[0]; + } + + length = sizeof(data); + error = DS_NoError; + if (0x880 - buffer->position < length) { + error = DS_MessageBufferOverflow; + length = 0x880 - buffer->position; + } + + if (length == 1) { + buffer->data[buffer->position] = bigEndianData[0]; + } else { + TRK_memcpy(buffer->data + buffer->position, bigEndianData, length); } - return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data)); + buffer->position += length; + buffer->length = buffer->position; + return error; } /* @@ -321,10 +371,53 @@ void TRKAppendBuffer_ui16(void) DSError TRKAppendBuffer_ui32(TRKBuffer* buffer, const u32* data, int count) { DSError err; + DSError appendErr; + const u32* currentData; int i; + int currentCount; + BOOL* bigEndianFlag; + u8* bigEndianData; + u8 swapBuffer[sizeof(*data)]; + u8 currentBuffer[sizeof(*data)]; + u32 length; + + i = 0; + bigEndianFlag = &gTRKBigEndian; + currentData = data; + currentCount = count; + err = DS_NoError; + while (err == DS_NoError && i < currentCount) { + *(u32*)currentBuffer = *currentData; + + if (*bigEndianFlag) { + bigEndianData = currentBuffer; + } else { + bigEndianData = swapBuffer; + + bigEndianData[0] = currentBuffer[3]; + bigEndianData[1] = currentBuffer[2]; + bigEndianData[2] = currentBuffer[1]; + bigEndianData[3] = currentBuffer[0]; + } - for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) { - err = TRKAppendBuffer1_ui32(buffer, data[i]); + length = sizeof(*data); + appendErr = DS_NoError; + if (0x880 - buffer->position < length) { + appendErr = DS_MessageBufferOverflow; + length = 0x880 - buffer->position; + } + + if (length == 1) { + buffer->data[buffer->position] = bigEndianData[0]; + } else { + TRK_memcpy(buffer->data + buffer->position, bigEndianData, length); + } + + buffer->position += length; + buffer->length = buffer->position; + err = appendErr; + currentData++; + i++; } return err; diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c index b13760a05..92d34a8d0 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c @@ -7,12 +7,24 @@ typedef struct _TRK_Msg { u8 m_msg[4]; // TODO: unknown array length } TRK_Msg; +static BOOL IsTRKConnected ATTRIBUTE_ALIGN(8); + +BOOL GetTRKConnected(void) +{ + return IsTRKConnected; +} + +void SetTRKConnected(BOOL connected) +{ + IsTRKConnected = connected; +} + /* * --INFO-- * Address: 8021CF78 * Size: 000098 */ -void TRKMessageIntoReply(TRKBuffer* buffer, MessageCommandID ackCmd, DSReplyError errSentInAck) +static inline void TRKMessageIntoReply(TRKBuffer* buffer, MessageCommandID ackCmd, DSReplyError errSentInAck) { TRKResetBuffer(buffer, 1); @@ -25,7 +37,7 @@ void TRKMessageIntoReply(TRKBuffer* buffer, MessageCommandID ackCmd, DSReplyErro * Address: 8021D010 * Size: 000050 */ -DSError TRKSendACK(TRKBuffer* buffer) +static inline DSError TRKSendACK(TRKBuffer* buffer) { DSError err; int ackTries; @@ -50,16 +62,6 @@ DSError TRKStandardACK(TRKBuffer* buffer, MessageCommandID commandID, DSReplyErr return TRKSendACK(buffer); } -/* - * --INFO-- - * Address: ........ - * Size: 000008 - */ -void TRKDoError(void) -{ - // UNUSED FUNCTION -} - /* * --INFO-- * Address: 8021D094 @@ -77,6 +79,7 @@ DSError TRKDoUnsupported(TRKBuffer* buffer) */ DSError TRKDoConnect(TRKBuffer* buffer) { + IsTRKConnected = TRUE; return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); } @@ -87,9 +90,11 @@ DSError TRKDoConnect(TRKBuffer* buffer) */ DSError TRKDoDisconnect(TRKBuffer* buffer) { - DSError error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); + DSError error; TRKEvent event; + IsTRKConnected = FALSE; + error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError); if (error == DS_NoError) { TRKConstructEvent(&event, 1); TRKPostEvent(&event); @@ -216,14 +221,14 @@ DSError TRKDoCPUType(TRKBuffer* buffer) */ DSError TRKDoReadMemory(TRKBuffer* buffer) { - u8 tempBuf[0x800] ATTRIBUTE_ALIGN(32); - u32 length; + DSError error; + DSReplyError replyError; + u8 tempBuf[0x800]; u32 msg_start; + u32 length; u16 msg_length; - u8 msg_options; u8 msg_command; - DSReplyError replyError; - DSError error; + u8 msg_options; if (buffer->length != 8) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); @@ -299,14 +304,14 @@ DSError TRKDoReadMemory(TRKBuffer* buffer) */ DSError TRKDoWriteMemory(TRKBuffer* buffer) { - u8 tmpBuffer[0x800] ATTRIBUTE_ALIGN(32); - u32 length; + DSError error; + DSReplyError replyError; + u8 tmpBuffer[0x800]; u32 msg_start; + u32 length; u16 msg_length; - u8 msg_options; u8 msg_command; - DSReplyError replyError; - DSError error; + u8 msg_options; if (buffer->length <= 8) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); @@ -385,14 +390,14 @@ DSError TRKDoWriteMemory(TRKBuffer* buffer) */ DSError TRKDoReadRegisters(TRKBuffer* buffer) { + DSError error; + DSReplyError replyError; DSMessageRegisterOptions options; u32 registerDataLength; - u16 msg_lastRegister; u16 msg_firstRegister; - u8 msg_options; + u16 msg_lastRegister; u8 msg_command; - DSError error; - DSReplyError replyError; + u8 msg_options; if (buffer->length != 6) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); @@ -473,14 +478,14 @@ DSError TRKDoReadRegisters(TRKBuffer* buffer) */ DSError TRKDoWriteRegisters(TRKBuffer* buffer) { + DSError error; + DSReplyError replyError; DSMessageRegisterOptions options; u32 registerDataLength; - u16 msg_lastRegister; u16 msg_firstRegister; - u8 msg_options; + u16 msg_lastRegister; u8 msg_command; - DSError error; - DSReplyError replyError; + u8 msg_options; if (buffer->length <= 6) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); @@ -564,12 +569,12 @@ DSError TRKDoWriteRegisters(TRKBuffer* buffer) */ DSError TRKDoFlushCache(TRKBuffer* buffer) { - u32 msg_end; - u32 msg_start; - u8 msg_options; - u8 msg_command; DSError error; DSReplyError replyErr; + u32 msg_start; + u32 msg_end; + u8 msg_command; + u8 msg_options; if (buffer->length != 10) { error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError); @@ -640,11 +645,11 @@ DSError TRKDoContinue(TRKBuffer* buffer) DSError TRKDoStep(TRKBuffer* buffer) { DSError error; - u32 msg_rangeEnd; - u32 msg_rangeStart; - u8 msg_count; - u8 msg_options; u8 msg_command; + u8 msg_options; + u8 msg_count; + u32 msg_rangeStart; + u32 msg_rangeEnd; u32 pc; if (buffer->length < 3) { @@ -739,3 +744,52 @@ DSError TRKDoStop(TRKBuffer* b) return TRKStandardACK(b, DSMSG_ReplyACK, replyError); } + +/* + * --INFO-- + * Address: 8021E21C + * Size: 0001A4 + */ +DSError TRKDoSetOption(TRKBuffer* buffer) +{ + DSError error; + u8 spA; + u8 sp9; + u8 sp8; + + spA = 0; + sp9 = 0; + sp8 = 0; + TRKSetBufferPosition(buffer, DSREPLY_NoError); + error = TRKReadBuffer1_ui8(buffer, &spA); + if (error == DS_NoError) { + error = TRKReadBuffer1_ui8(buffer, &sp9); + } + if (error == DS_NoError) { + error = TRKReadBuffer1_ui8(buffer, &sp8); + } + if (error != DS_NoError) { + TRKResetBuffer(buffer, 1); + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = 0x80; + buffer->length++; + } + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = 1; + buffer->length++; + } + TRKSendACK(buffer); + } else if (sp9 == 1) { + SetUseSerialIO(sp8); + } + TRKResetBuffer(buffer, 1); + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = 0x80; + buffer->length++; + } + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = 0; + buffer->length++; + } + return TRKSendACK(buffer); +} diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c index cccdd005b..a3c61b2a0 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/notify.c @@ -1,4 +1,3 @@ - #include "PowerPC_EABI_Support/MetroTRK/trk.h" inline DSError TRKWaitForACK(TRKBuffer* msg, MessageCommandID cmd) @@ -16,11 +15,8 @@ DSError TRKDoNotifyStopped(u8 cmd) { DSError err; int reqIdx; - TRKBuffer* msg; int bufIdx; - - // &msg - // &bufIdx + TRKBuffer* msg; err = TRKGetFreeBuffer(&bufIdx, &msg); if (err == DS_NoError) diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c index 75c3caddd..d3008381f 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/nubevent.c @@ -4,51 +4,24 @@ TRKEventQueue gTRKEventQueue; /* * --INFO-- - * Address: 8021C0B4 - * Size: 00005C - */ -DSError TRKInitializeEventQueue() -{ - TRKInitializeMutex(&gTRKEventQueue); - TRKAcquireMutex(&gTRKEventQueue); - gTRKEventQueue.count = 0; - gTRKEventQueue.next = 0; - gTRKEventQueue.eventID = 0x100; - TRKReleaseMutex(&gTRKEventQueue); - return DS_NoError; -} - -/* - * --INFO-- - * Address: 8021C110 + * Address: 8021C2EC * Size: 000024 */ -void TRKCopyEvent(TRKEvent* dstEvent, const TRKEvent* srcEvent) +void TRKDestructEvent(TRKEvent* event) { - TRK_memcpy(dstEvent, srcEvent, sizeof(TRKEvent)); + TRKReleaseBuffer(event->msgBufID); } /* * --INFO-- - * Address: 8021C134 - * Size: 0000C0 + * Address: 8021C2D4 + * Size: 000018 */ -BOOL TRKGetNextEvent(TRKEvent* event) +void TRKConstructEvent(TRKEvent* event, int eventType) { - BOOL status = 0; - TRKAcquireMutex(&gTRKEventQueue); - if (0 < gTRKEventQueue.count) - { - TRKCopyEvent(event, &gTRKEventQueue.events[gTRKEventQueue.next]); - gTRKEventQueue.count--; - gTRKEventQueue.next++; - if (gTRKEventQueue.next == 2) - gTRKEventQueue.next = 0; - - status = 1; - } - TRKReleaseMutex(&gTRKEventQueue); - return status; + event->eventType = eventType; + event->eventID = 0; + event->msgBufID = -1; } /* @@ -70,7 +43,7 @@ DSError TRKPostEvent(TRKEvent* event) else { nextEventID = (gTRKEventQueue.next + gTRKEventQueue.count) % 2; - TRKCopyEvent(&gTRKEventQueue.events[nextEventID], event); + TRK_memcpy(&gTRKEventQueue.events[nextEventID], event, sizeof(TRKEvent)); gTRKEventQueue.events[nextEventID].eventID = gTRKEventQueue.eventID; gTRKEventQueue.eventID++; if (gTRKEventQueue.eventID < 0x100) @@ -85,22 +58,39 @@ DSError TRKPostEvent(TRKEvent* event) /* * --INFO-- - * Address: 8021C2D4 - * Size: 000018 + * Address: 8021C134 + * Size: 0000C0 */ -void TRKConstructEvent(TRKEvent* event, int eventType) +BOOL TRKGetNextEvent(TRKEvent* event) { - event->eventType = eventType; - event->eventID = 0; - event->msgBufID = -1; + BOOL status = 0; + TRKAcquireMutex(&gTRKEventQueue); + if (0 < gTRKEventQueue.count) + { + TRK_memcpy(event, &gTRKEventQueue.events[gTRKEventQueue.next], sizeof(TRKEvent)); + gTRKEventQueue.count--; + gTRKEventQueue.next++; + if (gTRKEventQueue.next == 2) + gTRKEventQueue.next = 0; + + status = 1; + } + TRKReleaseMutex(&gTRKEventQueue); + return status; } /* * --INFO-- - * Address: 8021C2EC - * Size: 000024 + * Address: 8021C0B4 + * Size: 00005C */ -void TRKDestructEvent(TRKEvent* event) +DSError TRKInitializeEventQueue() { - TRKReleaseBuffer(event->msgBufID); + TRKInitializeMutex(&gTRKEventQueue); + TRKAcquireMutex(&gTRKEventQueue); + gTRKEventQueue.count = 0; + gTRKEventQueue.next = 0; + gTRKEventQueue.eventID = 0x100; + TRKReleaseMutex(&gTRKEventQueue); + return DS_NoError; } diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c index 04b5568e1..7323b29e4 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c @@ -4,39 +4,13 @@ BOOL gTRKBigEndian; /* * --INFO-- - * Address: 8021C310 - * Size: 0000D4 + * Address: 8021C408 + * Size: 000028 */ -DSError TRKInitializeNub(void) +void TRKNubWelcome(void) { - DSError ret; - DSError uartErr; - - ret = TRKInitializeEndian(); - - if (ret == DS_NoError) - usr_put_initialize(); - if (ret == DS_NoError) - ret = TRKInitializeEventQueue(); - if (ret == DS_NoError) - ret = TRKInitializeMessageBuffers(); - if (ret == DS_NoError) - ret = TRKInitializeDispatcher(); - - if (ret == DS_NoError) { - uartErr = TRKInitializeIntDrivenUART(0x0000e100, 1, 0, (volatile u8**)&gTRKInputPendingPtr); - TRKTargetSetInputPendingPtr(gTRKInputPendingPtr); - if (uartErr != DS_NoError) { - ret = uartErr; - } - } - - if (ret == DS_NoError) - ret = TRKInitializeSerialHandler(); - if (ret == DS_NoError) - ret = TRKInitializeTarget(); - - return ret; + TRK_board_display("MetroTRK for GAMECUBE v2.0"); + return; } /* @@ -50,26 +24,10 @@ DSError TRKTerminateNub(void) return DS_NoError; } -/* - * --INFO-- - * Address: 8021C408 - * Size: 000028 - */ -void TRKNubWelcome(void) -{ - TRK_board_display("MetroTRK for Dolphin v0.8"); - return; -} - -/* - * --INFO-- - * Address: 8021C430 - * Size: 000074 - */ -BOOL TRKInitializeEndian(void) +inline BOOL TRKInitializeEndian(void) { u8 bendian[4]; - BOOL result = FALSE; + BOOL result = FALSE; gTRKBigEndian = TRUE; bendian[0] = 0x12; @@ -86,3 +44,42 @@ BOOL TRKInitializeEndian(void) } return result; } + +/* + * --INFO-- + * Address: 8021C310 + * Size: 0000D4 + */ +DSError TRKInitializeNub(void) +{ + int ret; + DSError uartErr; + + ret = TRKInitializeEndian(); + + if (ret == DS_NoError) + usr_put_initialize(); + if (ret == DS_NoError) + ret = TRKInitializeEventQueue(); + if (ret == DS_NoError) + ret = TRKInitializeMessageBuffers(); + if (ret == DS_NoError) + ret = TRKInitializeDispatcher(); + + InitializeProgramEndTrap(); + + if (ret == DS_NoError) { + uartErr = TRKInitializeIntDrivenUART(0x0000e100, 1, 0, (volatile u8**)&gTRKInputPendingPtr); + TRKTargetSetInputPendingPtr(gTRKInputPendingPtr); + if (uartErr != DS_NoError) { + ret = uartErr; + } + } + + if (ret == DS_NoError) + ret = TRKInitializeSerialHandler(); + if (ret == DS_NoError) + ret = TRKInitializeTarget(); + + return ret; +} diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c index 06947aaa7..876ca9b21 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c @@ -1,135 +1,148 @@ #include "PowerPC_EABI_Support/MetroTRK/trk.h" -void* gTRKInputPendingPtr; static TRKFramingState gTRKFramingState; +void* gTRKInputPendingPtr = 0; -/* - * --INFO-- - * Address: ........ - * Size: 00004C - */ -void TRKDiscardFrame(void) +DSError TRKTerminateSerialHandler(void) { - // UNUSED FUNCTION + return 0; } -/* - * --INFO-- - * Address: ........ - * Size: 000040 - */ -void TRKRejectFrame(void) +DSError TRKInitializeSerialHandler(void) { - // UNUSED FUNCTION + gTRKFramingState.msgBufID = -1; + gTRKFramingState.receiveState = 0; + gTRKFramingState.isEscape = 0; + return 0; } -/* - * --INFO-- - * Address: 8021CD14 - * Size: 0000D0 - */ -TRKBufferID TRKTestForPacket(void) +void TRKProcessInput(TRKBufferID bufID) { - int bytes; - int batch; - DSError err; - TRKBuffer* b; - int id; - - bytes = TRKPollUART(); - - if (bytes > 0) { - TRKGetFreeBuffer(&id, &b); - if (bytes > 0x880) { - for (; bytes > 0; bytes -= batch) { - batch = bytes > 0x880 ? 0x880 : bytes; - TRKReadUARTN(b->data, batch); - } - TRKStandardACK(b, DSMSG_ReplyNAK, 6); - } else { - err = TRKReadUARTN(b->data, bytes); - if (err == DS_NoError) { - b->length = bytes; - return id; - } - } - } - - if (id != -1) { - TRKReleaseBuffer(id); - } - return -1; -} + TRKEvent event; -/* - * --INFO-- - * Address: ........ - * Size: 000070 - */ -void TRKProcessFrame(void) -{ - // UNUSED FUNCTION + TRKConstructEvent(&event, 2); + event.msgBufID = bufID; + gTRKFramingState.msgBufID = -1; + TRKPostEvent(&event); } -/* - * --INFO-- - * Address: 8021CDE4 - * Size: 00007C - */ void TRKGetInput(void) { - TRKBuffer* msgbuffer; - int bufID; + TRKBuffer* msgBuffer; + TRKBufferID id; u8 command; - bufID = TRKTestForPacket(); - - if (bufID != -1) { - msgbuffer = TRKGetBuffer(bufID); - TRKSetBufferPosition(msgbuffer, 0); - TRKReadBuffer1_ui8(msgbuffer, &command); + id = TRKTestForPacket(); + if (id != -1) { + msgBuffer = TRKGetBuffer(id); + TRKSetBufferPosition(msgBuffer, 0); + TRKReadBuffer1_ui8(msgBuffer, &command); if (command < 0x80) { - TRKProcessInput(bufID); + TRKEvent event; + + TRKConstructEvent(&event, NUBEVENT_Request); + event.msgBufID = id; + gTRKFramingState.msgBufID = -1; + TRKPostEvent(&event); } else { - TRKReleaseBuffer(bufID); + TRKReleaseBuffer(id); } } } -/* - * --INFO-- - * Address: 8021CE60 - * Size: 000050 - */ -void TRKProcessInput(TRKBufferID bufID) +static inline BOOL serpoll_inline_00(TRKBuffer* buffer) { - TRKEvent event; + if (buffer->length < 2) { + TRKStandardACK(buffer, DSMSG_ReplyNAK, DSREPLY_PacketSizeError); + if (gTRKFramingState.msgBufID != -1) { + TRKReleaseBuffer(gTRKFramingState.msgBufID); + gTRKFramingState.msgBufID = -1; + } + gTRKFramingState.buffer = NULL; + gTRKFramingState.receiveState = DSRECV_Wait; + return FALSE; + } - TRKConstructEvent(&event, 2); - event.msgBufID = bufID; - gTRKFramingState.msgBufID = -1; - TRKPostEvent(&event); + buffer->position = 0; + buffer->length--; + return TRUE; } -/* - * --INFO-- - * Address: 8021CEB0 - * Size: 000024 - */ -DSError TRKInitializeSerialHandler(void) +TRKBufferID TRKTestForPacket(void) { - gTRKFramingState.msgBufID = -1; - gTRKFramingState.receiveState = 0; - gTRKFramingState.isEscape = 0; - return 0; -} + s32 var_r29; + s32 var_r3; + s8 sp8; + s32 temp_r3; -/* - * --INFO-- - * Address: 8021CED4 - * Size: 000008 - */ -DSError TRKTerminateSerialHandler(void) -{ - return 0; + var_r29 = 0; + var_r3 = TRKReadUARTPoll(&sp8); + while (var_r3 == 0 && var_r29 == 0) { + if (gTRKFramingState.receiveState != DSRECV_InFrame) { + gTRKFramingState.isEscape = FALSE; + } + + switch (gTRKFramingState.receiveState) { + case DSRECV_Wait: + if (sp8 == 0x7E) { + var_r29 = TRKGetFreeBuffer(&gTRKFramingState.msgBufID, &gTRKFramingState.buffer); + gTRKFramingState.fcsType = 0; + gTRKFramingState.receiveState = DSRECV_Found; + } + break; + case DSRECV_Found: + if (sp8 == 0x7E) { + break; + } + gTRKFramingState.receiveState = DSRECV_InFrame; + /* fallthrough */ + case DSRECV_InFrame: + if (sp8 == 0x7E) { + if (gTRKFramingState.isEscape) { + TRKStandardACK(gTRKFramingState.buffer, DSMSG_ReplyNAK, DSREPLY_EscapeError); + if (gTRKFramingState.msgBufID != -1) { + TRKReleaseBuffer(gTRKFramingState.msgBufID); + gTRKFramingState.msgBufID = -1; + } + gTRKFramingState.buffer = NULL; + gTRKFramingState.receiveState = DSRECV_Wait; + break; + } + + if (serpoll_inline_00(gTRKFramingState.buffer)) { + temp_r3 = gTRKFramingState.msgBufID; + gTRKFramingState.msgBufID = -1; + gTRKFramingState.buffer = NULL; + gTRKFramingState.receiveState = DSRECV_Wait; + return temp_r3; + } + gTRKFramingState.receiveState = DSRECV_Wait; + } else { + if (gTRKFramingState.isEscape) { + sp8 ^= 0x20; + gTRKFramingState.isEscape = FALSE; + } else if (sp8 == 0x7D) { + gTRKFramingState.isEscape = TRUE; + break; + } + var_r29 = TRKAppendBuffer1_ui8(gTRKFramingState.buffer, sp8); + gTRKFramingState.fcsType += sp8; + } + break; + case DSRECV_FrameOverflow: + if (sp8 == 0x7E) { + if (gTRKFramingState.msgBufID != -1) { + TRKReleaseBuffer(gTRKFramingState.msgBufID); + gTRKFramingState.msgBufID = -1; + } + gTRKFramingState.buffer = NULL; + gTRKFramingState.receiveState = DSRECV_Wait; + } + break; + } + + var_r3 = TRKReadUARTPoll(&sp8); + } + + return -1; } diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c index cc1997e3f..aa53e64a7 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c @@ -1,21 +1,207 @@ #include "PowerPC_EABI_Support/MetroTRK/trk.h" -/* - * --INFO-- - * Address: 8021E21C - * Size: 0002D8 - */ -DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, u8* io_result, BOOL need_reply, BOOL read) +#include + +DSError HandlePositionFileSupportRequest(u32 replyErr, u32* param_2, u8 param_3, u8* ioResult) { - TRKBuffer* replyBuffer; - int replyBufferId; - u32 length; + int sp10; + int spC; + TRKBuffer* sp8; + TRKBuffer* var_r31; + DSError var_r27; + + var_r27 = TRKGetFreeBuffer(&spC, &sp8); + if (var_r27 == DS_NoError) { + var_r27 = TRKAppendBuffer1_ui8(sp8, 0xD4); + } + if (var_r27 == DS_NoError) { + var_r27 = TRKAppendBuffer1_ui32(sp8, replyErr); + } + if (var_r27 == DS_NoError) { + var_r27 = TRKAppendBuffer1_ui32(sp8, *param_2); + } + if (var_r27 == DS_NoError) { + var_r27 = TRKAppendBuffer1_ui8(sp8, param_3); + } + if (var_r27 == DS_NoError) { + *ioResult = DS_IONoError; + var_r27 = TRKRequestSend(sp8, &sp10, 3, 3, 0); + if (var_r27 == DS_NoError) { + var_r31 = TRKGetBuffer(sp10); + TRKSetBufferPosition(var_r31, 2); + } + if (var_r27 == DS_NoError) { + var_r27 = TRKReadBuffer1_ui8(var_r31, ioResult); + } + if (var_r27 == DS_NoError) { + var_r27 = TRKReadBuffer1_ui32(var_r31, param_2); + } else { + *param_2 = -1; + } + TRKReleaseBuffer(sp10); + } + TRKReleaseBuffer(spC); + return var_r27; +} + +DSError HandleCloseFileSupportRequest(int replyError, u8* ioResult) +{ + int sp10; + int spC; + DSError var_r31; + TRKBuffer* sp8; + TRKBuffer* var_r30; + + var_r31 = TRKGetFreeBuffer(&spC, &sp8); + if (var_r31 == DS_NoError) { + var_r31 = TRKAppendBuffer1_ui8(sp8, 0xD3); + } + if (var_r31 == DS_NoError) { + var_r31 = TRKAppendBuffer1_ui32(sp8, replyError); + } + if (var_r31 == DS_NoError) { + *ioResult = DS_IONoError; + var_r31 = TRKRequestSend(sp8, &sp10, 3, 3, 0); + if (var_r31 == DS_NoError) { + var_r30 = TRKGetBuffer(sp10); + TRKSetBufferPosition(var_r30, 2); + } + if (var_r31 == DS_NoError) { + var_r31 = TRKReadBuffer1_ui8(var_r30, ioResult); + } + TRKReleaseBuffer(sp10); + } + TRKReleaseBuffer(spC); + return var_r31; +} + +DSError HandleOpenFileSupportRequest(const char* path, u8 replyError, u32* param_3, u8* ioResult) +{ + int sp10; + int spC; + TRKBuffer* sp8; + TRKBuffer* var_r31; + DSError var_r26; + + *param_3 = 0; + var_r26 = TRKGetFreeBuffer(&spC, &sp8); + if (var_r26 == DS_NoError) { + var_r26 = TRKAppendBuffer1_ui8(sp8, 0xD2); + } + if (var_r26 == DS_NoError) { + var_r26 = TRKAppendBuffer1_ui8(sp8, replyError); + } + if (var_r26 == DS_NoError) { + var_r26 = TRKAppendBuffer1_ui16(sp8, strlen(path) + 1); + } + if (var_r26 == DS_NoError) { + var_r26 = TRKAppendBuffer_ui8(sp8, (const u8*)path, strlen(path) + 1); + } + if (var_r26 == DS_NoError) { + *ioResult = DS_IONoError; + var_r26 = TRKRequestSend(sp8, &sp10, 7, 3, 0); + if (var_r26 == DS_NoError) { + var_r31 = TRKGetBuffer(sp10); + TRKSetBufferPosition(var_r31, 2); + } + if (var_r26 == DS_NoError) { + var_r26 = TRKReadBuffer1_ui8(var_r31, ioResult); + } + if (var_r26 == DS_NoError) { + var_r26 = TRKReadBuffer1_ui32(var_r31, param_3); + } + TRKReleaseBuffer(sp10); + } + TRKReleaseBuffer(spC); + return var_r26; +} + +DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3) +{ + int error = DS_NoError; TRKBuffer* buffer; - int bufferId; + u32 timer; + int tries; + u8 msg_command; + u8 msg_error; + BOOL badReply = TRUE; + + *bufferId = -1; + + for (tries = p2 + 1; tries != 0 && *bufferId == -1 && error == DS_NoError; + tries--) { + error = TRKMessageSend(msgBuf); + if (error == DS_NoError) { + if (p3) { + timer = 0; + } + + while (TRUE) { + do { + *bufferId = TRKTestForPacket(); + if (*bufferId != -1) + break; + } while (!p3 || ++timer < 79999980); + + if (*bufferId == -1) + break; + + badReply = FALSE; + + buffer = TRKGetBuffer(*bufferId); + TRKSetBufferPosition(buffer, 0); + + if ((error = TRKReadBuffer1_ui8(buffer, &msg_command)) + != DS_NoError) + break; + + if (msg_command >= DSMSG_ReplyACK) + break; + + TRKProcessInput(*bufferId); + *bufferId = -1; + } + + if (*bufferId != -1) { + if (buffer->length < p1) { + badReply = TRUE; + } + if (error == DS_NoError && !badReply) { + error = TRKReadBuffer1_ui8(buffer, &msg_error); + } + if (error == DS_NoError && !badReply) { + if (msg_command != DSMSG_ReplyACK + || msg_error != DSREPLY_NoError) { + badReply = TRUE; + } + } + if (error != DS_NoError || badReply) { + TRKReleaseBuffer(*bufferId); + *bufferId = -1; + } + } + } + } + + if (*bufferId == -1) { + error = DS_Error800; + } + + return error; +} + +DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, + u8* io_result, BOOL need_reply, BOOL read) +{ DSError error; + int replyBufferId; + TRKBuffer* replyBuffer; + int bufferId; + TRKBuffer* buffer; + u32 length; u32 done; - u16 replyLength; u8 replyIOResult; + u16 replyLength; BOOL exit; if (data == NULL || *count == 0) { @@ -26,7 +212,8 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, u8* io_resul *io_result = DS_IONoError; done = 0; error = DS_NoError; - while (!exit && done < *count && error == DS_NoError && *io_result == DS_IONoError) { + while (!exit && done < *count && error == DS_NoError + && *io_result == DS_IONoError) { if (*count - done > 0x800) { length = 0x800; } else { @@ -36,7 +223,8 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, u8* io_resul error = TRKGetFreeBuffer(&bufferId, &buffer); if (error == DS_NoError) - error = TRKAppendBuffer1_ui8(buffer, read ? DSMSG_ReadFile : DSMSG_WriteFile); + error = TRKAppendBuffer1_ui8(buffer, read ? DSMSG_ReadFile + : DSMSG_WriteFile); if (error == DS_NoError) error = TRKAppendBuffer1_ui32(buffer, file_handle); @@ -52,7 +240,9 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, u8* io_resul replyLength = 0; replyIOResult = 0; - error = (0, TRKRequestSend(buffer, &replyBufferId, read ? 5 : 5, 3, !(read && file_handle == 0))); + error = TRKRequestSend(buffer, &replyBufferId, + read ? 5 : 5, 3, + !(read && file_handle == 0)); if (error == DS_NoError) { replyBuffer = (TRKBuffer*)TRKGetBuffer(replyBufferId); TRKSetBufferPosition(replyBuffer, 2); @@ -72,11 +262,13 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, u8* io_resul } if (replyLength <= length) - error = TRKReadBuffer_ui8(replyBuffer, data + done, replyLength); + error = TRKReadBuffer_ui8(replyBuffer, data + done, + replyLength); } if (replyLength != length) { - if ((!read || replyLength >= length) && replyIOResult == 0) + if ((!read || replyLength >= length) + && replyIOResult == 0) replyIOResult = 1; length = replyLength; exit = TRUE; @@ -96,79 +288,3 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, u8* io_resul *count = done; return error; } - -/* - * --INFO-- - * Address: 8021E4F4 - * Size: 0001A4 - */ -DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3) -{ - int error = DS_NoError; - TRKBuffer* buffer; - u32 timer; - int tries; - u8 msg_error; - u8 msg_command; - BOOL badReply = TRUE; - - *bufferId = -1; - - for (tries = p2 + 1; tries != 0 && *bufferId == -1 && error == DS_NoError; tries--) { - error = TRKMessageSend(msgBuf); - if (error == DS_NoError) { - if (p3) { - timer = 0; - } - - while (TRUE) { - do { - *bufferId = TRKTestForPacket(); - if (*bufferId != -1) - break; - } while (!p3 || ++timer < 79999980); - - if (*bufferId == -1) - break; - - badReply = FALSE; - - buffer = TRKGetBuffer(*bufferId); - TRKSetBufferPosition(buffer, 0); - - if ((error = TRKReadBuffer1_ui8(buffer, &msg_command)) != DS_NoError) - break; - - if (msg_command >= DSMSG_ReplyACK) - break; - - TRKProcessInput(*bufferId); - *bufferId = -1; - } - - if (*bufferId != -1) { - if (buffer->length < p1) { - badReply = TRUE; - } - if (error == DS_NoError && !badReply) { - error = TRKReadBuffer1_ui8(buffer, &msg_error); - } - if (error == DS_NoError && !badReply) { - if (msg_command != DSMSG_ReplyACK || msg_error != DSREPLY_NoError) { - badReply = TRUE; - } - } - if (error != DS_NoError || badReply) { - TRKReleaseBuffer(*bufferId); - *bufferId = -1; - } - } - } - } - - if (*bufferId == -1) { - error = DS_Error800; - } - - return error; -} diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.h b/src/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.h index bf0e9b928..fbd8fcc50 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.h +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Export/targsupp.h @@ -7,10 +7,10 @@ extern "C" { #endif -u32 TRKAccessFile(u32, u32, u32*, u8*); -u32 TRKOpenFile(u32, u32, u32*, u8*); -u32 TRKCloseFile(u32, u32); -u32 TRKPositionFile(u32, u32, u32*, u8*); +u32 TRKAccessFile(u8 command, u32 file_handle, u32* length_ptr, u8* buffer_ptr); +u32 TRKOpenFile(u8 command, u32 file_handle, u8 flags, u8* buffer_ptr); +u32 TRKCloseFile(u8 command, u32 file_handle); +u32 TRKPositionFile(u8 command, u32 file_handle, u32* position_ptr, u8 pos_mode); #ifdef __cplusplus } diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c b/src/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c index 77ea47844..37f8c29b1 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Processor/ppc/Generic/targimpl.c @@ -644,8 +644,8 @@ DSError TRKTargetAccessExtended2(u32 firstRegister, u32 lastRegister, TRKBuffer* */ DSError TRKTargetVersions(DSVersions* versions) { - versions->kernelMajor = 0; - versions->kernelMinor = 8; + versions->kernelMajor = 2; + versions->kernelMinor = 0; versions->protocolMajor = 1; versions->protocolMinor = 10; return DS_NoError; @@ -1051,6 +1051,7 @@ DSError TRKTargetAddStopInfo(TRKBuffer* buffer) { DSError error; u32 instruction; + s32 i; error = TRKAppendBuffer1_ui32(buffer, gTRKCPUState.Default.PC); if (error == DS_NoError) { @@ -1061,6 +1062,15 @@ DSError TRKTargetAddStopInfo(TRKBuffer* buffer) if (error == DS_NoError) error = TRKAppendBuffer1_ui16(buffer, gTRKCPUState.Extended1.exceptionID); + if (error == DS_NoError) { + for (i = 0; i < 32; i++) { + error = TRKAppendBuffer1_ui32(buffer, (u16)gTRKCPUState.Default.GPR[i]); + } + for (i = 0; i < 32; i++) { + error = TRKAppendBuffer1_ui64(buffer, (u16)gTRKCPUState.Float.FPR[i]); + } + } + return error; } @@ -1231,28 +1241,53 @@ u32 TRKTargetGetPC() DSError TRKTargetSupportRequest(void) { DSError error; - // u32 spC; + u32 position; + u8 commandId; size_t* length; TRKEvent event; u8 ioResult; - u8 commandId; - commandId = (MessageCommandID)gTRKCPUState.Default.GPR[3]; - if (commandId != DSMSG_ReadFile && commandId != DSMSG_WriteFile) { + commandId = gTRKCPUState.Default.GPR[3]; + if (commandId != DSMSG_ReadFile && commandId != DSMSG_WriteFile && commandId != DSMSG_OpenFile && commandId != DSMSG_CloseFile + && commandId != DSMSG_PositionFile) { TRKConstructEvent(&event, NUBEVENT_Exception); TRKPostEvent(&event); return DS_NoError; } - length = (size_t*)gTRKCPUState.Default.GPR[5]; - error = TRKSuppAccessFile((u8)gTRKCPUState.Default.GPR[4], (u8*)gTRKCPUState.Default.GPR[6], length, (DSIOResult*)&ioResult, TRUE, - commandId == DSMSG_ReadFile); - if (ioResult == DS_IONoError && error != DS_NoError) { - ioResult = DS_IOError; - } - gTRKCPUState.Default.GPR[3] = ioResult; - if (commandId == DSMSG_ReadFile) { - TRK_flush_cache((void*)gTRKCPUState.Default.GPR[6], *length); + if (commandId == DSMSG_OpenFile) { + error = HandleOpenFileSupportRequest((const char*)gTRKCPUState.Default.GPR[4], gTRKCPUState.Default.GPR[5] & 0xFF, + (u32*)gTRKCPUState.Default.GPR[6], (u8*)&ioResult); + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + gTRKCPUState.Default.GPR[3] = ioResult; + } else if (commandId == DSMSG_CloseFile) { + error = HandleCloseFileSupportRequest(gTRKCPUState.Default.GPR[4], (u8*)&ioResult); + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + gTRKCPUState.Default.GPR[3] = ioResult; + } else if (commandId == DSMSG_PositionFile) { + position = *(u32*)gTRKCPUState.Default.GPR[5]; + error = HandlePositionFileSupportRequest(gTRKCPUState.Default.GPR[4], &position, (u8)gTRKCPUState.Default.GPR[6], (u8*)&ioResult); + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + gTRKCPUState.Default.GPR[3] = ioResult; + *(u32*)gTRKCPUState.Default.GPR[5] = position; + } else { + u8 fileHandle = gTRKCPUState.Default.GPR[4]; + u8* data = (u8*)gTRKCPUState.Default.GPR[6]; + length = (size_t*)gTRKCPUState.Default.GPR[5]; + error = TRKSuppAccessFile(fileHandle, data, length, &ioResult, TRUE, commandId == DSMSG_ReadFile); + if (ioResult == DS_IONoError && error != DS_NoError) { + ioResult = DS_IOError; + } + gTRKCPUState.Default.GPR[3] = ioResult; + if (commandId == DSMSG_ReadFile) { + TRK_flush_cache((void*)gTRKCPUState.Default.GPR[6], *length); + } } gTRKCPUState.Default.PC += 4; return error; @@ -1309,11 +1344,12 @@ u32 TRKTargetStop() * Address: 8021FB40 * Size: 0000B0 */ -DSError TRKPPCAccessSPR(void* value, u32 spr_register_num, BOOL read) +inline DSError TRKPPCAccessSPR(void* value, u32 spr_register_num, BOOL read) { /* Initialize instruction array with nop */ - u32 access_func[5] = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; + u32 access_func[10] = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, + INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; /* ** Construct a small assembly function to perform the ** requested access and call it. The read/write function @@ -1347,10 +1383,11 @@ DSError TRKPPCAccessSPR(void* value, u32 spr_register_num, BOOL read) * Address: 8021FBF0 * Size: 000078 */ -DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read) +inline DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read) { // all nop by default - u32 instructionData[] = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; + u32 instructionData[] = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, + INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; if (read) { instructionData[0] = INSTR_PSQ_ST(psr, 0, 3, 0, 0); // psq_st psr, 0(r3), 0, 0 @@ -1369,11 +1406,12 @@ DSError TRKPPCAccessPairedSingleRegister(void* srcDestPtr, u32 psr, BOOL read) * Address: 8021FC68 * Size: 000180 */ -DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read) +inline DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read) { DSError error = DS_NoError; // all nop by default - u32 instructionData1[] = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; + u32 instructionData1[] = { INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, + INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP, INSTR_NOP }; if (fpr < FP_FPSCR_ACCESS) { if (read) { @@ -1385,31 +1423,6 @@ DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read) error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read); } else if (fpr == FP_FPSCR_ACCESS) { - if (read) { - /* - stfd f1, 0 (r4) - mffs sp - stfd f1, 0 (r3) - lfd f1, 0 (r4) - */ - instructionData1[0] = 0xD8240000; - instructionData1[1] = 0xFC20048E; - instructionData1[2] = 0xD8230000; - instructionData1[3] = 0xC8240000; - } else { - /* - stfd f1, 0 (r4) - lfd f1, 0 (r3) - mtfsf 0xff, f1 - lfd f1, 0 (r4) - */ - instructionData1[0] = 0xD8240000; - instructionData1[1] = 0xC8230000; - instructionData1[2] = 0xFDFE0D8E; - instructionData1[3] = 0xC8240000; - } - - error = TRKPPCAccessSpecialReg(srcDestPtr, instructionData1, read); *(u64*)srcDestPtr &= 0xFFFFFFFF; } else if (fpr == FP_FPECR_ACCESS) { @@ -1432,9 +1445,10 @@ DSError TRKPPCAccessFPRegister(void* srcDestPtr, u32 fpr, BOOL read) * Address: 8021FDE8 * Size: 000068 */ -DSError TRKPPCAccessSpecialReg(void* value, u32* access_func, BOOL read) +inline DSError TRKPPCAccessSpecialReg(void* value, u32* access_func, BOOL read) { typedef void (*asm_access_type)(void*, void*); + asm_access_type asm_access; /* ** Construct a small assembly function to perform the @@ -1447,15 +1461,17 @@ DSError TRKPPCAccessSpecialReg(void* value, u32* access_func, BOOL read) /* ** Put blr instruction at the end of access function (it should be - ** a 5-instruction array w/the last one empty). + ** a 10-instruction array w/the last one empty). */ - access_func[4] = INSTR_BLR; + access_func[9] = INSTR_BLR; /* ** Now that the instruction array is built, get a function pointer to it. */ + asm_access = (asm_access_type)access_func; + #if DEBUG_VECTORREG_ACCESS __puts("\r\nasm_access: "); @@ -1477,8 +1493,8 @@ DSError TRKPPCAccessSpecialReg(void* value, u32* access_func, BOOL read) #endif // Flush cache - TRK_flush_cache((void*)(u32)access_func, (sizeof(access_func) * 5)); - ((asm_access_type)access_func)((u32*)value, (void*)&TRKvalue128_temp); + TRK_flush_cache((void*)(u32)access_func, (sizeof(access_func) * 10)); + (*asm_access)((u32*)value, (void*)&TRKvalue128_temp); return DS_NoError; } diff --git a/tools/project.py b/tools/project.py index b33a4bc4e..ad4b0c01f 100644 --- a/tools/project.py +++ b/tools/project.py @@ -54,6 +54,7 @@ def __init__(self, completed: bool, name: str, **options: Any) -> None: "asflags": None, "asm_dir": None, "cflags": None, + "extab_padding": None, "extra_asflags": [], "extra_cflags": [], "extra_clang_flags": [], @@ -91,6 +92,7 @@ def set_default(key: str, value: Any) -> None: set_default("add_to_all", True) set_default("asflags", config.asflags) set_default("asm_dir", config.asm_dir) + set_default("extab_padding", None) set_default("host", False) set_default("mw_version", config.linker_version) set_default("scratch_preset_id", config.scratch_preset_id) @@ -203,6 +205,7 @@ def __init__(self) -> None: self.progress_each_module: bool = ( False # Include individual modules, disable for large numbers of modules ) + self.progress_report_args: List[str] = [] # Extra arguments for objdiff report self.progress_categories: List[ProgressCategory] = [] # Additional categories self.print_progress_categories: Union[bool, List[str]] = ( True # Print additional progress categories in the CLI progress output @@ -407,7 +410,10 @@ def generate_build_ninja( n.variable("ninja_required_version", "1.3") n.newline() - configure_script = Path(os.path.relpath(os.path.abspath(sys.argv[0]))) + configure_entry = sys.argv[0] + if configure_entry in {"", "-"} or not Path(configure_entry).exists(): + configure_entry = "configure.py" + configure_script = Path(os.path.relpath(os.path.abspath(configure_entry))) python_lib = Path(os.path.relpath(__file__)) python_lib_dir = python_lib.parent n.comment("The arguments passed to configure.py, for rerunning it.") @@ -626,6 +632,16 @@ def write_cargo_rule(): mwcc_sjis_cmd = f"{wrapper_cmd}{sjiswrap} {mwcc} $cflags -MMD -c $in -o $basedir" mwcc_sjis_implicit: List[Optional[Path]] = [*mwcc_implicit, sjiswrap] + # MWCC with extab post-processing + mwcc_extab_cmd = ( + f'{CHAIN}{mwcc_cmd} && {dtk} extab clean --padding "$extab_padding" $out $out' + ) + mwcc_extab_implicit: List[Optional[Path]] = [*mwcc_implicit, dtk] + mwcc_sjis_extab_cmd = ( + f'{CHAIN}{mwcc_sjis_cmd} && {dtk} extab clean --padding "$extab_padding" $out $out' + ) + mwcc_sjis_extab_implicit: List[Optional[Path]] = [*mwcc_sjis_implicit, dtk] + # MWLD mwld = compiler_path / "mwldeppc.exe" mwld_cmd = f"{wrapper_cmd}{mwld} $ldflags -o $out @$out.rsp" @@ -694,6 +710,26 @@ def write_cargo_rule(): ) n.newline() + n.comment("MWCC build (with extab post-processing)") + n.rule( + name="mwcc_extab", + command=mwcc_extab_cmd, + description="MWCC $out", + depfile="$basefile.d", + deps="gcc", + ) + n.newline() + + n.comment("MWCC build (with UTF-8 to Shift JIS wrapper & extab post-processing)") + n.rule( + name="mwcc_sjis_extab", + command=mwcc_sjis_extab_cmd, + description="MWCC $out", + depfile="$basefile.d", + deps="gcc", + ) + n.newline() + n.comment("Assemble asm") n.rule( name="as", @@ -905,18 +941,29 @@ def c_build(obj: Object, src_path: Path) -> Optional[Path]: if ("prodg" in obj.options["mw_version"].lower()): fakerule = "prodg" fakeimplicit = ngccc_implicit + variables = { + "mw_version": Path(obj.options["mw_version"]), + "cflags": cflags_str, + "basedir": os.path.dirname(obj.src_obj_path), + "basefile": obj.src_obj_path.with_suffix(""), + } + if obj.options["extab_padding"] is not None: + if obj.options["shift_jis"]: + fakerule = "mwcc_sjis_extab" + fakeimplicit = mwcc_sjis_extab_implicit + elif fakerule == "mwcc": + fakerule = "mwcc_extab" + fakeimplicit = mwcc_extab_implicit + variables["extab_padding"] = "".join( + f"{i:02x}" for i in obj.options["extab_padding"] + ) lib_name = obj.options["lib"] n.comment(f"{obj.name}: {lib_name} (linked {obj.completed})") n.build( outputs=obj.src_obj_path, rule=fakerule, inputs=src_path, - variables={ - "mw_version": Path(obj.options["mw_version"]), - "cflags": cflags_str, - "basedir": os.path.dirname(obj.src_obj_path), - "basefile": obj.src_obj_path.with_suffix(""), - }, + variables=variables, implicit=( fakeimplicit ), @@ -1236,9 +1283,14 @@ def add_unit(build_obj: BuildConfigUnit, link_step: LinkStep): # Generate progress report ### n.comment("Generate progress report") + report_args = ( + f" {' '.join(config.progress_report_args)}" + if config.progress_report_args + else "" + ) n.rule( name="report", - command=f"{objdiff} report generate -o $out", + command=f"{objdiff} report generate{report_args} -o $out", description="REPORT", ) n.build(