Рекомендации по использованию ТВП
Прерывания с кодами 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; просмотров: 1339;