public void Run() { RegisterFile = new RegisterFile(new byte[32], new StatusRegister(), 0, (ushort)(Stack.TopOfStack - 1)); while (true) { var currentProgramCounter = RegisterFile.ProgramCounter; ushort instructionWord = ProgramMemory.GetInstruction(RegisterFile.ProgramCounter); if (!OpcodeDecoder.TryDecode(instructionWord, out var instruction)) { RegisterFile = RegisterFile.WithProgramCounter(p => p + 1); ushort nextInstructionWord = ProgramMemory.GetInstruction(RegisterFile.ProgramCounter); instruction = OpcodeDecoder.DecodeWide(instructionWord, nextInstructionWord); } instruction.Address = (ushort)currentProgramCounter; Console.Error.WriteLine($"{instruction.Address * 2:X4}: {BitConverter.ToString(instruction.Bytes).Replace('-',' '),-12} {instruction.Opcode,-5} "); ExecuteInstruction(instruction); Console.Error.WriteLine($" {RegisterFile}"); RegisterFile = RegisterFile.WithProgramCounter(p => p + 1); } }
Core() { var methods = Assembly.GetExecutingAssembly().GetTypes() .SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public)) .SelectMany(m => m.GetCustomAttributes(typeof(InstructionHandlerAttribute), false), (m, a) => new { MethodInfo = m, InstructionHandlerAttribute = (InstructionHandlerAttribute)a }); List <Handler> Instructions = new List <Handler>(); foreach (var method in methods) { var name = method.MethodInfo.Name + (method.InstructionHandlerAttribute.Arguments.Length == 0 ? string.Empty : ("_" + string.Join("-", method.InstructionHandlerAttribute.Arguments))); if (method.MethodInfo.ReturnType != typeof(RegisterFile)) { throw new Exception($"Method should return a {typeof(RegisterFile)}"); } Instructions.Add(new Handler { Name = name, MethodInfo = method.MethodInfo }); OpcodeDecoder.AddDecoder(name, method.InstructionHandlerAttribute.Pattern); InstructionHandlers.Add(name, (instruction, registerFile) => { //var handler = Instructions.Single(h => ); var methodInfo = method.MethodInfo; var parameters = methodInfo.GetParameters().Select(p => MapParameter(p, instruction, registerFile, method.InstructionHandlerAttribute.Arguments)).ToArray(); try { if (methodInfo.IsStatic) { return((RegisterFile)methodInfo.Invoke(null, parameters)); } else { return((RegisterFile)methodInfo.Invoke(this, parameters)); } } catch (TargetInvocationException exception) { ExceptionDispatchInfo.Capture(exception.InnerException).Throw(); throw; } }); } }