예제 #1
0
        private FormattedSymbol CreateFormattedSymbol(DefSymbol defSym)
        {
            string typeStr;

            if (defSym.IsConstant)
            {
                typeStr = Res.Strings.ABBREV_CONSTANT;
            }
            else
            {
                typeStr = Res.Strings.ABBREV_ADDRESS;

                if (defSym.Direction == DefSymbol.DirectionFlags.Read)
                {
                    typeStr += "<";
                }
                else if (defSym.Direction == DefSymbol.DirectionFlags.Write)
                {
                    typeStr += ">";
                }
            }

            FormattedSymbol fsym = new FormattedSymbol(
                defSym,
                defSym.GenerateDisplayLabel(mFormatter),
                mFormatter.FormatValueInBase(defSym.Value, defSym.DataDescriptor.NumBase),
                typeStr,
                defSym.HasWidth ? defSym.DataDescriptor.Length.ToString() : NO_WIDTH_STR,
                defSym.Comment);

            return(fsym);
        }
예제 #2
0
        /// <summary>
        /// Constructor.  lvt will be null when creating a new entry.
        /// </summary>
        public EditLocalVariableTable(Window owner, DisasmProject project, Formatter formatter,
                                      LocalVariableTable lvt, int offset)
        {
            InitializeComponent();
            Owner       = owner;
            DataContext = this;

            mProject     = project;
            mFormatter   = formatter;
            mSymbolTable = project.SymbolTable;
            mOffset      = NewOffset = offset;

            if (lvt != null)
            {
                mWorkTable     = new LocalVariableTable(lvt);
                mIsNotNewTable = true;
            }
            else
            {
                mWorkTable = new LocalVariableTable();
            }

            for (int i = 0; i < mWorkTable.Count; i++)
            {
                DefSymbol defSym = mWorkTable[i];
                Variables.Add(CreateFormattedSymbol(defSym));
            }
        }
예제 #3
0
        private void projectSymbolsListView_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ListViewHitTestInfo info   = projectSymbolsListView.HitTest(e.X, e.Y);
            DefSymbol           defSym = WorkProps.ProjectSyms[info.Item.Text];

            DoEditSymbol(defSym);
        }
예제 #4
0
        /// <summary>
        /// Loads the project symbols into the ListView.
        /// </summary>
        private void LoadProjectSymbols()
        {
            // The set should be small enough that we don't need to worry about updating
            // the item list incrementally.
            //Debug.WriteLine("LPS loading " + WorkProps.ProjectSyms.Count + " project symbols");
            projectSymbolsListView.BeginUpdate();
            projectSymbolsListView.Items.Clear();
            foreach (KeyValuePair <string, DefSymbol> kvp in WorkProps.ProjectSyms)
            {
                DefSymbol defSym = kvp.Value;
                string    typeStr;
                if (defSym.SymbolType == Symbol.Type.Constant)
                {
                    typeStr = Properties.Resources.ABBREV_CONSTANT;
                }
                else
                {
                    typeStr = Properties.Resources.ABBREV_ADDRESS;
                }

                ListViewItem lvi = new ListViewItem();
                lvi.Text           = defSym.Label;
                mSymbolSubArray[0] = new ListViewItem.ListViewSubItem(lvi,
                                                                      NumFormatter.FormatValueInBase(defSym.Value, defSym.DataDescriptor.NumBase));
                mSymbolSubArray[1] = new ListViewItem.ListViewSubItem(lvi, typeStr);
                mSymbolSubArray[2] = new ListViewItem.ListViewSubItem(lvi, defSym.Comment);
                lvi.SubItems.AddRange(mSymbolSubArray);

                projectSymbolsListView.Items.Add(lvi);
            }
            projectSymbolsListView.EndUpdate();
        }
예제 #5
0
        private void DoEditSymbol(DefSymbol defSym)
        {
            EditDefSymbol dlg = new EditDefSymbol(this, mFormatter, mWorkTable.GetSortedByLabel(),
                                                  defSym, mSymbolTable, true, false);

            dlg.ShowDialog();
            if (dlg.DialogResult == true)
            {
                // Label might have changed, so remove old before adding new.
                mWorkTable.RemoveByLabel(defSym.Label);
                mWorkTable.AddOrReplace(dlg.NewSym);

                // Replace entry in items source.
                for (int i = 0; i < Variables.Count; i++)
                {
                    if (Variables[i].DefSym == defSym)
                    {
                        Variables[i] = CreateFormattedSymbol(dlg.NewSym);
                        break;
                    }
                }

                UpdateControls();
            }
        }
예제 #6
0
        /// <summary>
        /// Constructor, for editing a local variable, or editing a project symbol with
        /// the value field locked.
        /// </summary>
        /// <remarks>
        /// TODO(someday): disable the "constant" radio button unless CPU=65816.
        /// </remarks>
        public EditDefSymbol(Window owner, Formatter formatter,
                             SortedList <string, DefSymbol> defList, DefSymbol defSym,
                             SymbolTable symbolTable, bool isVariable, bool lockValueAndType)
        {
            InitializeComponent();
            Owner       = owner;
            DataContext = this;

            mNumFormatter         = formatter;
            mDefSymbolList        = defList;
            mOldSym               = defSym;
            mSymbolTable          = symbolTable;
            IsVariable            = isVariable;
            mReadOnlyValueAndType = lockValueAndType;

            Label = Value = VarWidth = Comment = string.Empty;

            int maxWidth;

            if (isVariable)
            {
                ConstantLabel = (string)FindResource("str_VariableConstant");
                maxWidth      = 256;
            }
            else
            {
                ConstantLabel = (string)FindResource("str_ProjectConstant");
                maxWidth      = 65536;
            }
            mIsWidthOptional = !isVariable;

            string fmt = (string)FindResource("str_WidthLimitFmt");

            WidthLimitLabel = string.Format(fmt, maxWidth);
        }
