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