Code: Select all
{MZ}
uses dos, strings;
var
OLDHANDLER : Procedure;
{$F+}
Procedure int21HANDLER(Flags, CS, IP, AX, BX, CX, DX,SI, DI,
DS, ES, BP: Word); Interrupt;
var
end_memory,top_memory:integer;
DriveNumber:byte;
Begin
{read character with echo}
IF HI(AX)=$01 THEN
BEGIN
ASM
XOR AX, AX
int 16h
mov ah, 0Eh
int 10h
END;
END;
{write character}
IF HI(AX)=$02 THEN
BEGIN
ASM
mov al, dl
mov ah, 0Eh
int 10h
END;
END;
{read character without echo}
IF HI(AX)=$07 THEN
BEGIN
ASM
xor ax, ax
int 16h
END;
END;
{ write string; input ds:dx = string (ended with '$')}
IF HI(AX)=$09 THEN
BEGIN
ASM { ds:dx points to string}
mov si,dx { ds:si = string}
cld
@print_loop:
lodsb { get next character}
cmp al,'$' { is it $ ?}
je @done { if so, we're done}
mov ah,0eh { function 0eh-print character}
xor bx,bx { video page 0}
int 10h
jmp @print_loop
@done:
mov ax,0e0ah
int 10h
mov ax,0e0dh
int 10h
END;
END;
{ get current drive}
IF HI(AX)=$19 THEN
BEGIN
DriveNumber:=0;
ASM
mov al,cs:[DriveNumber]
END;
END;
{set interrupt vector}
IF HI(AX)=$25 THEN
BEGIN
ASM
cmp al, 19h { do not allow to change int 19h (for rebooting)}
je @int21_error
cli
xor ah, ah
shl ax, 2
push si
push bx
push es
mov si, ax
xor bx, bx
mov es, bx
mov word ptr es:[si], dx { offset}
mov bx, ds
mov word ptr es:[si+2], bx { segment}
pop es
pop bx
pop si
sti
jmp @endit
@int21_error:
mov ax, 0FFFFh
@endit:
END;
END;
{get date
IF HI(AX)=$2A THEN
BEGIN
END;}
{set date
IF HI(AX)=$2B THEN
BEGIN
END;}
{get time
IF HI(AX)=$2C THEN
BEGIN
END;}
{set time
IF HI(AX)=$2D THEN
BEGIN
END;}
{jmp int21_error}
{get dos version}
IF HI(AX)=$30 THEN
BEGIN
AX:=$3031;
END;
{get interrupt vector}
IF HI(AX)=$35 THEN
BEGIN
ASM
push ds
push si
xor ah, ah
shl ax, 2
mov si, ax
xor bx, bx
mov ds, bx
mov bx, word ptr ds:[si+2]
push bx
mov bx, word ptr ds:[si]
pop es
pop si
pop ds
END;
END;
{alloc ram memory}
IF HI(AX)=$48 THEN
BEGIN
ASM
mov ax, es
shr ax, 2
inc ax
shl ax, 2
mov word ptr [end_memory], ax {; save (to know free memory)}
int 12h {; get ram size (in KB)}
{ ; convert in paragraphs: (*64)}
shl ax, 6
mov word ptr [top_memory], ax
mov ax, word ptr cs:[end_memory]
add ax, bx
cmp ax, word ptr cs:[top_memory]
jg @error
mov word ptr cs:[top_memory], ax
mov bx, word ptr cs:[top_memory] { return in bx free paragraphs}
sub bx, word ptr cs:[end_memory]
jmp @endit1
@error:
stc
mov ax, 0FFFFh
@endit1:
END;
END;
IF HI(AX)=$4C THEN
BEGIN
ASM
push cs
pop ax
mov ds, ax
mov es, ax
mov ip,0FFFFh
END;
END;
END;
{$F-}
procedure ShowText; assembler;
const
Msg :PChar =
'This text is shown using DOS ...INT 21h (09h) $';
asm
mov dx,word ptr Msg
mov ah,9
int 21h
end;
procedure WriteChr(Chr: Char);
begin
asm
MOV Al, Chr
PUSHA
MOV Ah, 0Eh
INT 10h
POPA
end;
end;
procedure next_line;
begin
asm
MOV AH,3
INT 10h
MOV AH,2
INC DH
MOV DL,0
INT 10h
end;
end;
PROCEDURE DOS_VER;
BEGIN
ASM
mov aH, 30h
int 21h
mov bl,ah
mov aH,0eh
int 10h
mov ax,0e2eh
int 10h
mov al,bl
mov aH,0eh
int 10h
END;
END;
procedure WritelnA(Str: String);
var
Pos: Integer;
Chr: array[0..254] of Char;
begin
StrPCopy(Chr, Str);
for Pos := 0 to (Length(Str) - 1) do
begin
WriteChr(Chr[Pos]);
end;
next_line;
end;
procedure WriteA(Str: String);
var
Pos: Integer;
Chr: array[0..254] of Char;
begin
StrPCopy(Chr, Str);
for Pos := 0 to (Length(Str) - 1) do
begin
WriteChr(Chr[Pos]);
end;
end;
procedure hold;
begin
asm
PUSHA
XOR AX,AX
INT 16h
POPA
end;
end;
Procedure INSTALL_HANDLER;
begin
GetIntVec($21,@OLDHANDLER);
SetIntVec($21,ADDR(int21HANDLER));
end;
PROCEDURE CLS;
BEGIN
ASM
mov AH,2
mov BH,0
mov DX,0
int 16
mov AH,9
mov CX,2000
mov AL,' '
mov BL,7
int 16
mov AH,2
mov BH,0
mov DX,0
int 16
END;
END;
begin
INSTALL_HANDLER;
writelnA('loading kernel 16 !');
hold;
CLS;
writelnA('hello world!');
hold;
writelnA('DOES INT 21 09h WORK?');
HOLD;
SHOWTEXT;
HOLD;
WriteA('The PAS-DOS Version ');DOS_VER;
NEXT_LINE;
hold;
writelnA('press enter to reboot!');
hold;
end.
I may have used a mod ver of the dos.tpu, if you have problem let me know and i will send you it.