Commit Graph
47598 Commits
Author SHA1 Message Date
Henrik Rydgård d6c0a7bbde Firmware install: Change dialog layout, remove warning when not needed 2026-09-10 15:52:53 -06:00
Henrik RydgårdandClaude Opus 5 e4d940604e Name both versions in the firmware overwrite warning
"Firmware 6.20 is installed. It will be erased and replaced with 6.60." is the
thing worth double-checking before wiping a firmware - installing off whatever
disc is to hand makes going backwards easy to do by accident.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 15:52:53 -06:00
Henrik Rydgård 86fcfdc60a Add some new function names that were cracked from NIDs by zecoxao
He used Claude, never thought of this use case, but it's logical - it
can go reverse engineer the functions to come up with likely names,
making it easier to match the SHA1 hash. (NIDs are truncated SHA1 hashes
of names, except in firmwares later than around 3.50).
2026-09-10 15:52:53 -06:00
Henrik Rydgård 1d7c427eba Merge pull request #22281 from hrydgard/firmware-vsh-boot
Boot to XMB on all (probably) firmware versions
2026-09-10 15:46:14 -06:00
Henrik RydgårdandClaude Opus 5 e82980635b headless: don't fake a framebuffer descriptor for the end-of-run screenshot
SendDebugScreenshot ignores the descriptor entirely and reads the display
framebuffer from the GPU, so filling one in was theatre - and it computed a
pointer from the display address, which is zero whenever the shell has the
display switched off.

Also reset g_screenshotSaved per test, so a test that emits its own screenshot
doesn't stop the next one getting the end-of-run capture, and clear the sceReg
open count on shutdown to match init.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 15:30:03 -06:00
Henrik Rydgård 35d69dd4a1 De-claude a bit. It's so verbose. 2026-09-10 15:25:47 -06:00
Henrik RydgårdandClaude Opus 5 1bc43d2109 docs: all 40 firmware versions reach an interactive XMB
Record the fifth cause (the rejected impose parameter), correct the counts now
that 3.80/3.90 and 2.6x-2.8x are covered, and note that 1.50 through 2.50 never
touch the encrypted XMB index at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 14:40:24 -06:00
Henrik RydgårdandClaude Opus 5 fda30ad99c HLE: add the 3.80/3.90 NIDs for the three VSH calls
Same three functions, one more NID each. Those two shells started no plugins at
all and sat on a black screen; both reach an interactive XMB now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 13:49:08 -06:00
Henrik RydgårdandClaude Opus 5 af5bc1db50 PrxDecrypter: add the 2.6x and 2.8x sceResmgr keys
2.60 and 2.71 tag their flash0:/vsh/etc/index.dat 0x495BE403 rather than with
the 0x0B2Bxxx0 the rest of this family uses; 2.80, 2.81 and 2.82 use 0x0B2B05F0.
All five now reach an interactive XMB.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 13:49:08 -06:00
Henrik RydgårdandClaude Opus 5 f3f5432cb0 sceImpose: accept parameter 0x40000000
Every impose.prx from 1.50 to 5.55 dispatches on it and returns a field of the
impose context - the same field that decides where the backlight brightness
answer comes from. We rejected it as not a parameter at all, and 3.11's shell
read the error back, blanked the display with sceDisplaySetFrameBuf(0, 0, 0)
and never turned it on again.

