Skip to content

denise: fold wide-FMODE scroll taps into the early masked fetch start#250

Merged
LinuxJedi merged 2 commits into
mainfrom
fix/aga-wide-fmode-scroll-fold
Jul 22, 2026
Merged

denise: fold wide-FMODE scroll taps into the early masked fetch start#250
LinuxJedi merged 2 commits into
mainfrom
fix/aga-wide-fmode-scroll-fold

Conversation

@LinuxJedi

Copy link
Copy Markdown
Owner

Summary

Fixes #248 (Alien Breed II AGA horizontal scroll jumping). Not a regression: the same displacement reproduces on v0.11.0, v0.12.0, and current main - a long-standing gap in the AGA wide-FMODE scroll model that no previously calibrated title exercised.

Hardware rule: Agnus masks an off-grid DDFSTRT down to the fetch-unit grid on wide FMODE fetches, so the data arrives early relative to the programmed start. Denise's reload comparator window is anchored at that early fetch start, so BPLCON1 scroll taps in the last earliness px of the gulp window already see the next gulp's data and the playfield sits one full gulp left: display delay = ((tap + earliness) mod gulp) - earliness. This is the wide-FMODE mirror of the vAmiga-verified FMODE=0 covered-scroll rule (PR #166), with the opposite sense: FMODE=0 placement rounds up (late data, covering scroll catches the floor slot), wide-FMODE placement rounds down. On-grid starts and scroll 0 never fold, so every calibrated case is unchanged by construction.

The failing constellation: AB2 AGA runs lo-res 6-plane, FMODE $0005 (32-bit fetches, 32 px gulps), DDFSTRT $24 (4 cck off the 16-cck unit grid, earliness 8 px), DIW $7B..$1C5. Its scroller walks the extended BPLCON1 through raw 1..15 and 49..63, pairing the folded taps (25..31) with a one-gulp pointer step. Without the fold, the playfield renders 32 px right for exactly 4 of every 16 pan frames (the copper-split HUD strips stay put), which is the jump in the issue video.

Verification

  • 250-frame headless dumps of the reporter scenario (walk left, and right+down) are now smooth: every frame delta is +-2 lo-res px or 0; before, +-32 px excursions every 16 frames.
  • New golden probe ddfprobe-agafold (16 bands of tap x pointer-offset pairs on the title's exact constellation): FS-UAE renders the band map identically, band by band (relative positions 0,+2,+4,+16,-44,-40,-32,-28,-108,-104,-96,-92,-64,-60,-172,-156), corroborating the rule and the fold boundary on the WinUAE core. vAmiga is OCS/ECS-only and cannot arbitrate AGA.
  • Unit test wide_fmode_scroll_folds_into_the_early_masked_fetch_start pins the fold, the boundary, and the on-grid identity.
  • Full suite green: 1718 unit tests; all 20 pre-existing golden probes pass without re-blessing (the branch only runs with FMODE != 0, so OCS/ECS output is byte-identical).
  • A1200 Workbench 3.1, CD32 boot, Roots II AGA, and Zool screenshots byte-identical to an unmodified main build (RTC pinned).
  • cargo clippy and cargo fmt --check clean.

The golden harness gains an A1200/AGA machine shape (68020, 2M chip, AGA) to boot the probe. Remaining TODO noted in the code: the fold's hi-res/SHRES scaling is unverified (the probe covers the lo-res BPL32 case).

Agnus masks an off-grid DDFSTRT down to the fetch-unit grid on wide
FMODE fetches, so the data arrives early relative to the programmed
start. Denise's reload comparator window is anchored at that early
fetch start, so BPLCON1 scroll taps in the last earliness pixels of the
gulp window already see the next gulp's data and the playfield sits one
full gulp left: the display delay is
((tap + earliness) mod gulp) - earliness. On-grid starts and scroll 0
never fold, leaving every previously calibrated case unchanged. The new
branch mirrors the FMODE=0 covered-scroll rule with the opposite sense:
an FMODE=0 placement rounds up (late data, a covering scroll catches
the floor slot), a wide-FMODE placement rounds down.

Regression example (issue #248): Alien Breed II AGA's playfield
(lo-res, FMODE BPL32, DDFSTRT $24 -> earliness 8 px) scrolls with the
folded taps 25..31 paired against a one-gulp bitplane-pointer step;
without the fold the pan jumps 32 pixels for 4 of every 16 frames while
the copper-split HUD strips stay put.

Pinned by a scroll-fold unit test and the new ddfprobe-agafold golden
probe (16 bands of tap x pointer-offset pairs on the title's exact
constellation), which FS-UAE renders identically band by band; the
golden harness gains an A1200/AGA machine shape to boot it. vAmiga is
OCS/ECS-only and cannot arbitrate AGA; the fold's hi-res/SHRES scaling
remains unverified.
Copilot AI review requested due to automatic review settings July 22, 2026 07:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes AGA wide-FMODE horizontal-scroll “jumping” (Issue #248) by modeling how off-grid DDFSTRT is effectively masked down to the wide fetch-unit grid, causing scroll taps near the end of the gulp window to fold into the next gulp’s data (a wide-FMODE counterpart to the prior FMODE=0 covered-scroll placement work in PR #166).

Changes:

  • Adjust Denise/bitplane reload-advance logic to account for wide-FMODE off-grid DDFSTRT scroll folding into the early masked fetch start.
  • Add regression coverage via a new AGA golden probe (ddfprobe-agafold) and a targeted unit test pinning the fold boundary/identity cases.
  • Update internal documentation and timing-test probe suite docs to describe the new modeled rule and probe coverage.

Reviewed changes

Copilot reviewed 6 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/video/bitplane.rs Implements wide-FMODE scroll fold behavior in reload_advance_for_scroll.
src/video/bitplane/tests.rs Adds a unit test covering the AGA wide-FMODE fold boundary and on-grid identity.
tests/probe_golden.rs Extends golden harness with an AGA machine shape and registers the new probe.
timing-test/ddfprobe-agafold.asm New probe program exercising the Alien Breed II AGA constellation and fold boundary.
timing-test/README.md Documents the added probe and updates probe-suite count.
docs/internals/video.md Documents the wide-FMODE off-grid DDFSTRT + scroll fold rule and its verification basis.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/probe_golden.rs Outdated
The Machine::Aga doc comment promises the A1200 shape, whose CPU is the
24-bit 68EC020, but the generated config asked for a full 68020. The
probe never leaves chip RAM, so the blessed golden render is unchanged;
the machine shape now matches the documentation and the reported
configuration of the issue #248 title.
@LinuxJedi
LinuxJedi merged commit 405ff02 into main Jul 22, 2026
14 checks passed
@LinuxJedi
LinuxJedi deleted the fix/aga-wide-fmode-scroll-fold branch July 22, 2026 07:56
@hobbo91

hobbo91 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Alien Breed II (AGA) - Horizontal scrolling issue

3 participants