Ejemplo n.º 1
0
    public void Executing_Instruction_Dxy0_DoesNotUseDisplay()
    {
      var cpu = new Cpu();
      var decodedInstruction = new DecodedInstruction(0xD230);

      var instruction = new Instruction_Dxyn(decodedInstruction);
      instruction.Execute(cpu, MockedDisplay, MockedKeyboard);
    }
Ejemplo n.º 2
0
    public void Executing_Instruction_Dxyn_WorksAsExpected()
    {
      const byte xCoordinate = 0x5, yCoordinate = 0x6;
      var cpu = new Cpu();
      cpu.V[2] = xCoordinate;
      cpu.V[3] = yCoordinate;
      cpu.I = 0x300;
      cpu.Memory[cpu.I] = 0x1;

      var decodedInstruction = new DecodedInstruction(0xD231);

      // Expected execution result:
      // - decodedInstruction.n bytes (1) are read from memory, starting at location I (0x300)
      // - those bytes are written to screen, starting at location (V2, V3) = 5,6
      // - since value at 0x300 is 0x1, and 1 is the least significant bit of that byte, then location where 
      //   pixel will be set is: xCoordinate + 7 (e.g. for value of 2, it would be xCoordinate + 6)
      // - re-executing the same command will reset the pixel and set VF register to 1
      var mockSequence = new MockSequence();
      var displayMock = new Mock<IDisplay>(MockBehavior.Strict);

      // First execution
      for(byte i = 0; i < 8; i++)
      {
        displayMock.InSequence(mockSequence).Setup(x => x.GetPixel(
          (byte)(xCoordinate + i), yCoordinate)).Returns(false);
      }
      displayMock.InSequence(mockSequence).Setup(x => x.SetPixel(xCoordinate + 7, yCoordinate));

      // Second execution
      for (byte i = 0; i < 8; i++)
      {
        displayMock.InSequence(mockSequence).Setup(x => x.GetPixel(
          (byte)(xCoordinate + i), yCoordinate)).Returns(i == 7);
      }
      displayMock.InSequence(mockSequence).Setup(x => x.ClearPixel(xCoordinate + 7, yCoordinate));

      var display = displayMock.Object;
      var instruction = new Instruction_Dxyn(decodedInstruction);

      instruction.Execute(cpu, display, MockedKeyboard);
      Assert.That(cpu.V[0xF], Is.EqualTo(0));

      instruction.Execute(cpu, display, MockedKeyboard);
      Assert.That(cpu.V[0xF], Is.EqualTo(1));

      displayMock.VerifyAll();
      Assert.That(instruction.Mnemonic, Is.EqualTo($"DRW V{decodedInstruction.x:X}, V{decodedInstruction.y:X}, {decodedInstruction.n:X}"));
    }
Ejemplo n.º 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));
        }