2.00, 3.03 and 3.11 now reach an interactive XMB.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 13:08:04 -06:00
Henrik RydgårdandClaude Opus 5 a3ce735123 AGENTS.md: spell out that commit messages carry no session marker
The rule was already here in one line and I still added a Claude-Session
trailer to ten commits, because the session's own attribution instructions say
to. Say plainly that this rule wins, and to check git log afterwards.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 12:52:19 -06:00
Henrik RydgårdandClaude Opus 5 ee431b812b docs: re-measure which firmware versions reach an interactive XMB
The old claim of "all of them" measured that the shell renders, which several
versions do while showing only the wallpaper or a full-screen error. Record what
each version actually does, the four causes that were in the way, and how to
find the next one of each kind - including that --timeout is wall-clock, so a
slow-drawing shell can look stuck when it isn't.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 12:49:06 -06:00
Henrik RydgårdandClaude Opus 5 48a9498729 sceKernelModule: resolve the VSH's kernel drivers on old firmwares too
The per-model naming only starts around 3.50. Older dumps have plain
memlmd.prx and loadexec.prx, name the wlan firmware after the chip revision
(wlanfirm_magpie.prx became wlanfirm_01g.prx), and don't have lowio.prx at all
until about 3.52 - so every one of those was reported as a failed load on
2.00 through 3.30. Try the emulated model, the model in the path, then those
older spellings, and say plainly when the firmware simply doesn't ship one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 12:46:18 -06:00
Henrik RydgårdandClaude Opus 5 6b82202a2d PrxDecrypter: add the 3.0x, 3.1x and 3.5x sceResmgr keys too
Those generations predate the per-model split and have a single
flash0:/vsh/etc/index.dat. 3.30 through 3.52 now reach an interactive XMB;
3.30 to 3.51 share 3.52's key.

3.03's mesg_led.prx is older than keys330_1, so its table was confirmed against
keys300_1 and keys280_1 instead - both match byte for byte.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 12:46:18 -06:00
Henrik RydgårdandClaude Opus 5 f32c015659 PrxDecrypter: add the sceResmgr keys for the 5.0x, 6.0x and 6.3x XMB indexes
flash0:/vsh/etc/index_XXg.dat is the index of what the XMB shows, and each
firmware generation tags it with a key per PSP model. We only had the 6.6x
triple, so 5.03 through 6.39 decrypted nothing, drew no icons, and gave up with
the red error screen.

The keys come out of each firmware's own mesg_led_XXg.prx, whose tag table is
24-byte entries of tag plus 16-byte key. Extracting the 6.6x triple that way
reproduces the three keys already in this file byte for byte, which is what
establishes the layout.

5.03, 5.50, 5.55, 6.00, 6.20, 6.31 and 6.39 now reach an interactive XMB.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 12:44:47 -06:00
Henrik RydgårdandClaude Opus 5 0054d30b1d HLE: cover the rest of the NIDs the VSH uses across firmware versions
sceKernelLoadModuleVSH, sceKernelGetModel and sceImposeSetStatus each appear
under a different NID in 3.95/4.05, 6.00/6.20 and 6.31/6.39. Without the load
one those shells started no plugins at all and sat on a black screen.

Identified the same way as the 5.xx set: for each firmware, the modulemgr export
with sceKernelLoadModuleVSH's callee set, and the vshbridge export whose body is
the user-level check 6.61 wraps sceKernelGetModel in - which is also the only
SysMemForKernel import those shells actually call.

3.95 and 4.05 now reach an interactive XMB.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 12:44:47 -06:00
Henrik RydgårdandClaude Opus 5 3bdc4380d8 sceReg: report a registry category_version every VSH accepts
The dumped 0x66 comes from a 6.6x PSP, and 5.50's shell rejects any schema
version above 0x58 as a corrupt registry - it drew its whole XMB and then
replaced it with the "settings are corrupt, press O to repair" dialog.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 12:44:47 -06:00
Henrik RydgårdandClaude Opus 5 41509a9295 sceReg: don't let a nested registry close drop another opener's categories
We hand every sceRegOpenRegistry the same handle 0, so closing one used to wipe
every open category - including ones a still-open registry handle owns. On
hardware each open gets its own object and they don't interfere.

The VSH's alarm scan does exactly this: it holds /CONFIG/ALARM open, then opens
and closes the registry once per alarm slot, and found its own category gone by
the end. Count the opens and only clear on the last close.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 12:44:47 -06:00
Henrik RydgårdandClaude Opus 5 56b6c3af90 PrxDecrypter: add the 5.xx sceResmgr key
flash0:/vsh/etc/index_XXg.dat is the index of what the XMB shows, and 5.50 tags
it 0x0B2B11F0, which we had no key for - so the shell decrypted nothing, drew
no icons, and gave up with the red error screen.

