Сборка Часть2 / АВМиС / lab1
.docБелорусский Государственный Университет Информатики и Радиоэлектроники
Кафедра ЭВМ
Отчет по лабораторной работе
Тема: «Программирование клавиатуры»
Выполнил:
студент группы 750503 Зеленкин Н.С.
Проверил:
к.т.н., доцент __________________ Одинец Д.Н.
Минск
2009
Постановка задачи
Разработать программу обработки прерывания от клавиатуры, которая должна:
-
распознавать нажатие комбинации клавиш и реагировать на него звуковым сигналом;
-
при первом нажатии "горячей" комбинации переходить в режим блокировки ввода заданной клавиши, при втором - отменять этот режим;
-
системная обработка всех других клавиш нарушаться не должна.
Комбинация блокировки: левый Shift + левый Alt + F5
Клавиша для блокирования – 4
Алгоритм решения
Программа состоит из основной программы и трех функций.
-
void* readvect(int inter) - функция читает вектор прерывания с номером inter и возвращает его значение.
-
void writevect (int inter, void *vect) - функция устанавливает новый вектор прерывания inter на новый обработчик этого прерывания по адресу vect.
-
void interrupt new9() - процедура нового обработчика прерывания 9h.
Алгоритм работы главной функции:
-
Запоминает адрес старого обработчика прерывания 9h в указатель old9, вызывая функцию readvect(int inter).
-
Записывает новый обработчик прерывания 9h, вызывая функцию writevect(int inter, void* vect).
-
Ввод строки пользователем. При этом при нажатии «горячей» комбинации происходит блокирование / разблокирование работы клавиши 4.
Алгоритм работы обработчика прерывания new9():
-
В переменную byte17 заносится содержимое ячейки по адресу 0040:0017.
-
В переменную byte18 заносится значение байта по адресу 0040:0018.
-
Считывается значение кода нажатой клавишы из порта 0x60. Если значение совпадает с кодом клавишы F5 – п. 4. Иначе п.12.
-
Если бит 1 в байте 0017 равен 1, то нажата клавиша левый Shift, переход к п.5. Иначе – п.12.
-
Если бит 3 в байте 0017 равен 1, то нажата клавиша Alt, переход к п.6. Иначе – п.12.
-
Если бит 1 в байте 0018 равен 1, то нажата клавиша левый Alt. Иначе – п.12.
-
Если переменная flag равна 0 (клавиша 4 не заблокирована), устанавливаем flag в 1,переходим к п.8. Если переменная flag равна 1 (клавиша 4 заблокирована), устанавливаем flag в 0, переходим к п. 12.
-
Читаем байт из порта 0x60. Если значение равно коду клавишы 4, п. 9, иначе п.12.
-
Выставляем в единицу старший бит порта 0x60.
-
Восстанавливаем значение порта, занося в него код считанного символа.
-
Выставляем в порт 0x20 значение 0x20, сбрасывая контроллер прерываний. Переход к п.13.
-
Вызываем старый обработчик прерываний.
-
Конец.
Текст программы
#include <dos.h>
void interrupt (*old9)(); // Указатель на старый обработчик прерывания 9h
void interrupt new9(); // Новый обработчик прерывания 9h
void *readvect (int inter); // Считывание вектора прерывания с номером inter
void writevect (int inter,void *vect); // Запись нового вектора прерывания
unsigned char F5_code=63; // Код клавиши F5
unsigned char key4_code=5; // Код клавиши 5
char flag=0; // Флаг блокирования ввода клавиши F5
union REGS reg;
struct SREGS segreg;
/*--------------------------------------------------------*/
void main()
{
char buf[80]; // Буфер для ввода
textbackground(0);
clrscr();
old9 = readvect(9);
writevect(9,new9);
textattr(0x0c);
cprintf("\n\n\r\"Hotkey\": ");
textattr(0x0a);
cprintf("Left Shift, Left Alt, F5\n\r");
textattr(0x0b);
cprintf("Blocked keyя: ");
textattr(0x0f);
cprintf("3");
textattr(0x07);
cprintf("\r\nPlease type some text:");
scanf("%s",buf);
writevect(9,old9);
}
/*--------------------------------------------------------*/
void* readvect(int inter)
{
reg.h.ah=0x35;
reg.h.al=inter;
intdosx(®,®,&segreg);
return(MK_FP(segreg.es,reg.x.bx));
}
/*--------------------------------------------------------*/
/* Запись вектора */
void writevect(int inter,void *vect)
{
reg.h.ah=0x25;
reg.h.al=inter;
segreg.ds=FP_SEG(vect);
reg.x.dx=FP_OFF(vect);
intdosx(®,®,&segreg);
}
/*--------------------------------------------------------*/
void interrupt new9()
{
unsigned char c,x,y;
unsigned char byte17,byte18;
unsigned char maskLeftShift = 0x02; // Маска для клавишы левый Shift
unsigned char maskAlt = 0x08; // Маска для клавишы Alt
unsigned char maskLeftAlt = 0x02; // Маска для клавишы левый Alt
byte17 = peekb(0x40,0x17);
byte18 = peekb(0x40,0x18);
if(inportb(0x60) == F5_code && (byte17&maskLeftShift) && (byte17&maskAlt) && !(byte18^maskLeftAlt) )
{
cputs("\7");
x = wherex();
y = wherey();
gotoxy(45,3);
textattr(0x1e);
if(flag==0)
{
flag=1;
cprintf("Клавиша \"4\" заблокирована ");
}
else
{
flag=0;
cprintf("Клавиша\"4\" разблокирована ");
}
gotoxy(x,y);
textattr(0x07);
(*old9)();
}
if( (flag == 1) && (inportb(0x60) == key4_code) )
{
c = inportb(0x61);
outportb(0x61,c|0x80);
outportb(0x61,c);
outportb(0x20,0x20);
}
else
(*old9)();
}
Заключение
В данной работе были освоены приемы программирования клавиатуры. В ходе решения задачи были рассмотрены специфики взаимодействия с клавиатурой, рассмотрена прямая работа с портом клавиатуры. Для решения задачи был использован язык C. Решение задачи можно расширить, сделав программу резидентной.