/* * _gfx_hfill256_segment — горизонтальный Fill-burst акселератора (register-ABI). * * ВХОД (регистры; вызывается ТОЛЬКО из asm — raw-примитивами): * HL = CPU-адрес начала строки (base + x) * C = цвет * B = длина (0 = 256 — конвенция акселератора) * E = y (строка для Port_Y) * Клоббер: A, F. Сохраняет BC/DE/HL/IX/IY — все опкоды акселератора это * `ld r,r`, т.е. no-op'ы по регистрам, поэтому color(C)/len(B)/y(E) переживают * accel-последовательность (это и есть смысл register-ABI — без скретча в _DATA). * Pre: W3 замаплен на видеобанк (вызывающий сделал _bgi_begin). * * Опкоды (docs/converted/accel_r.txt): * LD D,D (0x52) режим «задать размер блока»; СЛЕДУЮЩИЙ байт — длина, * ОБЯЗАН быть immediate-операндом LD A,n (0x3E) → SMC-патч. * LD C,C (0x49) горизонтальный Fill (LD (HL),A заливает n байт) * LD B,B (0x40) выключить акселератор * Другой `ld a,#n` между LD C,C и стреляющим LD (HL),A вставлять нельзя — * FSM акселератора перечитает immediate как новый размер блока. */ #include "../_bgi.h" void _gfx_hfill256_segment(void) __naked { __asm ld a, b ld (_hfill256_len_imm), a ; SMC: размер блока <- B ld a, e out (#0x89), a ; Port_Y <- E (y) di ld d, d ; 0x52 — режим размера блока ld a, #0 _hfill256_len_imm = . - 1 ld c, c ; 0x49 — горизонтальный Fill (C=color, no-op) ld a, c ; 0x79 — A = цвет ld (hl), a ; выстрел; заливает len байт ld b, b ; 0x40 — выключить (B=len, no-op) ei ret __endasm; }