forked from arti/vt1200
The 1987 DOS toolchain (GSPA/GSPLNK/GSPROM) runs under DOSBox and reassembles 32 KB of the v2.2 ROM byte-for-byte after five documented fixups to smart34010 output. The 1990 r5.01 tools are OS/2 NE and do not run in DOS. Adds the converter, round-trip script, and the DOSBox/dosemu benchmark.
105 lines
2.9 KiB
Bash
Executable File
105 lines
2.9 KiB
Bash
Executable File
#!/bin/sh
|
|
# Assemble a region of the VT1200 ROM with the 1987 TI TMS34010 toolchain
|
|
# (GSPA/GSPLNK/GSPROM, run under DOSBox) and compare the result byte-for-byte
|
|
# with the original.
|
|
#
|
|
# Usage: roundtrip.sh OFFSET SIZE BASE_BIT
|
|
# OFFSET byte offset into vt1200_v22.bin
|
|
# SIZE region size in bytes
|
|
# BASE_BIT bit address the region is linked at (e.g. 3F208000)
|
|
#
|
|
# Example: roundtrip.sh 0x1000 16384 3F208000
|
|
#
|
|
# The ROM is only read. All work happens in this directory.
|
|
set -eu
|
|
|
|
ROOT=$(cd "$(dirname "$0")/../.." && pwd)
|
|
DIR=$(cd "$(dirname "$0")" && pwd)
|
|
WORK="$DIR/work"
|
|
ROM="$ROOT/vt1200_v22.bin"
|
|
DIS="$ROOT/tools/smart34010/dis34"
|
|
|
|
OFF=${1:?offset}
|
|
SIZE=${2:?size}
|
|
BASE=${3:?base bit address}
|
|
OFF=$((OFF))
|
|
SIZE=$((SIZE))
|
|
|
|
mkdir -p "$WORK"
|
|
# tools: extract once from the 1987-11-06 floppy image
|
|
if [ ! -x "$WORK/GSPA.EXE" ]; then
|
|
IMG="$ROOT/tools/tms34010-sdk/1987-05 TMS34010 SDK/1987-11-06 TMS34010 Simulator-C Tools-ASM Tools.img"
|
|
mcopy -s -n -i "$IMG" "::/A2/*" "$WORK/"
|
|
mcopy -s -n -i "$IMG" "::/C2/*" "$WORK/"
|
|
fi
|
|
|
|
# TI hex constants must begin with a decimal digit
|
|
TBASE=$BASE
|
|
case "$TBASE" in
|
|
[0-9]*) ;;
|
|
*) TBASE="0$TBASE" ;;
|
|
esac
|
|
|
|
dd if="$ROM" of="$WORK/rt.bin" bs=1 skip="$OFF" count="$SIZE" 2>/dev/null
|
|
"$DIS" -b "$BASE" -o "$WORK/rt.bin" > "$WORK/rt.dis"
|
|
python3 "$DIR/dis2as34.py" "$BASE" "$SIZE" "$WORK/rt.dis" > "$WORK/RT.ASM"
|
|
sed -i '1i .text' "$WORK/RT.ASM"
|
|
echo '.end' >> "$WORK/RT.ASM"
|
|
|
|
cat > "$WORK/RT.CMD" <<EOF
|
|
-a
|
|
-o rt.out
|
|
-m rt.map
|
|
rt.obj
|
|
SECTIONS
|
|
{
|
|
.text ${TBASE}h: {}
|
|
}
|
|
EOF
|
|
sed -i 's/$/\r/' "$WORK/RT.CMD"
|
|
|
|
rm -f "$WORK"/RT.OBJ "$WORK"/RT.OUT "$WORK"/RT.LST "$WORK"/RTHI.HI "$WORK"/RTLO.LO
|
|
SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \
|
|
timeout 180 dosbox -conf "$DIR/dosbox.conf" -noprimaryconf -nolocalconf \
|
|
-c "mount c $WORK" -c "c:" \
|
|
-c "gspa rt rt.obj rt.lst -l" \
|
|
-c "gsplnk rt.cmd" \
|
|
-c "gsprom -i rt.out rthi rtlo" \
|
|
-c "exit" -exit >/dev/null 2>&1
|
|
|
|
python3 - "$WORK" "$SIZE" <<'EOF'
|
|
import sys
|
|
work, size = sys.argv[1], int(sys.argv[2])
|
|
|
|
def readhex(p):
|
|
d = {}
|
|
for line in open(p):
|
|
line = line.strip()
|
|
if not line.startswith(':'):
|
|
continue
|
|
b = bytes.fromhex(line[1:])
|
|
if b[3] != 0:
|
|
continue
|
|
a = (b[1] << 8) | b[2]
|
|
for i, x in enumerate(b[4:4 + b[0]]):
|
|
d[a + i] = x
|
|
return d
|
|
|
|
hi = readhex(work + "/RTHI.HI")
|
|
lo = readhex(work + "/RTLO.LO")
|
|
out = bytearray()
|
|
for a in sorted(hi):
|
|
out.append(lo[a])
|
|
out.append(hi[a])
|
|
orig = open(work + "/rt.bin", "rb").read()
|
|
n = min(len(orig), len(out))
|
|
bad = [i for i in range(n) if orig[i] != out[i]]
|
|
print("assembled %d bytes, original %d bytes, %d differing" % (len(out), len(orig), len(bad)))
|
|
if len(out) != len(orig) or bad:
|
|
print("FAIL")
|
|
for i in bad[:5]:
|
|
print(" %#x: orig %s out %s" % (i, orig[i:i+8].hex(), out[i:i+8].hex()))
|
|
sys.exit(1)
|
|
print("md5 " + __import__('hashlib').md5(out).hexdigest() + " BYTE-EXACT")
|
|
EOF
|