private void DisassemblyDisplay_Paint(object sender, PaintEventArgs e)
        {
            Font font = new Font(FontFamily.GenericMonospace, 12);

            e.Graphics.FillRectangle(Brushes.White, this.ClientRectangle);
            if (this.DesignMode)
            {
                e.Graphics.DrawRectangle(Pens.Black, new Rectangle(0, 0, this.Width - 1, this.Height - 1));
                return;
            }

            FastDisassembler disassembler = new FastDisassembler(Debugger.KnownLabels);
            Disassembly = disassembler.FastDisassemble(ref CPU.Memory, SelectedAddress, (ushort)(SelectedAddress + 100));

            int index = 0;
            bool setLast = false, dark = SelectedAddress % 2 == 0;

            Size baseFontSize = TextRenderer.MeasureText("0000", font);
            Size addressFontSize;

            for (int y = 0; y < this.Height; y += baseFontSize.Height + 2)
            {
                string address = Debugger.GetHexString(Disassembly[index].Address, 4) + ": ";
                addressFontSize = TextRenderer.MeasureText(address, font);
                Brush foreground = Brushes.Black;
                if (dark)
                    e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(255, 230, 230, 230)), new Rectangle(0, y, this.Width, addressFontSize.Height + 2));
                dark = !dark;

                int breakPointCount = CPU.Breakpoints.Where(b => b.Address == Disassembly[index].Address).Count();

                if (breakPointCount != 0)
                {
                    e.Graphics.FillRectangle(Brushes.DarkRed, new Rectangle(0, y, this.Width, addressFontSize.Height + 2));
                    foreground = Brushes.White;
                }
                if (Disassembly[index].Address == CPU.PC)
                {
                    if (breakPointCount != 0)
                    {
                        if (Disassembly[index].IsLabel)
                            e.Graphics.FillRectangle(Brushes.Yellow, new Rectangle(0, y + 2, this.Width, addressFontSize.Height));
                        else
                        {
                            if (index != 0)
                            {
                                if (Disassembly[index - 1].IsLabel)
                                    e.Graphics.FillRectangle(Brushes.Yellow, new Rectangle(0, y, this.Width, addressFontSize.Height));
                                else
                                    e.Graphics.FillRectangle(Brushes.Yellow, new Rectangle(0, y + 2, this.Width, addressFontSize.Height - 2));
                            }
                            else
                                e.Graphics.FillRectangle(Brushes.Yellow, new Rectangle(0, y + 2, this.Width, addressFontSize.Height - 2));
                        }
                    }
                    else
                        e.Graphics.FillRectangle(Brushes.Yellow, new Rectangle(0, y, this.Width, addressFontSize.Height + 2));
                    foreground = Brushes.Black;
                }

                e.Graphics.DrawString(address, font, Brushes.Gray, 2, y);

                if (!Debugger.KnownCode.ContainsKey(Disassembly[index].Address) || Disassembly[index].IsLabel)
                    e.Graphics.DrawString(Disassembly[index].Code, font, foreground, 2 + addressFontSize.Width + 3, y);
                else
                    e.Graphics.DrawString(Debugger.KnownCode[Disassembly[index].Address], font, foreground,
                        2 + addressFontSize.Width + 3, y );

                if(y + addressFontSize.Height > this.Height)
                {
                    setLast = true;
                    EndAddress = Disassembly[index].Address;
                }

                index++;
            }
            if (!setLast)
                EndAddress = Disassembly[index--].Address;
            index = 0;
            if (IsMouseWithin && !CPU.IsRunning) // TODO: Make this more versatile, probably integrate with organic
            {
                int x = MouseLocation.X;
                for( int y = 0; y < this.Height; y += baseFontSize.Height + 2 )
                {
                    if (Disassembly[index].IsLabel || Disassembly[index].Code.StartsWith("DAT"))
                    {
                        index++;
                        continue;
                    }
                    Size size = TextRenderer.MeasureText("0000: " + Disassembly[index].Code, font);
                    size.Width += 5;
                    if (new Rectangle(new Point(0, y), size).IntersectsWith(
                        new Rectangle(new Point(x, MouseLocation.Y), new Size(1, 1))))
                    {
                        ushort oldPC = CPU.PC;
                        ushort oldSP = CPU.SP;
                        CPU.PC = (ushort)(Disassembly[index].Address + 1);
                        int valueA = 0, valueB = 0;
                        ushort valueAcalc = CPU.Get(Disassembly[index].ValueA);
                        ushort valueBcalc = CPU.Get(Disassembly[index].ValueB);
                        if (Disassembly[index].Opcode == 0)
                        {
                            valueB = int.MaxValue;
                            valueA = TextRenderer.MeasureText("0000: " + Disassembly[index].OpcodeText + " ", font).Width + 4;
                        }
                        else
                        {
                            valueB = TextRenderer.MeasureText("0000: " + Disassembly[index].OpcodeText + " ", font).Width + 4;
                            valueA = valueB + TextRenderer.MeasureText(Disassembly[index].ValueBText + ", ", font).Width - 8;
                        }
                        if (x >= valueB && x <= valueA)
                        {
                            // hovering over value B
                            if (Disassembly[index].ValueB <= 0x1E)
                            {
                                e.Graphics.FillRectangle(Brushes.LightBlue, new Rectangle(new Point(valueB, y),
                                    TextRenderer.MeasureText(Disassembly[index].ValueBText, font)));
                                e.Graphics.DrawString(Disassembly[index].ValueBText, font, Brushes.Black, new PointF(valueB, y));
                                int locationY = y + size.Height;
                                if (this.Height / 2 < y)
                                    locationY = y - size.Height;
                                string text = Disassembly[index].ValueBText + " = 0x" + Debugger.GetHexString(valueBcalc, 4);
                                Size hoverSize = TextRenderer.MeasureText(text, font);
                                e.Graphics.FillRectangle(Brushes.LightBlue, new Rectangle(new Point(
                                    (valueB + (TextRenderer.MeasureText(Disassembly[index].ValueBText, font).Width / 2)) -
                                    (hoverSize.Width / 2), locationY), hoverSize));
                                e.Graphics.DrawString(text, font, Brushes.Black, new Point(
                                    (valueB + (TextRenderer.MeasureText(Disassembly[index].ValueBText, font).Width / 2)) -
                                    (hoverSize.Width / 2), locationY));
                            }
                        }
                        else if (x >= valueA)
                        {
                            // hovering over value A
                            if (Disassembly[index].ValueA <= 0x1E)
                            {
                                e.Graphics.FillRectangle(Brushes.LightBlue, new Rectangle(new Point(valueA, y),
                                    TextRenderer.MeasureText(Disassembly[index].ValueAText, font)));
                                e.Graphics.DrawString(Disassembly[index].ValueAText, font, Brushes.Black, new PointF(valueA, y));
                                int locationY = y + size.Height;
                                if (this.Height / 2 < y)
                                    locationY = y - size.Height;
                                string text = Disassembly[index].ValueAText + " = 0x" + Debugger.GetHexString(valueAcalc, 4);
                                Size hoverSize = TextRenderer.MeasureText(text, font);
                                e.Graphics.FillRectangle(Brushes.LightBlue, new Rectangle(new Point(
                                    (valueA + (TextRenderer.MeasureText(Disassembly[index].ValueAText, font).Width / 2)) -
                                    (hoverSize.Width / 2), locationY), hoverSize));
                                e.Graphics.DrawString(text, font, Brushes.Black, new Point(
                                    (valueA + (TextRenderer.MeasureText(Disassembly[index].ValueAText, font).Width / 2)) -
                                    (hoverSize.Width / 2), locationY));
                            }
                        }
                        CPU.PC = oldPC;
                        CPU.SP = oldSP;
                        break;
                    }
                    index++;
                }
            }
            e.Graphics.DrawRectangle(Pens.Black, new Rectangle(0, 0, this.Width - 1 - vScrollBar.Width, this.Height - 1));
        }
