/*
 * 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);
    }
}
