Рекомендации по использованию ТВП


Прерывания с кодами 5 или 9 можно использовать довольно просто и надежно. Код 5 соответствует нажатию клавиши «PrtSc», код 9 – поступлению сигнала при нажатии клавиши на клавиатуре компьютера. Начиная с вектора 64 можно использовать ТВП для реализации обработки программных прерываний (по запросам из программ).

Пример

TSR-программа с использованием запуска от клавиатуры.

Раздел инициализации должен выглядеть следующим образом:

#include <dos.h>

………….

void interrupt tsr_app(); // прикладная часть

char far * vid_mem; // адрес видеобуфера

char busy = 0; // флаг занятости обработкой прерывания, 0 – если не выполняется

void main()

{

struct address{

char far * p;

} temp;

// установка указателя на адрес вектора прерывания 9 в ТВП

struct address far * addr = (struct address far *) 36;

// установка указателя на адрес вектора прерывания 64 в ТВП

struct address far * int9 = (struct address far *) 256;

// сохранение адреса стандартного обработчика прерывания от клавиатуры

// Если содержимое векторов 64 и 65 совпадает, то эта операция еще не выполнялась

// иначе TSR-программа уже загружена

if (int9 -> p == (int9 + 1) -> p)

{

int9 -> p = addr -> p;

addr -> p = (char far *) tsr_app;

printf(“tsr_app установлена – F2, F3, F4 – используются”

“ для соответствующих функций”);

}

else

{

printf(“tsr_app уже была установлена!\n”);

exit(1);

}

// контроль режимов экрана, установка адреса видеобуфера vid_mem и т.п.

………………………………….

tsr(800); // программа остается резидентной

}

void tsr (unsigned size) // функция для того, чтобы оставить резидентной

{

union REGS r;

r.h.ah = 0x31;

r.h.al = 0;

r.x.dl = size;

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

}

В вызове функции tsr() в качестве аргумента мы указали приблизительный размер резидентной программы. На самом деле действительный размер можно установить точно, используя запрос к MS-DOS или собственные средства программы выведенные на уровень ассемблера. Эти возможности рассматриваются в дисциплине «Операционные системы» на 3-м курсе обучения.

В прикладную часть помимо функции, непосредственно получающей управление в результате прерывания, могут входить и другие функции. В нашем примере из tsr_app() вызывается window_main(), разработка которой предлагается в качестве упражнения.

void interrupt tsr_app()

{

char far *t = (char far *)1050; // адрес ячейки с индексом 1-й литеры в буфере клавиатуры

geninterrupt(64); // вначале обращение к стандартному обработчику прерываний

// клавиатуры

if (*t != *(t + 2)) // есть символ в буфере?

{

t = t + *t -30 +5; // переход к позиции введенного символа

if (*t == 60 || *t == 61 || *t == 62) // коды клавиш F2, F3, F4

{

bioskey(0); // сброс кода для F2, F3, F4 в буфере клавиатуры

if (!busy)

{

busy = !busy;

window_main(*t); // выполнение основной задачи

busy = !busy;

}

}

}

}

В данном примере вначале вызывается стандартный обработчик прерываний, а затем выполняются действия по распознаванию кодов клавиш F2, F3, F4 и выполнение некоторой частной задачи. Вызов bioskey() со значением аргумента 0 продвигает индекс 1-го символа в буфере клавиатуры вперед, – на один символ.

При каждом нажатии клавиши стандартный обработчик прерывания по вектору 9 размещает введенный символ в кольцевом буфере, позволяющем разместить до 15 символов (32 байта, поскольку размещается расширенный код, в зависимости от нажатых комбинаций клавиш). Буфер расположен с адреса 40:1Еh (или 1054 в десятичной с.с.). Расширенный код клавиши ВК автоматически размещается в конце буфера. Буфер организован в виде кольцевой очереди (непрерывное представление). Индекс 1-го символа хранится по адресу 40:1Ah (или 1050 в десятичной с.с.). Индекс последнего символа размещается в ячейке по адресу 40:1Ch (или 1052 в десятичной с.с.). Значения индексов совпадают, если буфер пуст. Значения индексов указываются в виде смещений относительно базового адреса сегмента, равного 40h. Для пересчета смещения в действительное значение указателя типа far необходимо уменьшить значение индекса на 30. Увеличение на 5 учитывает 4 байта под собственно индексы головы и хвоста и 1 байт для доступа к старшему байту кода символа, т.к. именно там располагаются коды после нажатия клавиш F2, F3 или F4. Младший байт при использовании кодов данного типа равен 0 (см. Касаткин).

Вопросы для самоконтроля

· Файл прототипов функций для работы с прерываниями?

· Перечислите имена функций для выполнения прерываний и охарактеризуйте их параметры!

· Для чего используется объединение union REGS?

· Какие данные содержит структура struct REGPACK?

· Для каких целей используется код прерывания 10h?

· Как устанавливаются параметры отображения курсора?

· Что означает запись в программе оператора «_CX = shape;»?

· Можно ли координаты курсора установить непосредственно в видеопамяти?

· На какие регистры выполняется загрузка символа и его атрибута при обращении к bios для отображения символа на экране монитора? – какой код прерывания? – какой код функции прерывания?

· Укажите назначение функций, прототипы которых расположены в файле conio.h!

· Каков содержательный смысл данных в структуре struct text_info?

· Для чего применяются TSR-программы и из каких частей они состоят?

· Каковы рекомендации по использованию таблицы векторов прерываний?

· Что указывает модификатор типа interrupt?

· Что содержат ячейки таблицы векторов прерываний?

Вопросы для самостоятельного изучения

· Для чего применяется и как записываются параметры макрокоманды MK_FP()?

· Каким образом можно использовать функцию kbhit()?

· Параметры и режимы выполнения функции bioskey()?



Дата добавления: 2016-05-26; просмотров: 1266;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.01 сек.