Пример #1
0
        private void GenerateLinkerScript(StreamWriter sw)
        {
            sw.WriteLine("# 6502bench SourceGen generated linker script for " + mFileNameBase);

            sw.WriteLine("MEMORY {");
            sw.WriteLine("    MAIN: file=%O, start=%S, size=65536;");
            for (int i = 0; i < Project.AddrMap.Count; i++)
            {
                AddressMap.AddressMapEntry ame = Project.AddrMap[i];
                sw.WriteLine(string.Format("#    MEM{0:D3}: file=%O, start=${1:x4}, size={2};",
                                           i, ame.Addr, ame.Length));
            }
            sw.WriteLine("}");

            sw.WriteLine("SEGMENTS {");
            sw.WriteLine("    CODE: load=MAIN, type=rw;");
            for (int i = 0; i < Project.AddrMap.Count; i++)
            {
                sw.WriteLine(string.Format("#    SEG{0:D3}: load=MEM{0:D3}, type=rw;", i));
            }
            sw.WriteLine("}");

            sw.WriteLine("FEATURES {}");
            sw.WriteLine("SYMBOLS {}");
        }
Пример #2
0
        /// <summary>
        /// Adds one or more entries to the address map for the specified segment.
        /// </summary>
        private static void AddAddressEntries(DisasmProject proj, SegmentMapEntry ent,
                                              int bufOffset, ChangeSet cs)
        {
            int addr   = ent.Address;
            int segRem = ent.Segment.Length;

            while (true)
            {
                // Generate an ORG directive.
                //int origAddr = proj.AddrMap.OffsetToAddress(bufOffset);
                AddressMap.AddressMapEntry addrEnt = new AddressMap.AddressMapEntry(bufOffset,
                                                                                    AddressMap.FLOATING_LEN, addr, string.Empty, false);
                UndoableChange uc = UndoableChange.CreateAddressChange(null, addrEnt);
                cs.Add(uc);

                // Compare amount of space in this bank to amount left in segment.
                int bankRem = 0x00010000 - (addr & 0xffff);
                if (bankRem > segRem)
                {
                    // All done, bail.
                    break;
                }

                // Advance to start of next bank.
                addr += bankRem;
                Debug.Assert((addr & 0x0000ffff) == 0);
                bufOffset += bankRem;
                segRem    -= bankRem;
                Debug.WriteLine("Adding additional ORG at " + addr);
            }
        }
Пример #3
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="owner">Parent window.</param>
        /// <param name="curRegion">Current region; will be null for new entries.</param>
        /// <param name="newEntry">Prototype entry to create.</param>
        /// <param name="selectionLen">Length, in bytes, of the selection.</param>
        /// <param name="isSingleLine">True if the selection is a single line.</param>
        /// <param name="project">Project reference.</param>
        /// <param name="formatter">Text formatter object.</param>
        public EditAddress(Window owner, AddressMap.AddressRegion curRegion,
                           AddressMap.AddressMapEntry newEntry, int selectionLen, bool isSingleLine,
                           DisasmProject project, Formatter formatter)
        {
            InitializeComponent();
            Owner       = owner;
            DataContext = this;

            Debug.Assert((curRegion == null) ^ (newEntry == null));     // exactly one must be true

            mProject         = project;
            mMaxAddressValue = project.CpuDef.MaxAddressValue;
            mShowBank        = !project.CpuDef.HasAddr16;
            mFormatter       = formatter;

            Configure(curRegion, newEntry, selectionLen, isSingleLine);
            UpdateControls();
        }
Пример #4
0
        private void OkButton_Click(object sender, RoutedEventArgs e)
        {
            bool ok = ParseAddress(out int addr);

            Debug.Assert(ok);

            AddressMap.AddressMapEntry baseEntry;
            if (CheckOption1)
            {
                baseEntry = mResultEntry1;
            }
            else
            {
                baseEntry = mResultEntry2;
            }

            // Combine base entry with pre-label string and relative addressing checkbox.
            ResultEntry = new AddressMap.AddressMapEntry(baseEntry.Offset,
                                                         baseEntry.Length, addr, PreLabelText, UseRelativeAddressing);
            Debug.WriteLine("Dialog result: " + ResultEntry);
            DialogResult = true;
        }
