Beispiel #1
0
        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;
                    }
                }
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        /// <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;
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
 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);
     }
 }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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 */);
                }
            }
        }
Beispiel #9
0
        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());
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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
            }
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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));
        }
Beispiel #14
0
        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;
                    }
                }
            }
        }
Beispiel #15
0
 public void AddSourceEntry(SourceEntry entry)
 {
     // InsertAddressEntry will ensure that no duplicate addresses are added.
     InsertAddressEntry(entry);
     InsertSourceEntry(entry);
 }