65816-llvm-mos/scripts/runInMame.sh
Scott Duensing 6d7eae0356 Checkpoint.
2026-04-30 01:29:16 -05:00

105 lines
3.3 KiB
Bash
Executable file

#!/usr/bin/env bash
# Run a 65816 binary inside MAME's apple2gs simulation.
#
# Usage:
# runInMame.sh <binary> <addr> <expected>
# Read one 16-bit value at addr, compare to expected.
# runInMame.sh <binary> --check <addr1>=<exp1> [<addr2>=<exp2> ...]
# Read multiple 16-bit values, all must match.
#
# Addresses can be 24-bit (e.g., "0x025000" for bank 2 offset $5000).
# Expected values are 4-hex (no 0x prefix).
#
# Code loads at $00:1000 in bank 0 RAM. Code can switch DBR to bank
# 2+ for safe data writes (bank 0 zero page is scribbled by IIgs ROM
# during execution).
#
# Exit 0 if all reads match, 1 otherwise.
set -euo pipefail
source "$(dirname "$0")/common.sh"
BIN="$1"
shift
SECS=3
# Build address list as Lua table entries.
LUA_CHECKS=""
EXPECT_LIST=()
ADDR_LIST=()
if [ "$1" = "--check" ]; then
shift
for pair in "$@"; do
ADDR="${pair%=*}"
EXP="${pair#*=}"
ADDR_LIST+=("$ADDR")
EXPECT_LIST+=("$EXP")
LUA_CHECKS="$LUA_CHECKS print(string.format('MAME-READ addr=0x%06x val=0x%04x', $ADDR, mem:read_u16($ADDR)))"$'\n'
done
else
ADDR="$1"
EXP="$2"
ADDR_LIST+=("$ADDR")
EXPECT_LIST+=("$EXP")
LUA_CHECKS="print(string.format('MAME-READ addr=0x%06x val=0x%04x', $ADDR, mem:read_u16($ADDR)))"
fi
[ -f "$BIN" ] || die "binary not found: $BIN"
LUA_PATH=$(mktemp --suffix=.lua)
trap 'rm -f "$LUA_PATH"' EXIT
cat > "$LUA_PATH" <<EOF
local frame = 0
local loaded = false
emu.register_frame_done(function()
frame = frame + 1
if frame == 30 and not loaded then
local cpu = manager.machine.devices[":maincpu"]
local mem = cpu.spaces["program"]
local f = io.open("$BIN", "rb")
if not f then print("BIN-MISSING"); manager.machine:exit(); return end
local data = f:read("*all"); f:close()
-- Load at \$00:1000 (bank 0). PB stays at \$00 — MAME's
-- apple2gs CPU model doesn't honor a Lua-side PB!=0 set.
-- The user's code can switch DBR to bank 2+ for safe data
-- writes (bank 2 is clear of IIgs ROM IRQ scribbling).
for i = 1, #data do mem:write_u8(0x001000 + i - 1, data:byte(i)) end
loaded = true
cpu.state["PC"].value = 0x1000
cpu.state["PB"].value = 0x00
cpu.state["DB"].value = 0x00
cpu.state["D"].value = 0x00
cpu.state["P"].value = 0x34 -- M=1, X=1, I=1 (IRQ off)
cpu.state["E"].value = 0
cpu.state["S"].value = 0x01FF
print("MAME-LOADED bytes=" .. #data)
end
if frame == 60 then
local cpu = manager.machine.devices[":maincpu"]
local mem = cpu.spaces["program"]
$LUA_CHECKS
manager.machine:exit()
end
end)
EOF
OUT=$(timeout 30 mame apple2gs \
-rompath "$PROJECT_ROOT/tools/mame/roms" \
-plugins -autoboot_script "$LUA_PATH" \
-window -sound none -nothrottle -seconds_to_run "$SECS" 2>&1 | grep "^MAME-")
echo "$OUT"
# Parse all val=... and compare to expected list.
mapfile -t GOT_LIST < <(printf '%s\n' "$OUT" | grep -oE 'val=0x[0-9a-f]+' | sed 's/val=0x//')
ok=1
for i in "${!EXPECT_LIST[@]}"; do
if [ "${GOT_LIST[$i]:-}" != "${EXPECT_LIST[$i]}" ]; then
warn "MAME mismatch at ${ADDR_LIST[$i]}: got 0x${GOT_LIST[$i]:-MISSING} expected 0x${EXPECT_LIST[$i]}"
ok=0
fi
done
if [ $ok -eq 1 ]; then
log "MAME OK: ${#EXPECT_LIST[@]} reads matched"
exit 0
fi
exit 1