Exemple #2
0
        private static void ParseInput(string originalInput)
        {
            string input = originalInput.ToLower().Trim();
            string[] parameters = input.Split(' ');

            if (input == "clear")
                Console.Clear();
            else if (input.StartsWith("bind "))
            {
                string[] parts = input.Split(' ');
                Shortcuts.Add(parts[1].ToLower(), input.Substring(5 + parts[1].Length));
            }
            else if (input.StartsWith("flash "))
            {
                bool littleEndian = false;
                string file;
                if (parameters.Length == 2)
                    file = parameters[1];
                else if (parameters.Length == 3)
                {
                    file = parameters[2];
                    littleEndian = parameters[1].ToLower() == "little";
                }
                else
                    return;
                List<ushort> data = new List<ushort>();
                using (Stream stream = File.OpenRead(file))
                {
                    for (int i = 0; i < stream.Length; i += 2)
                    {
                        byte a = (byte)stream.ReadByte();
                        byte b = (byte)stream.ReadByte();
                        if (littleEndian)
                            data.Add((ushort)(a | (b << 8)));
                        else
                            data.Add((ushort)(b | (a << 8)));
                    }
                }
                CPU.FlashMemory(data.ToArray());
            }
            else if (input.StartsWith("connect "))
                ConnectDevice(input.Substring(8));
            else if (input == "start")
                CPU.IsRunning = true;
            else if (input == "stop")
                CPU.IsRunning = false;
            else if (input.StartsWith("step"))
            {
                if (CPU.IsRunning)
                {
                    Console.WriteLine("CPU is still running; use \"stop\" first.");
                    return;
                }
                string[] parts = input.Split(' ');
                if (parts.Length > 1)
                {
                    if (parts[1] == "into" || parts[1] == "once")
                        CPU.Execute(-1);
                    else if (parts[1] == "over")
                    {
                    }
                    else
                    {
                        int i = int.Parse(parts[1]);
                        while (i > 0)
                        {
                            CPU.Execute(-1);
                            i--;
                        }
                    }
                }
                else
                    CPU.Execute(-1);
            }
            else if (input.StartsWith("dump "))
            {
                string[] parts = input.Substring(5).Split(' ');
                if (parts[0] == "screen")
                {
                    if (parts.Length > 1)
                    {
                        int index = int.Parse(parts[1]);
                        if (CPU.Devices[index] is LEM1802)
                            DrawScreen(CPU.Devices[index] as LEM1802);
                    }
                    else
                    {
                        foreach (var device in CPU.Devices)
                            if (device is LEM1802)
                            {
                                DrawScreen(device as LEM1802);
                                break;
                            }
                    }
                }
                else if (parts[0] == "memory" || parts[0] == "mem")
                {
                    ushort start = 0;
                    if (parts.Length > 1)
                        start = ushort.Parse(parts[1], NumberStyles.HexNumber);
                    ushort end = (ushort)(start + 0x40);
                    if (parts.Length > 2)
                        end = ushort.Parse(parts[2], NumberStyles.HexNumber);
                    int index = 0;
                    while (start < end)
                    {
                        if (index % 8 == 0)
                            Console.Write("0x" + GetHexString(start, 4) + ": ");
                        if (CPU.PC == start)
                            Console.Write("[" + GetHexString(CPU.Memory[start], 4) + "]");
                        else
                            Console.Write(" " + GetHexString(CPU.Memory[start], 4) + " ");
                        if (index % 8 == 7)
                            Console.Write("\n");
                        index++;
                        start++;
                    }
                }
                else if (parts[0] == "stack")
                {
                    ushort address = CPU.SP;
                    for (ushort i = 0; i < 10; i++)
                    {
                        Console.WriteLine("[" + GetHexString(address, 4) + "]: " + GetHexString(CPU.Memory[address], 4));
                        address++;
                    }
                }
            }
            else if (input.StartsWith("list "))
            {
                string[] parts = input.Split(' ');
                if (parts[1] == "registers")
                {
                    Console.Write("A:  " + GetHexString(CPU.A, 4));
                    Console.Write("   B:  " + GetHexString(CPU.B, 4) + "\n");
                    Console.Write("C:  " + GetHexString(CPU.C, 4));
                    Console.Write("   X:  " + GetHexString(CPU.X, 4) + "\n");
                    Console.Write("Y:  " + GetHexString(CPU.Y, 4));
                    Console.Write("   Z:  " + GetHexString(CPU.Z, 4) + "\n");
                    Console.Write("I:  " + GetHexString(CPU.I, 4));
                    Console.Write("   J:  " + GetHexString(CPU.J, 4) + "\n");
                    Console.Write("PC: " + GetHexString(CPU.PC, 4));
                    Console.Write("   SP: " + GetHexString(CPU.SP, 4) + "\n");
                    Console.Write("EX: " + GetHexString(CPU.EX, 4));
                    Console.Write("   IA: " + GetHexString(CPU.IA, 4) + "\n");
                }
                else if (parts[1] == "hardware")
                {
                    int i = 0;
                    foreach (var hw in CPU.Devices)
                        Console.WriteLine((i++) + ": " + hw.FriendlyName + " (0x" + hw.DeviceID.ToString("X8") + ")");
                }
            }
            else if (input.StartsWith("dasm") || input.StartsWith("dis"))
            {
                FastDisassembler fdas = new FastDisassembler(new Dictionary<ushort, string>());
                ushort start = (ushort)(CPU.PC - 2);
                string[] parts = input.Split(' ');
                if (parts.Length > 1)
                    start = ushort.Parse(parts[1], NumberStyles.HexNumber);
                var code = fdas.FastDisassemble(ref CPU.Memory, start, (ushort)(start + 0x10));
                foreach (var entry in code)
                {
                    if (CPU.PC == entry.Address)
                    {
                        ConsoleColor background = Console.BackgroundColor;
                        ConsoleColor foreground = Console.ForegroundColor;
                        Console.BackgroundColor = ConsoleColor.Yellow;
                        Console.ForegroundColor = ConsoleColor.Black;
                        Console.WriteLine(GetHexString(entry.Address, 4) + ": " + entry.Code);
                        Console.ForegroundColor = foreground;
                        Console.BackgroundColor = background;
                    }
                    else if (CPU.Breakpoints.Where(b => b.Address == entry.Address).Count() != 0)
                    {
                        ConsoleColor background = Console.BackgroundColor;
                        ConsoleColor foreground = Console.ForegroundColor;
                        Console.BackgroundColor = ConsoleColor.DarkRed;
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.WriteLine(GetHexString(entry.Address, 4) + ": " + entry.Code);
                        Console.ForegroundColor = foreground;
                        Console.BackgroundColor = background;
                    }
                    else
                        Console.WriteLine(GetHexString(entry.Address, 4) + ": " + entry.Code);
                }
            }
            else if (input.StartsWith("breakpoint "))
            {
                string[] parts = input.Split(' ');
                ushort address = ushort.Parse(parts[2], NumberStyles.HexNumber);
                if (parts[1] == "add" || parts[1] == "set")
                {
                    if (CPU.Breakpoints.Count(b => b.Address == address) == 0)
                    {
                        CPU.Breakpoints.Add(new Breakpoint()
                        {
                            Address = address
                        });
                    }
                    else
                        Console.WriteLine("There is already a breakpoint set at that address.");
                }
                else if (parts[1] == "remove")
                {
                    if (CPU.Breakpoints.Count(b => b.Address == address) != 0)
                        CPU.Breakpoints.Remove(CPU.Breakpoints.FirstOrDefault(b => b.Address == address));
                    else
                        Console.WriteLine("There is no breakpoint set at that address.");
                }
            }
            else if (input == "exit" || input == "quit" || input == "bye")
                Process.GetCurrentProcess().Kill();
            else if (input.StartsWith("help"))
                DoHelp(input);
            else if (input == "") { }
            else
            {
                if (File.Exists(input)) // Script?
                {
                    string[] file = File.ReadAllLines(input);
                    foreach (var line in file)
                        ParseInput(line);
                }
                else
                    Console.WriteLine("Unknown command.");
            }
            return;
        }
