/// <summary> /// Sets address and data for this addressing mode. /// </summary> /// <param name="ir"> /// Binary code of the instruction represented with InstructionRegister object. /// </param> /// <param name="constants"> /// Constants representing current architecture. /// </param> /// <param name="variables"> /// User variables. /// </param> /// <param name="startBit"> /// Start bit of the operand in instruction code. /// </param> /// <param name="endBit"> /// End bit of the operand in instruction code. /// </param> /// <param name="data"> /// Data to be set. /// </param> public void SetData(InstructionRegister ir, CPU cpu, Variables variables, int startBit, int endBit, int data) { var t = results.CompiledAssembly.GetType("DynamicClass" + name); object[] parameters = new object[] { ir, Program.Mem, cpu, variables, startBit, endBit, data }; t.GetMethod("setAddrData_" + this.name).Invoke(null, parameters); }
/// <summary> /// Gets address and data for this addressing mode. /// </summary> /// <param name="ir"> /// Binary code of the instruction represented with InstructionRegister object. /// </param> /// <param name="constants"> /// Constants representing current architecture. /// </param> /// <param name="variables"> /// User variables. /// </param> /// <param name="startBit"> /// Start bit of the operand in instruction code. /// </param> /// <param name="endBit"> /// End bit of the operand in instruction code. /// </param> /// <returns> /// Wanted data. /// </returns> public int GetData(InstructionRegister ir, CPU cpu, Variables variables, int startBit, int endBit) { var t = results.CompiledAssembly.GetType("DynamicClass" + name); int result = 0; object[] parameters = new object[] { ir, Program.Mem, cpu, variables, startBit, endBit, result }; t.GetMethod("getAddrData_" + this.name).Invoke(null, parameters); result = (int)(parameters[6]); return(result); }
/// <summary> /// Execution of instruction. /// </summary> /// <param name="ir"> /// Binary code of the instruction represented as InstructionRegister object. /// </param> /// <param name="constants"> /// Constants for current architecture. /// </param> /// <param name="variables"> /// User variables. /// </param> /// <param name="operands"> /// Operands needed for operation. /// </param> /// <returns> /// Result of instruction execution. /// </returns> public int[] Execute(InstructionRegister ir, CPU cpu, Variables variables, int[] operands) { int[] result = null; var t = results.CompiledAssembly.GetType("DynamicClass" + name); object[] parameters = new object[] { ir, Program.Mem, cpu, variables, operands, result }; t.GetMethod("execute_" + this.mnemonic.ToLower()).Invoke(null, parameters); result = (int[])(parameters[5]); return(result); }
/// <summary> /// Stores result of the execution. /// </summary> /// <param name="ir"> /// Binary code of the instruction represented with InstructionRegister object. /// </param> /// <param name="constants"> /// Architecture constants. /// </param> /// <param name="variables"> /// User variables. /// </param> /// <param name="dataToStore"> /// Result of the instruction execution. /// </param> public void StoreResult(InstructionRegister ir, CPU cpu, Variables variables, int[] dataToStore) { int argCount = 0; foreach (Argument arg in arguments) { if (arg.Type.ToLower().Equals("dst")) { arg.SelectedAddressingMode.SetData(ir, cpu, variables, arg.OperandStarts[arg.SelectedAddressingMode.Name], arg.OperandEnds[arg.SelectedAddressingMode.Name], dataToStore[argCount++]); } } }
/// <summary> /// Fetches operands for all arguments that are declared as src. /// </summary> /// <param name="ir"> /// Binary code of the instruction represented with InstructionRegister object. /// </param> /// <param name="constants"> /// Architecture constants of the curent architecture. /// </param> /// <param name="variables"> /// User variables. /// </param> /// <returns> /// Array containing fetched operands. /// </returns> public int[] FetchOperands(InstructionRegister ir, CPU cpu, Variables variables) { LinkedList <int> operands = new LinkedList <int>(); foreach (Argument arg in arguments) { if (arg.Type.ToLower().Equals("src")) { int result = arg.SelectedAddressingMode.GetData(ir, cpu, variables, arg.OperandStarts[arg.SelectedAddressingMode.Name], arg.OperandEnds[arg.SelectedAddressingMode.Name]); operands.AddLast(result); } } return(operands.ToArray()); }
/// <summary> /// Executes binary code step by step. /// </summary> private void executeStepByStep() { LinkedList <byte> instructionCode = new LinkedList <byte>(); Thread.BeginCriticalRegion(); executing = true; next = 0; Thread.EndCriticalRegion(); Stopwatch sw = new Stopwatch(); sw.Start(); try { vars = new Variables(); vars.SetVariable("working", true); while (true) { lock (Form1.LockObject) { int pc = cpu.Constants.GetRegister("pc").Val; Console.WriteLine("Executing pc = " + pc); if (separators.Contains(pc - entryPoint) && pc != entryPoint) { Thread.BeginCriticalRegion(); bool temp = stepByStepMode; Thread.EndCriticalRegion(); // TODO Check for step by step mode if (separators.Contains(pc - entryPoint)) { for (int i = 0; i < separators.Count - 1; i++) { if (separators.ElementAt(i) == pc - entryPoint) { Thread.BeginCriticalRegion(); next = i; Thread.EndCriticalRegion(); } } } Instruction inst = cpu.Constants.MatchInstruction(instructionCode.ToArray()); InstructionRegister ir = new InstructionRegister(instructionCode.ToArray()); inst.ReadAddressingModes(binary.ToArray()); int[] operands = inst.FetchOperands(ir, cpu, vars); int[] result = inst.Execute(ir, cpu, vars, operands); inst.StoreResult(ir, cpu, vars, result); instructionCode.Clear(); cpu.CheckForInterupts(vars); pc = cpu.Constants.GetRegister("pc").Val; for (int i = 0; i < separators.Count - 1; i++) { if (separators.ElementAt(i) == pc - entryPoint) { Thread.BeginCriticalRegion(); next = i; Thread.EndCriticalRegion(); } } if (pc - entryPoint >= binary.Count() || (bool)vars.GetVariable("working") == false) // First condition might not work for addressing word larger than 1 { Thread.BeginCriticalRegion(); executing = false; Thread.EndCriticalRegion(); //instSem.Release(1); Thread.Yield(); break; } //Thread.BeginCriticalRegion(); //temp = stepByStepMode; //Thread.EndCriticalRegion(); //if (temp == true) //{ // //instSem.Release(1); // Thread.Yield(); //} } //byte[] readFromMemory = Program.Mem[(uint)pc]; Form1.Instance.InstructionReached(next); if ((stepByStepMode || breakPoints.Contains(next)) && separators.Contains(pc - entryPoint)) { //breakSem.WaitOne(); system.Running = false; } byte[] readFromMemory = cpu.ReadFromMemory((uint)pc); Console.WriteLine("Read from memory {0}", ConversionHelper.ConvertFromByteArrayToInt(readFromMemory)); pc++; for (int k = 0; k < readFromMemory.Length; k++) { instructionCode.AddLast(readFromMemory[k]); } //binary.AddLast(binaryCode[pc++]); cpu.Constants.GetRegister("pc").Val = pc; Thread.EndCriticalRegion(); } } //breakSem.Release(); system.EndWorking(); writeToOutput(" Code executed successfully.\n"); Form1.Instance.ExecutionStoped(); sw.Stop(); Console.WriteLine("Execution time: {0} ms.", sw.ElapsedMilliseconds); } catch (System.Reflection.TargetInvocationException ex) { writeToOutput(DateTime.Now + " Execution error: " + ex.InnerException.Message + " in " + ex.InnerException.TargetSite + "\n"); File.AppendAllText("error.txt", ex.ToString()); //instSem.Release(1); //breakSem.Release(1); StopDebugging(); system.EndWorking(); endExecution(); } catch (Exception ex) { writeToOutput(DateTime.Now + " Execution error: " + ex.Message + "\n"); File.AppendAllText("error.txt", ex.ToString()); //instSem.Release(1); //breakSem.Release(1); StopDebugging(); system.EndWorking(); endExecution(); } }
/// <summary> /// Method that executes binary code. /// </summary> public void Execute() { try { cpu.Constants.GetRegister("pc").Val = entryPoint; LinkedList <Instruction> instructions = new LinkedList <Instruction>(); LinkedList <byte> binary = new LinkedList <byte>(); Thread.BeginCriticalRegion(); executing = true; Thread.EndCriticalRegion(); Variables vars = new Variables(); vars.SetVariable("working", true); while (true) { int pc = cpu.Constants.GetRegister("pc").Val; cpu.CheckForInterupts(vars); if (separators.Contains(pc) && pc != entryPoint) { Instruction inst = cpu.Constants.MatchInstruction(binary.ToArray()); InstructionRegister ir = new InstructionRegister(binary.ToArray()); inst.ReadAddressingModes(binary.ToArray()); int[] operands = inst.FetchOperands(ir, cpu, vars); int[] result = inst.Execute(ir, cpu, vars, operands); inst.StoreResult(ir, cpu, vars, result); binary.Clear(); pc = cpu.Constants.GetRegister("pc").Val; } if (pc - entryPoint >= binary.Count() || (bool)vars.GetVariable("working") == false) { Thread.BeginCriticalRegion(); executing = false; Thread.EndCriticalRegion(); break; } //binary.AddLast(binaryCode[pc++]); //byte[] nextWord = Program.Mem[(uint)pc]; byte[] nextWord = cpu.ReadFromMemory((uint)pc); for (int i = 0; i < nextWord.Length; i++) { binary.AddLast(nextWord[i]); } pc++; cpu.Constants.GetRegister("pc").Val = pc; } system.EndWorking(); output.Text += DateTime.Now.ToString() + " Code executed successfully.\n"; output.ScrollToCaret(); } catch (System.Reflection.TargetInvocationException ex) { writeToOutput(DateTime.Now + " Execution error: " + ex.InnerException.Message + " in " + ex.InnerException.TargetSite + "\n"); File.AppendAllText("error.txt", ex.ToString()); StopDebugging(); system.EndWorking(); endExecution(); } catch (Exception ex) { writeToOutput(DateTime.Now + " Execution error: " + ex.Message + "\n"); File.AppendAllText("error.txt", ex.ToString()); StopDebugging(); system.EndWorking(); endExecution(); } }