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); } }
public RegisterFile PopWide(RegisterFile registerFile, out ushort value) { registerFile = Pop(registerFile, out var h); registerFile = Pop(registerFile, out var l); value = (ushort)(h | (l << 8)); return(registerFile); }
public RegisterFile Pop(RegisterFile registerFile, out byte value) { if (registerFile.StackPointer >= TopOfStack) { throw new StackUnderflowException(); } value = Memory.Load(registerFile.StackPointer); return(registerFile.WithStackPointer(sp => (ushort)(sp + 1))); }
public RegisterFile PushWide(RegisterFile registerFile, ushort value) { registerFile = Push(registerFile, (byte)(value >> 8)); return(Push(registerFile, (byte)(value & 0xFF))); }
public RegisterFile Push(RegisterFile registerFile, byte value) { Memory.Store(registerFile.StackPointer, value); return(registerFile.WithStackPointer(sp => (ushort)(sp - 1))); }
object MapParameter(ParameterInfo parameterInfo, Instruction instruction, RegisterFile registerFile, object[] arguments) { if (parameterInfo.ParameterType == typeof(Instruction)) { return(instruction); } if (parameterInfo.ParameterType == typeof(RegisterFile)) { return(registerFile); } if (parameterInfo.ParameterType == typeof(MemoryBus)) { return(MemoryBus); } if (parameterInfo.ParameterType == typeof(Flash)) { return(ProgramMemory); } if (parameterInfo.ParameterType == typeof(Stack)) { return(Stack); } if (parameterInfo.ParameterType == typeof(object[])) { return(arguments); } if (parameterInfo.Name.Length == 1) { char name = parameterInfo.Name[0]; if (!instruction.Values.ContainsKey(name)) { throw new ArgumentException($"Instruction does not contain parameter {name}."); } if (parameterInfo.ParameterType == typeof(ushort)) { return((ushort)instruction[name]); } if (parameterInfo.ParameterType == typeof(uint)) { return((uint)instruction[name]); } if (parameterInfo.ParameterType == typeof(byte)) { return((byte)instruction[name]); } if (parameterInfo.ParameterType == typeof(short)) { return((short)instruction[name]); } if (parameterInfo.ParameterType == typeof(int)) { return((int)instruction[name]); } if (parameterInfo.ParameterType == typeof(sbyte)) { return((sbyte)instruction[name]); } } throw new ArgumentException($"Unable to map parameter {parameterInfo.Name}"); }