agnus: evaluate sprite DMA lines at both hardware slots#114
Merged
Conversation
Sprite N's line was captured in one shot at its second DMA slot; now the first slot ($15+4N) runs the line entry logic (vstop comparator, descriptor chain, arming) and samples the DATA word(s) at that slot's beam time, and the second slot ($17+4N) samples DATB at its own beam time and assembles the display line. Chip RAM rewritten between the two slots is therefore seen by DATB but not DATA, and a mid-line DMACON SPREN edge fetches exactly one word of the pair, matching the real bus timing. A skipped slot leaves SPRxPT one fetch behind the line-derived stream position; the display line reuses the stale latch on that side and a missed DATA slot never arms the sprite. The single-shot path remains for the pre-display replay wrapper and as the second-slot fallback when the first slot did not run. Stream re-seeds (descriptor reload, SPRxPT retarget) clear the pending state, and the per-line markers default to unset so a fresh state cannot false-match line 0. STATE_VERSION 17 (DisplaySpriteDmaState gained fields). Byte-identical on the demo regression set (Gen-X 110s/620s, ITM, Hamazing, Zool, Second Nature, Kickstart 1.3 and A1200 boots) vs main.
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.
Summary
Sprite DMA lines are now evaluated at both of their hardware bus slots
instead of once per pair: sprite N's first slot ($15+4N) runs the line
entry logic (vstop comparator, descriptor chain, arming) and samples the
DATA word(s) at that slot's beam time; the second slot ($17+4N) samples
DATB at its own beam time and assembles/emits the display line. SPREN is
still sampled per slot (from #110), so a mid-line DMACON edge between the
two slots fetches exactly one word of the pair, and chip RAM rewritten
between the slots is seen by DATB but not DATA -- matching the real bus
timing.
SpriteSlotPhase(Pair/Slot1/Slot2) threads through the formercaptured_sprite_line_with_slots: Slot1 stashes pending DATA words +line markers on
DisplaySpriteDmaState, Slot2 completes the line frompending state. The single-shot Pair path remains for the pre-display
replay wrapper and as the second-slot fallback when the first slot did
not run (SPREN low there, or the stream re-seeded between the slots).
position (
data_word_skew), so later fetches and the next descriptorfetch read from the hardware pointer's actual position; the display
line assembles from the stale latch on the skipped side, and a missed
DATA slot never arms the sprite.
Default-- a derivedzero default would false-match line 0), and stream re-seeds (descriptor
reload, SPRxPT retarget) clear the pending state.
DisplaySpriteDmaStategained fields).Scores
This is timing-correctness groundwork: the vAmigaTS
Agnus/Registers/DMACONsprena*/sprdis* family (29-43%) does notmove. Investigating that family against the real-A500 photos (which match
vAmiga exactly) showed its root cause is Copperline's descriptor-precompute
sprite model itself: hardware fetches POS/CTL on the vstop line through
these same two slots and runs the vertical comparators off Agnus register
copies, with the per-sprite DMA flip-flop cleared on the vstop line even
when SPREN is off. That register-level state machine is a follow-up
rework; this PR puts the per-slot evaluation points in place for it.
Testing
cargo testclean (~750 unit tests),cargo clippy/cargo fmtclean.sprite_dma_capture_samples_line_words_at_beam_time(RAM rewrittenbetween the two slots: DATA sees the pre-rewrite word, DATB the
post-rewrite word).
Gen-X 110s + 620s, Inside the Machine 25s, Hamazing 25s, A1200 Kickstart
25s, Zool 25s, Second Nature 40s -- all byte-identical.