Skip to content

paula: defer AUDxEN disable to the word boundary (fixes #74 regression)#151

Merged
LinuxJedi merged 1 commit into
mainfrom
fix/issue-74-audxen-disable-hrm-regression
Jul 7, 2026
Merged

paula: defer AUDxEN disable to the word boundary (fixes #74 regression)#151
LinuxJedi merged 1 commit into
mainfrom
fix/issue-74-audxen-disable-hrm-regression

Conversation

@LinuxJedi

Copy link
Copy Markdown
Owner

Summary

The Paula HRM audio-FSM rework (#134) reverted the original issue #74 fix (#77 / a4277ed). Its apply_audio_dmacon_edges idled an outputting channel immediately on the AUDxEN falling edge, then ran a fresh 000 -> 001 start-up on re-enable. That turns a clear/set pulse shorter than the current DMA word into a clean restart from AUDxLC, which is audibly wrong on 2c1.adf.

Real Paula never samples the clear at the DMACON write; it only re-evaluates AUDxON at the word-start boundary. The 011 period event in advance_audio_channels already models that ((AUDxON || !AUDxIP) ? move_011_010 : idle), so the edge handler must leave the output states 010/011 alone and idle only the DMA start-up states 001/101 (which have not begun output; a posted DMA request still survives to free-run them). vAmiga's synchronous disableDMA() idles immediately here and gets this case wrong too, which is why it plays 2c1.adf less accurately than Copperline.

No serialized AudChannel field changed, so STATE_VERSION is untouched (unlike the original fix, which added a dma_disable_pending flag).

Changes

  • src/chipset/paula.rs: on the AUDxEN falling edge, idle only 001/101; leave 010/011 to the natural word-boundary handling.
  • Restore/added regression tests: audio_dma_disable_reenabled_before_word_boundary_is_missed (the issue [Bug]: Paula state machine incorrect #74 case) and audio_dma_disable_left_off_idles_at_word_boundary_then_reenable_restarts; fixed two tests that had encoded the regressed immediate-idle behavior.
  • docs/internals/chipset.md: document the deferred/missed disable.

Verification

  • cargo test --lib: 1347 pass; cargo clippy and cargo fmt --check clean.
  • A/B WAV capture of 2c1.adf (this fix vs. a temporary rebuild with the old immediate-idle line): byte-identical up to t=6.00s, then diverges exactly at t=6.10s = frame 308, the precise frame where the DMACON trace shows write=0x0001 -> 0x07C0 (clear AUD0EN) immediately followed by write=0x8201 -> 0x07C1 (re-enable) within one frame. Nothing before that scene changed.

Fixes #74.

The HRM audio-FSM rework (PR #134) reverted the issue #74 fix: its
apply_audio_dmacon_edges idled an outputting channel immediately on the
AUDxEN falling edge, then ran a fresh 000->001 start-up on re-enable.
That turns a clear/set pulse shorter than the current DMA word into a
clean restart from AUDxLC, which is audibly wrong on 2c1.adf.

Real Paula never samples the clear at the DMACON write; it only
re-evaluates AUDxON at the word-start boundary. The 011 period event in
advance_audio_channels already models that (idle on AUDxON low AND AUDxIP
set), so the edge handler must leave the output states 010/011 alone and
idle only the DMA start-up states 001/101 (which have not begun output;
a posted request still survives to free-run them). vAmiga's synchronous
disableDMA() idles immediately here and gets this case wrong too.

No serialized field changed, so STATE_VERSION is untouched. Restore the
missed-clear and held-clear regression tests, and document the behavior
in docs/internals/chipset.md.
@LinuxJedi LinuxJedi merged commit 5b913af into main Jul 7, 2026
7 checks passed
@LinuxJedi LinuxJedi deleted the fix/issue-74-audxen-disable-hrm-regression branch July 7, 2026 10:35
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]: Paula state machine incorrect

1 participant