Files
Sprinter-SDCC/libc/irq/irq_ctc_remove.c
T
snark13 8a952b99eb irq: Phase 2a — CTC-таймер на отдельном векторе 0x06 (Z84C015)
- irq_ctc_install(handler, div2, div3) / irq_ctc_remove: канал 2 CTC
  делит видеотакт 875 кГц (1 тик = 1 знакоместо), канал 3 считает от
  него и прерывает; f = 875000/(div2*div3), div 0 = 256. Пресет
  IRQ_CTC_VSYNC_DIV2/3 = 112*160 — точное начало кадра ~48.8 Гц БЕЗ
  примеси клавиатуры (вектор 0x06 отделён от общего 0xFF)
- CTC-трамплин: полный сейв -> handler -> EI/RETI; RETI обязателен
  (daisy chain Z84C015 снимает IUS только по опкоду RETI); к DSS не
  чейнится — личное прерывание
- общая IM2-таблица под счётчиком ссылок (_irq_table.c): кадровый и
  CTC-хендлеры независимы, последний unref возвращает I/IM 1;
  atexit-уборка глушит CTC обязательно (иначе кГц-прерывания душат
  шелл после выхода)
- порты/слова по docs/samples: CH0=0x10/CH2=0x12/CH3=0x13,
  0x57/0xD7/вектор в CH0, стоп 0x03
- irqtest: CTC-vsync параллельно с кадровым + произвольная частота;
  MAME: frame 48 Гц, ctc(vsync) 49 Гц (parallel frame жив),
  ctc(50x50) 350 Гц точно по формуле, remove/выход чистые

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:15:04 +03:00

35 lines
1.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* irq_ctc_remove — остановить CTC-таймер (мягкий reset канала 3 —
* control-слово 0x03: reset без TC) и отпустить IM2-таблицу.
* Обязателен перед выходом (atexit-уборка зовёт сама): без остановки
* CTC продолжит дёргать INT после возврата в шелл. Идемпотентно.
*/
#include "_irq.h"
static void ctc_stop(void) __naked
{
__asm
ld a, #0x03 ; CH3: soft reset, прерывание выкл
out (#_IRQ_CTC_CH3), a
ld a, #0x03 ; CH2: остановить и делитель
out (#_IRQ_CTC_CH2), a
ret
__endasm;
}
void irq_ctc_remove(void)
{
if (!_irq_ctc_user) return;
IRQ_DISABLE();
ctc_stop();
_irq_ctc_user = 0;
/* Слоты вектора 0x06 — назад в заливку H (чейн на 0x0038). */
uint8_t *table = _irq_table();
uint8_t h = (uint8_t)((uint16_t)table >> 8);
table[0x06] = h;
table[0x07] = h;
IRQ_ENABLE();
_irq_table_unref();
}