joeylib2/scripts/diag-staxi-screen.sh

143 lines
5.7 KiB
Bash
Executable file

#!/usr/bin/env bash
# diag-staxi-screen.sh - one-off diagnostic for the STAXI title test:
# boot + launch STAXI, dump the full SHR framebuffer + palettes as hex
# at a target frame, then extract JOEYLOG.TXT from the work disk so the
# game's own init/asset-load log is visible. Outputs land in
# build/iigs/bin/ (staxi-shr.hex, staxi-joeylog.txt).
set -euo pipefail
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
: "${LLVM816_ROOT:?diag-staxi-screen.sh: source toolchains/env.sh first}"
CADIUS="${CADIUS:-$LLVM816_ROOT/tools/cadius/cadius}"
sys_disk=$repo/toolchains/emulators/support/gsos-system.po
data_disk=$repo/build/iigs/bin/joey.2mg
rompath="${MAME_ROMPATH:-$HOME/.mame/roms}"
dumpFrame="${STAXI_DUMP_FRAME:-9000}"
work=$(mktemp -d -t joeylib-staxidiag.XXXXXX)
trap 'rm -rf "$work"' EXIT
cp "$sys_disk" "$work/boot.po"
cp "$data_disk" "$work/joey.2mg"
cat > "$work/diag.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 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 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("STAXI") end},
{3660, function() press(key_cmd) end},
{3666, function() nat:post("o") end},
{3720, function() release(key_cmd) end},
}
local pcs = {}
emu.register_frame_done(function()
frame = frame + 1
while idx <= #steps and frame >= steps[idx][1] do
steps[idx][2]()
idx = idx + 1
end
-- Hang localization: sample the PC over 60 frames before the dump,
-- and probe NEWVIDEO (0xE0C029: bit7 = SHR on -> jlpInit ran).
if frame == $dumpFrame - 120 then
io.write(string.format("SHRPROBE newvideo=%02X shadow=%02X\n",
mem:read_u8(0xE0C029), mem:read_u8(0xE0C035)))
io.flush()
end
if frame >= $dumpFrame - 100 and frame < $dumpFrame - 40 then
local pc = cpu.state["PC"].value
local k = string.format("%06X", pc)
pcs[k] = (pcs[k] or 0) + 1
end
if frame == $dumpFrame - 40 then
for k, v in pairs(pcs) do
io.write(string.format("SHRPC %s count=%d\n", k, v))
end
io.flush()
end
if frame == $dumpFrame - 20 then
-- Locate the jlLog RAM ring without UBER's mailbox: bulk-read every
-- RAM bank and emit it as hex; the host greps for the build-stamp
-- text. read_range failures are reported, not swallowed.
local banks = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,0xE0,0xE1}
for _, bank in ipairs(banks) do
local base = bank * 65536
local ok, buf = pcall(function() return mem:read_range(base, base + 65535, 8) end)
if ok and buf ~= nil then
for off = 0, 65535, 256 do
local chunk = string.sub(buf, off + 1, off + 256)
local hex = {}
for i = 1, #chunk do
hex[#hex + 1] = string.format("%02X", string.byte(chunk, i))
end
io.write(string.format("SHRMEM %02X%04X %s\n", bank, off, table.concat(hex)))
end
else
io.write(string.format("SHRMEM-FAIL bank=%02X err=%s\n", bank, tostring(buf)))
end
end
io.flush()
end
if frame == $dumpFrame then
-- SHR pixel dump: 200 rows x 160 bytes as hex lines.
for row = 0, 199 do
local parts = {}
for b = 0, 159 do
parts[#parts + 1] = string.format("%02X", mem:read_u8(0xE12000 + row * 160 + b))
end
io.write("SHRROW " .. table.concat(parts) .. "\n")
end
-- SCBs + palettes.
local scb = {}
for i = 0, 15 do scb[#scb + 1] = string.format("%02X", mem:read_u8(0xE19D00 + i)) end
io.write("SHRSCB " .. table.concat(scb, " ") .. "\n")
local pal = {}
for i = 0, 31 do pal[#pal + 1] = string.format("%02X", mem:read_u8(0xE19E00 + i)) end
io.write("SHRPAL " .. table.concat(pal, " ") .. "\n")
io.flush()
manager.machine:exit()
end
end)
LUA
echo "diag-staxi: dumping SHR at frame $dumpFrame..." >&2
cd "$work"
out=$(QT_QPA_PLATFORM=offscreen SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
timeout 900 mame apple2gs \
-rompath "$rompath" \
-flop3 "$work/boot.po" -flop4 "$work/joey.2mg" \
-video none -sound none -nothrottle \
-autoboot_script "$work/diag.lua" </dev/null 2>&1) || true
echo "$out" | grep -E '^SHR(PROBE|PC)|^SHRMEM-FAIL' | sed 's/^/diag-staxi: /' >&2
echo "$out" | grep -E '^SHRMEM ' > "$repo/build/iigs/bin/staxi-mem.hex" || true
echo "$out" | grep -E '^SHR(ROW|SCB|PAL)' > "$repo/build/iigs/bin/staxi-shr.hex"
wc -l "$repo/build/iigs/bin/staxi-shr.hex" >&2
# The game flushed its log to the volume root; pull it off the WORK copy.
rm -f "$repo/build/iigs/bin/staxi-joeylog.txt" "$work/JOEYLOG.TXT"* 2>/dev/null || true
"$CADIUS" EXTRACTFILE "$work/joey.2mg" "/JOEYLIB/JOEYLOG.TXT" "$work/" >/dev/null 2>&1 || true
found=$(ls "$work"/JOEYLOG.TXT* 2>/dev/null | head -1)
if [ -n "$found" ]; then
tr -d '\r' < "$found" > "$repo/build/iigs/bin/staxi-joeylog.txt"
echo "diag-staxi: extracted JOEYLOG.TXT:" >&2
else
echo "diag-staxi: no JOEYLOG.TXT on work disk (flush never ran?)" >&2
fi