예제 #7
0
        private void RemoveSymbolButton_Click(object sender, RoutedEventArgs e)
        {
            // Single-select list view, button dimmed when no selection.
            Debug.Assert(symbolsList.SelectedItems.Count == 1);

            int             selectionIndex = symbolsList.SelectedIndex;
            FormattedSymbol item           = (FormattedSymbol)symbolsList.SelectedItems[0];
            DefSymbol       defSym         = item.DefSym;

            mWorkTable.RemoveByLabel(defSym.Label);
            for (int i = 0; i < Variables.Count; i++)
            {
                if (Variables[i].DefSym == defSym)
                {
                    Variables.RemoveAt(i);
                    break;
                }
            }
            UpdateControls();

            // Restore selection to the item that used to come after the one we just deleted,
            // so you can hit "Remove" repeatedly to delete multiple items.
            int newCount = symbolsList.Items.Count;

            if (selectionIndex >= newCount)
            {
                selectionIndex = newCount - 1;
            }
            if (selectionIndex >= 0)
            {
                symbolsList.SelectedIndex = selectionIndex;
                removeSymbolButton.Focus();     // so you can keep banging on Enter
            }
        }
예제 #8
0
        private void DoEditSymbol(DefSymbol defSym)
        {
            EditDefSymbol dlg = new EditDefSymbol(this, mFormatter, mWorkProps.ProjectSyms,
                                                  defSym, defSym, null);

            dlg.ShowDialog();
            if (dlg.DialogResult == true)
            {
                // Label might have changed, so remove old before adding new.
                mWorkProps.ProjectSyms.Remove(defSym.Label);
                mWorkProps.ProjectSyms[dlg.NewSym.Label] = dlg.NewSym;
                IsDirty = true;

                // Replace entry in items source.
                int i;
                for (i = 0; i < ProjectSymbols.Count; i++)
                {
                    if (ProjectSymbols[i].DefSym == defSym)
                    {
                        ProjectSymbols[i] = CreateFormattedSymbol(dlg.NewSym);
                        break;
                    }
                }
                Debug.Assert(i != ProjectSymbols.Count);

                UpdateControls();
                okButton.Focus();
            }
        }
예제 #9
0
        private void removeSymbolButton_Click(object sender, EventArgs e)
        {
            // Single-select list view, button dimmed when no selection.
            Debug.Assert(projectSymbolsListView.SelectedItems.Count == 1);

            int          selectionIndex = projectSymbolsListView.SelectedIndices[0];
            ListViewItem item           = projectSymbolsListView.SelectedItems[0];
            DefSymbol    defSym         = WorkProps.ProjectSyms[item.Text];

            WorkProps.ProjectSyms.Remove(defSym.Label);
            mDirty = true;
            LoadProjectSymbols();
            UpdateControls();

            // Restore selection, so you can hit "Remove" repeatedly to delete
            // multiple items.
            int newCount = projectSymbolsListView.Items.Count;

            if (selectionIndex >= newCount)
            {
                selectionIndex = newCount - 1;
            }
            if (selectionIndex >= 0)
            {
                projectSymbolsListView.SelectedIndices.Add(selectionIndex);
                removeSymbolButton.Focus();
            }
        }
예제 #10
0
        private void editSymbolButton_Click(object sender, EventArgs e)
        {
            // Single-select list view, button dimmed when no selection.
            Debug.Assert(projectSymbolsListView.SelectedItems.Count == 1);
            ListViewItem item   = projectSymbolsListView.SelectedItems[0];
            DefSymbol    defSym = WorkProps.ProjectSyms[item.Text];

            DoEditSymbol(defSym);
        }
예제 #11
0
        private void EditSymbolButton_Click(object sender, EventArgs e)
        {
            // Single-select list view, button dimmed when no selection.
            Debug.Assert(projectSymbolsList.SelectedItems.Count == 1);
            FormattedSymbol item   = (FormattedSymbol)projectSymbolsList.SelectedItems[0];
            DefSymbol       defSym = mWorkProps.ProjectSyms[item.Label];

            DoEditSymbol(defSym);
        }
예제 #12
0
        private void okButton_Click(object sender, EventArgs e)
        {
            bool isConstant = constantRadioButton.Checked;

            ParseValue(out int value, out int numBase);
            FormatDescriptor.SubType subType = FormatDescriptor.GetSubTypeForBase(numBase);
            DefSym = new DefSymbol(labelTextBox.Text, value, Symbol.Source.Project,
                                   isConstant ? Symbol.Type.Constant : Symbol.Type.ExternalAddr,
                                   subType, commentTextBox.Text, string.Empty);
        }
