예제 #1
0
        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));
        }
예제 #2
0
        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}"));
        }
예제 #3
0
        /// <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));
        }