Viewing Issue Advanced Details
ID Category [?] Severity [?] Reproducibility Date Submitted Last Update
09574 Crash/Freeze Critical (emulation) Random 5 days ago 6 hours ago
Tester yoshi200213 View Status Public Platform MAME (Unofficial Binary)
Assigned To Resolution Open OS Windows (x64)
Status [?] Confirmed Driver
Version 0.289 Fixed in Version Build x64
Fixed in Git Commit Github Pull Request #
Summary 09574: crazywar: the emulated game may freeze during gameplay
Description The game can freeze during gameplay when using the Hyperstone E1 recompiler with condition code elision enabled (the default configuration).
Steps To Reproduce
Additional Information
Github Commit
Flags
Regression Version
Affected Sets / Systems crazywar
Attached Files
? file icon tst1.inp (17,788 bytes) 1 day ago Uploaded by cuavas
Input recording that eventually triggers the bug.
Relationships
There are no relationship linked to this issue.
Notes
7
User avatar
No.24771
Robbbert
Moderator
4 days ago
edited on: 4 days ago
Only seems to happen when cheating.

If you were cheating then this report is invalid.
User avatar
No.24774
yoshi200213
Tester
4 days ago
But also happens without cheating
User avatar
No.24775
yoshi200213
Tester
4 days ago
I don't enable cheats for this game
User avatar
No.24779
cuavas
Administrator
1 day ago
It’s reproducible with an input recording. It only happens with the recompiler, and only if DO_ELIDE_CONDITION_CALC is set to 1 in src/devices/cpu/e132xs/e132xsdrc.cpp (the default).

Possible causes include:
* A bug in src/devices/cpu/e132xs/e1fe.cpp where it doesn’t set the condition codes produced or consumed by an instruction properly.
* A bug in src/devices/cpu/e132xs/e132xsdrc_ops.hxx where it doesn’t update all required condition codes.
* A bug in src/devices/cpu/drcfe.ipp where the register dependencies are calculated incorrectly.

Tracing it is difficult as there are apparently other non-deterministic things in the system meaning different runs produce slightly different results with the same input recording. Even setting a breakpoint and single-stepping can give different results to using run to next VBLANK.
User avatar
No.24780
Haze
Senior Tester
13 hours ago
it's reproducible even just left in attract
User avatar
No.24781
Haze
Senior Tester
12 hours ago
(I also checked if it was the speed-up, or related, but it isn't, although it happens earlier if you remove the speed-up)
User avatar
No.24782
cuavas
Administrator
6 hours ago
It’s easier to trace with the speedup hack disabled – that seems to get rid of most of the non-determinism.

It’s being triggered when a CPU timeslice ends after executing a delayed branch instruction where the branch will be taken before the instruction in the delay slot is executed. On the next timeslice, it runs a block starting with the instruction in the delay slot, and dynamically checks whether a delayed branch is pending. In this situation, static dependency analysis can’t account for the possible branch, so it doesn’t update condition codes that the next conditional branch depends on.

21fed0a0ecff0f462a1669e00b3e0cc7ab31cbe4 makes it always calculate all condition codes when it will dynamically check for a pending delayed branch. It fixes the easily reproducible cases of this bug at least.

The other recompilers for CPUs with delay slots (e.g. MIPS) don’t support returning to the scheduler between a delayed branch and the instruction in the delay slot and/or don’t attempt to elide unnecessary calculations, so they don’t suffer from the issue.

I think there are bugs in the dependency calculations in src/devices/cpu/drcfe.ipp, though. Consider this:

00035B38 t:FFFFFFFF f:..B...eRV.: LDW.D G04, L7, $fffffff4 [use:G4,FP]
00035B3C t:FFFFFFFF f:..........: MOVI L8, $a [use:FP] [mod:Z*,N*,V*]
00035B3E t:FFFFFFFF f:..........: MOV L6, L7 [use:FP] [mod:Z,N,V]
00035B40 t:00035B46 f:Ci........: DBNN $35b46 [use:N]
00035B42 t:FFFFFFFF f:...D......: SUB L5, L5 [use:FP] [mod:C*,Z*,N*,V*]
00035B42 t:FFFFFFFF f:..........: SUB L5, L5 [use:FP] [mod:C*,Z*,N*,V*]
00035B44 t:FFFFFFFF f:..........: NEG L6, L6 [use:FP] [mod:C,Z,N,V]
-----
00035B46 t:FFFFFFFF f:..B...e.V.: DIVS L5, L8 [use:FP] [mod:Z,N,V]
00035B48 t:00035B4E f:Ci........: DBNC $35b4e [use:C]
00035B4A t:FFFFFFFF f:...D......: MOV L7, L6 [use:FP] [mod:Z*,N*,V*]
00035B4A t:FFFFFFFF f:..........: MOV L7, L6 [use:FP] [mod:Z*,N*,V*]
00035B4C t:FFFFFFFF f:..........: NEG L7, L7 [use:FP] [mod:C,Z,N,V]

The DBNC at 00035B48 will depend on the C flag from the SUB L5, L5 in the delay slot of the DBNN $35b46 instruction at 00035B40 if the branch is taken, but it seems to think it doesn’t need to be calculated.