예제 #13
0
 public FormattedSymbol(DefSymbol defSym, string label, string value,
                        string type, string width, string comment)
 {
     DefSym  = defSym;
     Label   = label;
     Value   = value;
     Type    = type;
     Width   = width;
     Comment = comment;
 }
예제 #14
0
        private void EditSymbolButton_Click(object sender, EventArgs e)
        {
            // Single-select list view, button dimmed when no selection.
            Debug.Assert(symbolsList.SelectedItems.Count == 1);
            FormattedSymbol item   = (FormattedSymbol)symbolsList.SelectedItems[0];
            DefSymbol       defSym = mWorkTable.GetByLabel(item.Label);

            Debug.Assert(defSym != null);
            DoEditSymbol(defSym);
        }
예제 #15
0
        private void SymbolsList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (!symbolsList.GetClickRowColItem(e, out int unusedRow, out int unusedCol,
                                                out object objItem))
            {
                // Header or empty area; ignore.
                return;
            }
            FormattedSymbol item   = (FormattedSymbol)objItem;
            DefSymbol       defSym = mWorkTable.GetByLabel(item.Label);

            DoEditSymbol(defSym);
        }
예제 #16
0
파일: AsmAcme.cs 프로젝트: X65/6502bench
        // IGenerator
        public void OutputLocalVariableTable(int offset, List <DefSymbol> newDefs,
                                             LocalVariableTable allDefs)
        {
            OutputLine(string.Empty, "!zone", "Z" + offset.ToString("x6"), string.Empty);
            for (int i = 0; i < allDefs.Count; i++)
            {
                DefSymbol defSym = allDefs[i];

                string valueStr = PseudoOp.FormatNumericOperand(SourceFormatter,
                                                                Project.SymbolTable, null, defSym.DataDescriptor, defSym.Value, 1,
                                                                PseudoOp.FormatNumericOpFlags.None);
                OutputEquDirective(SourceFormatter.FormatVariableLabel(defSym.Label),
                                   valueStr, defSym.Comment);
            }
        }
예제 #17
0
        private void OkButton_Click(object sender, RoutedEventArgs e)
        {
            ParseValue(out int value, out int numBase);
            FormatDescriptor.SubType subType = FormatDescriptor.GetSubTypeForBase(numBase);
            int width = -1;

            if (IsConstant && !IsVariable)
            {
                // width field is ignored, don't bother parsing
            }
            else if (!string.IsNullOrEmpty(VarWidth))
            {
                bool ok = Asm65.Number.TryParseInt(VarWidth, out width, out int unusedNumBase);
                Debug.Assert(ok);
            }

            DefSymbol.DirectionFlags direction;
            if (IsReadChecked && IsWriteChecked)
            {
                direction = DefSymbol.DirectionFlags.ReadWrite;
            }
            else if (IsReadChecked)
            {
                direction = DefSymbol.DirectionFlags.Read;
            }
            else if (IsWriteChecked)
            {
                direction = DefSymbol.DirectionFlags.Write;
            }
            else
            {
                Debug.Assert(false);
                direction = DefSymbol.DirectionFlags.None;
            }

            // Parse and strip the annotation.
            string trimLabel = Symbol.TrimAndValidateLabel(Label, string.Empty, out bool unused1,
                                                           out bool unused2, out bool unused3, out bool unused4,
                                                           out Symbol.LabelAnnotation anno);

            NewSym = new DefSymbol(trimLabel, value,
                                   IsVariable ? Symbol.Source.Variable : Symbol.Source.Project,
                                   IsConstant ? Symbol.Type.Constant : Symbol.Type.ExternalAddr, anno,
                                   subType, width, width > 0, Comment, direction, null, string.Empty);

            DialogResult = true;
        }
예제 #18
0
        private void DoEditSymbol(DefSymbol defSym)
        {
            EditDefSymbol dlg = new EditDefSymbol(NumFormatter, WorkProps.ProjectSyms);

            dlg.DefSym = defSym;
            dlg.ShowDialog();
            if (dlg.DialogResult == DialogResult.OK)
            {
                // Label might have changed, so remove old before adding new.
                WorkProps.ProjectSyms.Remove(defSym.Label);
                WorkProps.ProjectSyms[dlg.DefSym.Label] = dlg.DefSym;
                mDirty = true;
                LoadProjectSymbols();
                UpdateControls();
            }
            dlg.Dispose();
        }
예제 #19
0
        // IGenerator
        public void OutputLocalVariableTable(int offset, List <DefSymbol> newDefs,
                                             LocalVariableTable allDefs)
        {
            // We can do better here, but it requires knowing whether anything in "newDefs"
            // overwrote a previous entry.  If everything is new, we don't need to start
            // a new zone, and can just output newDefs.  (We don't need to start a new zone
            // on a "clear previous".)
            OutputLine(string.Empty, "!zone", "Z" + offset.ToString("x6"), string.Empty);
            for (int i = 0; i < allDefs.Count; i++)
            {
                DefSymbol defSym = allDefs[i];

                string valueStr = PseudoOp.FormatNumericOperand(SourceFormatter,
                                                                Project.SymbolTable, null, defSym.DataDescriptor, defSym.Value, 1,
                                                                PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix);
                OutputEquDirective(SourceFormatter.FormatVariableLabel(defSym.Label),
                                   valueStr, defSym.Comment);
            }
        }
