예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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)));
        }
예제 #4
0
 public RegisterFile PushWide(RegisterFile registerFile, ushort value)
 {
     registerFile = Push(registerFile, (byte)(value >> 8));
     return(Push(registerFile, (byte)(value & 0xFF)));
 }
예제 #5
0
 public RegisterFile Push(RegisterFile registerFile, byte value)
 {
     Memory.Store(registerFile.StackPointer, value);
     return(registerFile.WithStackPointer(sp => (ushort)(sp - 1)));
 }
예제 #6
0
        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}");
        }