static void Main(string[] args) { PinnedConsole globalConsole = new PinnedConsole() { ID = -1, Width = Console.WindowWidth, Height = Console.WindowHeight, Interval = -1, Left = 0, Top = 0, Global = true }; Console.Clear(); Console.TreatControlCAsInput = true; globalConsole.WriteLine("Pickles DCPU-16 Debugger Copyright Drew DeVault 2012"); globalConsole.WriteLine("Use \"help\" for assistance."); foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { var types = asm.GetTypes().Where(t => typeof(Device).IsAssignableFrom(t) && t.IsAbstract == false); foreach (var type in types) PossibleDevices.Add((Device)Activator.CreateInstance(type)); } string input; CPU = new DCPU(); CPU.IsRunning = false; LastTick = DateTime.Now; ClockTimer = new System.Threading.Timer(FetchExecute, null, 10, Timeout.Infinite); while (true) { globalConsole.Write(">"); string originalInput = ReadLineEnableShortcuts().Trim(); ParseInput(originalInput, globalConsole); if (originalInput.ToLower() == "quit" || originalInput.ToLower() == "q") break; } }
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; }
private static void DrawScreen(LEM1802 Screen, PinnedConsole Console) { Console.Clear(); // TODO: not this ConsoleColor foregroundInitial = System.Console.ForegroundColor; ConsoleColor backgroundInitial = System.Console.BackgroundColor; ushort address = 0; System.Console.ForegroundColor = GetPaletteColor((byte)Screen.BorderColorValue); Console.Write(" \n"); for (int y = 0; y < 12; y++) { System.Console.ForegroundColor = GetPaletteColor((byte)Screen.BorderColorValue); Console.Write(" "); for (int x = 0; x < 32; x++) { ushort value = CPU.Memory[Screen.ScreenMap + address]; ConsoleColor background = GetPaletteColor((byte)((value & 0xF00) >> 8)); ConsoleColor foreground = GetPaletteColor((byte)((value & 0xF000) >> 12)); System.Console.ForegroundColor = foreground; System.Console.BackgroundColor = background; Console.Write(Encoding.ASCII.GetString(new byte[] { (byte)(value & 0xFF) })); address++; } System.Console.ForegroundColor = GetPaletteColor((byte)Screen.BorderColorValue); Console.Write(" \n"); } System.Console.ForegroundColor = foregroundInitial; System.Console.BackgroundColor = backgroundInitial; }