8086 DOS或BIOS功能可以睡眠少于1秒,例如0.75s?

时间:2018-12-12 03:37:54

标签: assembly delay dos x86-16 bios

所以基本上我的游戏运行正常,蛇移动的默认延迟为1秒。

我见过int 1Ah / AH=00中断会稍有延迟,使其运行缓慢,但是如何使它运行更快?还是我理解中断错误?想法是创建关卡,以便当您达到某个分数时,蛇移动得更快。假设我想让蛇移动0.75秒,然后再延迟0.5秒,等等。

1 个答案:

答案 0 :(得分:1)

  

我已经看到int 1Ah / AH = 00中断产生了延迟,使其运行缓慢,但是如何使它运行更快?还是我理解中断错误?

此BIOS函数返回“午夜以来的滴答声”值,其中每个滴答声大约为55毫秒,每天大约有1573040个滴答声。

创建N ms的延迟;用“约55”除以N,然后将午夜以来的当前滴答加到它上。这将是您的到期价格。通常,您需要类似while(current_tick < expiry_tick) { HLT(); }的东西,其中HLT()是等待IRQ的CPU的HLT指令。但是,这并不是那么简单,因为您必须关心当前的滴答声会在午夜滚动。

要解决此问题,您实际上想要更多类似的东西:

#define TICKS_PER_DAY    1573040
#define MS_PER_TICK      55

int milliSecondWait(unsigned int milliseconds) {

    // Calculate expiry time

     (midnightFlag, tick) = get_tick();
     expiryTick = tick + milliseconds / MS_PER_TICK;


    // Wait for the right day

    while(expiryTick > TICKS_PER_DAY) {
        (midnightFlag, tick) = get_tick();
        if( !midnightFlag) {
           HLT();
        } else {
            expiryTick -= TICKS_PER_DAY;
        }
    }

    // Wait for the right tick

    do {
        (midnightFlag, tick) = get_tick();
        if(midnightFlag) {
            break;      // Tick rolled over skipping the expiry time
        }
    } while(tick < expiryTick);

注意:这不是有效的C语言(我假设您将使用某种汇编语言来实现它的伪代码),(midnightFlag, tick) = get_tick();应该是一个返回2个值的函数(例如BIOS功能)。

可以更精确地完成此操作(例如,浮点数学运算,更精确的MS_PER_TICK),这可能包括将计时器/ PIT芯片配置为以更快的频率运行(默认的18.2 Hz频率是最慢的频率)。芯片可以运行)并诱使BIOS仍然正常工作(通过使用计数器来实现时钟分频器,并且仍以18.2 Hz的频率调用BIOS的IRQ处理程序);但我想您不需要所有这些复杂性。 ;)