3 Commits
Author SHA1 Message Date
pstef ce6484d947 EE/FPU: widen the FPR file's slots to 64 bits
The word stays in the slot's low half. Nothing but the stride moves.

fpuRegisters was itself the savestate's wire form; fpuRegistersWire is
now, and the freeze boundary converts.
2026-08-15 23:57:03 +02:00
Brian Degenhardt 21d1bfcf97 SaveState: don't reject a legacy state when the VM has no ELF CRC yet
Loading a state at startup resets the VM first, and the reset clears the ELF
CRC, so by the time the legacy reader checks identity the running game's CRC is
0. Comparing against it rejected every state booted with -statefile:

  This AetherSX2 save state is for CRC 45FE0CC4, but the running game is CRC
  00000000.

An unknown CRC is not a mismatch. Only compare when the VM actually has one,
which is the same rule the rest of the emulator uses (ReportGameChangeToHost
reports a CRC only once HasBootedELF()). The disc serial, which survives the
reset because it comes from the disc rather than the ELF, still hard-fails on a
wrong game — that gate is unchanged.

Ratchet & Clank: Up Your Arsenal now resumes from both legacy formats: the
NetherSX2 0x9A34 state and the AetherSX2-era 0x9A2C one, the latter exercising
all three of that era's deviations. Both consume the blob exactly, and the EE,
IOP and GS all run on from the restored state.
2026-08-02 11:19:56 -07:00
Brian Degenhardt 08dddb0947 SaveState: add a reader for the legacy 0x9A2C/0x9A34 blob layouts
Savestates written by the AetherSX2/NetherSX2 era of upstream PCSX2 use two
internal-structures layouts that today's reader cannot parse: 0x9A2C (upstream
0312e902) and 0x9A34 (upstream 7e939b75). Add a load-only deserializer that
consumes those layouts field-by-field into live emulator state.

Old struct layouts are declared in an OldState namespace, each cited to the
upstream sha it was taken from and guarded by a static_assert of the byte-exact
size. A second assert group pins the sizes of the CURRENT types the legacy
layout depends on, so upstream drift breaks the build rather than desyncing a
load mid-blob. Blocks that are byte-identical across eras reuse the existing
freeze functions.

The two era gaps that need real work: 32-bit cycle counters widen relative to
their domain base so wrap-straddling deltas survive, and fields that moved
between the cpuRegs and Cycles blocks at 0x9A31 are staged and committed once,
after the disc identity check, so a wrong-game state cannot half-apply.

Not yet wired into the load path; that follows.
2026-08-02 11:19:56 -07:00