mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-11-01 12:14:56 +02:00
The text panel grew .text past MARK and the payload overwrote its own code with cell() writes (illegal opcode on the unit). The build now parses build/lance.map and aborts if the end of .text reaches MARK, printing the remaining gap.
112 lines
3.8 KiB
Bash
Executable File
112 lines
3.8 KiB
Bash
Executable File
#!/bin/sh
|
|
# Build the raw LANCE receive probe.
|
|
#
|
|
# harness/udpstream/build.sh
|
|
#
|
|
# .text at bit 0x018C0000, .bss at 0x01C00000 (both inside the firmware's large
|
|
# free block), entry _start, no .cinit (the runtime's autoinit pass does not
|
|
# run -- see harness/c-hello/README.md).
|
|
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
|
|
|
|
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
|
|
|
|
SRC=${LANCE_SRC:-$DIR/lance.c}
|
|
cp "$SRC" "$WORK/LANCE.C"
|
|
cp "$DIR/romapi.h" "$WORK/ROMAPI.H"
|
|
cp "$DIR/entry.asm" "$WORK/ENTRY.ASM"
|
|
|
|
{
|
|
printf '%s\n' '-a'
|
|
printf '%s\n' '-o LANCE.out'
|
|
printf '%s\n' '-m LANCE.map'
|
|
printf '%s\n' '-e _start'
|
|
printf '%s\n' 'LANCE.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 = 40000h"
|
|
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/LANCE.CMD"
|
|
sed -i 's/$/\r/' "$WORK/LANCE.CMD"
|
|
|
|
rm -f "$WORK"/LANCE.OBJ "$WORK"/LANCE.OUT "$WORK"/LANCE.LST \
|
|
"$WORK"/LANCE.MAP "$WORK"/LANCE.ASM "$WORK"/LANCE.CPP \
|
|
"$WORK"/LANCE.IF "$WORK"/ENTRY.OBJ "$WORK"/ENTRY.LST
|
|
|
|
SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
|
|
timeout 240 dosbox -conf "$DOSBOX_CONF" -noprimaryconf -nolocalconf \
|
|
-c "mount c $WORK" -c "c:" \
|
|
-c "gspcpp LANCE" \
|
|
-c "gspcc LANCE" \
|
|
-c "gspcg LANCE" \
|
|
-c "gspa LANCE LANCE.obj LANCE.lst -l" \
|
|
-c "gspa ENTRY ENTRY.obj ENTRY.lst -l" \
|
|
-c "gsplnk LANCE.cmd" \
|
|
-c "exit" -exit > "$WORK/dosbox.log" 2>&1
|
|
|
|
if [ ! -f "$WORK/LANCE.OUT" ]; then
|
|
echo "build.sh: GSPLNK produced no LANCE.OUT" >&2
|
|
sed 's/\r$//' "$WORK/LANCE.MAP" 2>/dev/null | tail -20 >&2 || true
|
|
for f in LANCE.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 LANCE.LST ENTRY.LST; do
|
|
if sed 's/\r$//' "$WORK/$f" | 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
|
|
|
|
OUTNAME=${LANCE_OUT:-lance.coff}
|
|
cp "$WORK/LANCE.OUT" "$OUT/$OUTNAME"
|
|
sed 's/\r$//' "$WORK/LANCE.MAP" > "$OUT/lance.map"
|
|
# Guard: the marker block (MARK in the source) must sit clear of .text, or the
|
|
# payload overwrites its own code with cell() writes (an illegal-opcode crash).
|
|
python3 - "$SRC" "$OUT/lance.map" <<'PYCHK'
|
|
import re, sys
|
|
src, mp = sys.argv[1], sys.argv[2]
|
|
m = re.search(r'#define\s+MARK\s+(0x[0-9A-Fa-f]+)', open(src).read())
|
|
if m:
|
|
mark = int(m.group(1), 16)
|
|
for ln in open(mp):
|
|
f = ln.split()
|
|
if len(f) >= 4 and f[0] == '.text':
|
|
start, size = int(f[2], 16), int(f[3], 16)
|
|
end = start + size
|
|
if end > mark:
|
|
sys.stderr.write("build: ERROR .text ends at 0x%X, past MARK 0x%X\n" % (end, mark))
|
|
sys.exit(1)
|
|
print("build: .text ends 0x%X, MARK 0x%X (%d bytes clear)" % (end, mark, (mark - end) // 8))
|
|
PYCHK
|
|
sed 's/\r$//' "$WORK/LANCE.LST" > "$OUT/lance.lst"
|
|
sed 's/\r$//' "$WORK/ENTRY.LST" > "$OUT/entry.lst"
|
|
echo "build.sh: $OUT/$OUTNAME ($(wc -c < "$OUT/lance.coff") bytes)"
|
|
grep -E "ENTRY POINT|^\.(text|cinit|bss)" "$OUT/lance.map" | head -8
|