pico9918-core 1.3.0
TMS9918A / F18A video display processor emulation in C99
Loading...
Searching...
No Matches
goldenClock.h File Reference

pico9918-core - the golden harness's deterministic clock More...

#include <stdint.h>
+ Include dependency graph for goldenClock.h:

Go to the source code of this file.

Macros

#define GOLDEN_CLOCK_STEP_US   1000u
 
#define PICO9918_HOST_TIME_US()   goldenClockTick()
 

Functions

static uint32_t goldenClockTick (void)
 
static void goldenClockReset (void)
 

Variables

uint32_t goldenClockNow
 

Detailed Description

pico9918-core - the golden harness's deterministic clock

Copyright (c) 2026 Troy Schrapel

This code is licensed under the MIT license

https://github.com/visrealm/pico9918-core

Force-included (-include) into every TU of the golden build - the library AND the harness - through the documented host-override mechanism (see impl/platform.h).

WHY THIS EXISTS

The library's one wall-clock read is PICO9918_HOST_TIME_US(), which defaults to time_us_32() - QueryPerformanceCounter / clock_gettime off-target, so neither of the two library surfaces that read it is repeatable without this:

  • the diagnostics panel's GPU% row, and the flt2Str / uint2Str plumbing behind it, which cannot be covered at all against a wall clock, and
  • the F18A reset/snap timer registers, which are device behaviour a host can read back rather than diagnostics.

The counter below replaces the clock for both, which is the point of putting the op on the whole library rather than in the overlay: a clock injected for the panel alone would leave the timer registers on the wall clock and the resulting flakiness would read as a harness bug.

WHY A FIXED STEP AND NOT A CONSTANT

A constant clock would make totalTime (currentTime - lastUpdateTime) ZERO on the second and every later update, and the GPU% row divides by it - a divide-by-zero producing inf/nan and, worse, a row whose glyphs would no longer respond to the arithmetic being tested. A fixed nonzero STEP keeps the elapsed interval both deterministic and representative.

The step is a per-call increment, not a per-frame one, deliberately: the library must not be able to tell how many times it read the clock, so no call count is baked into a golden. Any read order still yields the same sequence because the sequence is the only state.

goldenClockReset() lets a scenario start the sequence from a known point, so cases stay independent of each other and of scene order - the same property overlayPrimeDiag exists to give the value strings.

Definition in file goldenClock.h.

Macro Definition Documentation

◆ GOLDEN_CLOCK_STEP_US

#define GOLDEN_CLOCK_STEP_US   1000u

Definition at line 61 of file goldenClock.h.

◆ PICO9918_HOST_TIME_US

#define PICO9918_HOST_TIME_US ( )    goldenClockTick()

Definition at line 77 of file goldenClock.h.

Function Documentation

◆ goldenClockTick()

static uint32_t goldenClockTick ( void  )
inlinestatic

Definition at line 65 of file goldenClock.h.

◆ goldenClockReset()

static void goldenClockReset ( void  )
inlinestatic

Definition at line 72 of file goldenClock.h.

Variable Documentation

◆ goldenClockNow

uint32_t goldenClockNow
extern

Definition at line 67 of file golden.c.