46bd9ad0f1
gfx_wait_vsync() и sleep() раньше предполагали, что КАЖДОЕ прерывание на векторе 0xFF — кадровый тик; с CBL/клавиатурой на том же векторе это уже не так. gfx_wait_vsync(): вместо halt — polling бита 5 порта 0xFE (реальная позиция луча, см. MAME kbd_fe_r), доступного пока включён CBL bit7 порта 0x004E. Разделяемое владение портом с CBL через _cbl_port_ref/unref (тот же ref-counting паттерн, что у IM2-таблицы) — cbl_close() возвращает "немой" режим вместо полного выключения, если gfx ещё держит ссылку. Fallback на halt при таймауте. sleep()/delayms(): калиброванный busy-wait по духу delayms.asm вместо подсчёта halt-пробуждений. Калибровка одна на кадр (не на секунду — не переполняет uint16_t и не требует умножения/32-бит арифметики), общий движок libc/time/_sleep_calib.c для обеих функций. Fallback на старое поведение при EBUSY (фрейм-хук занят другим irq_install()). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
43 lines
1.4 KiB
C
43 lines
1.4 KiB
C
/*
|
|
* delayms — заблокироваться на N миллисекунд калиброванным busy-
|
|
* wait'ом (см. _sleep_calib.c — общий движок с sleep(), по духу
|
|
* docs/samples/delayms.asm: DelayMS(HL)).
|
|
*
|
|
* delayms(ms) — просто ms раз калиброванный _sleep_spin() на 1 мс:
|
|
* умножения/32-бит арифметики нет вообще (масштабирование — через
|
|
* вложенный цикл вызовов, не через домножение константы).
|
|
*
|
|
* Fallback: если фрейм-хук уже занят другим irq_install()-клиентом
|
|
* (EBUSY) — калибровку сделать некорректно; точной альтернативы для
|
|
* миллисекундной гранулярности без калибровки нет, поэтому просто
|
|
* ждём один кадр (ei;halt) — грубо, зато не виснет.
|
|
*/
|
|
|
|
#include <unistd.h>
|
|
#include "_sleep_calib.h"
|
|
|
|
static void _delayms_legacy(void) __naked
|
|
{
|
|
__asm
|
|
ei
|
|
halt
|
|
ret
|
|
__endasm;
|
|
}
|
|
|
|
void delayms(uint16_t ms)
|
|
{
|
|
if (ms == 0) return;
|
|
|
|
if (!_sleep_units_per_frame) _sleep_calibrate();
|
|
|
|
if (!_sleep_units_per_frame) {
|
|
_delayms_legacy();
|
|
return;
|
|
}
|
|
|
|
while (ms--) {
|
|
_sleep_spin(_sleep_units_per_ms);
|
|
}
|
|
}
|