Bug #33
Quake 2 demo doesn't work with 32-bit build and new file systems
0%
Description
The old file systems work for the 32-bit Windows build when running the quake 2 time demo. But with the new file system it crashes while loading the map. My guess would be that since the new file system compiled Wine with SSE/SSE2 support that there might be a bug in the normal core with SSE/SSE2
Files
Associated revisions
#33 Fixed another FPU bug, this time with FXRSTOR. Now Quake 2 with the normal core is working.
#33 Fixed some FPU logging issues.
#33 Fixed an experimental x64 binary translator issue if the FPU was emulated.
History
Updated by James Bryant 9 months ago
Error from Quake 2 on Wine 5 is
wine: Unhandled exception 0xc000008f in thread 9 at address 7B031D2E (thread 0009), starting debugger...
0xc000008f is inexact floating point
7B031D2E is Kernalbase.RaiseException
with WINEDEBUG=+seh,+msvcrt
0009:trace:msvcrt:math_error (3, "pow", 1, 0, 11025)
0009:trace:msvcrt:math_error (3, "pow", 1, 0, 11025)
002a:trace:msvcrt:DllMain (0xd0b60000, DLL_THREAD_ATTACH, (nil)) pid(8), tid(2a), tls(1)
002a:trace:msvcrt:DllMain (0xd14f0000, DLL_THREAD_ATTACH, (nil)) pid(8), tid(2a), tls(5)
Creating Window for OpenGL: 800x600
0009:trace:seh:raise_exception code=c000008f flags=0 addr=0x7b031d2e ip=7b031d2e tid=0009
0009:trace:seh:raise_exception info0=0032f7f4
0009:trace:seh:raise_exception eax=0032f740 ebx=00000001 ecx=00000000 edx=0032f868 esi=0032f868 edi=0032f860
0009:trace:seh:raise_exception ebp=0032f798 esp=0032f734 cs=000f ds=0017 es=d0200017 fs=0053 gs=32005b flags=00000212
0009:trace:seh:call_stack_handlers calling handler at 0x440b28 code=c000008f flags=0
0009:trace:msvcrt:math_error (3, "pow", 1, 0, 11025)
3 = _OVERFLOW
double CDECL MSVCRT_pow( double x, double y ) { double z = pow(x,y); if (x < 0 && y != floor(y)) math_error(_DOMAIN, "pow", x, y, z); else if (!x && isfinite(y) && y < 0) math_error(_SING, "pow", x, y, z); else if (isfinite(x) && isfinite(y) && !isfinite(z)) math_error(_OVERFLOW, "pow", x, y, z); else if (x && isfinite(x) && isfinite(y) && !z) math_error(_UNDERFLOW, "pow", x, y, z); return z; }
Updated by James Bryant 9 months ago
Seems to crash in the statically linked function, float(9.75)
This is caused by the mask precision exception being turned off in the control word. If I hard code this mask in the emulator then Quake 2 works.
mov eax, dword_10028D70
sub esp, 8
push ebx
push esi
push edi
push 0FFFFh
push eax
call __ctrlfp
mov ecx, dword ptr [esp+1Ch+arg_0+6]
mov esi, dword ptr [esp+1Ch+arg_0+4]
mov edi, dword ptr [esp+1Ch+arg_0]
add esp, 8
and ecx, 7FF0h
mov ebx, eax
cmp ecx, 7FF0h
push esi
push edi ; double
jnz short loc_10015900
loc_10015900:
call __frnd
fstp [esp+1Ch+var_8]
fld [esp+1Ch+var_8]
fcomp [esp+1Ch+arg_0]
add esp, 8
fnstsw ax
test ah, 40h
jnz short loc_10015920
test bl, 20h
jz short loc_10015939
loc_10015939:
mov edx, dword ptr [esp+14h+var_8+4]
mov eax, dword ptr [esp+14h+var_8]
push ebx ; int
push edx
push eax ; double
push esi ; int
push edi ; int
push 0Bh ; int
push 10h ; char
call __except1
FPU log
// floor
// ctrlfp
Unknown 10019695 FNSTCW 0000 @0032F858
Unknown 100196AE FLDCW @0032F868
SetCW 173F (Down)
// end ctrlfp
// frnd
Unknown 10018BC6 FLD F64 9.750000 4023800000000000@0032F864
Valid 9.750000 0 7
Unknown 10018BC9 FRNDINT
Valid 9.000000 0 7
Unknown 10018BCB FSTP F64 9.000000 @0032F854
Unknown 10018BCE FLD F64 9.000000 4022000000000000@0032F854
Valid 9.000000 0 7
// end frnd
Unknown 10015905 FSTP F64 9.000000 @0032F878
Unknown 10015909 FLD F64 9.000000 4022000000000000@0032F878
Valid 9.000000 0 7
Unknown 1001590D FCOMP 9.750000 9.000000
Unknown 10015914 FNSTSW SW=100
Updated by James Bryant 9 months ago
The 2nd bug for Quake 2 was from fxrstor not properly setting the control and status words.
#33 FCOMI ST instruction mistakenly popped the FPU stack. This caused bogus results when using the FPU. I also improved FPU logging. This seems to fix one issue with Quake 2, but soon after this code runs another exception happens.