public void Jumping_OutsideValidMemoryRange_ThrowsException(ushort instructionCode, byte v0) { var cpu = new Cpu(); var decodedInstruction = new DecodedInstruction(instructionCode); cpu.V[0] = v0; var instruction = new Instruction_Bnnn(decodedInstruction); Assert.Throws <InvalidOperationException>(() => instruction.Execute(cpu, MockedDisplay, MockedKeyboard)); }
public void Executing_Instruction_Bnnn_WorksAsExpected(ushort instructionCode, byte v0, ushort expectedPcValue) { var cpu = new Cpu(); var decodedInstruction = new DecodedInstruction(instructionCode); cpu.V[0] = v0; var instruction = new Instruction_Bnnn(decodedInstruction); instruction.Execute(cpu, MockedDisplay, MockedKeyboard); Assert.That(cpu.PC, Is.EqualTo(expectedPcValue)); Assert.That(instruction.Mnemonic, Is.EqualTo($"JP V0, 0x{decodedInstruction.nnn:X}")); }
/// <summary> /// Converts instance of <see cref="DecodedInstruction"/> into an instance of <see cref="CpuInstruction"/>. /// </summary> /// <param name="decodedInstruction">Decoded 2 bytes of memory.</param> /// <returns>Concrete Cpu instruction or <see cref="UndefinedInstruction"/> if instruction cannot be determined.</returns> public CpuInstruction GetCpuInstruction(DecodedInstruction decodedInstruction) { CpuInstruction cpuInstruction = null; switch (decodedInstruction.OpCode) { case 0x0: if (decodedInstruction.kk == 0xE0) { cpuInstruction = new Instruction_00E0(decodedInstruction); } else if (decodedInstruction.kk == 0xEE) { cpuInstruction = new Instruction_00EE(decodedInstruction); } break; case 0x1: cpuInstruction = new Instruction_1nnn(decodedInstruction); break; case 0x2: cpuInstruction = new Instruction_2nnn(decodedInstruction); break; case 0x3: cpuInstruction = new Instruction_3xkk(decodedInstruction); break; case 0x4: cpuInstruction = new Instruction_4xkk(decodedInstruction); break; case 0x5: if (decodedInstruction.n == 0x0) { cpuInstruction = new Instruction_5xy0(decodedInstruction); } break; case 0x6: cpuInstruction = new Instruction_6xkk(decodedInstruction); break; case 0x7: cpuInstruction = new Instruction_7xkk(decodedInstruction); break; case 0x8: { switch (decodedInstruction.n) { case 0x0: cpuInstruction = new Instruction_8xy0(decodedInstruction); break; case 0x1: cpuInstruction = new Instruction_8xy1(decodedInstruction); break; case 0x2: cpuInstruction = new Instruction_8xy2(decodedInstruction); break; case 0x3: cpuInstruction = new Instruction_8xy3(decodedInstruction); break; case 0x4: cpuInstruction = new Instruction_8xy4(decodedInstruction); break; case 0x5: cpuInstruction = new Instruction_8xy5(decodedInstruction); break; case 0x6: cpuInstruction = new Instruction_8xy6(decodedInstruction); break; case 0x7: cpuInstruction = new Instruction_8xy7(decodedInstruction); break; case 0xE: cpuInstruction = new Instruction_8xyE(decodedInstruction); break; default: cpuInstruction = new UndefinedInstruction(decodedInstruction); break; } } break; case 0x9: if (decodedInstruction.n == 0x0) { cpuInstruction = new Instruction_9xy0(decodedInstruction); } break; case 0xA: cpuInstruction = new Instruction_Annn(decodedInstruction); break; case 0xB: cpuInstruction = new Instruction_Bnnn(decodedInstruction); break; case 0xC: cpuInstruction = new Instruction_Cxkk(decodedInstruction); break; case 0xD: cpuInstruction = new Instruction_Dxyn(decodedInstruction); break; case 0xE: { switch (decodedInstruction.kk) { case 0x9E: cpuInstruction = new Instruction_Ex9E(decodedInstruction); break; case 0xA1: cpuInstruction = new Instruction_ExA1(decodedInstruction); break; default: cpuInstruction = new UndefinedInstruction(decodedInstruction); break; } } break; case 0xF: { switch (decodedInstruction.kk) { case 0x07: cpuInstruction = new Instruction_Fx07(decodedInstruction); break; case 0x0A: cpuInstruction = new Instruction_Fx0A(decodedInstruction); break; case 0x15: cpuInstruction = new Instruction_Fx15(decodedInstruction); break; case 0x18: cpuInstruction = new Instruction_Fx18(decodedInstruction); break; case 0x1E: cpuInstruction = new Instruction_Fx1E(decodedInstruction); break; case 0x29: cpuInstruction = new Instruction_Fx29(decodedInstruction); break; case 0x33: cpuInstruction = new Instruction_Fx33(decodedInstruction); break; case 0x55: cpuInstruction = new Instruction_Fx55(decodedInstruction); break; case 0x65: cpuInstruction = new Instruction_Fx65(decodedInstruction); break; default: cpuInstruction = new UndefinedInstruction(decodedInstruction); break; } break; } default: cpuInstruction = new UndefinedInstruction(decodedInstruction); break; } return(cpuInstruction ?? new UndefinedInstruction(decodedInstruction)); }