# 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). ## Build ```sh 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: ```sh 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.