/*
 * _bgi_vspan_raw — вертикальная линия len пикселей от (x,y), mode 0x81,
 * через Vertical Fill акселератора (один burst = колонка до 256 строк).
 *
 * "Raw" leaf: тонкий, БЕЗ клиппинга диапазона.  Проверка (без GFX_NOCHECK)
 * отсекает лишь грубый выход за экран по одной координате — (unsigned)x>=320
 * и (unsigned)y>=256 → тихий возврат (единый стиль с _bgi_hspan_raw).
 *
 * ---- ОГРАНИЧЕНИЯ ВЫЗОВА (ответственность вызывающего) --------------
 *  - W3-скобка: вызывать ТОЛЬКО между _bgi_begin/_bgi_end.
 *  - Клиппинга диапазона НЕТ: требуется 0 <= y и y+len <= 256, иначе
 *    burst вылезет за низ колонки и затрёт чужую видеопамять.  По
 *    сознательному решению safe-версия проверяет валидность только x/y,
 *    но НЕ y+len; отрицательный y и y+len>256 НЕ обрезаются (в отличие от
 *    прежней версии) — координаты обязаны быть уже валидны.
 *  - Диапазон len: 1..256.  len==0: safe-версия (с проверками) тихо
 *    вернётся; fast (GFX_NOCHECK) из-за конвенции акселератора (B=0 =
 *    «256») зальёт 256 строк.
 *
 * __sdcccall(1): x→HL, y→DE(E=y), len→стек(4/5(ix)), color→стек(6(ix)),
 * __naked → callee-pops 3 байта (len+color).  В _gfx_vfill256_segment:
 * HL=addr, C=color, B=len, E=y (без глобального скретча).
 */

#include "../_bgi.h"

void _bgi_vspan_raw(int x, int y, int len, uint8_t color) __naked __preserves_regs(d,e)
{
    __asm
        .globl __gfx_addr_base
        .globl __gfx_vfill256_segment
        push  ix
        ld    ix, #0
        add   ix, sp
#ifndef GFX_NOCHECK
        ld    a, l
        sub   a, #0x40
        ld    a, h
        sbc   a, #0x01
        jr    NC, vs_ret         ; (unsigned)x >= 320
        ld    a, d
        or    a, a
        jr    NZ, vs_ret         ; (unsigned)y >= 256
        ld    a, 4 (ix)
        or    a, 5 (ix)
        jr    Z, vs_ret          ; len == 0 (иначе B=0 → «256»)
#endif
        ld    c, l
        ld    b, h               ; BC = x
        ld    hl, (__gfx_addr_base)
        add   hl, bc             ; HL = base + x
        ld    a, 6 (ix)
        ld    c, a               ; C = color
        ld    a, 4 (ix)
        ld    b, a               ; B = len (256 -> 0)
        call  __gfx_vfill256_segment
    vs_ret:
        pop   ix
        pop   hl
        pop   af
        inc   sp
        jp    (hl)
    __endasm;
}