예제 #20
0
        /// <summary>
        /// Prepares the project symbols ListView.
        /// </summary>
        private void LoadProjectSymbols()
        {
            ProjectSymbols.Clear();

            foreach (KeyValuePair <string, DefSymbol> kvp in mWorkProps.ProjectSyms)
            {
                DefSymbol defSym = kvp.Value;
                ProjectSymbols.Add(CreateFormattedSymbol(defSym));
            }

            // This doesn't seem to enable "live sorting".  It does an initial sort, but
            // without calling the Sorting function.  I'm not sure what the point of this is,
            // or how to cause the DataGrid to behave like somebody clicked on a header.

            //ICollectionView view =
            //    CollectionViewSource.GetDefaultView(projectSymbolsList.ItemsSource);
            //SortDescriptionCollection sortDes = view.SortDescriptions;
            //sortDes.Add(new SortDescription("Value", ListSortDirection.Descending));
            //projectSymbolsList.Columns[0].SortDirection = ListSortDirection.Ascending;
            //view.Refresh();
        }
예제 #21
0
        /// <summary>
        /// Loads entries from the work table into the items source.
        /// </summary>
        private FormattedSymbol CreateFormattedSymbol(DefSymbol defSym)
        {
            string typeStr;

            if (defSym.IsConstant)
            {
                typeStr = Res.Strings.ABBREV_STACK_RELATIVE;
            }
            else
            {
                typeStr = Res.Strings.ABBREV_ADDRESS;
            }

            FormattedSymbol fsym = new FormattedSymbol(
                defSym,
                defSym.GenerateDisplayLabel(mFormatter),
                mFormatter.FormatValueInBase(defSym.Value, defSym.DataDescriptor.NumBase),
                typeStr,
                defSym.DataDescriptor.Length,
                defSym.Comment);

            return(fsym);
        }
예제 #22
0
        private void RemoveSymbolButton_Click(object sender, RoutedEventArgs e)
        {
            // Single-select list view, button dimmed when no selection.
            Debug.Assert(projectSymbolsList.SelectedItems.Count == 1);

            int             selectionIndex = projectSymbolsList.SelectedIndex;
            FormattedSymbol item           = (FormattedSymbol)projectSymbolsList.SelectedItems[0];
            DefSymbol       defSym         = item.DefSym;

            mWorkProps.ProjectSyms.Remove(defSym.Label);
            IsDirty = true;

            for (int i = 0; i < ProjectSymbols.Count; i++)
            {
                if (ProjectSymbols[i].DefSym == defSym)
                {
                    ProjectSymbols.RemoveAt(i);
                    break;
                }
            }
            UpdateControls();

            // Restore selection to the item that used to come after the one we just deleted,
            // so you can hit "Remove" repeatedly to delete multiple items.
            int newCount = projectSymbolsList.Items.Count;

            if (selectionIndex >= newCount)
            {
                selectionIndex = newCount - 1;
            }
            if (selectionIndex >= 0)
            {
                projectSymbolsList.SelectedIndex = selectionIndex;
                removeSymbolButton.Focus();
            }
        }
예제 #23
0
        /// <summary>
        /// Gathers a list of platform symbols from the project's symbol table.
        /// </summary>
        private List <PlatSym> GeneratePlatSymList()
        {
            List <PlatSym> platSyms = new List <PlatSym>();
            SymbolTable    symTab   = mProject.SymbolTable;

            foreach (Symbol sym in symTab)
            {
                if (!(sym is DefSymbol))
                {
                    // ignore user labels
                    continue;
                }
                DefSymbol defSym = sym as DefSymbol;
                if (defSym.SymbolSource != Symbol.Source.Platform)
                {
                    // ignore project symbols
                    continue;
                }

                platSyms.Add(new PlatSym(defSym.Label, defSym.Value, defSym.Tag));
            }

            return(platSyms);
        }
