/*
 * absread — абсолютное чтение секторов логического диска через
 * BIOS $55 (rst 8): A=диск, HL:IX=32-битный номер сектора (HL=старшие,
 * у нас всегда 0), DE=буфер, B=число секторов.  Нумерация с 0 от
 * начала ЛОГИЧЕСКОГО диска (0 = boot-сектор, с 1 — первая FAT).
 * При ошибке errno=EREAD (как у Solid-C), возврат -1.
 * Буфер — в #4000-#BFFF (требование BIOS).
 */

#include <dos.h>
#include <errno.h>

static uint8_t  abs_disk;
static uint8_t  abs_cnt;
static uint16_t abs_sect;
static uint16_t abs_buf;
static int8_t   abs_rc;

int absread(uint8_t disk, uint16_t nsect, uint8_t count, void *buffer)
{
    abs_disk = disk;
    abs_sect = nsect;
    abs_cnt  = count;
    abs_buf  = (uint16_t)buffer;

    __asm
        push  ix
        ld    ix, (_abs_sect)       ; IX = младшие 16 бит номера сектора
        ld    hl, #0                ; HL = старшие 16 бит (всегда 0)
        ld    de, (_abs_buf)        ; DE = буфер
        ld    a, (_abs_cnt)
        ld    b, a                  ; B = число секторов
        ld    a, (_abs_disk)        ; A = диск
        ld    c, #0x55              ; BIOS READ (сектора)
        rst   #0x08
        pop   ix
        ld    a, #0
        jr    nc, _absr_done
        ld    a, #25                ; EREAD (код Solid-C)
        call  __errno_set
        ld    a, #0xFF
    _absr_done:
        ld    (_abs_rc), a
    __endasm;
    return abs_rc;
}
