119 lines
4.6 KiB
Bash
Executable file
119 lines
4.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# verify-iigs-game-disk.sh - Boot a disk made by make-iigs-game-disk.sh in
|
|
# headless MAME and assert it reaches the program and draws.
|
|
#
|
|
# Two checkpoints, both read out of memory rather than off the screen:
|
|
# 1. $E1:9DC8 == 0xAA. tools/iigsStart writes that marker immediately
|
|
# before its QuitGS, so it means GS/OS booted and the launcher ran.
|
|
# (0xEE would mean QuitGS returned, i.e. the program did not launch.)
|
|
# 2. The Super Hi-Res framebuffer, sampled a while later: the count of
|
|
# distinct nibble values, as scripts/verify-iigs.sh uses. A blank
|
|
# screen is 1. There is no Finder on these disks, so unlike that
|
|
# script's ~9-10 desktop baseline anything above 1 is the program's
|
|
# own drawing.
|
|
#
|
|
# An 800KB image goes in the 3.5 drive; anything larger has to come off a
|
|
# CFFA2 card because MAME's drive is 800KB GCR only.
|
|
#
|
|
# Usage: scripts/verify-iigs-game-disk.sh <image> [minDistinct] [ramsize]
|
|
# Env: GAME_VERIFY_FRAMES frame at which to sample (default 5400, 90 s)
|
|
# GAME_VERIFY_MACHINE MAME machine, default apple2gs (ROM 3).
|
|
# Use apple2gsr1 to check a ROM 01 machine; these disks keep
|
|
# TS2 so they must boot on both.
|
|
# Requires: ./install.sh install iigs.
|
|
set -euo pipefail
|
|
|
|
img=${1:?usage: verify-iigs-game-disk.sh <image> [minDistinct] [ramsize]}
|
|
minDistinct=${2:-2}
|
|
ramsize=${3:-4M}
|
|
readFrame=${GAME_VERIFY_FRAMES:-5400}
|
|
machine=${GAME_VERIFY_MACHINE:-apple2gs}
|
|
|
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
source "$repo/scripts/lib/joeyEnv.sh"
|
|
joeyNeed MAME mame
|
|
joeyNeed IIGS_ROMPATH iigsFirmware
|
|
rompath="$IIGS_ROMPATH"
|
|
name=$(basename "$img")
|
|
|
|
[ -f "$img" ] || { echo "verify-iigs-game-disk: no such image $img" >&2; exit 2; }
|
|
|
|
# MAME opens a hard-disk image read-write, so two runs must never share
|
|
# one file. Work on a private copy.
|
|
work=$(mktemp -d -t joeylib-gdverify.XXXXXX)
|
|
trap 'rm -rf "$work"' EXIT
|
|
cp "$img" "$work/$name"
|
|
|
|
bytes=$(stat -c %s "$img")
|
|
if [ "$bytes" -le 900000 ]; then
|
|
media=(-flop3 "$work/$name")
|
|
how="3.5 drive"
|
|
else
|
|
media=(-sl7 cffa2 -hard1 "$work/$name")
|
|
how="CFFA2 card"
|
|
fi
|
|
|
|
cat > "$work/verify.lua" <<LUA
|
|
local cpu = manager.machine.devices[":maincpu"]
|
|
local mem = cpu.spaces["program"]
|
|
local frame = 0
|
|
local quitAt = nil
|
|
emu.register_frame_done(function()
|
|
frame = frame + 1
|
|
if quitAt == nil then
|
|
local mb = mem:read_u8(0xE19DC8)
|
|
if mb == 0xAA or mb == 0xEE then
|
|
quitAt = frame
|
|
io.write(string.format("GAMEDISK-BOOT name=$name mailbox=%02X frame=%d seconds=%.1f\\n", mb, frame, frame / 60.0))
|
|
io.flush()
|
|
end
|
|
end
|
|
if frame == $readFrame then
|
|
local seen = {}
|
|
local distinct = 0
|
|
local nonzero = 0
|
|
for a = 0xE12000, 0xE12000 + 31999 do
|
|
local b = mem:read_u8(a)
|
|
if b ~= 0 then nonzero = nonzero + 1 end
|
|
local hi = (b >> 4) & 0xF
|
|
local lo = b & 0xF
|
|
if not seen[hi] then seen[hi] = true; distinct = distinct + 1 end
|
|
if not seen[lo] then seen[lo] = true; distinct = distinct + 1 end
|
|
end
|
|
io.write(string.format("GAMEDISK-DRAW name=$name frame=%d distinctNibbles=%d nonZeroBytes=%d scb0=%02X\\n",
|
|
frame, distinct, nonzero, mem:read_u8(0xE19D00)))
|
|
io.flush()
|
|
manager.machine:exit()
|
|
end
|
|
end)
|
|
LUA
|
|
|
|
out=$(cd "$work" && QT_QPA_PLATFORM=offscreen SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
|
|
timeout 600 "$MAME" "$machine" \
|
|
-ramsize "$ramsize" -rompath "$rompath" "${media[@]}" \
|
|
-video none -sound none -nothrottle -skip_gameinfo \
|
|
-autoboot_script "$work/verify.lua" </dev/null 2>&1) || true
|
|
|
|
boot=$(echo "$out" | grep -m1 'GAMEDISK-BOOT' || true)
|
|
draw=$(echo "$out" | grep -m1 'GAMEDISK-DRAW' || true)
|
|
[ -n "$boot" ] && echo "$boot"
|
|
[ -n "$draw" ] && echo "$draw"
|
|
|
|
if [ -z "$boot" ]; then
|
|
echo "verify-iigs-game-disk: FAIL ($name never reached the launcher's QuitGS marker; GS/OS did not boot from the $how)" >&2
|
|
exit 1
|
|
fi
|
|
if echo "$boot" | grep -q 'mailbox=EE'; then
|
|
echo "verify-iigs-game-disk: FAIL ($name QuitGS returned, so the program did not launch)" >&2
|
|
exit 1
|
|
fi
|
|
if [ -z "$draw" ]; then
|
|
echo "verify-iigs-game-disk: FAIL ($name booted but the screen was never sampled)" >&2
|
|
exit 1
|
|
fi
|
|
distinct=$(echo "$draw" | sed -E 's/.*distinctNibbles=([0-9]+).*/\1/')
|
|
if [ "$distinct" -lt "$minDistinct" ]; then
|
|
echo "verify-iigs-game-disk: FAIL ($name distinctNibbles=$distinct < $minDistinct - screen looks blank)" >&2
|
|
exit 1
|
|
fi
|
|
echo "verify-iigs-game-disk: PASS ($name booted off the $how on $machine and drew, distinctNibbles=$distinct >= $minDistinct)"
|