mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-31 12:05:05 +02:00
An 82-byte payload written in GSPA assembly, linked at bit 01800000h and loaded into main RAM by harness/mame/hello.lua, executes on the CPU: it writes DEAD/BEEF and a 1024-iteration counter into RAM and fills a 256x64 block in video RAM, which appears in the frame dump at x 256..511, y 136..199. Entry is a debugger breakpoint on the level-0 menu idle loop, not a delivery mechanism. Includes the build script, a COFF .text extractor (gsprom's hex addresses wrap at 64 KB), the run log, RAM excerpt, frame crops including a no-load control, and HELLO_WORLD_REPORT.md.
87 lines
2.8 KiB
Bash
Executable File
87 lines
2.8 KiB
Bash
Executable File
#!/bin/sh
|
|
# Assemble and link the hello-world payload with the 1987 TI TMS34010 SDK
|
|
# (GSPA 2.00 / GSPLNK 2.00) under DOSBox, then extract the linked bytes from
|
|
# the COFF (not from gsprom: its hex addresses wrap at 64 KB).
|
|
#
|
|
# Everything is written under harness/hello-world/work/; nothing is written
|
|
# outside this tree. The assembled output is the payload itself, not a
|
|
# reassembly of the firmware, so this build proves the toolchain generates
|
|
# runnable code.
|
|
#
|
|
# Usage: build.sh [origin-bit-address]
|
|
# Default origin 01800000h (byte 00300000h of the 4 MiB main RAM).
|
|
set -eu
|
|
|
|
ROOT=$(cd "$(dirname "$0")/../.." && pwd)
|
|
DIR=$(cd "$(dirname "$0")" && pwd)
|
|
WORK="$DIR/work"
|
|
ORIGIN=${1:-01800000}
|
|
IMG="$ROOT/tools/tms34010-sdk/1987-05 TMS34010 SDK/1987-11-06 TMS34010 Simulator-C Tools-ASM Tools.img"
|
|
DOSBOX_CONF="$ROOT/harness/sdk-scratch/dosbox-bench.conf"
|
|
# DOSBox is a 16-bit DOS environment: 8.3 upper-case names, no long paths.
|
|
HOSTNAME=HELLO
|
|
|
|
mkdir -p "$WORK"
|
|
|
|
# Extract the tool binaries once, the same way sdk-roundtrip/roundtrip.sh does.
|
|
if [ ! -x "$WORK/GSPA.EXE" ]; then
|
|
mcopy -s -n -i "$IMG" "::/A2/*" "$WORK/"
|
|
mcopy -s -n -i "$IMG" "::/C2/*" "$WORK/"
|
|
fi
|
|
|
|
cp "$DIR/hello.asm" "$WORK/HELLO.ASM"
|
|
|
|
# TI hex constants must begin with a decimal digit.
|
|
case "$ORIGIN" in
|
|
[0-9]*) ;;
|
|
*) ORIGIN="0$ORIGIN" ;;
|
|
esac
|
|
|
|
# Linker command file. CRLF, because the DOS tool reads it as text.
|
|
printf '%s\n' \
|
|
'-a' \
|
|
'-o hello.out' \
|
|
'-m hello.map' \
|
|
'hello.obj' \
|
|
'SECTIONS' \
|
|
'{' \
|
|
" .text ${ORIGIN}h: {}" \
|
|
'}' > "$WORK/HELLO.CMD"
|
|
sed -i 's/$/\r/' "$WORK/HELLO.CMD"
|
|
|
|
rm -f "$WORK"/HELLO.OBJ "$WORK"/HELLO.OUT "$WORK"/HELLO.LST \
|
|
"$WORK"/HELLO.MAP "$WORK"/HELLO.HI "$WORK"/HELLO.LO
|
|
|
|
SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
|
|
timeout 180 dosbox -conf "$DOSBOX_CONF" -noprimaryconf -nolocalconf \
|
|
-c "mount c $WORK" -c "c:" \
|
|
-c "gspa hello hello.obj hello.lst -l" \
|
|
-c "gsplnk hello.cmd" \
|
|
-c "exit" -exit >/dev/null 2>&1
|
|
|
|
if [ ! -f "$WORK/HELLO.OUT" ]; then
|
|
echo "build.sh: GSPLNK produced no HELLO.OUT" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# The assembler's own transcript is invisible in headless DOSBox; the listing
|
|
# is the record. Surface any error lines.
|
|
if [ ! -f "$WORK/HELLO.OBJ" ]; then
|
|
echo "build.sh: GSPA produced no HELLO.OBJ" >&2
|
|
grep -n '\*\*\*\*\*' "$WORK/HELLO.LST" >&2 || true
|
|
exit 1
|
|
fi
|
|
if grep -q '\*\*\*\*\*' "$WORK/HELLO.LST"; then
|
|
echo "build.sh: assembler reported diagnostics:" >&2
|
|
grep -n '\*\*\*\*\*' "$WORK/HELLO.LST" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "--- hello.map (placement) ---"
|
|
sed -n '/SECTION ALLOCATION MAP/,/GLOBAL SYMBOLS/p' "$WORK/HELLO.MAP"
|
|
|
|
python3 "$DIR/cofextract.py" "$WORK/HELLO.OUT" "$DIR/payload.bin"
|
|
# The map comes from a DOS program (CRLF); keep the committed copy LF-only so
|
|
# it does not churn in git.
|
|
sed 's/\r$//' "$WORK/HELLO.MAP" > "$DIR/payload.map"
|