Засоби BIOS для роботи з таймером

Для роботи з таймером (точніше, для роботи з каналом 0 таймера) BIOS має

дві функції переривання 1Ah. Вони дозволяють прочитати поточний вміст лічильника та змінити його. Функція 00h призначена для читання вмісту лічиль- ника таймера:

Вхід: AH = 00h

Вихід: CX – старше слово лічильника;

DX – молодше слово лічильника;

AL = 0, якщо після перезапуску таймера пройшло більше 24 годин. Змінити вміст лічильника таймера можна за допомогою функції 01h:

Вхід: AH = 01h

CX – старше слово лічильника;

DX – молодше слово лічильника.

BIOS комп’ютерів IBM PC AT містить ще дві цікаві функції для роботи з таймером: 83h та 86h переривання 15h. Функція 83h дозволяє запустити таймер на

рахунок, вказавши адресу деякого байта в оперативній пам’яті. Після закінчення часу, заданого при запуску таймера, функція встановлює старший біт вказаного

байта на одиницю, сигналізуючи таким чином програмі про завершення вказаного часового інтервалу.

Вхід: AH = 83h

AL = код підфункції (0 – встановити інтервал, запустити таймер);

(1 – відмінити роботу таймера);

CX = старше слово часу роботи таймера, мкс

DX = молодше слово часу роботи таймера, мкс

ES:BX = адреса байта, в якому після закінчення інтервалу часу старший біт буде встановлено на одиницю.

Функція 86h спеціально призначена для формування затримок. Вона дозво-

ляє визначити час затримки в мікросекундах, що зручно для багатьох задач. Під час виконання затримки дозволені переривання.

Вхід: AH = 86h

CX = старше слово часу затримки, мкс

DX = молодше слово часу затримки, мкс

Генерація звукових сигналів

Як відомо, канал 2 системного таймера керує гучномовцем комп’ютера – він

 


генерує прямокутні імпульси з частотою, рівною 1193180 / початкове значення лі- чильника герц. Але гучномовець не просто з’єднаний з виходом каналу 2 таймера. Порт виводу 61h також використовується для керування гучномовцем. Молодший біт порту 61h при встановленні на 1 дозволяє роботу каналу, тобто генерацію імпульсів для гучномовця, а при встановленні на 0 забороняє.

Додатково для керування гучномовцем використовується біт 1 порту 61h.

Якщо цей біт встановлений на 1, сигнали з виходу каналу 2 таймера через схему збігу зможуть проходити на гучномовець. Якщо в біті 1 нуль, то схема збігу забороняє проходження сигналів на гучномовець.

Генерація випадкових чисел

Для генерації випадкових чисел краще використовувати канал 2 в режимі 3.

У регістр лічильника каналу заноситься значення, що дорівнює діапазону потрібних випадкових чисел. Наприклад, якщо записати в регістр число 80 та

запустити канал таймера, отримані випадкові числа будуть дежати в діапазоні від

0 до 79.

 

 

МЕТОДИЧНІ ВКАЗІВКИ

 

 

В даній роботі пропонується дослідити і протестувати декілька програм, які використовують системний таймер для різноманітних цілей. Програми формують часові інтервали, генерують звук і послідовності випадкових чисел.

Для виконання роботи необхідні грунтовні знання архітектури і принципів функціонування таймера, а також знання та навички програмування каналів таймера та портів 60h та 61h.

 

 

ЛІТЕРАТУРА

 

 

1. Гук М. Аппаратные средства IBM PC. Энциклопедия. – СПб.: “Издательс-

тво Питер”, 1999. – 816 с.

2. Гуржій А. М., Коряк С. Ф., Самсонов В. В., Скляров О. Я. Архітектура, принципи функціонування і керування ресурсами IBM PC: Навч. посібник. Харків: ТОВ. “Компанія СМІТ”, 2003. – 512 с.

3. Зубков С. В. Ассемблер для DOS, Windows и Unix. – М.: ДМК, 1999. –

