示例#1
0
        public void DecodesOpeningZorkInstruction()
        {
            using var file = File.OpenRead(@"Data\ZORK1.DAT");
            var logger  = NullLoggerFactory.GetLogger();
            var machine = new Machine(logger, new SolveZorkInputStream());

            machine.Load(file);

            var decoder     = new InstructionDecoder(machine);
            var memory      = machine.Memory.SpanAt(machine.PC);
            var instruction = decoder.Decode(memory);

            instruction.Prepare(memory);
            instruction.Execute(memory);

            Assert.NotNull(instruction as VarInstruction);
            Assert.Equal("Call", instruction.Operation.Name);
            Assert.Equal(0, instruction.OpCode);
            Assert.Equal(0, instruction.StoreResult);
            Assert.Equal(3, instruction.Operands.Count);
            Assert.Equal(0x5479, machine.PC);

            memory      = machine.Memory.SpanAt(machine.PC);
            instruction = decoder.Decode(memory);
            instruction.Prepare(memory);
            instruction.Execute(memory);

            Assert.NotNull(instruction as VarInstruction);
            Assert.Equal("Call", instruction.Operation.Name);
            Assert.Equal(2, instruction.Operands.Count);
            Assert.Equal(3, instruction.StoreResult);
            Assert.Equal(OperandType.Variable, instruction.Operands[1].Type);
            Assert.Equal(1, instruction.Operands[1].RawValue);

            memory      = machine.Memory.SpanAt(machine.PC);
            instruction = decoder.Decode(memory);
            instruction.Prepare(memory);
            instruction.Execute(memory);

            Assert.NotNull(instruction as Op2Instruction);
            Assert.Equal("Add", instruction.Operation.Name);
            Assert.Equal(4, instruction.Size);
            Assert.Equal(2, instruction.Operands.Count);
            Assert.Equal(OperandType.Variable, instruction.Operands[0].Type);
            Assert.Equal(0x94, instruction.Operands[0].RawValue);
            Assert.Equal(OperandType.Small, instruction.Operands[1].Type);
            Assert.Equal(0xB4, instruction.Operands[1].RawValue);
            Assert.Equal(0x03, instruction.StoreResult);
        }
        public void Test3()
        {
            // Arrange
            var instruction = new Byte2(-985);

            // Act

            var decodedInstruction = InstructionDecoder.Decode(instruction);

            // Assert
            decodedInstruction.ComputationInstruction.Should().BeTrue();
            decodedInstruction.SourceMemory.Should().BeTrue();
            decodedInstruction.Operation.zx.Should().BeTrue();
            decodedInstruction.Operation.nx.Should().BeTrue();
            decodedInstruction.Operation.zy.Should().BeFalse();
            decodedInstruction.Operation.ny.Should().BeFalse();
            decodedInstruction.Operation.Function.Should().BeFalse();
            decodedInstruction.Operation.NegateOutput.Should().BeFalse();
            decodedInstruction.Destination.A.Should().BeTrue();
            decodedInstruction.Destination.D.Should().BeFalse();
            decodedInstruction.Destination.Ram.Should().BeFalse();
            decodedInstruction.Condition.GreaterThanZero.Should().BeTrue();
            decodedInstruction.Condition.EqualToZero.Should().BeTrue();
            decodedInstruction.Condition.LessThanZero.Should().BeTrue();
            decodedInstruction.w.ToInt16().Should().Be(0);
        }
        public ControlUnitOutput Do(Byte2 data, bool clock)
        {
            var decodedInstruction = InstructionDecoder.Decode(data);

            var selectedSourceMemory =
                Select16.Do(decodedInstruction.SourceMemory,
                            _memoryOutput.Ram,
                            _memoryOutput.A);

            _aluOutput =
                ArithmeticLogicUnit.Do(decodedInstruction.Operation,
                                       _memoryOutput.D,
                                       selectedSourceMemory);

            _selectedBasedOnComputationInstruction =
                Select16.Do(decodedInstruction.ComputationInstruction,
                            _aluOutput,
                            decodedInstruction.w);

            _memoryOutput = _memory.Do(decodedInstruction.Destination,
                                       _selectedBasedOnComputationInstruction,
                                       clock);

            var isCondition =
                ArithmeticLogicUnit.Evaluate(decodedInstruction.Condition,
                                             _aluOutput);

            return(new ControlUnitOutput(isCondition, _memoryOutput.A));
        }
