8086 DOS или BIOS работают менее 1 секунды, например 0,75 с? - PullRequest
0 голосов
/ 12 декабря 2018

Таким образом, моя игра работает нормально с задержкой по умолчанию на 1 с для движения змеи.

Я видел прерывание int 1Ah / AH=00, чтобы сделать задержку, чтобы замедлить его движение,но как мне заставить его двигаться быстрее?Или я неправильно понимаю прерывание?Идея состоит в том, чтобы создавать уровни, чтобы при достижении определенного значения змея двигалась быстрее.Скажем, я хочу, чтобы змея задержалась на 0,75 с, затем на 0,5 с и т. Д.

1 Ответ

0 голосов
/ 12 декабря 2018

Я видел прерывание int 1Ah / AH = 00, которое заставляло задержку замедлять его движение, но как мне заставить его двигаться быстрее?Или я неправильно понимаю прерывание?

Эта функция BIOS возвращает значение "тики с полуночи", где каждый тик составляет около 55 мс, а в день - около 1573040 тиков.

Для создания задержки N мс;разделите N на "около 55", затем добавьте к нему текущие тики с полуночиЭто будет твой срок действия.В общем, вы хотите что-то вроде while(current_tick < expiry_tick) { HLT(); }, где HLT() - это инструкция HLT процессора, ожидающая IRQ.Однако, это не так просто, потому что вам нужно позаботиться о том, чтобы текущий тик перевернулся в полночь.

Чтобы это исправить, вам на самом деле нужно что-то более похожее на:

#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 Гц - самая медленная, которую чип может запуститьа) и заставить BIOS все еще работать правильно (используя счетчик для реализации делителя тактовых импульсов и все еще вызывая обработчик IRQ в BIOS с частотой 18,2 Гц);но я предполагаю, что вам не нужны все эти осложнения.;)

...