/*
 * read / write — bulk transfer through ESTEX file handles.
 *
 *   ESTEX READ  ($13) / WRITE ($14):
 *      A = handle, HL = buffer, DE = byte count
 *      → DE = bytes actually transferred, CF = err with code in A.
 *
 * SDCC __sdcccall(1) for 3-arg int functions uses callee-pops for the
 * stack-passed argument; this implementation mirrors the pattern used
 * by SDCC's own z80.lib _memset.
 *
 * On error: sets errno, returns -1.
 */

#include <unistd.h>

int read(int fd, void *buf, size_t n) __naked
{
    (void)fd; (void)buf; (void)n;
    __asm
        pop   iy                       ; IY = return address
        pop   bc                       ; BC = n  (stack arg)
        ld    a, l                     ; A = handle
        ex    de, hl                   ; HL = buf
        ld    d, b
        ld    e, c                     ; DE = n

        push  ix
        push  iy                       ; preserve return addr across RST
        ld    c, #0x13                 ; ESTEX READ
        rst   #0x10
        pop   iy
        pop   ix
        jr    c, _read_err
        ;; DE already holds count read.
        jp    (iy)
    _read_err:
        call  __errno_set
        ld    de, #-1
        jp    (iy)
    __endasm;
}

int write(int fd, const void *buf, size_t n) __naked
{
    (void)fd; (void)buf; (void)n;
    __asm
        pop   iy
        pop   bc
        ld    a, l
        ex    de, hl
        ld    d, b
        ld    e, c
        push  ix
        push  iy
        ld    c, #0x14
        rst   #0x10
        pop   iy
        pop   ix
        jr    c, _write_err
        jp    (iy)
    _write_err:
        call  __errno_set
        ld    de, #-1
        jp    (iy)
    __endasm;
}