示例#4
0
        private static TInstruction AssertBytesDecodedAs <TInstruction>(byte[] bytes) where TInstruction : IInstruction
        {
            var(instruction, bytesRead) = InstructionDecoder.Decode(bytes);

            Assert.IsType <TInstruction>(instruction);
            var loadInstruction = (TInstruction)instruction;

            //Whole message was read
            Assert.Equal(bytes.Length, bytesRead);
            return(loadInstruction);
        }
示例#5
0
        public void FourBitOpcodeRegisterAInBits7To11(int register)
        {
            var decoder = new InstructionDecoder();

            ForEachOpcode(FourBitOpcodes, opcode =>
            {
                var encodedInstruction = (ushort)(opcode | (register << 8));
                var decodedInstruction = decoder.Decode(encodedInstruction);
                decodedInstruction.RegisterA.Should().Be(register);
            });
        }
示例#6
0
        void TestOpcodeParameter(IEnumerable <Opcode> opcodes, ushort rawValue, int expectedDecodedValue)
        {
            var decoder = new InstructionDecoder();

            ForEachOpcode(opcodes, opcode =>
            {
                var encodedInstruction = (ushort)(opcode | rawValue);
                var decodedInstruction = decoder.Decode(encodedInstruction);
                decodedInstruction.Value.Should().Be(expectedDecodedValue);
            });
        }
示例#7
0
        public void EightBitOpcodeRegisterBInBits0To3(int register)
        {
            var decoder = new InstructionDecoder();

            ForEachOpcode(EightBitOpcodes, opcode =>
            {
                var encodedInstruction = (ushort)(opcode | (register << 0));
                var decodedInstruction = decoder.Decode(encodedInstruction);
                decodedInstruction.RegisterB.Should().Be(register);
            });
        }
        public void For_data_instruction_W_returns_input()
        {
            // Arrange
            var instruction = new Byte2(17);

            // Act

            var decodedInstruction = InstructionDecoder.Decode(instruction);

            // Assert
            decodedInstruction.w.ToInt16().Should().Be(17);
        }
示例#9
0
文件: Debugger.cs 项目: claassen/RIVM
        private void updateMemoryDisplay()
        {
            DataTable dt = new DataTable();

            dt.Columns.Add(new DataColumn("address", typeof(string)));
            dt.Columns.Add(new DataColumn("value", typeof(string)));
            dt.Columns.Add(new DataColumn("instruction", typeof(String)));

            int start = _memoryDisplayStartAddress;
            int end   = start + 1000;

            for (int address = start; address < end;)
            {
                if (_memoryDisplaySize == 4)
                {
                    int machineCode = _vm.cpu.Memory.Get(address, false, 4);

                    object[] firstRowData = new object[3];
                    firstRowData[0] = address;
                    firstRowData[1] = machineCode;

                    address += 4;

                    Instruction instruction = InstructionDecoder.Decode(machineCode);

                    if (instruction.HasImmediate)
                    {
                        instruction.Immediate = _vm.cpu.Memory.Get(address, false, 4);
                        address += 4;
                    }

                    firstRowData[2] = instruction.ToString();
                    dt.Rows.Add(firstRowData);

                    if (instruction.HasImmediate)
                    {
                        dt.Rows.Add(address - 4, instruction.Immediate, "[immediate value]");
                    }
                }
                else
                {
                    int value = BitHelper.ExtractBytes(_vm.cpu.Memory.Get(address, false, 1), 1);
                    dt.Rows.Add(address, value, "");
                    address++;
                }
            }

            memoryGridView.Invoke((MethodInvoker)(() =>
            {
                memoryGridView.DataSource = dt;
            }));
        }
