Coverage of the interpreter per route, field porting order #31

Merged
Gatchan merged 4 commits from coverage into main 2026-10-29 20:35:56 +00:00
Owner

Fixes #30

Interpreter coverage per route, and the field porting order it gives.

What

  • Core debug API (core/port/coverage.c, ff6_debug.h): routine entries (JSR/JSL targets, interrupts incl. reset, tail jumps: JML, JMP (abs)/(abs,X), RTS/RTL to a pushed address, JMP/BRA/BRL below the current entry), each instruction attributed to the innermost entry of a shadow call stack (frames popped by stack pointer, so dropped return addresses and stack switches are handled; a call replaced by a port in mode on pushes nothing), call/jump edges, spans (activations that cross a frame boundary), executed-address bitmap (2 MiB, one bit per 24-bit address). Same hook dispatcher as the port registry and the RAM trace; state in the core context; one flag test when off; about 2% slower when on.
  • Hosts: ff6cli --coverage <file> (text format, version 1, documented), drive server coverage start|stop|write <path>.
  • tools/coverage_report.py: aggregates any number of files of one version (the version comes from the files; a different --version is refused), known routines from the .dbg (ff6sym.routines: top-level code labels that start an instruction, in code segments), per module reached/known, instructions, top routines by instructions and by activations, --never, --field-order N.
  • Docs: docs/coverage.md (method, format, how to run, numbers, porting order), docs/build.md. Reports for the route library committed under re/coverage/ (names and addresses only); the coverage files stay in others/.
  • Tests: rom.coverage.{US,JP}_V10 (label rom): a 600-frame run gives the same file twice, and the same file from ff6cli and from the drive server; the run hashes are unchanged with --coverage. Synthetic checks of ff6sym.routines and coverage_report.py in tools.disasm.

Numbers (three routes, release)

Module Reached / known US JP
field 252 / 334 250 / 335
event 122 / 207 122 / 207
menu 418 / 1401 429 / 1451
battle 297 / 526 295 / 526
btlgfx 632 / 1203 646 / 1207
world 48 / 273 48 / 273
cutscene 103 / 206 100 / 203
sound 13 / 17 13 / 17
all 1885 / 4167 (45.2%) 1903 / 4219 (45.1%)

Field porting order top 15 (US, JP the same set): InitMaskHDMAData, TfrObjGfxSub, UpdateObjFrame, MoveObjs, _c0714a, UpdateScrollHDMA, DrawOverlaySprites, CalcScrollPos, CheckTimer, UpdateFixedColor, DrawLetter, TfrBGAnimGfx, DecTimersMenuBattle, _c0249a, SetTopSpriteMSB. Details in docs/coverage.md and on the issue.

Validation

  • Builds clean: debug, release, clang, mingw.
  • release --fast and debug --fast: 24/24 passed (includes rom.coverage.*); rom.coverage.US_V10 also passes under wine (mingw).
  • All six committed movies replayed with --coverage: movie: match (picture, WRAM, SRAM) on US and JP; no stack overflow, nothing dropped.

🤖 Generated with Claude Code

Fixes #30 Interpreter coverage per route, and the field porting order it gives. ## What - **Core debug API** (`core/port/coverage.c`, `ff6_debug.h`): routine entries (JSR/JSL targets, interrupts incl. reset, tail jumps: JML, JMP (abs)/(abs,X), RTS/RTL to a pushed address, JMP/BRA/BRL below the current entry), each instruction attributed to the innermost entry of a shadow call stack (frames popped by stack pointer, so dropped return addresses and stack switches are handled; a call replaced by a port in mode `on` pushes nothing), call/jump edges, `spans` (activations that cross a frame boundary), executed-address bitmap (2 MiB, one bit per 24-bit address). Same hook dispatcher as the port registry and the RAM trace; state in the core context; one flag test when off; about 2% slower when on. - **Hosts**: `ff6cli --coverage <file>` (text format, version 1, documented), drive server `coverage start|stop|write <path>`. - **`tools/coverage_report.py`**: aggregates any number of files of one version (the version comes from the files; a different `--version` is refused), known routines from the `.dbg` (`ff6sym.routines`: top-level code labels that start an instruction, in code segments), per module reached/known, instructions, top routines by instructions and by activations, `--never`, `--field-order N`. - **Docs**: `docs/coverage.md` (method, format, how to run, numbers, porting order), `docs/build.md`. Reports for the route library committed under `re/coverage/` (names and addresses only); the coverage files stay in `others/`. - **Tests**: `rom.coverage.{US,JP}_V10` (label rom): a 600-frame run gives the same file twice, and the same file from ff6cli and from the drive server; the run hashes are unchanged with `--coverage`. Synthetic checks of `ff6sym.routines` and `coverage_report.py` in `tools.disasm`. ## Numbers (three routes, release) | Module | Reached / known US | JP | |---|---|---| | field | 252 / 334 | 250 / 335 | | event | 122 / 207 | 122 / 207 | | menu | 418 / 1401 | 429 / 1451 | | battle | 297 / 526 | 295 / 526 | | btlgfx | 632 / 1203 | 646 / 1207 | | world | 48 / 273 | 48 / 273 | | cutscene | 103 / 206 | 100 / 203 | | sound | 13 / 17 | 13 / 17 | | **all** | **1885 / 4167 (45.2%)** | **1903 / 4219 (45.1%)** | Field porting order top 15 (US, JP the same set): InitMaskHDMAData, TfrObjGfxSub, UpdateObjFrame, MoveObjs, _c0714a, UpdateScrollHDMA, DrawOverlaySprites, CalcScrollPos, CheckTimer, UpdateFixedColor, DrawLetter, TfrBGAnimGfx, DecTimersMenuBattle, _c0249a, SetTopSpriteMSB. Details in `docs/coverage.md` and on the issue. ## Validation - Builds clean: debug, release, clang, mingw. - `release --fast` and `debug --fast`: 24/24 passed (includes `rom.coverage.*`); `rom.coverage.US_V10` also passes under wine (mingw). - All six committed movies replayed with `--coverage`: `movie: match` (picture, WRAM, SRAM) on US and JP; no stack overflow, nothing dropped. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Routine entries (calls, interrupts, tail jumps) on a shadow call stack, instructions attributed
to the innermost entry, call/jump edges, executed-address bitmap; same hook dispatcher as the
port registry and the RAM trace. Test rom.coverage.*: deterministic, identical between ff6cli
and the drive server, run unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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!31
No description provided.