Skip to content

Hardware IRQ-delivery model (IPL pipe + sampling) and blitter startup cycles#125

Merged
LinuxJedi merged 1 commit into
mainfrom
fix/irq-ipl-pipe-and-blit-startup
Jul 6, 2026
Merged

Hardware IRQ-delivery model (IPL pipe + sampling) and blitter startup cycles#125
LinuxJedi merged 1 commit into
mainfrom
fix/irq-ipl-pipe-and-blit-startup

Conversation

@LinuxJedi

Copy link
Copy Markdown
Owner

Replaces the blanket 65-cck interrupt-recognition latency with the hardware mechanisms it approximated, and adds the blitter's missing startup cycles.

What

  • Paula IPL pipe (5 cck): a change to the enabled-pending interrupt set reaches the CPU's IPL pins through a short pipeline, not combinationally. COPPERLINE_IRQ_LATENCY_CCK now configures this pipe (0 disables it and the sampling delay below). INTREQR reads are never delayed.
  • 68000 IPL boundary sampling: the take-interrupt decision at an instruction boundary uses the level latched at the previous instruction's last bus access (CpuBus::sample_ipl). A level that rises during trailing internal cycles is recognised one instruction later, as on silicon. STOP samples live.
  • Blitter startup (3 slots): normal blits now spend the BLTSIZE register-commit cycle plus the two BLT_STRT bus-arbitration cycles before the micro-program begins. Line blits untouched (their duration is calibrated against timing-test row 25).

Why

The 65-cck constant was calibrated against timing-test row 19 with a mis-decoded VHPOSR: the low byte is the beam position in colour clocks (H8..H1 of the 9-bit counter), not cck/2. Real raise-to-entry latency is ~52-61 cck, not ~114-122, so the blanket delivered every interrupt ~50 cck late - the dominant cause of the vAmigaTS cputim/irqtim divergence.

Verified against vAmiga (v4.4 headless) with a beam-position probe across seven IRQ-source x CPU-loop geometries plus a BLTSIZE-to-blitter-IRQ chain measurement, and against the vAmigaTS real-A500 photos.

Results

case before after
Agnus/Blitter/cputim1 79.3% 2.8%
Agnus/Blitter/irqtim1 24.1% 7.9%
Agnus/Blitter/dmacon/dmaoff1 47.6% 6.9%
Agnus/Blitter/dmacon9 37.4% 0.0%
Agnus/Blitter/bltint1 95.5% (emulated program crashed) 7.2%
Agnus/Blitter family (233 cases, summed) 3373% 1750%

bltint1 deliberately holds a garbage level-3 vector for a few cycles after starting a blit; correct blit-IRQ latency is what keeps real hardware out of that window.

Gates

  • 1304 unit tests green (new: irq_recognition_uses_previous_instruction_ipl_sample); clippy + fmt clean.
  • Demo screenshot set (phooey, tomato, roots-ecs, roots-aga, zool at 4s+8s) byte-identical.
  • timing-test rows unchanged except 19/20/22, which now match vAmiga's true beam positions.
  • STATE_VERSION 17 -> 18.

Known trade

eon's scene player returns to ~37% frame skips (was ~1% with the blanket): the removed constant was masking a real ~50 cck/frame CPU-budget deficit. Sensitivity is flat for honest pipe values (8/12 cck change nothing), so this needs its own investigation rather than a compensating constant; tracked in the vAmigaTS work list.

Replace the blanket 65-cck interrupt-recognition latency with the
hardware mechanisms it approximated:

- Paula pipelines the encoded interrupt level to the CPU's IPL pins
  over a few chip clocks; DEFAULT_IRQ_LATENCY_CCK becomes that pipe
  (5 cck: the ~4-cycle pin pipe plus the poked-INTREQ register-commit
  cycle). INTREQR reads are never delayed.
- The 68000 latches its IPL pins during bus cycles: the take-interrupt
  decision at an instruction boundary uses the level sampled at the
  previous instruction's last bus access (CpuBus::sample_ipl), so a
  level rising in an instruction's trailing internal cycles is taken
  one instruction later. A STOPped CPU samples live.
- Normal blits get three internal startup slots: the BLTSIZE register
  commit plus the two bus-arbitration startup cycles Agnus spends
  before the micro-program begins.

The 65-cck constant had been calibrated against timing-test row 19
with a mis-decoded VHPOSR: the low byte is the beam position in colour
clocks (H8..H1 of the 9-bit counter), not cck/2, so the real
raise-to-entry latency is ~52-61 cck, not ~114-122, and the blanket
made every interrupt ~50 cck late. Verified against vAmiga with a
beam-position probe across seven IRQ-source/CPU-loop geometries plus
a BLTSIZE-to-blitter-IRQ chain measurement, and against the vAmigaTS
real-A500 photos.

vAmigaTS: cputim1 79.3->2.8%, irqtim1 24.1->7.9%, dmaoff1 47.6->6.9%,
dmacon9 37.4->0.0%, bltint1 95.5(emulated program crashed)->7.2%;
Agnus/Blitter family summed 3373->1750%. Demo screenshot set is
byte-identical. Known trade: eon's scene player returns to ~37% frame
skips (the removed constant was masking a real ~50 cck/frame CPU
budget deficit tracked separately).

Save states: STATE_VERSION 18 (blit state gains the startup counter).
@LinuxJedi LinuxJedi merged commit d335be5 into main Jul 6, 2026
7 checks passed
@LinuxJedi LinuxJedi deleted the fix/irq-ipl-pipe-and-blit-startup branch July 6, 2026 06:32
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.

1 participant