Skip to content

Commit 1950680

Browse files
JoeMattclaude
andcommitted
acid: bring up framework end-to-end (smoke test passes)
Brought up the toolkit on a real host and shook out three blockers during first integration: * Boot stub: I had originally placed a `jmp entry` at $800400 thinking the BIOS jumped through it. The actual contract is that the file loader reads the 32-bit cart entry address as raw bytes from $800404 (see src/core/file.c:140 -- jaguarRunAddress = GET32(jagMemSpace, 0x800404)) and HLE BIOS init writes that value to the 68K reset PC vector at $00000004 before m68k_pulse_reset(). Replaced the JMP with `dc.l entry` at $800404 and updated the header comments to match. * Signature address conflict: ACID_BASE was at $100, but HLE BIOS init fills the entire 68K exception vector table from $0..$3FF on cart boot, which clobbered our signature ($100 is vector 64, the IRQ vector that irq_ack_handler() returns for all hardware IRQs). Moved ACID_BASE to $100000 (1 MB into main RAM) -- well clear of vectors, BIOS workspace, cart-mode stack ($4000), and typical RAM-loaded executable region. Switched the macros from short- absolute (.w) to long-absolute (.l) addressing accordingly. * BIOS mode: runner was setting `virtualjaguar_bios = "enabled"` which selects the real BIOS path -- which performs cart authentication that synthetic test ROMs don't satisfy. Switched to "disabled" so the HLE-BIOS path runs, sets the 68K reset PC from our cart entry vector, and dumps the CPU straight into the test code. * ACID_FAIL macro: callers can now pass either immediate (#imm) or register (dN/aN) operands -- the macro forwards them to move.l directly instead of forcing immediate addressing. The original copy_simple test `ACID_FAIL d3,d5,d4` form now assembles cleanly. Added `tests/blitter/zzz_smoke.s`, the simplest possible test (just ACID_INIT + ACID_PASS), which now reports PASS through the runner. This proves the framework end-to-end: $ make all && ./acid_run ../../virtualjaguar_libretro.dylib \ tests/blitter/zzz_smoke.jag [PASS ] tests/blitter/zzz_smoke.jag The real `copy_simple.jag` blitter test still reports NOT-RUN-YET -- the test code itself is buggy (likely register offsets / command encoding) and crashes before reaching ACID_PASS / ACID_FAIL. That's a test-content issue, not a framework issue, and will be fixed in a follow-up alongside expanded blitter coverage. vasm 1.9 (prb28/vasm GitHub mirror) verified working on macOS arm64. Toolchain install instructions in test/acid/README.md will be updated in the next commit to point at that mirror, since the upstream sun.hasenbraten.de site has been intermittently unreachable. Co-Authored-By: Claude Opus 4.7 <[email protected]>
1 parent 872b16e commit 1950680

4 files changed

Lines changed: 81 additions & 46 deletions

File tree

test/acid/include/acid_test.s

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
;
22
; acid_test.s - pass/fail signature macros.
33
;
4-
; The host runner reads four 32-bit words at RAM offset $100..$10F:
4+
; The host runner reads four 32-bit words at RAM offset $100000..$10000F:
55
;
6-
; $100 ACID_RESULT $12345678 = pass
6+
; $100000 ACID_RESULT $12345678 = pass
77
; $DEADBEEF = fail
88
; $00000000 = not-yet-run
9-
; $104 ACID_DETAIL test-specific code
10-
; $108 ACID_OBSERVED value the test got
11-
; $10C ACID_EXPECTED value the test expected
9+
; $100004 ACID_DETAIL test-specific code
10+
; $100008 ACID_OBSERVED value the test got
11+
; $10000C ACID_EXPECTED value the test expected
1212
;
13+
; The signature lives at $100000 (1 MB into main RAM) to stay well
14+
; clear of:
15+
; $0..$3FF 68K exception vector table (filled by HLE BIOS init)
16+
; $400..$1FFF BIOS workspace + stack (cart-mode SSP=$4000 grows down)
17+
; $4000..$103FF typical RAM-loaded executable region
18+
; $802000+ cart code
1319

