Field ports batch 3: scroll/HDMA/dialogue routines deferred from batch 2, VRAM upload operation #56

Closed
opened 2026-11-04 13:55:29 +00:00 by Gatchan · 1 comment
Owner

Deferred from #54: InitBG1VScroll, InitBG2VScroll, _c0249a, UpdateBG1, UpdateBG3HScroll, UpdateScrollHDMA, InitMaskHDMAData, _c0714a, MoveObjs, DrawOverlaySprites, LoadLetterGfx, UpdateDlgWindow; with a VRAM upload operation in video.h: TfrBGAnimGfx, TfrBG3AnimGfx, TfrObjGfxSub; SetWindowSelect (window service, 1 BG1-scroll mismatch to explain). Then continue the docs/coverage.md field order. Create re/known-bugs.toml (#40) with the UpdateMosaic quirk.

Deferred from #54: InitBG1VScroll, InitBG2VScroll, _c0249a, UpdateBG1, UpdateBG3HScroll, UpdateScrollHDMA, InitMaskHDMAData, _c0714a, MoveObjs, DrawOverlaySprites, LoadLetterGfx, UpdateDlgWindow; with a VRAM upload operation in video.h: TfrBGAnimGfx, TfrBG3AnimGfx, TfrObjGfxSub; SetWindowSelect (window service, 1 BG1-scroll mismatch to explain). Then continue the docs/coverage.md field order. Create re/known-bugs.toml (#40) with the UpdateMosaic quirk.
Author
Owner

Merged in PR #57.

