/* * _irq_tramp — вход IM2-прерывания (вектор 0xFF: кадр/клавиатура/CBL). * * До выяснения источника трогаем только AF: * - клавиатура (бит 0 порта 0x19 = SIO-A RR0 «Rx Character * Available») уходит напрямую в DSS; * - CBL (бит 7 порта 0xFE) проверяется ТОЛЬКО при зарегистрированном * хуке _irq_cbl_hook: при выключенном CBL бит подтянут к 1 (MAME * kbd_fe_r: data |= 0xE0) и проверка ложно срабатывала бы на * каждом кадре. CBL-путь: полный сейв → насос → restore → * EI/RETI, к DSS НЕ чейнится (личное прерывание); * - кадровое: полный сейв → user-handler → restore → чейн. * * Чейн — ВСЕГДА jp на обработчик DSS 0x0038 (DSS работает в IM 1; * jp с interrupted-PC на стеке имитирует RST 38) — он делает свой * save/restore и завершает EI/RETI: клавиатурный FIFO, SYSTIME и * курсор мыши живут. * * Операнд финального jp (_irq_dss_target) — SMC, патчится из * _irq_table_ref; модуль в _CODE (RAM на Sprinter, W2 в tiny/big). */ #include "_irq.h" void _irq_tramp(void) __naked { __asm push af in a, (#0x19) rrca ; бит 0 — клавиатурный байт принят? jr C, _irq_chain ;; --- CBL? --- старший байт хука ненулевой у любого ;; W2-адреса — для проверки «хук есть» хватает одного байта. ld a, (__irq_cbl_hook + 1) or a, a jr Z, _irq_frame in a, (#0xFE) rlca ; бит 7 — запрос блока CBL? jr NC, _irq_frame ;; --- CBL: сейв, насос, restore, EI/RETI (без DSS) --- push bc push de push hl .db 0x08 ; ex af,af (теневой AF) push af exx push bc push de push hl push ix push iy ld hl, (__irq_cbl_hook) call _irq_call_hl pop iy pop ix pop hl pop de pop bc exx pop af .db 0x08 ; ex af,af (теневой AF) pop hl pop de pop bc pop af ei reti _irq_frame: ;; --- кадровое прерывание --- push bc push de push hl ld hl, (__irq_user) ld a, h or a, l jr Z, _irq_pop3 ; handler не установлен ;; Сохранить теневой набор и индексные — user-код клобберит всё. .db 0x08 ; ex af,af (теневой AF) push af exx push bc push de push hl push ix push iy ld hl, (__irq_user) call _irq_call_hl pop iy pop ix pop hl pop de pop bc exx pop af .db 0x08 ; ex af,af (теневой AF) _irq_pop3: pop hl pop de pop bc _irq_chain: pop af ;; Всегда к DSS (IM 1, обработчик 0x0038) — EI/RETI за ним. .db 0xC3 ; jp nn __irq_dss_target:: .dw 0x0038 ; SMC: подтверждается в _irq_table_ref _irq_call_hl: jp (hl) __endasm; }