Files
Sprinter-SDCC/tests/irqtest/irqtest.c
T
snark13 5184415fc4 irq: фикс Phase 1 после отладки — DSS работает в IM 1, чейн всегда на 0x0038
Первая версия висла на первом прерывании. Две причины (verified по
docs/samples/sprinterIntLib.asm, SIO_CTC_KEY.asm и исходникам MAME):

- DSS работает в IM 1 (обработчик 0x0038); I=0x3F — наследие Spectrum
  ROM, НЕ таблица: чтение [I<<8|0xFF] давало мусор (0x00BF) и прыжок в
  никуда. Чейн из трамплина теперь ВСЕГДА jp 0x0038 (interrupted-PC на
  стеке = имитация RST 38); irq_remove безусловно восстанавливает IM 1
- CBL-фильтр по биту 7 порта 0xFE убран: при выключенном CBL бит
  подтянут к 1 (MAME kbd_fe_r: data |= 0xE0) — каждый кадр ложно
  уходил в чейн, user-handler не вызывался бы. Вернуть в Phase 2
  вместе с поддержкой CBL

Попутно подтверждено: порт 0x19 = SIO-A RR0 (Z84C015), бит 0 = Rx
Available; вектора встроенной периферии SIO 0x10..0x1E / CTC 0x06
(заливка 257×H ловит любые); внешний вектор 0xFF.

irqtest: диагностика I до установки + фаза без ESTEX; прогон в MAME:
~49 Гц, клавиатура жива, remove останавливает тики, чистый выход.

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

94 lines
2.7 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.
/*
* irqtest — smoke-тест IM2-модуля (Phase 1, docs/im2_isr_design.md).
*
* Проверяет:
* 1. тикает ~50 Гц (сверка с time() за 3 секунды);
* 2. клавиатура/SYSTIME живы при установленном handler'е (чейн к DSS);
* 3. irq_remove останавливает тики;
* 4. чистый выход в шелл (I восстановлен).
*/
#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <errno.h>
#include <irq.h>
static volatile uint16_t ticks;
static void on_tick(void)
{
ticks++;
}
/* Диагностика: регистр I до установки (что за режим у DSS?). */
static uint8_t get_i(void) __naked
{
__asm
ld a, i
ret
__endasm;
}
/* Busy-пауза без единого ESTEX-вызова (~симв. полсекунды). */
static void busy_wait(void)
{
for (volatile uint16_t i = 0; i < 30000u; i++) ;
}
/* Атомарное чтение 16-битного счётчика, разделяемого с ISR. */
static uint16_t read_ticks(void)
{
uint16_t v;
IRQ_DISABLE();
v = ticks;
IRQ_ENABLE();
return v;
}
int main(void)
{
/* --- диагностика ДО установки --- */
uint8_t old_i = get_i();
const uint8_t *vec = (const uint8_t *)(((uint16_t)old_i << 8) + 0xFF);
printf("I=%02x, [I:FF]=%02x%02x (DSS isr cand: %04x)\n",
old_i, vec[1], vec[0],
(unsigned)(vec[0] | ((uint16_t)vec[1] << 8)));
if (irq_install(on_tick) != 0) {
printf("irq_install failed: errno=%d\n", errno);
return 1;
}
puts("irq installed");
/* Фаза 1: busy-пауза БЕЗ ESTEX — жив ли трамплин/чейн вообще. */
busy_wait();
printf("phase1: ticks=%u (expect >0)\n", read_ticks());
puts("phase2: measuring 3 s vs time()...");
/* Выровняться на границу секунды (time() зовёт ESTEX SYSTIME в
* цикле — заодно стресс чейна к DSS). */
time_t t0 = time(0);
while (time(0) == t0) ;
uint16_t start = read_ticks();
time_t t1 = time(0);
while (time(0) < t1 + 3) ;
uint16_t got = read_ticks() - start;
printf("ticks: %u in 3 s (~%u Hz, expect ~50)\n", got, got / 3);
puts("press any key (keyboard must work)...");
getch();
irq_remove();
uint16_t frozen = read_ticks();
time_t t2 = time(0);
while (time(0) < t2 + 1) ;
if (read_ticks() == frozen) puts("remove: ticks frozen, OK");
else puts("remove: FAIL, still ticking");
puts("irqtest done.");
return 0;
}