Unit      Int_0405; Interface
{ ------------------------------------------------------------------------- }
{ Support module for units optimized by Sally Peephole Optimizer.           }
{ Copyright 1994 by Sally I/S.                                              }
{                                                                           }
{ Private individuals may distribute compiled versions of this unit as part }
{ of their own software provided that the copyright messages are left       }
{ intact.                                                                   }
{                                                                           }
{ Installs handlers for exceptions 04 and 05.  These are generated by the   }
{ IntO and Bound instructions.  As IBM used 05 for print screen despite its }
{ being reserved by Intel we check for the origin of the interrupt -- it's  }
{ fool proof but it's not damn fool proof.                                  }
{ ------------------------------------------------------------------------- }
{$R-,S-,I-,Q-,O-,F-,G-,A+}
{$IFNDEF MSDOS}
  {$C Fixed Preload Permanent} { Holds exception handlers }
{$ENDIF}

Implementation

Uses      {$IFDEF WINDOWS} Windos {$ENDIF}
          {$IFDEF OS2}     Windos {$ENDIF}
          {$IFDEF DPMI}    Dos    {$ENDIF}
          {$IFDEF MSDOS}   Dos    {$ENDIF};
{ ------------------------------------------------------------------------- }
Var       Halterror  : Pointer;
          SaveInt04  : Pointer;
          SaveInt05  : Pointer;
          SaveExit   : Pointer;
{ ------------------------------------------------------------------------- }
{$IFDEF MSDOS}
Procedure Real_Int04; Far; Assembler;
Asm
          Jmp    @@0
  @@1:    Db     0Eah
          Dd     0
  @@0:    Jno    @@1
          Push   Ax
          Mov    Ax,Ds
          Cmp    Ax,Seg @Data
          Pop    Ax
          Jne    @@1
          Mov    Ax,215
          Jmp    [Dword Ptr Halterror]
End;
{ ------------------------------------------------------------------------- }
Procedure Real_Int05; Far; Assembler;
Asm
          Jmp    @@0
  @@1:    Db     0Eah
          Dd     0
  @@0:    Push   Ax
          Mov    Ax,Ds
          Cmp    Ax,Seg @Data
          Pop    Ax
          Jne    @@1
          Push   Bp
          Mov    Bp,Sp
          Lds    Bp,[Bp+2]
          Cmp    [Word Ptr Ds:Bp],$622E          { Bound Ax,[Cs:....] }
          Je     @@5
          Cmp    [Word Ptr Ds:Bp],$2E66          { Op32, Cs: }
          Je     @@3
          Cmp    [Word Ptr Ds:Bp],$662E          { Cs:, Op32 }
          Jne    @@2
  @@3:    Cmp    [Word Ptr Ds:Bp+2],$0662        { Bound Eax,[....] }
          Jne    @@2
  @@5:    Mov    Bp,Seg @Data
          Mov    Ds,Bp
          Pop    Bp
          Mov    Ax,201
          Jmp    [Dword Ptr Halterror]
  @@2:    Mov    Bp,Seg @Data
          Mov    Ds,Bp
          Pop    Bp
          Jmp    @@1
End;
{$ENDIF MSDOS}
{ ------------------------------------------------------------------------- }
{$IFNDEF MSDOS}
Procedure Protected_Except04; Far; Assembler;
Asm       Push   Ax
          Mov    Ax,215
          Db     0Eah
          Dd     0
End;
{ ------------------------------------------------------------------------- }
Procedure Protected_Except05; Far; Assembler;
Asm       Push   Ax
          Mov    Ax,201
          Db     0Eah
          Dd     0
End;
{$ENDIF MSDOS}
{ ------------------------------------------------------------------------- }
Procedure NewExit; Far;
Begin
  ExitProc:=SaveExit;
  {$IFDEF MSDOS}
    SetIntVec($04,SaveInt04);
    SetIntVec($05,SaveInt05);
  {$ELSE}
    Asm    Mov   Ax,0203H
           Mov   Bl,04H
           Mov   Cx,[Word Ptr SaveInt04+2]
           Mov   Dx,[Word Ptr SaveInt04]
           Int   31H

           Mov   Ax,0203H
           Mov   Bl,05H
           Mov   Cx,[Word Ptr SaveInt05+2]
           Mov   Dx,[Word Ptr SaveInt05]
           Int   31H
    End;
  {$ENDIF}
End;
{ ------------------------------------------------------------------------- }
Procedure Install;
Var       Where     : Pointer;
          Copyright : String;
Begin
  Copyright:='Portions copyright 1993 by Sally I/S'#13#10;
  SaveExit:=ExitProc;
  ExitProc:=@NewExit;

  {$IFDEF MSDOS}
    GetIntVec($04,SaveInt04);          { Save state }
    GetIntVec($05,SaveInt05);
    SetIntVec($04,@Real_Int04);
    SetIntVec($05,@Real_Int05);

    Where:=@Real_Int04;                { Place handlers for easy access. }
    Inc(Word(Where),3);
    Pointer(Where^):=SaveInt04;
    Where:=@Real_Int05;
    Inc(Word(Where),3);
    Pointer(Where^):=SaveInt05;

    GetIntVec($00,Where);              { Dirty hack to find HaltError. }
    Inc(Word(Where),3);
    Halterror:=Where;
  {$ELSE}
    Asm    Mov   Ax,0202H
           Mov   Bl,04H
           Int   31H
           Mov   [Word Ptr SaveInt04],Dx
           Mov   [Word Ptr SaveInt04+2],Cx

           Mov   Ax,0202H
           Mov   Bl,05H
           Int   31H
           Mov   [Word Ptr SaveInt05],Dx
           Mov   [Word Ptr SaveInt05+2],Cx

           Mov   Ax,0203H
           Mov   Bl,04H
           Mov   Cx,Cs
           Mov   Dx,Offset Protected_Except04
           Int   31H

           Mov   Ax,0203H
           Mov   Bl,05H
           Mov   Cx,Cs
           Mov   Dx,Offset Protected_Except05
           Int   31H

           Mov   Ax,0202H              { Get and save exception entry }
           Mov   Bl,00H
           Int   31H
           Add   Dx,4
           Mov   Ax,Cs
           Add   Ax,[Selectorinc]
           Mov   Es,Ax
           Mov   [Word Ptr Es:Protected_Except04+5],Dx
           Mov   [Word Ptr Es:Protected_Except04+7],Cx
           Mov   [Word Ptr Es:Protected_Except05+5],Dx
           Mov   [Word Ptr Es:Protected_Except05+7],Cx
    End;
  {$ENDIF}
End;
{ ------------------------------------------------------------------------- }
Procedure Zeroextend_Registers;
Const     Op32 = $66;
Begin
  { This zero extends the registers Esp and Ebp for 386/486 processors
    I don't really know if this is needed, but it won't hurt. }
  If Test8086>=2 Then
    Asm    Db Op32 ; And Sp,$FFFF ; Dw 0
           Db Op32 ; And Bp,$FFFF ; Dw 0
    End;
End;
{ ------------------------------------------------------------------------- }
Begin
  Zeroextend_Registers;
  Install;
End.
