diff --git a/MBBSEmu/CPU/CPUCore.cs b/MBBSEmu/CPU/CPUCore.cs
index 22ddf700..d54d7be4 100644
--- a/MBBSEmu/CPU/CPUCore.cs
+++ b/MBBSEmu/CPU/CPUCore.cs
@@ -955,7 +955,89 @@ private uint GetOperandValueUInt32(OpKind opKind, EnumOperandType operandType)
}
///
+ /// This is a helper method which takes the resulting value from GetOperandValueUInt8 and signs it depending on the underlying
/// OpKind and MemorySize
+ ///
+ ///
+ ///
+ [MethodImpl(OpcodeCompilerOptimizations)]
+ private sbyte GetOperandValueInt8(OpKind opKind, EnumOperandType operandType)
+ {
+ var value = GetOperandValueUInt8(opKind, operandType);
+
+ return opKind switch
+ {
+ OpKind.Immediate8 => (sbyte)value,
+ OpKind.Register => (sbyte)value,
+ OpKind.Memory => _currentInstruction.MemorySize switch
+ {
+ MemorySize.Int8 => (sbyte)value,
+ _ => throw new Exception($"Invalid Operand Size: {_currentInstruction.MemorySize}")
+ },
+ _ => throw new Exception($"Unsupported OpKind: {opKind}")
+ };
+ }
+
+ ///
+ /// This is a helper method which takes the resulting value from GetOperandValueUInt16 and signs it depending on the underlying
+ /// OpKind and MemorySize
+ ///
+ ///
+ ///
+ [MethodImpl(OpcodeCompilerOptimizations)]
+ private short GetOperandValueInt16(OpKind opKind, EnumOperandType operandType)
+ {
+ var value = GetOperandValueUInt16(opKind, operandType);
+
+ return opKind switch
+ {
+ OpKind.Immediate8 => (sbyte)value,
+ OpKind.Immediate16 => (short)value,
+ OpKind.Immediate8to16 => (short)value,
+ OpKind.Register => (short)value,
+ OpKind.Memory => _currentInstruction.MemorySize switch
+ {
+ MemorySize.Int8 => (sbyte)value,
+ MemorySize.UInt8 => (byte)value,
+ MemorySize.Int16 => (short)value,
+ _ => throw new Exception($"Invalid Operand Size: {_currentInstruction.MemorySize}")
+ },
+ _ => throw new Exception($"Unsupported OpKind: {opKind}")
+ };
+ }
+
+ ///
+ /// 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 int GetOperandValueInt32(OpKind opKind, EnumOperandType operandType)
+ {
+ var value = GetOperandValueUInt32(opKind, operandType);
+
+ return opKind switch
+ {
+ OpKind.Immediate8 => (sbyte)value,
+ OpKind.Immediate16 => (short)value,
+ OpKind.Immediate8to16 => (short)value,
+ OpKind.Immediate32 => (int)value,
+ OpKind.Immediate8to32 => (int)value,
+ OpKind.Register => (int)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,
+ _ => throw new Exception($"Invalid Operand Size: {_currentInstruction.MemorySize}")
+ },
+ _ => throw new Exception($"Unsupported OpKind: {opKind}")
+ };
+ }
+
///
/// This is a helper method which takes the resulting value from GetOperandValueUInt64 and signs it depending on the underlying
/// OpKind and MemorySize
@@ -2757,7 +2839,12 @@ private void Op_Imul_3operand_8()
{
var operand2 = GetOperandValueInt8(_currentInstruction.Op1Kind, EnumOperandType.Source);
var operand3 = GetOperandValueInt8(_currentInstruction.Op2Kind, EnumOperandType.Source);
+ var result = operand2 * operand3;
+
//Set CarryFlag and OverflowFlag if the result is too large to fit in the destination
+ Registers.OverflowFlag = Registers.CarryFlag = result is > sbyte.MaxValue or < sbyte.MinValue;
+
+ WriteToDestination((byte)result);
}
[MethodImpl(OpcodeSubroutineCompilerOptimizations)]