DOS-extender для компилятора Borland C++ 3.1, защищенный режим процессора 80286, организация многозадачной работы процессора
Страница 9
jmp keyb_putq_exit
@@kb8:
cmp ax, 0038h ; L_ALT down
jnz @@kb9
mov ax, [_keyb_status]
or ax, L_ALT
mov [_keyb_status], ax
jmp keyb_putq_exit
@@kb9:
cmp ax, 00b8h ; L_ALT up
jnz @@kb10
mov ax, [_keyb_status]
and ax, NL_ALT
mov [_keyb_status], ax
jmp keyb_putq_exit
@@kb10:
cmp ax, 0e038h ; R_ALT down
jnz @@kb11
mov ax, [_keyb_status]
or ax, R_ALT
mov [_keyb_status], ax
jmp keyb_putq_exit
@@kb11:
cmp ax, 0e0b8h ; R_ALT up
jnz @@kb12
mov ax, [_keyb_status]
and ax, NR_ALT
mov [_keyb_status], ax
jmp keyb_putq_exit
@@kb12:
cmp ax, 003ah ; CAPS_LOCK up
jnz @@kb13
mov ax, [_keyb_status]
xor ax, CAPS_LOCK
mov [_keyb_status], ax
jmp keyb_putq_exit
@@kb13:
cmp ax, 00bah ; CAPS_LOCK down
jnz @@kb14
jmp keyb_putq_exit
@@kb14:
cmp ax, 0046h ; SCR_LOCK up
jnz @@kb15
mov ax, [_keyb_status]
xor ax, SCR_LOCK
mov [_keyb_status], ax
jmp keyb_putq_exit
@@kb15:
cmp ax, 00c6h ; SCR_LOCK down
jnz @@kb16
jmp keyb_putq_exit
@@kb16:
cmp ax, 0045h ; NUM_LOCK up
jnz @@kb17
mov ax, [_keyb_status]
xor ax, NUM_LOCK
mov [_keyb_status], ax
jmp keyb_putq_exit
@@kb17:
cmp ax, 00c5h ; NUM_LOCK down
jnz @@kb18
jmp keyb_putq_exit
@@kb18:
cmp ax, 0e052h ; INSERT up
jnz @@kb19
mov ax, [_keyb_status]
xor ax, INSERT
mov [_keyb_status], ax
jmp keyb_putq_exit
@@kb19:
cmp ax, 0e0d2h ; INSERT down
jnz @@kb20
jmp keyb_putq_exit
@@kb20:
test ax, 0080h
jnz keyb_putq_exit
mov [_key_code], ax
mov al, 0ffh
mov [_key_flag], al
keyb_putq_exit:
pop ax
ret
ENDP Keyb_PutQ
; Обработчик программного прерывания
; для ввода с клавиатуры. По своим функциям
; напоминает прерывание INT 16 реального
; режима.
PROC _Int_30h_Entry NEAR
push ax dx
; Ожидаем прерывание от клавиатуры
keyb_int_wait:
sti
nop
nop
cli
; Проверяем флаг, который устанавливается
; обработчиком аппаратного прерывания клавиатуры
mov al, [_key_flag]
cmp al, 0
jz keyb_int_wait
; Сбрасываем флаг после прихода прерывания
mov al, 0
mov [_key_flag], al
sti
pop dx ax
iret
ENDP _Int_30h_Entry
END
#ifndef SCREEN_H
#define SCREEN_H
// Границы перемещения бегунков
#define B_SIZE 70
// Структура, описывающая бегунок
typedef struct _TLabel
{
char Pos; // Позиция бегунка
char Dir; // Направление движения
} TLabel;
extern void StepLabel(TLabel* Label1, TLabel* Label2, char* Buf);
#endif
#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] = '\\';
}
}
}
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 ; запоминаем для команды