From 66883b9715efc10dcfb1faf54614529871b8bc5f Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 15:30:22 -0700 Subject: [PATCH 01/47] Improve MSL matching progress --- configure.py | 8 ++++---- .../PowerPC_EABI_Support/MSL_C/MSL_Common/math_api.h | 2 ++ src/PowerPC_EABI_Support/src/MSL_C/PPC_EABI/math_ppc.c | 1 + .../src/Runtime/__init_cpp_exceptions.cpp | 6 +++++- .../src/Runtime/global_destructor_chain.c | 4 ++++ 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/configure.py b/configure.py index 8f1608937..470bbfab5 100644 --- a/configure.py +++ b/configure.py @@ -843,7 +843,7 @@ def MatchingFor(*versions): [ Object(NonMatching, "Runtime/__mem.c", extra_cflags=["-inline on, deferred"]), Object(Matching, "Runtime/__va_arg.c"), - Object(NonMatching, "Runtime/global_destructor_chain.c"), + Object(Matching, "Runtime/global_destructor_chain.c"), Object(NonMatching, "Runtime/New.cp"), Object(NonMatching, "Runtime/NMWException.cp"), Object(Matching, "Runtime/CPlusLibPPC.cp"), @@ -871,7 +871,7 @@ def MatchingFor(*versions): 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(Matching, "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"), @@ -923,7 +923,7 @@ 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( @@ -945,7 +945,7 @@ def MatchingFor(*versions): Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mem_TRK.c"), Object(NonMatching, "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(Matching, "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/Export/targsupp.s"), Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/mpc_7xx_603e.c"), 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/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/__init_cpp_exceptions.cpp b/src/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp index 617b7374d..12964308d 100644 --- a/src/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp +++ b/src/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp @@ -3,6 +3,10 @@ #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() ; @@ -34,4 +38,4 @@ asm char* GetR2() __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/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) From f1959164163c0cbd4643a85e6978427706095be6 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 15:38:48 -0700 Subject: [PATCH 02/47] Match MSL float constants --- configure.py | 2 +- src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/float.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/configure.py b/configure.py index 470bbfab5..46d2725f4 100644 --- a/configure.py +++ b/configure.py @@ -884,7 +884,7 @@ def MatchingFor(*versions): 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(Matching, "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") 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 }; From a128acda7a097709b00573853cfe1adcee688433 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 15:53:00 -0700 Subject: [PATCH 03/47] Match more MSL TRK units --- configure.py | 6 +- .../src/Runtime/__init_cpp_exceptions.cpp | 24 +++--- .../embedded/MetroTRK/Portable/notify.c | 6 +- .../embedded/MetroTRK/Portable/nubevent.c | 84 ++++++++----------- 4 files changed, 53 insertions(+), 67 deletions(-) diff --git a/configure.py b/configure.py index 46d2725f4..36cff5911 100644 --- a/configure.py +++ b/configure.py @@ -849,7 +849,7 @@ def MatchingFor(*versions): Object(Matching, "Runtime/CPlusLibPPC.cp"), Object(NonMatching, "Runtime/ptmf.c"), Object(NonMatching, "Runtime/runtime.c"), - Object(NonMatching, "Runtime/__init_cpp_exceptions.cpp"), + Object(Matching, "Runtime/__init_cpp_exceptions.cpp"), Object(NonMatching, "Runtime/Gecko_ExceptionPPC.cp"), Object(NonMatching, "Runtime/GCN_mem_alloc.c"), ] @@ -930,7 +930,7 @@ def MatchingFor(*versions): "TRK_MINNOW_DOLPHIN", [ Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mainloop.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubevent.c"), + Object(Matching, "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"), @@ -940,7 +940,7 @@ def MatchingFor(*versions): Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msghndlr.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/support.c"), Object(Matching, "debugger/embedded/MetroTRK/Portable/mutex_TRK.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/notify.c"), + Object(Matching, "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"), 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 12964308d..48a2e4d84 100644 --- a/src/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp +++ b/src/PowerPC_EABI_Support/src/Runtime/__init_cpp_exceptions.cpp @@ -11,12 +11,12 @@ 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 @@ -28,12 +28,12 @@ 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; 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; } From caaf6278f4eab77f0f627dce57a32747f2da9de6 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 15:58:24 -0700 Subject: [PATCH 04/47] Match MSL runtime helpers --- configure.py | 2 +- src/PowerPC_EABI_Support/src/Runtime/runtime.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.py b/configure.py index 36cff5911..f1d27e0b3 100644 --- a/configure.py +++ b/configure.py @@ -848,7 +848,7 @@ def MatchingFor(*versions): Object(NonMatching, "Runtime/NMWException.cp"), Object(Matching, "Runtime/CPlusLibPPC.cp"), Object(NonMatching, "Runtime/ptmf.c"), - Object(NonMatching, "Runtime/runtime.c"), + Object(Matching, "Runtime/runtime.c"), Object(Matching, "Runtime/__init_cpp_exceptions.cpp"), Object(NonMatching, "Runtime/Gecko_ExceptionPPC.cp"), Object(NonMatching, "Runtime/GCN_mem_alloc.c"), 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 From b910b60e0e27818334d71640887fc2e2385d07bc Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 16:05:55 -0700 Subject: [PATCH 05/47] Match more MSL TRK support --- configure.py | 2 +- .../src/MSL_C/MSL_Common/mem_funcs.c | 368 +++++++++--------- .../embedded/MetroTRK/Portable/mainloop.c | 136 ++++--- 3 files changed, 256 insertions(+), 250 deletions(-) diff --git a/configure.py b/configure.py index f1d27e0b3..cb0507b01 100644 --- a/configure.py +++ b/configure.py @@ -929,7 +929,7 @@ def MatchingFor(*versions): trkLib( "TRK_MINNOW_DOLPHIN", [ - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mainloop.c"), + Object(Matching, "debugger/embedded/MetroTRK/Portable/mainloop.c"), Object(Matching, "debugger/embedded/MetroTRK/Portable/nubevent.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubassrt.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubinit.c"), 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/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 } From 843a82c5c86dcb97d2b61dd9ac118123e9088e38 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 16:22:35 -0700 Subject: [PATCH 06/47] Match TRK dispatch --- configure.py | 2 +- .../embedded/MetroTRK/Portable/dispatch.c | 80 ++++++++++++------- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/configure.py b/configure.py index cb0507b01..299169564 100644 --- a/configure.py +++ b/configure.py @@ -936,7 +936,7 @@ def MatchingFor(*versions): 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(Matching, "debugger/embedded/MetroTRK/Portable/dispatch.c", extra_cflags=["-sdata 0", "-sdata2 0"]), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msghndlr.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/support.c"), Object(Matching, "debugger/embedded/MetroTRK/Portable/mutex_TRK.c"), 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 } From 1bc202f9fff38a49e31761688c8cddd923028d2b Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 16:31:02 -0700 Subject: [PATCH 07/47] Improve TRK message handler matching --- configure.py | 2 +- .../embedded/MetroTRK/Portable/msghndlr.c | 85 +++++++++++++++---- 2 files changed, 71 insertions(+), 16 deletions(-) diff --git a/configure.py b/configure.py index 299169564..6974a3510 100644 --- a/configure.py +++ b/configure.py @@ -937,7 +937,7 @@ def MatchingFor(*versions): Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msgbuf.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/serpoll.c"), Object(Matching, "debugger/embedded/MetroTRK/Portable/dispatch.c", extra_cflags=["-sdata 0", "-sdata2 0"]), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msghndlr.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msghndlr.c", extra_cflags=["-sdata 0", "-sdata2 0"]), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/support.c"), Object(Matching, "debugger/embedded/MetroTRK/Portable/mutex_TRK.c"), Object(Matching, "debugger/embedded/MetroTRK/Portable/notify.c"), diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c index b13760a05..3547f17fd 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,7 +221,7 @@ DSError TRKDoCPUType(TRKBuffer* buffer) */ DSError TRKDoReadMemory(TRKBuffer* buffer) { - u8 tempBuf[0x800] ATTRIBUTE_ALIGN(32); + u8 tempBuf[0x800]; u32 length; u32 msg_start; u16 msg_length; @@ -299,7 +304,7 @@ DSError TRKDoReadMemory(TRKBuffer* buffer) */ DSError TRKDoWriteMemory(TRKBuffer* buffer) { - u8 tmpBuffer[0x800] ATTRIBUTE_ALIGN(32); + u8 tmpBuffer[0x800]; u32 length; u32 msg_start; u16 msg_length; @@ -739,3 +744,53 @@ DSError TRKDoStop(TRKBuffer* b) return TRKStandardACK(b, DSMSG_ReplyACK, replyError); } + +/* + * --INFO-- + * Address: 8021E21C + * Size: 0001A4 + */ +DSError TRKDoSetOption(TRKBuffer* buffer) +{ + DSError error; + u8 msg_command; + u8 msg_option; + u8 msg_param; + + msg_command = 0; + msg_option = 0; + msg_param = 0; + + TRKSetBufferPosition(buffer, DSREPLY_NoError); + error = TRKReadBuffer1_ui8(buffer, &msg_command); + if (error == DS_NoError) + error = TRKReadBuffer1_ui8(buffer, &msg_option); + if (error == DS_NoError) + error = TRKReadBuffer1_ui8(buffer, &msg_param); + + if (error != DS_NoError) { + TRKResetBuffer(buffer, 1); + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = DSMSG_ReplyACK; + buffer->length += 1; + } + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = DSREPLY_PacketSizeError; + buffer->length += 1; + } + TRKSendACK(buffer); + } else if (msg_option == 1) { + SetUseSerialIO(msg_param); + } + + TRKResetBuffer(buffer, 1); + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = DSMSG_ReplyACK; + buffer->length += 1; + } + if (buffer->position < 0x880) { + buffer->data[buffer->position++] = DSREPLY_NoError; + buffer->length += 1; + } + return TRKSendACK(buffer); +} From 06122104931c4337ef30994d89cb61a052192db1 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 16:39:08 -0700 Subject: [PATCH 08/47] Tighten TRK msghndlr matching --- .../embedded/MetroTRK/Portable/msghndlr.c | 95 +++++++++---------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c index 3547f17fd..92d34a8d0 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msghndlr.c @@ -221,14 +221,14 @@ DSError TRKDoCPUType(TRKBuffer* buffer) */ DSError TRKDoReadMemory(TRKBuffer* buffer) { + DSError error; + DSReplyError replyError; u8 tempBuf[0x800]; - u32 length; 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); @@ -304,14 +304,14 @@ DSError TRKDoReadMemory(TRKBuffer* buffer) */ DSError TRKDoWriteMemory(TRKBuffer* buffer) { + DSError error; + DSReplyError replyError; u8 tmpBuffer[0x800]; - u32 length; 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); @@ -390,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); @@ -478,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); @@ -569,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); @@ -645,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) { @@ -753,44 +753,43 @@ DSError TRKDoStop(TRKBuffer* b) DSError TRKDoSetOption(TRKBuffer* buffer) { DSError error; - u8 msg_command; - u8 msg_option; - u8 msg_param; - - msg_command = 0; - msg_option = 0; - msg_param = 0; + u8 spA; + u8 sp9; + u8 sp8; + spA = 0; + sp9 = 0; + sp8 = 0; TRKSetBufferPosition(buffer, DSREPLY_NoError); - error = TRKReadBuffer1_ui8(buffer, &msg_command); - if (error == DS_NoError) - error = TRKReadBuffer1_ui8(buffer, &msg_option); - if (error == DS_NoError) - error = TRKReadBuffer1_ui8(buffer, &msg_param); - + 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++] = DSMSG_ReplyACK; - buffer->length += 1; + buffer->data[buffer->position++] = 0x80; + buffer->length++; } if (buffer->position < 0x880) { - buffer->data[buffer->position++] = DSREPLY_PacketSizeError; - buffer->length += 1; + buffer->data[buffer->position++] = 1; + buffer->length++; } TRKSendACK(buffer); - } else if (msg_option == 1) { - SetUseSerialIO(msg_param); + } else if (sp9 == 1) { + SetUseSerialIO(sp8); } - TRKResetBuffer(buffer, 1); if (buffer->position < 0x880) { - buffer->data[buffer->position++] = DSMSG_ReplyACK; - buffer->length += 1; + buffer->data[buffer->position++] = 0x80; + buffer->length++; } if (buffer->position < 0x880) { - buffer->data[buffer->position++] = DSREPLY_NoError; - buffer->length += 1; + buffer->data[buffer->position++] = 0; + buffer->length++; } return TRKSendACK(buffer); } From c8ab8d4c6fe274c6825edc97ebc8d80addde559c Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 16:49:09 -0700 Subject: [PATCH 09/47] Match TRK main entry --- configure.py | 2 +- src/runtime_libs/debugger/embedded/MetroTRK/Portable/main_TRK.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.py b/configure.py index 6974a3510..187c6704b 100644 --- a/configure.py +++ b/configure.py @@ -941,7 +941,7 @@ def MatchingFor(*versions): Object(NonMatching, "debugger/embedded/MetroTRK/Portable/support.c"), Object(Matching, "debugger/embedded/MetroTRK/Portable/mutex_TRK.c"), Object(Matching, "debugger/embedded/MetroTRK/Portable/notify.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/main_TRK.c"), + Object(Matching, "debugger/embedded/MetroTRK/Portable/main_TRK.c", extra_cflags=["-sdata 0", "-sdata2 0"]), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/mem_TRK.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/string_TRK.c"), Object(Matching, "debugger/embedded/MetroTRK/Processor/ppc/Generic/flush_cache.c"), 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-- From 6308469bbce97475853c2443dbd4fcf650eaafe9 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 17:11:58 -0700 Subject: [PATCH 10/47] Tighten TRK nubinit matching --- configure.py | 2 +- .../embedded/MetroTRK/Portable/nubinit.c | 97 +++++++++---------- 2 files changed, 47 insertions(+), 52 deletions(-) diff --git a/configure.py b/configure.py index 187c6704b..e9764cfd8 100644 --- a/configure.py +++ b/configure.py @@ -932,7 +932,7 @@ def MatchingFor(*versions): Object(Matching, "debugger/embedded/MetroTRK/Portable/mainloop.c"), Object(Matching, "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/nubinit.c", extra_cflags=["-sdata 0", "-sdata2 0"]), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msg.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msgbuf.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/serpoll.c"), diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/nubinit.c index 04b5568e1..a40bf4849 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; } /* @@ -52,25 +26,20 @@ DSError TRKTerminateNub(void) /* * --INFO-- - * Address: 8021C408 - * Size: 000028 - */ -void TRKNubWelcome(void) -{ - TRK_board_display("MetroTRK for Dolphin v0.8"); - return; -} - -/* - * --INFO-- - * Address: 8021C430 - * Size: 000074 + * Address: 8021C310 + * Size: 0000D4 */ -BOOL TRKInitializeEndian(void) +DSError TRKInitializeNub(void) { u8 bendian[4]; - BOOL result = FALSE; - gTRKBigEndian = TRUE; + BOOL* bigEndian; + DSError ret; + DSError uartErr; + volatile u8** inputPendingPtr; + + ret = DS_NoError; + bigEndian = &gTRKBigEndian; + *bigEndian = TRUE; bendian[0] = 0x12; bendian[1] = 0x34; @@ -78,11 +47,37 @@ BOOL TRKInitializeEndian(void) bendian[3] = 0x78; if (*(u32*)bendian == 0x12345678) { - gTRKBigEndian = TRUE; + *bigEndian = TRUE; } else if (*(u32*)bendian == 0x78563412) { - gTRKBigEndian = FALSE; + *bigEndian = FALSE; } else { - result = TRUE; + ret = TRUE; } - return result; + + 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) { + inputPendingPtr = (volatile u8**)&gTRKInputPendingPtr; + uartErr = TRKInitializeIntDrivenUART(0x0000e100, 1, 0, inputPendingPtr); + TRKTargetSetInputPendingPtr((void*)*inputPendingPtr); + if (uartErr != DS_NoError) { + ret = uartErr; + } + } + + if (ret == DS_NoError) + ret = TRKInitializeSerialHandler(); + if (ret == DS_NoError) + ret = TRKInitializeTarget(); + + return ret; } From e654a6e6bb651196358dab39807b37f3417d3405 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 17:33:29 -0700 Subject: [PATCH 11/47] Improve MSL signal and exit matching --- .../src/MSL_C/MSL_Common/signal.c | 18 ++--- .../src/MSL_C/PPC_EABI/abort_exit.c | 66 ++++++++++--------- 2 files changed, 44 insertions(+), 40 deletions(-) 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..f82820379 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 @@ -8,32 +8,34 @@ __signal_func_ptr signal_funcs[6]; int raise(int sig) { __signal_func_ptr signal_func; + __signal_func_ptr* signal_ptr; if (sig < 1 || sig > 6) { return -1; } - __begin_critical_region(stderr_access); - signal_func = signal_funcs[sig - 1]; + __begin_critical_region(4); + signal_ptr = &signal_funcs[sig]; + signal_func = *--signal_ptr; - if (signal_func != ((__std(__signal_func_ptr))1)) + if ((unsigned long)signal_func != 1) { - signal_funcs[sig - 1] = ((__std(__signal_func_ptr))0); + *signal_ptr = NULL; } - __end_critical_region(stderr_access); + __end_critical_region(4); - if (signal_func == ((__std(__signal_func_ptr))1) || (signal_func == ((__std(__signal_func_ptr))0) && sig == 1)) + if ((unsigned long)signal_func == 1 || (signal_func == NULL && sig == 1)) { return 0; } - if (signal_func == ((__std(__signal_func_ptr))0)) + if (signal_func == NULL) { exit(0); } (*signal_func)(sig); return 0; -} \ No newline at end of file +} 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; } From 81f78d78dd83a96ce246f49ff2888c332bd607ef Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 17:41:21 -0700 Subject: [PATCH 12/47] Match TRK serial polling parser --- .../embedded/MetroTRK/Portable/serpoll.c | 218 ++++++++++-------- 1 file changed, 118 insertions(+), 100 deletions(-) diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c index 06947aaa7..b103b6f4b 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/serpoll.c @@ -3,133 +3,151 @@ void* gTRKInputPendingPtr; static TRKFramingState gTRKFramingState; -/* - * --INFO-- - * Address: ........ - * Size: 00004C - */ -void TRKDiscardFrame(void) +DSError TRKInitializeSerialHandler(void) { - // UNUSED FUNCTION + gTRKFramingState.msgBufID = -1; + gTRKFramingState.receiveState = 0; + gTRKFramingState.isEscape = 0; + return 0; } /* * --INFO-- - * Address: ........ - * Size: 000040 + * Address: 8021CED4 + * Size: 000008 */ -void TRKRejectFrame(void) +DSError TRKTerminateSerialHandler(void) { - // UNUSED FUNCTION + 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; } From 62e215c9c1da06e73900c3c4c5e18bd059586887 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 17:49:23 -0700 Subject: [PATCH 13/47] Import TRK file support helpers --- .../embedded/MetroTRK/Portable/support.c | 296 ++++++++++++------ 1 file changed, 205 insertions(+), 91 deletions(-) diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c index cc1997e3f..f39007431 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c @@ -1,22 +1,208 @@ #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 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; + 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; +} + +DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, + u8* io_result, BOOL need_reply, BOOL read) +{ + BOOL exit; + u32 done; + DSError error; int replyBufferId; - u32 length; TRKBuffer* buffer; + TRKBuffer* replyBuffer; + u32 length; int bufferId; - DSError error; - u32 done; u16 replyLength; u8 replyIOResult; - BOOL exit; if (data == NULL || *count == 0) { return DS_ParameterError; @@ -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,8 @@ 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 = (0, TRKRequestSend(buffer, &replyBufferId, read ? 5 : 5, 3, + !(read && file_handle == 0))); if (error == DS_NoError) { replyBuffer = (TRKBuffer*)TRKGetBuffer(replyBufferId); TRKSetBufferPosition(replyBuffer, 2); @@ -72,7 +261,8 @@ 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) { @@ -96,79 +286,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; -} From 1bf53bfb95334ff914ebce69351378f986c96ee9 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 17:59:23 -0700 Subject: [PATCH 14/47] Tighten TRK support matching --- .../embedded/MetroTRK/Portable/support.c | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c index f39007431..ba55703ed 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/support.c @@ -122,8 +122,8 @@ DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3) TRKBuffer* buffer; u32 timer; int tries; - u8 msg_error; u8 msg_command; + u8 msg_error; BOOL badReply = TRUE; *bufferId = -1; @@ -193,16 +193,17 @@ DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3) DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, u8* io_result, BOOL need_reply, BOOL read) { - BOOL exit; - u32 done; DSError error; int replyBufferId; - TRKBuffer* buffer; TRKBuffer* replyBuffer; - u32 length; int bufferId; - u16 replyLength; + TRKBuffer* buffer; + u32 length; + const BOOL doRead = read; + u32 done; u8 replyIOResult; + u16 replyLength; + BOOL exit; if (data == NULL || *count == 0) { return DS_ParameterError; @@ -223,7 +224,7 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, error = TRKGetFreeBuffer(&bufferId, &buffer); if (error == DS_NoError) - error = TRKAppendBuffer1_ui8(buffer, read ? DSMSG_ReadFile + error = TRKAppendBuffer1_ui8(buffer, doRead ? DSMSG_ReadFile : DSMSG_WriteFile); if (error == DS_NoError) @@ -232,7 +233,7 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, if (error == DS_NoError) error = TRKAppendBuffer1_ui16(buffer, length); - if (!read && error == DS_NoError) + if (!doRead && error == DS_NoError) error = TRKAppendBuffer_ui8(buffer, data + done, length); if (error == DS_NoError) { @@ -240,8 +241,9 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, replyLength = 0; replyIOResult = 0; - error = (0, TRKRequestSend(buffer, &replyBufferId, read ? 5 : 5, 3, - !(read && file_handle == 0))); + error = (0, TRKRequestSend(buffer, &replyBufferId, + doRead ? 5 : 5, 3, + !(doRead && file_handle == 0))); if (error == DS_NoError) { replyBuffer = (TRKBuffer*)TRKGetBuffer(replyBufferId); TRKSetBufferPosition(replyBuffer, 2); @@ -253,7 +255,7 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, if (error == DS_NoError) error = TRKReadBuffer1_ui16(replyBuffer, &replyLength); - if (read && error == DS_NoError) { + if (doRead && error == DS_NoError) { if (replyBuffer->length != replyLength + 5) { replyLength = replyBuffer->length - 5; if (replyIOResult == 0) @@ -266,7 +268,8 @@ DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count, } if (replyLength != length) { - if ((!read || replyLength >= length) && replyIOResult == 0) + if ((!doRead || replyLength >= length) + && replyIOResult == 0) replyIOResult = 1; length = replyLength; exit = TRUE; From 2508fbd239aad08790c38d860f4278c6519a20a3 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 18:17:23 -0700 Subject: [PATCH 15/47] Improve TRK msgbuf matching --- configure.py | 2 +- .../embedded/MetroTRK/Portable/msgbuf.c | 137 ++++++++++++++---- 2 files changed, 111 insertions(+), 28 deletions(-) diff --git a/configure.py b/configure.py index e9764cfd8..4061d641d 100644 --- a/configure.py +++ b/configure.py @@ -934,7 +934,7 @@ def MatchingFor(*versions): Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubassrt.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubinit.c", extra_cflags=["-sdata 0", "-sdata2 0"]), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msg.c"), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msgbuf.c"), + Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msgbuf.c", extra_cflags=["-sdata 0", "-sdata2 0"]), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/serpoll.c"), Object(Matching, "debugger/embedded/MetroTRK/Portable/dispatch.c", extra_cflags=["-sdata 0", "-sdata2 0"]), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msghndlr.c", extra_cflags=["-sdata 0", "-sdata2 0"]), diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c index cce3a6339..d2650dc2c 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c @@ -42,12 +42,17 @@ DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg) *outMsg = NULL; for (i = 0; i < 3; i++) { - TRKBuffer* buf = TRKGetBuffer(i); + TRKBuffer* buf = NULL; + + if (i >= 0 && i < 3) { + buf = &gTRKMsgBufs[i]; + } TRKAcquireMutex(buf); if (!buf->isInUse) { - TRKResetBuffer(buf, 1); - TRKSetBufferUsed(buf, TRUE); + buf->length = 0; + buf->position = 0; + buf->isInUse = TRUE; error = DS_NoError; *outMsg = buf; *msgID = i; @@ -56,6 +61,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 +215,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)]; + u32 length; + DSError error; 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]; } - return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data)); + 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); + } + + buffer->position += length; + buffer->length = buffer->position; + return error; } /* @@ -230,22 +254,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)]; + u32 length; + DSError error; 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 +294,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)]; + u32 length; + DSError error; 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; } - return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data)); + 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; + return error; } /* @@ -322,9 +376,38 @@ DSError TRKAppendBuffer_ui32(TRKBuffer* buffer, const u32* data, int count) { DSError err; int i; + u8* bigEndianData; + u8 swapBuffer[sizeof(*data)]; + u32 length; for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) { - err = TRKAppendBuffer1_ui32(buffer, data[i]); + if (gTRKBigEndian) { + bigEndianData = (u8*)data; + } else { + bigEndianData = swapBuffer; + + bigEndianData[0] = ((u8*)data)[3]; + bigEndianData[1] = ((u8*)data)[2]; + bigEndianData[2] = ((u8*)data)[1]; + bigEndianData[3] = ((u8*)data)[0]; + } + + length = sizeof(*data); + err = DS_NoError; + if (0x880 - buffer->position < length) { + err = 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; + data++; } return err; From b30334c6a1efec4bc1e65c4dd7f4a190fb86fd49 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 18:28:36 -0700 Subject: [PATCH 16/47] Tighten TRK msgbuf matching --- .../debugger/embedded/MetroTRK/Portable/msgbuf.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c index d2650dc2c..e200c2f03 100644 --- a/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c +++ b/src/runtime_libs/debugger/embedded/MetroTRK/Portable/msgbuf.c @@ -37,12 +37,13 @@ DSError TRKInitializeMessageBuffers(void) */ DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg) { - DSError error = DS_NoMessageBufferAvailable; int i; + DSError error = DS_NoMessageBufferAvailable; + TRKBuffer* buf; *outMsg = NULL; for (i = 0; i < 3; i++) { - TRKBuffer* buf = NULL; + buf = NULL; if (i >= 0 && i < 3) { buf = &gTRKMsgBufs[i]; @@ -216,8 +217,8 @@ DSError TRKAppendBuffer1_ui16(TRKBuffer* buffer, const u16 data) { u8* bigEndianData; u8 swapBuffer[sizeof(data)]; - u32 length; DSError error; + u32 length; if (gTRKBigEndian) { bigEndianData = (u8*)&data; @@ -255,8 +256,8 @@ DSError TRKAppendBuffer1_ui32(TRKBuffer* buffer, const u32 data) { u8* bigEndianData; u8 swapBuffer[sizeof(data)]; - u32 length; DSError error; + u32 length; if (gTRKBigEndian) { bigEndianData = (u8*)&data; @@ -295,8 +296,8 @@ DSError TRKAppendBuffer1_ui64(TRKBuffer* buffer, const u64 data) { u8* bigEndianData; u8 swapBuffer[sizeof(data)]; - u32 length; DSError error; + u32 length; if (gTRKBigEndian) { bigEndianData = (u8*)&data; } else { From 3735d570d59a0e36582f8fe5067ef2faaf8617ca Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 18:35:55 -0700 Subject: [PATCH 17/47] Match TRK serial polling data layout --- configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.py b/configure.py index 4061d641d..eb332362f 100644 --- a/configure.py +++ b/configure.py @@ -935,7 +935,7 @@ def MatchingFor(*versions): Object(NonMatching, "debugger/embedded/MetroTRK/Portable/nubinit.c", extra_cflags=["-sdata 0", "-sdata2 0"]), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msg.c"), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/msgbuf.c", extra_cflags=["-sdata 0", "-sdata2 0"]), - Object(NonMatching, "debugger/embedded/MetroTRK/Portable/serpoll.c"), + Object(NonMatching, "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(NonMatching, "debugger/embedded/MetroTRK/Portable/msghndlr.c", extra_cflags=["-sdata 0", "-sdata2 0"]), Object(NonMatching, "debugger/embedded/MetroTRK/Portable/support.c"), From 2491459dfe03064193ec9b8bef3bf1a9a9f2afbb Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 20:31:08 -0700 Subject: [PATCH 18/47] Improve MSL rand match --- src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/rand.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) 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; } From a9770bafb6982684080eae655d890dc491c3b55f Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 20:45:16 -0700 Subject: [PATCH 19/47] Improve MSL direct_io fread match --- .../src/MSL_C/MSL_Common/direct_io.c | 244 +++++++++++++++--- 1 file changed, 207 insertions(+), 37 deletions(-) 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..9ba6672bd 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,15 +10,185 @@ #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) +#ifndef _IONBF +#define _IONBF 0 +#endif + +#ifndef _IOLBF +#define _IOLBF 1 +#endif + +#ifndef _IOFBF +#define _IOFBF 2 +#endif + +#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 fread(void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) { - // UNUSED FUNCTION + size_t retval; + + __begin_critical_region(stdin_access); + retval = __fread(pPtr, memb_size, num_memb, pFile); + __end_critical_region(stdin_access); + + return retval; } -void __fread(void) +size_t __fread(void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) { - // UNUSED FUNCTION + 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 fwrite(const void* pPtr, size_t memb_size, size_t num_memb, FILE* pFile) @@ -44,34 +214,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,63 +250,62 @@ 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; } From cb0be3f62e27d6b312af7adbb45a44c1d427e96b Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 20:55:11 -0700 Subject: [PATCH 20/47] Improve MSL file_io donor import --- .../MSL_C/MSL_Common/file_io.h | 2 + .../MSL_C/MSL_Common/misc_io.h | 3 + .../src/MSL_C/MSL_Common/file_io.c | 138 ++++++++++++++++++ .../src/MSL_C/MSL_Common/misc_io.c | 7 +- 4 files changed, 148 insertions(+), 2 deletions(-) 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/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/src/MSL_C/MSL_Common/file_io.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/file_io.c index c28e5ca4d..f4956b4c6 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,6 +1,55 @@ #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" + +#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) +{ + file_modes modes; + + __stdio_atexit(); + + if (!file) { + return NULL; + } + + fclose(file); + clearerr(file); + + if (!__get_file_modes(mode, &modes)) { + return NULL; + } + + __init_file(file, modes, 0, 0x400); + + 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) { @@ -74,6 +123,95 @@ int fflush(FILE* file) 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; + default: + return 0; + } + + modes->io_mode = io_mode; + return 1; +} + int __msl_strnicmp(const char* s1, const char* s2, int n) { int i; 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..cf1646bb8 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,10 +1,13 @@ +#include "PowerPC_EABI_Support/MSL_C/MSL_Common/misc_io.h" + extern void (*__stdio_exit)(void); extern void __close_all(void); -void clearerr(void) +void clearerr(FILE* stream) { - // UNUSED FUNCTION + stream->mState.eof = 0; + stream->mState.error = 0; } void feof(void) From e204593e6fca0e18e916bda1783be060147d633f Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 21:13:50 -0700 Subject: [PATCH 21/47] Improve MSL wchar_io donor match --- .../src/MSL_C/MSL_Common/wchar_io.c | 99 ++++--------------- 1 file changed, 21 insertions(+), 78 deletions(-) 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; + } } From dfe5bffc4cf10e51870e935e7d7609f124525c2f Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 21:30:06 -0700 Subject: [PATCH 22/47] Improve MSL arith abs match --- .../src/MSL_C/MSL_Common/arith.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) 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) From 0c8fa466a063eb0470e205fb8bd2837d2e149fd8 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 21:42:18 -0700 Subject: [PATCH 23/47] Improve MSL ctype donor trim --- .../src/MSL_C/MSL_Common/ctype.c | 135 +++++------------- 1 file changed, 37 insertions(+), 98 deletions(-) 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..2012be5c5 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) +__declspec(weak) int isprint(int c) { - // 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); + return __ctype_map[c & 0xff] & __printable; } int tolower(int c) { - return (c == -1 ? -1 : (int)__lower_map[(u8)c]); -} - -int toupper(int c) -{ - return (c == -1 ? -1 : (int)__upper_map[(u8)c]); -} + if (c == -1) { + return 0xffffffff; + } -void iswblank(void) -{ - // UNUSED FUNCTION + return (unsigned int)__lower_map[c & 0xff]; } From 247a7ba9df7f32d6b125b0875122a31cdda0ef8e Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 21:50:46 -0700 Subject: [PATCH 24/47] Improve MSL buffer_io donor import --- .../src/MSL_C/MSL_Common/buffer_io.c | 187 ++++++++++++++---- 1 file changed, 152 insertions(+), 35 deletions(-) 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..359b98dbe 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,168 @@ #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); + +inline void __convert_from_newlines(char* buffer, size_t* length) {} + +void __prep_buffer(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 __load_buffer(FILE* file, size_t* bytes_loaded, int mode) { - // UNUSED + int ioresult; + char* buffer_start; + + __prep_buffer(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; + + if (!file->mMode.binary_io) { + int i; + + buffer_start = file->mBuffer; + for (i = file->mBufferLength; i != 0; i--) { + char c = *buffer_start; + buffer_start++; + if (c == '\n') { + file->mPosition++; + } + } + } + + return __no_io_error; } -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, &file->mBufferLength); + } + + ioresult = file->writeFunc(file->mHandle, file->mBuffer, &file->mBufferLength, file->ref_con); + + if (bytes_flushed) { + *bytes_flushed = file->mBufferLength; + } + + if (ioresult) { + return ioresult; + } + + file->mPosition += file->mBufferLength; + } + + __prep_buffer(file); + + return __no_io_error; } -int __flush_buffer(FILE *file, size_t *length) +int setvbuf(FILE* file, char* buffer, int mode, size_t size) { - 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; + 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; } From e882d7093c64b4cf1ff8bd97fbae89a632e0f55a Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 21:54:11 -0700 Subject: [PATCH 25/47] Improve MSL ansi_files donor import --- .../src/MSL_C/MSL_Common/ansi_files.c | 98 ++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) 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; +} From 7eabf0f61f14749712f300faa9c37feb0ae8d3ff Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 22:08:48 -0700 Subject: [PATCH 26/47] Improve MSL string donor import --- .../src/MSL_C/MSL_Common/string.c | 549 ++++++++++-------- 1 file changed, 308 insertions(+), 241 deletions(-) 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..617c16424 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,373 @@ -#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)\0" + "\0"; + +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); + (void)n; - return (c ? 0 : (char*)p); -} + while (*++dstPtr) { + } -void strcoll(void) -{ - // UNUSED FUNCTION -} + --dstPtr; + while ((*++dstPtr = *++srcPtr) != 0) { + } -void strxfrm(void) -{ - // UNUSED FUNCTION + return dst; } -char* strrchr(const char* str, int chr) +char* strcat(char* dst, const char* src) { - const u8* p = (u8*)str - 1; - const u8* q = 0; - u32 c = (chr & 0xFF); - u32 ch; + const unsigned char* p = (const unsigned char*)src - 1; + unsigned char* q = (unsigned char*)dst - 1; - while (ch = *++p) - if (ch == c) - q = p; + while (*++q) + ; - if (q) - return ((char*)q); + q--; - return (c ? 0 : (char*)p); -} + while (*++q = *++p) + ; -void strpbrk(void) -{ - // UNUSED FUNCTION + return dst; } -void strspn(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 strcspn(void) -{ - // UNUSED FUNCTION + return dst; } -void strtok(void) +char* strcpy(char* dst, const char* src) { - // UNUSED FUNCTION -} + register unsigned char *destb, *fromb; + register unsigned long w, t, align; -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; + fromb = (unsigned char*)src; + destb = (unsigned char*)dst; - if ((pat == 0) || (!(firstc = *++p1))) { - return ((char*)str); + if ((align = ((int)fromb & 3)) != ((int)destb & 3)) { + goto bytecopy; } - while (c1 = *++s1) { - if (c1 == firstc) { - const unsigned char* s2 = s1 - 1; - const unsigned char* p2 = p1 - 1; - - 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)); + + t = w + K2; + + t &= K1; + if (t) { + goto bytecopy; + } + --((int*)(destb)); + + 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; } From c32ce13b9173efc1dfe0ecc00b93e82ecce9f109 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 22:21:46 -0700 Subject: [PATCH 27/47] Improve MSL extras strcmpi match --- .../src/MSL_C/MSL_Common/extras.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) 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..72415dc54 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 @@ -150,9 +150,24 @@ void _strncasecmp(void) // UNUSED FUNCTION } -void strcmpi(void) +int strcmpi(const char* str1, const char* str2) { - // UNUSED FUNCTION + char a_var; + char b_var; + + do { + b_var = _tolower(*str1++); + a_var = _tolower(*str2++); + + if (b_var < a_var) { + return -1; + } + if (b_var > a_var) { + return 1; + } + } while (b_var != 0); + + return 0; } void _strcmpi(void) From cc31688aa8e2cf1d89959235183f8470317162e9 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 22:40:09 -0700 Subject: [PATCH 28/47] Improve MSL strtoul atoi donor trim --- .../src/MSL_C/MSL_Common/strtoul.c | 61 ++----------------- 1 file changed, 6 insertions(+), 55 deletions(-) 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..93dc2ce07 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 @@ -281,73 +281,24 @@ unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, in 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) +int atoi(const char* str) { unsigned long uvalue; - long svalue; + int 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; - } + uvalue = __strtoul(10, 0x7FFFFFFF, &__StringRead, (void*)&isc, &count, &negative, &overflow); - if (overflow || (!negative && uvalue > LONG_MAX) || (negative && uvalue > -LONG_MIN)) { - svalue = (negative ? -LONG_MIN : LONG_MAX); + if (overflow || (!negative && uvalue > INT_MAX) || (negative && uvalue > -INT_MIN)) { + svalue = (negative ? -INT_MIN : INT_MAX); errno = ERANGE; } else { - svalue = (negative ? (long)-uvalue : (long)uvalue); + svalue = (negative ? (int)-uvalue : (int)uvalue); } return svalue; } - -void strtoll(void) -{ - // UNUSED FUNCTION -} - -int atoi(const char* str) -{ - // UNUSED FUNCTION -} - -void atol(void) -{ - // UNUSED FUNCTION -} From 036eba3e98875063be959b72f9efb3dbb67c23fb Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 22:56:09 -0700 Subject: [PATCH 29/47] Improve MSL char_io donor import --- .../src/MSL_C/MSL_Common/char_io.c | 329 ++++++++++++------ 1 file changed, 219 insertions(+), 110 deletions(-) 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; +} From d9b2ca61f2fd7aa21d198de61c9812951e148fc4 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 23:11:47 -0700 Subject: [PATCH 30/47] Improve MSL mem donor compiler match --- configure.py | 12 +- .../src/MSL_C/MSL_Common/mem.c | 138 +++++++----------- 2 files changed, 65 insertions(+), 85 deletions(-) diff --git a/configure.py b/configure.py index eb332362f..93b1f007c 100644 --- a/configure.py +++ b/configure.py @@ -249,6 +249,16 @@ "-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", +] + # dolphin library flags cflags_dolphin = [ *cflags_base, @@ -873,7 +883,7 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/FILE_POS.C"), Object(Matching, "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.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), 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"), 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..661f5e36d 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) +int memcmp(const void* lhs, const void* rhs, size_t count) { - const char *csrc; - char *cdst; + const unsigned char* p1; + const unsigned char* p2; - int reverse = (u32)src < (u32)dst; + for (p1 = (const unsigned char*)lhs - 1, p2 = (const unsigned char*)rhs - 1, count++; --count;) + if (*++p1 != *++p2) + return ((*p1 < *p2) ? -1 : +1); - 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, len++; --len;) - { - *++cdst = *++csrc; - } - } - else - { - for (csrc = (const char *)src + len, cdst = (char *)dst + len, len++; --len;) - { - *--cdst = *--csrc; - } - } - } - - return dst; + return 0; } -void *memchr(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 - 1, n++; --n;) - { - if ((*++p & 0xFF) == v) - { - return (void *)p; - } - } + for (p = (unsigned char*)ptr + count, count++; --count;) + if (*--p == v) + return (void*)p; - return NULL; + return NULL; } -void *__memrchr(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 + n, n++; --n;) - { - if (*--p == v) - { - return (void *)p; - } - } + for (p = (unsigned char*)ptr - 1, count++; --count;) + if ((*++p & 0xFF) == v) + return (void*)p; - return NULL; + return NULL; } -int memcmp(const void *src1, const void *src2, size_t n) +void* memmove(void* dst, const void* src, size_t n) { - const u8 *p1; - const u8 *p2; + const char* csrc; + char* cdst; + int reverse = (unsigned int)src < (unsigned int)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); + } + } - for (p1 = (const u8 *)src1 - 1, p2 = (const u8 *)src2 - 1, n++; --n;) - { - if (*++p1 != *++p2) - { - return (*p1 < *p2) ? -1 : 1; - } - } + 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 0; + return dst; } From 03996676917edcfe3c035ce03691ccef973d4fa4 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 23:20:43 -0700 Subject: [PATCH 31/47] Improve MSL signal donor compiler match --- configure.py | 2 +- .../src/MSL_C/MSL_Common/signal.c | 26 +++++++++---------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/configure.py b/configure.py index 93b1f007c..0cdfc2118 100644 --- a/configure.py +++ b/configure.py @@ -890,7 +890,7 @@ def MatchingFor(*versions): 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/signal.c", cflags=cflags_msl_gc13_runtime), Object(NonMatching, "MSL_C/MSL_Common/string.c"), Object(NonMatching, "MSL_C/MSL_Common/strtold.c"), Object(NonMatching, "MSL_C/MSL_Common/strtoul.c"), 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 f82820379..c1a1c6e29 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 @@ -3,36 +3,34 @@ #include "PowerPC_EABI_Support/MSL_C/MSL_Common/critical_regions.h" #include "PowerPC_EABI_Support/MSL_C/MSL_Common/abort_exit.h" -__signal_func_ptr signal_funcs[6]; +#define SIGNAL_NUM 6 + +__signal_func_ptr signal_funcs[SIGNAL_NUM]; int raise(int sig) { __signal_func_ptr signal_func; - __signal_func_ptr* signal_ptr; - if (sig < 1 || sig > 6) - { + if (sig < 1 || sig > SIGNAL_NUM) { return -1; } - __begin_critical_region(4); - signal_ptr = &signal_funcs[sig]; - signal_func = *--signal_ptr; + __begin_critical_region(stderr_access); + signal_func = signal_funcs[sig - 1]; - if ((unsigned long)signal_func != 1) - { - *signal_ptr = NULL; + if (signal_func != ((__std(__signal_func_ptr))1)) { + signal_funcs[sig - 1] = ((__std(__signal_func_ptr))0); } - __end_critical_region(4); + __end_critical_region(stderr_access); - if ((unsigned long)signal_func == 1 || (signal_func == NULL && sig == 1)) + if (signal_func == ((__std(__signal_func_ptr))1) || + (signal_func == ((__std(__signal_func_ptr))0) && sig == 1)) { return 0; } - if (signal_func == NULL) - { + if (signal_func == ((__std(__signal_func_ptr))0)) { exit(0); } From e7e3f3ff846847d227b2d9c33dfcb333321ebe7f Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 23:26:55 -0700 Subject: [PATCH 32/47] Improve MSL mbstring donor compiler match --- configure.py | 2 +- .../src/MSL_C/MSL_Common/mbstring.c | 391 +++++++----------- 2 files changed, 153 insertions(+), 240 deletions(-) diff --git a/configure.py b/configure.py index 0cdfc2118..33b16b364 100644 --- a/configure.py +++ b/configure.py @@ -882,7 +882,7 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/file_io.c"), Object(NonMatching, "MSL_C/MSL_Common/FILE_POS.C"), Object(Matching, "MSL_C/MSL_Common/locale.c"), - Object(NonMatching, "MSL_C/MSL_Common/mbstring.c"), + Object(NonMatching, "MSL_C/MSL_Common/mbstring.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), Object(NonMatching, "MSL_C/MSL_Common/mem.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), Object(NonMatching, "MSL_C/MSL_Common/mem_funcs.c"), Object(NonMatching, "MSL_C/MSL_Common/misc_io.c"), 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; } From a52b3e94c0e8d25614c2b56dd1db85e35ccdeb34 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 23:33:17 -0700 Subject: [PATCH 33/47] Improve MSL FILE_POS compiler match --- configure.py | 7 ++++++- src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/FILE_POS.C | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/configure.py b/configure.py index 33b16b364..269e630ac 100644 --- a/configure.py +++ b/configure.py @@ -259,6 +259,11 @@ "-lang=c", ] +cflags_msl_runtime_cpp = [ + *cflags_runtime, + "-lang=c++", +] + # dolphin library flags cflags_dolphin = [ *cflags_base, @@ -880,7 +885,7 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/direct_io.c"), 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/FILE_POS.C", cflags=cflags_msl_runtime_cpp), Object(Matching, "MSL_C/MSL_Common/locale.c"), Object(NonMatching, "MSL_C/MSL_Common/mbstring.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), Object(NonMatching, "MSL_C/MSL_Common/mem.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), 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..03bce0cf5 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; From eb6c9f602987e2502284a7275ca17441fc72d3da Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 23:49:41 -0700 Subject: [PATCH 34/47] Improve MSL misc_io target surface --- .../MSL_C/MSL_Common/FILE_POS.h | 2 +- .../src/MSL_C/MSL_Common/misc_io.c | 22 +++++-------------- 2 files changed, 7 insertions(+), 17 deletions(-) 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/src/MSL_C/MSL_Common/misc_io.c b/src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/misc_io.c index cf1646bb8..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 @@ -4,25 +4,15 @@ extern void (*__stdio_exit)(void); extern void __close_all(void); -void clearerr(FILE* stream) -{ - stream->mState.eof = 0; - stream->mState.error = 0; -} - -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; } From faa03f6e0716447f945bfab539d08203323d3a28 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Sun, 19 Apr 2026 23:59:15 -0700 Subject: [PATCH 35/47] Improve MSL rand misc_io compiler match --- configure.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.py b/configure.py index 269e630ac..c333e6103 100644 --- a/configure.py +++ b/configure.py @@ -890,10 +890,10 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/mbstring.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), Object(NonMatching, "MSL_C/MSL_Common/mem.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), Object(NonMatching, "MSL_C/MSL_Common/mem_funcs.c"), - Object(NonMatching, "MSL_C/MSL_Common/misc_io.c"), + Object(NonMatching, "MSL_C/MSL_Common/misc_io.c", cflags=cflags_runtime), 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/rand.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/scanf.c"), Object(NonMatching, "MSL_C/MSL_Common/signal.c", cflags=cflags_msl_gc13_runtime), Object(NonMatching, "MSL_C/MSL_Common/string.c"), From 7567aff495baff50f6ba8f1a2483e576f8f8a56c Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 00:03:25 -0700 Subject: [PATCH 36/47] Improve MSL wchar_io compiler match --- configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.py b/configure.py index c333e6103..61824f8ac 100644 --- a/configure.py +++ b/configure.py @@ -901,7 +901,7 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/strtoul.c"), Object(Matching, "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/wchar_io.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c") ] ), From 3d64548a50c2e352e14cd09f1861562474ba058f Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 00:08:20 -0700 Subject: [PATCH 37/47] Improve MSL runtime profile matches --- configure.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.py b/configure.py index 61824f8ac..a6f203a81 100644 --- a/configure.py +++ b/configure.py @@ -877,12 +877,12 @@ def MatchingFor(*versions): 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/arith.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/bsearch.c"), Object(NonMatching, "MSL_C/MSL_Common/buffer_io.c"), 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(NonMatching, "MSL_C/MSL_Common/ctype.c", cflags=cflags_runtime), + Object(NonMatching, "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", cflags=cflags_msl_runtime_cpp), @@ -900,7 +900,7 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/strtold.c"), Object(NonMatching, "MSL_C/MSL_Common/strtoul.c"), Object(Matching, "MSL_C/MSL_Common/float.c"), - Object(NonMatching, "MSL_C/MSL_Common/char_io.c"), + Object(NonMatching, "MSL_C/MSL_Common/char_io.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/wchar_io.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common_Embedded/uart_console_io_gcn.c") ] From 01851926a653e169c6ed5cd31b719d8c440c9819 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 00:22:21 -0700 Subject: [PATCH 38/47] Improve MSL donor runtime profile matches --- configure.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/configure.py b/configure.py index a6f203a81..c87014007 100644 --- a/configure.py +++ b/configure.py @@ -875,16 +875,16 @@ def MatchingFor(*versions): [ 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/ansi_files.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), Object(NonMatching, "MSL_C/MSL_Common_Embedded/ansi_fp.c"), Object(NonMatching, "MSL_C/MSL_Common/arith.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/bsearch.c"), - Object(NonMatching, "MSL_C/MSL_Common/buffer_io.c"), + Object(NonMatching, "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", cflags=cflags_runtime), Object(NonMatching, "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_io.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/FILE_POS.C", cflags=cflags_msl_runtime_cpp), Object(Matching, "MSL_C/MSL_Common/locale.c"), Object(NonMatching, "MSL_C/MSL_Common/mbstring.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), @@ -896,9 +896,9 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/rand.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/scanf.c"), Object(NonMatching, "MSL_C/MSL_Common/signal.c", cflags=cflags_msl_gc13_runtime), - Object(NonMatching, "MSL_C/MSL_Common/string.c"), + Object(NonMatching, "MSL_C/MSL_Common/string.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/strtold.c"), - Object(NonMatching, "MSL_C/MSL_Common/strtoul.c"), + Object(NonMatching, "MSL_C/MSL_Common/strtoul.c", cflags=cflags_runtime), Object(Matching, "MSL_C/MSL_Common/float.c"), Object(NonMatching, "MSL_C/MSL_Common/char_io.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/wchar_io.c", cflags=cflags_runtime), From e6035074ef069adb04348f061e67d8fb5df2a66a Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 00:31:58 -0700 Subject: [PATCH 39/47] Improve MSL string strncat match --- src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/string.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) 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 617c16424..1f929b070 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 @@ -250,15 +250,19 @@ char* strncat(char* dst, const char* src, size_t n) const unsigned char* srcPtr = (const unsigned char*)src - 1; unsigned char* dstPtr = (unsigned char*)dst - 1; - (void)n; - while (*++dstPtr) { } --dstPtr; - while ((*++dstPtr = *++srcPtr) != 0) { + n++; + while (--n) { + if (!(*++dstPtr = *++srcPtr)) { + --dstPtr; + break; + } } + *++dstPtr = 0; return dst; } From 4e21e4d0f83f981f6e96002c91773046f72e9350 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 00:42:52 -0700 Subject: [PATCH 40/47] Improve MSL buffer_io load match --- .../src/MSL_C/MSL_Common/buffer_io.c | 14 -------------- 1 file changed, 14 deletions(-) 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 359b98dbe..ed3781dd9 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 @@ -37,7 +37,6 @@ void __prep_buffer(FILE* file) int __load_buffer(FILE* file, size_t* bytes_loaded, int mode) { int ioresult; - char* buffer_start; __prep_buffer(file); @@ -61,19 +60,6 @@ int __load_buffer(FILE* file, size_t* bytes_loaded, int mode) file->mPosition += file->mBufferLength; - if (!file->mMode.binary_io) { - int i; - - buffer_start = file->mBuffer; - for (i = file->mBufferLength; i != 0; i--) { - char c = *buffer_start; - buffer_start++; - if (c == '\n') { - file->mPosition++; - } - } - } - return __no_io_error; } From 9077462f5f2bf570b94380544ff19a7641c33540 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 00:51:14 -0700 Subject: [PATCH 41/47] Improve MSL strtoul ctype table match --- .../src/MSL_C/MSL_Common/strtoul.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) 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 93dc2ce07..ed8944603 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 @@ -44,7 +44,7 @@ unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int 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++; @@ -98,7 +98,7 @@ unsigned long __strtoul(int base, int max_width, int (*ReadProc)(void*, int, int value_max = ULONG_MAX / base; } - if (isdigit(c)) { + if (_isdigit(c)) { if ((c -= '0') >= base) { if (scan_state == digit_loop) { scan_state = finished; @@ -109,7 +109,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 +118,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) { @@ -175,7 +175,7 @@ unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, in 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++; @@ -229,7 +229,7 @@ unsigned long long __strtoull(int base, int max_width, int (*ReadProc)(void*, in value_max = ullmax / base; } - if (isdigit(c)) { + if (_isdigit(c)) { if ((c -= '0') >= base) { if (scan_state == digit_loop) { scan_state = finished; @@ -240,7 +240,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 +249,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) { @@ -285,7 +285,7 @@ int atoi(const char* str) { unsigned long uvalue; int svalue; - int count, negative, overflow; + int overflow, negative, count; __InStrCtrl isc; isc.NextChar = (char*)str; From d1830f6a09aa3ae6ceb0d825647edb7813f4eb54 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 01:02:51 -0700 Subject: [PATCH 42/47] Improve MSL file_io close path match --- .../src/MSL_C/MSL_Common/file_io.c | 196 +++++++++++++----- 1 file changed, 144 insertions(+), 52 deletions(-) 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 f4956b4c6..11d3e602d 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 @@ -20,6 +20,7 @@ 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) { file_modes modes; + u32 pos; __stdio_atexit(); @@ -27,14 +28,56 @@ inline static FILE* freopen(const char* name, const char* mode, FILE* file) return NULL; } - fclose(file); + if (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->mState.io_state == 2) { + file->mBufferLength = 0; + } + + 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; + } + + 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->closeFunc)(file->mHandle); + file->mMode.file_kind = __closed_file; + file->mHandle = 0; + + if (file->mState.free_buffer) { + free(file->mBuffer); + } + } clearerr(file); if (!__get_file_modes(mode, &modes)) { return NULL; } - __init_file(file, modes, 0, 0x400); + __init_file(file, modes, 0, 0x1000); if (__open_file(name, modes, &file->mHandle)) { file->mMode.file_kind = __closed_file; @@ -53,74 +96,123 @@ inline static FILE* freopen(const char* name, const char* mode, FILE* file) int fclose(FILE* file) { - int flush_result, close_result; + int flush_result, close_result; + u32 pos; - if (file == NULL) - return (-1); - if (file->mMode.file_kind == __closed_file) - return (0); + if (file == NULL) + return (-1); + if (file->mMode.file_kind == __closed_file) + return (0); - flush_result = fflush(file); + if (file == NULL) + { + flush_result = __flush_all(); + } + else if (file->mState.error != 0 || file->mMode.file_kind == __closed_file) + { + flush_result = -1; + } + else if (file->mMode.io_mode == 1) + { + flush_result = 0; + } + else + { + if (file->mState.io_state >= 3) + { + file->mState.io_state = 2; + } - close_result = (*file->closeFunc)(file->mHandle); + if (file->mState.io_state == 2) + { + file->mBufferLength = 0; + } - file->mMode.file_kind = __closed_file; - file->mHandle = 0; + if (file->mState.io_state != 1) + { + file->mState.io_state = 0; + flush_result = 0; + } + else + { + 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; + flush_result = -1; + } + else + { + file->mState.io_state = 0; + file->mPosition = pos; + file->mBufferLength = 0; + flush_result = 0; + } + } + } - if (file->mState.free_buffer) - free(file->mBuffer); - return ((flush_result || close_result) ? -1 : 0); + 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) From a5a7b5d49850f18a2149a8450b0e20a8eafad291 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 01:12:55 -0700 Subject: [PATCH 43/47] Improve MSL file_io fopen config match --- configure.py | 2 +- .../src/MSL_C/MSL_Common/file_io.c | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/configure.py b/configure.py index c87014007..dd2006c37 100644 --- a/configure.py +++ b/configure.py @@ -884,7 +884,7 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/ctype.c", cflags=cflags_runtime), Object(NonMatching, "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", cflags=cflags_runtime), + Object(NonMatching, "MSL_C/MSL_Common/file_io.c", cflags=cflags_runtime + ["-D_MSL_WIDE_CHAR"]), Object(NonMatching, "MSL_C/MSL_Common/FILE_POS.C", cflags=cflags_msl_runtime_cpp), Object(Matching, "MSL_C/MSL_Common/locale.c"), Object(NonMatching, "MSL_C/MSL_Common/mbstring.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), 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 11d3e602d..ca461a598 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 @@ -28,7 +28,7 @@ inline static FILE* freopen(const char* name, const char* mode, FILE* file) return NULL; } - if (file->mMode.file_kind != __closed_file) { + if (file && file->mMode.file_kind != __closed_file) { if (file == NULL) { __flush_all(); } @@ -130,8 +130,7 @@ int fclose(FILE* file) if (file->mState.io_state != 1) { - file->mState.io_state = 0; - flush_result = 0; + file->mState.io_state = flush_result = 0; } else { @@ -146,10 +145,9 @@ int fclose(FILE* file) } else { - file->mState.io_state = 0; + file->mState.io_state = flush_result = 0; file->mPosition = pos; - file->mBufferLength = 0; - flush_result = 0; + file->mBufferLength = flush_result; } } } @@ -232,7 +230,7 @@ int __get_file_modes(const char* mode, file_modes* modes) signed char mode_char; int mode_str; unsigned char open_mode; - int io_mode; + signed char io_mode; modes->file_kind = __disk_file; mode_char = mode[0]; @@ -300,7 +298,7 @@ int __get_file_modes(const char* mode, file_modes* modes) return 0; } - modes->io_mode = io_mode; + modes->io_mode = (unsigned char)io_mode; return 1; } From ac5fa3bd0bc6769fcf4e5f0c1b9ee17c2939b253 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 01:23:34 -0700 Subject: [PATCH 44/47] Improve MSL file_io mode parsing match --- .../src/MSL_C/MSL_Common/file_io.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 ca461a598..45d285f1c 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 @@ -130,7 +130,8 @@ int fclose(FILE* file) if (file->mState.io_state != 1) { - file->mState.io_state = flush_result = 0; + flush_result = 0; + file->mState.io_state = flush_result; } else { @@ -145,7 +146,8 @@ int fclose(FILE* file) } else { - file->mState.io_state = flush_result = 0; + flush_result = 0; + file->mState.io_state = flush_result; file->mPosition = pos; file->mBufferLength = flush_result; } @@ -230,7 +232,7 @@ int __get_file_modes(const char* mode, file_modes* modes) signed char mode_char; int mode_str; unsigned char open_mode; - signed char io_mode; + int io_mode; modes->file_kind = __disk_file; mode_char = mode[0]; @@ -294,11 +296,9 @@ int __get_file_modes(const char* mode, file_modes* modes) case 'a+': io_mode = __read_write | __append; break; - default: - return 0; } - modes->io_mode = (unsigned char)io_mode; + modes->io_mode = io_mode; return 1; } From 6b54b653029ffad3c979f7938c344dd85439c9a7 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 08:52:42 -0700 Subject: [PATCH 45/47] Improve MSL mem_funcs compiler match --- configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.py b/configure.py index dd2006c37..bc00154b1 100644 --- a/configure.py +++ b/configure.py @@ -889,7 +889,7 @@ def MatchingFor(*versions): Object(Matching, "MSL_C/MSL_Common/locale.c"), Object(NonMatching, "MSL_C/MSL_Common/mbstring.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), Object(NonMatching, "MSL_C/MSL_Common/mem.c", mw_version="GC/1.3", cflags=cflags_msl_gc13_runtime), - Object(NonMatching, "MSL_C/MSL_Common/mem_funcs.c"), + Object(NonMatching, "MSL_C/MSL_Common/mem_funcs.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/misc_io.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/printf.c"), Object(NonMatching, "MSL_C/MSL_Common/qsort.c"), From dba34bf76667c18a6f37a216377da748fbdf61dc Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 09:02:29 -0700 Subject: [PATCH 46/47] Add MSL qsort donor import --- .../src/MSL_C/MSL_Common/qsort.c | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/PowerPC_EABI_Support/src/MSL_C/MSL_Common/qsort.c 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; + } + } + } +} From 887613c06f78cb7b83ebf35a40664c5911b54209 Mon Sep 17 00:00:00 2001 From: Zachary Canann Date: Mon, 20 Apr 2026 09:20:53 -0700 Subject: [PATCH 47/47] Improve MSL scanf donor compiler match --- configure.py | 2 +- .../src/MSL_C/MSL_Common/scanf.c | 43 +++++-------------- 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/configure.py b/configure.py index bc00154b1..b82928627 100644 --- a/configure.py +++ b/configure.py @@ -894,7 +894,7 @@ def MatchingFor(*versions): Object(NonMatching, "MSL_C/MSL_Common/printf.c"), Object(NonMatching, "MSL_C/MSL_Common/qsort.c"), Object(NonMatching, "MSL_C/MSL_Common/rand.c", cflags=cflags_runtime), - Object(NonMatching, "MSL_C/MSL_Common/scanf.c"), + Object(NonMatching, "MSL_C/MSL_Common/scanf.c", cflags=cflags_runtime + ["-inline deferred"]), Object(NonMatching, "MSL_C/MSL_Common/signal.c", cflags=cflags_msl_gc13_runtime), Object(NonMatching, "MSL_C/MSL_Common/string.c", cflags=cflags_runtime), Object(NonMatching, "MSL_C/MSL_Common/strtold.c"), 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; }