The key is read out of that firmware's own mesg_led_02g.prx, whose tag table is
24-byte entries of tag plus 16-byte key. The two neighbouring entries hold
keys330_1 and keys505_a byte for byte, which is how the layout was confirmed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 10:48:32 -06:00
Henrik RydgårdandClaude Opus 5 1a3f14acd0 HLE: add the 5.xx NIDs the VSH of that era imports
sceKernelLoadModuleVSH, sceKernelGetModel, and four of sceImpose_driver's calls
already have implementations; 5.xx just asks for them under different NIDs, so
the 5.50 shell got nothing back. Each one was identified by disassembling that
firmware's own module and comparing the body against 6.61's, where the same
function is exported under a name - the pairs are instruction-for-instruction
identical apart from context-struct offsets.

GetModel was the one that mattered most: unresolved, vshbridge handed the shell
a garbage model number, and it went looking for PSP-3000 resources on a dump
that has none.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 10:48:32 -06:00
Henrik RydgårdandClaude Opus 5 765d5bfbcf headless: make --nand and --screenshot-save work
--nand had a field and an ApplyToConfig branch but nothing ever parsed it, so it
was silently ignored.

--screenshot-save only fired when a GE replay finished or a test used the
EMIT_SCREENSHOT devctl, and even then only under --compare. Anything else - a
game, or --vsh - ran to the timeout and wrote nothing. Capture the display at
the end of the run when nothing else did, which is what makes it usable for
looking at what a booting system actually has on screen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 10:48:32 -06:00
Henrik Rydgård a52b11aa2e Merge pull request #22275 from hrydgard/scemp4-review-fixes
sceMp4: Read the effective flags (not the config), don't reload the modules by accident
2026-09-09 19:32:10 -06:00
Henrik Rydgård 9d2ebd5a3a Merge pull request #22274 from hrydgard/headless-debugger-run
headless: say when we're waiting at the entry point, and add --debugger-run
2026-09-09 17:13:04 -06:00
Henrik RydgårdandClaude Opus 5 95d03449b3 sceMp4: don't reload the modules, read the effective flags, check four bytes
Three from a read-through of the sceMp4 firmware-module path:

Clearing the module UIDs when the game says it's done with the MP4 module
didn't unload anything - it only meant the next load brought in a second copy
of libmp4.prx and mp4msv.prx, some 220KB at the top of user memory each time.
Keep them for the boot instead; __UtilityInit clears them per game, which is
the point at which they really are gone.

The flag test read g_Config directly, so it ignored the very fallback
CheckDisableHLEAvailability computes when the dump is missing - it would go and
try to load modules that aren't there while import resolution had correctly
stayed on HLE. It also ignored a boundary restored from a savestate.

sceKernelGetModuleGPByAddress checked one byte of the pointer it writes four to.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 16:59:21 -06:00
Henrik Rydgård 9356a3acbc Merge pull request #22271 from hrydgard/firmware-screen
Add a Tools/PSP Firmware screen, improve compat with older firmwares
2026-09-09 16:50:13 -06:00
Henrik RydgårdandClaude Opus 5 29c5d1baf1 Offer to install the disc's firmware updater from the game context menu
The game screen already reports which updater a disc carries, but there was no
way to act on it - the only route to installing one was picking an updater PBP
out of the browser. The unpacker already handles being pointed at a disc, so
this just wires the menu entry to it.

Shown only when the disc actually has one, and not while a game is running:
installing wipes the NAND that game has mounted.

InstallUpdateScreen takes the archive size now, because for a disc the size of
the file it was handed is the game's and says nothing about the firmware.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 16:25:13 -06:00
Henrik RydgårdandClaude Opus 5 63eb3d5b21 Boot the VSH on every firmware, 1.50 through 6.61
Backwards from 5.01, one release at a time, against all 39 versions that ship
on a disc plus the download-only 6.61. Nothing here is an offset - it's almost
entirely Sony renumbering the kernel *_driver NIDs, which sends an import we
mean to HLE into the real firmware module instead.

