Files
vt1200/bad-apple/player/build.sh
T

133 lines
4.3 KiB
Bash
Executable File

#!/bin/sh
# Build the Bad Apple payload with the 1987 TI TMS34010 SDK under DOSBox.
#
# .text at bit 0x018C0000, .bss at bit 0x01C00000 (the free block the rdebug
# loader already uses). Outputs: build/player.coff, player.bin, player.env.
set -eu
ROOT=$(cd "$(dirname "$0")/../.." && pwd)
DIR=$(cd "$(dirname "$0")" && pwd)
WORK="$DIR/work"
OUT="$DIR/build"
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"
TEXT=018C0000
BSS=01C00000
NET=${NET:-0}
if [ "$NET" = 1 ]; then
NAME=player-net
else
NAME=player
fi
mkdir -p "$WORK" "$OUT"
if [ ! -x "$WORK/GSPCG.EXE" ]; then
mcopy -s -n -i "$IMG" "::/A2/*" "$WORK/"
mcopy -s -n -i "$IMG" "::/C2/*" "$WORK/"
fi
cp "$DIR/main.c" "$WORK/MAIN.C"
cp "$DIR/movie.c" "$WORK/MOVIE.C"
cp "$DIR/movie.h" "$WORK/MOVIE.H"
cp "$DIR/romapi.h" "$WORK/ROMAPI.H"
printf '#define NET_DEFAULT %s\n' "$NET" > "$WORK/MODECFG.H"
cp "$DIR/fill.asm" "$WORK/FILL.ASM"
cp "$DIR/entry.asm" "$WORK/ENTRY.ASM"
{
printf '%s\n' '-a'
printf '%s\n' '-o PLAYER.out'
printf '%s\n' '-m PLAYER.map'
printf '%s\n' '-e _start'
printf '%s\n' 'MAIN.obj'
printf '%s\n' 'MOVIE.obj'
printf '%s\n' 'FILL.obj'
printf '%s\n' 'ENTRY.obj'
printf '%s\n' '-l RTS.LIB'
printf '%s\n' 'MEMORY'
printf '%s\n' '{'
printf '%s\n' " prog: origin = ${TEXT}h, length = 20000h"
printf '%s\n' " ram: origin = ${BSS}h, length = 200000h"
printf '%s\n' '}'
printf '%s\n' 'SECTIONS'
printf '%s\n' '{'
printf '%s\n' ' .text: {} > prog'
printf '%s\n' ' .data: {} > prog'
printf '%s\n' ' .cinit: {} > prog'
printf '%s\n' ' .bss: {} > ram'
printf '%s\n' '}'
} > "$WORK/PLAYER.CMD"
sed -i 's/$/\r/' "$WORK/PLAYER.CMD"
{
printf 'gspcpp MAIN\r\n'
printf 'gspcc MAIN\r\n'
printf 'gspcg MAIN\r\n'
printf 'gspa MAIN MAIN.obj MAIN.lst -l\r\n'
printf 'gspcpp MOVIE\r\n'
printf 'gspcc MOVIE\r\n'
printf 'gspcg MOVIE\r\n'
printf 'gspa MOVIE MOVIE.obj MOVIE.lst -l\r\n'
printf 'gspa FILL FILL.obj FILL.lst -l\r\n'
printf 'gspa ENTRY ENTRY.obj ENTRY.lst -l\r\n'
printf 'gsplnk PLAYER.cmd\r\n'
printf 'exit\r\n'
} > "$WORK/BUILD.BAT"
rm -f "$WORK"/MAIN.OBJ "$WORK"/MOVIE.OBJ "$WORK"/FILL.OBJ \
"$WORK"/ENTRY.OBJ "$WORK"/PLAYER.OUT "$WORK"/PLAYER.MAP \
"$WORK"/MAIN.LST "$WORK"/MOVIE.LST "$WORK"/FILL.LST \
"$WORK"/ENTRY.LST
SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
timeout 240 dosbox -conf "$DOSBOX_CONF" -noprimaryconf -nolocalconf \
-c "mount c $WORK" -c "c:" \
-c "BUILD.BAT" \
-c "exit" -exit > "$WORK/dosbox.log" 2>&1
if [ ! -f "$WORK/PLAYER.OUT" ]; then
echo "build.sh: GSPLNK produced no PLAYER.OUT" >&2
sed 's/\r$//' "$WORK/PLAYER.MAP" 2>/dev/null | tail -20 >&2 || true
for f in MAIN.LST MOVIE.LST FILL.LST ENTRY.LST; do
sed 's/\r$//' "$WORK/$f" 2>/dev/null | grep -i 'error' \
| grep -vi 'no errors' >&2 || true
done
exit 1
fi
for f in MAIN.LST MOVIE.LST FILL.LST ENTRY.LST; do
if sed 's/\r$//' "$WORK/$f" 2>/dev/null | grep -i 'error' \
| grep -qvi 'no errors'; then
echo "build.sh: $f diagnostics:" >&2
sed 's/\r$//' "$WORK/$f" | grep -in 'error' \
| grep -vi 'no errors' >&2
exit 1
fi
done
cp "$WORK/PLAYER.OUT" "$OUT/player.coff"
sed 's/\r$//' "$WORK/PLAYER.MAP" > "$OUT/player.map"
sed 's/\r$//' "$WORK/MAIN.LST" > "$OUT/main.lst" 2>/dev/null || true
sed 's/\r$//' "$WORK/MOVIE.LST" > "$OUT/movie.lst" 2>/dev/null || true
sed 's/\r$//' "$WORK/FILL.LST" > "$OUT/fill.lst" 2>/dev/null || true
python3 "$ROOT/harness/hello-world/cofextract.py" \
"$WORK/PLAYER.OUT" "$OUT/$NAME.bin" > "$OUT/cofextract.txt"
cp "$WORK/PLAYER.OUT" "$OUT/$NAME.coff"
ENTRY_PTR=$(sed 's/\r$//' "$WORK/PLAYER.MAP" \
| awk '/ENTRY POINT SYMBOL/ { print $NF; exit }')
MARK_PTR=$(sed 's/\r$//' "$WORK/PLAYER.MAP" \
| awk '$2 == "_marker_page" { print $1; exit }')
if [ -z "$ENTRY_PTR" ] || [ -z "$MARK_PTR" ]; then
echo "build.sh: no entry point or _marker_page in PLAYER.map" >&2
exit 1
fi
printf 'ENTRY_PTR=0x%s\nMARK_PTR=0x%s\n' "$ENTRY_PTR" "$MARK_PTR" \
> "$OUT/$NAME.env"
echo "build.sh: $OUT/$NAME.bin ($(wc -c < "$OUT/$NAME.bin") bytes)"
grep -E "ENTRY POINT|^\.(text|cinit|bss)" "$OUT/player.map" | head -8
echo "build.sh: entry bit 0x$ENTRY_PTR"