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