4.11.2 SCREEN.C

#include <stdio.h>

#include <dos.h>

#include <conio.h>

#include <stdlib.h>

#include "tos.h"

#include "screen.h"

void vi_putch(unsigned int x, unsigned int y ,char c, char attr);

char hex_tabl[] = "0123456789ABCDEF";

// Вывод байта на экран, координаты (x,y),

// выводится шестнадцатеричное представление

// байта chr с экранными атрибутами attr.

void vi_put_byte(unsigned int x,

unsigned int y, unsigned char chr, char attr)

{

unsigned char temp;

temp = hex_tabl[(chr & 0xf0) >> 4];

vi_putch(x, y, temp, attr);

temp = hex_tabl[chr & 0xf];

vi_putch(x+1, y, temp, attr);

}

// Вывод слова на экран, координаты (x,y),

// выводится шестнадцатеричное представление

// слова chr с экранными атрибутами attr.

void vi_put_word(unsigned int x,

unsigned int y, word chr, char attr)

{

vi_put_byte(x, y, (chr & 0xff00) >> 8, attr);

vi_put_byte(x+2, y, chr & 0xff, attr);

}

// Вывод символа c на экран, координаты - (x,y),

// атрибут выводимого символа - attr

void vi_putch(unsigned int x,

unsigned int y ,char c, char attr)

{

register unsigned int offset;

char far *vid_ptr;

offset = (y*160) + (x*2);

vid_ptr = MK_FP(VID_MEM_SELECTOR, offset);

*vid_ptr++=c; *vid_ptr=attr;

}

// Вывод строки s на экран, координаты - (x,y),

// атрибут выводимой строки - attr

void vi_print(unsigned int x,

unsigned int y, char *s, char attr)

{

while (*s)

vi_putch(x++, y, *s++, attr);

}

// Вывод стоки сообщения о запуске программы

void vi_hello_msg(void)

{

vi_print(0, 0,

" Threads for DOS, "

" Version 0.1/i286, Copyright (c) 2000 Eugeny Balahonov ", 0x30);

}

// Вывод бегущей строки

void StepLabel(TLabel* Label1, TLabel* Label2, char* Buf)

{

// Стираем символы меток

Buf[Label1->Pos] = ' ';

Buf[Label2->Pos] = ' ';

// Если двигаемся налево

if (Label1->Dir == 0)

{

// Если не дошли до крайней левой позиции

if (Label1->Pos > 0)

{

Label1->Pos--;

Buf[Label1->Pos] = '';

}

else

{

Label1->Dir = 1;

Buf[Label1->Pos] = '/';

}

}

// Если двигаемся направо

else

{

// Если не дошли до крайней правой позиции

if (Label1->Pos < B_SIZE)

{

Label1->Pos++;

Buf[Label1->Pos] = '/';

}

else

{

Label1->Dir = 0;

Buf[Label1->Pos] = '';

}

}

// Если двигаемся налево

if (Label2->Dir == 0)

{

// Если не дошли до крайней левой позиции

if (Label2->Pos > 0)

{

Label2->Pos--;

Buf[Label2->Pos] = '';

}

else

{

Label2->Dir = 1;

Buf[Label2->Pos] = '/';

}

}

// Если двигаемся направо

else

{

// Если не дошли до крайней правой позиции

if (Label2->Pos < B_SIZE)

{

Label2->Pos++;

Buf[Label2->Pos] = '/';

}

else

{

Label2->Dir = 0;

Buf[Label2->Pos] = '';

}

}

}

4.12 Файл TOSSYST.ASM. Процедуры для инициализации, перехода в защищённый режим и возврата в реальный режим, для загрузки регистра TR и переключения задач.

IDEAL

MODEL SMALL

RADIX 16

P286

DATASEG

include "tos.inc"

PUBLIC _beep

; Область памяти для инициализации IDTR

idtr idtr_struc <,,,0>

; Область памяти для инициализации GDTR

gdt_ptr dw (8*15)-1 ; размер GDT, 15 элементов

gdt_ptr2 dw ?

gdt_ptr4 dw ?

; Область памяти для записи селектора задачи,

; на которую будет происходить переключение

new_task dw 00h

new_select dw 00h

; Область памяти для хранения регистров,

; используется для возврата в реальный режим

real_ss dw ?

real_sp dw ?

real_es dw ?

protect_sel dw ?

init_tss dw ?

CODESEG

PUBLIC _real_mode,_protected_mode,_jump_to_task

PUBLIC _load_task_register, _load_idtr, _enable_interrupt

; -------------------------------------------------------------------

; Процедура для переключения в защищённый режим.

; Прототип для вызова:

