public void Load(Computer computer, Program program) { // skip entry point stuff // Load the code segment into memory. for (int i = 0; i < program.codeSegment.Item1.Count; i++) { // stack (grows downwards to data/code). computer.memory.virtualAddressSpace[i].value = program.codeSegment.Item1[i]; computer.memory.virtualAddressSpace[i].asmLine = program.codeSegment.Item2[i]; } int nextLoadPoint = program.codeSegment.Item1.Count; // 8-byte stack reservation. // Load the data segment into memory. //todo - doesn't work at mo, because it needs to minus the nextLoadPoint, not add it, perhaps, in memory? /*for (int i = 0; i < program.dataSegment.Count; i++) { computer.memory.virtualAddressSpace[i + nextLoadPoint].value = program.dataSegment[i]; }*/ nextLoadPoint += program.dataSegment.Count; // Set IP (instruction pointer) to entry point. computer.cPU.GetRegisters().SetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0, Helper.GetHelper().PadWithBytes((byte)(program.entryPoint), 4)); }
public X86InstructionSet(Computer parentComputer) { this.parentComputer = parentComputer; // * Opcodes. * this.opcodes = new Dictionary<string, string>(); this.opcodes.Add("_184", "MOV EAX, "); this.opcodes.Add("_232", "CALL "); this.opcodes.Add("_40", "INC EAX"); this.opcodes.Add("_50", "PUSH EAX"); this.opcodes.Add("_58", "POP EAX"); this.opcodes.Add("_195", "RET"); this.opcodes.Add("_106", "PUSH "); this.opcodes.Add("_233", "JMP "); this.opcodes.Add("_89", "MOV "); }
public void ExecuteOpcode(Computer computer, byte opcode) { // Do your reflective invocation thing here... Type reflectionType = typeof(X86InstructionSet); // Turn 32-bit instruction opcode into instruction opcode. // Prep for 'reflective invoke' :-). int line = computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; string methodName = "_" + computer.memory.virtualAddressSpace[line].value;//Encoding.ASCII.GetString(this.operands[0].value).Trim(new char[] { '\0' }); // Remove empty character bytes from opcode. MethodInfo info = reflectionType.GetMethod(methodName); ParameterInfo[] parameterInfos = info.GetParameters(); if (parameterInfos.Length > 0) { byte[] parameters = new byte[0]; Array.Resize(ref parameters, parameters.Count() + 1); parameters[parameters.Count() - 1] = computer.memory.virtualAddressSpace[line + 1].value; // Next byte is opcode's needed parameter. IInstructionSet instructions = new X86InstructionSet(computer); // todo <-- horrible hack creating a new instruction set on the fly, here... //computer.cPU.instructionSet; info.Invoke(instructions, new object[] { parameters }); // Turn byte array into object array with single byte array element. } else { IInstructionSet instructions = new X86InstructionSet(computer); // todo horrible hack creating a new instruction set on the fly, here... //computer.cPU.instructionSet; info.Invoke(instructions, null); // Turn byte array into object array with single byte array element. } }
public Program CreateProgram(Computer computer, List<string> listing) { // Fingers on the Spectrum cassette player... // 1. Execute interpreter on listing. Interpreter interpreter = new Interpreter(); return interpreter.Interpret(listing); }
//public int line { get; set; } public void Step(Computer computer) { // Run the program. //for (i = 0; i < computer.memory.virtualAddressSpace.Count; i++) //{ //ExecuteOpcode(computer, computer.memory.virtualAddressSpace[line]); int castedIP = computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; ExecuteOpcode(computer, computer.memory.virtualAddressSpace[castedIP].value); //this.line += ToSkip(computer.memory.virtualAddressSpace[castedIP]); // Get next opcode to instruction ready to read. // todo - Horrible hack to re-get the IP if it may have been changed by an instruction such as RET. castedIP = computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; X86InstructionSet instructions = new X86InstructionSet(computer); // todo Remove, as only instantiated for the ToSkip() call below. int toSkip = instructions.ToSkip(computer.memory.virtualAddressSpace[castedIP].value); int toSkip2 = toSkip + computer.cPU.GetRegisters().GetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0)[0]; computer.cPU.GetRegisters().SetRegister((int)(X86Registers.RegisterPointers.INSTRUCTION_POINTER), 0, Helper.GetHelper().PadWithBytes((byte)(toSkip2), 4)); // Get next opcode to instruction ready to read. }
// * Constructor * public X86CPU(Computer computer) { this.x86InstructionSet = new X86InstructionSet(computer); this.x86Registers = new X86Registers(); }
public void PrepareProgram(Computer computer, Program program) { // 2. Execute loader on source. loader.Load(computer, program); }