105 lines
3.3 KiB
Bash
Executable file
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
|