From b5b7f29255ab0ac8a028d0d472a866047e24f312 Mon Sep 17 00:00:00 2001 From: Kellan Clark Date: Sun, 23 Oct 2022 20:22:21 -0400 Subject: [PATCH] Fix division edge cases and prevent crash --- desmume/src/MMU.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 94ff543ff..5295a3ce8 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -1068,7 +1068,6 @@ static void execsqrt() { } static void execdiv() { - s64 num,den; s64 res,mod; u8 mode = MMU_new.div.mode; @@ -1096,15 +1095,29 @@ static void execdiv() { break; } - if(den==0) + if(den == 0) { res = ((num < 0) ? 1 : -1); mod = num; + + // when the result is 32bits, the upper 32bits of the sign-extended result are inverted + if (mode == 0) + res ^= 0xFFFFFFFF00000000; // the DIV0 flag in DIVCNT is set only if the full 64bit DIV_DENOM value is zero, even in 32bit mode if ((u64)T1ReadQuad(MMU.ARM9_REG, 0x298) == 0) MMU_new.div.div0 = 1; } + else if((mode != 0) && (num == 0x8000000000000000) && (den == -1)) + { + res = 0x8000000000000000; + mod = 0; + } + else if((mode == 0) && (num == (s64) (s32) 0x80000000) && (den == -1)) + { + res = 0x80000000; + mod = 0; + } else { res = num / den;