示例#10
0
        public void Decode_Works()
        {
            var instructionDecoder = new InstructionDecoder();
            var decodedInstruction = instructionDecoder.Decode(0x12, 0x34);

            Assert.That(decodedInstruction.InstructionCode, Is.EqualTo(0x1234));
            Assert.That(decodedInstruction.nnn, Is.EqualTo(0x234));
            Assert.That(decodedInstruction.n, Is.EqualTo(0x4));
            Assert.That(decodedInstruction.x, Is.EqualTo(0x2));
            Assert.That(decodedInstruction.y, Is.EqualTo(0x3));
            Assert.That(decodedInstruction.kk, Is.EqualTo(0x34));
            Assert.That(decodedInstruction.OpCode, Is.EqualTo(0x1));
        }
示例#11
0
        public void Step()
        {
            try
            {
                int machineCode = Fetch();
                _currentInstruction = InstructionDecoder.Decode(machineCode);

                if (_currentInstruction is Break)
                {
                    _debugging = true;
                    _debuggingNotification();
                }

                if (_currentInstruction.HasImmediate)
                {
                    _currentInstruction.Immediate = Fetch();
                }

                _currentInstruction.Execute(this);

                if (Interrupts.Count > 0)
                {
                    lock (Interrupts)
                    {
                        throw new InterruptException(Interrupts.Dequeue());
                    }
                }
            }
            catch (InterruptException ex)
            {
                //Index into Interrupt Descriptor Table
                int interrupt = ex.InterruptNumber;

                KernelMode = true;

                //TODO: Need to switch to kernel stack? Should this be handled by IR common stub?

                //Similar to a call, stored the address where code should resume executing on the stack
                Memory[Registers[Register.SP]] = Registers[Register.IP];
                Registers[Register.SP]        += 4;

                //Set IP to fixed interrupt handler address
                Registers[Register.IP] = Memory[IDTPointer + interrupt * 4];
            }

            if (_stepNotification != null && _debugging)
            {
                _stepNotification();
            }
        }
示例#12
0
文件: Debugger.cs 项目: claassen/RIVM
        private Instruction getNextInstruction()
        {
            int address = _vm.cpu.Registers[Register.IP];

            int machineCode = _vm.cpu.Memory.Get(address, false, 4);

            address += 4;

            Instruction instruction = InstructionDecoder.Decode(machineCode);

            if (instruction.HasImmediate)
            {
                instruction.Immediate = _vm.cpu.Memory.Get(address, false, 4);
            }

            return(instruction);
        }
示例#13
0
        public void decode_logical_and_instruction(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.ANA, result);
        }
示例#14
0
        public void Decode_NotSupportedOpcode_ThrowOpcodeReadException(Opcode opcode)
        {
            var bytes = InstructionByteBuilder.Create().Opcode(opcode).ToArray();

            Assert.Throws <OpcodeDecodeException>(() => InstructionDecoder.Decode(bytes));
        }
示例#15
0
 public void Decode_ZeroBytesToDecode_RaiseArgumentException()
 {
     Assert.Throws <ArgumentException>(() => InstructionDecoder.Decode(Array.Empty <byte>()));
 }
示例#16
0
        public void store_accumulator_indirect_instruction(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.STAX, result);
        }
示例#17
0
        public void Run(IEnumerable <byte> program)
        {
            // Init the core
            Memory.Write(BaseAddres, program);
            Register.WriteUnsignedInt(Register.ProgramCounter, BaseAddres);
            var decoder     = new InstructionDecoder(EndianCoding);
            var typeDecoder = new TypeDecoder();

            // Create a simple bootstrap CPU
            var cpu = new Cpu64();

            cpu.AssignMemory(Memory);
            cpu.AssignRegister(Register);
            cpu.AssignEEI(Environment);
            cpu.AssignRasStack(RasStack);
            cpu.AssignCrs(CsrRegister);
            cpu.Init();

            // Fetch the first instruction and run the loop
            var pc = Register.ReadUnsignedInt(Register.ProgramCounter);

            // Get the first 2 Bytes from the Base Address aka PC
            var instructionCoding = Memory.GetHalfWord(pc);

            while (ContinueIfValid(instructionCoding))
            {
                // Loop for the commands
                var instruction = decoder.Decode(instructionCoding);
                InstructionsProcessed.Add(instruction);

                // If the decoder cannot decode the parameter pattern, throw an exception
                if (instruction.Type == InstructionType.Unknown)
                {
                    string unknownOpCodeErrorMessage = String.Format("Error:  OpCode = {0}", instruction.OpCode);
                    throw new OpCodeNotSupportedException(unknownOpCodeErrorMessage)
                          {
                              Coding = instructionCoding,
                              Type   = instruction.Type,
                              OpCode = instruction.OpCode
                          };
                }

                // Reload the other bytes if required!

                if (instruction.InstructionLength == 4)
                {
                    // Read the complete 32 Bit instruction set for the decoding

                    var inst32Coding = Memory.GetWord(pc);
                    var payload      = typeDecoder.DecodeType(instruction, inst32Coding);

                    if (payload == null)
                    {
                        throw new RiscVSimException("No Payload available!");
                    }

                    // For UnitTesting:  Add the result to the list
                    InstructionPayloads.Add(payload);


                    // Execute the command
                    cpu.Execute(instruction, payload);
                }


                // Done. Next run.
                pc = Register.ReadUnsignedInt(Register.ProgramCounter);
                instructionCoding = Memory.GetHalfWord(pc);
            }
        }
