diff --git a/rtl/msdos/prt0comn.asm b/rtl/msdos/prt0comn.asm index a44e27d4f4..0b035ae9f9 100644 --- a/rtl/msdos/prt0comn.asm +++ b/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 diff --git a/rtl/msdos/system.pp b/rtl/msdos/system.pp index c82bed64e5..f6e12eb3c1 100644 --- a/rtl/msdos/system.pp +++ b/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}