14-
ACID_BASE equ $100
20+
ACID_BASE equ $100000
1521
ACID_RESULT equ ACID_BASE+0
1622
ACID_DETAIL equ ACID_BASE+4
1723
ACID_OBSERVED equ ACID_BASE+8
@@ -26,28 +32,33 @@ ACID_FAIL_MAGIC equ $DEADBEEF
2632
;
2733
ACID_PASS macro
2834
move.l #ACID_PASS_MAGIC,d0
29-
move.l d0,ACID_RESULT.w
35+
move.l d0,ACID_RESULT.l
3036
bra.s .acid_halt\@
3137
.acid_halt\@: bra.s .acid_halt\@
3238
endm
3339

3440
;
3541
; ACID_FAIL - mark this test as failing and halt.
36-
; Args:
37-
; detail : 32-bit code (typically a sub-test ID)
38-
; observed: 32-bit value the test actually saw
39-
; expected: 32-bit value the test wanted
40-
; Clobbers d0/d1.
42+
; Args (any addressing mode that move.l accepts):
43+
; detail : 32-bit value -- include `#` for immediate, omit for register
44+
; observed : ditto
45+
; expected : ditto
46+
; Clobbers d0.
47+
;
48+
; Examples:
49+
; ACID_FAIL #5,#$DEAD,#$BEEF ; all immediates
50+
; ACID_FAIL d3,d5,d4 ; all from registers
51+
; ACID_FAIL #1,d2,#0 ; mixed
4152
;
4253
ACID_FAIL macro detail,observed,expected
43-
move.l #(\1),d0
44-
move.l d0,ACID_DETAIL.w
45-
move.l #(\2),d0
46-
move.l d0,ACID_OBSERVED.w
47-
move.l #(\3),d0
48-
move.l d0,ACID_EXPECTED.w
54+
move.l \1,d0
55+
move.l d0,ACID_DETAIL.l
56+
move.l \2,d0
57+
move.l d0,ACID_OBSERVED.l
58+
move.l \3,d0
59+
move.l d0,ACID_EXPECTED.l
4960
move.l #ACID_FAIL_MAGIC,d0
50-
move.l d0,ACID_RESULT.w
61+
move.l d0,ACID_RESULT.l
5162
bra.s .acid_halt\@
5263
.acid_halt\@: bra.s .acid_halt\@
5364
endm
@@ -58,7 +69,7 @@ ACID_FAIL macro detail,observed,expected
5869
; Clobbers d0/a0.
5970
;
6071
ACID_INIT macro
61-
lea ACID_BASE.w,a0
72+
lea ACID_BASE.l,a0
6273
moveq #0,d0
6374
move.l d0,(a0)+
6475
move.l d0,(a0)+

test/acid/include/jaguar_header.s

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,45 @@
11
;
2-
; jaguar_header.s - minimal Jaguar cart header + entry vector.
2+
; jaguar_header.s - minimal Jaguar cart header.
33
;
44
; Layout:
5-
; $800000 ATARI tag ; bypassed by emulators that skip auth
6-
; $800400 jump table to entry ; standard Universal Header offset
7-
; $802000 user code begins here
8-
;
9-
; The harness loads the .jag at $800000 and the BIOS jumps to $802000
10-
; via the universal header at $800400. This is the same layout used by
11-
; Atari's tools and most homebrew. Authentication is bypassed inside
12-
; the core (the BIOS auth-loop handler in src/core/jaguar.c short-
13-
; circuits when a cart is present), so we don't need a real cart
14-
; signature.
5+
; $800000 ATARI tag ; cosmetic; emulator's HLE-BIOS
6+
; path skips signature check
7+
; $800404 dc.l entry ; ROM-loader reads this 32-bit
8+
; word as the cart entry point
9+
; (see src/core/file.c:140
10+
; jaguarRunAddress = GET32(
11+
; jagMemSpace, 0x800404)). HLE
12+
; BIOS init then writes that
13+
; value to the 68K reset PC
14+
; vector at $00000004 before
15+
; m68k_pulse_reset(), so the CPU
16+
; starts execution at `entry`.
17+
; $802000 user code begins here ; conventional cart entry org
1518
;
1619
; Each test should:
17-
; include "jaguar_header.s" ; this file
18-
; include "acid_test.s" ; pass/fail macros
20+
; include "include/jaguar_header.s" ; this file
21+
; include "include/acid_test.s" ; pass/fail macros
1922
; org $802000
20-
; entry: ; <-- BIOS jumps here
23+
; entry: ; <-- 68K starts execution here after reset
2124
; ACID_INIT
2225
; ; ... your test code ...
23-
; ACID_PASS ; or ACID_FAIL ...,...,...
26+
; ACID_PASS ; or ACID_FAIL ...,...,...
2427
;
2528

