/* * _bgi_blit_cols_raw — accel block-copy КОЛОНКАМИ (буфер column-major -> * экран). Парный к _bgi_blit_rows_raw, но вертикальный проход: каждая * КОЛОНКА копируется одним accel-burst'ом вниз (Port_Y авто-шагает), * опкод LD A,A (0x7F — «копирование блока для вертикального прохода», * см. docs/reference/accel_r.txt). dst двигается на +1 (следующий x) на * колонку; Port_Y сбрасывается в y0 перед каждой колонкой (accel шагает * его внутри burst'а); src двигается на sstride на колонку. * * ЗАЧЕМ: бесплатный ГОРИЗОНТАЛЬНЫЙ флип персонажей — вызывающий подаёт * src с конца (src+(w-1)*h) и sstride=-h, тогда правая колонка источника * ложится в левый x экрана (зеркало). Реверс без CPU и без удвоения * памяти. Спрайты персонажей хранятся column-major. * * ВХОД (__sdcccall(1)): src→HL, dst→DE; стек: w 4(ix), h 5(ix), * sstride 6/7(ix), y0 8(ix). w — число КОЛОНОК (1..256, 0=256); h — * высота колонки = размер accel-блока (1..256, 0=256); sstride — шаг * адреса src между колонками (±); y0 — стартовый Port_Y. Callee-pop 5 Б. * * Raw: без клиппинга (вызывающий); W3 замаплен (_bgi_begin/end снаружи); * банк выставлен вызывающим (0x5C прозрачный / 0x50 обычный). src ВНЕ W3. * ОДИН DI на весь блит. Колонки > 256 строк режет вызывающий (h ≤ 256). * Клоббер: AF/BC/DE/HL; IX сохраняется. */ #include "../_bgi.h" void _bgi_blit_cols_raw(const uint8_t *src, uint8_t *dst, uint8_t w, uint8_t h, int sstride, uint8_t y0) __naked { (void)src; (void)dst; (void)w; (void)h; (void)sstride; (void)y0; __asm push ix ld ix, #0 add ix, sp ;; SMC: размер accel-блока <- h (высота колонки) ld a, 5 (ix) ld (bc_len_imm), a ;; SMC: src-страйд между колонками (8-бит adc-цепочка, ± на вызов) ld a, 6 (ix) ld (bc_slo_imm), a ld a, 7 (ix) ld (bc_shi_imm), a ld b, 4 (ix) ; B = число колонок (0 => 256: djnz) ld c, 8 (ix) ; C = y0 (Port_Y, константа) di ; один DI на весь блит ld d, d ; 0x52 — режим размера блока ld a, #0 bc_len_imm = . - 1 ld b, b ; 0x40 — стоп (B=счётчик не тронут) bc_col: ld a, c out (#0x89), a ; Port_Y = y0 (сброс на верх колонки) ;; ЧТЕНИЕ — ГОРИЗОНТАЛЬНОЙ копией (LD L,L): src-колонка лежит в ОЗУ ;; СМЕЖНО, адрес шагает (не port_y). ЗАПИСЬ — ВЕРТИКАЛЬНОЙ (LD A,A): ;; port_y шагает вниз по видео-колонке. Режим меняется между read и ;; write (do_accel_block применяет один режим на весь блок). ld l, l ; 0x6D — гориз. копия (для ЧТЕНИЯ смежных) ld a, (hl) ; read-блок: h смежных байт src -> буфер accel ld a, a ; 0x7F — верт. копия (для ЗАПИСИ колонки) ld (de), a ; write-блок: буфер -> видео-колонка (port_y++) ld b, b ; 0x40 — стоп ;; src += sstride (следующая колонка источника) ld a, l add a, #0 bc_slo_imm = . - 1 ld l, a ld a, h adc a, #0 bc_shi_imm = . - 1 ld h, a inc de ; dst += 1 (следующий x) djnz bc_col ei ; закрыть DI-окно pop ix ;; callee-pop 5 байт (w,h,sstride:2,y0) pop hl ; ret-адрес pop af pop af inc sp jp (hl) __endasm; }