/*
 * _errno_set — set `errno` from an ESTEX error code (0..255 in A).
 *
 * Replaces the inline pattern
 *      ld    (_errno),    a
 *      xor   a, a
 *      ld    (_errno+1),  a            ; 7 bytes per error path
 * with a single
 *      call  __errno_set                ; 3 bytes per error path
 *
 * Saves ~4 bytes at every libc error handler that converts an ESTEX
 * code into the C-side `errno`.  Helper itself is 7 bytes; with 10+
 * error paths in our libc the size win is net-positive.
 *
 * ABI:
 *   in:    A  = ESTEX error code (0..255)
 *   out:   HL = A (zero-extended); errno fully overwritten so a prior
 *               large value (e.g. errno = -1) can't leak its high byte.
 *   clobbers: HL, AF flags.  Caller must not depend on HL afterwards.
 *
 * Defensive 16-bit store — see chat 2026-06-02: if anyone ever assigns
 * errno via C (`errno = -1`), the high byte becomes 0xFF, and a partial
 * 8-bit write here would leave that 0xFF in place.  Always writing the
 * full word keeps errno honest regardless of who set it last.
 */

void _errno_set(unsigned char code) __naked
{
    (void)code;
    __asm
        ;; __sdcccall(1): single uint8_t arg already in A.
        ;; Write the two bytes separately so HL/BC/DE/IX/IY remain
        ;; untouched.  Only A is clobbered: it is the input register,
        ;; and ABI does not require preserving it across a void call.
        ld    (_errno), a            ; low byte = code
        xor   a, a
        ld    (_errno+1), a          ; high byte = 0
        ret
    __endasm;
}
