Рефераты. DOS-extender для компилятора Borland C++ 3.1 p> // Вход в защищённый режим protected_mode(MK_LIN_ADDR(_DS, &gdt), sizeof(gdt),

CODE_SELECTOR, DATA_SELECTOR);
}


4.4 Файл TASKS.C. Содержит функции задач.


#include
#include
#include
#include
#include
#include "tos.h"
#include "screen.h"

word dispatcher(void);

// Номер текущей строки для вывода на экран extern unsigned int y;

// Задача TASK_1 void task1(void)
{ while(1)
{ vi_print(0,y++, " Запущена задача TASK_1, "

" возврат управления главной задаче", 0x70); jump_to_task(MAIN_TASK_SELECTOR);

// После повторного запуска этой задачи
// снова входим в цикл.
}
}

// Задача TASK_2 long delay_cnt1 = 0l; word flipflop1 = 0; void task2(void)
{ char Buf[B_SIZE + 1]; // Буфер вывода задачи 2 static TLabel Label1; static TLabel Label2;

memset(Buf, ' ', B_SIZE);
Buf[B_SIZE] = 0;

Label1.Pos = 0;
Label1.Dir = 1;

Buf[Label1.Pos] = '/';

Label2.Pos = B_SIZE;
Label2.Dir = 0;
Buf[Label2.Pos] = '';

vi_print(30, 15, "Работает задача 2:", 0x7f);

while (1)
{
// Периодически выводим на экран движки,
// каждый раз переключая
// семафор номер 1. Этот семафор однозначно
// соответствует выведенной на экран строке. asm sti if (delay_cnt1 > 150000l)
{ asm cli

StepLabel(&Label1, &Label2, Buf);

if (flipflop1)

{ vi_print(5, 16, Buf, 0x1f); sem_clear(1);

} else

{ vi_print(5, 16, Buf, 0x1f); sem_set(1);

} flipflop1 ^= 1; delay_cnt1 = 0l; asm sti
} delay_cnt1++;
}
}

word flipflop = 0; long delay_cnt = 0l;

// Эта задача также периодически выводит на экран
// с меньшим периодом. Кроме того, эта задача
// работает только тогда, когда установлен
// семафор номер 1. void flipflop_task(void)
{ char Buf[B_SIZE + 1]; // Буфер вывода задачи 2 static TLabel Label1; static TLabel Label2;

memset(Buf, ' ', B_SIZE);
Buf[B_SIZE] = 0;

Label1.Pos = 0;
Label1.Dir = 1;
Buf[Label1.Pos] = '/';

Label2.Pos = B_SIZE;
Label2.Dir = 0;
Buf[Label2.Pos] = '';

vi_print(30, 12, "Работает задача 0:", 0x7f);

while(1)
{ asm sti if (delay_cnt > 20000l )
{ sem_wait(1); // ожидаем установки семафора asm cli

StepLabel(&Label1, &Label2, Buf); vi_print(5, 13, Buf, 0x1f); flipflop ^= 1; delay_cnt = 0l; asm sti
} delay_cnt++;
}
}

word keyb_code;

extern word keyb_status;

// Эта задача вводит символы с клавиатуры
// и отображает скан-коды нажатых клавиш
// и состояние переключающих клавиш на экране.
// Если нажимается клавиша ESC, задача
// устанавливает семафор номер 0.
// Работающая параллельно главная задача
// ожидает установку этого семафора. Как только
// семафор 0 окажется установлен, главная задача
// завершает свою работу и программа возвращает
// процессор в реальный режим, затем передаёт
// управление MS-DOS. void keyb_task(void)
{ vi_print(32, 20, " Key code: .... ", 0x20); vi_print(32, 21, " Key status: .... ", 0x20); while(1)
{ keyb_code = kb_getch(); vi_put_word(45, 20, keyb_code, 0x4f); vi_put_word(45, 21, keyb_status, 0x4f); if ((keyb_code & 0x00ff) == 1) sem_set(0);
}
}


4.5 Файл SEMAPHOR.C. Содержит процедуры для работы с семафорами.


#include
#include
#include
#include
#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
}

4.6 Файл TIMER.C. Процедуры для работы с таймером и диспетчер задач.

Cодержит обработчик аппаратного прерывания таймера, который периодически выдаёт звуковой сигнал и инициирует работу диспетчера задач.
Диспетчер задач циклически перебирает селекторы TSS задач, участвующих в процессе разделения времени, возвращая селектор той задачи, которая должна стать активной. В самом конце обработки аппаратного прерывания таймера происходит переключение именно на эту задачу.

#include
#include
#include
#include
#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
// задач, участвующих в параллельной работе,
// т.е. диспетчеризуемых задач

word task_list[] =
{
MAIN_TASK_SELECTOR,
FLIP_TASK_SELECTOR,
KEYBIN_TASK_SELECTOR,
TASK_2_SELECTOR
};

word current_task = 0; // текущая задача word max_task = 3; // количество задач - 1

// Используем простейший алгоритм диспетчеризации -
// выполняем последовательное переключение на все
// задачи, селекторы TSS которых находятся
// в массиве task_list[].

