Frame model: per-port coroutines, first frame-waiting ports (#37) #65

Merged
Gatchan merged 4 commits from frame-model into main 2026-11-06 04:47:55 +00:00
Owner

Frame model for ported code (#37): tm_wait_frame (core/platform/timing.h) is the single yield point; a port flagged PORT_WAITS_FRAMES runs its bridge in a libco coroutine (core/port/port_frame.c). At a wait the machine idles in WAI at the routine's address, runs its interrupt handlers, and the C resumes once the NMI handler has returned there. Mode on: the real machine, resumed from the instruction hook. Shadow: the clone follows the original cycle by cycle with its pad state; the call is compared when the original returns (same state, same number of vblank interrupts). A savestate is refused while a port in mode on waits.

First ports: field/WaitVblank and btlgfx/WaitVblank.

Found on the way: #64 (LakeSnes keeps the old FastROM access table after snes_loadState), worked around in core/hw.

Validation:

  • shadow, both ports alone, the 4 chapter 1 routes, US+JP once each: btlgfx 39108/39108 US, 37025/37025 JP; field 46586/46589 US, 42888/42891 JP (one call per route still waiting at the movie's end); 0 mismatch, 0 fallback; movies match
  • ff6-portcheck.sh all: PASS, 136 checks US+JP (WaitVblank 52 + 65 states per version)
  • debug ctest -LE slow: 27/27

Closes #37.

🤖 Generated with Claude Code

🤖 Generated with Claude Code

Frame model for ported code (#37): `tm_wait_frame` (core/platform/timing.h) is the single yield point; a port flagged `PORT_WAITS_FRAMES` runs its bridge in a libco coroutine (core/port/port_frame.c). At a wait the machine idles in WAI at the routine's address, runs its interrupt handlers, and the C resumes once the NMI handler has returned there. Mode on: the real machine, resumed from the instruction hook. Shadow: the clone follows the original cycle by cycle with its pad state; the call is compared when the original returns (same state, same number of vblank interrupts). A savestate is refused while a port in mode on waits. First ports: field/WaitVblank and btlgfx/WaitVblank. Found on the way: #64 (LakeSnes keeps the old FastROM access table after snes_loadState), worked around in core/hw. Validation: - shadow, both ports alone, the 4 chapter 1 routes, US+JP once each: btlgfx 39108/39108 US, 37025/37025 JP; field 46586/46589 US, 42888/42891 JP (one call per route still waiting at the movie's end); 0 mismatch, 0 fallback; movies match - ff6-portcheck.sh all: PASS, 136 checks US+JP (WaitVblank 52 + 65 states per version) - debug ctest -LE slow: 27/27 Closes #37. 🤖 Generated with [Claude Code](https://claude.com/claude-code) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Gatchan/FF6Portage!65
No description provided.