1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using Mesen.GUI.Config; 8 9 namespace Mesen.GUI.Debugger 10 { 11 public class DebugWorkspaceManager 12 { 13 private static DebugWorkspace _workspace; 14 private static Ld65DbgImporter _symbolProvider; 15 private static string _romName; 16 private static object _lock = new object(); 17 SymbolProviderChangedHandler(Ld65DbgImporter provider)18 public delegate void SymbolProviderChangedHandler(Ld65DbgImporter provider); 19 public static event SymbolProviderChangedHandler SymbolProviderChanged; 20 21 public static Ld65DbgImporter SymbolProvider 22 { 23 get { return _symbolProvider; } 24 private set 25 { 26 if(_symbolProvider != value) { 27 _symbolProvider = value; 28 SymbolProviderChanged?.Invoke(value); 29 } 30 } 31 } 32 SaveWorkspace()33 public static void SaveWorkspace() 34 { 35 if(_workspace != null) { 36 lock(_lock) { 37 if(_workspace != null) { 38 _workspace.WatchValues = new List<string>(WatchManager.WatchEntries); 39 _workspace.Labels = new List<CodeLabel>(LabelManager.GetLabels()); 40 _workspace.Breakpoints = new List<Breakpoint>(BreakpointManager.Breakpoints); 41 _workspace.Save(); 42 } 43 } 44 } 45 } 46 Clear()47 public static void Clear() 48 { 49 lock(_lock) { 50 _workspace = null; 51 _romName = null; 52 SymbolProvider = null; 53 } 54 } 55 ResetWorkspace()56 public static void ResetWorkspace() 57 { 58 if(_workspace != null) { 59 lock(_lock) { 60 if(_workspace != null) { 61 _workspace.Breakpoints = new List<Breakpoint>(); 62 _workspace.Labels = new List<CodeLabel>(); 63 _workspace.WatchValues = new List<string>(); 64 LabelManager.ResetLabels(); 65 WatchManager.WatchEntries = _workspace.WatchValues; 66 BreakpointManager.SetBreakpoints(_workspace.Breakpoints); 67 _workspace.Save(); 68 Clear(); 69 } 70 } 71 } 72 } 73 GetWorkspace()74 public static DebugWorkspace GetWorkspace() 75 { 76 string romName = InteropEmu.GetRomInfo().GetRomName(); 77 if(_workspace == null || _romName != romName) { 78 SymbolProvider = null; 79 lock(_lock) { 80 if(_workspace == null || _romName != romName) { 81 if(_workspace != null) { 82 SaveWorkspace(); 83 } 84 _romName = InteropEmu.GetRomInfo().GetRomName(); 85 _workspace = DebugWorkspace.GetWorkspace(); 86 87 //Load watch entries 88 WatchManager.WatchEntries = _workspace.WatchValues; 89 90 //Load breakpoints 91 BreakpointManager.SetBreakpoints(_workspace.Breakpoints); 92 93 //Setup labels 94 if(_workspace.Labels.Count == 0) { 95 LabelManager.ResetLabels(); 96 if(!ConfigManager.Config.DebugInfo.DisableDefaultLabels) { 97 LabelManager.SetDefaultLabels(InteropEmu.GetRomInfo().MapperId); 98 } 99 } else { 100 LabelManager.ResetLabels(); 101 LabelManager.SetLabels(_workspace.Labels, true); 102 } 103 } 104 } 105 } 106 return _workspace; 107 } 108 109 private static DebuggerFlags _flags = DebuggerFlags.None; SetFlags(DebuggerFlags flags)110 public static void SetFlags(DebuggerFlags flags) 111 { 112 _flags |= flags; 113 InteropEmu.DebugSetFlags(_flags); 114 } 115 ClearFlags(DebuggerFlags flags = DebuggerFlags.None)116 public static void ClearFlags(DebuggerFlags flags = DebuggerFlags.None) 117 { 118 if(flags == DebuggerFlags.None) { 119 _flags = DebuggerFlags.None; 120 } else { 121 _flags &= ~flags; 122 } 123 InteropEmu.DebugSetFlags(_flags); 124 } 125 ResetLabels()126 public static void ResetLabels() 127 { 128 LabelManager.ResetLabels(); 129 if(!ConfigManager.Config.DebugInfo.DisableDefaultLabels) { 130 LabelManager.SetDefaultLabels(InteropEmu.GetRomInfo().MapperId); 131 } 132 SaveWorkspace(); 133 GetWorkspace(); 134 } 135 AutoLoadDbgFiles(bool silent)136 public static void AutoLoadDbgFiles(bool silent) 137 { 138 if(ConfigManager.Config.DebugInfo.AutoLoadDbgFiles) { 139 RomInfo info = InteropEmu.GetRomInfo(); 140 string dbgPath = Path.Combine(info.RomFile.Folder, info.GetRomName() + ".dbg"); 141 if(File.Exists(dbgPath)) { 142 DateTime lastDbgUpdate = File.GetLastWriteTime(dbgPath); 143 if(lastDbgUpdate != SymbolProvider?.DbgFileStamp) { 144 ImportDbgFile(dbgPath, silent); 145 } else { 146 //Currently loaded symbol provider is still valid 147 return; 148 } 149 } else { 150 string mlbPath = Path.Combine(info.RomFile.Folder, info.GetRomName() + ".mlb"); 151 if(File.Exists(mlbPath)) { 152 ImportMlbFile(mlbPath, silent); 153 } else { 154 string fnsPath = Path.Combine(info.RomFile.Folder, info.GetRomName() + ".fns"); 155 if(File.Exists(fnsPath)) { 156 ImportNesasmFnsFile(fnsPath, silent); 157 } 158 } 159 } 160 } 161 } 162 ImportNesasmFnsFile(string fnsPath, bool silent = false)163 public static void ImportNesasmFnsFile(string fnsPath, bool silent = false) 164 { 165 if(ConfigManager.Config.DebugInfo.ImportConfig.ResetLabelsOnImport) { 166 ResetLabels(); 167 } 168 NesasmFnsImporter.Import(fnsPath, silent); 169 } 170 ImportMlbFile(string mlbPath, bool silent = false)171 public static void ImportMlbFile(string mlbPath, bool silent = false) 172 { 173 if(ConfigManager.Config.DebugInfo.ImportConfig.ResetLabelsOnImport) { 174 ResetLabels(); 175 } 176 MesenLabelFile.Import(mlbPath, silent); 177 } 178 ImportDbgFile(string dbgPath, bool silent)179 public static void ImportDbgFile(string dbgPath, bool silent) 180 { 181 if(ConfigManager.Config.DebugInfo.ImportConfig.ResetLabelsOnImport) { 182 ResetLabels(); 183 } 184 185 Ld65DbgImporter dbgImporter = new Ld65DbgImporter(); 186 dbgImporter.Import(dbgPath, silent); 187 188 DebugWorkspaceManager.SymbolProvider = dbgImporter; 189 } 190 } 191 } 192