Four more NIDs each for sceRtc_driver/sceRtcSetAlarmTick and
sceHprm_driver/sceHprmReadLatch, covering 1.50 up. The rtc one is what parked
every thread on a SceSysconSync semaphore; the hprm one runs once a frame, so
unresolved it was most of the boot log. Also sceImposeGetParam/sceImposeChanges
(1.50 - 2.xx) and sceKernelLoadModuleVSH (1.x, which is how the shell loads its
own plugins - unresolved it got module id 0 and StartModule failed).

sceRtcIsAlarmed had to be implemented too; it returns 0, as in JPCSP. As a null
entry it returned LIBRARY_NOT_YET_LINKED, and the 3.0x-3.5x VSH read that as
"ask the hardware instead" and went back to blocking on syscon.

Two structural findings:

- Up to 4.05, scePaf's heap allocator is a separate heaparea1.prx that paf
  imports as scePafHeaparea. Load it when it's there. Its pool pointer needs
  the same pre-fill paf's does, at gp - 0x7FCC rather than gp - 0x7E88.
- 1.50's vshmain.prx declares no module attributes at all - PSP_MODULE_VSH_MODE
  only appears from 1.52 - so the whole VSH bootstrap was being skipped. Accept
  the module name too.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 14:43:39 -06:00
Henrik RydgårdandClaude Opus 5 480c5e44e2 Boot the VSH on every firmware from 5.01 up
The blocker below 6.60 wasn't offsets, it was that Sony renumbered the kernel
*_driver NIDs between versions. A function we HLE under its 6.6x NID is a
stranger on an older build, so the import lands in the real firmware module
instead - and that's where it goes wrong:

- sceRtc_driver sceRtcSetAlarmTick. Without the HLE the VSH's alarm call ran
  the real rtc.prx, which called on into syscon.prx and blocked forever on a
  SceSysconSync semaphore. That was the whole "stalls with every thread parked"
  symptom; the tell was a fourth SceSysconSync waiter a healthy boot lacks.
- sceHprm_driver sceHprmReadLatch, called once a frame - so before this an
  older firmware's 12-second boot logged ~20000 lines of one unresolved import.

Three extra NIDs each, found by disassembling the module from both firmwares
and matching on the address of the user-mode export whose NID never changed
(sceRtc/0x7D1FBED3, sceHprm/0x40D2F9F0).

5.55 additionally needed two PRX decryption keys we didn't have (0x4C941AF0
and 0x4C941BF0) - without them none of flash0:/kd decrypted and the shell came
up with no drivers behind it at all.

Checked one release at a time against every version that ships on a disc, plus
6.61. 4.05 and below still die on a null write inside vsh_module.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 13:40:37 -06:00
Henrik RydgårdandClaude Opus 5 caf3ed4335 Firmware screen: don't list details a fonts-only install doesn't have
With no kernel modules there's no firmware to speak of - it's the fonts we
pulled off a game's disc - and rows reading "Kernel modules: 0 / XMB: No"
say nothing. Keep the font count and the size.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 12:56:43 -06:00
Henrik RydgårdandClaude Opus 5 b21e40a53f Boot the VSH on firmware 6.60 too, and stop patching builds blind
6.60 ships byte-identical paf.prx and vshmain.prx to 6.61 - all 6338 + 669
functions disassemble the same - and boots to an interactive XMB, so let
FirmwareVersionSupportsVSH accept it. That matters because no UMD carries 6.61
(it was download-only), so 6.60 is the best a disc-installed firmware can be.

The two module patches were hardcoded offsets from the module base applied to
any module of the right name, which is quietly wrong on any other build:

- The scePaf heap arena slot moves with every build (0x18CCD8 on 6.00 through
  0x18D728 on 6.60/6.61) but sits at gp - 0x7E88 in all of them, so find it
  that way. On its own this turns an immediate SIGSEGV inside scePaf into a
  clean stall on 6.00 through 6.39 - they still don't reach an XMB, they get
  stuck in sceVshBridge_Driver instead.
- The vsh_module alarm-category offset has no such anchor, so check the word
  there is the one the patch was derived from. On 6.20 and 6.00 it's ASCII
  string data - the unconditional write was corrupting a string table.

