Files
vt1200/harness/hello-world
arti 8f831eaf33 fix(video): model the real unit's VR319 monitor
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.
2026-10-31 20:53:51 +02:00
..

Hello world: a payload built with the TMS34010 SDK

A minimal payload written in GSPA assembly, assembled and linked by the 1987 TI TMS34010 SDK (GSPA 2.00 / GSPLNK 2.00) under DOSBox, then loaded into main RAM and entered by harness/mame/hello.lua.

This is our code, not a disassembly of the firmware. The ROM (vt1200_v22.bin, md5 b46a3e442ccb86134d2356bd70d22fd2) is only read.

Read harness/mame/HELLO_WORLD_REPORT.md for the evidence and caveats. The short version:

  • linked at bit 0x01800000 (byte 0x00300000 of the 4 MiB main RAM);
  • writes 0xDEAD, 0xBEEF and a loop counter 0x0400 to RAM at bit 0x01810000, and fills a 256x64 block in video RAM at row 100, column 64;
  • both are observed from inside the emulator (RAM readback) and from a frame dump (white block at screen x 256..511, y 136..199).

Pitch note. hello.asm writes 1024-bit rows (the old derived layout). The harness now defaults to the real unit's VR319 2048-bit layout, so add VT1200_MONITOR=VR150 to the run below to see the block where this README says it is; at the VR319 default the rendered block is sheared because the payload, not the firmware, chose the old pitch.

Build

harness/hello-world/build.sh                 # origin defaults to 01800000h
harness/hello-world/build.sh 01840000        # alternate bit address

It extracts the DOS tools into work/ on first use (same image and method as harness/sdk-roundtrip/roundtrip.sh), assembles hello.asm, links it, and extracts the .text section from the COFF with cofextract.py.

Outputs:

file what it is
payload.bin the linked bytes (82 bytes)
payload.map GSPLNK's map, with the bit-address origin
work/HELLO.LST GSPA listing (addresses in bits)

payload.bin and payload.map are committed, so the MAME run does not need DOSBox or the SDK. Rebuild them to change the payload.

Run

From the repository root:

M=/home/arti/code/k-space/mame0289/vt1200

HELLO_END=150 \
VT1200_DUMP_FRAME=145 VT1200_DUMP_RAM=145 \
VT1200_DUMP_DIR=harness/hello-world/evidence \
$M vt1200 -rompath harness/mame/roms -video none -sound none -nothrottle \
   -debug -debugger none \
   -autoboot_script harness/mame/hello.lua -autoboot_delay 0

Environment knobs (all optional):

variable default meaning
HELLO_AT 120 frame at which to load the payload and arm the entry breakpoint
HELLO_END 150 frame at which to inspect the markers and exit
HELLO_PAYLOAD harness/hello-world/payload.bin linked payload
HELLO_ORIGIN 0x01800000 load/entry bit address

Set HELLO_AT=9999 for the control run: nothing is loaded, and the markers stay zero.

Mechanism (and what it is not)

hello.lua lets the firmware boot to the level-0 diagnostics menu, writes the payload bytes into RAM at frame 120, and arms a breakpoint on the menu's idle loop (3FDCE400, dsjs a9, itself). The breakpoint action assigns pc = 01800000 and resumes. The payload then runs, masks interrupts, writes its markers and the VRAM block, and spins.

This is debugger entry, not a delivery mechanism. It proves the toolchain produces runnable code and the payload runs on the emulated CPU; it says nothing about how code would reach a real terminal.

Evidence files

file what it shows
evidence/hello-run.log transcript of the run above
evidence/hello-ram-marker.txt RAM excerpt: payload bytes and marker words
evidence/hello-frame-145.png the frame at 145, cropped to the menu + block
evidence/control-frame-145.png the same crop with HELLO_AT=9999 (no block)
evidence/hello-payload.dis dis34 disassembly of payload.bin, base 01800000

The .ppm and .bin dumps referenced in hello-run.log are large and are not committed; the command above regenerates them.