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 {}"); }
/// <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); } }
/// <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(); }
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; }
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); }