2629
;; ROM origin
2730
org $800000
2831

29-
;; Skunkboard / Universal Header preamble. Real carts
30-
;; have an "ATARI" tag and licence text here that the
31-
;; BIOS validates; we rely on the emulator skipping
32-
;; that check, so just pad to the entry vector.
32+
;; Cosmetic ATARI tag. Real cart loader validates this
33+
;; against the boot ROM's expected hash; our emulator's
34+
;; HLE BIOS path skips that check entirely, so any
35+
;; non-zero text works here.
3336
dc.b "ATARI APPROVED DATA HEADER ATRI ",0
34-
ds.b $800400-*,0
37+
ds.b $800404-*,0
3538

36-
;; Universal Header entry vector at $800400.
37-
;; The Jaguar BIOS jumps through this to start the cart.
38-
jmp entry
39+
;; Cart entry point: a literal 32-bit big-endian address
40+
;; that file.c picks up via GET32(jagMemSpace, 0x800404)
41+
;; and uses as the 68K's initial PC.
42+
dc.l entry
3943

40-
;; Pad to the user code area.
44+
;; Pad to the user code area at $802000.
4145
ds.b $802000-*,0

test/acid/run.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#include "libretro.h"
2929

3030
/* Acid signature offsets and magic, mirrored from acid_test.s. */
31-
#define ACID_BASE 0x100
31+
#define ACID_BASE 0x100000
3232
#define ACID_RESULT (ACID_BASE + 0)
3333
#define ACID_DETAIL (ACID_BASE + 4)
3434
#define ACID_OBSERVED (ACID_BASE + 8)
@@ -77,7 +77,13 @@ static bool environment_cb(unsigned cmd, void *data)
7777
/* Acid tests don't depend on these, but the core polls
7878
* them. Return sane defaults. */
7979
if (strcmp(var->key, "virtualjaguar_bios") == 0)
80-
{ var->value = "enabled"; return true; }
80+
{ var->value = "disabled"; return true; } /* HLE BIOS:
81+
* the real BIOS performs cart authentication that
82+
* synthetic test ROMs can't satisfy without faking
83+
* a CRC. HLE skips that, sets the 68K reset PC from
84+
* the cart's entry vector at $800404, and dumps us
85+
* straight into the test code. See
86+
* src/core/jaguar.c:JaguarReset HLE path. */
8187
if (strcmp(var->key, "virtualjaguar_pal") == 0)
8288
{ var->value = "disabled"; return true; }
8389
if (strcmp(var->key, "virtualjaguar_usefastblitter") == 0)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
;
2+
; zzz_smoke.s - smoke test, no blitter, no logic.
3+
; Just writes ACID_PASS_MAGIC to ACID_RESULT and halts.
4+
; If THIS doesn't pass, the boot stub / 68K cold-start is broken.
5+
; Filename starts with "zzz_" so `find` lists it last; runner reports
6+
; in find order.
7+
;
8+
include "include/jaguar_header.s"
9+
include "include/acid_test.s"
10+
11+
org $802000
12+
entry:
13+
ACID_INIT
14+
ACID_PASS

0 commit comments

Comments
 (0)