Защищенный режим процессоров Intel 80286,80386,80486.1993



         

Пример мультизадачного монитора - часть 5


Как только // семафор 0 окажется установлен, главная задача // завершает свою работу и программа возвращает // процессор в реальный режим, затем передаёт // управление MS-DOS. vi_print(60, 5, " Key code: .... ", 0x20); vi_print(60, 6, " Key status: .... ", 0x20); while(1){ keyb_code = kb_getch(); vi_put_word(73, 5, keyb_code, 0x4f); vi_put_word(73, 6, keyb_status, 0x4f); if((keyb_code & 0x00ff) == 1) sem_set(0); } }

Файл semaphor.c содержит исходные тексты процедур сброса семафора, установки семафора и ожидания семафора.

В массиве semaphore[5] определено пять семафоров. Разумеется, что когда вы будете экспериментировать с программой, вы можете изменить количество доступных семафоров. Листинг 8. Процедуры для работы с семафорами. Файл semaphor.c ----------------------------------------------------------- #include <stdio.h> #include <dos.h> #include <conio.h> #include <stdlib.h> #include "tos.h" // Массив из пяти семафоров word semaphore[5]; // Процедура сброса семафора. // Параметр sem - номер сбрасываемого семафора void sem_clear(int sem) { asm cli semaphore[sem] = 0; asm sti } // Процедура установки семафора // Параметр sem - номер устанавливаемого семафора void sem_set(int sem) { asm cli semaphore[sem] = 1; asm sti } // Ожидание установки семафора // Параметр sem - номер ожидаемого семафора void sem_wait(int sem) { while(1) { asm cli if(semaphore[sem]) break; // проверяем семафор asm sti // ожидаем установки семафора asm nop asm nop } asm sti }

Файл timer.c содержит обработчик аппаратного прерывания таймера, который периодически выдаёт звуковой сигнал и инициирует работу диспетчера задач. Диспетчер задач циклически перебирает селекторы TSS задач, участвующих в процессе разделения времени, возвращая селектор той задачи, которая должна стать активной. В самом конце обработки аппаратного прерывания таймера происходит переключение именно на эту задачу. Листинг 9. Процедуры для работы с таймером и диспетчер задач. Файл timer.c ----------------------------------------------------------- #include <stdio.h> #include <dos.h> #include <conio.h> #include <stdlib.h> #include "tos.h" // ------------------------------------------- // Модуль обслуживания таймера // ------------------------------------------- #define EOI 0x20 #define MASTER8259A 0x20 extern void beep(void); extern void flipflop_task(void); void Timer_int(void); word dispatcher(void); word timer_cnt; // ------------------------------------------ // Обработчик аппаратного прерывания таймера // ------------------------------------------ void Timer_int(void) { asm pop bp // Периодически выдаём звуковой сигнал timer_cnt += 1; if((timer_cnt & 0xf) == 0xf) { beep(); } // Выдаём в контроллер команду конца // прерывания asm mov al,EOI asm out MASTER8259A,al // Переключаемся на следующую задачу, // селектор TSS которой получаем от // диспетчера задач dispatcher() jump_to_task(dispatcher()); asm iret } // -------------------------------------- // Диспетчер задач // -------------------------------------- // Массив селекторов, указывающих на TSS // задач, участвующих в параллельной работе, // т.е.


Содержание  Назад  Вперед