Interrupt Vector Table
Interrupt Vector Table
Hi all,
Im still programming in real mode and as i've read from the intel manuals in real mode theres an IDT like structure for handling interrupts. My question is how can i program it (is it similar to the IDT in means of assigning interrupt handlers?) I mean the IDT has to face the protection mechanisms which doesn't exist in real mode. But i didn't find any tutorials on the int. vector table.
Best Regards
Im still programming in real mode and as i've read from the intel manuals in real mode theres an IDT like structure for handling interrupts. My question is how can i program it (is it similar to the IDT in means of assigning interrupt handlers?) I mean the IDT has to face the protection mechanisms which doesn't exist in real mode. But i didn't find any tutorials on the int. vector table.
Best Regards
I need someone to show me the things in life that I cant find
I cant see the things that make true happiness, I must be blind
I cant see the things that make true happiness, I must be blind
- xenos
- Member
- Posts: 1121
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
In real mode there exists an interrupt vector table at address 0:0 containing 256 entries. Each entry consists of the segment:offset address of an interrupt handler routine and is 4 bytes long. That makes programming the IVT very easy: Just put the address of your handler routine at seg:off = 0:(4 * intnum).
I have coded a simple Dos OS (called "MiniDOS" ) that is also a tut for beginner OS devs, this is compatable with Dos for basic stuff, it will run some old dos games com or exe, but is less than 2k.
Have a look at the code may help.
http://www.dex4u.com/etc/MiniDos.zip
Runs in qemu too, screenshot:
Have a look at the code may help.
http://www.dex4u.com/etc/MiniDos.zip
Runs in qemu too, screenshot:
-
- Member
- Posts: 31
- Joined: Thu Apr 14, 2005 11:00 pm
- Location: Planet Earth
- Contact:
- carbonBased
- Member
- Posts: 382
- Joined: Sat Nov 20, 2004 12:00 am
- Location: Wellesley, Ontario, Canada
- Contact:
There's nothing wrong with TASM.deathangel wrote:Why in the world are you using TASM? Use NASM and get real! lol
As per your assembly line:
mov word ptr [0:00h*4],int20
What does TASM complain about? I haven't used in a while, so I forget it's memory syntax. You might try:
mov word ptr [DS:0], int20
with ds == 0.
It's true, though, that you'll probably get more help with nasm issues, as most osdevers here seem to use it (and some use fasm).
--Jeff
Thanks, but that code does not look right, wheres it from ?.
Also you should use fasm (the best assembler in the world! ) as MiniDOS is coded in fasm.
Also note that you can write your OS in turbo pascal or freepascal and MiniDOS can be used as a boot loader, i wrote a turbo pascal OS many years ago, also here's a pmode freepascal OS to study.
http://www.dex4u.com/images/AnonymOS.zip
Also you should use fasm (the best assembler in the world! ) as MiniDOS is coded in fasm.
Also note that you can write your OS in turbo pascal or freepascal and MiniDOS can be used as a boot loader, i wrote a turbo pascal OS many years ago, also here's a pmode freepascal OS to study.
http://www.dex4u.com/images/AnonymOS.zip
I would use NASM IF BP 7.0 supported it.
TASM will generate error:
"Need register in expression" = that INT20 label!.
Why NASM dont support BP 7.0?
Because NASM dont have any declarations of procedures. "Procedure is a label" - taken from some Linux programming. Borland Pascal will then generate error "Unresolved external" - because I am using external procedures, that MUST be definded as proc:
"IntHandler proc near"
and not
"IntHandler:" or "@@IntHandler:"
You may say: "So use FreePascal".
I am sticked to years-preffered "tradition" and Free Pascal will put some extender stuff in that executable and many other things. Forget about it completely. I just need some working code, please, so dont protest for BP or FP or NASM.
//EDIT:
to DEX: I use Alexei Frounze's bootloader (like you ) to boot an EXE.
That ASM line is from your MiniDOS.
//EDIT2:
Sorry for bad English. I not study English and i live in SR.
Thanks
inflater
TASM will generate error:
"Need register in expression" = that INT20 label!.
Why NASM dont support BP 7.0?
Because NASM dont have any declarations of procedures. "Procedure is a label" - taken from some Linux programming. Borland Pascal will then generate error "Unresolved external" - because I am using external procedures, that MUST be definded as proc:
"IntHandler proc near"
and not
"IntHandler:" or "@@IntHandler:"
You may say: "So use FreePascal".
I am sticked to years-preffered "tradition" and Free Pascal will put some extender stuff in that executable and many other things. Forget about it completely. I just need some working code, please, so dont protest for BP or FP or NASM.
//EDIT:
to DEX: I use Alexei Frounze's bootloader (like you ) to boot an EXE.
That ASM line is from your MiniDOS.
//EDIT2:
Sorry for bad English. I not study English and i live in SR.
Thanks
inflater
- carbonBased
- Member
- Posts: 382
- Joined: Sat Nov 20, 2004 12:00 am
- Location: Wellesley, Ontario, Canada
- Contact:
Indeed, this makes sense. You can't move from memory to memory... only from register to memory and vise versa.inflater wrote: TASM will generate error:
"Need register in expression" = that INT20 label!.
That's not exactly true. When you get right down to it, functions *are* labels. The only reason you're getting an unresolved external when using nasm, I assume, is because you haven't made the label global, or are not abiding by the ABI (which probably states _ prefixes):inflater wrote: Why NASM dont support BP 7.0?
Because NASM dont have any declarations of procedures. "Procedure is a label" - taken from some Linux programming. Borland Pascal will then generate error "Unresolved external" - because I am using external procedures, that MUST be definded as proc:
.global _myFunc
_myFunc:
; do stuff
ret
Any assembler should be able to interface with any C compiler (edit: or pascal compiler ), you just need to match the calling conventions.
Cheers,
Jeff
No. Still not working
Borland Pascal 7.0 will report this message when compiling:
Invalid PUBLIC definition
and that says all. - There is no PUBLIC definition for proc _IntHandlers, only GLOBAL.
(Fixed one small bug - removed dot from .GLOBAL)
My code in NASM (converted from TASM):
Borland Pascal 7.0 will report this message when compiling:
Invalid PUBLIC definition
and that says all. - There is no PUBLIC definition for proc _IntHandlers, only GLOBAL.
(Fixed one small bug - removed dot from .GLOBAL)
My code in NASM (converted from TASM):
Code: Select all
use16
global _IntHandlers
_IntHandlers:
push ds
cli
xor ax,ax
mov ds,ax
mov word [ds:00h*4],int00
mov word [ds:00h*4+2],cs
sti
jmp koniec ;This word is END in Slovak Language :D
int00:
extern _CPUINT0 ;warning - a Pascal procedure !
call _CPUINT0
koniec:
pop ds
ret
end
That code in minidos is this
Here is some code from my old pascal OS that may help
I may have used a mod ver of the dos.tpu, if you have problem let me know and i will send you it.
PS: This was written many years ago, when i was into pascal programming
Code: Select all
;====================================================;
; Install int. ;
;====================================================;
Installints:
push ds ; Save DS
cli ; Turn off int's
xor ax,ax
mov ds,ax ; 0 DS
mov word [ds:20h*4],int20 ; load int vecter with int20h address
mov word [ds:20h*4+2],cs ; + CS
mov word [ds:21h*4],int21 ; load int vecter with int21h address
mov word [ds:21h*4+2],cs ; + CS
sti ; Turn on int's
pop ds ; restore DS
ret ; Return
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.
PS: This was written many years ago, when i was into pascal programming
Last edited by Dex on Fri Sep 29, 2006 12:23 pm, edited 1 time in total.
I try your function, thanks
I tried AT LEAST 3 forums and nothing... You know, that is really annoying and disgusting, when you must ask some shitty forums (i keep my mouth shut) and no answer or 5,000,000 answers from total nerds, that did not know what Pascal/ASM means... But this forum is maybe better than another (for example, some google groups).
//EDIT: I need GETINTVEC/SETINTVEC translated to normal PROCEDURE block. Can you help me?
inflater
I tried AT LEAST 3 forums and nothing... You know, that is really annoying and disgusting, when you must ask some shitty forums (i keep my mouth shut) and no answer or 5,000,000 answers from total nerds, that did not know what Pascal/ASM means... But this forum is maybe better than another (for example, some google groups).
//EDIT: I need GETINTVEC/SETINTVEC translated to normal PROCEDURE block. Can you help me?
inflater
But you can just use this, for seting ISR.
Also try this
Code: Select all
BEGIN
ASM
cli
xor ah, ah {al = function number to replace eg: 21h }
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
@endit:
END;
END;
Code: Select all
Procedure SetIntVec(Vec:integer;VAddr:pointer);
begin
pointer(meml[0:vec*4]) := vaddr;
end;
Procedure GetIntVec(Vec:integer;VAddr:pointer);
begin
vaddr:=pointer(meml[0:vec*4]);
end;