122 lines
3.9 KiB
Bash
Executable file
122 lines
3.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Run a 65816 binary in MAME after pre-loading a stub GS/OS
|
|
# dispatcher at $E100A8. This lets the smoke test exercise the
|
|
# wrapper-to-dispatcher contract end-to-end without needing a
|
|
# real GS/OS-bootable disk image.
|
|
#
|
|
# The stub is the assembled bytes of /tmp/gsosStub.s (rebuilt
|
|
# from runtime/src/iigsGsosStub.s as part of this script — kept
|
|
# in-tree so it's reproducible). It writes byte $42 to *parm
|
|
# and returns A=0 (success) for any call number. That is enough
|
|
# to verify the wrapper:
|
|
# 1. pushes the parm-block low ptr (PHA),
|
|
# 2. pushes a zero bank (PEA 0),
|
|
# 3. JSLs $E100A8 with the right return convention,
|
|
# 4. returns A correctly to the caller.
|
|
#
|
|
# Usage: runInMameWithGsosStub.sh <binary> <addr> <expected>
|
|
# runInMameWithGsosStub.sh <binary> --check <addr>=<exp>...
|
|
|
|
set -euo pipefail
|
|
source "$(dirname "$0")/common.sh"
|
|
|
|
BIN="$1"
|
|
shift
|
|
SECS=3
|
|
|
|
# 23-byte stub bytes (see runtime/src/iigsGsosStub.s for source).
|
|
# Hand-assembled to avoid relying on llvm-mc tracking M-flag state.
|
|
STUB_HEX="0848 a309 85e4 a000 00e2 20a9 4291 e4c2 2068 28a9 0000 6b"
|
|
|
|
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
|
|
|
|
# Build the stub-write Lua statement (one mem:write_u8 per byte).
|
|
STUB_BYTES=$(echo "$STUB_HEX" | tr -d ' ')
|
|
STUB_LUA=""
|
|
i=0
|
|
while [ $i -lt ${#STUB_BYTES} ]; do
|
|
byte="${STUB_BYTES:$i:2}"
|
|
addr=$(( 0xe100a8 + i / 2 ))
|
|
STUB_LUA="${STUB_LUA} mem:write_u8(${addr}, 0x${byte})"$'\n'
|
|
i=$(( i + 2 ))
|
|
done
|
|
|
|
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()
|
|
for i = 1, #data do
|
|
local addr = 0x001000 + i - 1
|
|
if not (addr >= 0x00C000 and addr < 0x00D000) then
|
|
mem:write_u8(addr, data:byte(i))
|
|
end
|
|
end
|
|
-- Install GS/OS dispatcher stub at \$E100A8 (bank E1 RAM).
|
|
$STUB_LUA
|
|
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
|
|
cpu.state["E"].value = 0
|
|
cpu.state["S"].value = 0x01FF
|
|
print("MAME-LOADED bytes=" .. #data .. " stub=$((${#STUB_BYTES}/2))")
|
|
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"
|
|
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 (gsos-stub) OK: ${#EXPECT_LIST[@]} reads matched"
|
|
exit 0
|
|
fi
|
|
exit 1
|