public void RemoveSourceEntry(SourceEntry entry) { // Remove from address table for (int i = 0; i < _orderedSourceEntries.Count; i++) { if (_orderedSourceEntries[i].Address == entry.Address) { _orderedSourceEntries.RemoveAt(i); break; } } // Remove from source table if present if (_sourceFileToSourceEntryMap.ContainsKey(entry.SourcePath)) { for (int i = 0; i < _sourceFileToSourceEntryMap[entry.SourcePath].Count; i++) { if (_sourceFileToSourceEntryMap[entry.SourcePath][i].Address == entry.Address) { _sourceFileToSourceEntryMap[entry.SourcePath].RemoveAt(i); break; } } } }
private void InsertAddressEntry(SourceEntry entry) { if (_orderedSourceEntries.Count == 0) { _orderedSourceEntries.Add(entry); return; } // Find the first entry that has an address greater than the new entry's. // for (int i = 0; i < _orderedSourceEntries.Count; i++) { // Sanity check -- if these entries have equal addresses then we need to stop here. if (_orderedSourceEntries[i].Address == entry.Address) { throw new InvalidOperationException( String.Format("Duplicate address {0:x4} in source map.", entry.Address)); } if (_orderedSourceEntries[i].Address > entry.Address) { _orderedSourceEntries.Insert(i, entry); return; } } // // If we get here, then this address is greater than any already in the list, so we add it at the end. // _orderedSourceEntries.Add(entry); }
/// <summary> /// Loads the appropriate source file, brings the specified line into view /// and highlights the specified line. /// </summary> /// <param name="entry"></param> public void SelectSourceEntry(SourceEntry entry, bool readOnly, bool iop) { LoadSourceFile(entry.SourcePath); SelectLine(entry.LineNumber); this.ReadOnly = readOnly; _iopCode = iop; }
public void DisplayCurrentCode() { RefreshSourceMaps(); // // Select active files in the source file list // SourceFiles.ClearSelected(); foreach (SourceMap s in _sourceMaps) { foreach (string fileName in s.GetSourceFiles()) { for (int i = 0; i < SourceFiles.Items.Count; i++) { if (fileName == (string)SourceFiles.Items[i]) { SourceFiles.SetSelected(i, true); } } } } // // Find the source line that matches the current TPC, if any. // int tpc = _system.CP.TPC[(int)_system.CP.CurrentTask]; foreach (SourceMap s in _sourceMaps) { SourceEntry entry = s.GetExactSourceForAddress((ushort)tpc); if (entry != null) { // WE GOT ONE!!! SourceDisplay.AttachMap(s); SourceDisplay.SelectSourceEntry(entry, false, false /* cp */); // Select the source file in the source list for (int i = 0; i < SourceFiles.Items.Count; i++) { if (entry.SourcePath == (string)SourceFiles.Items[i]) { SourceFiles.SetSelected(i, true); } } break; } } // // Highlight the line in the disassembly as well. // Disassembly.SelectAddress(tpc); }
private void InsertSourceEntry(SourceEntry entry) { if (!_sourceFileToSourceEntryMap.ContainsKey(entry.SourcePath)) { List <SourceEntry> newList = new List <SourceEntry>(); newList.Add(entry); _sourceFileToSourceEntryMap.Add(entry.SourcePath, newList); } else { _sourceFileToSourceEntryMap[entry.SourcePath].Add(entry); } }
public SourceEntry GetSymbolForAddress(int address) { RefreshSourceMaps(); SourceEntry entry = null; foreach (SourceMap s in _sourceMaps) { entry = s.GetSourceForAddress((ushort)address); if (entry != null) { break; } } return(entry); }
public SourceEntry GetSourceForAddress(ushort address) { SourceEntry result = null; // // Find the SourceEntry nearest this address, if there is one. // foreach (SourceEntry entry in _orderedSourceEntries) { if (entry.Address > address) { break; } result = entry; } return(result); }
private void OnDisassemblySelectionChanged(object sender, EventArgs e) { // // Sync the source display with the selected disassembly address, if possible. // int address = Disassembly.SelectedAddress; // // TODO: we should search through all source maps, not just the current one. // if (SourceDisplay.SourceMap != null && address != -1 && SourceDisplay.SelectedAddress != address) { SourceEntry entry = SourceDisplay.SourceMap.GetSourceForAddress((ushort)address); if (entry != null && !string.IsNullOrWhiteSpace(entry.SourcePath)) { SourceDisplay.SelectSourceEntry(entry, false, false /* cp */); } } }
private void PrintIOPStatus() { WriteLine(String.Format("IOP PC=${0:x4} SP=${1:x4} AF=${2:x4} BC=${3:x4} DE=${4:x4} HL=${5:x4}", _system.IOP.CPU.PC, _system.IOP.CPU.SP, _system.IOP.CPU.AF, _system.IOP.CPU.BC, _system.IOP.CPU.DE, _system.IOP.CPU.HL)); WriteLine(String.Format("Flags {0}", GetStringForFlags(_system.IOP.CPU.F))); SourceEntry entry = _iopDebugger.SourceMap.GetSourceForAddress(_system.IOP.CPU.PC); string symbolName = null; string currentSymbol = String.Empty; if (entry != null) { if (entry.SymbolNames.Length == 0 || entry.SymbolNames[0] == "*none*" || // TODO: move to constant entry.Address != _system.IOP.CPU.PC) { // No symbol name associated with this entry, find the nearest. SourceEntry symbolEntry = _iopDebugger.SourceMap.GetNearestSymbolForAddress(_system.IOP.CPU.PC); if (symbolEntry != null) { symbolName = String.Format("{0}+${1:x}", symbolEntry.SymbolNames[0], _system.IOP.CPU.PC - symbolEntry.Address); } } else { symbolName = entry.SymbolNames[0]; } if (symbolName != null) { currentSymbol = String.Format("{0},{1} line {2}", symbolName, entry.SourcePath, entry.LineNumber); } } WriteLine(String.Format("${0:x4} ({1})\r\n {2}", _system.IOP.CPU.PC, currentSymbol, _system.IOP.CPU.Disassemble(_system.IOP.CPU.PC))); // Update the IOP debugger's title bar with current MP value _iopDebugger.Text = String.Format("IOP Debugger - MP {0}", _system.IOP.MiscIO.MPanelBlank ? "<blank>" : _system.IOP.MiscIO.MPanelValue.ToString()); }
public SourceEntry GetNearestSymbolForAddress(ushort address) { SourceEntry result = null; // // Find the SourceEntry nearest this address that has a symbol name defined, if there is one. // foreach (SourceEntry entry in _orderedSourceEntries) { if (entry.Address > address) { break; } if (entry.SymbolNames.Length > 0 && entry.SymbolNames[0] != "*none*") // TODO: move to constant { result = entry; } } return(result); }
public void DisplayCurrentCode() { SourceEntry entry = _sourceMap.GetSourceForAddress(_system.IOP.CPU.PC); if (entry != null && !string.IsNullOrWhiteSpace(entry.SourcePath)) { SourceDisplay.SelectSourceEntry(entry, false, true /* iop */); // Find the source entry in the file list and select it. for (int i = 0; i < SourceFiles.Items.Count; i++) { if ((string)SourceFiles.Items[i] == entry.SourcePath) { SourceFiles.SelectedIndex = i; break; } } } else { // Should show disassembly instead } }
public bool GetAddressForSource(SourceEntry entry, out ushort address) { bool found = false; address = 0; // // Find the source line entry that matches. // if (_sourceFileToSourceEntryMap.ContainsKey(entry.SourcePath)) { foreach (SourceEntry line in _sourceFileToSourceEntryMap[entry.SourcePath]) { if (line.LineNumber == entry.LineNumber) { found = true; address = line.Address; break; } } } return(found); }
private void PrintCPStatus() { int tpc = _system.CP.TPC[(int)_system.CP.CurrentTask]; SourceEntry symbolEntry = _cpDebugger.GetSymbolForAddress(tpc); string currentSymbol = String.Empty; if (symbolEntry != null) { string symbolName = symbolEntry.SymbolNames.Length > 0 && symbolEntry.SymbolNames[0] != "*none*" ? symbolEntry.SymbolNames[0] : String.Empty; currentSymbol = String.Format("{0},{1} line {2}", symbolName, symbolEntry.SourcePath, symbolEntry.LineNumber); } WriteLine(String.Format("CP Task={0} TPC={1:x3} {2}", _system.CP.CurrentTask, tpc, currentSymbol)); StringBuilder regString = new StringBuilder(); for (int i = 0; i < 16; i++) { regString.AppendFormat(" R{0:x}=0x{1:x4} ", i, _system.CP.ALU.R[i]); if (((i + 1) % 8) == 0) { WriteLine(regString.ToString()); regString.Clear(); } } StringBuilder reghString = new StringBuilder(); for (int i = 0; i < 16; i++) { reghString.AppendFormat(" RH{0:x}=0x{1:x2} ", i, _system.CP.RH[i]); if (((i + 1) % 8) == 0) { WriteLine(reghString.ToString()); reghString.Clear(); } } WriteLine(reghString.ToString()); StringBuilder stackString = new StringBuilder(); // By convention, R0 is TOS in Mesa. stackString.AppendFormat("0x{0:x4} ", _system.CP.ALU.R[0]); for (int i = _system.CP.StackP; i > 0; i--) { stackString.AppendFormat("{0:x4} ", _system.CP.U[i]); } WriteLine(String.Format(" stackP=0x{0:x1} stack: {1}", _system.CP.StackP, stackString)); WriteLine(String.Format( " Q=0x{0:x4} MAR=0x{1:x5} MD=0x{2:x4} pc16={3} ibPtr={4} ibFront=0x{5:x2} ib[0]=0x{6:x2} ib[1]=0x{7:x2}", _system.CP.ALU.Q, _system.MemoryController.MAR, _system.MemoryController.MD, _system.CP.PC16 ? 1 : 0, _system.CP.IBPtr, _system.CP.IBFront, _system.CP.IB[0], _system.CP.IB[1])); WriteLine(String.Format(" Z={0} N={1} Nb={2} Pg={3} C={4} O={5}", _system.CP.ALU.Zero, _system.CP.ALU.Neg, _system.CP.ALU.NibCarry, _system.CP.ALU.PgCarry, _system.CP.ALU.CarryOut, _system.CP.ALU.Overflow)); Microinstruction inst = new Microinstruction(_system.CP.MicrocodeRam[tpc]); int nia = inst.INIA | _system.CP.NIAModifier; WriteLine(String.Format("{0:x3} {1:x12} - {2} (NIA={3:x3}) [c{4}]", tpc, _system.CP.MicrocodeRam[tpc], inst.Disassemble(_system.CP.Cycle), nia, _system.CP.Cycle)); }
private void ReadMap(string mapFile, string sourceRoot) { // // If the file does not exist, we will just start with an empty map. // if (!File.Exists(mapFile)) { return; } using (StreamReader map = new StreamReader(mapFile)) { string sourceFile = string.Empty; ReadState state = ReadState.NextFileHeader; int mapLineNumber = 0; while (!map.EndOfStream) { string line = map.ReadLine().Trim(); mapLineNumber++; if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#")) { // Nothing of note here, continue. continue; } if (line.StartsWith("[")) { // Looks like the start of a file header. state = ReadState.NextFileHeader; } switch (state) { case ReadState.NextFileHeader: // We expect the line to be in the form "[<source path>]" // If this is not the case, then the map file is incorrectly formed. if (line.StartsWith("[")) { int closingBracket = line.LastIndexOf(']'); if (closingBracket < 0) { throw new InvalidOperationException( String.Format("Badly formed source file entry on line {0}", mapLineNumber)); } sourceFile = line.Substring(1, closingBracket - 1).Trim(); state = ReadState.NextSymbolEntry; } else { throw new InvalidOperationException( String.Format("Expected file header on line {0}", mapLineNumber)); } break; case ReadState.NextSymbolEntry: // // This is expected to be a symbol map entry, which looks like // <symbol name 1>, .. , <symbol name N> : <address or value (hex)>,<line number(decimal) in current source file> // string[] symbolAddressTokens = line.Split(':'); if (symbolAddressTokens.Length != 2) { // Should be two tokens here, one on each side of the ':' throw new InvalidOperationException( String.Format("Badly formed symbol entry on line {0}", mapLineNumber)); } // Grab the symbol names. There must be at least one present since the above split succeeded. string[] symbolNames = symbolAddressTokens[0].Trim().Split(','); // Grab the source information. There must be exactly two entries. string[] sourceData = symbolAddressTokens[1].Trim().Split(','); if (sourceData.Length != 2) { throw new InvalidOperationException( String.Format("Badly formed symbol entry on line {0} -- source information is invalid.", mapLineNumber)); } // Convert source info into integers and build a new SourceEntry. int lineNumber = 0; ushort address = 0; try { address = (ushort)Convert.ToInt32(sourceData[0].Trim(), 16); lineNumber = int.Parse(sourceData[1].Trim()) - 1; // line numbers are 1-indexed } catch (Exception) { throw new InvalidOperationException( String.Format("Badly formed symbol entry on line {0} -- source information is invalid.", mapLineNumber)); } SourceEntry newEntry = new SourceEntry(sourceFile, symbolNames, address, lineNumber); AddSourceEntry(newEntry); break; } } } }
public void AddSourceEntry(SourceEntry entry) { // InsertAddressEntry will ensure that no duplicate addresses are added. InsertAddressEntry(entry); InsertSourceEntry(entry); }