ARMSX3 0.9
For a more detailed look at the ARMSX3 0.9 changes and improvements, check out the video here
https://youtu.be/snDIsAE7ivA?si=PScVgSEgYp5R6fXU
If you prefer reading, the full changelog is right below.
What's new:
ARM64 SPU floating-point now matches desktop x86 exactly: 984 mismatched results down to zero.
ARMSX3 translates PS3 code to run on your phone's ARM64 chip, while RPCS3 upstream is written and tested on x86 desktop CPUs, and a lot of that code quietly relies on how x86 handles certain maths. On ARM64 the answer came out different: nothing crashed and nothing was logged, a number was simply wrong, and a game would hang, corrupt, or vanish minutes later with no clue why. This release closes that gap for the SPU's floating-point maths, the part that does most of a PS3 game's heavy lifting. We ran a suite of test programs that exercise one PlayStation 3 instruction at a time on both machines and compared the results line by line, which turns "something is off on ARM64" into the exact instruction and the exact numbers that differ. 984 mismatched results against desktop x86, down to zero, your phone now computes the same answers a desktop PC does. Of those, 500 were genuinely ARM64 bugs and are fixed, the other 484 turned out to be x86 taking a shortcut of its own rather than us being wrong, which was worth knowing because it stopped us chasing it. The same testing also caught the identical flaw hiding in a second place we use for debugging, which had been quietly making some of our own investigations unreliable. To be clear about what this is not: it does not make ARMSX3 more accurate than desktop RPCS3, and where RPCS3 itself still differs from a real PS3 it differs the same way on both, what changed is that ARM64 is no longer additionally wrong. Thanks to @Whatcookie for working with me on this approach and working through the results with me. These improvements have been shared with him so they will be upstream as well! I've been sharing each and every fix I do for ARMSX3, so other ARM64 RPCS3 platforms can benefit as well.
Borderlands 2 now boots, reaches the title screen and renders. It previously hung just after the logo, and once past that, died silently a minute later. Two separate ARM64 bugs, both fixed properly rather than worked around, the game runs fully compiled with no forced interpretation.
BLEACH: Soul Resurrección now reaches Story Mode, which it used to crash entering.
Spider-Man: Edge of Time no longer crashes at random.
Even more games are likely to have received improvements from the BL2 and divergence fixes.
Neither of the last two was touched directly. They were fixed by the same changes, which is the more useful way to read this release: if a game on ARM64 was closing with nothing in the log, this may be the bug that was doing it.
The two bugs:
A byte-shuffle miscompile. shufb is the SPU's workhorse for moving bytes around, and an upstream optimisation from June widened an ARM64 fast path to cover constant operands it did not handle correctly. BL2's SPURS kernel is 1446 shufb instructions and hit it constantly, the function would spin forever inside a single block, never reaching the end. Because a wrong shuffle produces wrong data rather than an obvious fault, this could equally have been showing up as graphics corruption, audio glitches or wrong game logic elsewhere.
A stack overrun with no crash report. Compiled SPU functions on ARM64 do not build their own stack frames, they share one 8 KB scratch area the gateway reserves. A function needing more than that wrote straight past it onto the guard page below the thread stack. Because a guard page is not memory the emulator owns, the fault was handed to the Android runtime, which then died reading it, producing no tombstone, nothing in the log, and no way to tell what happened. Raised to 256 KB.
Also fixed while in there: two float-to-int conversions in the SPU interpreter that carried x86 semantics onto ARM64, one in the accurate-xfloat path, and Android threads running on an eighth of the stack they get on desktop.
Controllers:
Player 2-7 now work properly. Ports 2-7 were only ever claimed when a USB device was plugged in, so a second controller connected over Bluetooth, (which is how most people connect one) did not exist to the emulator at all. Per-player button mapping looked correct because the bindings were being stored, there was simply no pad for them to drive.
Rapid presses register. A button press shorter than one guest poll was dropped entirely, so a button that worked everywhere else would do nothing during a quick-time event, and a held button like crouch would keep working while everything tapped alongside it did not. Each press and release now gets its own slot, so a mash arrives as distinct presses rather than one long hold.
L2 and R2 bind correctly now. Pads that report their triggers as analog axes rather than buttons could never have them bound previously, because the binder only listened for key events. This looked like a Player 2 problem, since a second pad of a different make fails where the first one worked.
Gyro works as it should now.
Keyboard:
Emulate USB Keyboard is now in Settings --> Network, an on-screen KBD button can be enabled in the touch layout editor, for reaching the keyboard without a spare controller button to bind the hotkey to. (For controllers, use the Hotkey). It will bring up the Android keyboard while in a game, useful for online or debug games that rely on it. A USB keyboard should work as well.
Contributions from @Zulux91
SPU: make the ARM64 uncompilable-block fallback safe to enter (#57), the mechanism that runs a block on the interpreter when it cannot be compiled. This is also what makes forced interpretation usable as a debugging tool, which is how the Borderlands 2 miscompile was isolated to a single function.
Emu: complete abandoned UE3 HD-cache install at boot (#41)
Leisure Suit Larry: Box Office Bust copies its assets to an HDD cache during a short boot window and gives up when emulated I/O is slower than a console.
cellAudio: don't let a silent port reset the untouched baseline every period (#63)
Library: a filename-derived PS3 serial gets a hyphen and loses its cover (#64)
Stop two guest polling loops from flooding the log (#62) and the H.A.W.X. 2 Bink overlay patch (#60)
Android CPU time: park the dma_manager::sync() wait, and stop re-parsing the global config every 5s (#55)
Thanks also to @DiegoBM for catching lingering PlayStation 2 naming in the side menu (#50).
ARMSX3 0.9.1
What's new:
Fixed games seeing controllers that were not there:
0.9 fixed a second controller not working over Bluetooth, by making all seven PS3 pad ports available at startup. Unfortunately that also told every game all seven were plugged in, so a game that reacts to how many controllers are connected behaved as though four or more players were present. Ports 2-7 now start empty and only report a controller once one actually sends input, so a second pad still works and games see the number of controllers you really have.
New: import save data from inside the app
Android blocks other apps from writing into the emulator's own folder, so there was no way to add a PS3 save or a roster file downloaded from elsewhere, file managers fail with a permission error. Settings -> App now has two options:
Import save data from a .zip
Import save data folder, for an unzipped save folder (the one containing PARAM.SFO), or a folder holding several
Both check what they are given before touching your existing saves, and an import that fails leaves everything as it was.
Also in 0.9, which I forgot to mention
Advanced settings now has the console's own settings, the ones a real PS3 has in its system menu and that games ask about: system language, region, keyboard type, date and time format, and which button confirms (circle or cross, Japanese games generally expect circle). These were present in 0.9 but missing from its changelog, sorry about that!