word dispatcher(void)
{ if (current_task < max_task) current_task++; else current_task = 0; return(task_list[current_task]);
}


4.7 Файл EXCEPT.C. Обработка исключений.


#include
#include
#include
#include
#include "tos.h"

void prg_abort(int err);

// Номер текущей строки для вывода на экран

extern unsigned int y;

// Обработчики исключений

void exception_0(void) { prg_abort(0); } void exception_1(void) { prg_abort(1); } void exception_2(void) { prg_abort(2); } void exception_3(void) { prg_abort(3); } void exception_4(void) { prg_abort(4); } void exception_5(void) { prg_abort(5); } void exception_6(void) { prg_abort(6); } void exception_7(void) { prg_abort(7); } void exception_8(void) { prg_abort(8); } void exception_9(void) { prg_abort(9); } void exception_A(void) { prg_abort(0xA); } void exception_B(void) { prg_abort(0xB); } void exception_C(void) { prg_abort(0xC); } void exception_D(void) { prg_abort(0xD); } void exception_E(void) { prg_abort(0xE); } void exception_F(void) { prg_abort(0xF); } void exception_10(void) { prg_abort(0x10); } void exception_11(void) { prg_abort(0x11); } void exception_12(void) { prg_abort(0x12); } void exception_13(void) { prg_abort(0x13); } void exception_14(void) { prg_abort(0x14); } void exception_15(void) { prg_abort(0x15); } void exception_16(void) { prg_abort(0x16); } void exception_17(void) { prg_abort(0x17); } void exception_18(void) { prg_abort(0x18); } void exception_19(void) { prg_abort(0x19); } void exception_1A(void) { prg_abort(0x1A); } void exception_1B(void) { prg_abort(0x1B); } void exception_1C(void) { prg_abort(0x1C); } void exception_1D(void) { prg_abort(0x1D); } void exception_1E(void) { prg_abort(0x1E); } void exception_1F(void) { prg_abort(0x1F); }

// ------------------------------
// Аварийный выход из программы
// ------------------------------

void prg_abort(int err)
{ vi_print(1, y++,"ERROR!!! ---> Произошло исключение", 0xc);

real_mode(); // Возвращаемся в реальный режим

// В реальном режиме выводим сообщение об исключении

gotoxy(1, ++y); cprintf(" Исключение %X, нажмите любую клавишу", err); getch();

textcolor(WHITE); textbackground(BLACK); clrscr(); exit(0);
}


4.8 Файл INTPROC.C. Заглушки для аппаратных прерываний.


#include
#include
#include
#include
#include "tos.h"

// Заглушки для необрабатываемых
// аппаратных прерываний.

void iret0(void)
{ // первый контроллер прерываний asm { push ax mov al,EOI out MASTER8259A,al pop ax pop bp iret
}
}

// -----------------------------------------------------------
// второй контроллер прерываний void iret1(void)
{ asm { push ax mov al,EOI out MASTER8259A,al out SLAVE8259A,al pop ax pop bp iret
}
}

4.9 Файл KEYB.C. Ввод символа с клавиатуры.


#include
#include
#include
#include
#include "tos.h"

extern word key_code;

// Функция, ожидающая нажатия любой
// клавиши и возвращающая её скан-код

unsigned int kb_getch(void)
{ asm int 30h return (key_code);
}

4.10 Файл KEYBOARD.ASM. Процедуры для работы с клавиатурой.


IDEAL

MODEL SMALL
RADIX 16

P286 include "tos.inc"

; ------------------------------------------
; Модуль обслуживания клавиатуры
; ------------------------------------------

PUBLIC _Keyb_int, _Int_30h_Entry, _key_code, _keyb_status
EXTRN _beep:PROC
DATASEG

_key_flag db 0

_key_code dw 0 ext_scan db 0

_keyb_status dw 0

CODESEG

PROC _Keyb_int NEAR cli

call _beep

push ax mov al, [ext_scan] cmp al, 0 jz normal_scan1 cmp al, 0e1h jz pause_key

in al, 60h

cmp al, 2ah jz intkeyb_exit_1 cmp al, 0aah jz intkeyb_exit_1

mov ah, [ext_scan] call Keyb_PutQ

mov al, 0 mov [ext_scan], al jmp intkeyb_exit

pause_key:

in al, 60h cmp al, 0c5h jz pause_key1 cmp al, 45h jz pause_key1

jmp intkeyb_exit

pause_key1: mov ah, [ext_scan] call Keyb_PutQ

mov al, 0 mov [ext_scan], al jmp intkeyb_exit

normal_scan1: in al, 60h cmp al, 0feh jz intkeyb_exit cmp al, 0e1h jz ext_key cmp al, 0e0h jnz normal_scan

ext_key: mov [ext_scan], al jmp intkeyb_exit

intkeyb_exit_1: mov al, 0 mov [ext_scan], al jmp intkeyb_exit

normal_scan: mov ah, 0 call Keyb_PutQ

intkeyb_exit: in al, 61h mov ah, al or al, 80h out 61h, al xchg ah, al out 61h, al mov al,EOI out MASTER8259A,al

Страницы: 1, 2, 3, 4



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.