Exemple #3
0
        private static void ParseInput(string originalInput, PinnedConsole Console)
        {
            string input = originalInput.ToLower().Trim();
            string[] parameters = input.Split(' ');

            if (input == "quit" || input == "q")
                return;
            else if (input == "clear")
            {
                if (Console.Global)
                    System.Console.Clear();
                else
                    Console.Clear();
            }
            else if (input.StartsWith("bind "))
            {
                string[] parts = input.Split(' ');
                Shortcuts.Add(parts[1].ToLower(), input.Substring(5 + parts[1].Length));
            }
            else if (input.StartsWith("pin ")) // pin x y interval command...
            {
                string[] parts = input.Split(' ');
                int x = int.Parse(parts[1]);
                int y = int.Parse(parts[2]);
                int interval = int.Parse(parts[3]);
                string command = input.Substring(input.IndexOf(' ') + 1);
                command = command.Substring(command.IndexOf(' ') + 1);
                command = command.Substring(command.IndexOf(' ') + 1);
                command = command.Substring(command.IndexOf(' ') + 1);
                PinnedConsole pc = new PinnedConsole()
                {
                    Command = command,
                    Left = x,
                    Top = y,
                    Interval = interval,
                    ID = ConsoleID++
                };
                pc.Timer = new Timer(new TimerCallback(UpdateConsole), pc, pc.Interval, System.Threading.Timeout.Infinite);
                Console.WriteLine("Console ID " + pc.ID.ToString() + " created.");
            }
            else if (input.StartsWith("flash "))
            {
                bool littleEndian = false;
                string file;
                if (parameters.Length == 2)
                    file = parameters[1];
                else if (parameters.Length == 3)
                {
                    file = parameters[2];
                    littleEndian = parameters[1].ToLower() == "little";
                }
                else
                    return;
                List<ushort> data = new List<ushort>();
                using (Stream stream = File.OpenRead(file))
                {
                    for (int i = 0; i < stream.Length; i += 2)
                    {
                        byte a = (byte)stream.ReadByte();
                        byte b = (byte)stream.ReadByte();
                        if (littleEndian)
                            data.Add((ushort)(a | (b << 8)));
                        else
                            data.Add((ushort)(b | (a << 8)));
                    }
                }
                CPU.FlashMemory(data.ToArray());
            }
            else if (input.StartsWith("connect "))
                ConnectDevice(input.Substring(8));
            else if (input == "start")
                CPU.IsRunning = true;
            else if (input == "stop")
                CPU.IsRunning = false;
            else if (input.StartsWith("step"))
            {
                if (CPU.IsRunning)
                {
                    Console.WriteLine("CPU is still running; use \"stop\" first.");
                    return;
                }
                string[] parts = input.Split(' ');
                if (parts.Length > 1)
                {
                    if (parts[1] == "into" || parts[1] == "once")
                        CPU.Execute(-1);
                    else if (parts[1] == "over")
                    {
                    }
                    else
                    {
                        int i = int.Parse(parts[1]);
                        while (i > 0)
                        {
                            CPU.Execute(-1);
                            i--;
                        }
                    }
                }
                else
                {
                    CPU.Execute(-1);
                }
            }
            else if (input.StartsWith("dump "))
            {
                string[] parts = input.Substring(5).Split(' ');
                if (parts[0] == "screen")
                {
                    if (parts.Length > 1)
                    {
                        int index = int.Parse(parts[1]);
                        if (CPU.Devices[index] is LEM1802)
                            DrawScreen(CPU.Devices[index] as LEM1802, Console);
                    }
                    else
                    {
                        foreach (var device in CPU.Devices)
                            if (device is LEM1802)
                            {
                                DrawScreen(device as LEM1802, Console);
                                break;
                            }
                    }
                }
                else if (parts[0] == "memory" || parts[0] == "mem")
                {
                    ushort start = 0;
                    if (parts.Length > 1)
                        start = ushort.Parse(parts[1], NumberStyles.HexNumber);
                    ushort end = (ushort)(start + 0x40);
                    if (parts.Length > 2)
                        end = ushort.Parse(parts[2], NumberStyles.HexNumber);
                    int index = 0;
                    while (start < end)
                    {
                        if (index % 8 == 0)
                            Console.Write("0x" + GetHexString(start, 4) + ": ");
                        if (CPU.PC == start)
                            Console.Write("[" + GetHexString(CPU.Memory[start], 4) + "]");
                        else
                            Console.Write(" " + GetHexString(CPU.Memory[start], 4) + " ");
                        if (index % 8 == 7)
                            Console.Write("\n");
                        index++;
                        start++;
                    }
                }
                else if (parts[0] == "stack")
                {
                    ushort address = CPU.SP;
                    for (ushort i = 0; i < 10; i++)
                    {
                        Console.WriteLine("[" + GetHexString(address, 4) + "]: " + GetHexString(CPU.Memory[address], 4));
                        address++;
                    }
                }
            }
            else if (input.StartsWith("list "))
            {
                string[] parts = input.Split(' ');
                if (parts[1] == "registers")
                {
                    Console.Write("A:  " + GetHexString(CPU.A, 4));
                    Console.Write("   B:  " + GetHexString(CPU.B, 4) + "\n");
                    Console.Write("C:  " + GetHexString(CPU.C, 4));
                    Console.Write("   X:  " + GetHexString(CPU.X, 4) + "\n");
                    Console.Write("Y:  " + GetHexString(CPU.Y, 4));
                    Console.Write("   Z:  " + GetHexString(CPU.Z, 4) + "\n");
                    Console.Write("I:  " + GetHexString(CPU.I, 4));
                    Console.Write("   J:  " + GetHexString(CPU.J, 4) + "\n");
                    Console.Write("PC: " + GetHexString(CPU.PC, 4));
                    Console.Write("   SP: " + GetHexString(CPU.SP, 4) + "\n");
                    Console.Write("EX: " + GetHexString(CPU.EX, 4));
                    Console.Write("   IA: " + GetHexString(CPU.IA, 4) + "\n");
                }
                else if (parts[1] == "hardware")
                {
                    foreach (var hw in CPU.Devices)
                        Console.WriteLine(hw.FriendlyName);
                }
            }
            else if (input.StartsWith("dasm") || input.StartsWith("dis"))
            {
                FastDisassembler fdas = new FastDisassembler(new Dictionary<ushort, string>());
                ushort start = (ushort)(CPU.PC - 2);
                string[] parts = input.Split(' ');
                if (parts.Length > 1)
                    start = ushort.Parse(parts[1], NumberStyles.HexNumber);
                var code = fdas.FastDisassemble(ref CPU.Memory, start, (ushort)(start + 0x10));
                foreach (var entry in code)
                {
                    if (CPU.PC == entry.Address)
                    {
                        ConsoleColor background = System.Console.BackgroundColor;
                        ConsoleColor foreground = System.Console.ForegroundColor;
                        System.Console.BackgroundColor = ConsoleColor.Yellow;
                        System.Console.ForegroundColor = ConsoleColor.Black;
                        Console.WriteLine(GetHexString(entry.Address, 4) + ": " + entry.Code);
                        System.Console.ForegroundColor = foreground;
                        System.Console.BackgroundColor = background;
                    }
                    else if (CPU.Breakpoints.Where(b => b.Address == entry.Address).Count() != 0)
                    {
                        ConsoleColor background = System.Console.BackgroundColor;
                        ConsoleColor foreground = System.Console.ForegroundColor;
                        System.Console.BackgroundColor = ConsoleColor.DarkRed;
                        System.Console.ForegroundColor = ConsoleColor.White;
                        Console.WriteLine(GetHexString(entry.Address, 4) + ": " + entry.Code);
                        System.Console.ForegroundColor = foreground;
                        System.Console.BackgroundColor = background;
                    }
                    else
                        Console.WriteLine(GetHexString(entry.Address, 4) + ": " + entry.Code);
                }
            }
            else if (input.StartsWith("breakpoint "))
            {
                CPU.Breakpoints.Add(new Breakpoint()
                {
                    Address = ushort.Parse(input.Substring(11), NumberStyles.HexNumber)
                });
            }
            else if (input == "") { }
            else
            {
                if (File.Exists(input)) // Script?
                {
                    string[] file = File.ReadAllLines(input);
                    foreach (var line in file)
                        ParseInput(line, Console);
                }
                else
                    Console.WriteLine("Unknown command.");
            }
            return;
        }