Commit Graph
162 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5.5 6d122f416e Keep JIT block entries and replacement hooks out of PSP memory
The JITs used to find a block by overwriting its first instruction with an "emuhack" holding
the offset into the code space, and replacement functions installed their own emuhack the same
way. Anything that read code (savestates, the debugger, memory dumps, cheats, the function
hasher, games reading their own code) had to translate them back.

Blocks now live in a block shadow: one u32 per guest instruction, indexed by the PC masked with
BLOCK_SHADOW_MASK (1GB on 64-bit, folding the kernel and uncached mirrors; 256MB on 32-bit, iOS
and Switch, where address space is short), with the low bits cleared so a misaligned PC can't
read across two entries. Only the ranges under memory views are committed, so a bad PC still
faults in the dispatcher, and the shadow is reserved before the memory map so it can't land in
a gap of the 4GB window. Entries hold full 32-bit offsets, lifting the 16MB limit. The
dispatchers on every backend, and the IR interpreter's loop, look blocks up there.

A hooked instruction without a compiled block gets the JIT's hook value in its entry: the offset
of the dispatcher's compile path (1 for the interpreters, the IR arena keeping that offset
empty), so dispatching there compiles a block, and the frontends substitute the hook. Compiling
replaces the entry with the block's, and destroying the block puts the hook value back. The hook
value is rewritten when the JIT changes or regenerates its dispatcher.

Hooks live in a map keyed by the masked address, and are dropped when the game overwrites the
hooked instruction, or when an icache invalidation finds the function's hash (immediates masked,
as when matching it) changed. Those checks run when queued invalidations are processed, since
cheats and the debugger queue them before writing. Installing and removing hooks invalidates
deferred, as it happens in HLE calls that can run inside a block. The cache instruction goes
through MIPSState, so it drops changed hooks too.

With clean memory, the save/clear/restore around savestates, memory reads and dumps goes away,
as do the source-range invalidations in the memcpy replacements, sceDmac and the cheats.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 10:33:30 +02:00
Henrik RydgårdandClaude Opus 5.5 2e5edcd298 Savestate: Don't break event callbacks when a save fails
CoreTiming::DoState replaced every event's callback with the anti-crash
one in every mode, relying on each module's restore to put it back. A save
that failed partway never got to those, and left the running game with
events that break into the debugger. The missing-section fallbacks then
also ran on the save: cheats and the mic re-registered events into the
wrong slots, and achievements reset the runtime.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 09:34:06 -06:00
Henrik Rydgård e2ab84087e Fix five ways to end up stuck, crashed, or silently degraded
System.cpp stamped BootState::Complete unconditionally after InitGPU(), overwriting
the Failed that InitGPU sets when GPU_Init() fails - after it has already run
CPU_Shutdown(). PSP_InitUpdate then took the success path on a core that no longer
existed, down to a null Memory::base, and the first guest access dereferenced it.
InitGPU now reports failure and both callers honor it. (The libretro path had the
same problem from the other direction: it calls InitGPU after the Failed check.)

HandleAssert called g_assertCancelCallback directly on the IDCANCEL path, without
the null check its own BreakIntoPSPDebugger() helper does - and EmuScreen clears the
callback when a game is unloaded. So any assert after returning to the menu turned
"Cancel: skip and break into PPSSPP debugger" into a null jump, from the one button
whose entire purpose is surviving the assert.

__CheatDoState registered the cheat event type when the savestate had no CwCheat
section, but never scheduled it. CoreTiming::DoState has already swapped in the
state's event queue by then, which doesn't contain one either - so loading an old
savestate silently killed cheats, and the enable/disable polling with them, for the
rest of the session.

Achievements::ChangeUMD set g_isIdentifying and returned without clearing it when
hashing failed, leaving IsBlockingExecution() true forever - EmuScreen stops running
the CPU and the game is frozen until restart. Reachable from a disc swap on any ISO
whose PARAM.SFO or EBOOT.BIN can't be read.

x64Analyzer routed opcode 0x88 into the write path but had no case for it, so it hit
the default, logged from inside the crash handler, and failed. 0x88 is exactly what
the x64 JIT emits for a guest sb, so MemFault could never skip or ignore a bad byte
store the way it can a word one. Handle the 8-bit forms, and drop the 0x8a/0x8b cases
in the read path that the same 0xF0 mask made unreachable. Covered by a new
CheckAnalyze case, which fails without this change.