Also resolve the per-model kernel drivers (memlmd, loadexec, wlanfirm) to the
model being emulated. They were asked for as _01g, which a firmware unpacked
for a single model doesn't have - and our own updater unpack defaults to 02g.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 12:56:34 -06:00
Henrik RydgårdandClaude Opus 5 bb96802f72 Fix a heap overflow decrypting a PRX whose size we had to guess
KIRK CMD1 writes header + data_offset + align16(data_size) bytes into outbuf,
and all three come out of the header the decrypter just decrypted, not from the
caller. The SHA1 check doesn't bound them - it only covers the header, so it
passes just as happily for a block that's been cut short.

The PSAR walker has to guess how long an updater's second block is (nothing
records it, so it tries the sizes real updaters use), and a wrong guess sent
KIRK off the end of the buffer: unpacking a firmware crashed roughly half the
time, on every version and disc I tried, depending on the heap layout.

Bound the write against the size the caller gave us, in all six decrypt types.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 12:56:17 -06:00
Henrik Rydgård 304eef9b16 Merge pull request #22270 from hrydgard/reverb-tuning
Reverb effect tuning
2026-09-09 12:26:43 -06:00
Henrik RydgårdandClaude Opus 5 57e96b2d81 Add a PSP Firmware screen under Settings > Tools
Shows what's actually in PSP/NAND - nothing, a fonts-only partial install, or
a full firmware with its version, build date and region - read from
flash0:/vsh/etc/version.txt, which is present both in a PSAR-unpacked install
and a NAND dumped off hardware.

Also offers to install an updater, erase the NAND, and launch the XMB, the
last one gated on FirmwareVersionSupportsVSH() since the module patches that
get vshmain.prx running are tied to 6.61's offsets.

Installing a firmware now erases flash0/flash1/ipl first - two firmwares can't
be merged, a file the new one doesn't have would linger and still get loaded.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 12:07:28 -06:00
Henrik Rydgård 6d945404d1 sceSas: Fix send/return levels for the reverb effects
The two fudge factors in the reverb path cancelled, which is why the
overall level felt roughly right.

- The send is accumulator * 0x20 >> 16, i.e. sample >> 2. We used >> 1,
  driving the reverb 6dB hot.
- The return is (evol * out) >> 11. We used >> 12, i.e. 6dB quiet.

Net level is therefore unchanged, but the reverb now runs at the level
the presets were designed around. That matters because the filter clamps
internally, so a 6dB hot input changes how the feedback path saturates -
worst on the presets with heavy feedback.

Also adds a slider in the imgui.
2026-09-09 11:05:40 -06:00
Henrik Rydgård 5402579a44 sceSas: correct the reverb presets
The reverb presets came from nocash's PS1 table. Six of the nine are
identical on the PSP, but three are not.

Also correct our linear interpolation expression: we were close but
our formula can produce an off by 1 at times.
2026-09-09 10:48:53 -06:00
Henrik RydgårdandClaude Opus 5 794263ed6a headless: say when we're waiting at the entry point, and add --debugger-run
--debugger sets startBreak, so the run sits at the entry point until a client
resumes it. A session that forgets to do that looks like a frozen game rather
than a paused CPU - all the way down to "ticks: 0" - so say so on the way up,
and add --debugger-run for the common case of wanting the debugger attached to
a run that just goes.

Also stop headless forcing HLE for the graduated modules. Those come out of the
game's own disc rather than a firmware dump - libpsmfplayer.prx and friends are
user libraries, always present - so forcing them to HLE made headless quietly
disagree with the app about which code a game runs. Tekken 6 plays its movie
through scePsmfPlayer, and headless was faking it, so the movie never reached
sceMpeg at all; now the disc's real psmfplayer drives the real mpeg.prx.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 10:15:02 -06:00
Henrik Rydgård e5b98b07e8 Merge pull request #22269 from hrydgard/me-re-tools
Headless RE tools: Add some options to disassemble ME images
2026-09-09 09:41:53 -06:00
Henrik Rydgård 280a5df557 headless: split the second stream out of an ME image, and accept a bare one
An ME image is two KL4E streams back to back: the code that runs at
0x88300000, then a blob the image decompresses to ME local RAM at
0x00101000, which is where its data segment lives. Decompressing only the
first left every global unaccounted for.

