1   2   3   4   5   6   7   8
Ім'я файлу: ЗВІТ КУРСАЧА - РЕЗИДЕНТНИЙ КАЛЬКУЛЯТОР.docx
Розширення: docx
Розмір: 511кб.
Дата: 05.11.2021
скачати

3.2. Переривання INT 1Ch


Переривання INT 1Ch є програмним і викликається обробником апаратного переривання від таймера INT 08h приблизно 18,2 рази в секунду.

Наша програма використовує це переривання, для того щоб виводити в правому верхньому куті екрану миготливі символи "*" та "+". Таке миготіння потрібно тільки для індикації активності резидентної програми. Якщо індикація не потрібно, ви можете не змінювати відповідний вектор переривання і не передбачати обробник для цього переривання.

Наш обробник переривання INT 1Ch називається new_int1c і має такий вигляд:

void interrupt new_int1c ()

{s_arrayptr screen [80]; // відеопам'ять

static int count; // лічильник

screen [0] = (s_arrayptr) MK_FP (0xB800,0);

count ++; count% = 6;

screen [0] [79] =

((Count> 2)? '*': '+') + ATTR;

_chain_intr (old_int1c);}

Масив screen містить далекі покажчики на масив цілих чисел, певні наступним чином:

typedef unsigned int (far * s_arrayptr);

У перший елемент цього масиву ми записуємо покажчик на область відеопам'яті, відповідну самому верхньому рядку екрана. Для кольорового видеоконтроллера цю адресу дорівнює B800h: 0000h.

Для того щоб символи не блимає занадто часто, обробник переривання INT 1Ch підраховує переривання в статичному лічильнику count. Якщо значення цього лічильника більше 2, виводиться символ '* ", якщо менше - символ" + ".

Перед тим як повернути управління, функція new_int1c викликає старий оброблювач переривання INT 1Ch, адреса якого зберігається в змінної old_int1c. Для цього використовується функція _chain_intr.

3.3. Переривання INT 2Fh


Оброблювач переривання INT 2Fh, який вбудовує наша програма, виконує дві функції.

По-перше, цей обробник використовується для запобігання повторного завантаження резидентної програми в пам'ять.

По-друге, він потрібен для вивантаження резидентної програми з пам'яті.

Оригінальний текст обробника переривання INT 2Fh представлений нижче:

void interrupt far new_int2f (

unsigned bp, unsigned di, unsigned si,

unsigned ds, unsigned es, unsigned dx,

unsigned cx, unsigned bx, unsigned ax)

{ if (ax == 0xff00) ax = 0x00ff;

else if (ax == 0xff01)

{ExitAddress = ((long) bx << 16) + dx;

if (! tsr_already_active)

{_enable ();

tsr_exit ();

ax = 0xFFFF;

tsr_already_active = -ax;} }

else _chain_intr (old_int2f);}

Виклик переривання INT 2Fh відбувається при запуску нашої програми, а також і при запуску інших резидентних програм. Регістр AH при цьому повинен містити ідентифікатор резидентної програми. Для програми TSRDEMO ми вибрали ідентифікатор FFh, хоча ніхто не зможе гарантувати, що такий ідентифікатор вже не використовується іншою програмою. Для надійності ви можете вказати додатковий ідентифікатор, наприклад, у вигляді текстового рядка, адреса якої передається через інші регістри. Ми не стали цього робити для скорочення обсягу лістингу програми.

Отже, якщо при виклику переривання INT 2Fh регістр AH містить значення FFh, наш обробник переривання вважає, що виклик виконує програма TSRDEMO.

У цьому випадку він додатково перевіряє вміст регістру AL, в якому знаходиться код виконуваної функції.

Якщо цей код дорівнює 0, переривання INT 2Fh викликано для перевірки наявності програми TSRDEMO в пам'яті. У відповідь обробник повертає в регістрі AX значення 00FFh. Це і є ознака того, що програма TSRDEMO вже завантажена в пам'ять і її повторне завантаження неможлива.

Якщо ж код дорівнює 1, програма TSRDEMO була запущена з параметром u для вивантаження своєї копії з пам'яті.

В цьому випадку обробник переривання INT 2Fh зберігає в глобальній змінній ExitAddress адресу завершення, переданий оброблювачу в регістрах BX: DX. Потім перевіряється прапор tsr_already_active, який встановлений, якщо резидентна програма активна і її в даний момент не можна вивантажувати з пам'яті.

Далі обробник дозволяє апаратні переривання, які були заборонені перед викликом переривання INT 2Fh для вивантаження, і робить спробу вивантажити резидентную програму, викликаючи функцію tsr_exit.

Зауважимо, що після вивантаження резидентної програми функція tsr_exit передає управління MS-DOS, а не повертає його назад в програму.

Спроба вивантаження програми може закінчитися невдало, якщо користувач завантажив після програми TSRDEMO іншу резидентну програму, яка змінила вектора переривань, для яких програма TSRDEMO встановила свої обробники. В цьому випадку наша програма "не знає", як відновити вектора переривань і не вивантажується з пам'яті. Тим не менш, вона блокує свою роботу, записуючи в змінну tsr_already_active значення -FFFFh.

Детальніше процес вивантаження резидентної програми буде розглянуто пізніше.

Зауважимо, що якщо вміст регістра AX при виклику переривання INT 2Fh не дорівнює FF00h або FF01h, наш обробник переривання передає управління у ланцюжку, викликаючи для цього функцію _chain_intr.

1   2   3   4   5   6   7   8

скачати

© Усі права захищені
написати до нас