314 pspautotests pass, all unit tests pass.
2026-08-31 12:27:24 +02:00
Henrik Rydgård 5c6fc2e69f Minor CwCheat correctness fixes 2026-08-20 00:29:00 +02:00
Henrik Rydgård 9f90512ef6 Make instruction cache invalidation (for us, jit cache invalidation) clearer 2026-08-16 16:59:52 +02:00
Henrik Rydgård 3bd41376da More memory cleanup 2026-08-11 20:12:10 +02:00
Henrik Rydgård 66c8bfbcb2 Improve semantics 2026-08-10 10:11:24 +02:00
Henrik Rydgård a9017b301e Also support the "Post-comment" syntax used by cheats.db for comments 2026-04-24 14:41:47 +02:00
Henrik Rydgård c97007adfe CwCheat screen: Detect titles and display them as large text instead of checkboxes 2026-04-24 14:29:09 +02:00
Henrik Rydgård 22b07849cf Add a missing lock 2026-03-13 11:35:10 +01:00
Henrik Rydgård f21876b0b7 Move CheatFileParser out to the header, remove the line_ mmember variable 2025-10-07 10:07:04 -06:00
Henrik Rydgård 9c5b1c1b8b Remove some scaffolding directed at supporting TempAR codes in the future. Not likely to happen. 2025-10-07 09:50:05 -06:00
Henrik Rydgård abbea9ac05 Restore cache invalidation in CwCheats code 2025-01-04 17:18:23 +01:00
Henrik Rydgård 74817c779d CwCheat: Don't double-check already checked memory pointers 2025-01-03 21:08:26 +01:00
Henrik Rydgård b6fde72f52 CwCheat: Avoid instruction cache invalidations on reads. Not needed. 2025-01-03 21:08:23 +01:00
Henrik Rydgård 01acd59357 CwCheats: Avoid logspam with some bad cheats. Tag cheat structs with names (sometimes useful for debugging). 2025-01-03 20:55:26 +01:00
Henrik Rydgård b71ccfdb71 CwCheats: Add ms unit, rename to Refresh Interval. 2024-01-19 15:12:53 +01:00
Henrik Rydgård aed8bc6d7b RetroAchievements: Finish the Challenge->Hardcore rename 2023-12-03 16:41:29 +01:00
Henrik Rydgård c17b84b3d4 Implement RetroAchievements challenge mode restrictions, and fix related bugs 2023-07-08 21:55:32 +02:00
Henrik Rydgård eb21a2e6c9 Break out the OSD data holder from Common/System/System.h, into OSD.cpp/h 2023-06-30 17:15:49 +02:00
Henrik Rydgård 7cc8c6cea4 OSD: Add semantics, move the the OSD state to common (while keeping the renderer in the UI). 2023-06-20 14:40:46 +02:00
Henrik Rydgård ee6234ecb6 I18N: Switch to getting categories by index instead of by string lookup
Also gets rid of the shared_ptr usage, and generally makes things nicer.

Needed for later config refactorings, good to get in early.
2023-04-07 10:35:01 +02:00
Henrik Rydgård 9e125eeba7 Remove NotifyUserMessage from Host 2023-03-25 10:32:09 +01:00
Unknown W. Brackets 728dde8eb3 Cheats: Cleanup sizes of invalidates and checks.
And ensure we're always invalidating full words to be safe.
2023-01-01 10:30:47 -08:00
Unknown W. Brackets fe470c790e Postshader: Reset ini keys for defaults.
Should fix the Vignette shader defaults, see #16562.
2022-12-12 19:11:20 -08:00
Henrik Rydgård fc24a7d426 CwCheat: Remove assert on TempAR type codes. Seems weird that we had this. 2021-10-18 17:19:57 +02:00
Linblow 0fcf68632d Detect CwCheat file UTF-8 BOM sequence and ignore it 2021-07-26 11:47:21 +02:00
Linblow 69657ef05e Added JIT hack for MTX MotoTrax EU (ported from US) 2021-07-17 12:59:15 +02:00
Henrik Rydgård 025bcb1673 Introduce Path, start using it all over the place.
Still lots left to convert!

Convert GetSysDirectory to return Path.

More buildfixing

