Files
vt1200/harness/udpstream/vidstream.c
T

91 lines
3.4 KiB
C

/*
* vidstream.c -- terminal side of the VT1200 video stream (startup skeleton).
*
* Task 3 only: claim the working set with ONE malloc at startup and publish
* where it landed. The receive ring (Task 4) and the blit loop (Task 5) build
* on the pointer this file leaves behind.
*
* Marker layout. The design plan names markers as 0x01810020, 0x01810024,
* 0x01810030, ... Those cannot be read literally as bit addresses: the
* TMS34010 is bit-addressed, so 0x01810024 is FOUR BITS after 0x01810020,
* inside the same 32-bit cell. They are byte offsets into the marker page
* (bit 0x01810000, byte 0x00302000), which is the only reading under which
* the plan's 4-byte spacing holds. So a named marker 0x018100NN lives at
*
* bit 0x01810000 + NN * 8
*
* (POOL_PTR = 0x01810100, POOL_FREE before/after = 0x01810120/0x01810140).
* vidstream.lua uses the same rule. See the task-3 report.
*
* K&R C only: no prototypes, no '//', declarations before statements.
*/
#include "romapi.h"
#include "poolcfg.h" /* POOL_BYTES, written by build-stream.sh */
#define MARK_PAGE 0x01810000 /* bit address of the marker page */
#define POOL_PTR (MARK_PAGE + 0x20 * 8) /* u32 bit pointer to the pool */
#define POOL_FREEB (MARK_PAGE + 0x24 * 8) /* u32 heap free bytes, before */
#define POOL_FREEA (MARK_PAGE + 0x28 * 8) /* u32 heap free bytes, after */
#define VID_ALIVE (MARK_PAGE + 0x2c * 8) /* u32 heartbeat while spinning */
#define HEAP_FREE 0x1E8BA0 /* firmware free-byte counter, IN BITS */
#define MARK 0x01A00000 /* .text must end before this bit address */
#define STATIC_BYTES 249856 /* the designed working set, 244 KB */
/*
* Static fallback. pool_static is global so the linker map names it and the
* MAME check can assert the exact address a failed malloc falls back to.
* stack_cushion and the five VRAM words below sit between it and ENTRY.ASM's
* _cstack: TMS34010 pushes grow downward, so the 4 KB stack spills into those
* 4 KB, never into the pool.
*/
unsigned int pool_static[STATIC_BYTES / 4];
unsigned int stack_cushion[1024];
/*
* VRAM.ASM's externals. vram.asm is linked into every payload in this
* directory; the C side owns the values. Task 5 fills the blit_* words.
*/
unsigned int vram_pattern;
unsigned int blit_src, blit_sptch, blit_daddr, blit_dydx;
/*
* The firmware's free-space counter is a 32-bit count IN BITS at
* 0x1E8BA0 (dwt/notes/HEAP.md). POOL_FREE reports bytes, because the
* marker is for humans and the check compares against POOL_BYTES.
*/
static unsigned int heap_bytes()
{
return *(unsigned int *)HEAP_FREE / 8;
}
int main()
{
unsigned int before, after, ptr;
*(unsigned int *)VID_ALIVE = 0;
*(unsigned int *)POOL_PTR = 0;
*(unsigned int *)POOL_FREEB = 0;
*(unsigned int *)POOL_FREEA = 0;
before = heap_bytes();
ptr = malloc_(POOL_BYTES); /* malloc_ takes BYTES, returns BITS */
after = heap_bytes();
if (ptr == 0) {
/* The fallback is the 244 KB static pool by definition; a larger
* request still reports the failure through the low-bit flag. */
ptr = (unsigned int)pool_static;
*(unsigned int *)POOL_FREEB = before | 1;
} else {
*(unsigned int *)POOL_FREEB = before;
}
*(unsigned int *)POOL_FREEA = after;
*(unsigned int *)POOL_PTR = ptr; /* publish last: readers see a complete record */
for (;;) {
*(unsigned int *)VID_ALIVE = *(unsigned int *)VID_ALIVE + 1;
}
}