Field batch 3 (refs #56, fixes #56, fixes #40): 21 field routines ported with the tools (draftc -> port -> portbridge.py bridge and row -> shadow + fuzz).

Ported: TfrBGAnimGfx, TfrBG3AnimGfx, TfrObjGfxSub, SetWindowSelect, InitBG1VScroll, InitBG2VScroll, UpdateBG1VScroll, UpdateBG2VScroll, UpdateBG1HScroll, UpdateBG2HScroll, UpdateBG3HScroll, UpdateBG1, UpdateBG2, UpdateBG3, _c0249a, UpdateScrollHDMA, InitMaskHDMAData, InitSpriteMSB, BGColorDec, BGColorUnDec, DrawOverlaySprites. Game code 1138 -> 1852 lines (new field_anim.c, field_tilemap.c: the 11 tilemap routines share one layer-parametrised drawer).

Platform and tools

  • video.h: vid_begin_tile_uploads, vid_set_tile_destination, vid_upload_tiles (VRAM; destination written once so the read latch matches), vid_force_blank, vid_stop_line_effects, vid_set_window_layers, vid_set_layer_scroll (docs/platform.md).
  • Game data as DMA source: res_at (pointer from game data -> resource bytes), res_rom_offset (backend: resource bytes -> cartridge address); new blob resources map_anim_gfx, map_sprite_gfx, map_sprite_gfx_ptrs/banks, map_sprite_tile_offsets.
  • SetWindowSelect: PORT_WRITES_PPU_WINDOWS compares only W12SEL-WOBJSEL (the batch 2 mismatch was BG1 scroll changed by HDMA during the original). WMADD (WRAM port address) is now compared for every port; port_set_wram_port for InitMaskHDMAData.
  • portbridge.py: --set NZ=.
  • re/known-bugs.toml (#40): format in its header; UpdateMosaic 16-bit clear of the restore request, BGColorUnDec carry.

Validation

  • Shadow, 5 routes, 21 ports: US 606 420 calls, JP 557 490, 0 mismatch, 0 fallback; every movie matches its end hashes.
  • Fuzz (field_menu_tour state, 120 iterations/version, pokes of animation, window, wavy, shake, map update, scroll speed, overlay states): 91 298 US / 91 322 JP calls, 0 mismatch, 0 fallback. Callee alone (_c0249a, 60 it.): 1 mismatch/version, WRAM $7E:0004 (pad_raw) written by a FieldNMI that interrupted the original mid-call; _c0249a never accesses it (shadow skips only calls crossing a frame count, not an NMI: tool limit, to be filed as an issue with the math unit note below).
  • Original instructions executed (routes + fuzz): 2070/2070 US, 2070/2070 JP.
  • portstyle 0 findings; debug and clang builds 0 warnings, ctest -LE slow 27/27 each.

Skipped

  • MoveObjs: V and $1A left by its UpdateObjFrame callee per object path; needs the callee's bridge logic shared.
  • _c0714a, LoadLetterGfx, UpdateDlgWindow, UpdateSpotlights, CheckCollosions (registers X/Y/C/V live over many exits): large or scratch-heavy, next batch.
  • TfrDlgTextGfx, TfrDlgCursorGfx, ClearDlgTextRegion: write the DMA indirect bank ($4307) where the other field VRAM uploads do not: needs a second upload style chosen without the game naming it.
  • DrawTimer: uses the hardware divider, whose state shadow does not compare (UpdatePalAnimPulse's port already leaves the multiplier different: noted).
  • CalcTextWidth: US only (not in JP).
  • Frame-crossing routines not attempted (#37).
Merged in PR #57. Field batch 3 (refs #56, fixes #56, fixes #40): 21 field routines ported with the tools (draftc -> port -> portbridge.py bridge and row -> shadow + fuzz). Ported: TfrBGAnimGfx, TfrBG3AnimGfx, TfrObjGfxSub, SetWindowSelect, InitBG1VScroll, InitBG2VScroll, UpdateBG1VScroll, UpdateBG2VScroll, UpdateBG1HScroll, UpdateBG2HScroll, UpdateBG3HScroll, UpdateBG1, UpdateBG2, UpdateBG3, _c0249a, UpdateScrollHDMA, InitMaskHDMAData, InitSpriteMSB, BGColorDec, BGColorUnDec, DrawOverlaySprites. Game code 1138 -> 1852 lines (new `field_anim.c`, `field_tilemap.c`: the 11 tilemap routines share one layer-parametrised drawer). Platform and tools - `video.h`: `vid_begin_tile_uploads`, `vid_set_tile_destination`, `vid_upload_tiles` (VRAM; destination written once so the read latch matches), `vid_force_blank`, `vid_stop_line_effects`, `vid_set_window_layers`, `vid_set_layer_scroll` (docs/platform.md). - Game data as DMA source: `res_at` (pointer from game data -> resource bytes), `res_rom_offset` (backend: resource bytes -> cartridge address); new blob resources map_anim_gfx, map_sprite_gfx, map_sprite_gfx_ptrs/banks, map_sprite_tile_offsets. - SetWindowSelect: `PORT_WRITES_PPU_WINDOWS` compares only W12SEL-WOBJSEL (the batch 2 mismatch was BG1 scroll changed by HDMA during the original). WMADD (WRAM port address) is now compared for every port; `port_set_wram_port` for InitMaskHDMAData. - portbridge.py: `--set NZ=`. - `re/known-bugs.toml` (#40): format in its header; UpdateMosaic 16-bit clear of the restore request, BGColorUnDec carry. Validation - Shadow, 5 routes, 21 ports: US 606 420 calls, JP 557 490, 0 mismatch, 0 fallback; every movie matches its end hashes. - Fuzz (field_menu_tour state, 120 iterations/version, pokes of animation, window, wavy, shake, map update, scroll speed, overlay states): 91 298 US / 91 322 JP calls, 0 mismatch, 0 fallback. Callee alone (_c0249a, 60 it.): 1 mismatch/version, WRAM $7E:0004 (pad_raw) written by a FieldNMI that interrupted the original mid-call; _c0249a never accesses it (shadow skips only calls crossing a frame count, not an NMI: tool limit, to be filed as an issue with the math unit note below). - Original instructions executed (routes + fuzz): 2070/2070 US, 2070/2070 JP. - portstyle 0 findings; debug and clang builds 0 warnings, `ctest -LE slow` 27/27 each. Skipped - MoveObjs: V and $1A left by its UpdateObjFrame callee per object path; needs the callee's bridge logic shared. - _c0714a, LoadLetterGfx, UpdateDlgWindow, UpdateSpotlights, CheckCollosions (registers X/Y/C/V live over many exits): large or scratch-heavy, next batch. - TfrDlgTextGfx, TfrDlgCursorGfx, ClearDlgTextRegion: write the DMA indirect bank ($4307) where the other field VRAM uploads do not: needs a second upload style chosen without the game naming it. - DrawTimer: uses the hardware divider, whose state shadow does not compare (UpdatePalAnimPulse's port already leaves the multiplier different: noted). - CalcTextWidth: US only (not in JP). - Frame-crossing routines not attempted (#37).
Sign in to join this conversation.
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#56
No description provided.