fntrace: add fntrace_mark_game_started() for compiled-flow entry - #99
Conversation
|
Hiya! Thanks for the PR. It looks like the changes in this branch are beyond the scope of the description. Would you mind to factor out the excess changes and put them into their own PRs, if applicable? Some of them I think already superseded by changes on master as well, so they may be redundant. Thank you in advance! |
|
Hello! Sure thing, doing it now. Thank you! |
d9ede05 to
bdb8248
Compare
|
Done — rebased onto current master and slimmed the branch to exactly the described change (the two fntrace commits). The SPU/IP2/audio-pump commits are gone since #104 supersedes them, and the CD fixes + SCPH1001 seeds will come as their own small PRs. Thanks for the pointer, and for carrying the #102 work forward with the IP2 second-latch-site and turbo-mute gating fixes. |
Some titles reach their entry point through compiled code flow rather than a dispatcher round-trip, so fntrace_record() never sees the entry_pc dispatch and the game-start latch never fires. Add fntrace_mark_game_started(CPUState*) — a centralised, idempotent transition that performs all handoff side effects: - dirty_ram_clear_image_baseline() - memory_clear_low_boot_scratch() - cdrom_notify_game_started() - boot_state_trigger_capture() Refactor fntrace_record() to call the same function, removing the inlined copy. Generated entry-point functions can call this directly to latch game-start regardless of how they were reached. Tested with Tenchu 2 (SLUS-00939): adding the call at the top of func_8002E4BC engages widescreen, 2x CD speed, and boot turbo exit correctly on first entry without requiring a dispatcher round-trip.
bdb8248 to
9939514
Compare
|
Important correction pushed: the interpreter-path trigger commit originally latched on the first dispatch to any phys >= 0x10000. That fires during BIOS boot (the shell/kernel execute relocated RAM code above 0x10000), and the handoff's baseline/scratch clears then corrupt the boot — found when Medal of Honor (SLUS-00974) regressed from playable to a frame-~700 garbage-jump/VBLANK-wedge, bisected to exactly this commit pair on top of current master. The branch now latches only on the exact game entry pc armed via fntrace_set_game_range (same semantics as the compiled path), verified: MoH boots 1500+ frames with the fix, and a no-range-armed title simply never latches (previous behavior). Worth knowing for review: the failure mode is title-dependent — GT/007/C-12 happened to survive the broad match, MoH did not. |
Some titles reach their entry point through compiled code flow rather than a dispatcher round-trip, so \ntrace_record()\ never sees the \entry_pc\ dispatch and the game-start latch (which drives widescreen engagement, CD speed switch, and boot turbo exit) remains false forever.
Problem
\s_game_started\ is only set inside \ntrace_record()\ when the dispatcher targets either:
The secondary path has a chicken-and-egg: the dirty baseline is only cleared after the primary latch fires.
For titles like Tenchu 2 (SLUS-00939) where the BIOS-to-game handoff bypasses the dispatcher, \s_game_started\ remains 0 forever.
Fix
Add \ntrace_mark_game_started(CPUState* cpu)\ — a centralised, idempotent transition that performs all handoff side effects:
Refactor \ntrace_record()\ to call the same function, removing the inlined copy. Generated entry-point functions can call \ntrace_mark_game_started(cpu)\ directly to latch game-start regardless of how they were reached (dispatcher or compiled flow).
Safety
Testing
Companion generator change
A follow-up PR to \ull_function_emitter.cpp\ would emit the call automatically for the entry-point function, removing the need for manual per-title patches.
Developed with AI assistance; validated as described (test evidence in PR body). AI writes the code and the PR, but I always test before I send something up. Happy to iterate on this process with your feedback.