diff --git a/MBBSEmu.Tests/CPU/FCOMPP_Tests.cs b/MBBSEmu.Tests/CPU/FCOMPP_Tests.cs index 4b769329..746f5e73 100644 --- a/MBBSEmu.Tests/CPU/FCOMPP_Tests.cs +++ b/MBBSEmu.Tests/CPU/FCOMPP_Tests.cs @@ -15,6 +15,8 @@ public class FCOMPP_Tests : CpuTestBase [InlineData(1d, 1d, (ushort)EnumFpuStatusFlags.Code3)] [InlineData(double.NaN, 0d, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] [InlineData(0d, double.NaN, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(double.PositiveInfinity, 0d, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(0d, double.NegativeInfinity, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] public void FCOMPP_Test(double ST0Value, double ST1Value, ushort expectedFlags) { Reset(); diff --git a/MBBSEmu.Tests/CPU/FCOM_Tests.cs b/MBBSEmu.Tests/CPU/FCOM_Tests.cs index 3676cb4c..2cbe02c0 100644 --- a/MBBSEmu.Tests/CPU/FCOM_Tests.cs +++ b/MBBSEmu.Tests/CPU/FCOM_Tests.cs @@ -16,7 +16,10 @@ public class FCOM_Tests : CpuTestBase [InlineData(double.MinValue, 0d, (ushort)EnumFpuStatusFlags.Code0)] [InlineData(1d, 1d, (ushort)EnumFpuStatusFlags.Code3)] [InlineData(double.NaN, 0d, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(double.NegativeInfinity, 0d, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] [InlineData(0d, double.NaN, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(0d, double.PositiveInfinity, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(double.NegativeInfinity, double.PositiveInfinity, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] public void FCOM_ST1_Test(double ST0Value, double ST1Value, ushort expectedFlags) { Reset(); @@ -42,7 +45,10 @@ public void FCOM_ST1_Test(double ST0Value, double ST1Value, ushort expectedFlags [InlineData(float.MinValue, 0d, (ushort)EnumFpuStatusFlags.Code0)] [InlineData(1d, 1d, (ushort)EnumFpuStatusFlags.Code3)] [InlineData(float.NaN, 0d, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(float.NegativeInfinity, 0d, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] [InlineData(0d, float.NaN, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(0d, float.PositiveInfinity, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(float.NegativeInfinity, float.PositiveInfinity, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] public void FCOM_M32_Test(double ST0Value, float m32Value, ushort expectedFlags) { Reset(); @@ -70,7 +76,10 @@ public void FCOM_M32_Test(double ST0Value, float m32Value, ushort expectedFlags) [InlineData(double.MinValue, 0d, (ushort)EnumFpuStatusFlags.Code0)] [InlineData(1d, 1d, (ushort)EnumFpuStatusFlags.Code3)] [InlineData(double.NaN, 0d, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(double.NegativeInfinity, 0d, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] [InlineData(0d, double.NaN, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(0d, double.PositiveInfinity, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] + [InlineData(double.NegativeInfinity, double.PositiveInfinity, (ushort)(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3))] public void FCOM_M64_Test(double ST0Value, double m32Value, ushort expectedFlags) { Reset(); diff --git a/MBBSEmu.Tests/CPU/FILD_Tests.cs b/MBBSEmu.Tests/CPU/FILD_Tests.cs index 13069106..fac6f513 100644 --- a/MBBSEmu.Tests/CPU/FILD_Tests.cs +++ b/MBBSEmu.Tests/CPU/FILD_Tests.cs @@ -9,9 +9,9 @@ public class FILD_Tests : CpuTestBase { [Theory] [InlineData(0)] - [InlineData(ushort.MaxValue)] - [InlineData(ushort.MinValue)] - public void FILD_Test_M16(ushort valueToLoad) + [InlineData(short.MaxValue)] + [InlineData(short.MinValue)] + public void FILD_Test_M16(short valueToLoad) { Reset(); @@ -30,8 +30,8 @@ public void FILD_Test_M16(ushort valueToLoad) [Theory] [InlineData(1, 2)] - [InlineData(ushort.MaxValue, ushort.MinValue)] - public void FILD_Multiple_Test_M16(ushort st0, ushort st1) + [InlineData(short.MaxValue, short.MinValue)] + public void FILD_Multiple_Test_M16(short st0, short st1) { Reset(); @@ -54,9 +54,9 @@ public void FILD_Multiple_Test_M16(ushort st0, ushort st1) [Theory] [InlineData(0)] - [InlineData(uint.MaxValue)] - [InlineData(uint.MinValue)] - public void FILD_Test_M32(uint valueToLoad) + [InlineData(int.MaxValue)] + [InlineData(int.MinValue)] + public void FILD_Test_M32(int valueToLoad) { Reset(); @@ -75,8 +75,8 @@ public void FILD_Test_M32(uint valueToLoad) [Theory] [InlineData(1, 2)] - [InlineData(uint.MaxValue, uint.MinValue)] - public void FILD_Multiple_Test_M32(uint st0, uint st1) + [InlineData(int.MaxValue, int.MinValue)] + public void FILD_Multiple_Test_M32(int st0, int st1) { Reset(); @@ -99,9 +99,9 @@ public void FILD_Multiple_Test_M32(uint st0, uint st1) [Theory] [InlineData(0)] - [InlineData(ulong.MaxValue)] - [InlineData(ulong.MinValue)] - public void FILD_Test_M64(ulong valueToLoad) + [InlineData(long.MaxValue)] + [InlineData(long.MinValue)] + public void FILD_Test_M64(long valueToLoad) { Reset(); @@ -120,8 +120,8 @@ public void FILD_Test_M64(ulong valueToLoad) [Theory] [InlineData(1, 2)] - [InlineData(ulong.MaxValue, ulong.MinValue)] - public void FILD_Multiple_Test_M64(ulong st0, ulong st1) + [InlineData(long.MaxValue, long.MinValue)] + public void FILD_Multiple_Test_M64(long st0, long st1) { Reset(); diff --git a/MBBSEmu.Tests/CPU/RLC_Tests.cs b/MBBSEmu.Tests/CPU/RCL_Tests.cs similarity index 50% rename from MBBSEmu.Tests/CPU/RLC_Tests.cs rename to MBBSEmu.Tests/CPU/RCL_Tests.cs index 5eab86e8..fbd5520d 100644 --- a/MBBSEmu.Tests/CPU/RLC_Tests.cs +++ b/MBBSEmu.Tests/CPU/RCL_Tests.cs @@ -7,13 +7,13 @@ namespace MBBSEmu.Tests.CPU public class RCL_Tests : CpuTestBase { [Theory] - [InlineData(0x8000, 1, false, 0x0000, true)] // Rotate left with carry in, resulting in CF set - [InlineData(0x8000, 1, true, 0x0001, true)] // Rotate left with carry in, resulting in CF set, and LSB set from previous CF - [InlineData(0x0001, 1, false, 0x0002, false)] // Simple rotate left - [InlineData(0x0000, 1, true, 0x0001, false)] // Rotate with carry flag set, no bit set in value - [InlineData(0xFFFF, 4, false, 0xFFF7, true)] // Rotate left multiple times + [InlineData(0x8000, 1, false, 0x0000, true, true)] // Rotate left with carry in, resulting in CF set + [InlineData(0x8000, 1, true, 0x0001, true, true)] // Rotate left with carry in, resulting in CF set, and LSB set from previous CF + [InlineData(0x0001, 1, false, 0x0002, false, false)] // Simple rotate left + [InlineData(0x0000, 1, true, 0x0001, false, false)] // Rotate with carry flag set, no bit set in value + [InlineData(0xFFFF, 4, false, 0xFFF7, true, false)] // Rotate left multiple times public void Op_Rcl_16_Test(ushort axValue, byte bitsToRotate, bool initialCarryFlag, ushort expectedResult, - bool expectedCarryFlag) + bool expectedCarryFlag, bool expectedOverflowFlag) { Reset(); mbbsEmuCpuRegisters.AX = axValue; @@ -27,16 +27,17 @@ public void Op_Rcl_16_Test(ushort axValue, byte bitsToRotate, bool initialCarryF Assert.Equal(expectedResult, mbbsEmuCpuRegisters.AX); Assert.Equal(expectedCarryFlag, mbbsEmuCpuRegisters.CarryFlag); + Assert.Equal(expectedOverflowFlag, mbbsEmuCpuRegisters.OverflowFlag); } [Theory] - [InlineData(0x80, 1, false, 0x00, true)] // Rotate left with carry in, resulting in CF set - [InlineData(0x80, 1, true, 0x01, true)] // Rotate left with carry in, resulting in CF set, and LSB set from previous CF - [InlineData(0x01, 1, false, 0x02, false)] // Simple rotate left - [InlineData(0x00, 1, true, 0x01, false)] // Rotate with carry flag set, no bit set in value - [InlineData(0xFF, 4, false, 0xF7, true)] // Rotate left multiple times + [InlineData(0x80, 1, false, 0x00, true, true)] // Rotate left with carry in, resulting in CF set + [InlineData(0x80, 1, true, 0x01, true, true)] // Rotate left with carry in, resulting in CF set, and LSB set from previous CF + [InlineData(0x01, 1, false, 0x02, false, false)] // Simple rotate left + [InlineData(0x00, 1, true, 0x01, false, false)] // Rotate with carry flag set, no bit set in value + [InlineData(0xFF, 4, false, 0xF7, true, false)] // Rotate left multiple times public void Op_Rcl_8_Test(byte alValue, byte bitsToRotate, bool initialCarryFlag, ushort expectedResult, - bool expectedCarryFlag) + bool expectedCarryFlag, bool expectedOverflowFlag) { Reset(); mbbsEmuCpuRegisters.AL = alValue; @@ -50,6 +51,7 @@ public void Op_Rcl_8_Test(byte alValue, byte bitsToRotate, bool initialCarryFlag Assert.Equal(expectedResult, mbbsEmuCpuRegisters.AL); Assert.Equal(expectedCarryFlag, mbbsEmuCpuRegisters.CarryFlag); + Assert.Equal(expectedOverflowFlag, mbbsEmuCpuRegisters.OverflowFlag); } } diff --git a/MBBSEmu.Tests/CPU/RCR_Tests.cs b/MBBSEmu.Tests/CPU/RCR_Tests.cs index 073ac653..42841c15 100644 --- a/MBBSEmu.Tests/CPU/RCR_Tests.cs +++ b/MBBSEmu.Tests/CPU/RCR_Tests.cs @@ -5,18 +5,20 @@ namespace MBBSEmu.Tests.CPU { - public class RCR_Tests : CpuTestBase + public class RCR_Tests : CpuTestBase { [Theory] - [InlineData(0xF, 1, 0x7, true)] - [InlineData(0xE, 1, 0x7, false)] - [InlineData(0x1FF, 1, 0xFF, true)] - [InlineData(0x1FE, 1, 0xFF, false)] - [InlineData(0x3C, 2, 0xF, false)] - [InlineData(0x3E, 2, 0xF, true)] - [InlineData(0xFFFF, 2, 0xBFFF, true)] + [InlineData(0xF, 1, 0x7, true, false)] + [InlineData(0xE, 1, 0x7, false, false)] + [InlineData(0x6, 1, 0x3, false, false)] + [InlineData(0x1FF, 1, 0xFF, true, false)] + [InlineData(0x1FE, 1, 0xFF, false, false)] + [InlineData(0x3C, 2, 0xF, false, false)] + [InlineData(0x3E, 2, 0xF, true, false)] + [InlineData(0xFFFF, 1, 0x7FFF, true, true)] + [InlineData(0xFFFF, 2, 0xBFFF, true, false)] public void RCR_AX_IMM16_CF_CLEAR(ushort axValue, byte bitsToRotate, ushort expectedValue, - bool expectedCFValue) + bool expectedCFValue, bool expectedOFValue) { Reset(); mbbsEmuCpuRegisters.AX = axValue; @@ -29,17 +31,20 @@ public void RCR_AX_IMM16_CF_CLEAR(ushort axValue, byte bitsToRotate, ushort expe Assert.Equal(expectedValue, mbbsEmuCpuRegisters.AX); Assert.Equal(expectedCFValue, mbbsEmuCpuRegisters.CarryFlag); + Assert.Equal(expectedOFValue, mbbsEmuCpuRegisters.OverflowFlag); } [Theory] - [InlineData(0xF, 1, 0x8007, true)] - [InlineData(0xE, 1, 0x8007, false)] - [InlineData(0x1FF, 1, 0x80FF, true)] - [InlineData(0x1FE, 1, 0x80FF, false)] - [InlineData(0x3C, 2, 0x400F, false)] - [InlineData(0x3E, 2, 0x400F, true)] - [InlineData(0xFFFF, 2, 0xFFFF, true)] - public void RCR_AX_IMM16_CF_SET(ushort axValue, byte bitsToRotate, ushort expectedValue, bool expectedCFValue) + [InlineData(0xF, 1, 0x8007, true, true)] + [InlineData(0xF, 2, 0xC003, true, false)] + [InlineData(0xE, 1, 0x8007, false, true)] + [InlineData(0x1FF, 1, 0x80FF, true, true)] + [InlineData(0x1FE, 1, 0x80FF, false, true)] + [InlineData(0x3C, 2, 0x400F, false, false)] + [InlineData(0x3E, 2, 0x400F, true, false)] + [InlineData(0xFFFF, 2, 0xFFFF, true, false)] + [InlineData(0xFFFF, 1, 0xFFFF, true, false)] + public void RCR_AX_IMM16_CF_SET(ushort axValue, byte bitsToRotate, ushort expectedValue, bool expectedCFValue, bool expectedOFValue) { Reset(); mbbsEmuCpuRegisters.AX = axValue; @@ -53,12 +58,16 @@ public void RCR_AX_IMM16_CF_SET(ushort axValue, byte bitsToRotate, ushort expect Assert.Equal(expectedValue, mbbsEmuCpuRegisters.AX); Assert.Equal(expectedCFValue, mbbsEmuCpuRegisters.CarryFlag); + Assert.Equal(expectedOFValue, mbbsEmuCpuRegisters.OverflowFlag); } [Theory] - [InlineData(0xF, 1, 0x7, true)] - [InlineData(0xE, 1, 0x7, false)] - public void RCR_AH_IMM8_CF_CLEAR(byte ahValue, byte bitsToRotate, byte expectedValue, bool expectedCFValue) + [InlineData(0xF, 1, 0x7, true, false)] + [InlineData(0xFF, 1, 0x7F, true, true)] + [InlineData(0xFF, 2, 0xBF, true, false)] + [InlineData(0x0, 1, 0x0, false, false)] + [InlineData(0xE, 1, 0x7, false, false)] + public void RCR_AH_IMM8_CF_CLEAR(byte ahValue, byte bitsToRotate, byte expectedValue, bool expectedCFValue, bool expectedOFValue) { Reset(); mbbsEmuCpuRegisters.AH = ahValue; @@ -71,12 +80,16 @@ public void RCR_AH_IMM8_CF_CLEAR(byte ahValue, byte bitsToRotate, byte expectedV Assert.Equal(expectedValue, mbbsEmuCpuRegisters.AH); Assert.Equal(expectedCFValue, mbbsEmuCpuRegisters.CarryFlag); + Assert.Equal(expectedOFValue, mbbsEmuCpuRegisters.OverflowFlag); } [Theory] - [InlineData(0xF, 1, 0x87, true)] - [InlineData(0xE, 1, 0x87, false)] - public void RCR_AH_IMM8_CF_SET(byte ahValue, byte bitsToRotate, ushort expectedValue, bool expectedCFValue) + [InlineData(0xF, 1, 0x87, true, true)] + [InlineData(0x7F, 1, 0xBF, true, true)] + [InlineData(0xFF, 2, 0xFF, true, false)] + [InlineData(0x0, 1, 0x80, false, true)] + [InlineData(0xE, 1, 0x87, false, true)] + public void RCR_AH_IMM8_CF_SET(byte ahValue, byte bitsToRotate, ushort expectedValue, bool expectedCFValue, bool expectedOFValue) { Reset(); mbbsEmuCpuRegisters.AH = ahValue; @@ -90,18 +103,21 @@ public void RCR_AH_IMM8_CF_SET(byte ahValue, byte bitsToRotate, ushort expectedV Assert.Equal(expectedValue, mbbsEmuCpuRegisters.AH); Assert.Equal(expectedCFValue, mbbsEmuCpuRegisters.CarryFlag); + Assert.Equal(expectedOFValue, mbbsEmuCpuRegisters.OverflowFlag); } [Theory] - [InlineData(0xF, 1, 0x7, true)] - [InlineData(0xE, 1, 0x7, false)] - [InlineData(0x1FF, 1, 0xFF, true)] - [InlineData(0x1FE, 1, 0xFF, false)] - [InlineData(0x3C, 2, 0xF, false)] - [InlineData(0x3E, 2, 0xF, true)] - [InlineData(0xFFFF, 2, 0xBFFF, true)] + [InlineData(0xF, 1, 0x7, true, false)] + [InlineData(0xE, 1, 0x7, false, false)] + [InlineData(0x6, 1, 0x3, false, false)] + [InlineData(0x1FF, 1, 0xFF, true, false)] + [InlineData(0x1FE, 1, 0xFF, false, false)] + [InlineData(0x3C, 2, 0xF, false, false)] + [InlineData(0x3E, 2, 0xF, true, false)] + [InlineData(0xFFFF, 1, 0x7FFF, true, true)] + [InlineData(0xFFFF, 2, 0xBFFF, true, false)] public void RCR_M16_IMM16_1(ushort memoryValue, byte bitsToRotate, ushort expectedValue, - bool expectedCFValue) + bool expectedCFValue, bool expectedOFValue) { Reset(); mbbsEmuCpuRegisters.DS = 2; @@ -115,6 +131,7 @@ public void RCR_M16_IMM16_1(ushort memoryValue, byte bitsToRotate, ushort expect Assert.Equal(expectedValue, mbbsEmuMemoryCore.GetWord(2, 0)); Assert.Equal(expectedCFValue, mbbsEmuCpuRegisters.CarryFlag); + Assert.Equal(expectedOFValue, mbbsEmuCpuRegisters.OverflowFlag); } } } diff --git a/MBBSEmu/CPU/CPUCore.cs b/MBBSEmu/CPU/CPUCore.cs index c3044733..29ff9c12 100644 --- a/MBBSEmu/CPU/CPUCore.cs +++ b/MBBSEmu/CPU/CPUCore.cs @@ -360,7 +360,10 @@ public void Tick() { _showDebug = true; //Set to log Register values to console after execution _logger.Debug($"{Registers.CS:X4}:{_currentInstruction.IP16:X4} {_currentInstruction}"); - _logger.Debug($"{Registers}"); + foreach(var l in Registers.ToString().Split("\n")) + _logger.Debug(l); + for(var i = 0; i < 8; i++) + _logger.Debug($"FPU[{i}]: {FpuStack[i]} {(i == Registers.Fpu.GetStackTop() ? " <--" : string.Empty)}"); } else { @@ -951,6 +954,43 @@ private uint GetOperandValueUInt32(OpKind opKind, EnumOperandType operandType) } } + /// + /// This is a helper method which takes the resulting value from GetOperandValueUInt64 and signs it depending on the underlying + /// OpKind and MemorySize + /// + /// + /// + [MethodImpl(OpcodeCompilerOptimizations)] + private long GetOperandValueInt64(OpKind opKind) + { + var value = GetOperandValueUInt64(opKind); + + return opKind switch + { + OpKind.Immediate8 => (sbyte)value, + OpKind.Immediate16 => (short)value, + OpKind.Immediate8to16 => (short)value, + OpKind.Immediate32 => (int)value, + OpKind.Immediate8to32 => (int)value, + OpKind.Immediate64 => (long)value, + OpKind.Immediate8to64 => (long)value, + OpKind.Memory => _currentInstruction.MemorySize switch + { + MemorySize.Int8 => (sbyte)value, + MemorySize.UInt8 => (byte)value, + MemorySize.Int16 => (short)value, + MemorySize.UInt16 => (ushort)value, + MemorySize.Int32 => (int)value, + MemorySize.UInt32 => (uint)value, + MemorySize.Int64 => (long)value, + MemorySize.UInt64 => (long)value, + _ => throw new Exception($"Invalid Operand Size: {_currentInstruction.MemorySize}") + }, + _ => throw new Exception($"Unsupported OpKind: {opKind}") + }; + + } + /// /// Returns the Operand Value as a 64-bit Integer /// @@ -1597,6 +1637,10 @@ private byte Op_Rcr_8() Registers.CarryFlag = newCFValue; } + //Only on 1 Bit Rotations to we evaluate Overflow + if (source == 1) + Registers.OverflowFlag = result.IsBitSet(7) ^ result.IsBitSet(6); + return result; } } @@ -1638,6 +1682,10 @@ private ushort Op_Rcr_16() Registers.CarryFlag = newCFValue; } + //Only on 1 Bit Rotations to we evaluate Overflow + if (source == 1) + Registers.OverflowFlag = result.IsBitSet(15) ^ result.IsBitSet(14); + return result; } } @@ -1684,6 +1732,10 @@ private byte Op_Rcl_8() Registers.CarryFlag = newCFValue; } + //For 1 Bit Rotations, we evaluate Overflow + if(source == 1) + Registers.OverflowFlag = result.IsBitSet(7) ^ Registers.CarryFlag; + return result; } } @@ -1713,6 +1765,10 @@ private ushort Op_Rcl_16() Registers.CarryFlag = newCFValue; } + //For 1 Bit Rotations, we evaluate Overflow + if (source == 1) + Registers.OverflowFlag = result.IsBitSet(7) ^ Registers.CarryFlag; + return result; } } @@ -3107,7 +3163,7 @@ private void Op_Fld() [MethodImpl(OpcodeCompilerOptimizations)] private void Op_Fild() { - var valueToLoad = GetOperandValueUInt64(_currentInstruction.Op0Kind); + var valueToLoad = GetOperandValueInt64(_currentInstruction.Op0Kind); Registers.Fpu.PushStackTop(); FpuStack[Registers.Fpu.GetStackTop()] = valueToLoad; @@ -3814,7 +3870,7 @@ private void Op_Fcom() var source = GetOperandValueDouble(_currentInstruction.Op0Kind, EnumOperandType.Source); var ST0 = FpuStack[Registers.Fpu.GetStackTop()]; - if (double.IsNaN(ST0) || double.IsNaN(source)) + if (double.IsNaN(ST0) || double.IsNaN(source) || double.IsInfinity(ST0) || double.IsInfinity(source)) { Registers.Fpu.SetFlag(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3); return; @@ -3860,7 +3916,7 @@ private void Op_Fcompp() var ST0 = FpuStack[Registers.Fpu.GetStackTop()]; var ST1 = FpuStack[Registers.Fpu.GetStackPointer(Register.ST1)]; - if (double.IsNaN(ST0) || double.IsNaN(ST1)) + if (double.IsNaN(ST0) || double.IsNaN(ST1) || double.IsInfinity(ST0) || double.IsInfinity(ST1)) { Registers.Fpu.SetFlag(EnumFpuStatusFlags.Code0 | EnumFpuStatusFlags.Code2 | EnumFpuStatusFlags.Code3); } @@ -3984,8 +4040,9 @@ private byte Op_Ror_8() //CF Set if Most Significant Bit set to 1 Registers.CarryFlag = result.IsNegative(); - //If Bits 7 & 6 are not the same, then we overflowed - Registers.OverflowFlag = result.IsBitSet(7) != result.IsBitSet(6); + //If Bits 7 & 6 are not the same, then we overflowed for 1 bit rotations + if(source == 1) + Registers.OverflowFlag = result.IsBitSet(7) != result.IsBitSet(6); return result; } @@ -4008,8 +4065,9 @@ private ushort Op_Ror_16() //CF Set if Most Significant Bit set to 1 Registers.CarryFlag = result.IsNegative(); - //If Bits 15 & 14 are not the same, then we overflowed - Registers.OverflowFlag = result.IsBitSet(15) != result.IsBitSet(14); + //If Bits 15 & 14 are not the same, then we overflowed for 1 bit rotations + if (source == 1) + Registers.OverflowFlag = result.IsBitSet(15) != result.IsBitSet(14); return result; } diff --git a/MBBSEmu/Module/CrashReport.cs b/MBBSEmu/Module/CrashReport.cs index e102a653..04d03dfd 100644 --- a/MBBSEmu/Module/CrashReport.cs +++ b/MBBSEmu/Module/CrashReport.cs @@ -61,7 +61,15 @@ public string Save(string fileName = "") crashReportVariables.Add(_exception.StackTrace); //CPU Instruction - crashReportVariables.Add(_moduleToReport.Memory.GetInstruction(_registers.CS, _registers.IP).ToString()); + try + { + crashReportVariables.Add(_moduleToReport.Memory.GetInstruction(_registers.CS, _registers.IP).ToString()); + } + catch (Exception e) + { + crashReportVariables.Add("Exception retrieving CPU Instruction"); + } + //Registers crashReportVariables.Add(_registers.ToString());