Page 1 of 2

Interrupt Vector Table

Posted: Fri Aug 25, 2006 5:44 am
by joke
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

Posted: Sat Aug 26, 2006 2:04 am
by xenos
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).

Posted: Sat Aug 26, 2006 4:00 pm
by Dex
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:
Image

Posted: Sun Aug 27, 2006 5:37 am
by joke
I've already checked yuor os :D Nice work! And i also found the code for loading dos interrupts :wink: Thank you both

Posted: Thu Sep 28, 2006 10:39 am
by inflater
Hi all,

the MiniDOS is what I need! It is cool! ;)

But, I am an ASM newbie (intermediate in Pascal) and i am writing my own OS (in Pascal :D thanx to Alexei Frounze and you :D ).

I need to translate this line
mov word ptr [0:00h*4],int20

to TASM.
Can you help me?

Inflater

Posted: Thu Sep 28, 2006 12:42 pm
by deathangel
Why in the world are you using TASM? Use NASM and get real! lol

Posted: Thu Sep 28, 2006 2:08 pm
by carbonBased
deathangel wrote:Why in the world are you using TASM? Use NASM and get real! lol
There's nothing wrong with TASM.

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

Posted: Thu Sep 28, 2006 5:12 pm
by Dex
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

Posted: Thu Sep 28, 2006 10:14 pm
by inflater
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

Posted: Fri Sep 29, 2006 9:34 am
by carbonBased
inflater wrote: TASM will generate error:
"Need register in expression" = that INT20 label!.
Indeed, this makes sense. You can't move from memory to memory... only from register to memory and vise versa.
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:
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):

.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

Posted: Fri Sep 29, 2006 10:58 am
by inflater
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):

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


Posted: Fri Sep 29, 2006 12:08 pm
by Dex
That code in minidos is this

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
Here is some code from my old pascal OS that may help

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.

PS: This was written many years ago, when i was into pascal programming

Posted: Fri Sep 29, 2006 12:18 pm
by inflater
I try your function, thanks :D

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... :evil: 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

Posted: Fri Sep 29, 2006 12:43 pm
by Dex
But you can just use this, for seting ISR.

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; 
 
Also try this

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;

Posted: Fri Sep 29, 2006 1:30 pm
by inflater
Thank GOD thats over !!! :D
It is working for now - Ive combined those functions, added CLI and STI to beginning of every part of INT handling.

If someone needs the code, write here.

Thanks Dex, you are very VERY helpful !!!
inflater