Смекни!
smekni.com

DOS-extender для компилятора Borland C++ (стр. 4 из 7)

#define word unsigned int

// Селекторы, определённые в GDT

#define CODE_SELECTOR 0x08 // сегмент кода

#define DATA_SELECTOR 0x10 // сегмент данных

#define TASK_1_SELECTOR 0x18 // задача TASK_1

#define TASK_2_SELECTOR 0x20 // задача TASK_2

#define MAIN_TASK_SELECTOR 0x28 // главная задача

#define VID_MEM_SELECTOR 0x30 // сегмент видеопамяти

#define IDT_SELECTOR 0x38 // талица IDT

#define KEYBIN_TASK_SELECTOR 0x40 // задача ввода с клавиатуры

#define KEYB_TASK_SELECTOR 0x48 // задача обработки

// клавиатурного прерывания

#define FLIP_TASK_SELECTOR 0x50 // задача FLIP_TASK

// Байт доступа

typedef struct

{

unsigned accessed : 1;

unsigned read_write : 1;

unsigned conf_exp : 1;

unsigned code : 1;

unsigned xsystem : 1;

unsigned dpl : 2;

unsigned present : 1;

} ACCESS;

// Структура дескриптора

typedef struct descriptor

{

word limit; // Предел (размер сегмента в байтах)

word base_lo; // Базовый адрес сегмента (младшее слово)

unsigned char base_hi; // Базовый адрес сегмента (старший байт)

unsigned char type_dpl; // Поле доступа дескриптора

unsigned reserved; // Зарезервированные 16 бит

} descriptor;

// Структура вентиля вызова, задачи, прерывания,

// исключения

typedef struct gate

{

word offset;

word selector;

unsigned char count;

unsigned char type_dpl;

word reserved;

} gate;

// Структура сегмента состояния задачи TSS

typedef struct tss

{

word link; // поле обратной связи

word sp0; // указатель стека кольца 0

word ss0;

word sp1; // указатель стека кольца 1

word ss1;

word sp2; // указатель стека кольца 1

word ss2;

word ip; // регистры процессора

word flags;

word ax;

word cx;

word dx;

word bx;

word sp;

word bp;

word si;

word di;

word es;

word cs;

word ss;

word ds;

word ldtr;

} tss;

// Размеры сегментов и структур

#define TSS_SIZE (sizeof(tss))

#define DESCRIPTOR_SIZE (sizeof(descriptor))

#define GATE_SIZE (sizeof(gate))

#define IDT_SIZE (sizeof(idt))

// Физические адреса видеопамяти для цветного

// и монохромного видеоадаптеров

#define COLOR_VID_MEM 0xb8000L

#define MONO_VID_MEM 0xb0000L

// Видеоржеимы

#define MONO_MODE 0x07 // монохромный

#define BW_80_MODE 0x02 // монохромный, 80 символов

#define COLOR_80_MODE 0x03 // цветной, 80 символов

// Значения для поля доступа

#define TYPE_CODE_DESCR 0x18

#define TYPE_DATA_DESCR 0x10

#define TYPE_TSS_DESCR 0x01

#define TYPE_CALL_GATE 0x04

#define TYPE_TASK_GATE 0x85

#define TYPE_INTERRUPT_GATE 0x86

#define TYPE_TRAP_GATE 0x87

#define SEG_WRITABLE 0x02

#define SEG_READABLE 0x02

#define SEG_PRESENT_BIT 0x80

// Константы для обработки аппаратных

// прерываний

#define EOI 0x20

#define MASTER8259A 0x20

#define SLAVE8259A 0xa0

// Макро для формирования физического

// адреса из компонент сегменоного адреса

// и смещения

#define MK_LIN_ADDR(seg,off) (((unsigned long)(seg))<<4)+(word)(off)

// Тип указателя на функцию типа void без параметров

typedef void (func_ptr)(void);

4.3 Файл TOS.H. Основной файл программы.

#include <stdio.h>

#include <stdlib.h>

#include <dos.h>

#include <conio.h>

#include "tos.h"

// --------------------------------

// Определения вызываемых функций

// --------------------------------

// Инициализация защищенного режима и вход в него

void Init_And_Protected_Mode_Entry(void);

void protected_mode(unsigned long gdt_ptr, unsigned int gdt_size,

word cseg, word dseg);

word load_task_register(word tss_selector);

void real_mode(void);

void jump_to_task(word tss_selector);

void load_idtr(unsigned long idt_ptr, word idt_size);

void Keyb_int(void);

void Timer_int(void);

void Int_30h_Entry(void);

extern word kb_getch(void);

void enable_interrupt(void);

void task1(void);

void task2(void);

void flipflop_task(void);

void keyb_task(void);

void init_tss(tss *t, word cs, word ds,

unsigned char *sp, func_ptr ip);

void init_gdt_descriptor(descriptor *descr, unsigned long base,

word limit, unsigned char type);

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 iret0(void);

void iret1(void);

// --------------------------------------

// Глобальная таблица дескрипторов GDT

// --------------------------------------

descriptor gdt[11];

// --------------------------------------

// Дескрипторная таблица прерываний IDT

// --------------------------------------

gate idt[] =

