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,