Repository navigation
Carts play together: the ROM arena stays put, carts borrow it - #5
Merged
Merged
Conversation
ESP-IDF Size Report for 'Tab5 Emu'
FLASH uses app .bin size or json2 flash sum. RAM sums DRAM+IRAM via idf_size. Percentages shown when totals are available. |
CONFIG_TAB5_EMU_AUTOSTART_MATCH takes a comma-separated list and CONFIG_TAB5_EMU_AUTOQUIT_SECONDS quits each auto-started game after that long, the way the pause menu's Quit does, then starts the next one, round and round. Each launch logs the free internal RAM and PSRAM (and the largest blocks) before and after make_cart's releases. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Playing The Phantom Menace and then Jedi Knight could crash JK's level load with a corrupt heap. JK was short of PSRAM: TPM's recompiled game is 3.1 MB of code that, like all code on the P4, runs from PSRAM, so the merged firmware's heap is 3.3 MB smaller than the JK-only build's (and the bring-up allocation tracker, CONFIG_JK_ESP_DEBUG, took another 1.5 MB). JK runs again with that option off; the arena changes below keep the PSRAM in large, stable blocks: - JK no longer hands the 6 MB ROM arena back to the system heap. It makes a private heap of it (multi_heap) for its large allocations; blocks carry their session, so the engine's late frees from an earlier session are dropped instead of corrupting the next heap. - GBA takes its first ROM cache blocks from the arena (a gpSP allocation hook) instead of releasing it. - MGS and TPM borrow the arena for their big buffers. Before, they needed a 3.8 / 4.9 MB hole in a heap other games had cut up: after JK, TPM found no 4.9 MB block and ran without save states. The arena now stays at its boot address, so MGS and TPM save states keep loading after other games ran, and the largest free PSRAM block stays at 8.9 MB through any order of launches (it fell to 4 MB). Tested with the soak test: TPM, JK, MGS, SNES, GBA and Genesis in every pairing, 16 launches with quits, on the Tab5. mgs_reversing 0ac4d5d: Mgs_ArenaBorrow. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
finger563
force-pushed
the
feat/shared-arena
branch
from
October 18, 2026 13:16
41d264d to
ed529bd
Compare
Nine 640x480 menu backgrounds (2.7 MB of PSRAM) stayed loaded through a level started without a menu; the material cache thrashed for the room. Now the level's textures all fit with 1.3 MB to spare. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Playing The Phantom Menace and then Jedi Knight crashed JK while it loaded its first level (
CORRUPT HEAP … multi_heap_free … (head != NULL)injk_engine, undersithThing_FreeThing).Cause. It turned out not to be TPM leaving memory behind. JK crashed the same way when it was the first game after a boot. JK was short of PSRAM:
CONFIG_JK_ESP_DEBUG) holds a 1.5 MB table.JK runs again with that debug option off; it defaults to off.
The soak test found a second problem. After JK or GBA, the free PSRAM was cut up: the largest block fell from 10.5 MB to about 4 MB. TPM then found no 4.9 MB block and ran without save states. The ROM arena also came back at a different address, so MGS and TPM states saved earlier could no longer load.
Changes
The 6 MB ROM arena reserved at boot now stays reserved, at its boot address. Carts borrow it instead of releasing it:
multi_heap) for the engine's large allocations. Each block carries its session, so a late free from an earlier session (the engine does these at the next start) is dropped instead of corrupting the new heap.gpsp_rom_block_alloc/gpsp_rom_block_free); the rest come from the heap as before.Mgs_ArenaBorrow, mgs_reversing 0ac4d5d), with the heap as a fallback. A lent block is never freed.Results:
Soak test (separate commit):
CONFIG_TAB5_EMU_AUTOSTART_MATCHtakes a comma-separated list, andCONFIG_TAB5_EMU_AUTOQUIT_SECONDSquits each game after that long (the pause menu's Quit path) and starts the next. Each launch logs free and largest-block memory.JK texture thrashing (OpenJKDF2 756c012)
Once the player left the start area, the texture (material) cache kept evicting and reloading. Measured on the board with an allocation dump: nine 640×480 menu backgrounds (
bkMain,bkEsc(twice),bkSetup, …), 2.7 MB in all, stayed loaded for the whole level. That's more than the first level's entire texture set, 2.2 MB, computed from the GOBs. Menus unload them when they close, but a level started without a menu (-autostart, level changes) never did.jkMain_GameplayShownow unloads them, and they come back on demand throughstdBitmap_EnsureData.After the fix the cache holds every material the level showed (346), with no failed loads and no purges, and 1.3 MB to spare.
The console now reports the cache every 5 s, and the frame's non-zero-pixel check is no longer debug-only.
Testing
On the Tab5, 16 launches with 45 s each:
TPM → JK → MGS → TPM → MGS → JK → SNES (Chrono Trigger) → JK → GBA (Minish Cap) → TPM → Genesis (Sonic 2) → MGS → SNES → TPM → TPM → JK
0x48cfc3c0.Not tested: loading a save state across another game (the addresses now match, which is what states need).
Note
JK has about 1.9 MB less PSRAM than in the JK-only build, because of TPM's code. The first level loads and plays fine; JK's texture cache is designed to fill whatever is left. I didn't test later, larger levels.
🤖 Generated with Claude Code