Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2392_Смирнова_ЛР4_ЭВМ.docx
Скачиваний:
1
Добавлен:
05.12.2024
Размер:
78.03 Кб
Скачать

Ввод информации с клавиатуры средствами bios

Интерфейсом программ в персональном компьютере с клавиатурой является прерывание 16h BIOS. Далее приводится описание его функций.

АН = 00h - чтение с ожиданием двухбайтового кода из буфера клавиатуры. Прочитанный код возвращается в регистре АХ: младший байт - в регистре AL, старший - в АН. Если нажата ASCII-клавиша, в AL помещается ASCII-код символа, в АН - скэн-код. При нажатии специальных клавиш AL равен 0, а в АН возвращается расширенный скэн-код.

АН = 0lh - чтение без ожидания двухбайтового кода из буфера клавиатуры. Если буфер пуст, в 1 выставляется флаг нуля ZF. В противном случае в АХ возвращается двухбайтовый код из буфера клавиатуры, но продвижение указателя "головы" буфера не производится, т.е. код "остается" в буфере.

АН = 02h - определение состояния шифт- и триггерных клавиш. В регистре AL возвращается содержимое байта по адресу 40:17h (см. табл. 4.1).

Функция АН = 05h не имеет аналогов в библиотеке Turbo С и может использоваться для имитации нажатии клавиш в демонстрационных программах, программах переноса текста и т.д.

Функции АН = 10 - 12h являются аналогами функций 00 - 02h, но предназначены для использования в компьютерах с клавиатурой 101 /102 клавиши.

Функции АН = 00 - 02h прерывания 16h BIOS положены в основу функции bioskey() библиотеки Turbo С. Далее следует описание этой функции.

int bioskey(int cmd)

Обращается в зависимости от значения в cmd к функциям АН = 00 - 02h прерывания 16h. Возвращаемое функцией значение повторяет значение регистра АХ при выходе из прерывания

Алгоритмы

Программа, написанная для первого задания, реализует следующий алгоритм:

  • Подключить библиотеки conio.h и dos.h для работы с консолью и DOS.

  • Определить константы для задания границ окна, в котором будет перемещаться символ ‘*’.

  • Объявить и инициализировать переменные для хранения координат и скорости символа.

  • Очистить экран и изменить координаты окна.

  • Переместить курсор в начальную позицию символа.

  • Запустить бесконечный цикл, в котором будет происходить следующее:

    • Проверить, была ли нажата клавиша на клавиатуре.

    • Если была нажата клавиша, то считать ее код и выполнить действие в зависимости от кода:

      • Если была нажата расширенная клавиша, то считать следующий символ и выполнить действие в зависимости от символа:

        • Если была нажата ↑, то уменьшить координату y, если не достигнута верхняя граница окна.

        • Если была нажата ↓, то увеличить координату y, если не достигнута нижняя граница окна.

        • Если была нажата ←, то уменьшить координату x, если не достигнута левая граница окна.

        • Если была нажата →, то увеличить координату x, если не достигнута правая граница окна.

      • Если был нажат Escape, то завершить программу.

    • Переместить курсор на текущую позицию символа и вывести символ ‘@’.

    • Задержать выполнение программы на 100 миллисекунд.

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

1 задаиие

#include<conio.h>

#include<dos.h>

#include<stdio.h>

int main()

{

int ch, x = 1, y = 1;

textbackground(8);

clrscr();

window(25, 5, 55, 15);

textbackground(13);

textcolor(15);

_setcursortype (_NOCURSOR);

do

{

clrscr();

gotoxy(x, y);

cprintf("@");

ch = getch();

switch(ch)

{

case 72: //up

if (y > 1)

y--;

else if (y == 1)

{

sound(100);

delay(100);

nosound();

y = 11;

}

break;

case 80: //down

if (y <= 10)

y++;

else if (y > 10)

{

sound(100);

delay(100);

nosound();

y = 1;

}

break;

case 77: //right

if (x <= 30)

x++;

else if (x > 30)

{

sound(100);

delay(100);

nosound();

x = 1;

}

break;

case 75: //left

if (x > 1)

x--;

else if (x == 1)

{

sound(100);

delay(100);

nosound();

x = 31;

}

break;

default: break;

}

} while (ch != 27);

return 0;

}

2 задание

#include <stdio.h>

#include <conio.h>

#include <dos.h>

int getkey();

void sound(int, int);

void tm_sound(int freq, int time);

// Массив частот

int PartA_1[] =

{

330, 494, 740, 587, 659, 494, 392, 494,

330, 494, 740, 784, 880, 784, 740, 587,

330, 494, 740, 587, 659, 494, 392, 494,

330, 494, 740, 784, 880, 784, 740, 587, 0

};

int PartA_2[] =

{

131, 262, 740, 587, 659, 494, 392, 494,

124, 247, 740, 784, 880, 784, 740, 587,

165, 330, 740, 587, 659, 494, 392, 494,

165, 330, 740, 784, 880, 784, 740, 587, 0

};

// Массив длительностей

