/*
 * 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 <gfx.h>
#include <stdint.h>

#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();
}