Пример #5
0
        private void Configure(AddressMap.AddressRegion curRegion,
                               AddressMap.AddressMapEntry newEntry, int selectionLen, bool isSingleLine)
        {
            Debug.WriteLine("Configuring AR: reg=" + curRegion + " newEnt=" + newEntry +
                            " selLen=" + selectionLen + " isSingle=" + isSingleLine);

            ShowOption1             = ShowOption2 = true;
            EnableOption1           = EnableOption2 = true;
            CheckOption1            = true;
            EnableAttributeControls = true;

            string option1Summ;
            string option1Msg;
            string option2Summ;
            string option2Msg;

            if (curRegion != null)
            {
                // Editing an existing region.
                CanDeleteRegion    = true;
                ShowExistingRegion = true;
                mOrigPreLabel      = curRegion.PreLabel;
                mParentNonAddr     = (curRegion.PreLabelAddress == Address.NON_ADDR);

                if (curRegion.Address == Address.NON_ADDR)
                {
                    AddressText = Address.NON_ADDR_STR;
                }
                else
                {
                    AddressText = Asm65.Address.AddressToString(curRegion.Address, false);
                }
                PreLabelText          = curRegion.PreLabel;
                UseRelativeAddressing = curRegion.IsRelative;

                OperationStr       = (string)FindResource("str_HdrEdit");
                mRegionAddress     = curRegion.Address;
                mRegionStartOffset = curRegion.Offset;
                mRegionEndOffset   = curRegion.Offset + curRegion.ActualLength - 1;
                mPreLabelAddress   = curRegion.PreLabelAddress;

                if (isSingleLine)
                {
                    // Only thing selected was arstart/arend.  First action is to edit
                    // the region properties, second action is to convert floating end
                    // to fixed.
                    mResultEntry1 = new AddressMap.AddressMapEntry(curRegion.Offset,
                                                                   curRegion.Length, curRegion.Address, curRegion.PreLabel,
                                                                   curRegion.IsRelative);
                    option1Summ = (string)FindResource("str_OptEditAsIsSummary");
                    option1Msg  = (string)FindResource("str_OptEditAsIs");

                    if (curRegion.IsFloating)
                    {
                        option2Summ   = (string)FindResource("str_OptEditAndFixSummary");
                        option2Msg    = (string)FindResource("str_OptEditAndFix");
                        mResultEntry2 = new AddressMap.AddressMapEntry(curRegion.Offset,
                                                                       curRegion.ActualLength, curRegion.Address, curRegion.PreLabel,
                                                                       curRegion.IsRelative);
                    }
                    else
                    {
                        option2Summ   = string.Empty;
                        option2Msg    = (string)FindResource("str_EditFixedAlreadyFixed");
                        mResultEntry2 = null;
                        EnableOption2 = false;  // show it, but disabled
                    }
                }
                else
                {
                    // Selection started with arstart and included multiple lines.  First
                    // action is to resize region.  Second action is edit without resize.
                    // If resize is illegal (e.g. new region exactly overlaps another),
                    // first action is disabled.
                    mResultEntry1 = new AddressMap.AddressMapEntry(curRegion.Offset,
                                                                   selectionLen, curRegion.Address, curRegion.PreLabel,
                                                                   curRegion.IsRelative);
                    mResultEntry2 = new AddressMap.AddressMapEntry(curRegion.Offset,
                                                                   curRegion.Length, curRegion.Address, curRegion.PreLabel,
                                                                   curRegion.IsRelative);

                    option1Summ = (string)FindResource("str_OptResizeSummary");
                    string fmt = (string)FindResource("str_OptResize");
                    option1Msg = string.Format(fmt,
                                               mFormatter.FormatOffset24(curRegion.Offset + selectionLen - 1),
                                               FormatLength(selectionLen));
                    option2Summ = (string)FindResource("str_OptEditAsIsSummary");
                    option2Msg  = (string)FindResource("str_OptEditAsIs");

                    Debug.Assert(selectionLen > 0);
                    AddressMap.AddResult ares;
                    TryCreateRegion(curRegion, curRegion.Offset, selectionLen,
                                    curRegion.Address, out ares);
                    if (ares != AddressMap.AddResult.Okay)
                    {
                        // Can't resize the new region, so disable that option (still visible).
                        option1Summ = string.Empty;
                        string fmta = (string)FindResource("str_OptResizeFail");
                        option1Msg    = string.Format(fmta, GetErrorString(ares));
                        EnableOption1 = false;
                        CheckOption2  = true;
                    }

                    if (curRegion.ActualLength == selectionLen)
                    {
                        // The selection size matches the region's length, which means they
                        // have the entire region selected, so "resize" and "edit" do the same
                        // thing.  No real need to disable the resize option, but we can default
                        // to "edit only" to emphasize that there's no actual change.
                        CheckOption2 = true;
                    }
                }
            }
            else
            {
                // Creating a new region.  Prototype entry specifies offset, length, and address.
                // First action is to create a fixed-length region, second action is to create
                // a floating region.  Default changes for single-item selections.
                CanDeleteRegion    = false;
                ShowExistingRegion = false;
                mOrigPreLabel      = string.Empty;

                if (newEntry.Address == Address.NON_ADDR)
                {
                    AddressText = Address.NON_ADDR_STR;
                }
                else
                {
                    AddressText = Asm65.Address.AddressToString(newEntry.Address, false);
                }
                PreLabelText          = string.Empty;
                UseRelativeAddressing = false;

                OperationStr = (string)FindResource("str_HdrCreate");

                AddressMap.AddResult     ares1;
                AddressMap.AddressRegion newRegion1 = TryCreateRegion(null, newEntry.Offset,
                                                                      newEntry.Length, newEntry.Address, out ares1);
                AddressMap.AddResult     ares2;
                AddressMap.AddressRegion newRegion2 = TryCreateRegion(null, newEntry.Offset,
                                                                      AddressMap.FLOATING_LEN, newEntry.Address, out ares2);

                if (isSingleLine)
                {
                    // For single-line selection, create a floating region by default.
                    CheckOption2 = true;
                }

                // If it failed, report the error.  Most common reason will be a start offset
                // that overlaps an existing region.  You can create a fixed region inside
                // a fixed region with the same start offset, but can't create a float there.
                if (ares1 == AddressMap.AddResult.Okay)
                {
                    mResultEntry1 = new AddressMap.AddressMapEntry(newEntry.Offset,
                                                                   newRegion1.ActualLength, newEntry.Address, string.Empty, false);

                    option1Summ = (string)FindResource("str_CreateFixedSummary");
                    string fmt = (string)FindResource("str_CreateFixed");
                    option1Msg = string.Format(fmt,
                                               mFormatter.FormatOffset24(newEntry.Offset),
                                               FormatLength(newRegion1.ActualLength));
                    mPreLabelAddress = newRegion1.PreLabelAddress;

                    mParentNonAddr = (newRegion1.PreLabelAddress == Address.NON_ADDR);
                }
                else
                {
                    option1Summ = string.Empty;
                    if (ares1 == AddressMap.AddResult.StraddleExisting)
                    {
                        option1Msg = (string)FindResource("str_CreateFixedFailStraddle");
                    }
                    else
                    {
                        option1Msg = (string)FindResource("str_CreateFixedFail");
                    }
                    CheckOption2  = true;
                    EnableOption1 = false;
                }
                if (ares2 == AddressMap.AddResult.Okay)
                {
                    mResultEntry2 = new AddressMap.AddressMapEntry(newEntry.Offset,
                                                                   AddressMap.FLOATING_LEN, newEntry.Address, string.Empty, false);

                    option2Summ = (string)FindResource("str_CreateFloatingSummary");
                    string fmt = (string)FindResource("str_CreateFloating");
                    option2Msg = string.Format(fmt,
                                               mFormatter.FormatOffset24(newEntry.Offset),
                                               FormatLength(newRegion2.ActualLength));
                    mPreLabelAddress = newRegion2.PreLabelAddress;

                    mParentNonAddr = (newRegion2.PreLabelAddress == Address.NON_ADDR);
                }
                else
                {
                    option2Summ   = string.Empty;
                    option2Msg    = (string)FindResource("str_CreateFloatingFail");
                    CheckOption1  = true;
                    CheckOption2  = false;  // required for some reason
                    EnableOption2 = false;
                }
                if (ares1 != AddressMap.AddResult.Okay && ares2 != AddressMap.AddResult.Okay)
                {
                    // Unable to create region here.  Explain why not.
                    EnableAttributeControls = false;
                    CheckOption1            = CheckOption2 = false;
                    mPreLabelAddress        = Address.NON_ADDR;

                    SetErrorString(ares1);
                }
            }

            TextBlock tb1 = option1TextBlock;

            tb1.Inlines.Clear();
            if (!string.IsNullOrEmpty(option1Summ))
            {
                tb1.Inlines.Add(new Run(option1Summ + " ")
                {
                    FontWeight = FontWeights.Bold
                });
            }
            tb1.Inlines.Add(option1Msg);

            TextBlock tb2 = option2TextBlock;

            tb2.Inlines.Clear();
            if (!string.IsNullOrEmpty(option2Summ))
            {
                tb2.Inlines.Add(new Run(option2Summ + " ")
                {
                    FontWeight = FontWeights.Bold
                });
            }
            tb2.Inlines.Add(option2Msg);
        }