/* * _bgi_blit_cols_not_raw — accel-блит КОЛОНКАМИ операцией NOT: приёмник = * ~источник (приёмник в операции НЕ участвует). Колоночный близнец * _bgi_blit_rows_not_raw; про то, почему NOT делается XOR'ом по блоку * единиц, а не `CPL`, — в его шапке и в common/_bgi_ones256.c. * * ЦЕПОЧКА НА КОЛОНКУ (три burst'а): * OUT Port_Y = y0 * LD L,L · LD A,(DE) ; ГОРИЗ: буфер := колонка src (смежная) * LD B,B ; СТОП — разоружить перед сменой HL * PUSH HL · LD HL,#ones · LD L,L · XOR (HL) ; ГОРИЗ: буфер = ~src * LD B,B · POP HL ; вернуть адрес колонки экрана * LD A,A · LD (HL),A ; ВЕРТ: буфер -> видео-колонка * LD B,B * В отличие от _bgi_blit_cols_op_raw, ВТОРОЙ OUT Port_Y здесь НЕ нужен: * op-burst идёт по блоку единиц в ГОРИЗОНТАЛЬНОМ режиме, а Port_Y шагает * только вертикальный. PUSH/POP выполняются под СТОПом (accel разоружён) * — иначе обращение к стеку само стало бы триггером. * * ВХОД (__sdcccall(1)): src→HL, dst→DE; стек: w 4(ix), h 5(ix), * sstride 6/7(ix), y0 8(ix) — как у _bgi_blit_cols_raw. Callee-pop 5 Б. * Raw: без клипа, W3 замаплен снаружи, банк ставит вызывающий, src ВНЕ W3. * Клоббер: AF/BC/DE/HL; IX сохраняется. */ #include "../_bgi.h" void _bgi_blit_cols_not_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 (cn_len_imm), a ;; SMC: src-страйд между колонками (± на вызов — даёт флип) ld a, 6 (ix) ld (cn_slo_imm), a ld a, 7 (ix) ld (cn_shi_imm), a ld b, 4 (ix) ; B = число колонок (0 => 256: djnz) ld c, 8 (ix) ; C = y0 (Port_Y, константа) ex de, hl ; HL = dst (видео), DE = src (ОЗУ) di ; один DI на весь блит ld d, d ; 0x52 — режим размера блока ld a, #0 cn_len_imm = . - 1 ld b, b ; 0x40 — стоп cn_col: ld a, c out (#0x89), a ; Port_Y = y0 (верх колонки) ld l, l ; 0x6D — гориз. режим (колонка src смежна) ld a, (de) ; read-burst : h байт src -> буфер ld b, b ; 0x40 — стоп (разоружить перед PUSH/LD HL) push hl ; спрятать адрес колонки экрана ld hl, #__bgi_ones256 ld l, l ; 0x6D — гориз. режим xor a, (hl) ; op-burst : буфер ^= #FF... = ~src ld b, b ; 0x40 — стоп pop hl ; HL = адрес колонки экрана ld a, a ; 0x7F — верт. режим ld (hl), a ; write-burst: буфер -> видео-колонка ld b, b ; 0x40 — стоп ;; src += sstride (следующая колонка источника) ld a, e add a, #0 cn_slo_imm = . - 1 ld e, a ld a, d adc a, #0 cn_shi_imm = . - 1 ld d, a inc hl ; dst += 1 (следующий x) djnz cn_col ei pop ix ;; callee-pop 5 байт (w,h,sstride:2,y0) pop hl ; ret-адрес pop af pop af inc sp jp (hl) __endasm; }