; void protected_mode(unsigned long gdt_ptr, unsigned int gdt_size,

; unsigned int cseg, unsigned int dseg)

; -------------------------------------------------------------------

PROC _protected_mode NEAR

push bp

mov bp,sp

; Параметр gdt_ptr

mov ax,[bp+4] ; мл. слово адреса GDT

mov dx,[bp+6] ; ст. слово адреса GDT

mov [gdt_ptr4], dx ; запоминаем адрес GDT

mov [gdt_ptr2], ax

; Параметр gdt_size

mov ax,[bp+8] ; получаем размер GDT

mov [gdt_ptr], ax ; и запоминаем его

; Параметры cseg и dseg

mov ax,[bp+10d] ; получаем селектор сегмента кода

mov dx,[bp+12d] ; получаем селектор сегмента данных

mov [cs:p_mode_select], ax ; запоминаем для команды

mov [protect_sel], dx ; перехода far jmp

; Подготовка к возврату в реальный режим

push ds ; готовим адрес возврата

mov ax,40h ; из защищённого режима

mov ds,ax

mov [WORD 67h],OFFSET shutdown_return

mov [WORD 69h],cs

pop ds

; Запрещаем и маскируем все прерывания

cli

in al, INT_MASK_PORT

and al, 0ffh

out INT_MASK_PORT, al

; Записываем код возврата в CMOS-память

mov al,8f

out CMOS_PORT,al

jmp delay1

delay1:

mov al,5

out CMOS_PORT+1,al

call enable_a20 ; открываем линию A20

mov [real_ss],ss ; запоминаем регистры SS и ES

mov [real_es],es

; Перепрограммируем контроллер прерываний

; для работы в защищённом режиме

mov dx,MASTER8259A

mov ah,20

call set_int_ctrlr

mov dx,SLAVE8259A

mov ah,28

call set_int_ctrlr

; Загружаем регистры IDTR и GDTR

lidt [FWORD idtr]

lgdt [QWORD gdt_ptr]

mov ax, 0001h ; переключаем процессор

lmsw ax ; в защищённый режим

; jmp far flush

db 0eah

dw OFFSET flush

p_mode_select dw ?

LABEL flush FAR

mov dx, [protect_sel]

mov ss, dx

mov ds, dx

mov es, dx

; Обнуляем содержимое регистра LDTR

mov ax, 0

lldt ax

pop bp

ret

ENDP _protected_mode

; ----------------------------------------------------

; Возврат в реальный режим.

; Прототип для вызова

; void real_mode();

; ----------------------------------------------------

PROC _real_mode NEAR

; Сброс процессора

cli

mov [real_sp], sp

mov al, SHUT_DOWN

out STATUS_PORT, al

rmode_wait:

hlt

jmp rmode_wait

LABEL shutdown_return FAR

; Вернулись в реальный режим

mov ax, DGROUP

mov ds, ax

assume ds:DGROUP

mov ss,[real_ss]

mov sp,[real_sp]

in al, INT_MASK_PORT

and al, 0

out INT_MASK_PORT, al

call disable_a20

mov ax, DGROUP

mov ds, ax

mov ss, ax

mov es, ax

mov ax,000dh

out CMOS_PORT,al

sti

ret

ENDP _real_mode

; -------------------------------------------------------

; Загрузка регистра TR.

; Прототип для вызова:

; void load_task_register(unsigned int tss_selector);

; -------------------------------------------------------

PROC _load_task_register NEAR

push bp

mov bp,sp

ltr [bp+4] ; селектор для текущей задачи

pop bp

ret

ENDP _load_task_register

; -------------------------------------------------------

; Переключение на задачу.

; Прототип для вызова:

; void jump_to_task(unsigned int tss_selector);

; -------------------------------------------------------

PROC _jump_to_task NEAR

push bp

mov bp,sp

mov ax,[bp+4] ; получаем селектор

; новой задачи

mov [new_select],ax ; запоминаем его

jmp [DWORD new_task] ; переключаемся на

; новую задачу

pop bp

ret

ENDP _jump_to_task

; ------------------------------

; Открываем линию A20

; ------------------------------

PROC enable_a20 NEAR

push ax

mov al, A20_PORT

out STATUS_PORT, al

mov al, A20_ON

out KBD_PORT_A, al

pop ax

ret

ENDP enable_a20

; ------------------------------

; Закрываем линию A20

; ------------------------------

PROC disable_a20 NEAR

push ax

mov al, A20_PORT

out STATUS_PORT, al

mov al ,A20_OFF

out KBD_PORT_A, al

pop ax

ret

ENDP disable_a20

; -----------------------------------------------------------

