КаталогИндекс раздела
НазадОглавлениеВперед


Лабораторня работа N5
УПРАВЛЕНИЕ КЛАВИАТУРОЙ

1. Цель работы

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

2. Темы для предварительного изучения

3. Постановка задачи

Разработать программу обработки прерывания от клавиатуры, которая должна:

4. Порядок выполнения

Порядок выполнения работы и содержание отчета определены в общих указаниях.

5. Индивидуальные задания

 Nп/п  "Горячая" комбинация/ Клавиша,
которая
блокируется
 Shift   Ctrl   Alt   Fxx 
 Лев.   Пр.   Лев.   Пр.   Лев.   Пр. 
 1   +    +            F1   1 
 2   +      +          F2   2 
 3    +       +     F3   3 
 4  +         +     F4   4
 5  +           +   F5   5 
 6     +   +         F6   6 
 7     +       +     F7   7 
 8     +     +       F8   8 
 9     +         +   F9   9 
 10       +     +     F10   0 
 11       +       +   F1   q 
 12         +   +     F2   w 
 13         +     +   F3   e 
 14   +     + или +       F4   r 
 15     +       + или +   F5   t 
 16               F6   y 
 17   +   +   + или +       F7   u 
 18   +   +       + или +   F8   i 
 19       + или +   + или +   F9   o 
 20   +   +   + или +   + или +   F10   p 

5. Пример решения задачи

5.1. Индивидуальное задание.

5.2. Разработка алгоритма

5.2.1. Структура программы

Программа состоит из основной программы и трех функций.

5.2.2. Описание переменных

Глобальные переменные программы: old9 - адрес старого обработчика прерывания 9h; F3_code - скан-код клавиши "F3", которая входит в комбинацию "горячих" клавиш; key3_code - скан-код клавиши "3", которая будет блокироваться/разблокироваться при каждом нажатии "горячей" комбинации клавиш; f - флаг, который при каждом нажатии "горячей" комбинации клавиш переключается из состояния 0 в 1 или из 1 в 0 (состояние 1 означает, что клавиша "3" заблокирована); rr и sr - переменные, которые используются для задания значений регистров общего назначения и сегментных регистров соответственно при вызове прерывания.

В главной программе использует символьный массив string для проверки работы программы.

Переменные процедуры обработки прерывания 9h:

5.2.3. Описание алгоритма программы

Главная программа выполняет такие действия:

  1. Запоминает адрес старого обработчика прерывания 9h, вызывая функцию readvect(in) с параметром in=9.
  2. Записывает в таблицу векторов прерываний адрес нового обработчика прерывания с помощью функции writevect().
  3. Вводом строки символов дает возможность проверить работу программы и ее реакцию на нажатие "горячей" комбинации клавиш и блокирование/разблокирование ввода клавиши "3".
  4. В конце работы восстанавливает в таблице векторов прерываний адрес старого обработчика.

Для решения задачи процедура обработки прерывания от клавиатуры new9() должна действовать по такому алгоритму:

  1. Прочитать флаги состояния клавиатуры (статус клавиш-переключателей), которые находятся в области данных BIOS (два байта по адресам 0040:0017 и 0040:0018).
  2. Выделить бит 1 в флаге по адресу 0040:0017 (если он равен 1, то нажата клавиша левый Shift).
  3. Выделить бит 2 в этом же флаге (если он равен 1, то нажата левый или правый Ctrl).
  4. Выделить бит 0 в флаге состояния клавиатуры по адресу 0040:0018 (если он равен 1, то нажата клавиша левый Ctrl).
  5. Из порта 60h прочитать скан-код нажатой клавиши.
  6. Если нажата комбинация клавиш левый Shift, правый Ctrl (нажата клавиша Ctrl, но это не правый Ctrl)и клавиша F3, то выполнить п.7. Иначе - перейти к п.8.
  7. Сигнализировать о нажатии "горячей" комбинации клавиш звуковым сигналом, переключить значение флага блокирования ввода клавиши "3" на обратное и вызвать старый обработчик прерывания от клавиатуры.
  8. Прочитав байт из порта 60h, определить, нажата ли клавиша 3" и если, кроме этого, еще и флаг блокирования указывает на то, что она заблокирована (f=1), то выполнить п.п. 9 и 10, иначе - вызвать старый обработчик прерывания.
  9. Послать подтверждение приема в клавиатуру. Для этого в порт 61h на короткое время выставить "1" по шине старшего разряда.
  10. Сбросить контроллер прерываний, посылая код 20h в порт 20h.

