public void TestHalt() { // Arrange var cpu = new CPU(); var random = new Random(); var memory = new Memory(random); var consoleOutput = new ConsoleOutput(); var interpreter = new Interpreter(cpu, memory, random, consoleOutput); var instruction = new Instruction { ExecutionPossibility = 100, FirstRegister = 0, MemoryAddress = 0, OpCode = OpCodes.Halt, SecondRegister = 0, ThirdRegister = 0 }; // Act interpreter.ExecuteInstruction(instruction); // Assert // Expected exception specified in method attribute }
public void TestComparison() { // Arrange var cpu = new CPU(); cpu.C = 0; cpu.R[2] = 100; cpu.R[3] = 200; var random = new Random(); var memory = new Memory(random); var consoleOutput = new ConsoleOutput(); var interpreter = new Interpreter(cpu, memory, random, consoleOutput); var instruction = new Instruction { ExecutionPossibility = 100, FirstRegister = 2, MemoryAddress = 0, OpCode = OpCodes.Compare, SecondRegister = 3, ThirdRegister = 0 }; // Act interpreter.ExecuteInstruction(instruction); // Assert Assert.AreEqual(-1, cpu.C); }
public bool Equals(Instruction other) { return OpCode == other.OpCode && FirstRegister == other.FirstRegister && SecondRegister == other.SecondRegister && ThirdRegister == other.ThirdRegister && ExecutionPossibility == other.ExecutionPossibility && MemoryAddress == other.MemoryAddress; }
public void TestParsingFromWordWithUnusedBits() { // Arrange const int word = 0x20F3B05F; var targetResult = new Instruction { OpCode = OpCodes.Compare, FirstRegister = 3, SecondRegister = 11, ThirdRegister = 0, ExecutionPossibility = 95 }; // Act var instruction = Instruction.FromWord(word); // Assert Assert.AreEqual(targetResult, instruction); }
public void TestParsingTwoWordInstruction() { // Arrange const int word1 = 0x40050064; const int word2 = 0x12345678; var targetResult = new Instruction { OpCode = OpCodes.LoadByMem, FirstRegister = 5, SecondRegister = 0, ThirdRegister = 0, ExecutionPossibility = 100, MemoryAddress = 0x12345678 }; // Act var instruction = Instruction.FromWord(word1, word2); // Assert Assert.AreEqual(targetResult, instruction); }
public void ExecuteInstruction(Instruction instruction) { _cpu.AdvancePC(); if (instruction.OpCode == OpCodes.LoadByMem || instruction.OpCode == OpCodes.StoreByMem) { _cpu.AdvancePC(); } if (instruction.OpCode == OpCodes.Halt) { throw new VmHaltException(); } else if ((instruction.ExecutionPossibility == 0) || (_random.Next(0, 100) > instruction.ExecutionPossibility)) { return; } switch (instruction.OpCode) { case OpCodes.Add: _cpu.R[instruction.FirstRegister] = _cpu.R[instruction.SecondRegister] + _cpu.R[instruction.ThirdRegister]; break; case OpCodes.And: _cpu.R[instruction.FirstRegister] = _cpu.R[instruction.SecondRegister] & _cpu.R[instruction.ThirdRegister]; break; case OpCodes.Compare: int subtractionResult = _cpu.R[instruction.FirstRegister] - _cpu.R[instruction.SecondRegister]; _cpu.C = (sbyte) Math.Sign(subtractionResult); break; case OpCodes.Decrease: _cpu.R[instruction.FirstRegister]--; break; case OpCodes.Divide: _cpu.R[instruction.FirstRegister] = _cpu.R[instruction.SecondRegister] / _cpu.R[instruction.ThirdRegister]; break; case OpCodes.Increase: _cpu.R[instruction.FirstRegister]++; break; case OpCodes.Jump: _cpu.PC = (uint) _cpu.R[instruction.FirstRegister]; break; case OpCodes.JumpIfEqual: if (_cpu.C == 0) { _cpu.PC = (uint) _cpu.R[instruction.FirstRegister]; } break; case OpCodes.JumpIfGreater: if (_cpu.C == 1) { _cpu.PC = (uint) _cpu.R[instruction.FirstRegister]; } break; case OpCodes.JumpIfLess: if (_cpu.C == -1) { _cpu.PC = (uint) _cpu.R[instruction.FirstRegister]; } break; case OpCodes.JumpIfNotEqual: if (_cpu.C != 0) { _cpu.PC = (uint) _cpu.R[instruction.FirstRegister]; } break; case OpCodes.LoadByMem: _cpu.R[instruction.FirstRegister] = _memory.ReadWord(instruction.MemoryAddress); break; case OpCodes.LoadByReg: _cpu.R[instruction.FirstRegister] = _memory.ReadWord((uint) _cpu.R[instruction.SecondRegister]); break; case OpCodes.Modulo: _cpu.R[instruction.FirstRegister] = _cpu.R[instruction.SecondRegister] % _cpu.R[instruction.ThirdRegister]; break; case OpCodes.Multiply: _cpu.R[instruction.FirstRegister] = _cpu.R[instruction.SecondRegister] * _cpu.R[instruction.ThirdRegister]; break; case OpCodes.Negate: _cpu.R[instruction.FirstRegister] = ~ _cpu.R[instruction.SecondRegister]; break; case OpCodes.Or: _cpu.R[instruction.FirstRegister] = _cpu.R[instruction.SecondRegister] | _cpu.R[instruction.ThirdRegister]; break; case OpCodes.PrintNumber: _output.Write(_cpu.R[instruction.FirstRegister].ToString()); break; case OpCodes.PrintString: var bytes = BitConverter.GetBytes(_cpu.R[instruction.FirstRegister]); Array.Reverse(bytes); var text = Encoding.ASCII.GetString(bytes); _output.Write(text); break; case OpCodes.RandomizedAdd: _cpu.R[instruction.FirstRegister] = Randomize(_cpu.R[instruction.SecondRegister] + _cpu.R[instruction.ThirdRegister]); break; case OpCodes.RandomizedDivide: _cpu.R[instruction.FirstRegister] = Randomize(_cpu.R[instruction.SecondRegister] / _cpu.R[instruction.ThirdRegister]); break; case OpCodes.RandomizedModulo: _cpu.R[instruction.FirstRegister] = Randomize(_cpu.R[instruction.SecondRegister] % _cpu.R[instruction.ThirdRegister]); break; case OpCodes.RandomizedMultiply: _cpu.R[instruction.FirstRegister] = Randomize(_cpu.R[instruction.SecondRegister] * _cpu.R[instruction.ThirdRegister]); break; case OpCodes.RandomizedSubtract: _cpu.R[instruction.FirstRegister] = Randomize(_cpu.R[instruction.SecondRegister] - _cpu.R[instruction.ThirdRegister]); break; case OpCodes.StoreByMem: _memory.WriteWord(instruction.MemoryAddress, _cpu.R[instruction.FirstRegister]); break; case OpCodes.StoreByReg: _memory.WriteWord((uint)_cpu.R[instruction.SecondRegister], _cpu.R[instruction.FirstRegister]); break; case OpCodes.Subtract: _cpu.R[instruction.FirstRegister] = _cpu.R[instruction.SecondRegister] - _cpu.R[instruction.ThirdRegister]; break; case OpCodes.Xor: _cpu.R[instruction.FirstRegister] = _cpu.R[instruction.SecondRegister] ^ _cpu.R[instruction.ThirdRegister]; break; } }
public void TestJumpIfGreater() { // Arrange var cpu = new CPU(); cpu.C = 1; cpu.PC = 0; unchecked { cpu.R[0] = (int) 0x98513691; } var random = new Random(); var memory = new Memory(random); var consoleOutput = new ConsoleOutput(); var interpreter = new Interpreter(cpu, memory, random, consoleOutput); var instruction = new Instruction { ExecutionPossibility = 100, FirstRegister = 0, MemoryAddress = 0, OpCode = OpCodes.JumpIfGreater, SecondRegister = 0, ThirdRegister = 0 }; // Act interpreter.ExecuteInstruction(instruction); // Assert Assert.AreEqual(0x98513691, cpu.PC); }
public void TestStoreByMem() { // Arrange var cpu = new CPU(); cpu.R[0] = 0x0A0B0C0D; var random = new Random(); var memory = new Memory(random); var consoleOutput = new ConsoleOutput(); var interpreter = new Interpreter(cpu, memory, random, consoleOutput); var instruction = new Instruction { ExecutionPossibility = 100, FirstRegister = 0, MemoryAddress = 0x87654320, OpCode = OpCodes.StoreByMem, SecondRegister = 1, ThirdRegister = 2 }; // Act interpreter.ExecuteInstruction(instruction); var valueInMemory = memory.ReadWord(0x87654320); // Assert Assert.AreEqual(0x0A0B0C0D, valueInMemory); }
public void TestRandomizedAdd() { // Arrange var cpu = new CPU(); cpu.R[0] = 0; cpu.R[1] = 200; cpu.R[2] = 300; var random = new Random(); var memory = new Memory(random); var consoleOutput = new ConsoleOutput(); var interpreter = new Interpreter(cpu, memory, random, consoleOutput); var instruction = new Instruction { ExecutionPossibility = 100, FirstRegister = 0, MemoryAddress = 0, OpCode = OpCodes.RandomizedAdd, SecondRegister = 1, ThirdRegister = 2 }; // Act interpreter.ExecuteInstruction(instruction); // Assert Assert.That(cpu.R[0], Is.EqualTo(500).Within(1).Percent); }
public void TestMultiplication() { // Arrange var cpu = new CPU(); cpu.R[0] = 0; cpu.R[1] = 200; cpu.R[2] = 300; var random = new Random(); var memory = new Memory(random); var consoleOutput = new ConsoleOutput(); var interpreter = new Interpreter(cpu, memory, random, consoleOutput); var instruction = new Instruction { ExecutionPossibility = 100, FirstRegister = 0, MemoryAddress = 0, OpCode = OpCodes.Multiply, SecondRegister = 1, ThirdRegister = 2 }; // Act interpreter.ExecuteInstruction(instruction); // Assert Assert.AreEqual(60000, cpu.R[0]); }
public void TestLogicalOrWithZeroProbability() { // Arrange var cpu = new CPU(); cpu.R[10] = 0; cpu.R[11] = 0x02040608; cpu.R[12] = 0x10305070; var random = new Random(); var memory = new Memory(random); var consoleOutput = new ConsoleOutput(); var interpreter = new Interpreter(cpu, memory, random, consoleOutput); var instruction = new Instruction { ExecutionPossibility = 0, FirstRegister = 10, MemoryAddress = 0, OpCode = OpCodes.Or, SecondRegister = 11, ThirdRegister = 12 }; // Act interpreter.ExecuteInstruction(instruction); // Assert Assert.AreEqual(0, cpu.R[10]); }