; Готовим структуру для загрузки регистра IDTR

; Прототип для вызова функции:

; void load_idtr(unsigned long idt_ptr, word idt_size);

; -----------------------------------------------------------

PROC _load_idtr NEAR

push bp

mov bp,sp

mov ax,[bp+4] ; мл. слово адреса IDT

mov dx,[bp+6] ; ст. слово адреса IDT

mov bx, OFFSET idtr

; Запоминаем адрес IDTR в структуре

mov [(idtr_struc bx).idt_low], ax

mov [(idtr_struc bx).idt_hi], dl

; Получаем предел IDT и запоминаем его в структуре

mov ax, [bp+8]

mov [(idtr_struc bx).idt_len], ax

pop bp

ret

ENDP _load_idtr

; ----------------------------------

; Установка контроллера прерываний

; ----------------------------------

PROC set_int_ctrlr NEAR

mov al, 11

out dx, al

jmp SHORT $+2

mov al, ah

inc dx

out dx, al

jmp SHORT $+2

mov al, 4

out dx, al

jmp SHORT $+2

mov al, 1

out dx, al

jmp SHORT $+2

mov al, 0ffh

out dx, al

dec dx

ret

ENDP set_int_ctrlr

; --------------------------

; Выдача звукового сигнала

; --------------------------

PROC _beep NEAR

push ax bx cx

in al,KBD_PORT_B

push ax

mov cx,80

beep0:

push cx

and al,11111100b

out KBD_PORT_B,al

mov cx,60

idle1:

loop idle1

or al,00000010b

out KBD_PORT_B,al

mov cx,60

idle2:

loop idle2

pop cx

loop beep0

pop ax

out KBD_PORT_B,al

pop cx bx ax

ret

ENDP _beep

; -------------------------------

; Задержка выполнения программы

; -------------------------------

PROC _pause NEAR

push cx

mov cx,10

ploop0:

push cx

xor cx,cx

ploop1:

loop ploop1

pop cx

loop ploop0

pop cx

ret

ENDP _pause

; -----------------------

; Размаскирование прерываний

; -----------------------

PROC _enable_interrupt NEAR

in al, INT_MASK_PORT

and al, 0fch

out INT_MASK_PORT, al

sti

ret

ENDP _enable_interrupt

end

5. Выводы.

Процессоры семейства Intel x86 реализуют необходимые средства для организации мультизадачных ОС с разделением адресного пространства и виртуальной памяти.

В процессе написания данного курсового проекта мной были изучена организация работы защищенного режима процессоров 80286, адресация ими свыше 1 Мб памяти, работа с прерываниями в защищенном режиме процессора, организация мультизадачных операционных систе


Информация о работе «DOS-extender для компилятора Borland C++»
Раздел: Информатика, программирование
Количество знаков с пробелами: 67701
Количество таблиц: 0
Количество изображений: 1

Похожие работы

Скачать
35965
0
1

... под него. Среди остальных расширителей можно отметить: Phar Lap 386/DOS-Extender; Quarterdeck DESQview и DESQview /X, обеспечивающий многозадачную и многооконную работу обычных программ DOS; 16- и 32-битные расширители DOS фирмы Borland, поставлявшиеся с компиляторами C++ и Паскаля; GO32 (используется в GCC и Free Pascal); WDOSX (эмулирует подмножество Win32 и позволяет некоторым консольным ...

Скачать
448518
14
55

... также невысока и обычно составляет около 100 кбайт/с. НКМЛ могут использовать локальные интерфейсы SCSI. Лекция 3. Программное обеспечение ПЭВМ 3.1 Общая характеристика и состав программного обеспечения 3.1.1 Состав и назначение программного обеспечения Процесс взаимодействия человека с компьютером организуется устройством управления в соответствии с той программой, которую пользователь ...

Скачать
127060
2
1

... для таблиц dBASE и Paradox. С использованием этих компонентов создание программы просмотра и редактирования базы данных почти не требует программирования. Win 3.1. На этой странице находятся компоненты Delphi 1.0, возможности которых перекрываются аналогичными компонентами Windows 95. Internet. Эта страница предоставляет компоненты для разработки приложений, позволяющих создавать HTML ...

Скачать
175379
2
5

... в Win32 позволила реализовать так называемые многопотоковые приложения (multithread application). При этом выделяют два новых понятия — процесс (proccess) и поток (thread). Процессы в Win32 API примерно эквивалентны приложениям в Windows API. Для каждого процесса выделяются определенные системные ресурсы — адресное пространство, приоритеты и права доступа к разделяемым ресурсам и прочее, но не ...

0 комментариев


Наверх