Files
vt1200/harness/hello-world/build.sh
T
SDD 1608a68cdb hello-world: the TMS34010 SDK assembles code that runs on the emulated VT1200
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.
2026-10-18 01:20:38 +03:00

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"