joeylib2/scripts/verify-iigs-keys.sh

120 lines
4.6 KiB
Bash
Executable file

#!/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-keys.sh - Headless gate for the IIgs's key predicates, the
# asm jlKeyDown and jlKeyPressed (JL_HAS_INPUT_PREDICATES, joeyDraw.s).
# Boots GS/OS under MAME and launches the KEYS example off joey.2mg, which
# lights a key's cell while jlKeyDown says it is held and quits on
# jlKeyPressed(JL_KEY_ESCAPE). Holds A on the emulated ADB keyboard and
# reads the A cell straight out of SHR memory: unlit before, lit while
# held, unlit after. Then presses Escape: KEYS must quit to the Finder,
# whose 640-mode SCB replaces KEYS' 320-mode one.
#
# Usage: scripts/verify-iigs-keys.sh
# Requires: ./install.sh install iigs; build/iigs/bin/joey.2mg built
# with the current KEYS (make iigs-disk).
set -euo pipefail
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
source "$repo/scripts/lib/joeyEnv.sh"
joeyNeed MAME mame
joeyNeed IIGS_ROMPATH iigsFirmware
joeyNeed GSOS_SYSTEM_DISK iigsFirmware
sys_disk=$GSOS_SYSTEM_DISK
data_disk=$repo/build/iigs/bin/joey.2mg
for f in "$sys_disk" "$data_disk"; do
[ -f "$f" ] || { echo "verify-iigs-keys: missing $f (run 'make iigs-disk')" >&2; exit 2; }
done
work=$(mktemp -d -t joeylib-keys-verify.XXXXXX)
trap 'rm -rf "$work"' EXIT
cp "$sys_disk" "$work/boot.po"
cp "$data_disk" "$work/joey.2mg"
# Finder keystroke timeline as in verify-iigs-input.sh. The A cell is
# KEYS' row 2, column 0 (examples/keys: MARGIN 2, CELL 28x26, GAP 4); its
# middle, x 16 y 75, is the SHR byte $E1/2000 + 75*160 + 8 = $E1/4EE8:
# $11 unlit (COLOR_UNLIT), $22 lit (COLOR_LIT). SCB 0 is $E1/9D00.
cat > "$work/verify.lua" <<'LUA'
local cpu = manager.machine.devices[":maincpu"]
local mem = cpu.spaces["program"]
local nat = manager.machine.natkeyboard
local frame = 0
local idx = 1
local function field(port, name)
local p = manager.machine.ioport.ports[port]
if p == nil then return nil end
return p.fields[name]
end
local key_cmd = field(":macadb:KEY3", "Command / Open Apple")
local key_a = field(":macadb:KEY0", "a A")
local key_esc = field(":macadb:KEY3", "Esc")
local function press(f) if f then f:set_value(1) end end
local function release(f) if f then f:set_value(0) end end
local function report(tag)
io.write(string.format("VERIFY-IIGS-KEYS %s scb0=%02X cell=%02X\n", tag, mem:read_u8(0xE19D00), mem:read_u8(0xE14EE8)))
io.flush()
end
local steps = {
{3000, function() nat:post("J") end},
{3120, function() press(key_cmd) end},
{3126, function() nat:post("o") end},
{3180, function() release(key_cmd) end},
{3540, function() nat:post("KEYS") end},
{3660, function() press(key_cmd) end},
{3666, function() nat:post("o") end},
{3720, function() release(key_cmd) end},
{6600, function() report("before") end},
{6610, function() press(key_a) end},
{6700, function() report("held") end},
{6710, function() release(key_a) end},
{6800, function() report("released") end},
{6810, function() press(key_esc) end},
{6830, function() release(key_esc) end},
{9000, function() report("escape"); manager.machine:exit() end},
}
emu.register_frame_done(function()
frame = frame + 1
while idx <= #steps and frame >= steps[idx][1] do
steps[idx][2]()
idx = idx + 1
end
end)
LUA
cd "$work"
out=$(QT_QPA_PLATFORM=offscreen SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
timeout 300 "$MAME" apple2gs \
-rompath "$IIGS_ROMPATH" \
-flop3 "$work/boot.po" -flop4 "$work/joey.2mg" \
-video none -sound none -nothrottle \
-autoboot_script "$work/verify.lua" </dev/null 2>&1) || true
report=$(echo "$out" | grep -E '^VERIFY-IIGS-KEYS ' || true)
echo "$report"
value() {
echo "$report" | grep " $1 " | sed -E "s/.*$2=([0-9A-Fa-f]+).*/\1/"
}
fails=()
[ "$(value before scb0)" = "00" ] || fails+=("KEYS never launched (SCB 0 $(value before scb0))")
[ "$(value before cell)" = "11" ] || fails+=("the A cell lit before A was held ($(value before cell))")
[ "$(value held cell)" = "22" ] || fails+=("jlKeyDown: the A cell unlit while A was held ($(value held cell))")
[ "$(value released cell)" = "11" ] || fails+=("jlKeyDown: the A cell still lit after A was let go ($(value released cell))")
scb=$(value escape scb0)
[ -n "$scb" ] && [ $((16#$scb)) -ge 128 ] || fails+=("jlKeyPressed: Escape did not quit KEYS (SCB 0 ${scb:-none})")
if [ ${#fails[@]} -eq 0 ]; then
echo "verify-iigs-keys: PASS (A lit only while held; Escape quit KEYS)"
exit 0
fi
for f in "${fails[@]}"; do
echo "verify-iigs-keys: FAIL - $f" >&2
done
exit 1