640 с.

4. Фролов А. В., Фролов Г. В. Аппаратное обеспечение персонального ком-

пьютера. – М.: ДИАЛОГ МИФИ, 1997. – 304 с.

 

 

ЗАВДАННЯ

 

 

1. На вінчестері створити каталог TIME.

2. За допомогою редактора середовища Borland C++ 3.1 створити символь-

ний файл тексту програми delay – 1 та записати його в каталог TIME.

3. Виконати налагодження програми та запустити її на виконання.

4. Спробувати проконтролювати за допомогою секундоміра годинника точність відліку часу програмною затримкою.

 


5. Змінити програму таким чином, щоб точність формування інтервалу часу була в межах однієї мс. Для цього:

5.1 Обчислити відповідний коефіцієнт перерахунку для нульового каналу

таймера за формулою:

 

 

(0,84 мкс) ´ Ксч = (1 мс) ´ 1000

 

 

та записати його в шістнадцятковому форматі.

5.2 Сформувати керуюче слово для режиму 3; тип рахунку – двійковий;

спосіб запису коефіцієнта перерахунку – молодший байт, старший байт; канал

– 0.

5.3 Написати модуль перепрограмування каналу 0 таймера та помістити його у відповідне місце програми затримки.

5.4 У кінці програми передбачити відновлення попереднього режиму

роботи каналу 0 таймера.

5.5 Виконати налагодження програми та запустити її на виконання.

6. Дослідити програму формування часового інтервалу, що використовує функцію 86h переривання 15h delay – 2.

7. За допомогою редактора середовища Borland C++ 3.1 створити символь-

ний файл тексту програми delay – 2 та записати його в каталог TIME.

8. Виконати налагодження програми та запустити її на виконання.

9. Порівняти характеристики програми з характеристиками попередньої

(розмір коду, точносні характеристики, можливі впливи на роботу системи).

10. Зробити відповідні висновки та розробити рекомендації по застосуванню розглянених підходів до формування часових інтервалів у прикладних програмах.

11. Дослідити програму bip, що формує звукові сигнали пропорційні скен-

коду натисненої клавіши клавіатури. Визначити, в якому режимі працює канал 2 таймера.

12. За текстом програми нарисувати схему алгоритму.

13. За допомогою редактора середовища Borland C++ 3.1 створити символь-

ний файл тексту програми bip та записати його в каталог TIME.

14. Виконати налагодження програми та запустити її на виконання.

15. Змінити коефіцієнт пропорційності k спочатку в більший, а потім в менший бік та виконати пункт 14.

16. Зробити висновки про власні спостереження.

17. Вивчити та дослідити структуру програми random, що призначена для формування послідовності псевдовипадкових чисел у заданому діапазоні.

18. Відновити схему алгоритму програми.

19. Для більшої наочності зображення псевдовипадкових чисел змінити програму так, щоб числа відображувались на екрані у вигляді стовпчастої

діаграми.

20. Розробити програму, в якій діапазон зображення чисел можна було б задавати з екрана в діалоговому режимі.

21. Зробити висновки.

 

 


ТЕКСТИ ПРОГРАМ

 

// delay – 1

#include <conio.h>

#include <stdio.h>

 

void tm_delay (int ticks)

{

asm {

// збереження в стеку вмісту регістра SI

push si

// помістити змінну ticks у регістр SI

mov si, ticks

// занести код функції 00h переривання 1Ah в регістр AH

mov ah, 00h

// викликати обробник переривання 1Ah int 1Ah

// переписати молодше слово лічильника із DX у BX

mov bx, dx

// скласти вміст регістрів BX, SI

add bx, si

}

// мітка переходу для організації циклу затримки

delay_loop:

asm {

// викликати обробник переривання 1Ah int 1Ah

// порівняти поточне значення лічильника із заданим

cmp dx, bx

// якщо нерівні, йти на мітку циклу затримки

jne delay_loop

// інакше, відновити вміст регістра SI

pop si

}

}

 