예제 #24
0
        /// <summary>
        /// Validates input and updates controls appropriately.
        /// </summary>
        private void UpdateControls()
        {
            if (!IsLoaded)
            {
                return;
            }

            // Label must be valid and not already exist in the table we're editing.  (For project
            // symbols, it's okay if an identical label exists elsewhere.)
            bool labelValid = Asm65.Label.ValidateLabel(Label);
            bool labelUnique;

            // NOTE: should be using Asm65.Label.LABEL_COMPARER?
            if (mDefSymbolList.TryGetValue(Label, out DefSymbol existing))
            {
                // It's okay if it's the same object.
                labelUnique = (existing == mOldSym);
            }
            else
            {
                labelUnique = true;
            }

            // For local variables, do a secondary uniqueness check across the full symbol table.
            if (labelUnique && mSymbolTable != null)
            {
                labelUnique = !mSymbolTable.TryGetValue(Label, out Symbol sym);

                // It's okay if this and the other are both variables.
                if (!labelUnique && IsVariable && sym.IsVariable)
                {
                    labelUnique = true;
                }
            }

            // Value must be blank, meaning "erase any earlier definition", or valid value.
            // (Hmm... don't currently have a way to specify "no symbol" in DefSymbol.)
            //if (!string.IsNullOrEmpty(valueTextBox.Text)) {
            bool valueValid = ParseValue(out int thisValue, out int unused2);
            //} else {
            //    valueValid = true;
            //}

            bool widthValid = true;
            int  thisWidth  = -1;

            if (IsConstant && !IsVariable)
            {
                // width field is ignored
            }
            else if (string.IsNullOrEmpty(VarWidth))
            {
                // blank field is okay if the width is optional
                widthValid = mIsWidthOptional;
            }
            else if (!Asm65.Number.TryParseInt(VarWidth, out thisWidth, out int unusedBase) ||
                     thisWidth < DefSymbol.MIN_WIDTH || thisWidth > DefSymbol.MAX_WIDTH ||
                     (IsVariable && thisWidth > 256))
            {
                // All widths must be between 1 and 65536.  For a variable, the full thing must
                // fit on zero page without wrapping.  We test for 256 here so that we highlight
                // the "bad width" label, rather than the "it doesn't fit on the page" label.
                widthValid = false;
            }

            bool valueRangeValid = true;

            if (IsVariable && valueValid && widthValid)
            {
                // $ff with width 1 is okay, $ff with width 2 is not
                if (thisValue < 0 || thisValue + thisWidth > 256)
                {
                    valueRangeValid = false;
                }
            }

            Symbol.Type symbolType = IsConstant ? Symbol.Type.Constant : Symbol.Type.ExternalAddr;

            // For a variable, the value must also be unique within the table.  Values have
            // width, so we need to check for overlap.
            bool valueUniqueValid = true;

            if (IsVariable && valueValid && widthValid)
            {
                foreach (KeyValuePair <string, DefSymbol> kvp in mDefSymbolList)
                {
                    if (kvp.Value != mOldSym &&
                        DefSymbol.CheckOverlap(kvp.Value, thisValue, thisWidth, symbolType))
                    {
                        valueUniqueValid = false;
                        break;
                    }
                }
            }

            bool rwValid = true;

            if (!IsVariable && IsAddress)
            {
                rwValid = IsReadChecked || IsWriteChecked;
            }

            labelNotesLabel.Foreground  = labelValid ? mDefaultLabelColor : Brushes.Red;
            labelUniqueLabel.Foreground = projectLabelUniqueLabel.Foreground =
                labelUnique ? mDefaultLabelColor : Brushes.Red;
            valueNotesLabel.Foreground     = valueValid ? mDefaultLabelColor : Brushes.Red;
            varValueRangeLabel.Foreground  = valueRangeValid ? mDefaultLabelColor : Brushes.Red;
            varValueUniqueLabel.Foreground = valueUniqueValid ? mDefaultLabelColor : Brushes.Red;
            widthNotesLabel.Foreground     = widthValid ? mDefaultLabelColor : Brushes.Red;
            checkReadWriteLabel.Foreground = rwValid ? mDefaultLabelColor : Brushes.Red;

            IsValid = labelValid && labelUnique && valueValid && valueRangeValid &&
                      valueUniqueValid && widthValid && rwValid;
        }
예제 #25
0
        /// <summary>
        /// Validates input and updates controls appropriately.
        /// </summary>
        private void UpdateControls()
        {
            if (!IsLoaded)
            {
                return;
            }

            // Label must be valid and not already exist in the table we're editing.  (For project
            // symbols, it's okay if an identical label exists elsewhere.)
            string trimLabel = Symbol.TrimAndValidateLabel(Label, string.Empty,
                                                           out bool labelValid, out bool unused1, out bool unused2, out bool unused3,
                                                           out Symbol.LabelAnnotation unused4);
            bool labelUnique;

            if (mDefSymbolList.TryGetValue(trimLabel, out DefSymbol existing))
            {
                // We found a match.  See if we're just seeing the symbol we're editing.
                // If there's no "original" symbol, then the fact that we matched anything
                // means the label is not unique.  Otherwise, we consider it unique if the
                // label matches the original symbol.
                //
                // We only need to check the label.  Since we're comparing the original
                // symbol to the value from the symbol table, it should be a total match,
                // but the other fields don't actually matter.  It's safer to let the Symbol
                // class comparison operators do the work though.
                labelUnique = (existing == mOrigSym);
                //labelUnique = mOrigSym != null &&
                //    Asm65.Label.LABEL_COMPARER.Equals(existing.Label, mOrigSym.Label);
            }
            else
            {
                labelUnique = true;
            }

            // For local variables, do a secondary uniqueness check across the full symbol table.
            if (labelUnique && mSymbolTable != null)
            {
                labelUnique = !mSymbolTable.TryGetValue(trimLabel, out Symbol sym);

                // It's okay if this and the other are both variables.
                if (!labelUnique && IsVariable && sym.IsVariable)
                {
                    labelUnique = true;
                }
            }

            // Value must be blank, meaning "erase any earlier definition", or valid value.
            // (Hmm... don't currently have a way to specify "no symbol" in DefSymbol.)
            //if (!string.IsNullOrEmpty(valueTextBox.Text)) {
            bool valueValid = ParseValue(out int thisValue, out int unused5);
            //} else {
            //    valueValid = true;
            //}

            bool widthValid = true;
            int  thisWidth  = -1;

            if (IsConstant && !IsVariable)
            {
                // width field is ignored
            }
            else if (string.IsNullOrEmpty(VarWidth))
            {
                // blank field is okay if the width is optional
                widthValid = mIsWidthOptional;
            }
            else if (!Asm65.Number.TryParseInt(VarWidth, out thisWidth, out int unusedBase) ||
                     thisWidth < DefSymbol.MIN_WIDTH || thisWidth > DefSymbol.MAX_WIDTH ||
                     (IsVariable && thisWidth > MAX_VAR_WIDTH))
            {
                // All widths must be between 1 and 65536.  For a variable, the full thing must
                // fit on zero page, except on 65816 where a 16-bit access at $ff can extend
                // off the end of the direct page.
                //
                // We test the variable width here so that we highlight the "width limit" label,
                // rather than the "value range" label.
                widthValid = false;
            }

            bool valueRangeValid = true;

            if (IsVariable && valueValid && widthValid)
            {
                // $ff with width 1 is okay, $ff with width 2 is okay on 65816, width=3 is bad
                if (thisValue < 0 || thisValue + thisWidth > MAX_VAR_WIDTH)
                {
                    valueRangeValid = false;
                }
            }
            else if (IsAddress && valueValid)
            {
                // limit to positive 24-bit integers; use a long for value+width so we
                // don't get fooled by overflow
                long lvalue = thisValue;
                if (thisWidth > 0)
                {
                    lvalue += thisWidth - 1;
                }
                if (thisValue < 0 || lvalue > 0x00ffffff)
                {
                    valueRangeValid = false;
                }
            }

            Symbol.Type symbolType = IsConstant ? Symbol.Type.Constant : Symbol.Type.ExternalAddr;

            // For a variable, the value must also be unique within the table.  Values have
            // width, so we need to check for overlap.
            bool valueUniqueValid = true;

            if (IsVariable && valueValid && widthValid)
            {
                foreach (KeyValuePair <string, DefSymbol> kvp in mDefSymbolList)
                {
                    if (kvp.Value != mOrigSym &&
                        DefSymbol.CheckOverlap(kvp.Value, thisValue, thisWidth, symbolType))
                    {
                        valueUniqueValid = false;
                        break;
                    }
                }
            }

            bool rwValid = true;

            if (!IsVariable && IsAddress)
            {
                rwValid = IsReadChecked || IsWriteChecked;
            }

            labelNotesLabel.Foreground  = labelValid ? mDefaultLabelColor : Brushes.Red;
            labelUniqueLabel.Foreground = projectLabelUniqueLabel.Foreground =
                labelUnique ? mDefaultLabelColor : Brushes.Red;
            valueNotesLabel.Foreground     = valueValid ? mDefaultLabelColor : Brushes.Red;
            addrValueRangeLabel.Foreground = valueRangeValid ? mDefaultLabelColor : Brushes.Red;
            varValueRangeLabel.Foreground  = valueRangeValid ? mDefaultLabelColor : Brushes.Red;
            varValueUniqueLabel.Foreground = valueUniqueValid ? mDefaultLabelColor : Brushes.Red;
            widthNotesLabel.Foreground     = widthValid ? mDefaultLabelColor : Brushes.Red;
            checkReadWriteLabel.Foreground = rwValid ? mDefaultLabelColor : Brushes.Red;

            IsValid = labelValid && labelUnique && valueValid && valueRangeValid &&
                      valueUniqueValid && widthValid && rwValid;
        }
예제 #26
0
 /// <summary>
 /// Constructor, for editing a project or platform symbol.
 /// </summary>
 public EditDefSymbol(Window owner, Formatter formatter,
                      SortedList <string, DefSymbol> defList, DefSymbol defSym,
                      SymbolTable symbolTable)
     : this(owner, formatter, defList, defSym, symbolTable, false, false)
 {
 }