Функция readvect() читает вектор заданного прерывания. Для чтения вектора используется функция 35h DOS (прерывания 21h):

Вход: AH = 35h;
AL = номер вектора прерывания.
Выход: ES:BX = адрес программы обработки прерывания

Функция writevect() устанавливает новый вектор прерывания на заданный адрес. Для записи вектора используется функция 25h DOS:

Вход: AL = номер вектора прерывания;
DS:BX = 4-байтный адрес нового обработчика прерывания.

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

/*-------------------Лабораторная работа N5---------------*/
/*-------------------Управление клавиатурой---------------*/
/* Подключение стандартных заголовков */
#include <dos.h>

void interrupt (*old9)(); /* Старый обработчик прерывания 9h */
void interrupt new9();    /* Новый обработчик прерывания 9h  */
void *readvect (int in);  /* Чтение вектора                  */
void writevect (int in,void *h); /* Запись вектора           */

unsigned char F3_code=61; /* scan-code "F3"                  */
unsigned char key3_code=4;/* scan-code "3"                   */
char f=0;                 /* Флаг                            */
union REGS rr;
struct SREGS sr;

/*--------------------------------------------------------*/
void main()
{
  char string[80]; /* Буфер для ввода текста */

  textbackground(0);
  clrscr();
  textattr(0x0a);
  cprintf("---------------");
  cprintf("              Лабораторная работа N5              ");
  cprintf("---------------");
  cprintf("---------------");
  cprintf("              Управление клавиатурой              ");
  cprintf("---------------");

  old9=readvect(9);
  writevect(9,new9);
  textattr(0x0c);
  cprintf("\n\n\r\"горячая\" комбинация: ");
  textattr(0x0a);
  cprintf("Left Shift, Right Ctrl, F3\n\r");
  textattr(0x0b);
  cprintf("Клавиша, которая блокируется: ");
  textattr(0x0f);
  cprintf("3");
  textattr(0x07);
  cprintf("\r\nВводите строку символов>");
  scanf("%s",string);
  writevect(9,old9);
}
/*--------------------------------------------------------*/
/* Чтение вектора */
void *readvect(int in)
{
  rr.h.ah=0x35;
  rr.h.al=in;
  intdosx(&rr,&rr,&sr);
  return(MK_FP(sr.es,rr.x.bx));
}
/*--------------------------------------------------------*/
/* Запись вектора */
void writevect(int in,void *h)
{
  rr.h.ah=0x25;
  rr.h.al=in;
  sr.ds=FP_SEG(h);
  rr.x.dx=FP_OFF(h);
  intdosx(&rr,&rr,&sr);
}
/*--------------------------------------------------------*/
/* Новый обработчик 9-го прерыванмя */
void interrupt new9()
{
  unsigned char c,x,y;
  unsigned char byte17,byte18;
  unsigned char mask=0x02;
  unsigned char mask17=0x04;
  unsigned char mask18=0x01;

  byte17=peekb(0x40,0x17);
  byte18=peekb(0x40,0x18);
  if((inportb(0x60)==F3_code)&&(byte17&mask)&&
                        (byte17&mask17)&&(!(byte18&mask18)))
  {
   cputs("\7");
   x=wherex();
   y=wherey();
   gotoxy(55,3);
   textattr(0x1e);
   if(f==0)
   {
    f=1;
    cprintf("Клавиша \"3\" заблокирована ");
   }
   else
   {
    f=0;
    cprintf("Клавиша \"3\" разблокирована");
   }
   gotoxy(x,y);
   textattr(0x07);
   (*old9)();
  }
  if( (f==1) && (inportb(0x60)==key3_code) )
  {
   c=inportb(0x61);
   outportb(0x61,c|0x80);
   outportb(0x61,c);
   outportb(0x20,0x20);
  }
  else
   (*old9)();
}

5.4. Результаты работы программы

Во время программы при первом нажатии комбинации клавиш LeftCtrl+RightShift+F3 программа переходит в режим блокирования вводу клавиши 3, при втором - отменяет этот режим.


КаталогИндекс раздела
НазадОглавлениеВперед