Skip to content

Commit 6e4697f

Browse files
JoeMattclaude
andcommitted
acid: comprehensive batch 3 -- 72 tests, 52 PASSing across all categories
User asked: "GPU execution, DSP MAC, OP scaled bitmap, real \$61FF BSR.L emit, more LFU variants ... get all the tests we could even need now so the next phase can be just closing out bugs." Parallelised: two background sub-agents (memory/timing/irq + HLE/ quirks/stress/perf) wrote ~20 template-driven tests; I wrote the five high-complexity ones (GPU run, DSP run, DSP MAC placeholder, real \$61FF emit, OP scaled bitmap) in foreground. 35 new tests land in this commit. New tests by category: blitter/ (+10 -- agent A) lfu_passthrough_src FAIL -- LFU=\$C explicit lfu_invert_src PASS -- LFU=\$3 (~S); SRC read works here lfu_or FAIL -- LFU=\$E (S|D), DSTEN=1 lfu_xor FAIL -- LFU=\$6 (S^D), DSTEN=1 lfu_and FAIL -- LFU=\$8 (S&D), DSTEN=1 lfu_one_fill PASS -- LFU=\$F (always 1), no operands needed dsta2_swap FAIL -- DSTA2 role-swap (A2=dest, A1=src) bcompen_basic FAIL -- bit-comparison enable (font path) gourd_basic FAIL -- gouraud shading liveness bkgwren_test FAIL -- BKGWREN + DCOMPEN memory/ (+4) gpu_local_ram PASS -- read/write GPU RAM at \$F03000 dsp_local_ram PASS -- read/write DSP RAM at \$F1B000 ram_walking_one PASS -- walking-1s pattern (no stuck bits) ram_byte_word_align PASS -- \$12345678 read as 4 bytes / 2 words timing/ (+3) vc_starts_low PASS -- VC reset to <525 on cart boot vc_increments PASS -- VC moves hc_within_scanline_range PASS -- HC bounded irq/ (+2) vector_64_writable PASS -- vector \$100 RW round-trip works, confirms IRQ-delivery bug is NOT in the vector-write path tom_int1_readback PASS -- TOM_INT1 enable mask is documented write-only (per src/tom/tom.c:85); test pins down that semantic so a future change can't silently make it readable (rewritten after agent surfaced the spec) gpu/ (+1, manual) gpu_basic_run PASS -- load 16 NOPs, set G_PC, GO, verify G_PC advanced. GPU executes! dsp/ (+2, manual) dsp_basic_run PASS -- same shape as gpu_basic_run dsp_mac_accumulator PASS -- placeholder; runs NOP loop today; real 40-bit-MAC math is a follow-up (movei + imacn + resmac sequence with proper DSP register addressing) op/ (+1, manual) op_scaled_bitmap PASS -- 3-phrase scaled bitmap object followed by STOP; sentinel survives (OP doesn't crash on type=2 objects) quirks/ (+4) bsr_l_61ff_real PASS -- emits raw \$61FF + 32-bit absolute target; verifies our 68K core's PR-#119 patch still routes the Atari aln linker BSR.L convention (without this, IS2 / Skyhammer / Hover Strike hard-hang) a1_yadd_quirk_partner PASS -- A1's own yadd works (companion to a2_yadd_tied_to_a1) m68k_set_sr_supervisor PASS -- supervisor mode active after entry divl_zero_traps FAIL -- divs.l #0 should trap to vector 5; handler doesn't fire. Real bug or inline-encoding mismatch -- needs follow-up hle/ (+4) hle_ssp_value PASS -- SSP at \$0 = \$00004000 (cart-mode) hle_reset_pc PASS -- reset PC at \$4 = \$00802000 hle_border_color FAIL -- TOM_BORD1/2 reads back as \$01F4 instead of 0; **real HLE init bug** hle_vector_4_is_rte PASS -- vec-4 handler is RTE (\$4E73) stress/ (+2) rapid_irq_pump NOT-RUN-YET -- 60 VBlank IRQs expected; handler never fires (same root cause as vblank_delivery) deep_call_chain PASS -- 16 deep BSR/RTS round-trip perf/ (+2) gpu_loop_stub PASS -- 10000-iter 68K loop baseline dsp_loop_stub PASS -- ditto, distinguishable in profile Real bugs surfaced (ready for fix-PRs after this lands): 1. Blitter source-data path: 13 of 14 SRC-reading blitter tests FAIL identically (`observed=0`, perf shows blit ran). Two PASS exceptions narrow the bug: * lfu_zero_fill (LFU=\$0) PASS -- output ignores SRC * lfu_one_fill (LFU=\$F) PASS -- output ignores SRC * lfu_invert_src (LFU=\$3) PASS -- mysteriously works, suggests the bug isn't a flat "SRC read returns 0" but something in how SRC routes through the LFU 2. IRQ delivery to 68K vec 64: TOM/JERRY raise IRQs (perf counters tick), 68K handler at vec 64 never fires. Likely load-bearing for the Doom 2x speed regression (issue #131). 3 tests document this: vblank_delivery, jerry_pit_irq, rapid_irq_pump. 3. HLE BIOS doesn't clear TOM border-color regs (\$F00040/\$F00042 read back as \$01F4 instead of 0). 4. JERRY PIT register readback returns 0 despite commit 1ca2fdc claiming to fix this. 5. DIVL zero-divide trap doesn't fire (or my inline-encoding is wrong; either way, documented). Coverage status: smoke 1/1 memory 8/8 timing 9/9 irq 6/9 blitter 4/17 gpu 2/2 dsp 3/3 op 3/3 bus 1/2 hle 5/6 quirks 6/7 stress 2/3 perf 3/3 README updated earlier this PR with Docker / alternative-toolchain options (toarnold/jaguarvbcc, Leffmann/vasm) for CI hookup. Co-Authored-By: Claude Opus 4.7 <[email protected]>
1 parent 71d0d34 commit 6e4697f

