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 Мб памяти, работа с прерываниями в защищенном режиме процессора, организация мультизадачных операционных систе
... под него. Среди остальных расширителей можно отметить: Phar Lap 386/DOS-Extender; Quarterdeck DESQview и DESQview /X, обеспечивающий многозадачную и многооконную работу обычных программ DOS; 16- и 32-битные расширители DOS фирмы Borland, поставлявшиеся с компиляторами C++ и Паскаля; GO32 (используется в GCC и Free Pascal); WDOSX (эмулирует подмножество Win32 и позволяет некоторым консольным ...
... также невысока и обычно составляет около 100 кбайт/с. НКМЛ могут использовать локальные интерфейсы SCSI. Лекция 3. Программное обеспечение ПЭВМ 3.1 Общая характеристика и состав программного обеспечения 3.1.1 Состав и назначение программного обеспечения Процесс взаимодействия человека с компьютером организуется устройством управления в соответствии с той программой, которую пользователь ...
... для таблиц dBASE и Paradox. С использованием этих компонентов создание программы просмотра и редактирования базы данных почти не требует программирования. Win 3.1. На этой странице находятся компоненты Delphi 1.0, возможности которых перекрываются аналогичными компонентами Windows 95. Internet. Эта страница предоставляет компоненты для разработки приложений, позволяющих создавать HTML ...
... в Win32 позволила реализовать так называемые многопотоковые приложения (multithread application). При этом выделяют два новых понятия — процесс (proccess) и поток (thread). Процессы в Win32 API примерно эквивалентны приложениям в Windows API. Для каждого процесса выделяются определенные системные ресурсы — адресное пространство, приоритеты и права доступа к разделяемым ресурсам и прочее, но не ...
0 комментариев