int delPartA_1[] =

{

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428, 0

};

int delPartA_2[] =

{

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 428, 0

};

//--------------//

int PartB_1[] =

{

165, 494, 659, 587, 659, 494,

220, 494, 370, 392, 156, 370,

165, 494, 659, 587, 659, 330, 294,

131, 494, 220, 247, 124, 370, 0

};

int PartB_2[] =

{

165, 494, 587, 740, 659, 494,

131, 494, 294, 494, 262, 494,

185, 220, 294, 330, 370, 294,

131, 494, 440, 740, 784, 740, 0

};

int delPartB_1[] =

{

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 214, 214,

428, 428, 428, 428, 428, 428, 0

};

int delPartB_2[] =

{

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 0

};

//--------------//

int PartC_1[] =

{

880, 494, 880, 494, 196, 880,

740, 494, 294, 784, 740, 784,

740, 494, 440, 880, 392, 494,

659, 494, 440, 740, 784, 740, 0

};

int delPartC_1[] =

{

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 0

};

int PartC_2[] =

{

880, 494, 880, 494, 392, 880,

740, 494, 294, 784, 740, 784,

740, 494, 440, 880, 392, 494,

659, 494, 440, 494, 698, 784, 0

};

int delPartC_2[] =

{

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 0

};

//--------------//

int delPartD[] =

{

107, 107, 1700, 858,

428, 428, 858, 858, 858,

428, 428, 428, 428, 428, 428, 428, 428,

428, 428, 428, 428, 428, 428, 428, 1700, 0

};

int PartD[] =

{

440, 523, 880, 349,

523, 587, 659, 587, 523,

494, 659, 740, 587, 659, 494, 392, 494,

330, 494, 740, 784, 880, 784, 740, 587, 0

};

int main(void)

{

int i;

int ch, x = 1, y = 1;

textbackground(8);

clrscr();

window(25, 5, 55, 15);

textbackground(13);

textcolor(15);

_setcursortype (_NOCURSOR);

do

{

clrscr();

gotoxy(x, y);

cprintf("@");

ch = getkey();

switch(ch)

{

case 32:

do{

for (i = 0; PartA_1[i] != 0; i++)

tm_sound(PartA_1[i], delPartA_1[i]);

if (kbhit())

break;

for (i = 0; PartA_2[i] != 0; i++)

tm_sound(PartA_2[i], delPartA_2[i]);

if (kbhit())

break;

for (i = 0; PartB_1[i] != 0; i++)

tm_sound(PartB_1[i], delPartB_1[i]);

if (kbhit())

break;

for (i = 0; PartB_2[i] != 0; i++)

tm_sound(PartB_2[i], delPartB_2[i]);

if (kbhit())

break;

for (i = 0; PartC_1[i] != 0; i++)

tm_sound(PartC_1[i], delPartC_1[i]);

if (kbhit())

break;

for (i = 0; PartC_2[i] != 0; i++)

tm_sound(PartC_2[i], delPartC_2[i]);

if (kbhit())

break;

for (i = 0; PartD[i] != 0; i++)

tm_sound(PartD[i], delPartD[i]);

} while (ch!=27);

break;

case 72: //up

if (y > 1)

y--;

else if (y == 1)

{

sound(100);

delay(100);

nosound();

y = 11;

}

break;

case 80: //down

if (y <= 10)

y++;

else if (y > 10)

{

sound(100);

delay(100);

nosound();

y = 1;

}

break;

case 77: //right

if (x <= 30)

x++;

else if (x > 30)

{

sound(100);

delay(100);

nosound();

x = 1;

}

break;

case 75: //left

if (x > 1)

x--;

else if (x == 1)

{

sound(100);

delay(100);

nosound();

x = 31;

}

break;

default: break;

}

} while (ch != 27);

return 0;

}

int getkey()

{

union REGS regs;

regs.h.ah = 0x07;

int86(0x21, &regs, &regs);

return regs.h.al;

}

void tm_sound(int freq, int time)

{

int cnt;

// Задаем режим канала 2 таймера

outp(0x43, 0xb6);

// Вычисляем задержку для загрузки в

// регистр счетчика таймера

cnt = (int)(1193180L / freq);

// Загружаем регистр счетчика таймера - сначала

// младший, затем старший байты

outp(0x42, cnt & 0x00ff);

outp(0x42, (cnt & 0xff00) >> 8);

// Включаем громкоговоритель. Сигнал от

// канала 2 таймера теперь будет проходить

// на вход громкоговорителя

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

// Выполняем задержку.

delay(time);

// Выключаем громкоговоритель.

outp(0x61, inp(0x61) & 0xfc);

}

Примеры запуска программы

Вывод

В ходе выполнения данной лабораторной работы была изучена работа с клавиатурой: ознакомились со стандартными средствами библиотеки C++ и средствами системы прерываний DOS и BIOS, обслуживающими клавиатуру.

Структурная схема аппаратных средств, используемых при выполнении программы с необходимой степенью детализации содержимого блоков.

Соседние файлы в предмете Организация ЭВМ