next up previous contents index
Next: Real mode callbacks Up: Protected mode memory organization Previous: Hardware interrupts

Software interrupts

Ordinarily, a handler installed with set_pm_interrupt only services software interrupts that are executed in protected mode; real mode software interrupts can be redirected by set_rm_interrupt.

See also set_rm_interrupt, get_rm_interrupt, set_pm_interrupt, get_pm_interrupt, lock_data, lock_code, enable, disable, outportb

The following examples illustrate the use of software interrupts.

Example
Program softint;

uses go32;

var r : trealregs;

begin
     r.al := $01;
     realintr($21, r);
     Writeln('DOS v', r.al,'.',r.ah, ' detected');
end.

Example
Program rmpm_int;

uses crt, go32;

{$ASMMODE DIRECT}

var r : trealregs;
    axreg : Word; 

    oldint21h : tseginfo;
    newint21h : tseginfo;

procedure int21h_handler; assembler;
asm
   cmpw $0x3001, %ax
   jne CallOld
   movw $0x3112, %ax
   iret

CallOld:
   ljmp %cs:OLDHANDLER

OLDHANDLER: .long 0
            .word 0
end;

procedure resume;
begin
     Writeln;
     Write('-- press any key to resume --'); readkey;
     gotoxy(1, wherey); clreol;
end;

begin
     clrscr;
     Writeln('Executing real mode interrupt');
     resume;
     r.ah := $30; r.al := $01;  realintr($21, r);
     Writeln('DOS v', r.al,'.',r.ah, ' detected');
     resume;
     Writeln('Executing protected mode interrupt',
             ' without our own handler');
     Writeln;
     asm
        movb $0x30, %ah
        movb $0x01, %al
        int $0x21
        movw %ax, _AXREG
     end;
     Writeln('DOS v', r.al,'.',r.ah, ' detected');
     resume;
     Writeln('As you can see the DPMI hosts',
             ' default protected mode handler');
     Writeln('simply redirects it to the real mode handler');
     resume;
     Writeln('Now exchanging the protected mode',
             'interrupt with our own handler');
     resume;

     newint21h.offset := @int21h_handler;
     newint21h.segment := get_cs;
     get_pm_interrupt($21, oldint21h);
     asm
        movl _OLDINT21H, %eax
        movl %eax, OLDHANDLER
        movw 4+_OLDINT21H, %ax
        movw %ax, 4+OLDHANDLER
     end;
     set_pm_interrupt($21, newint21h);

     Writeln('Executing real mode interrupt again');
     resume;
     r.ah := $30; r.al := $01; realintr($21, r);
     Writeln('DOS v', r.al,'.',r.ah, ' detected');
     Writeln;
     Writeln('See, it didn''t change in any way.');
     resume;
     Writeln('Now calling protected mode interrupt');
     resume;
     asm
        movb $0x30, %ah
        movb $0x01, %al
        int $0x21
        movw %ax, _AXREG
     end;
     Writeln('DOS v', lo(axreg),'.',hi(axreg), ' detected');
     Writeln;
     Writeln('Now you can see that there''s',
             ' a distinction between the two ways of ');
     Writeln('calling interrupts...');
     set_pm_interrupt($21, oldint21h);
end.



Michael Van Canneyt
Thu Sep 10 13:59:33 CEST 1998