mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-11-03 12:33:16 +02:00
The harness forced the VR150 monitor switch, so the firmware wrote the OS screen at 1024 px / 128-byte rows. VT1200_VRAM_REAL then re-read that framebuffer at the VR319 pitch, which sheared the OS and wrapped the right quarter of every row. Model VR319 (switch 0x60) by default -- the real unit's mode -- so the firmware itself programs 1280x1024 with a 256-byte row pitch (CONVDP=0x14). The renderer's pitch follows VT1200_MONITOR, and the destination span now comes from HEBLNK..HSBLNK instead of x=0, placing the active 1280 px at x=336 in MAME's 1696-wide raster. Verified: clean Terminal Manager at frame 600, legible faithful diagnostics menu and level-1 error screens, tile mode PASS with tile_check 1280/1280 tiles, tablet/mouse pixel-identical. VT1200_MONITOR=VR150 reproduces the old geometry; the regression baseline moves 198 -> 199 (2 PCs) and is recorded in harness/mame/README.md.
117 lines
4.1 KiB
Bash
Executable File
117 lines
4.1 KiB
Bash
Executable File
#!/bin/sh
|
|
# Build the C hello world with the 1987 TI TMS34010 SDK (K&R C compiler).
|
|
#
|
|
# harness/c-hello/build.sh
|
|
#
|
|
# Pipeline: gspcpp -> gspcc -> gspcg -> gspa -> gsplnk, all under DOSBox.
|
|
# entry.asm is assembled separately: it is the process entry (sets STK/FP,
|
|
# calls _main, `rets`) and replaces boot.obj, whose exit path is a `for(;;)`
|
|
# spin followed by an `reti` -- both wrong for a create_process child.
|
|
#
|
|
# .text/.data are linked at bit 0x018A0000, .bss at 0x01A00000 (both inside the
|
|
# firmware's large free block).
|
|
#
|
|
# Outputs: build/hello.coff (the linker output the COFF loader eats),
|
|
# hello.map, hello.lst, entry.lst, hello.obj
|
|
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=018A0000
|
|
BSS=01A00000
|
|
# `build.sh emu` builds a 128-byte-stride variant for the harness's VR150 mode
|
|
# (VT1200_MONITOR=VR150); the default VR319 layout matches the real unit.
|
|
MODE=${1:-real}
|
|
NAME=hello
|
|
if [ "$MODE" = "emu" ]; then NAME=hello-emu; 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
|
|
|
|
if [ "$MODE" = "emu" ]; then
|
|
sed 's/#define ROW_BYTES 256/#define ROW_BYTES 128/' "$DIR/hello.c" > "$WORK/HELLO.C"
|
|
else
|
|
cp "$DIR/hello.c" "$WORK/HELLO.C"
|
|
fi
|
|
cp "$DIR/entry.asm" "$WORK/ENTRY.ASM"
|
|
|
|
{
|
|
printf '%s\n' '-a'
|
|
printf '%s\n' '-o HELLO.out'
|
|
printf '%s\n' '-m HELLO.map'
|
|
printf '%s\n' '-e _start'
|
|
printf '%s\n' 'HELLO.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/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 \
|
|
"$WORK"/HELLO.ASM "$WORK"/HELLO.CPP "$WORK"/HELLO.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 HELLO" \
|
|
-c "gspcc HELLO" \
|
|
-c "gspcg HELLO" \
|
|
-c "gspa HELLO HELLO.obj HELLO.lst -l" \
|
|
-c "gspa ENTRY ENTRY.obj ENTRY.lst -l" \
|
|
-c "gsplnk HELLO.cmd" \
|
|
-c "exit" -exit > "$WORK/dosbox.log" 2>&1
|
|
|
|
if [ ! -f "$WORK/HELLO.OUT" ]; then
|
|
echo "build.sh: GSPLNK produced no HELLO.OUT" >&2
|
|
sed 's/\r$//' "$WORK/HELLO.MAP" 2>/dev/null | tail -20 >&2 || true
|
|
exit 1
|
|
fi
|
|
if [ ! -f "$WORK/HELLO.OBJ" ] || [ ! -f "$WORK/ENTRY.OBJ" ]; then
|
|
echo "build.sh: missing object file (compile/assemble failed)" >&2
|
|
for f in HELLO.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
|
|
# NB: the C code generator writes "***" banner comments into the .s file, so the
|
|
# assembly listing is full of asterisks; only real error lines are matched here.
|
|
for f in HELLO.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
|
|
|
|
cp "$WORK/HELLO.OUT" "$OUT/$NAME.coff"
|
|
cp "$WORK/HELLO.OBJ" "$OUT/hello.obj"
|
|
cp "$WORK/ENTRY.OBJ" "$OUT/entry.obj"
|
|
sed 's/\r$//' "$WORK/HELLO.MAP" > "$OUT/hello.map"
|
|
sed 's/\r$//' "$WORK/HELLO.LST" > "$OUT/hello.lst"
|
|
sed 's/\r$//' "$WORK/ENTRY.LST" > "$OUT/entry.lst"
|
|
[ -f "$WORK/HELLO.ASM" ] && sed 's/\r$//' "$WORK/HELLO.ASM" > "$OUT/hello.s"
|
|
echo "build.sh: $OUT/$NAME.coff ($(wc -c < "$OUT/hello.coff") bytes)"
|
|
sed -n '1,40p' "$OUT/hello.map"
|