Reply 1720 of 2419, by hail-to-the-ryzen
Attached.
Attached.
Also, ignore my previous report about a full core in dosbox (actually tested normal versus dynamic cores only).
I just incorporated and adapted fpu_instructions_x86.h from SVN into DOSBox-X and the code from configure.ac to enable it.
It seems to fix the glitches.
So as far as I can tell there's something Explora does with the FPU that requires the full 80-bit precision to render it's graphics correctly.
I think the best course of action is to change DOSBox-X's non-x86 FPU emulation to use "long double" which will enable the full 80-bit precision on everything except Microsoft Visual C++ (which can use fpu_instruction_x86.h anyway now).
I do know from previous programming experiments that "long double" is the full 80-bit IEEE format when compiled with GCC on x86, x86_64, arm7 (Raspberry Pi) and an old PowerPC powerbook I loaded YDL Linux on. Any noncompliant targets can be set up to error out at compile time if long double is not longer than double.
fpu_instructions_x86.h does not work in VS2015 when targeting x86_64 because VS2015 does not allow inline __asm when targeting 64-bit Windows.
Is there something that SVN has to work around that or does 64-bit SVN have the same limitation?
Probably the VS would reduce backward compatibility, so the gcc systems may be preferred.
Thank you for the commits!
Edit: I see now. They must not target x64 for the VS path. I read that generally the code would have to be changed.
The problem may not be related to just the difference in precision, fpu_instructions.h is a very minimal x87 implementation that doesn't always take FP exceptions when it should or set flags correctly for many instructions. Using "long double" won't fix that.
Intel made a utility to test for correct x87 operation: https://winworldpc.com/product/386sx-math-coprocess/10
Dosbox fails every test unless using fpu_instructions_x86.h, which is obviously limited to (32-bit) x86 only as it uses real x87 instructions.
wrote:The problem may not be related to just the difference in precision, fpu_instructions.h is a very minimal x87 implementation that doesn't always take FP exceptions when it should or set flags correctly for many instructions. Using "long double" won't fix that.
Intel made a utility to test for correct x87 operation: https://winworldpc.com/product/386sx-math-coprocess/10
Dosbox fails every test unless using fpu_instructions_x86.h, which is obviously limited to (32-bit) x86 only as it uses real x87 instructions.
That's a good find, I actually have an old 386SX system I acquired some time ago where someone had installed the i387 in it, I should try that utility on it.
pcem shows same issue so both the svn and pcem code would likely have to have the same missing emulation. However, pcem does not have the full long double handling.
Both the x86 and the non-x86 fpu code defaults to double precision in DOSBox/-X. One possibility is the EXPLORA demo resets the fpu to long double precision.
First, confirmed that the working x86 fpu emulation, with core=normal, does not have the rendering artifacts at beginning of the demo. Then disabled any change from double precision in the x86 fpu emulation which then led to the artifacts:
diff -rupN dosbox-Orig//src/fpu/fpu.cpp dosbox/src/fpu/fpu.cpp
--- dosbox-Orig//src/fpu/fpu.cpp
+++ dosbox/src/fpu/fpu.cpp
@@ -32,7 +32,7 @@ FPU_rec fpu;
void FPU_FLDCW(PhysPt addr){
Bit16u temp = mem_readw(addr);
- FPU_SetCW(temp);
+ // FPU_SetCW(temp);
}
Bit16u FPU_GetTag(void){
diff -rupN dosbox-Orig//src/fpu/fpu_instructions_x86.h dosbox/src/fpu/fpu_instructions_x86.h
--- dosbox-Orig//src/fpu/fpu_instructions_x86.h
+++ dosbox/src/fpu/fpu_instructions_x86.h
@@ -1251,7 +1251,7 @@ static void FPU_FLDENV(PhysPt addr){
tag = static_cast<Bit16u>(tagbig);
}
FPU_SetTag(tag);
- FPU_SetCW(cw);
+ // FPU_SetCW(cw);
TOP=FPU_GET_TOP();
}
So then the non-x86 core might be able to make the demo happy on Linux systems at least if I can change it to use long double and use the right GCC macros to make sure extended precision is enabled.
https://code.woboq.org/userspace/glibc/sysdep … _control.h.html
That is a good plan. It may work to only adapt a small set of fpu instructions for long double precision. Testing with the x86 fpu code shows the rendering artifacts are reproduced by reduced precision in the following two functions (tested against the beginning of the Explora demo):
diff -rupN dosbox-Orig//src/fpu/fpu_instructions_x86.h dosbox//src/fpu/fpu_instructions_x86.h
--- dosbox-Orig//src/fpu/fpu_instructions_x86.h
+++ dosbox//src/fpu/fpu_instructions_x86.h
@@ -1121,11 +1121,15 @@ static void FPU_FDIVR_EA(Bitu op1){
}
static void FPU_FMUL(Bitu op1, Bitu op2){
+ FPU_SetCW(0x37F);
FPUD_ARITH1(fmulp)
+ FPU_SetCW(0x3FF);
}
static void FPU_FMUL_EA(Bitu op1){
+ FPU_SetCW(0x37F);
FPUD_ARITH1_EA(fmulp)
+ FPU_SetCW(0x3FF);
}
static void FPU_FSUB(Bitu op1, Bitu op2){
I just made an alternate fpu_instructions_longdouble.h which uses long double instead of double.
It doesn't seem to resolve the artifacts yet, but perhaps focusing on those two functions might help.
However "Toontown" is able to display properly without the need for the "use80" hack in the original fpu_instructions.h (FPU Pentium memcpy trick, remember?)
That is good news. It sounds like you have the issue almost resolved. 😀
wrote:That is good news. It sounds like you have the issue almost resolved. 😀
Maybe. I'm testing the new long double FPU code against DOS games like Heretic, Quake, Duke Nukem 3D, etc. anything known to use the FPU to see if the changes broke anything obvious.
I'll test, too.
wrote:I'll test, too.
Help is appreciated. Make sure C_FPU_X86 is not set and that HAS_LONG_DOUBLE is defined from include/dosbox.h. Do not test with Microsoft C++, long double doesn't work there.
Will do. Nonuse of MS C++ is a bonus.
Looks like Quake is the latest casualty in the DOSBox-X problem of too many VESA BIOS modes, but only if you try to change video mode. 😀
Use the 'vesa modelist cap' option if Quake crashes when you try to set a SVGA mode.