Skip to content

denise: correct out-of-range BPLCON0/BPLCON2 mode and priority decoding#117

Merged
LinuxJedi merged 3 commits into
mainfrom
fix/denise-ham-dualplayfield-invalid
Jul 5, 2026
Merged

denise: correct out-of-range BPLCON0/BPLCON2 mode and priority decoding#117
LinuxJedi merged 3 commits into
mainfrom
fix/denise-ham-dualplayfield-invalid

Conversation

@LinuxJedi

@LinuxJedi LinuxJedi commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Three closely-related fixes for how Denise decodes invalid BPLCON0 /
BPLCON2 programming (modes and priority codes that no real software uses).
Each is gated on its invalid condition, so every valid mode renders
byte-identically -- verified against main on phooey (OCS), TurboTomato
(OCS), Roots (ECS), Roots (AGA) and Zool (AGA, dual playfield).

Fixes

  1. Invalid HAM + dual-playfield combination. With both BPLCON0 bits set,
    Denise resolves the dual-playfield colour index and then runs it through
    HAM: the HAM control code comes from the raw plane 5/6 bits, the value
    nibble from the resolved index. Copperline previously took the HAM-only
    path and ignored the dual-playfield bit. (vAmiga translateDPF +
    colorizeHAM.)

  2. Out-of-range dual-playfield priority. A dual-playfield field whose
    BPLCON2 priority code is 5-7 is drawn transparent -- the winning field
    collapses to the background instead of revealing the field behind.
    (vAmiga zPF returns 0 for codes 5-7.)

  3. Out-of-range single-playfield priority. A single playfield with an
    out-of-range PF2 priority code keeps only bitplanes 5-6 wherever bitplane
    5 is set, eliminating the four low planes, at background sprite priority.
    (vAmiga translateSPF.)

Accuracy (vAmigaTS Denise/Registers, vs vAmiga 4.4 refs; no regressions)

case main this PR
BPLCON2 dualpf1-12 10-35% 0.0% (all exact)
BPLCON0 modes4 10.9% 0.0% (exact)
BPLCON0 invprio3 11.8% 2.4%
BPLCON0 invprio1 6.4% 2.4%
BPLCON0 invprio0 7.8% 3.3%
BPLCON0 modes3 / 3b / 3c ~8.0% 4.0%
BPLCON0 block3 / block3m 3.5 / 2.1% 1.0 / 1.3%

The dual-playfield priority handling was substantially wrong on main
(the whole dualpf class); it is now pixel-exact against vAmiga.

Tests

cargo test green (1302 lib tests; adds three targeted tests);
cargo clippy and cargo fmt --check clean. Pure rendering change, no
serialized-state change (STATE_VERSION unchanged).

LinuxJedi added 2 commits July 4, 2026 22:38
…layfield combo

When BPLCON0 sets both the HAM and dual-playfield bits (an invalid
combination no real software uses), Denise resolves the dual-playfield
colour index and then runs it through the HAM logic: the HAM control code
still comes from the raw plane 5/6 bits, but the value nibble (and the
'set' palette index) is the dual-playfield-resolved index rather than the
raw plane bits. This mirrors vAmiga (translateDPF writes the resolved
index into mBuffer, colorizeHAM reads the control from the raw bitplane
bits) and the real-A500 photo.

Copperline previously took the HAM-only path and ignored the dual-playfield
bit for these pixels. The change is gated on both bits being set, so every
valid mode renders byte-identically.

vAmigaTS Denise/BPLCON0/modes4 10.9% -> 0.0%; invprio/modes3 improved.
…rent

A dual-playfield field whose BPLCON2 priority code is programmed out of
range (5-7) is drawn transparent: the winning field's pixels collapse to
the background rather than revealing the field behind it. This mirrors
vAmiga (zPF returns 0 for codes 5-7, masking that field's index to 0) and
the real-A500 photo.

Gated on the priority code being > 4, so valid dual-playfield content
(codes 0-4) is byte-identical. Combined with the HAM+dual-playfield fix
this resolves the vAmigaTS invprio cases, which set both an invalid
priority and the invalid HAM+dual-playfield mode: invprio3 11.8% -> 2.4%,
invprio1 6.4% -> 2.4%.
@LinuxJedi LinuxJedi changed the title denise: correct the invalid HAM + dual-playfield combo denise: correct invalid HAM+dual-playfield and out-of-range dual-playfield priority Jul 4, 2026
…ority

A single playfield whose BPLCON2 PF2 priority code is programmed out of
range (5-7) keeps only bitplanes 5-6 wherever bitplane 5 is set --
eliminating the four low bitplanes -- and draws the pixel at background
sprite priority. This mirrors vAmiga translateSPF (the quirk does not apply
in HAM mode, which is handled separately).

Gated on the priority code being > 4, so valid single-playfield content
(codes 0-4) is byte-identical. vAmigaTS Denise/BPLCON0/invprio0 7.8% ->
3.3%.
@LinuxJedi LinuxJedi changed the title denise: correct invalid HAM+dual-playfield and out-of-range dual-playfield priority denise: correct out-of-range BPLCON0/BPLCON2 mode and priority decoding Jul 4, 2026
@LinuxJedi LinuxJedi merged commit 629e5e9 into main Jul 5, 2026
8 checks passed
@LinuxJedi LinuxJedi deleted the fix/denise-ham-dualplayfield-invalid branch July 5, 2026 05:13
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