blitter: narrow the BLTPRI BLS fence; denise: scroll-aware off-grid DDFSTRT placement#166
Merged
Conversation
The whole-blit BLS fence (BLTPRI holds the CPU off the chip bus until BLTDONE, bus-free micro-cycles included) fixed Jim Power's MFM-decode trackloader but overshot the hardware: line-heavy demo main loops lost the CPU time real Agnus leaves them in the line pipeline's bus-free Bresenham cycles. Rampage's vector parts run ~55 line blits per frame under BLTPRI; with 2 of the 4 cycles per pixel fenced off, the per-frame handler overran every 4th frame -- the "present" overlay vanished in a metronomic 4-frame flicker and the music tick dropped to 44-45 of 50 vblanks (~12% tempo slowdown). Neither vAmiga nor FS-UAE shows this: both arbitrate per slot and have no whole-blit fence (vAmiga's BUSIDLE and BLT_STRT micro-cycles never allocate the bus). With BLTPRI set, the CPU is now fenced only through the blit's warm-up: the startup ladder (register commit, BLT_STRT1/2, Init) and, for D-writing blits, the first word's body cycles including the empty first-D bubble, while the sequencer's bus request is held asserted by its queued back-to-back first fetches. That is all the trackloader ordering needs -- the restore write and its prefetches queue behind the fenced startup/first-D holes and land after the blit -- while primed bus-free micro-cycles (line Bresenham, fill idle, disabled-channel gaps) return to the CPU. Verified from save states on both regression titles: Jim Power loads level 1 (guru 00000003 with the holes open), and Rampage's frame cadence and music tick match the pre-fence run exactly. - bltpri_stalls_cpu_chip_access_through_blitter_access_cycles now encodes the trackloader property: the first-D bubble is denied and the CPU first wins the internal E cycle after BBUSY drops (4 cck). - blithog_set_blocks_cpu_slowdown_back_pressure_until_blitter_finishes returns to 14 cck: a source-only blit has no bus-free cycles, and the CPU rides the terminal E/F clocks as before. - New bltpri_line_blit_bresenham_cycles_stay_cpu_available_after_warmup guards the line-mode property. - timing-test golden row 26 re-blessed 25161 -> 25089 (0x6201), within 8 cck of the FS-UAE 25095 / vAmiga 25097 references (pre-fence was 25073/-22; the whole-blit fence read +66). Row 27 shifts a few cck as its poll-catch phase rides on row 26's completion position. - docs/internals/timing.md and timing-test/README.md updated to describe the warm-up fence.
… reload slot The FMODE=0 placement quantization (an off-grid fetch waits for the NEXT shifter reload slot) is only correct for BPLCON1 = 0. The playfield's scroll taps the shifter S pixels late, so when the scroll covers the fetch's phase lateness (phase * px-per-cck <= S, tie covers), the data catches its own floor slot and the picture sits one full gulp left of the rounded-up origin. vAmiga-verified with two new probes (timing-test/ddfprobe-phase.asm, ddfprobe-phase2.asm): copper re-anchors the same marker bitmap every line while walking (DDFSTRT, BPLCON1) per band. On A500_ECS_1MB, lo-res DDFSTRT $66 with scroll 15 sits exactly 1 lo-res px left of $68 with scroll 0, while $66 with scroll 0 rounds up to the $68 slot; on-grid starts never move, and the arosddf1 $3C photo case is unchanged. Copperline now matches vAmiga on every band of both probes. Regression example (bisected: PR #107 good, PR #109 first bad): the Rampage dot-cube part pans by walking DDFSTRT $66->$68->...->$6E against a BPLCON1 wrap $FF->$00, bitplane pointers on a constant ring stride. The unconditional round-up made the wrap frame not move, so the picture jumped ~16 lo-res px a few times a second; with the covered-phase advance the pan is smooth again (frame-centroid jump count back to the pre-#109 baseline from the same save state). Implementation: reload_advance_for_scroll / row_reload_advance extend the row's fetch span left by the largest per-playfield advance, and sample_delay_for_plane rebases each plane's (now signed) sample delay against it, so covered planes land one gulp early while uncovered planes and every scroll-0 row render bit-identically to before (no golden re-bless needed). Note OCS masks DDFSTRT to 4-cck resolution (0xFC) vs ECS 2-cck (0xFE), so the phase differs per Agnus revision.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two regression fixes for demo-scene display/timing behavior, both bisected from save states and verified against vAmiga/FS-UAE references.
1. BLTPRI BLS fence narrowed to the blit's warm-up window
PR #162's whole-blit BLS fence (BLTPRI holds the CPU off the chip bus until BLTDONE, bus-free micro-cycles included) fixed Jim Power's MFM-decode trackloader but overshot the hardware. Bisected from a save state: straight after the Rampage "present" scene, the overlay text vanished in a metronomic 4-frame flicker and the music tick dropped to 44-45 of 50 vblanks (~12% tempo slowdown). The scene runs ~55 line blits per frame under BLTPRI, and line mode leaves 2 of its 4 cycles per pixel bus-free (Bresenham cycles) -- CPU time the demo's frame handler depends on. Neither vAmiga nor FS-UAE shows the slowdown: both arbitrate per slot and have no whole-blit fence.
With BLTPRI set, the CPU is now fenced only through the blit's warm-up window: the startup ladder (register commit, BLT_STRT1/2, Init) and, for D-writing blits, the first word's body cycles including the empty first-D bubble. That is all the trackloader ordering needs -- the restore write and its prefetches queue behind the fenced startup/first-D holes and land after the blit -- while primed bus-free micro-cycles (line Bresenham, fill idle, disabled-channel gaps) return to the CPU.
Verification:
2. Scroll-aware FMODE=0 off-grid DDFSTRT placement
Bisected from a save state (PR #107 good, PR #109 first bad): Rampage's dot-cube part jumped ~16 lo-res px a few times a second instead of panning smoothly. The demo pans by walking DDFSTRT $66->$68->...->$6E against a BPLCON1 fine-scroll wrap $FF->$00 with the bitplane pointers on a constant ring stride; PR #109's unconditional round-up-to-reload-grid placement makes the wrap frame not move.
The hardware rule is scroll-aware, established with two new probes (
timing-test/ddfprobe-phase.asm,ddfprobe-phase2.asm: copper re-anchors the same marker bitmap every line while walking (DDFSTRT, BPLCON1) per band) run against vAmiga: an off-grid fetch whose phase lateness is covered by the playfield's BPLCON1 delay (lateness <= S) catches its own floor reload slot, one full gulp left of the rounded-up origin. vAmiga: ($66, S=15) sits exactly 1 lo-res px left of ($68, S=0) -- the smooth pair -- while ($66, S=0) rounds up, on-grid starts never move, and the arosddf1 $3C photo case is unchanged. Copperline now matches vAmiga on every band of both probes.Implementation (
src/video/bitplane.rs):reload_advance_for_scroll/row_reload_advanceextend the row's fetch span left by the largest per-playfield advance;sample_delay_for_planerebases each plane's (now signed) sample delay against it. Scroll-0 rendering is bit-identical by construction: no golden re-bless needed.Verification:
Full
cargo test --release(unit + golden probe suite),cargo clippy,cargo fmt --checkclean on both commits.