/*
 * write — блочная запись в файловый хендл ESTEX.
 *
 *   ESTEX WRITE ($14): A=handle, HL=буфер, DE=число байт
 *      → CF=err с кодом в A.
 *
 * КВИРК (подтверждён в MAME, DSS 1.71.57, 2026-07-06): вопреки докам
 * («DE = реальное количество записанных байт») на успехе DE = 0.
 * Достоверный признак полной записи — A = 0 при CF = 0 (как у READ,
 * где A=0 «всё», A=FFh «меньше»); solid-c в своём fflush так же
 * закомментировал сравнение по DE и проверяет A.  Поэтому:
 *   CF=1        → errno из A, возврат -1;
 *   CF=0, A=0   → всё записано, возврат n (запрошенного);
 *   CF=0, A!=0  → частичная запись (диск полон), реальный счётчик
 *                 неизвестен → errno=ENOSPC, возврат -1.
 *
 * ABI-паттерн идентичен read() — см. read.c.
 */

#include <unistd.h>

int write(int fd, const void *buf, size_t n) __naked
{
    (void)fd; (void)buf; (void)n;
    __asm
        pop   iy                       ; IY = адрес возврата
        pop   bc                       ; BC = n (стековый аргумент)
        ld    a, l                     ; A = handle
        ex    de, hl                   ; HL = buf
        ld    d, b
        ld    e, c                     ; DE = n
        push  bc                       ; n нужен после RST (всё клобберится)
        push  ix
        push  iy                       ; сохранить адрес возврата через RST
        ld    c, #0x14                 ; ESTEX WRITE
        rst   #0x10
        pop   iy
        pop   ix
        pop   bc                       ; BC = n
        jr    c, _write_err
        or    a, a                     ; A=0 — всё записано (DE недостоверен)
        jr    nz, _write_short
        ld    d, b
        ld    e, c                     ; вернуть запрошенное n
        jp    (iy)
    _write_short:
        ld    a, #10                   ; ENOSPC (DSS 0Ah No free space)
    _write_err:
        call  __errno_set
        ld    de, #-1
        jp    (iy)
    __endasm;
}