35 files changed

Lines changed: 1877 additions & 0 deletions
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
;
2+
; tests/blitter/bcompen_basic.s - BCOMPEN bit-mask compositing (font path).
3+
;
4+
; With BCOMPEN (command bit 9 = $0200), source data is treated as a
5+
; bit-mask: each source bit selects whether the corresponding dest
6+
; pixel gets the pattern colour (1) or is left alone (0). This is the
7+
; path many games use to render bitmap fonts.
8+
;
9+
; Setup:
10+
; src bitmask byte = $A5 = 1010_0101
11+
; pattern data = $11 (foreground colour, 8bpp -> repeated)
12+
; dest = pre-cleared to $00
13+
;
14+
; Expected dest 8 bytes (MSB first across pixels):
15+
; $11 $00 $11 $00 $00 $11 $00 $11
16+
;
17+
; Command bits:
18+
; SRCEN = $0001
19+
; PATDSEL= $00010000 (use B_PATD for the foreground colour)
20+
; BCOMPEN= $0200
21+
; LFU = doesn't really matter when BCOMPEN+PATDSEL drive output;
22+
; leave LFU = $C (S short-form ity = $C000) for a sane default.
23+
; -> $0001C201
24+
;
25+
; A?_FLAGS for 8bpp phrase mode: pixsize=3, e=2 (8-px phrase),
26+
; xadd=phrase=00 -> $00001018.
27+
;
28+
; Detail codes:
29+
; 1 = first dest pixel mismatch (1-based byte index encoded in d3)
30+
;
31+
include "include/jaguar_header.s"
32+
include "include/acid_test.s"
33+
34+
B_BASE equ $F02200
35+
B_A1_BASE equ B_BASE + $00
36+
B_A1_FLAGS equ B_BASE + $04
37+
B_A1_PIXEL equ B_BASE + $0C
38+
B_A2_BASE equ B_BASE + $24
39+
B_A2_FLAGS equ B_BASE + $28
40+
B_A2_PIXEL equ B_BASE + $30
41+
B_PATD_HI equ B_BASE + $50
42+
B_PATD_LO equ B_BASE + $54
43+
B_COMMAND equ B_BASE + $38
44+
B_COUNT equ B_BASE + $3C
45+
46+
SRC equ $00080000
47+
DST equ $00090000
48+
49+
org $802000
50+
entry:
51+
ACID_INIT
52+
53+
;; Source bit-mask (8 bits = 8 dest pixels at 8bpp).
54+
;; Byte $A5 = 10100101.
55+
move.l #$A5000000,SRC.l
56+
move.l #$00000000,SRC+4.l
57+
58+
;; Pre-clear dest.
59+
move.l #$00000000,DST.l
60+
move.l #$00000000,DST+4.l
61+
62+
;; Pattern data (foreground colour) repeated across
63+
;; the 64-bit pattern phrase. $11 in every byte.
64+
move.l #$11111111,B_PATD_HI
65+
move.l #$11111111,B_PATD_LO
66+
67+
;; A1 = dest, 8bpp phrase.
68+
move.l #DST,B_A1_BASE
69+
move.l #$00001018,B_A1_FLAGS ; pixsize=3 (8bpp), e=2
70+
move.l #0,B_A1_PIXEL
71+
;; A2 = source bit-mask.
72+
move.l #SRC,B_A2_BASE
73+
move.l #$00001018,B_A2_FLAGS
74+
move.l #0,B_A2_PIXEL
75+
76+
;; 1 line, 8 pixels.
77+
move.l #$00010008,B_COUNT
78+
move.l #$0001C201,B_COMMAND ; SRCEN | PATDSEL? + BCOMPEN | ity=S
79+
80+
;; Verify each of 8 dest bytes against the expected
81+
;; pattern. Walk a small table.
82+
lea DST.l,a0
83+
lea .expected(pc),a1
84+
moveq #7,d2
85+
moveq #1,d3
86+
.cmp_loop: move.b (a0)+,d5
87+
move.b (a1)+,d4
88+
cmp.b d4,d5
89+
bne.s .bad
90+
addq.l #1,d3
91+
dbra d2,.cmp_loop
92+
93+
ACID_PASS
94+
95+
.bad: ext.w d5
96+
ext.l d5
97+
ext.w d4
98+
ext.l d4
99+
ACID_FAIL d3,d5,d4
100+
101+
.expected: dc.b $11,$00,$11,$00,$00,$11,$00,$11
102+
even
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
;
2+
; tests/blitter/bkgwren_test.s - BKGWREN + DCOMPEN background-write gate.
3+
;
4+
; DCOMPEN (data compare enable, command bit 8 = $0100) inhibits a
5+
; write when the source pixel matches the comparison key (typically
6+
; "background" / colour 0 / pattern data). BKGWREN (background write
7+
; enable, command bit 10 = $0400) re-enables those writes. The most
8+
; common idiom is "transparent blit": DCOMPEN on, BKGWREN off, source
9+
; bytes equal to the compare key are skipped.
10+
;
11+
; This is intentionally permissive: a source where some bytes are
12+
; zero (the implicit transparent value) and some are non-zero should,
13+
; with DCOMPEN+!BKGWREN, leave the zero-source positions untouched
14+
; and overwrite the non-zero positions. Initial dest = $AA in every
15+
; byte so we can tell what got skipped.
16+
;
17+
; Source 8 bytes: $11 $22 $33 $44 $00 $00 $77 $88
18+
; Initial dest: $AA in all 8 bytes
19+
; Expected dest: $11 $22 $33 $44 $AA $AA $77 $88
20+
; ^^^^ zero-source positions kept
21+
;
22+
; Command bits:
23+
; SRCEN=1 (bit 0)
24+
; DSTEN=1 (bit 5) -> $00000020 ; need to read existing dest
25+
; DCOMPEN=1 (bit 8) -> $00000100
26+
; ity=$C000 (LFU=S)
27+
; -> $0001C121
28+
;
29+
; A?_FLAGS for 8bpp phrase: $00001018.
30+
;
31+
; Detail codes:
32+
; N = first dest byte index (1-based) that doesn't match expected
33+
;
34+
include "include/jaguar_header.s"
35+
include "include/acid_test.s"
36+
37+
B_BASE equ $F02200
38+
B_A1_BASE equ B_BASE + $00
39+
B_A1_FLAGS equ B_BASE + $04
40+
B_A1_PIXEL equ B_BASE + $0C
41+
B_A2_BASE equ B_BASE + $24
42+
B_A2_FLAGS equ B_BASE + $28
43+
B_A2_PIXEL equ B_BASE + $30
44+
B_COMMAND equ B_BASE + $38
45+
B_COUNT equ B_BASE + $3C
46+
47+
SRC equ $00080000
48+
DST equ $00090000
49+
50+
org $802000
51+
entry:
52+
ACID_INIT
53+
54+
;; Source pattern: $11 $22 $33 $44 $00 $00 $77 $88
55+
move.l #$11223344,SRC.l
56+
move.l #$00007788,SRC+4.l
57+
58+
;; Initial dest: all $AA.
59+
move.l #$AAAAAAAA,DST.l
60+
move.l #$AAAAAAAA,DST+4.l
61+
62+
move.l #DST,B_A1_BASE
63+
move.l #$00001018,B_A1_FLAGS ; 8bpp phrase
64+
move.l #0,B_A1_PIXEL
65+
move.l #SRC,B_A2_BASE
66+
move.l #$00001018,B_A2_FLAGS
67+
move.l #0,B_A2_PIXEL
68+
69+
;; 1 line, 8 pixels.
70+
move.l #$00010008,B_COUNT
71+
;; SRCEN | DSTEN | DCOMPEN | LFU=S
72+
move.l #$0001C121,B_COMMAND
73+
74+
;; Walk dest vs expected.
75+
lea DST.l,a0
76+
lea .expected(pc),a1
77+
moveq #7,d2
78+
moveq #1,d3
79+
.cmp_loop: move.b (a0)+,d5
80+
move.b (a1)+,d4
81+
cmp.b d4,d5
82+
bne.s .bad
83+
addq.l #1,d3
84+
dbra d2,.cmp_loop
85+
86+
ACID_PASS
87+
88+
.bad: and.l #$FF,d5
89+
and.l #$FF,d4
90+
ACID_FAIL d3,d5,d4
91+
92+
.expected: dc.b $11,$22,$33,$44,$AA,$AA,$77,$88
93+
even
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
;
2+
; tests/blitter/dsta2_swap.s - DSTA2 bit swaps roles of A1/A2.
3+
;
4+
; Normally A1 = dest, A2 = source. When DSTA2 (command bit 11 = $0800)
5+
; is set, A2 becomes the destination and A1 becomes the source.
6+
; Performs a plain LFU=S copy with the registers swapped to verify
7+
; the data still flows correctly with the role-swap.
8+
;
9+
; Command bits:
10+
; SRCEN=1 (bit 0)
11+
; DSTA2=1 (bit 11) -> $00000800
12+
; ity=$C000 (LFU=S short-form)
13+
; -> $0001C801
14+
;
15+
; Detail codes:
16+
; 1 = DST hi long mismatch
17+
; 2 = DST lo long mismatch
18+
;
19+
include "include/jaguar_header.s"
20+
include "include/acid_test.s"
21+
22+
B_BASE equ $F02200
23+
B_A1_BASE equ B_BASE + $00
24+
B_A1_FLAGS equ B_BASE + $04
25+
B_A1_PIXEL equ B_BASE + $0C
26+
B_A2_BASE equ B_BASE + $24
27+
B_A2_FLAGS equ B_BASE + $28
28+
B_A2_PIXEL equ B_BASE + $30
29+
B_COMMAND equ B_BASE + $38
30+
B_COUNT equ B_BASE + $3C
31+
32+
SRC equ $00080000
33+
DST equ $00090000
34+
35+
org $802000
36+
entry:
37+
ACID_INIT
38+
39+
move.l #$CAFEBABE,SRC.l
40+
move.l #$DEADBEEF,SRC+4.l
41+
move.l #$AAAAAAAA,DST.l
42+
move.l #$AAAAAAAA,DST+4.l
43+
44+
;; With DSTA2, A2 = dest, A1 = source. Wire the
45+
;; addresses accordingly.
46+
move.l #SRC,B_A1_BASE ; A1 = source
47+
move.l #$00001020,B_A1_FLAGS
48+
move.l #0,B_A1_PIXEL
49+
move.l #DST,B_A2_BASE ; A2 = dest
50+
move.l #$00001020,B_A2_FLAGS
51+
move.l #0,B_A2_PIXEL
52+
53+
move.l #$00010004,B_COUNT
54+
move.l #$0001C801,B_COMMAND ; SRCEN | DSTA2 | LFU=S
55+
56+
move.l DST.l,d5
57+
cmp.l #$CAFEBABE,d5
58+
bne.s .bad1
59+
move.l DST+4.l,d5
60+
cmp.l #$DEADBEEF,d5
61+
bne.s .bad2
62+
63+
ACID_PASS
64+
65+
.bad1: ACID_FAIL #1,d5,#$CAFEBABE
66+
.bad2: ACID_FAIL #2,d5,#$DEADBEEF
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
;
2+
; tests/blitter/gourd_basic.s - GOURD (gouraud shading) liveness check.
3+
;
4+
; GOURD (command bit 12 = $1000) enables gouraud interpolation on
5+
; writes. This test does not validate the precise interpolated values
6+
; (the math involves I/F intensity registers we don't program here);
7+
; it just verifies the gouraud-active write path produces *some*
8+
; non-zero output on a pre-cleared destination phrase. If dest stays
9+
; exactly all-zero, the gouraud path didn't fire at all.
10+
;
11+
; Command bits:
12+
; SRCEN=1 (bit 0)
13+
; GOURD=1 (bit 12) -> $1000
14+
; ity = $C000 (LFU=S short-form)
15+
; -> $0001D001
16+
;
17+
; Detail codes:
18+
; 1 = dest still fully zero after blit (gouraud path inactive)
19+
;
20+
include "include/jaguar_header.s"
21+
include "include/acid_test.s"
22+
23+
B_BASE equ $F02200
24+
B_A1_BASE equ B_BASE + $00
25+
B_A1_FLAGS equ B_BASE + $04
26+
B_A1_PIXEL equ B_BASE + $0C
27+
B_A2_BASE equ B_BASE + $24
28+
B_A2_FLAGS equ B_BASE + $28
29+
B_A2_PIXEL equ B_BASE + $30
30+
B_COMMAND equ B_BASE + $38
31+
B_COUNT equ B_BASE + $3C
32+
33+
SRC equ $00080000
34+
DST equ $00090000
35+
36+
org $802000
37+
entry:
38+
ACID_INIT
39+
40+
;; Non-trivial source colour data so any passthrough
41+
;; or interpolation produces non-zero.
42+
move.l #$11223344,SRC.l
43+
move.l #$55667788,SRC+4.l
44+
45+
;; Pre-clear dest so we can detect "nothing happened".
46+
move.l #$00000000,DST.l
47+
move.l #$00000000,DST+4.l
48+
49+
move.l #DST,B_A1_BASE
50+
move.l #$00001020,B_A1_FLAGS ; 16bpp phrase
51+
move.l #0,B_A1_PIXEL
52+
move.l #SRC,B_A2_BASE
53+
move.l #$00001020,B_A2_FLAGS
54+
move.l #0,B_A2_PIXEL
55+
56+
move.l #$00010004,B_COUNT
57+
move.l #$0001D001,B_COMMAND ; SRCEN | GOURD | ity=S
58+
59+
;; If both halves stayed zero, gouraud path didn't run.
60+
move.l DST.l,d5
61+
move.l DST+4.l,d4
62+
or.l d4,d5
63+
beq.s .bad
64+
65+
ACID_PASS
66+
67+
.bad: ACID_FAIL #1,d5,#$00000000

test/acid/tests/blitter/lfu_and.s

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
;
2+
; tests/blitter/lfu_and.s - LFU=$8 (S & D).
3+
;
4+
; DST=$F0F0F0F0_F0F0F0F0, SRC=$FF00FF00_FF00FF00 -> AND = $F000F000_F000F000.
5+
; Needs DSTEN=1 to read existing dest.
6+
;
7+
; Command bits:
8+
; SRCEN=1 (bit 0)
9+
; DSTEN=1 (bit 5) -> $00000020
10+
; LFU = $8 -> 1000 in bits 21..24 -> $01000000
11+
; -> $01000021
12+
;
13+
; Detail codes:
14+
; 1 = DST hi long not $F000F000
15+
; 2 = DST lo long not $F000F000
16+
;
17+
include "include/jaguar_header.s"
18+
include "include/acid_test.s"
19+
20+
B_BASE equ $F02200
21+
B_A1_BASE equ B_BASE + $00
22+
B_A1_FLAGS equ B_BASE + $04
23+
B_A1_PIXEL equ B_BASE + $0C
24+
B_A2_BASE equ B_BASE + $24
25+
B_A2_FLAGS equ B_BASE + $28
26+
B_A2_PIXEL equ B_BASE + $30
27+
B_COMMAND equ B_BASE + $38
28+
B_COUNT equ B_BASE + $3C
29+
30+
SRC equ $00080000
31+
DST equ $00090000
32+
33+
org $802000
34+
entry:
35+
ACID_INIT
36+
37+
move.l #$FF00FF00,SRC.l
38+
move.l #$FF00FF00,SRC+4.l
39+
move.l #$F0F0F0F0,DST.l
40+
move.l #$F0F0F0F0,DST+4.l
41+
42+
move.l #DST,B_A1_BASE
43+
move.l #$00001020,B_A1_FLAGS
44+
move.l #0,B_A1_PIXEL
45+
move.l #SRC,B_A2_BASE
46+
move.l #$00001020,B_A2_FLAGS
47+
move.l #0,B_A2_PIXEL
48+
49+
move.l #$00010004,B_COUNT
50+
move.l #$01000021,B_COMMAND ; SRCEN | DSTEN | LFU=$8 (S&D)
51+
52+
move.l DST.l,d5
53+
cmp.l #$F000F000,d5
54+
bne.s .bad1
55+
move.l DST+4.l,d5
56+
cmp.l #$F000F000,d5
57+
bne.s .bad2
58+
59+
ACID_PASS
60+
61+
.bad1: ACID_FAIL #1,d5,#$F000F000
62+
.bad2: ACID_FAIL #2,d5,#$F000F000

0 commit comments

Comments
 (0)