DOS-extender для компилятора Borland C++ 3.1
Рефераты >> Программирование и компьютеры >> DOS-extender для компилятора Borland C++ 3.1

TYPE_TSS_DESCR | SEG_PRESENT_BIT);

// Инициализация TSS для задачи KEYB обработки ввода с клавиатуры

init_tss(&keyb_tss, CODE_SELECTOR, DATA_SELECTOR,

keyb_stack + sizeof(keyb_stack), Keyb_int);

// Инициализация элемента 10 таблицы GDT

init_gdt_descriptor(&gdt[10],

MK_LIN_ADDR(_DS, &flipflop_tss),

(unsigned long)TSS_SIZE-1,

TYPE_TSS_DESCR | SEG_PRESENT_BIT);

// Инициализация TSS для задачи FLIP_TASK

init_tss(&flipflop_tss, CODE_SELECTOR, DATA_SELECTOR,

flipflop_stack + sizeof(flipflop_stack), flipflop_task);

// Загрузка регистра IDTR

load_idtr(MK_LIN_ADDR(_DS, &idt), IDT_SIZE);

// Вход в защищённый режим

protected_mode(MK_LIN_ADDR(_DS, &gdt), sizeof(gdt),

CODE_SELECTOR, DATA_SELECTOR);

}

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

#include <stdio.h>

#include <dos.h>

#include <conio.h>

#include <stdlib.h>

#include <mem.h>

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

}

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

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

#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

// задач, участвующих в параллельной работе,

// т.е. диспетчеризуемых задач


Страница: