예제 #1
0
 /// <summary>
 /// Applies the LabelMap to the label.  If the LabelMap is null, or does not have an
 /// entry for the label, the original label is returned.
 /// </summary>
 /// <param name="label">Label to convert.</param>
 /// <returns>New label, or original label.</returns>
 public string ConvLabel(string label)
 {
     if (LabelMap != null)
     {
         if (LabelMap.TryGetValue(label, out string newLabel))
         {
             label = newLabel;
         }
     }
     return(label);
 }
예제 #2
0
        /// <summary>
        /// Remaps labels that match opcode names.  Updated names will be added to LabelMap.
        /// This should be run after localization and underscore concealment have finished.
        /// </summary>
        /// <remarks>
        /// Most assemblers don't like it if you create a label with the same name as an
        /// opcode, e.g. "jmp LSR" doesn't work.  We can use the label map to work around
        /// the issue.
        ///
        /// Most assemblers regard mnemonics as case-insensitive, even if labels are
        /// case-sensitive, so we want to remap both "lsr" and "LSR".
        ///
        /// This doesn't really have anything to do with label localization other than that
        /// we're updating the label remap table.
        /// </remarks>
        public void FixOpcodeLabels()
        {
            if (LabelMap == null)
            {
                LabelMap = new Dictionary <string, string>();
            }

            // Create a searchable list of opcode names using the current CPU definition.
            // (All tested assemblers that failed on opcode names only did so for names
            // that were part of the current definition, e.g. "TSB" was accepted as a label
            // when the CPU was set to 6502.)
            Dictionary <string, Asm65.OpDef> opnames = new Dictionary <string, Asm65.OpDef>();

            Asm65.CpuDef cpuDef = mProject.CpuDef;
            for (int i = 0; i < 256; i++)
            {
                Asm65.OpDef op = cpuDef.GetOpDef(i);
                // There may be multiple entries with the same name (e.g. "NOP").  That's fine.
                opnames[op.Mnemonic.ToUpperInvariant()] = op;
            }

            // Create a list of all labels, for uniqueness testing.  If a label has been
            // remapped, we add the remapped entry.
            // (All tested assemblers that failed on opcode names only did so for names
            // in their non-localized form.  While "LSR" failed, "@LSR", "_LSR", ".LSR", etc.
            // were accepted.  So if it  was remapped by the localizer, we don't need to
            // worry about it.)
            SortedList <string, string> allLabels = new SortedList <string, string>();

            for (int i = 0; i < mProject.FileDataLength; i++)
            {
                Symbol sym = mProject.GetAnattrib(i).Symbol;
                if (sym == null)
                {
                    continue;
                }
                LabelMap.TryGetValue(sym.Label, out string mapLabel);
                if (mapLabel != null)
                {
                    allLabels.Add(mapLabel, mapLabel);
                }
                else
                {
                    allLabels.Add(sym.Label, sym.Label);
                }
            }

            // Now run through the list of labels, looking for any that match opcode
            // mnemonics.
            for (int i = 0; i < mProject.FileDataLength; i++)
            {
                Symbol sym = mProject.GetAnattrib(i).Symbol;
                if (sym == null)
                {
                    // No label at this offset.
                    continue;
                }
                string cmpLabel = sym.Label;
                if (LabelMap.TryGetValue(sym.Label, out string mapLabel))
                {
                    cmpLabel = mapLabel;
                }

                if (opnames.ContainsKey(cmpLabel.ToUpperInvariant()))
                {
                    //Debug.WriteLine("Remapping label (op mnemonic): " + sym.Label);

                    int    uval = 0;
                    string uniqueLabel;
                    do
                    {
                        uval++;
                        uniqueLabel = cmpLabel + "_" + uval.ToString();
                    } while (allLabels.ContainsKey(uniqueLabel));

                    allLabels.Add(uniqueLabel, uniqueLabel);
                    LabelMap.Add(sym.Label, uniqueLabel);
                }
            }

            if (LabelMap.Count == 0)
            {
                // didn't do anything, lose the table
                LabelMap = null;
            }
        }