joeylib2/scripts/verify-iigs-game-disk.sh

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)"