예제 #27
0
        /// <summary>
        /// Validates input and updates controls appropriately.
        /// </summary>
        private void UpdateControls()
        {
            if (!IsLoaded)
            {
                return;
            }

            // Label must be valid and not already exist in the table we're editing.  (For project
            // symbols, it's okay if an identical label exists elsewhere.)
            string trimLabel = Symbol.TrimAndValidateLabel(Label, string.Empty,
                                                           out bool labelValid, out bool unused1, out bool unused2, out bool unused3,
                                                           out Symbol.LabelAnnotation unused4);
            bool labelUnique;

            if (mDefSymbolList.TryGetValue(trimLabel, out DefSymbol existing))
            {
                // We found a match.  See if we're just seeing the symbol we're editing.
                //
                // We only want to check the label, not the entire symbol, because otherwise
                // things can go funny when multiple edits are done without flushing the data
                // back to the symbol table.  For example, when this is invoked from the
                // Edit Project Symbol button in the instruction operand editor, the user might
                // edit the comment field of an existing project symbol, hit OK here, then try
                // to edit it again before closing the operand editor.  In that case we get
                // passed the edited DefSymbol, which no longer fully matches what's in the
                // symbol table.
                //
                // TODO: we still don't handle the case where the user changes the label from
                // FOO to FOO1 and then back to FOO without closing the instruction edit dialog.
                // The problem is that we find a match for FOO in the symbol table without
                // realizing that it was the original name before the edits began.  To fix this
                // we need to pass in the original label as well as the recently-edited symbol,
                // and allow the new name to match either.

                //labelUnique = (existing == mOldSym);
                labelUnique = Asm65.Label.LABEL_COMPARER.Equals(existing.Label, mOldSym.Label);
            }
            else
            {
                labelUnique = true;
            }

            // For local variables, do a secondary uniqueness check across the full symbol table.
            if (labelUnique && mSymbolTable != null)
            {
                labelUnique = !mSymbolTable.TryGetValue(trimLabel, out Symbol sym);

                // It's okay if this and the other are both variables.
                if (!labelUnique && IsVariable && sym.IsVariable)
                {
                    labelUnique = true;
                }
            }

            // Value must be blank, meaning "erase any earlier definition", or valid value.
            // (Hmm... don't currently have a way to specify "no symbol" in DefSymbol.)
            //if (!string.IsNullOrEmpty(valueTextBox.Text)) {
            bool valueValid = ParseValue(out int thisValue, out int unused5);
            //} else {
            //    valueValid = true;
            //}

            bool widthValid = true;
            int  thisWidth  = -1;

            if (IsConstant && !IsVariable)
            {
                // width field is ignored
            }
            else if (string.IsNullOrEmpty(VarWidth))
            {
                // blank field is okay if the width is optional
                widthValid = mIsWidthOptional;
            }
            else if (!Asm65.Number.TryParseInt(VarWidth, out thisWidth, out int unusedBase) ||
                     thisWidth < DefSymbol.MIN_WIDTH || thisWidth > DefSymbol.MAX_WIDTH ||
                     (IsVariable && thisWidth > MAX_VAR_WIDTH))
            {
                // All widths must be between 1 and 65536.  For a variable, the full thing must
                // fit on zero page, except on 65816 where a 16-bit access at $ff can extend
                // off the end of the direct page.
                //
                // We test the variable width here so that we highlight the "width limit" label,
                // rather than the "value range" label.
                widthValid = false;
            }

            bool valueRangeValid = true;

            if (IsVariable && valueValid && widthValid)
            {
                // $ff with width 1 is okay, $ff with width 2 is okay on 65816, width=3 is bad
                if (thisValue < 0 || thisValue + thisWidth > MAX_VAR_WIDTH)
                {
                    valueRangeValid = false;
                }
            }
            else if (IsAddress && valueValid)
            {
                // limit to positive 24-bit integers; use a long for value+width so we
                // don't get fooled by overflow
                long lvalue = thisValue;
                if (thisWidth > 0)
                {
                    lvalue += thisWidth - 1;
                }
                if (thisValue < 0 || lvalue > 0x00ffffff)
                {
                    valueRangeValid = false;
                }
            }

            Symbol.Type symbolType = IsConstant ? Symbol.Type.Constant : Symbol.Type.ExternalAddr;

            // For a variable, the value must also be unique within the table.  Values have
            // width, so we need to check for overlap.
            bool valueUniqueValid = true;

            if (IsVariable && valueValid && widthValid)
            {
                foreach (KeyValuePair <string, DefSymbol> kvp in mDefSymbolList)
                {
                    if (kvp.Value != mOldSym &&
                        DefSymbol.CheckOverlap(kvp.Value, thisValue, thisWidth, symbolType))
                    {
                        valueUniqueValid = false;
                        break;
                    }
                }
            }

            bool rwValid = true;

            if (!IsVariable && IsAddress)
            {
                rwValid = IsReadChecked || IsWriteChecked;
            }

            labelNotesLabel.Foreground  = labelValid ? mDefaultLabelColor : Brushes.Red;
            labelUniqueLabel.Foreground = projectLabelUniqueLabel.Foreground =
                labelUnique ? mDefaultLabelColor : Brushes.Red;
            valueNotesLabel.Foreground     = valueValid ? mDefaultLabelColor : Brushes.Red;
            addrValueRangeLabel.Foreground = valueRangeValid ? mDefaultLabelColor : Brushes.Red;
            varValueRangeLabel.Foreground  = valueRangeValid ? mDefaultLabelColor : Brushes.Red;
            varValueUniqueLabel.Foreground = valueUniqueValid ? mDefaultLabelColor : Brushes.Red;
            widthNotesLabel.Foreground     = widthValid ? mDefaultLabelColor : Brushes.Red;
            checkReadWriteLabel.Foreground = rwValid ? mDefaultLabelColor : Brushes.Red;

            IsValid = labelValid && labelUnique && valueValid && valueRangeValid &&
                      valueUniqueValid && widthValid && rwValid;
        }
예제 #28
0
        private void ImportSymbolsButton_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog fileDlg = new OpenFileDialog()
            {
                Filter      = ProjectFile.FILENAME_FILTER + "|" + Res.Strings.FILE_FILTER_ALL,
                FilterIndex = 1
            };

            if (fileDlg.ShowDialog() != true)
            {
                return;
            }
            string projPathName = Path.GetFullPath(fileDlg.FileName);

            DisasmProject newProject = new DisasmProject();

            if (!ProjectFile.DeserializeFromFile(projPathName, newProject,
                                                 out FileLoadReport report))
            {
                // Unable to open project file.  Report error and bail.
                ProjectLoadIssues dlg = new ProjectLoadIssues(this, report.Format(),
                                                              ProjectLoadIssues.Buttons.Cancel);
                dlg.ShowDialog();
                // ignore dlg.DialogResult
                return;
            }

            // Import all user labels that were marked as "global export".  These become
            // external-address project symbols with unspecified width.
            int foundCount = 0;

            foreach (KeyValuePair <int, Symbol> kvp in newProject.UserLabels)
            {
                if (kvp.Value.SymbolType == Symbol.Type.GlobalAddrExport)
                {
                    Symbol    sym    = kvp.Value;
                    DefSymbol defSym = new DefSymbol(sym.Label, sym.Value, Symbol.Source.Project,
                                                     Symbol.Type.ExternalAddr, FormatDescriptor.SubType.None);
                    mWorkProps.ProjectSyms[defSym.Label] = defSym;
                    foundCount++;
                }
            }
            if (foundCount != 0)
            {
                IsDirty = true;
                LoadProjectSymbols();   // just reload the whole set
                UpdateControls();
            }

            newProject.Cleanup();

            // Tell the user we did something.  Might be nice to tell them how many weren't
            // already present.
            string msg;

            if (foundCount == 0)
            {
                msg = Res.Strings.SYMBOL_IMPORT_NONE;
            }
            else
            {
                msg = string.Format(Res.Strings.SYMBOL_IMPORT_GOOD_FMT, foundCount);
            }
            MessageBox.Show(msg, Res.Strings.SYMBOL_IMPORT_CAPTION,
                            MessageBoxButton.OK, MessageBoxImage.Information);
        }
예제 #29
0
        private void importSymbolsButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDlg = new OpenFileDialog();

            fileDlg.Filter = ProjectFile.FILENAME_FILTER + "|" +
                             Properties.Resources.FILE_FILTER_ALL;
            fileDlg.FilterIndex = 1;
            if (fileDlg.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            string projPathName = Path.GetFullPath(fileDlg.FileName);

            DisasmProject newProject = new DisasmProject();

            if (!ProjectFile.DeserializeFromFile(projPathName, newProject,
                                                 out FileLoadReport report))
            {
                ProjectLoadIssues dlg = new ProjectLoadIssues();
                dlg.Messages    = report.Format();
                dlg.CanContinue = false;
                dlg.ShowDialog();
                // ignore dlg.DialogResult
                dlg.Dispose();
                return;
            }

            // Import all user labels that were marked as "global export".  These become
            // external-address project symbols.
            int foundCount = 0;

            foreach (KeyValuePair <int, Symbol> kvp in newProject.UserLabels)
            {
                if (kvp.Value.SymbolType == Symbol.Type.GlobalAddrExport)
                {
                    Symbol    sym    = kvp.Value;
                    DefSymbol defSym = new DefSymbol(sym.Label, sym.Value, Symbol.Source.Project,
                                                     Symbol.Type.ExternalAddr, FormatDescriptor.SubType.None,
                                                     string.Empty, string.Empty);
                    WorkProps.ProjectSyms[defSym.Label] = defSym;
                    foundCount++;
                }
            }
            if (foundCount != 0)
            {
                mDirty = true;
                LoadProjectSymbols();
                UpdateControls();
            }

            newProject.Cleanup();

            // Tell the user we did something.  Might be nice to tell them how many weren't
            // already present.
            string msg;

            if (foundCount == 0)
            {
                msg = Properties.Resources.SYMBOL_IMPORT_NONE;
            }
            else
            {
                msg = string.Format(Properties.Resources.SYMBOL_IMPORT_GOOD, foundCount);
            }
            MessageBox.Show(msg, Properties.Resources.SYMBOL_IMPORT_CAPTION,
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
예제 #30
0
        /// <summary>
        /// Gathers a list of platform symbols from the project's symbol table.
        /// </summary>
        private List <PlSymbol> GeneratePlSymbolList()
        {
            List <PlSymbol> plSymbols = new List <PlSymbol>();
            SymbolTable     symTab    = mProject.SymbolTable;

            foreach (Symbol sym in symTab)
            {
                PlSymbol.Source plsSource;
                switch (sym.SymbolSource)
                {
                case Symbol.Source.Platform:
                    plsSource = PlSymbol.Source.Platform;
                    break;

                case Symbol.Source.Project:
                    plsSource = PlSymbol.Source.Project;
                    break;

                case Symbol.Source.User:
                    plsSource = PlSymbol.Source.User;
                    break;

                case Symbol.Source.Variable:
                case Symbol.Source.Auto:
                    // don't forward these to plugins
                    continue;

                default:
                    Debug.Assert(false);
                    continue;
                }
                PlSymbol.Type plsType;
                switch (sym.SymbolType)
                {
                case Symbol.Type.LocalOrGlobalAddr:
                case Symbol.Type.GlobalAddr:
                case Symbol.Type.GlobalAddrExport:
                case Symbol.Type.ExternalAddr:
                    plsType = PlSymbol.Type.Address;
                    break;

                case Symbol.Type.Constant:
                    plsType = PlSymbol.Type.Constant;
                    break;

                default:
                    Debug.Assert(false);
                    continue;
                }

                int    width = -1;
                string tag   = string.Empty;
                if (sym is DefSymbol)
                {
                    DefSymbol defSym = sym as DefSymbol;
                    width = defSym.DataDescriptor.Length;
                    tag   = defSym.Tag;
                }


                plSymbols.Add(new PlSymbol(sym.Label, sym.Value, width, plsSource, plsType, tag));
            }

            return(plSymbols);
        }