Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторні роботи Степаненко.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
2.5 Mб
Скачать

Тексти програм

// 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 ();

}

}

38

// 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

39

}

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)

40

{

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. Які порти використовуються для керування гучномовцем ПК?

41