void main (void)

{

int n;

char c = „y‟;

 

while (c!= „n‟) {

clrscr ();

printf (“Введіть час затримки в секундах: ”);

scanf (“%d”, &n);

 

tm_delay (n * 18);

 

printf (“Завершено. Бажаєте ще (y/n)?”);

c = getch ();

}

}

 

 


// delay – 2

#include <dos.h>

#include <conio.h>

#include <stdio.h>

 

void main (void)

{

unsigned long time_mks;

unsigned int lw, hw;

 

clrscr ();

printf (“Введіть час затримки, мкс: ”);

scanf (“%ld”, &time_mks);

 

// формування молодшого та старшого байтів затримки

lw = (unsigned int) (time_mks & 0x0000FFFF);

hw = (unsigned int) ((time_mks & 0xFFFF0000) >> 16);

 

asm {

// зберігаємо в стеку всі регістри

pusha

// заносимо в регістр AH номер функції 0x86 mov ah, 0x86

// заносимо в регістр CX старший байт затримки

mov cx, hw

// заносимо в регістр DX молодший байт затримки

mov dx, lw

// викликаємо обробник переривання 15h

int 0x15

// відновлюємо вміст регістрів

popa

}

 

printf (“Час затримки закінчився”);

}

 

// bip

#include <conio.h>

 

void beep (void)

{

asm {

// зберегти вміст регістрів AX і CX у стеку

push ax

push cx

// коефіцієнт перерахунку – в регістр CX

mov cx, frac

// в регістр AL – керуюче слово таймера

mov al, 0xB6

// керуюче слово відсилається в порт 43h з регістра AL

out 0x43, al

 


 

}

tm:


// коефіцієнт перерахунку заноситься в регістр CX

mov ax, cx

// в порт 42h пересилається спочатку молодший,

out 0x42, al

mov al, ah

// а потім старший байт

out 0x42, al

// читається байт з порту 61h in al, 0x61

// прочитаний байт зберігається в регістрі AH

mov ah, al

// у два молодші біти записуються одиниці

or al, 3

// нове значення відсилається в порт 61h

out 0x61, al


asm {

// в регістр AL – скан-код натисненої клавіши

in al, 0x60

// утворюється додатковий скан-код

and al, 0x80

// залишитись у циклі, якщо клавіша натиснена

jz tm

// відновлюємо початкове значення байта

mov al, ah out 0x61, al

// відновлюємо регістри CX та AX

pop cx

pop ax

}

}

 

void main (void)

{

int frac;

char k;

 

clrscr ();

printf (“Натискайте клавіши та слухайте звуки.\n”);

printf (“Для завершення роботи натисність ECS.\n”);

 

while ((k = getch ())!= 27) {

frac = k * 100;

beep ();

}

}

 

// random

#include <dos.h>

 

void rnd_set (int bound)

 


{

outp (0x43, 0xB6);

outp (0x42, bound & 0x00FF);

outp (0x42, (bound & 0xFF00) >> 8);

outp (0x61, inp (0x61) | 1);

}

 

int rnd_get (void)

{

int i;

outp (0x43, 0x86);

i = inp (0x42);

i = (inp (0x42) << 8) + i;

return i;

}

 

void main (void)

{

int i, j;

 

clrscr ();

rnd_set (100);

for (i = 1; i < 40; i++) {

printf (“%d ”, rnd_get ());

getchar ();

}

}

 

КОНТРОЛЬНІ ЗАПИТАННЯ

 

 

1. Скільки та які порти вводу/виводу використовуються для програмування таймера?

2. Які дії передбачає програмування таймера?

3. Назвіть засоби BIOS, що використовуються для роботи з таймером.

4. Чому часові затримки, сформовані з використанням таймера, не залежать від продуктивності комп’ютера?

5. Які порти використовуються для керування гучномовцем ПК?

 

 



Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: