/* * _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; }