From 18b496146b722edb81c94f1bf9748397c52cd988 Mon Sep 17 00:00:00 2001 From: "opencode.energia.arti.ee" Date: Fri, 30 Oct 2026 22:47:02 +0000 Subject: [PATCH] fix(stream): absolute payload path; pool must be word-aligned and below the payload --- harness/mame/run-vidstream.sh | 4 ++++ harness/mame/vidstream.lua | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/harness/mame/run-vidstream.sh b/harness/mame/run-vidstream.sh index 2cfe86f..9dcef20 100755 --- a/harness/mame/run-vidstream.sh +++ b/harness/mame/run-vidstream.sh @@ -47,9 +47,13 @@ if [ -f "$ENVFILE" ]; then fi mkdir -p "$LOGDIR" +# Absolute: the Lua runs with MAME's cwd, so a relative default only resolves +# when the caller happens to be at the repo root. +VID_PAYLOAD="$ROOT/harness/udpstream/build/vidstream.bin" set +e VT1200_SKIP_LEVEL1=1 \ VT1200_MODE="$MODE" \ +VID_PAYLOAD="$VID_PAYLOAD" \ VID_POOL_BYTES="$POOL_BYTES" \ VID_STATIC_PTR="$STATIC_PTR" \ VID_ENTRY_PTR="$ENTRY_PTR" \ diff --git a/harness/mame/vidstream.lua b/harness/mame/vidstream.lua index e1610cf..6f9e0ea 100644 --- a/harness/mame/vidstream.lua +++ b/harness/mame/vidstream.lua @@ -10,6 +10,9 @@ -- -- Mode "alloc" (Task 3) asserts: -- * POOL_PTR is non-zero and its BYTE address is in 0x100000..0x400000; +-- * the pointer is 16-bit-word aligned and, for a real allocation, its byte +-- address is BELOW the payload origin (a pool above .text would overlap +-- .text/.bss -- the old range test alone accepted byte 0x318000/0x380000); -- * the heap free counter dropped by POOL_BYTES (plus allocator header); -- * on a failed malloc, POOL_PTR is the linked static buffer and the low bit -- of POOL_FREE (before) marks the fallback, i.e. the payload keeps running. @@ -154,6 +157,20 @@ local function inspect() hex(ptr), hex(pbyte, 6))) end + -- Alignment: a 32-bit C value occupies two 16-bit words on the TMS34010, + -- so the storage needs 16-bit-word alignment. The firmware allocator + -- returns word-aligned bit pointers (observed 0x0090C8D0 = byte + -- 0x12191A, ptr % 16 == 0 but ptr % 32 == 16); a literal ptr % 32 == 0 + -- would reject every correct allocation, so test the real guarantee. + if ptr ~= 0 then + if (ptr % 16) ~= 0 then + print(string.format("VID: pool pointer %s not 16-bit-word aligned -> FAIL", hex(ptr))) + ok = false + else + print(string.format("VID: pool pointer %s is 16-bit-word aligned -> PASS", hex(ptr))) + end + end + if (freeb & 1) == 1 then -- malloc failed: the low bit of the before value is the static flag. local before = freeb - 1 @@ -166,6 +183,18 @@ local function inspect() ok = false end else + -- A real pool must not sit on top of the payload's own .text or .bss. + -- Both are above the poke origin, so "below the origin" covers both. + local origin_byte = math.floor(ORIGIN / 8) + if pbyte >= origin_byte then + print(string.format("VID: pool byte %s is not below the payload origin byte %s -> FAIL", + hex(pbyte, 6), hex(origin_byte, 6))) + ok = false + else + print(string.format("VID: pool byte %s is below the payload origin byte %s -> PASS", + hex(pbyte, 6), hex(origin_byte, 6))) + end + local drop = freeb - freea local delta = drop - POOL_BYTES if delta < 0 then delta = -delta end