--re-decrypt now reports how much of the plaintext the first stream used
and writes the remainder to <out>.tail, and accepts an already-plain
KL4E/KL3E file so that tail can be fed straight back in.
2026-09-09 09:00:29 -06:00
Henrik Rydgård 1a1430e8ca headless: add --re-decrypt and --re-raw-base to the RE tool
--re-decrypt runs pspDecryptPRX() over a file and unpacks the KL4E/KL3E
stream behind it. This opens up flash0:/kd/resource/*.img, the images the
Media Engine actually runs: they are ordinary tagged containers (tag
862648D1, which PrxDecrypter already has a key for) with the ~PSP
signature blanked, so the normal module loader never touches them.

--re-raw-base analyzes --re-module as a flat code image at a given
address rather than as a PRX. The decrypted ME images are raw MIPS with
no ELF around them; the address they were linked for is recoverable from
their own jal targets (0x08300000 for meimg.img).

Also makes PrxDecrypter.h self-contained - PSP_Header is built from _le
types, so it needs Common/Swap.h rather than relying on the includer.
2026-09-09 09:00:29 -06:00
Henrik Rydgård d163551823 Merge pull request #22262 from NABN00B/stereo-settings
Show stereo shader options dynamically
2026-09-09 08:53:46 -06:00
Henrik Rydgård 3d59ef6f09 Merge pull request #22268 from hrydgard/revert-mipstracer
Revert exposing MIPSTracer to websocket
2026-09-09 08:46:19 -06:00
Henrik Rydgård f161e7f9f9 Revert "Expose the MIPSTracer over the WebSocket debugger"
This reverts commit ccdaa94f53.
2026-09-09 08:07:19 -06:00
Henrik Rydgård 25812b70fb Merge pull request #22266 from hrydgard/firmware-module-reset
sceUtility: forget injected firmware modules between games
2026-09-08 17:08:09 -06:00
Henrik Rydgård a333a93a7c sceUtility: forget injected firmware modules between games
Clear them in __UtilityInit, which runs per boot.
2026-09-08 16:57:43 -06:00
Henrik Rydgård 32a70d0d3d Merge pull request #22265 from hrydgard/vaudio-mp3-sample-counts
sceVaudioChReserve: accept the MP3 frame sizes
2026-09-08 16:14:13 -06:00
Henrik Rydgård 47c17b5589 Merge pull request #22264 from hrydgard/re-module-dump
Module dumper for reverse engineering
2026-09-08 16:07:37 -06:00
Henrik Rydgård c192ddcaa1 Merge pull request #22263 from hrydgard/hardware-verified-hle-fixes
Hardware verified HLE fixes
2026-09-08 15:53:35 -06:00
Henrik RydgårdandClaude Opus 5 ed9078b055 sceVaudioChReserve: accept the MP3 frame sizes
The channel took only 256, 1024 and 2048 samples, so a game that hands it MP3
frames got SCE_KERNEL_ERROR_INVALID_SIZE and no music. Dead or Alive Paradise
does exactly that from its music player: sceVaudioChReserve(1152, 44100, 2),
1152 being the MPEG-1 Layer III frame size.

The format check moves below the sample count check to match: the module
returns 0x80000104 for a bad count before it ever looks at the format, so a
call with both wrong got the wrong error out of us. The two error codes we
already returned are the ones it uses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 15:52:10 -06:00
Henrik Rydgård cc44ba22d0 Android buildfix 2026-09-08 15:45:11 -06:00
Henrik RydgårdandClaude Opus 5 fa577eaa83 Document --re-module in AGENTS.md and docs/reverse-engineering.md
A tool nobody knows about is a tool nobody uses. AGENTS.md gets a short section
pointing at it, plus the two things most likely to be got wrong when reading
the output: that a function's arity can't be inferred from the registers it
reads, since MIPS code passes arguments through untouched, and that a finding
is worth much more when the comment says which module it came from.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 15:32:23 -06:00