diff --git a/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.FunctOpCode.cs b/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.FunctOpCode.cs
index f3dd199..c871de3 100644
--- a/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.FunctOpCode.cs
+++ b/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.FunctOpCode.cs
@@ -7,7 +7,9 @@
public enum FunctOpCode : byte
{
/// Write Indexed TLB Entry.
- TLBWI = 0b000010
+ TLBWI = 0b000010,
+ /// Return From Exception.
+ ERET = 0b011000
}
}
}
diff --git a/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.cs b/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.cs
index 684a585..bb0a77f 100644
--- a/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.cs
+++ b/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.cs
@@ -38,13 +38,29 @@ namespace DotN64.CPU
{
if (functOperations.TryGetValue((FunctOpCode)i.Funct, out var operation))
operation(i);
- else if (i.Funct == 0b010000)
+ else //if (i.Funct == 0b010000) // TODO: Uncomment once the operations are implemented.
ExceptionProcessing.ReservedInstruction(cpu, i);
}
};
functOperations = new Dictionary>
{
- [FunctOpCode.TLBWI] = i => { /* TODO. */ }
+ [FunctOpCode.TLBWI] = i => { /* TODO. */ },
+ [FunctOpCode.ERET] = i =>
+ {
+ if (Status.ERL)
+ {
+ cpu.PC = Registers[(int)RegisterIndex.ErrorEPC];
+ Status.ERL = false;
+ }
+ else
+ {
+ cpu.PC = Registers[(int)RegisterIndex.EPC];
+ Status.EXL = false;
+ }
+
+ cpu.LLBit = false;
+ cpu.DelaySlot = null;
+ }
};
}
#endregion
diff --git a/DotN64/CPU/VR4300/VR4300.SpecialOpCode.cs b/DotN64/CPU/VR4300/VR4300.SpecialOpCode.cs
index dcfd0a4..37ded60 100644
--- a/DotN64/CPU/VR4300/VR4300.SpecialOpCode.cs
+++ b/DotN64/CPU/VR4300/VR4300.SpecialOpCode.cs
@@ -45,7 +45,11 @@
/// Doubleword Divide Unsigned.
DDIVU = 0b011111,
/// Shift Right Arithmetic.
- SRA = 0b000011
+ SRA = 0b000011,
+ /// Move To LO.
+ MTLO = 0b010011,
+ /// Move To HI.
+ MTHI = 0b010001
}
}
}
diff --git a/DotN64/CPU/VR4300/VR4300.cs b/DotN64/CPU/VR4300/VR4300.cs
index 7ffb60a..554b874 100644
--- a/DotN64/CPU/VR4300/VR4300.cs
+++ b/DotN64/CPU/VR4300/VR4300.cs
@@ -222,6 +222,8 @@ namespace DotN64.CPU
HI = rs % rt;
},
[Instruction.FromOpCode(SpecialOpCode.SRA)] = i => GPR[i.RD] = (ulong)((int)GPR[i.RT] >> i.SA),
+ [Instruction.FromOpCode(SpecialOpCode.MTLO)] = i => LO = GPR[i.RS],
+ [Instruction.FromOpCode(SpecialOpCode.MTHI)] = i => HI = GPR[i.RS],
[Instruction.FromOpCode(RegImmOpCode.BGEZAL)] = i => Branch(i, (rs, rt) => rs >= 0, true),
[Instruction.FromOpCode(RegImmOpCode.BGEZL)] = i => BranchLikely(i, (rs, rt) => rs >= 0)
};
diff --git a/DotN64/Diagnostics/Debugger.InstructionFormat.cs b/DotN64/Diagnostics/Debugger.InstructionFormat.cs
index be82968..a688331 100644
--- a/DotN64/Diagnostics/Debugger.InstructionFormat.cs
+++ b/DotN64/Diagnostics/Debugger.InstructionFormat.cs
@@ -93,6 +93,8 @@
switch (instruction.Special)
{
case VR4300.SpecialOpCode.JR:
+ case VR4300.SpecialOpCode.MTLO:
+ case VR4300.SpecialOpCode.MTHI:
return Format(instruction, FormatRegister(instruction.RS, cpu));
case VR4300.SpecialOpCode.MFHI:
case VR4300.SpecialOpCode.MFLO:
diff --git a/DotN64/Diagnostics/Debugger.cs b/DotN64/Diagnostics/Debugger.cs
index e91fac6..6916442 100644
--- a/DotN64/Diagnostics/Debugger.cs
+++ b/DotN64/Diagnostics/Debugger.cs
@@ -51,6 +51,8 @@ namespace DotN64.Diagnostics
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.JR)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.MFHI)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.MFLO)] = InstructionFormat.R,
+ [VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.MTHI)] = InstructionFormat.R,
+ [VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.MTLO)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.MULTU)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.OR)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.SLL)] = InstructionFormat.R,