14#ifndef _PICO9918_FRAME_H
15#define _PICO9918_FRAME_H
183#define PICO9918_FRAME_STARTUP_FRAMES 900
230#define PICO9918_FRAME_LINE_BUFFER(name, hVirtualPixels) \
231 PICO9918_ALIGN(4) PICO9918_PIXEL_T name[hVirtualPixels]
234#define PICO9918_FRAME_ASSERT_GEOMETRY(hVirtualPixels) \
235 PICO9918_STATIC_ASSERT((hVirtualPixels) >= TMS9918_PIXELS_X * 2, \
236 "hVirtualPixels underflows the half-border count"); \
237 PICO9918_STATIC_ASSERT((hVirtualPixels) % 4 == 0, \
238 "hVirtualPixels must be a multiple of 4 to tile the line exactly")
266 PICO9918_PIXEL_T* pixels);
301 const uint32_t p = (uint32_t)pixel;
302 return ((p & 0x00f) * 0x11u) << 16 | (((p >> 4) & 0x00f) * 0x11u) << 8 | ((p >> 8) & 0x00f) * 0x11u;
313 const uint32_t p = (uint32_t)pixel;
314 return 0xff000000u | (((p >> 8) & 0x00f) * 0x11u) << 16 | (((p >> 4) & 0x00f) * 0x11u) << 8 |
315 ((p & 0x00f) * 0x11u);
pico9918-core - core interface
#define PICO9918_INST_ARG
declare the instance ahead of other parameters
#define PICO9918_INST_ONLY_ARG
declare the instance as the only parameter
#define PICO9918_DLLEXPORT
the linkage every public entry point carries - see LINKAGE MODES above
static uint32_t pico9918_pixel_rgb888(PICO9918_PIXEL_T pixel)
one pixel from the buffer above as 0x00RRGGBB
bool pico9918_frame_output_line(pico9918_t *tms9918, uint32_t outputLine, pico9918_scanline_params_t *params, PICO9918_PIXEL_T *pixels)
generate one OUTPUT line - the entry for a host that scans out a fixed frame
void pico9918_frame_porch(pico9918_t *tms9918)
vertical porch: blank the display and park the scanline counter at the F18A vsync value
bool pico9918_frame_scanline(pico9918_t *tms9918, uint16_t y, const pico9918_scanline_params_t *params, PICO9918_PIXEL_T *pixels)
generate one display scanline: border fill or active render, the F18A scanline and blanking registers...
static uint32_t pico9918_pixel_rgba(PICO9918_PIXEL_T pixel)
one pixel as 0xAABBGGRR: the bytes a little-endian RGBA surface reads as R,G,B,A
void pico9918_frame_raise_end_of_frame_int(pico9918_t *tms9918)
raise this frame's end-of-frame interrupt: latch doneInt, set the SR1 vsync bit, trigger the GPU if R...
pico9918_frame_geometry_t pico9918_frame_end(pico9918_t *tms9918, float tempC, float frameRateHz, pico9918_frame_display_t *display)
true end of frame: advance the frame counter, fold in this frame's temperature reading,...
void pico9918_frame_end_of_scanline(pico9918_t *tms9918)
end-of-frame trigger line: if this frame has not raised its interrupt yet, account for the dropped fr...
void pico9918_frame_update_interrupts(pico9918_t *tms9918, uint8_t tempStatus)
merge newly raised status flags into the SR0 latch, publish it, and bring the /INT pin into agreement
void pico9918_frame_set_config_reload_callback(pico9918_t *tms9918, pico9918_config_reload_fn cb, void *userdata)
register the host's late-config-reload hook
pico9918_frame_geometry_t pico9918_frame_geometry(pico9918_t *tms9918, pico9918_frame_display_t *display)
recompute the vertical display geometry from R0's double-rows bit and R49's row-30 bit,...
the host's mutable vertical display parameters, as the end-of-frame geometry sees them
int displayPixels
vertical active lines of the host's mode (in)
uint16_t vVirtualPixels
(in, and out when yScale > 1)
uint8_t vPixelScale
(in, and out when yScale > 1)
the vertical geometry the end of frame derives
uint32_t vBorder
top border offset, in virtual lines
uint32_t triggerScanline
vBorder + vPixels
int vPixels
active VDP display lines
the host's per-call display parameters, as the scanline sees them
uint16_t vVirtualPixels
virtual lines per field
uint16_t hVirtualPixels
full scanline width; exactly this many pixels are written
uint8_t interlacedFieldOrder
0 or 1: XOR'd with the field number
bool interlaced
the host's mode is interlaced