gfx/time: vsync через polling бита кадра, sleep/delayms без halt-подсчёта
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>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user