Частота
4DAEh
19886
60Hz
965C
39722
30Hz
E90B
59659
20Hz
Таким образом, нам следует перепрограммировать счетчик 0 таким образом, чтобы он генерировал прерывания с более подходящей для нашей игры частотой - так, чтобы наша игра могла контролировать события чаще чем 18.2 раза в секунду.
Давайте посмотрим, каким образом можно задать соответствующее значение счетчика. Нас интересуют порты ввода/вывода 40h и 43h (все, о чем мы будем говорить, относится к ним): счетчик 0 и соответствующий управляющий регистр. Значения битов управляющего регистра, показаны в таблице 12.4.
Из таблицы 12.4 видно, что в нашем распоряжении много параметров. Впрочем, нам сейчас все они не нужны, нам надо всего-навсего изменить начальное значение счетчика 0. При этом значения других битов должны быть следующими:
§
Режим работы - 2, генератор частоты;
§ Метод подсчета - двоичный;
§ Запись регистра счетчика осуществляется при помощи операции «Прочитать/записать младший байт, а затем старший байт счетчика».
Таким образом, все что мы должны сделать, это записать управляющее слово в порт 43h, а затем выполнить две операции записи в порт 40h. В ходе первой операции записи мы установим значение младшего байта нового значения счетчика, а при второй — значение старшего байта. В том, где какие байты аппаратные средства разберутся сами, поэтому вам об этом волноваться не надо. В Листинге 12.5 приведен текст функции, программирующей таймер.
Листинг 12.5. Перепрограммируем системные часы (OUTATIME.C).
// ВКЛЮЧАЕМЫЕ ФАЙЛЫ /////////////////////////////////////
#include<stdio.h>
#include<conio.h>
// ОПРЕДЕЛЕНИЯ //////////////////////////////////////////
#define CONTROL_8253 0х43 // управляющий регистр 6253
#define CONTROL_WORD
0хЗС // управляющее слово, задающее режим 2,
// двоичный подсчет, запись
// младший/старший байт
#define COUNTERED 0х40 // счетчик
0
#define TIMER_60HZ 0x4DAE // 60Гц
#define TIMER_30HZ 0x965C // 30Гц
#define TIMER_20HZ 0xE90B // 20Гц
#define TIMER_18HZ 0xFFFF // 18.2Гц (стандартная
частота)
// МАКРОСЫ //////////////////////////////////////////////
#define LOW_BYTE(n) (n & 0x00ff)
#define HI_BYTE(n) ((n>>8) & 0x00ff}
// ФУНКЦИИ //////////////////////////////////////////////
void Change Time(unsigned int new count)
{
// послать управляющее слово, задающее режим 2, двоичный подсчет,
// запись
младший/старший'байт
_outp(CONTROL_8253, CONTROL_WORD);
// теперь
запишем младший
значащий байт
в регистр
счетчика
_outp(COUNTER_0,LOW_BYTE(new_count));
//я теперь запишем старший байт в регистр счетчика
_outp(COUNTER_0,HI_BYTE(new_count) ) ;
} // конец Change_Time
// ОСНОВНАЯ ПРОГРАММА ///////////////////////////////////
main()
{
// перепрограммирование таймера с частоты 18.2Гц на частоту 60Гц
Change_Time (TIMER_60HZ);
} // конец,функции main
После окончания этой программы системный таймер будет работать слишком быстро для внутренних часов DOS. Для того чтобы это поправить, вы можете:
§ Перезагрузить компьютер;
§ Запустить программу еще раз, изменив константу, передаваемую функции Change_Time (), на TIMER_18HZ.