Beispiel #1
0
        public static void Emulator(Configuration configuration, IEnumerable <UrclInstruction> instructions, Action <string> output, Action wait, bool allowConsole)
        {
            instructions = instructions.Append(new UrclInstruction(Operation.HLT));

            var machine = new UrclMachine(1, configuration.Registers, configuration.AvailableMemory, configuration.AvailableROM, configuration.ExecuteOnROM, configuration.WordBitMask, allowConsole ? new ConsoleIO() : null);

            if (configuration.ExecuteOnROM)
            {
                machine.LoadROM(0, instructions);
            }
            else
            {
                machine.LoadRAM(0, instructions);
            }

            var start     = Environment.TickCount64;
            var timeLimit = (long)configuration.MaxTime + start;
            var fault     = false;

            while (!machine.Halted && (configuration.StepThrough || timeLimit - Environment.TickCount64 > 0))
            {
                try
                {
                    var brk = machine.Clock();

                    if ((brk && !configuration.DisableBreak) || configuration.StepThrough)
                    {
                        if (!configuration.StepThrough)
                        {
                            output("Breakpoint hit! System suspended.");
                            output("Dumping machine state...");
                        }

                        RenderMachineState(machine, configuration.StepThrough, output);

                        output("Press any key to continue...");
                        wait?.Invoke();
                    }
                }
                catch (UrclMachine.InvalidOperationException ex)
                {
                    output($"Fault! {ex.Message}");
                    fault = true;
                    break;
                }
            }

            if (!machine.Halted && !fault)
            {
                output("Maximum time for execution was exceeded!");
            }

            output($"System halted. Execution finished in {Environment.TickCount64 - start}ms ({machine.Ticks} ticks).");
            output("Dumping final machine state...");

            RenderMachineState(machine, true, output);
        }
Beispiel #2
0
        private static void RenderMachineState(UrclMachine machine, bool allCores, Action <string> output)
        {
            output($"Cores: {machine.Cores.LongLength}, Word Mask: 0x{machine.BitMask:X}, RAM: {machine.RAM.LongLength} words, ROM: {machine.ROM.LongLength} words");
            output($"Current Core: {machine.CurrentCore}");

            if (allCores)
            {
                ulong i = 0;
                foreach (var core in machine.Cores)
                {
                    RenderCoreState(i, core, output);
                    i++;
                }
            }
            else
            {
                RenderCoreState(machine.CurrentCore, machine.Cores[machine.CurrentCore], output);
            }
        }
Beispiel #3
0
 public Core(UrclMachine host, bool executeFromROM, ulong registers)
 {
     Host           = host;
     ExecuteFromROM = executeFromROM;
     Registers      = new ulong[registers];
 }
Beispiel #4
0
 public InvalidOperationException(UrclMachine machine, string message) : base(message)
 {
     MachineState = machine;
 }
Beispiel #5
0
        public static void Emulator(Configuration configuration, IEnumerable <UrclInstruction> instructions, Action <string> output, Action wait, bool allowConsole)
        {
            ulong startAddress = 0;
            var   wordSize     = configuration.WordSize;

            instructions = instructions.Select(inst =>
            {
                if (inst.Operation == Operation.BITS)
                {
                    if (inst.A > 0 && inst.A <= configuration.WordSize)
                    {
                        wordSize = (ushort)inst.A;
                    }
                }
                else if (inst.Operation == Operation.COMPILER_PRAGMA && inst.Arguments != null)
                {
                    if (inst.Arguments.Length == 2)
                    {
                        var operand = inst.Arguments[1].ToLower();

                        switch (inst.Arguments[0].ToLower())
                        {
                        case "org":
                            if (Parser.TryParseValue(operand, out ulong v))
                            {
                                startAddress = v;
                            }
                            else
                            {
                                throw new ParserError($"ORG pragma is not valid with parameter \"{operand}\".");
                            }
                            break;
                        }
                    }
                }

                return(inst);
            }).Where(inst => inst.Operation != Operation.BITS).Append(new UrclInstruction(Operation.HLT)).ToArray();

            var machine = new UrclMachine(1, configuration.Registers, configuration.MaxStack, configuration.AvailableMemory, configuration.AvailableROM, configuration.ExecuteOnROM, Configuration.GetBitMask(wordSize), allowConsole ? new ConsoleIO() : null);

            if (configuration.ExecuteOnROM)
            {
                machine.LoadROM(startAddress, instructions);
            }
            else
            {
                machine.LoadRAM(startAddress, instructions);
            }

            var start     = Environment.TickCount64;
            var timeLimit = (long)configuration.MaxTime + start;
            var fault     = false;

            while (!machine.Halted && (configuration.StepThrough || timeLimit - Environment.TickCount64 > 0))
            {
                try
                {
                    var brk = machine.Clock();

                    if ((brk && !configuration.DisableBreak) || configuration.StepThrough)
                    {
                        output(string.Empty);

                        if (!configuration.StepThrough)
                        {
                            output("Breakpoint hit! System suspended.");
                            output("Dumping machine state...");
                        }

                        RenderMachineState(machine, configuration.StepThrough, output);

                        output("Press any key to continue...");
                        wait?.Invoke();
                    }
                }
                catch (UrclMachine.InvalidOperationException ex)
                {
                    output(string.Empty);
                    output($"***Fault! {ex.Message}***");
                    fault = true;
                    break;
                }
            }

            output(string.Empty);

            if (!machine.Halted && !fault)
            {
                output("Maximum time for execution was exceeded!");
            }

            output($"System halted. Execution finished in {Environment.TickCount64 - start}ms ({machine.Ticks} ticks).");
            output("Dumping final machine state...");

            RenderMachineState(machine, true, output);
        }