pico9918-core 1.3.0
TMS9918A / F18A video display processor emulation in C99
Loading...
Searching...
No Matches
diag.h
Go to the documentation of this file.
1/**
2 * \file
3 * \brief pico9918-core - Diagnostics overlay
4 *
5 * Copyright (c) 2024 Troy Schrapel
6 *
7 * This code is licensed under the MIT license
8 *
9 * https://github.com/visrealm/pico9918-core
10 *
11 * The diagnostics panels the device draws over the borders when the PICO9918_CONF_DIAG*
12 * config bytes are set: render timings, frame rate, GPU load, temperature, the
13 * register dump, the table addresses and the palette strip. Device behaviour,
14 * not decoration - the panels are driven entirely by library-owned config bytes
15 * rendering library-owned state.
16 *
17 * Geometry arrives per call, like the splash overlay. Everything the library
18 * cannot know - the host's frame rate, its dropped-frame accounting, its board
19 * revision strings and its display-mode labels - arrives through push setters,
20 * called per frame or rarer. The library never reaches back into the host.
21 *
22 * pico9918_diag_render_text is public because the host also draws its own text over
23 * the border (the pending-display banner); the font and the glyph blitter live
24 * here, so there is one text path rather than two.
25 */
26
27#ifndef _PICO9918_DIAG_H
28#define _PICO9918_DIAG_H
29
30#include "impl/platform.h"
31#include "pico9918.h"
32#include "pico9918_build_config.h"
33
34#include <stdint.h>
35
36/*
37 * Optional GPU-frames row. The count is host-pushed (the host's frame hook sees
38 * the F18A status bit), so the row and its setter appear together or not at all.
39 */
40#ifndef PICO9918_DIAG_GPU_FRAME_COUNTER
41/** \brief set to 1 to build the GPU-frames row and its setter */
42#define PICO9918_DIAG_GPU_FRAME_COUNTER 0
43#endif
44
45/* glyph cell size of the built-in font, for callers that centre text */
46#define PICO9918_DIAG_CHAR_WIDTH 6 /**< glyph cell width, pixels */
47#define PICO9918_DIAG_CHAR_HEIGHT 6 /**< glyph cell height, pixels */
48
49/*
50 * This API hands out a PICO9918_PIXEL_T buffer and the pixel width is a per-build
51 * choice, so a consumer compiled against a different policy than the library
52 * would stride every write wrongly - with a clean compile and a clean link, then
53 * corrupt pixels. Assert UNCONDITIONALLY against the width recorded when the
54 * library was built. (Same reasoning as overlay/splash.h; see the note
55 * there on why a compile definition cannot do this job.)
56 */
57PICO9918_STATIC_ASSERT(sizeof(PICO9918_PIXEL_T) == PICO9918_BUILD_PIXEL_SIZE,
58 "PICO9918_PIXEL_T does not match the width this library was built "
59 "with (see pico9918_build_config.h). Select the same pixel "
60 "policy the library used - one ships, and it is the default in "
61 "platform/ on both platforms.");
62
63#ifdef __cplusplus
64extern "C"
65{
66#endif
67
68 /** one-time initialisation of the panel value strings */
70 void pico9918_diag_init(void);
71
72 /** rebuild the panel row table - call whenever the PICO9918_CONF_DIAG* bytes change */
75
76 /** core temperature, degrees C */
78 void pico9918_diag_set_temperature(float tempC);
79
80 /** system clock, Hz */
82 void pico9918_diag_set_clock_hz(float clockHz);
83
84 /**
85 * Host display timing, Hz. The library has no clock of its own, so the FPS row is
86 * (16 - droppedFrames) * (frameRate / 16); only this term is pushed. The dropped
87 * frames come from the frame module, which owns that accounting and is read
88 * directly.
89 */
91 void pico9918_diag_set_frame_rate(float frameRateHz);
92
93 /**
94 * Version identity for the HWVER / FWVER rows. The strings are host policy: only
95 * the host knows its board revisions and its own firmware version, and the
96 * library must not carry PICO9918 revision knowledge. Both are copied into the
97 * panel buffers, so the caller keeps no lifetime obligation. Either may be NULL
98 * to leave that row's current text alone.
99 */
101 void pico9918_diag_set_version_info(const char* hwVersion, const char* fwVersion);
102
103 /**
104 * Display-mode label for the OUTPUT row, e.g. "480P " + "@60". The encoding of
105 * PICO9918_CONF_DISP_DRIVER is host policy (which timings a board supports), so the host
106 * supplies the label rather than the library carrying board-specific strings.
107 * `name` is copied; `units` is retained by pointer, so it must have static
108 * storage duration. Either may be NULL to leave that part alone.
109 */
111 void pico9918_diag_set_output_name(const char* name, const char* units);
112
113 /** accumulate one scanline's render and total time, in microseconds */
115 void pico9918_diag_update_render_time(uint32_t renderTime, uint32_t frameTime);
116
117 /** recompute the panel values - call once per frame */
119 void pico9918_diag_update(PICO9918_INST_ARG uint32_t frameCount);
120
121 /**
122 * render text into the scanline buffer, if row `scanline` falls in the glyph
123 * band starting at `y`. Returns the x position just past the last pixel written,
124 * so calls chain. A cell's unlit pixels are darkened, not left untouched.
125 * `x` must be a whole number of ink words - cells are written a word at a time.
126 */
128 int pico9918_diag_render_text(uint16_t scanline, const char* text, uint16_t x, uint16_t y, PICO9918_PIXEL_T fg,
129 PICO9918_PIXEL_T* pixels);
130
131 /** render the diagnostics panels for border row `y` */
133 void pico9918_diag_render(PICO9918_INST_ARG uint16_t y, uint32_t vVirtualPixels,
134 PICO9918_PIXEL_T* pixels);
135
136#ifdef __cplusplus
137}
138#endif
139
140#endif // _PICO9918_DIAG_H
void pico9918_diag_set_clock_hz(float clockHz)
system clock, Hz
Definition diag.c:265
void pico9918_diag_init(void)
one-time initialisation of the panel value strings
Definition diag.c:200
void pico9918_diag_set_temperature(float tempC)
core temperature, degrees C
Definition diag.c:260
void pico9918_diag_set_version_info(const char *hwVersion, const char *fwVersion)
Version identity for the HWVER / FWVER rows.
Definition diag.c:226
void pico9918_diag_update(pico9918_t *tms9918, uint32_t frameCount)
recompute the panel values - call once per frame
Definition diag.c:280
void pico9918_diag_config_updated(pico9918_t *tms9918)
rebuild the panel row table - call whenever the PICO9918_CONF_DIAG* bytes change
Definition diag.c:541
int pico9918_diag_render_text(uint16_t scanline, const char *text, uint16_t x, uint16_t y, PICO9918_PIXEL_T fg, PICO9918_PIXEL_T *pixels)
render text into the scanline buffer, if row scanline falls in the glyph band starting at y.
Definition diag.c:348
void pico9918_diag_render(pico9918_t *tms9918, uint16_t y, uint32_t vVirtualPixels, PICO9918_PIXEL_T *pixels)
render the diagnostics panels for border row y
Definition diag.c:596
void pico9918_diag_set_output_name(const char *name, const char *units)
Display-mode label for the OUTPUT row, e.g.
Definition diag.c:243
void pico9918_diag_set_frame_rate(float frameRateHz)
Host display timing, Hz.
Definition diag.c:274
void pico9918_diag_update_render_time(uint32_t renderTime, uint32_t frameTime)
accumulate one scanline's render and total time, in microseconds
Definition diag.c:393
pico9918-core - core interface
#define PICO9918_INST_ARG
declare the instance ahead of other parameters
Definition pico9918.h:71
#define PICO9918_INST_ONLY_ARG
declare the instance as the only parameter
Definition pico9918.h:72
#define PICO9918_DLLEXPORT
the linkage every public entry point carries - see LINKAGE MODES above
Definition pico9918.h:41
pico9918-core - Platform Abstraction