v0.9.0 — Second Platform
The first tagged release. Earlier versions in the changelog predate tagging and have no artifacts — v0.9.0 is where that starts.
This is a release about verification: the project got its first CI, its second platform, and — because CI ran the existing test suites somewhere new — fifteen silent miscompiles that had been sitting in the tree unnoticed.
macOS, and the first CI this repository has ever had
Thanks to @slushiimusic, who filed #94 pointing out that docs/BUILDING.md advertised Apple Clang under "full support" while the tree did not compile on arm64 at all — with the errors and a fix — and then contributed both PRs.
- #95 — arm64 macOS build + the first CI workflow. It failed 17 seconds after landing, on a
getenvwithout<stdlib.h>that MSVC had been quietly accepting. - #96 — an RSX Metal backend (clear, flip, guest vertex fetch, pipeline-state cache, blend translation) plus
runtime/host/host_posix.c, which drives cellGcm → RSX → backend with no lifted game by hand-building a big-endian NV4097 command buffer.
CI asserts the presented pixel, not the exit code:
[ppu-conformance] 1311 checks passed, 0 FAILED, 0 skipped
[host] clear colour through the FIFO: 0xFF101830 (expected 0xFF101830) OK
[host] presented pixel: 0xFF101830 (expected 0xFF101830) OK # clear
[host] presented pixel: 0xFFFF0000 (expected 0xFFFF0000) OK # NV4097 draw
Fifteen VMX miscompiles
The conformance suite only ever compiled its generated driver on Windows. Everywhere else it printed COMPILE FAILED and executed nothing — and a missing compiler exited 0, so a skip read as a pass.
Once it actually ran: the vupk* family (12 cases) read and wrote the big-endian vector register file through host int16_t*/int32_t* pointers, byte-reversing every result element. vcmpgtsw/vcmpgtsh compared byte-reversed values, so a mixed-sign vector produced an all-zero mask instead of the correct FF one. vadduwm propagated carries the wrong way and spilled into neighbouring elements. The byte-width members of each family passed by luck — a byte has no endianness. vadduhm, vsubuhm and vsubuwm had the same latent bug with no test covering them.
It now compiles and runs on all three platforms, and a skip fails under CI, because a green tick meaning "compiled nothing" is worse than a red one.
Runtime fixes from driving two titles
- The GCM label/control block lived at a hardcoded
0x03000000— inside main memory, where a title's own allocator hands out blocks. flOw's heap swallowed it: the game memset over the control register, and the FIFO drain read ASCII asput. - Malformed MFC transfers were reported and then performed anyway. Hardware raises an alignment exception and moves nothing.
- The host-RVA → guest-function mapper invented frames, attributing any runtime address to whichever lifted function sat below it. Now bounded; it prints the raw RVA rather than guessing.
- Two-level jump tables were rejected outright, including the common case where the table base is loaded in the prologue.
Platform support
| Windows | macOS (arm64) | Linux | |
|---|---|---|---|
| Runtime library builds | yes | yes | untested |
| Lifter + 8 test suites | yes | yes | untested |
| Render backend | D3D12 | Metal | none |
| Runs a recompiled game | yes | no | no |
macOS builds, renders and passes the full suite but cannot run a title yet — the PPU boot scaffold (ppu_loader.cpp, boot_main.cpp, HLE dispatch) is Win32-only. Linux has no CI and no backend; it is listed as untested rather than supported. Porting that scaffold is the next step.
Full credits in CONTRIBUTORS.md.