/* * _bgi_vspan_raw — вертикальная линия len пикселей от (x,y), * mode 0x81. Вертикальный Fill акселератора сам инкрементирует Port_Y, * так что вся колонка (высота 256) — один burst. W3-naive. */ #include "../_bgi.h" /* Вертикальный Fill: _gfx_acc_len пикселей в колонке _gfx_acc_addr, * верхняя строка _gfx_acc_y. Про SMC и правила FSM акселератора — * см. _gfx_hfill256.c. */ static void vfill_chunk(void) __naked { __asm ld a, (__gfx_acc_len) ld (_vfill256_len_imm), a ld a, (__gfx_acc_y) out (#0x89), a ; стартовый Y ld a, (__gfx_acc_color) ld c, a ld hl, (__gfx_acc_addr) ld d, d ; 0x52 — режим размера блока ld a, #0 ; immediate-длина (патчится) _vfill256_len_imm = . - 1 ld e, e ; 0x5B — вертикальный Fill ld a, c ; A = цвет ld (hl), a ; выстрел ld b, b ; 0x40 — выключить ret __endasm; } void _bgi_vspan_raw(int x, int y, int len, uint8_t color) { if ((unsigned)x >= GFX_WIDTH) return; if (y < 0) { len += y; y = 0; } if (y >= GFX_HEIGHT) return; if (y + len > GFX_HEIGHT) len = GFX_HEIGHT - y; if (len <= 0) return; /* GFX_HEIGHT = 256, полная колонка — один accel-burst. */ _gfx_acc_color = color; _gfx_acc_y = (uint8_t)y; _gfx_acc_addr = (uint16_t)(_gfx_addr_base + (unsigned)x); _gfx_acc_len = (len == 256) ? 0 : (uint8_t)len; vfill_chunk(); }