mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
b9716154f0
The recompiler and runtime now build and run natively on macOS (Apple
Silicon & Intel) and Linux, alongside Windows. The recompiled BIOS boots to
the PlayStation logo, and Tomba boots into gameplay with working memory-card
save/load — the previously Windows-only path.
Core change — the BIOS thread scheduler:
- runtime/src/psx_fiber.{h,c} (new): one cooperative-fiber API, backed by
Win32 Fibers on Windows and ucontext (makecontext/swapcontext) on POSIX,
with a GetCurrentFiber analog (psx_fiber_current).
- traps.c: the BIOS thread switcher now uses psx_fiber_* on every platform.
The old non-Windows setjmp/longjmp fallback is removed — it ran target
threads nested on the caller's C stack and so couldn't resume an arbitrary
suspended thread, which hung the BIOS CD-boot WaitEvent handoff. Real
per-thread stacks (fibers/ucontext) fix it.
- interrupts.c: the exception-deferral path (g_exception_owner_fiber,
deferred_exception_longjmp) is now fiber-based on all platforms via the
same abstraction, instead of #ifdef _WIN32.
Cross-platform build fixes:
- recompiler/CMakeLists.txt: vendored fmt 9.1.0 force-enables consteval on
Apple clang (the __cpp_consteval clause overrides its own Apple exclusion),
which clang 21 then rejects; force FMT_CONSTEVAL empty on non-MSVC.
- runtime.cmake: add psx_fiber.c; add pkg-config's SDL2_LIBRARY_DIRS so
-lSDL2 resolves outside default paths (Homebrew /opt/homebrew/lib).
- crash_trace.c: include <stdarg.h> (not pulled in transitively off Windows).
- main.cpp: the forced "opengl" render-driver hint (a Windows-GDI-freeze
workaround) is now Windows-only so macOS uses Metal; create the renderer
with PRESENTVSYNC; SDL_RenderSetLogicalSize(640,480) so fullscreen
letterboxes; add an F11 / Alt+Enter / Cmd+F fullscreen toggle.
Verified: SCPH1001 BIOS boots to the Sony logo on Apple Silicon, and Tomba!
(SCUS-94236) boots into gameplay with memory-card saves persisting across
relaunches. Gamepad (SDL_GameController) was already cross-platform.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
56 lines
2.0 KiB
C
56 lines
2.0 KiB
C
/*
|
|
* psx_fiber.h — cross-platform cooperative fibers for the BIOS thread
|
|
* scheduler (traps.c) and exception-deferral (interrupts.c).
|
|
*
|
|
* The PS1 BIOS manages its own threads (TCBs) and switches between them
|
|
* cooperatively; the runtime mirrors each BIOS thread with a host fiber so
|
|
* the recompiled C for a suspended thread keeps its own native call stack
|
|
* across a ChangeThread. The CD-boot handoff in particular depends on this:
|
|
* a thread issues a CD command, WaitEvent-blocks, and the scheduler must be
|
|
* able to resume a *different* thread's previously-suspended stack — which
|
|
* requires real separate stacks, not nested dispatch.
|
|
*
|
|
* Backends:
|
|
* - Windows: the Win32 Fiber API (ConvertThreadToFiber / CreateFiber /
|
|
* SwitchToFiber / DeleteFiber). Behavior is identical to the original.
|
|
* - POSIX (macOS/Linux): ucontext (makecontext / swapcontext).
|
|
*
|
|
* Cooperative, single-threaded: exactly one fiber runs at a time and all
|
|
* switches are explicit. psx_fiber_current() is the GetCurrentFiber analog.
|
|
*/
|
|
#ifndef PSX_FIBER_H
|
|
#define PSX_FIBER_H
|
|
|
|
#include <stddef.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef void* psx_fiber_t;
|
|
typedef void (*psx_fiber_entry)(void* arg);
|
|
|
|
/* Make the current thread a fiber so it can switch to others. Idempotent;
|
|
* returns the handle for the current thread's fiber. Call before the first
|
|
* psx_fiber_switch on this thread. */
|
|
psx_fiber_t psx_fiber_convert_thread(void);
|
|
|
|
/* The currently-executing fiber (GetCurrentFiber analog). */
|
|
psx_fiber_t psx_fiber_current(void);
|
|
|
|
/* Create a fiber with its own stack. It does not run until switched to. */
|
|
psx_fiber_t psx_fiber_create(size_t stack_size, psx_fiber_entry entry, void* arg);
|
|
|
|
/* Switch execution to target; the caller is suspended until switched back. */
|
|
void psx_fiber_switch(psx_fiber_t target);
|
|
|
|
/* Destroy a fiber created by psx_fiber_create and free its stack. Must not
|
|
* be the currently-running fiber. */
|
|
void psx_fiber_destroy(psx_fiber_t fiber);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* PSX_FIBER_H */
|