{

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

{ (word)&exception_0, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 0

{ (word)&exception_1, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1

{ (word)&exception_2, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 2

{ (word)&exception_3, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 3

{ (word)&exception_4, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 4

{ (word)&exception_5, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 5

{ (word)&exception_6, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 6

{ (word)&exception_7, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 7

{ (word)&exception_8, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 8

{ (word)&exception_9, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 9

{ (word)&exception_A, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // A

{ (word)&exception_B, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // B

{ (word)&exception_C, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // C

{ (word)&exception_D, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // D

{ (word)&exception_E, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // E

{ (word)&exception_F, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // F

{ (word)&exception_10, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 10

{ (word)&exception_11, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 11

{ (word)&exception_12, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 12

{ (word)&exception_13, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 13

{ (word)&exception_14, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 14

{ (word)&exception_15, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 15

{ (word)&exception_16, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 16

{ (word)&exception_17, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 17

{ (word)&exception_18, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 18

{ (word)&exception_19, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 19

{ (word)&exception_1A, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1A

{ (word)&exception_1B, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1B

{ (word)&exception_1C, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1C

{ (word)&exception_1D, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1D

{ (word)&exception_1E, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1E

{ (word)&exception_1F, CODE_SELECTOR, 0, TYPE_TRAP_GATE, 0 }, // 1F

// Обработчик прерываний таймера

{ (word)&Timer_int, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 20

// { (word)&Keyb_int, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 21

// Вентиль задачи, запускающейся по прерыванию от клавиатуры

{ 0, KEYB_TASK_SELECTOR, 0, TYPE_TASK_GATE, 0 }, // 21

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

{ (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 22

{ (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 23

{ (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 24

{ (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 25

{ (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 26

{ (word)&iret0, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 27

{ (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 28

{ (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 29

{ (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2A

{ (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2B

{ (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2C

{ (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2D

{ (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2E

{ (word)&iret1, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 2F

// Обработчик для программного прерывания, которое

// используется для ввода с клавиатуры

{ (word)&Int_30h_Entry, CODE_SELECTOR, 0, TYPE_INTERRUPT_GATE, 0 }, // 30

// Вентиль задачи FLIP_TASK

{ 0, FLIP_TASK_SELECTOR, 0, TYPE_TASK_GATE, 0 } // 31

};

// -------------------------------------------

// Сегменты TSS для различных задач

// -------------------------------------------

tss main_tss; // TSS главной задачи

tss task_1_tss; // TSS задачи TASK_1

tss task_2_tss; // TSS задачи TASK_2

tss keyb_task_tss; // TSS задач обслуживания

tss keyb_tss; // клавиатуры

tss flipflop_tss; // TSS задачи FLIP_TASK

// -------------------------------------------

// Стеки для задач

// -------------------------------------------

unsigned char task_1_stack[1024];

unsigned char task_2_stack[1024];

unsigned char keyb_task_stack[1024];

unsigned char keyb_stack[1024];

unsigned char flipflop_stack[1024];

word y=0; // номер текущей строки для вывода на экран

// -------------------------------------------

// Начало программы

// -------------------------------------------

extern int getcpu(void);

void main(void)

{

// Очищаем экран

textcolor(BLACK);

textbackground(LIGHTGRAY);

clrscr();

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

Init_And_Protected_Mode_Entry();

// Выводим сообщение

vi_hello_msg();

y=3;

vi_print(0, y++, " Установлен защищённый режим в главной задаче", 0x7f);

// Загружаем регистр TR селектором главной задачи

// т.е. задачи main()

load_task_register(MAIN_TASK_SELECTOR);

// Переключаемся на задачу TASK_1

jump_to_task(TASK_1_SELECTOR);

// После возврата в главную задачу выдаём сообщение

vi_print(0, y++ ," Вернулись в главную задачу", 0x7f);

// Запускаем планировщик задач

vi_print(0, y++ ," Запущен планировщик задач", 0x70);

enable_interrupt(); // разрешаем прерывание таймера

// Ожидаем установки семафора с номером 0. После того,

// как этот семафор окажется установлен, возвращаемся

// в реальный режим.

// Семафор 0 устанавливается задачей, обрабатывающей ввод с

// клавиатуры, которая работает независимо от

// главной задаче.

vi_print(18, 24," Для возврата в реальный режим нажмите ESC", 0x70);

sem_clear(0); // сброс семафора 0

sem_wait(0); // ожидание установки семафора 0

// Возврат в реальный режим, стирание экрана и

// передача управления MS-DOS

real_mode();

textcolor(WHITE);

textbackground(BLACK);

clrscr();

}

// -----------------------------------

// Функция инициализации сегмента TSS

// -----------------------------------

void init_tss(tss *t, word cs, word ds,

unsigned char *sp, func_ptr ip)

{

t->cs = cs; // селектор сегмента кода

t->ds = ds; // поля ds, es, ss устанавливаем

t->es = ds; // на сегмент данных

t->ss = ds;

t->ip = (word)ip; // указатель команд

t->sp = (word)sp; // смещение стека

t->bp = (word)sp;

}

// -------------------------------------------------

// Функция инициализации дескриптора в таблице GDT

// -------------------------------------------------

void init_gdt_descriptor(descriptor *descr,

unsigned long base,

word limit,

unsigned char type)

{

// Младшее слово базового адреса

descr->base_lo = (word)base;

// Старший байт базового адреса

descr->base_hi = (unsigned char)(base >> 16);

// Поле доступа дескриптора

descr->type_dpl = type;

// Предел

descr->limit = limit;

// Зарезервированное поле, должно быть

// сброшено в 0 всегда (для процессоров 286)

descr->reserved = 0;

}

// -----------------------------------------------

// Инициализация всех таблиц и вход

// в защищённый режим

// -----------------------------------------------

void Init_And_Protected_Mode_Entry(void)

{

union REGS r;

// Инициализируем таблицу GDT, элементы с 1 по 5

init_gdt_descriptor(&gdt[1], MK_LIN_ADDR(_CS, 0),

0xffffL, TYPE_CODE_DESCR | SEG_PRESENT_BIT | SEG_READABLE);