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

3.4. Переривання INT 09h


Апаратне переривання від клавіатури INT 09h обробляється для того щоб виявити комбінацію клавіш, призначену для активізації резидентної програми:

void interrupt far new_int9 (

unsigned bp, unsigned di, unsigned si,

unsigned ds, unsigned es, unsigned dx,

unsigned cx, unsigned bx, unsigned ax)

{if (tsr_already_active) _chain_intr (old_int9);

keycode = inp (KEYBOARD_PORT);

if ((_ bios_keybrd (_KEYBRD_SHIFTSTATUS) & ShiftKey)! = ShiftKey)

_chain_intr (old_int9);

if (! (keycode == HotKeyRecording))

_chain_intr (old_int9);

popup_while_dos_busy = 1;

asm cli

asm in al, 61h

asm mov ah, al

asm or al, 80h

asm out 61h, al

asm xchg ah, al

asm out 61h, al

asm mov al, 20h

asm out 20h, al

asm sti}

Коли програма вже активна, встановлений прапор tsr_already_active. У цьому випадку наш обробник переривання передає управління у ланцюжку, викликаючи старий обробник.

Якщо програма TSRDEMO не активна, наш обробник переривання вводить код натиснутоюклавіші з порту клавіатури і перевіряє, чи була натиснута клавіша . Потім перевіряється код натиснутоюклавіші. У тому випадку, якщо користувач натиснув комбінацію клавіш , потрібно активізувати резидентну програму.

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

Активізація резидентної програми буде виконана пізніше, при обробці апаратного переривання INT 08h або переривання INT 28h.

Для коректної обробки апаратного переривання необхідно видати в контролер переривання відповідну команду, роздільну обробку інших переривань. Цю задачу вирішують кілька команд, оформлених як asm-вставки в вихідний текст обробника.

3.5. Переривання INT 08h


Активізація резидентної програми TSRDEMO не виконується відразу після того, як користувач натиснув комбінацію клавіш . Для активізації необхідно вибрати відповідний момент, коли переривається програма не викликає функцію MS-DOS або переривання BIOS, призначене для роботи з диском.

Наша програма використовує кілька можливостей для своєї активізації. Зокрема, обробник апаратного переривання таймера INT 08h періодично перевіряє можливість активізації:

void interrupt far new_int8 (

unsigned bp, unsigned di, unsigned si,

unsigned ds, unsigned es, unsigned dx,

unsigned cx, unsigned bx, unsigned ax)

{if (! tsr_already_active &&

popup_while_dos_busy &&

! DosBusy () &&! Unsafe_flag)

{popup_while_dos_busy = 0;

tsr_already_active = 1;

(* Old_int8) ();

_enable (); // дозволяємо переривання

activate_tsr (); // активізуємо TSR

tsr_already_active = 0;

}else (* old_int8) ();}

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

Активізація не виконується також і в тому випадку, якщо встановлено прапор InDos або unsafe_flag (останній встановлюється, якщо викликаний оброблювач переривання INT 13h).

Прапор popup_while_dos_busy встановлений в тому випадку, коли був запит на активізацію. Він встановлюється оброблювачем апаратного переривання від клавіатури INT 08h. Якщо запиту на активізацію немає, цей прапор не встановлений і, отже, активізацію виконувати не потрібно.

Якщо активізація можлива, скидаються прапори popup_while_dos_busy і встановлюється прапор tsr_already_active. Потім викликається старий обробник переривання INT 08h і вирішуються переривання.

Далі викликається функція activate_tsr, яка виконує всі дії, необхідні для активізації. Вона буде описана окремо. Після повернення управління з цієї функції прапор tsr_already_active скидається.

У тому випадку, коли активізація резидентної програми неможлива, наш обробник переривання INT 08h викликає старий оброблювач і повертає управління перерваної програми.

3.6. Переривання INT 28h


Переривання INT 28h викликається MS-DOS, коли вона очікує введення даних від клавіатури або, іншими словами, нічим особливим не зайнята. Тому обробник переривання INT 28h може активізувати резидентну програму, якщо на це є запит від користувача.

Наведемо вихідний текст обробника переривання INT 28h:

void interrupt far new_int28 (

unsigned bp, unsigned di, unsigned si,

unsigned ds, unsigned es, unsigned dx,

unsigned cx, unsigned bx, unsigned ax)

{int_28_in_progress ++;

if (popup_while_dos_busy && (! Int28DosBusy ())

&&! Tsr_already_active &&! Unsafe_flag)

{tsr_already_active = 1;

activate_tsr (); // активізуємо TSR

tsr_already_active = 0;}

int_28_in_progress--;

_chain_intr (old_int28);}

Оброблювач переривання INT 28h містить лічильник рекурсивних викликів int_28_in_progress, який аналізується при активізації резидентної програми функцією activate_tsr.

Якщо є запит на активізацію, перевіряються прапори tsr_already_active і unsafe_flag. Додатково перевіряється, не виконується спроба активізувати резидентну програму під час обробки переривання MS-DOS, відмінного від INT 28h. Для цього викликається функція Int28DosBusy.

Зверніть увагу на відмінність в способі перевірки можливості активізації при обробці переривання INT 08h і INT 28h.

У першому випадку викликається функція DosBusy:

int DosBusy (void)

{if (indos_ptr && crit_err_ptr)

return (* crit_err_ptr || * indos_ptr);

else

return 0xFFFF;}

Ця функція перевіряє вміст прапорів InDos і прапора обробки критичної помилки. Якщо MS-DOS не виконує обробку критичної помилки і якщо переривається програма не викликає функцію MS-DOS, можна виконувати активізацію. У цьому випадку функція DosBusy повертає значення 0.

Однак при виклику переривання INT 28h прапор InDos встановлений завжди, так як вказане переривання - це теж переривання MS-DOS. В даному випадку для перевірки можливості активізації використовується інша функція, яка називається Int28DosBusy.

Ця функція допускає одноразовий (НЕ рекурсивний) виклик функції INT 28h, перевіряючи значення, яке записується в байт пам'яті, відведений для прапора InDos:

int Int28DosBusy (void)

{if (indos_ptr && crit_err_ptr)

return (* crit_err_ptr || (* indos_ptr> 1));

else

return 0xFFFF;}

При рекурсивних викликах функцій MS-DOS значення, що зберігається в цьому байті, збільшується на 1. Активізація резидентної програми допускається тільки в тому випадку, коли в цьому байті знаходиться значення 1, т. д. Коли немає рекурсії.

Оброблювач переривання INT 28h активізує резидентную програму точно таким же способом, що і обробник переривання INT 08h, а саме, викликаючи спеціально призначену для активізації функцію activate_tsr, певну в нашій програмі.

1   2   3   4   5   6   7   8

скачати

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