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 не виконується відразу після того, як користувач натиснув комбінацію клавіш Наша програма використовує кілька можливостей для своєї активізації. Зокрема, обробник апаратного переривання таймера 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 |