2
0
Эх сурвалжийг харах

Add two word variables to store fpu control and status register in interrupt 0x10

git-svn-id: trunk@36653 -
pierre 8 жил өмнө
parent
commit
963d109331

+ 20 - 0
rtl/msdos/prt0comn.asm

@@ -72,6 +72,9 @@
         extern __SaveInt10
         extern __SaveInt75
 
+        extern __fpu_status
+        extern __fpu_control
+
         extern FPC_HANDLE_I8086_ERROR
 
 %ifdef __TINY__
@@ -364,6 +367,23 @@ FPC_INT10_HANDLER:
         mov bp, DGROUP
 %endif
         mov ds, bp
+        ; Check that an unmasked exception is indeed set
+        ; First load FPU control register to __fpu_control
+        fnstcw word [__fpu_control]
+        ; Move control register value to bx register
+        mov bx,word [__fpu_control]
+        ; Now load status register to ax
+        fnstsw word [__fpu_status]
+        ; Only the exception part is useful, clear other parts
+        and bx,3fh
+        ; at least one same bit must also be set in bx
+        ; in that case with a bit set in status register
+        ; which means an exception has been generated by the FPU
+        ; and the exeception is not masked, as the same
+        ; bit is set in control register
+        mov ax,word [__fpu_status]
+        and ax,bx
+        je  .call_previous_handler10
 
 %ifdef __NEAR_DATA__
         ; in memory models, where SS=DS, also

+ 8 - 0
rtl/msdos/system.pp

@@ -8,6 +8,9 @@ interface
   but it uses default SysGetMem names }
 
 {$define HAS_MEMORYMANAGER}
+{ define TEST_FPU_INT10 to force keeping local int10,
+  for testing purpose only }
+
 
 {$DEFINE FPC_INCLUDE_SOFTWARE_MUL}
 {$DEFINE FPC_INCLUDE_SOFTWARE_MOD_DIV}
@@ -80,6 +83,9 @@ var
   SaveInt00: FarPointer;public name '__SaveInt00';
   SaveInt10: FarPointer;public name '__SaveInt10';
   SaveInt75: FarPointer;public name '__SaveInt75';
+  fpu_status: word;public name '__fpu_status';
+  fpu_control: word;public name '__fpu_control';
+
 
   AllFilesMask: string [3];
 {$ifndef RTLLITE}
@@ -245,6 +251,7 @@ Procedure SysInitFPU;
       { Special handler of interrupt $10
         not needed anymore
         Restore previous interrupt $10 handler }
+      {$ifndef TEST_FPU_INT10}
       if restore_old_int10 then
         asm
           push es
@@ -255,6 +262,7 @@ Procedure SysInitFPU;
           int $21
           pop es
         end;
+      {$endif ndef TEST_FPU_INT10}
   end;
 
 {$I system.inc}