/* * gfx_font.c — bitmap-font management shared by the 256- and 16-colour * text renderers. * * Format (ZX-Spectrum-compatible): 256 glyphs × 8 rows × 1 byte = 2 KB, * INTERLEAVED row-major — * offset = row * 256 + char_code * so row 0 of every glyph occupies bytes 0x000..0x0FF, row 1 occupies * 0x100..0x1FF, etc. Each row byte is MSB-first (bit 7 = leftmost px). * * The default source is BIOS WIN_GET_ZG (fn 0xB8) — the active system * character generator. Programs may override with gfx_set_font(). * * Lazy initialisation: gfx_text_256.c / gfx_text_16.c call _gfx_font_ensure * on first use so a pure-graphics program doesn't pay the BIOS call. * * The font pointer and the buffer are exported to the two text renderers * via _gfx_font_ptr (extern), which always points at valid data once * _gfx_font_ensure has been called. */ #include #include #define FONT_BYTES 2048 static uint8_t _gfx_font_buf[FONT_BYTES]; const uint8_t *_gfx_font_ptr = _gfx_font_buf; static uint8_t _gfx_font_loaded = 0; /* BIOS WIN_GET_ZG (0xB8): DE = destination, returns 2 KB. */ static void bios_get_zg(uint8_t *dest) __naked { (void)dest; __asm push ix ; BIOS clobbers IX ex de, hl ; DE = dest (HL was arg) xor a ; font 0 (default) ld c, #0xB8 rst #0x08 pop ix ret __endasm; } void gfx_load_default_font(void) { bios_get_zg(_gfx_font_buf); _gfx_font_ptr = _gfx_font_buf; _gfx_font_loaded = 1; } void gfx_set_font(const uint8_t *font) { _gfx_font_ptr = font; _gfx_font_loaded = 1; } /* Called from text renderers — loads the default font on first use. */ void _gfx_font_ensure(void) { if (!_gfx_font_loaded) gfx_load_default_font(); }