示例#18
0
        public void decode_decrement_register_pair(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.DCX, result);
        }
示例#19
0
        public void move_immediate_instruction(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.MVI, result);
        }
示例#20
0
        public void decode_double_add_instruction(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.DAD, result);
        }
示例#21
0
        public void decode_add_with_carry_instruction(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.ADC, result);
        }
示例#22
0
        public void pop_instruction(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.POP, result);
        }
示例#23
0
        public void decode_exclusive_or_instruction(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.XRA, result);
        }
示例#24
0
        public void decode_restart_instruction(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.RST, result);
        }
示例#25
0
        public void decode_increment_instruction(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.INR, result);
        }
示例#26
0
        public void decode_subtract_with_borrow_instruction(byte instruction)
        {
            var result = InstructionDecoder.Decode(instruction);

            Assert.Equal(InstructionMnemonic.SBB, result);
        }
示例#27
0
        /// <summary>
        /// The generic fetch method for all hart implementations
        /// </summary>
        private void Fetch()
        {
            // Done!
            // Fetch the first instruction and run the loop. Get the first 2 Bytes from the Base Address aka PC
            var pc = register.ReadUnsignedInt(register.ProgramCounter);
            var instructionCoding = memory.GetHalfWord(pc);

            Logger.Info("Instruction {ins:X} fetched", BitConverter.ToString(instructionCoding.ToArray()));

            while (ContinueIfValid(instructionCoding))
            {
                // Loop for the commands
                var instruction = instructionDecoder.Decode(instructionCoding);

                if (rvMode)
                {
                    var isCustom = (instructionCoding.First() & 0x7F) == 0x00;
                    if (isCustom)
                    {
                        Logger.Info("Processing RV custom command.");
                        var customCoding = memory.GetWord(pc);

                        var isHalt = customCoding.SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00 });
                        if (isHalt)
                        {
                            // Stop the simulation!
                            break;
                        }


                        var payload = typeDecoder.DecodeCustom(instruction, customCoding);

                        var rvOpcode = new RvOpcode(memory, register, environment);
                        var inc      = rvOpcode.Execute(instruction, payload);

                        if (inc)
                        {
                            // Go to the next instruction...
                            register.NextInstruction(4);
                        }
                    }
                    else
                    {
                        // Handle instruction as usual..
                        HandleCompliantMode(pc, instructionCoding, instruction);
                    }
                }
                else
                {
                    HandleCompliantMode(pc, instructionCoding, instruction);
                }

                // Stop the instruction fetch if an error occured or the state is stopped
                var currentState = environment.GetCurrentState();
                if (currentState == State.FatalError || currentState == State.Stopped)
                {
                    break;
                }

                // Done. Next run.
                pc = register.ReadUnsignedInt(register.ProgramCounter);
                instructionCoding = memory.GetHalfWord(pc);
                Logger.Info("Instruction {ins:X} fetched", BitConverter.ToString(instructionCoding.ToArray()));
            }

            if (environment.GetCurrentState() == State.FatalError)
            {
                Console.Error.WriteLine("# FATAL ERROR occured : " + environment.GetStateDescription());
            }

            if (environment.GetCurrentState() == State.Stopped)
            {
                Console.Out.WriteLine("# Hart Stopped");
            }

            environment.NotifyStopped();
        }