diff --git a/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.cs b/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.cs index 2ec0a50..68c8a46 100644 --- a/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.cs +++ b/DotN64/CPU/VR4300/CP0/VR4300.SystemControlUnit.cs @@ -10,8 +10,7 @@ namespace DotN64.CPU { #region Fields private readonly VR4300 cpu; - private readonly IReadOnlyDictionary> operations; - private readonly IReadOnlyDictionary> functOperations; + private readonly IReadOnlyDictionary> operations; #endregion #region Properties @@ -33,22 +32,12 @@ namespace DotN64.CPU Config = new ConfigRegister(this); Status = new StatusRegister(this); Cause = new CauseRegister(this); - operations = new Dictionary> + operations = new Dictionary> { - [OpCode.MT] = i => Registers[i.RD] = cpu.GPR[i.RT], - [OpCode.MF] = i => cpu.GPR[i.RT] = (ulong)(int)Registers[i.RD], - [OpCode.CO] = i => - { - if (functOperations.TryGetValue((FunctOpCode)i.Funct, out var operation)) - operation(i); - else //if (i.Funct == 0b010000) // TODO: Uncomment once the operations are implemented. - ExceptionProcessing.ReservedInstruction(cpu, i); - } - }; - functOperations = new Dictionary> - { - [FunctOpCode.TLBWI] = i => { /* TODO. */ }, - [FunctOpCode.ERET] = i => + [From(OpCode.MT)] = i => Registers[i.RD] = cpu.GPR[i.RT], + [From(OpCode.MF)] = i => cpu.GPR[i.RT] = (ulong)(int)Registers[i.RD], + [From(FunctOpCode.TLBWI)] = i => { /* TODO. */ }, + [From(FunctOpCode.ERET)] = i => { if (Status.ERL) { @@ -69,6 +58,26 @@ namespace DotN64.CPU #endregion #region Methods + private static Instruction From(OpCode op) => new Instruction { RS = (byte)op }; + + private static Instruction From(FunctOpCode op) => new Instruction { RS = (byte)OpCode.CO, Funct = (byte)op }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Instruction ToOpCode(Instruction instruction) + { + switch ((OpCode)instruction.RS) + { + case OpCode.CO: + return new Instruction + { + RS = instruction.RS, + Funct = instruction.Funct + }; + default: + return new Instruction { RS = instruction.RS }; + } + } + /// /// Increments the Count register (must be called on every odd PClock cycle), and updates the timer interrupt. /// @@ -107,7 +116,7 @@ namespace DotN64.CPU [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Run(Instruction instruction) { - if (operations.TryGetValue((OpCode)instruction.RS, out var operation)) + if (operations.TryGetValue(ToOpCode(instruction), out var operation)) operation(instruction); else ExceptionProcessing.ReservedInstruction(cpu, instruction);