Floating-point exception in pascal
Posted: Sun Aug 19, 2007 3:15 am
Greetings,
after these tiny problems there grew a big one:
I'm trying to use FPU inside free pascal. I didn't make my own functions because I can use the functions from go32v2 extender. And here's the catch:
This function works fine, but if that function has been called many times (10 or such), Bochs will start to panic:
01236716631i[CPU0 ] math_abort: MSDOS compatibility FPU exception
And this is right in the instrunction "fwait", right before the fldcw. And after fwait, every floating point instruction will fail and Bochs will generate very big log with all this. I wonder why this isn't called right on the first FPU instruction, always it would start after some calls (program is computing circles to draw a color spiral on the screen).
That program worked fine in DOS though...
After PortixOS would boot in protected mode, I initalize the FPU with this:
This wouldn't generate a exception. That CLI and STI in the code are only for debugging, I thought that i need to disable IRQs or something (I read that Bochs will fire IRQ 13 when this exception arise).
This seems a harder nut to crack... Should I after every calls of round(); call finit?
Thanks for help.
//EDIT: The "MSDOS compatibility exception" will arise only in the second fwait, fld, fist and the last fldcw (the 2nd part of my code). Other code that works with FPU doesn't generate this exception, for example
Regards
inflater
after these tiny problems there grew a big one:
I'm trying to use FPU inside free pascal. I didn't make my own functions because I can use the functions from go32v2 extender. And here's the catch:
Code: Select all
{$ASMMODE intel}
function round(d : extended) : longint;assembler;[internconst:in_const_round];
var
oldcw,
newcw : word;
res : longint;
asm
cli
fnstcw oldcw
fwait
mov newcw,1372h
@@blah1:
cmp cx,3
jne @@blah1
fldcw newcw
fwait
fld d
fist res
mov eax,res
fldcw oldcw
sti
end ['EAX'];
{$ASMMODE ATT}
01236716631i[CPU0 ] math_abort: MSDOS compatibility FPU exception
And this is right in the instrunction "fwait", right before the fldcw. And after fwait, every floating point instruction will fail and Bochs will generate very big log with all this. I wonder why this isn't called right on the first FPU instruction, always it would start after some calls (program is computing circles to draw a color spiral on the screen).
That program worked fine in DOS though...
After PortixOS would boot in protected mode, I initalize the FPU with this:
Code: Select all
feni
fclex
fwait
finit
fstcw word[TempW]
mov ax,TempW
and ax,3FFh
mov [TempW],ax
fldcw word[TempW]
ret
TempW dw 0
This seems a harder nut to crack... Should I after every calls of round(); call finit?
Thanks for help.
//EDIT: The "MSDOS compatibility exception" will arise only in the second fwait, fld, fist and the last fldcw (the 2nd part of my code). Other code that works with FPU doesn't generate this exception, for example
when counting cosine of Phase1 and dividing it by 1.2, it wont generate this exception:y := MidY + round(Phase2*cos(Phase1)/1.2);
- this works fine.(disassembly)
fcos
fld qword ptr ss:[ebp+0xffffffe8]
fld qword ptr ss:[ebp+0xfffffff0]
fmulp st(1), st(0)
fld tbyte ptr ds:0x401b59
fdivp st(1), st(0)
Regards
inflater