Files
vt1200/harness/mame/run-vidstream.sh
T

156 lines
6.1 KiB
Bash
Executable File

#!/bin/sh
# run-vidstream.sh -- build the streaming payload and run its MAME check.
#
# harness/mame/run-vidstream.sh # build, then mode alloc
# BENCH=0 harness/mame/run-vidstream.sh # use the existing .bin
# VT1200_MODE=rx harness/mame/run-vidstream.sh # alloc + the receive path
# VT1200_MODE=draw harness/mame/run-vidstream.sh # alloc + rx + the blit
# VT1200_MODE=stream harness/mame/run-vidstream.sh # the status back-channel
# VT1200_MODE=ring harness/mame/run-vidstream.sh # the RX ring's structure
# STREAM_POOL_BYTES=0x7FFF000 harness/mame/run-vidstream.sh # force fallback
#
# Mode rx delivers one valid frame and one corrupted frame through the payload's
# own LANCE RX ring and asserts RX_OK == 1 && RX_BAD == 1 (see vidstream.lua and
# the task-7 report).
#
# Mode draw delivers one 128-row strip frame (stretch 8 = 1024 screen rows),
# lets the payload blit it, and dumps the screen and the delivered frame; this
# script then runs harness/mame/vidstream_check.py, which compares every screen
# row against its source row. The pixel verdict is the checker's, not the Lua's.
#
# Mode stream plays the sender: 200 strip frames, then RX_EOF so the terminal
# reports the final count. The payload takes the LANCE over for receive and
# transmit and builds a KIND_STATUS frame every 64 accepted frames; the Lua
# reads those frames back from the payload's own transmit buffer and this
# script runs harness/mame/vidstream_status_check.py, which decodes them with
# the host sender's wire format. There is no network in this run: the emulated
# LANCE has no interface (ruling R11), so the evidence is the buffer's bytes
# plus the completed descriptor, and the wire path needs the unit.
#
# Mode ring asserts the transport's structure: 16 descriptors armed with OWN set
# for slot A, a completed frame moving them to slot B, a header claiming more
# than SLOT_BYTES rejected without a blit (RX_BAD moves, RX_OK does not, the
# screen does not change), and a datagram the chip flags bad (RMD3 = 0, so it
# carries no bytes) counted in RX_FCS_DROP with its frame abandoned. The verdict
# is in the Lua; the evidence is $LOGDIR/ring-status.txt.
#
# The run uses VT1200_SKIP_LEVEL1=1: the payload's heap is only initialised in
# the OS phase. In the diagnostics menu the free counter (0x1E8BA0) and the
# free-list head (0x1E8AC0) both read 0, so the malloc success path cannot be
# tested there. The skip is a documented divergence (harness/mame/README.md).
#
# Exit status: 0 only if vidstream.lua printed "VID: RESULT PASS" and, in draw
# or stream mode, the checker for that mode passed too.
set -eu
HERE=$(cd "$(dirname "$0")" && pwd)
ROOT=$(cd "$HERE/../.." && pwd)
MAME=${MAME:-/home/arti/code/k-space/mame0289/vt1200}
BENCH=${BENCH:-1}
MODE=${VT1200_MODE:-alloc}
LOGDIR=${LOGDIR:-/tmp/opencode}
LOG="$LOGDIR/vidstream-mame.log"
if [ ! -x "$MAME" ]; then
echo "run-vidstream.sh: no MAME binary at $MAME (set MAME=...)" >&2
exit 1
fi
if [ "$BENCH" != "0" ]; then
STREAM_POOL_BYTES=${STREAM_POOL_BYTES:-249856} \
"$ROOT/harness/udpstream/build-stream.sh"
fi
if [ ! -f "$ROOT/harness/udpstream/build/vidstream.bin" ]; then
echo "run-vidstream.sh: no build/vidstream.bin (run without BENCH=0)" >&2
exit 1
fi
# POOL_BYTES / STATIC_PTR come from the image that was just built, so the check
# compares against the linked fallback address rather than a guess.
POOL_BYTES=249856
STATIC_PTR=0
ENTRY_PTR=0x018C0000
ENVFILE="$ROOT/harness/udpstream/build/vidstream.env"
if [ -f "$ENVFILE" ]; then
# shellcheck disable=SC1090
. "$ENVFILE"
fi
mkdir -p "$LOGDIR"
# Ruling R15: draw-mode evidence must come from THIS run. The Lua removes its
# own dump files at startup; removing them here as well means a run that dies
# before the script starts (or before it dumps) leaves no previous screen
# behind for vidstream_check.py to bless.
if [ "$MODE" = "draw" ]; then
rm -f "$LOGDIR/vram-draw.bin" "$LOGDIR/frame-draw.bin" \
"$LOGDIR/draw-status.txt"
fi
if [ "$MODE" = "stream" ]; then
rm -f "$LOGDIR/stream-status.bin" "$LOGDIR/stream-status.txt"
fi
if [ "$MODE" = "ring" ]; then
rm -f "$LOGDIR/ring-status.txt"
fi
# Absolute: the Lua runs with MAME's cwd, so a relative default only resolves
# when the caller happens to be at the repo root.
VID_PAYLOAD="$ROOT/harness/udpstream/build/vidstream.bin"
set +e
VT1200_SKIP_LEVEL1=1 \
VT1200_MODE="$MODE" \
VID_PAYLOAD="$VID_PAYLOAD" \
VID_DUMP_DIR="$LOGDIR" \
VID_POOL_BYTES="$POOL_BYTES" \
VID_STATIC_PTR="$STATIC_PTR" \
VID_ENTRY_PTR="$ENTRY_PTR" \
"$MAME" vt1200 -rompath "$HERE/roms" -video none -sound none -nothrottle \
-skip_gameinfo -debug -debugger none \
-seconds_to_run "${VID_SECONDS:-120}" \
-autoboot_script "$HERE/vidstream.lua" -autoboot_delay 0 \
> "$LOG" 2>&1
STATUS=$?
set -e
grep '^VID:' "$LOG" || true
if [ "$STATUS" -ne 0 ]; then
echo "run-vidstream.sh: MAME exited $STATUS; log $LOG" >&2
tail -20 "$LOG" >&2
exit "$STATUS"
fi
if ! grep -q '^VID: RESULT PASS' "$LOG"; then
echo "run-vidstream.sh: check failed (log $LOG)" >&2
exit 1
fi
# The pixel comparison is a separate, independent reading of the geometry
# (vidstream_check.py); a transport pass with the wrong picture is a failure.
if [ "$MODE" = "draw" ]; then
set +e
python3 "$HERE/vidstream_check.py" \
--vram "$LOGDIR/vram-draw.bin" \
--frame "$LOGDIR/frame-draw.bin" \
--status "$LOGDIR/draw-status.txt"
STATUS=$?
set -e
if [ "$STATUS" -ne 0 ]; then
echo "run-vidstream.sh: pixel check failed (log $LOG)" >&2
exit "$STATUS"
fi
fi
# The status frames are decoded by the host side's wire format, so the payload's
# encoder and frame.py cannot drift apart without failing here.
if [ "$MODE" = "stream" ]; then
set +e
python3 "$HERE/vidstream_status_check.py" \
--bin "$LOGDIR/stream-status.bin" \
--status "$LOGDIR/stream-status.txt" \
--frames "${VID_STREAM_FRAMES:-200}"
STATUS=$?
set -e
if [ "$STATUS" -ne 0 ]; then
echo "run-vidstream.sh: status check failed (log $LOG)" >&2
exit "$STATUS"
fi
fi
exit 0