Remove unnecessary Path( constructors
2021-05-13 10:39:16 +02:00
Unknown W. Brackets 0f3f74408f Cheats: Parse files using C files for Path compat. 2021-05-09 17:00:48 -07:00
Unknown W. Brackets ca1a936d56 GPU: Stop using Off as terminator for postshaders.
There's really no need to have a dummy entry at the end of the array.
2021-04-10 18:35:23 -07:00
Unknown W. Brackets a76ba9a957 Core: Handle Disc ID a bit more consistently. 2021-02-28 10:52:35 -08:00
Unknown W. Brackets e7b968be73 Debugger: Notate Memcpys directly as well. 2021-02-15 15:01:23 -08:00
Henrik Rydgård 93fd62f54b Merge pull request #13832 from unknownbrackets/events
SaveState: Make event restoring more obvious
2021-02-15 23:39:42 +01:00
Henrik Rydgård f34f554321 Don't assert on invalid format in CwCheat.
Not sure exactly what we should do, though..
2021-02-13 18:36:52 +01:00
Unknown W. Brackets 06f8ab5a49 SaveState: Make event restoring more obvious.
We still must restore all events, but everything can be taken care of
during the save state load.
2020-12-28 13:29:19 -08:00
Henrik Rydgård 4f43cff5ca Move fileutil, net, image loaders, ui to Common. (#13506)
* Move and rename file_util/fd_util to Common/File/FileUtil and DirListing

Let's also move net while we're at it.

Move the ZIM/PNG loaders over to Common.

Move the UI framework into Common

iOS buildfix

* Buildfix

* Buildfixes

* Apple buildfix

* This typo again..

* UWP buildfix

* Fix build of PPSSPPQt, such as it is (it's not in good condition...)

* Guess what? Another buildfix.
2020-10-04 20:48:47 +02:00
Henrik Rydgård ff8148dd92 Move native/util, native/data and native/i18 to Common/Data.
Also move colorutil.cpp/h

linking build fix experiment

Delete a bunch of unused CMakeLists.txt files

CMakeLists.txt linking fix

Don't include NativeApp.h from any headers.

Android.mk buildfix

Half of the UWP fix

Buildfix

Minor project file cleanup

Buildfixes

Guess what? More buildfixes!
2020-10-04 07:28:29 +02:00
iota97 0c885db052 User chain support 2020-09-13 21:48:00 +02:00
Henrik Rydgård 5d64fc5ff1 Switch to PPSSPP's assert functions (don't use the system's) 2020-08-16 10:01:10 +02:00
Unknown W. Brackets b8342fb8ec SaveState: Rename ChunkFile files to Serialize.
Makes more sense and less weird than ChunkFileDoMap, etc.
2020-08-10 08:04:05 +00:00
Unknown W. Brackets 4b4e3432cd SaveState: Split Do() into a separate header. 2020-08-10 08:03:41 +00:00
iota97 45bfb4f52b Code style fix 2020-06-04 19:08:10 +02:00
iota97 6f59f02b38 Support chain 2020-05-17 19:06:23 +02:00
iota97 c83e2fb070 Memory reading CWCheat 2020-05-17 18:07:30 +02:00
iota97 69d806a83a Add postprocessing CWCHEAT 2020-05-17 18:07:30 +02:00
Henrik Rydgård cc916180b5 Merge pull request #12816 from LunaMoo/XVibrationCheat
Implement Xinput vibration CWCheat (PPSSPP specific 0xA code type)
2020-04-17 10:50:44 +02:00
LunaMoo e999444b23 Implement PPSSPP specific cheats:
0xA0 vibration cheat(Xinput)
Syntax is: 0xA0NNLLLL 0x00MMRRRR
where NN/MM is time vibration lasts LLLL/RRRR is the vibration power

0xA1 read value for the vibration(Xinput) from game memory
Syntax is: 0xA1000000 0xNNNNNNNN
where NNNNNNNN is the address that stores following values at offset:
0xNNNNNNNN + 0x0 Left Vibration power,
0xNNNNNNNN + 0x2 Right Vibration Power
0xNNNNNNNN + 0x4 Left Vibration time
0xNNNNNNNN + 0x6 Right Vibration time

Left some room for other PPSSPP specific cheats(0xA2-0xAF)
2020-04-16 23:00:29 +02:00
Unknown W. Brackets e60623498f Cheats: Fix use in homebrew on start. 2020-04-11 14:01:32 -07:00
Unknown W. Brackets 5ba7cca5f3 Cheats: Cleanup global usage. 2020-04-11 13:56:06 -07:00