static void Main(string[] args) { ConfigFilePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); ConfigFilePath = Path.Combine(ConfigFilePath, ".lettuce"); Configuration = ConfigurationManager.LoadConfiguration(ConfigFilePath); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); if (!System.Diagnostics.Debugger.IsAttached) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException, true); Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); } // Enumerate loaded devices from plugins and Tomato List<Device> PossibleDevices = new List<Device>(); GenericKeyboard kb = new GenericKeyboard(); 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)); } } CPU = new DCPU(); string binFile = null; bool littleEndian = false, pairKeyboards = true; List<Device> devices = new List<Device>(); CPU.IsRunning = false; for (int i = 0; i < args.Length; i++) { string arg = args[i]; if (arg.StartsWith("-")) { switch (arg) { case "--no-wait": case "--nowait": CPU.IsRunning = true; break; case "-c": case "--connect": if (i + 1 == args.Length || args[i + 1].StartsWith("-")) { Console.Error.WriteLine("Missing argument at --connect"); break; } bool gotWrongParam = false; string deviceID = args[++i]; string[] ids = deviceID.Split(','); foreach (var dID in ids) { uint id; bool foundDevice = false; if (uint.TryParse(dID, NumberStyles.HexNumber, null, out id)) { foreach (Device d in PossibleDevices) { if (d.DeviceID == id) { devices.Add((Device) Activator.CreateInstance(d.GetType())); foundDevice = true; } } } else { foreach (Device d in PossibleDevices) { if (d.GetType().Name.ToLower() == dID.ToLower()) { devices.Add((Device)Activator.CreateInstance(d.GetType())); foundDevice = true; } } } if (!foundDevice) { Console.Error.WriteLine("Device '" + dID + "' could not be found, continuing.."); gotWrongParam = true; } } if (gotWrongParam) return; break; case "--skip-pairing": pairKeyboards = false; break; case "--listing": var file = args[++i]; if(!File.Exists(file)) { Console.Error.WriteLine("Could not find listing-file: " + file); return; } Debugger.LoadOrganicListing(file); break; case "--little-endian": littleEndian = true; break; case "--list-devices": Console.WriteLine("Got {0} devices:", PossibleDevices.Count); foreach (var device in PossibleDevices) { Console.WriteLine("ID: 0x{0:X}, Name: {1}", device.DeviceID, device.GetType().Name); } return; case "--disable-auto-arrange": EnableAutomaticArrangement = false; break; case "--help": Console.WriteLine("Lettuce - a graphical debugger for DCPU-16 programs"); Console.WriteLine("Options:"); Console.WriteLine("\t--no-wait Starts debugging immediately."); Console.WriteLine("\t--connect [Devices] A comma-seperated list of devices to connect"); Console.WriteLine("\t For example: --connect 0x40E41D9D,M35FD"); Console.WriteLine("\t See also: --list-devices"); Console.WriteLine("\t--list-devices Lists all available devices and exits."); Console.WriteLine("\t--skip-pairing"); Console.WriteLine("\t--listing [File.lst] Loads File.lst to make debugging easier."); Console.WriteLine("\t--little-endian Switches to little-endian mode."); Console.WriteLine("\t--help Outputs this and exits."); return; } } else { if (binFile == null) binFile = arg; else Debugger.LoadOrganicListing(args[i]); } } if (binFile == null) { var mc = new MemoryConfiguration(); var result = mc.ShowDialog(); if (result == DialogResult.Cancel) return; if (result == DialogResult.OK) { binFile = mc.FileName; littleEndian = mc.LittleEndian; } } if (devices.Count == 0) { var hwc = new HardwareConfiguration(); var result = hwc.ShowDialog(); if (result == DialogResult.Cancel) return; foreach (var device in hwc.SelectedDevices) devices.Add(device); } // Inject custom UITypeEditor into M35FD TypeDescriptor.AddAttributes(typeof(ushort[]), new EditorAttribute(typeof(M35FDTypeEditor), typeof(UITypeEditor))); if (!string.IsNullOrEmpty(binFile)) { lastbinFilepath = binFile; // Load binary file List<ushort> data = new List<ushort>(); using (Stream stream = File.OpenRead(binFile)) { 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 CPU.IsRunning = false; foreach (var device in devices) CPU.ConnectDevice(device); debugger = new Debugger(ref CPU); if (EnableAutomaticArrangement) { debugger.StartPosition = FormStartPosition.Manual; if (RuntimeInfo.IsMacOSX) debugger.Location = new Point(0, 22); else debugger.Location = new Point(0, 0); } debugger.ResetLayout(); debugger.Show(); screenLocation.Y = debugger.Location.Y + 4; screenLocation.X = debugger.Location.X + debugger.Width + 5; foreach (Device d in CPU.Devices) { if (d is LEM1802) AddWindow(new LEM1802Window(d as LEM1802, CPU, pairKeyboards)); else if (d is SPED3) AddWindow(new SPED3Window(d as SPED3, CPU)); else if (d is M35FD) AddWindow(new M35FDWindow(d as M35FD, CPU)); } // Run again for extra keyboards for (int i = 0; i < CPU.Devices.Count; i++) { if (CPU.Devices[i] is GenericKeyboard && !LEM1802Window.AssignedKeyboards.Contains(i)) AddWindow(new GenericKeyboardWindow(CPU.Devices[i] as GenericKeyboard, CPU)); } debugger.Focus(); LastTick = DateTime.Now; timer = new System.Threading.Timer(FetchExecute, null, 10, Timeout.Infinite); Application.Run(debugger); timer.Dispose(); }
static void Main(string[] args) { RuntimeInfo.GatherInfo(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); if (!System.Diagnostics.Debugger.IsAttached) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException, true); Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); } // Enumerate loaded devices from plugins and Tomato List<Device> PossibleDevices = new List<Device>(); GenericKeyboard kb = new GenericKeyboard(); 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)); } } CPU = new DCPU(); string binFile = null; bool littleEndian = false; List<Device> devices = new List<Device>(); CPU.IsRunning = false; for (int i = 0; i < args.Length; i++) { string arg = args[i]; if (arg.StartsWith("-")) { switch (arg) { case "--no-wait": case "--nowait": CPU.IsRunning = true; break; case "-c": case "--connect": string deviceID = args[++i]; string[] ids = deviceID.Split(','); foreach (var dID in ids) { uint id; if (uint.TryParse(dID, NumberStyles.HexNumber, null, out id)) { foreach (Device d in PossibleDevices) { if (d.DeviceID == id) devices.Add((Device)Activator.CreateInstance(d.GetType())); } } else { foreach (Device d in PossibleDevices) { if (d.GetType().Name.ToLower() == dID.ToLower()) devices.Add((Device)Activator.CreateInstance(d.GetType())); } } } break; case "--listing": Debugger.LoadOrganicListing(args[++i]); break; } } else { if (binFile == null) binFile = arg; else Debugger.LoadOrganicListing(args[i]); } } if (binFile == null) { MemoryConfiguration mc = new MemoryConfiguration(); if (mc.ShowDialog() == DialogResult.OK) { binFile = mc.FileName; littleEndian = mc.LittleEndian; } } if (devices.Count == 0) { HardwareConfiguration hwc = new HardwareConfiguration(); hwc.ShowDialog(); foreach (var device in hwc.SelectedDevices) devices.Add(device); } if (!string.IsNullOrEmpty(binFile)) { lastbinFilepath = binFile; // Load binary file List<ushort> data = new List<ushort>(); using (Stream stream = File.OpenRead(binFile)) { 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 CPU.IsRunning = false; foreach (var device in devices) CPU.ConnectDevice(device); debugger = new Debugger(ref CPU); debugger.StartPosition = FormStartPosition.Manual; debugger.Location = new Point(0, 0); debugger.ResetLayout(); debugger.Show(); screenLocation.Y = debugger.Location.Y + 4; screenLocation.X = debugger.Location.X + debugger.Width + 5; int keyboardCount = 0; foreach (Device d in CPU.Devices) if (d is LEM1802) AddWindow(new LEM1802Window(d as LEM1802, CPU, true)); else if (d is GenericKeyboard) keyboardCount++; int remaining = keyboardCount - LEM1802Window.AssignedKeyboards.Count(); for(;remaining > 0; remaining--) AddWindow(new GenerickeyboardWindow(null, CPU, true)); debugger.Focus(); LastTick = DateTime.Now; timer = new System.Threading.Timer(FetchExecute, null, 10, Timeout.Infinite); Application.Run(debugger); timer.Dispose(); }