/*
 * hex_print.c — compact hex print primitives ported from solid-c
 * (third_party/solid-c/SRC/CLIB/STDLIB.ASM, modules hex8/hex16/hex32).
 *
 *   void hex8 (uint8_t  v) — always-2-digit  "00"      ..  "FF"
 *   void hex16(uint16_t v) — always-4-digit  "0000"    .. "FFFF"
 *   void hex32(uint32_t v) — always-8-digit  "00000000" .. "FFFFFFFF"
 *
 * Each nibble is emitted via the classic Z80 `cp 10 / sbc 0x69 / daa`
 * trick — 5 bytes per nibble.  hex8 self-calls for the high nibble
 * then falls through for the low nibble.  hex16/hex32 split into two
 * hex8/hex16 calls.
 *
 * ESTEX PUTCHAR ($5B) preserves IX (empirically verified) so we skip
 * the usual push/pop ix around the RST.
 */

#include <stdio.h>
#include <stdint.h>

void hex8(uint8_t v) __naked
{
    (void)v;
    __asm
        ;; A = v on entry.
        push  af
        rra
        rra
        rra
        rra
        call  _hex8_digit
        pop   af
    _hex8_digit:
        and   a, #0x0F
        cp    a, #10
        sbc   a, #0x69
        daa
        ld    c, #0x5B
        rst   #0x10
        ret
    __endasm;
}

void hex16(uint16_t v) __naked
{
    (void)v;
    __asm
        ;; HL = v on entry.
        ld    a, h
        push  hl
        call  _hex8
        pop   hl
        ld    a, l
        jp    _hex8                ; tail-call
    __endasm;
}

void hex32(uint32_t v) __naked
{
    (void)v;
    __asm
        ;; HL = high16, DE = low16 on entry (SDCC HLDE).
        push  de
        call  _hex16
        pop   hl
        jp    _hex16               ; tail-call
    __endasm;
}
