#!/usr/bin/env bash # Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License. # See LICENSE.md for license information. # SPDX-License-Identifier: MIT # # 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 [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 [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" <> 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" &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)"