mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-11 13:50:13 +00:00
ORG rework, part 7
Implemented "is relative" flag. This only affects source code generation, replacing ".arstart <addr>" with ".arstart *+<value>". Only output by 64tass and ACME generators. Added a bold-text summary to radio buttons in address region edit dialog. This makes it much easier to see what you're doing. Added a warning to the label edit dialog when a label is being placed in a non-addressable region. Modified double-click behavior for .arstart/.arend to jump to the other end when the opcode is clicked on. This matches the behavior of instructions with address operands. Reordered Actions menu, putting "edit operand" at the top. Fixed AddressMap entry collision testing. Fixed PRG issue with multiple address regions at offset +000002. Added regression tests. Most of the complicated stuff with regions is tested by unit tests inside AddressMap, but we still need to exercise nested region code generation.
This commit is contained in:
parent
e6c5c7f8df
commit
e8608770b9
@ -256,6 +256,7 @@ namespace CommonUtil {
|
|||||||
// (Shouldn't be necessary since we're only doing this to pass the address map to
|
// (Shouldn't be necessary since we're only doing this to pass the address map to
|
||||||
// plugins, but... better safe.)
|
// plugins, but... better safe.)
|
||||||
foreach (AddressMapEntry ent in entries) {
|
foreach (AddressMapEntry ent in entries) {
|
||||||
|
// TODO(maybe): suppress Regenerate() call in AddEntry while we work
|
||||||
AddResult result = AddEntry(ent.Offset, ent.Length, ent.Address, ent.PreLabel,
|
AddResult result = AddEntry(ent.Offset, ent.Length, ent.Address, ent.PreLabel,
|
||||||
ent.IsRelative);
|
ent.IsRelative);
|
||||||
if (result != AddResult.Okay) {
|
if (result != AddResult.Okay) {
|
||||||
@ -357,7 +358,7 @@ namespace CommonUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a new entry to the map.
|
/// Adds a new entry to the map. Uses defaults for PreLabel and IsRelative.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="offset">File offset of region start.</param>
|
/// <param name="offset">File offset of region start.</param>
|
||||||
/// <param name="length">Length of region, or FLOATING_LEN for a floating end point.</param>
|
/// <param name="length">Length of region, or FLOATING_LEN for a floating end point.</param>
|
||||||
@ -423,14 +424,16 @@ namespace CommonUtil {
|
|||||||
return AddResult.Okay;
|
return AddResult.Okay;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find insertion point.
|
// Find the insertion point, and check for conflicts.
|
||||||
int insIdx;
|
//
|
||||||
for (insIdx = 0; insIdx < mMapEntries.Count; insIdx++) {
|
// If we know where to insert the new entry, we only need to check the previous
|
||||||
AddressMapEntry ent = mMapEntries[insIdx];
|
// node, following node, and parents. However, we may not have regenerated the
|
||||||
if (ent.Offset > offset) {
|
// tree structure since the previous add, so we can't rely on that. We're expecting
|
||||||
// Insert before this one.
|
// the list to be short, so checking all entries shouldn't be prohibitive.
|
||||||
break;
|
int insIdx = -1;
|
||||||
} else if (ent.Offset == offset) {
|
for (int i = 0; i < mMapEntries.Count; i++) {
|
||||||
|
AddressMapEntry ent = mMapEntries[i];
|
||||||
|
if (ent.Offset == offset) {
|
||||||
// We share a start point with this entry. See if we fit inside it or
|
// We share a start point with this entry. See if we fit inside it or
|
||||||
// wrap around it.
|
// wrap around it.
|
||||||
if (length == FLOATING_LEN || ent.Length == FLOATING_LEN) {
|
if (length == FLOATING_LEN || ent.Length == FLOATING_LEN) {
|
||||||
@ -441,33 +444,18 @@ namespace CommonUtil {
|
|||||||
return AddResult.OverlapExisting;
|
return AddResult.OverlapExisting;
|
||||||
} else if (ent.Length < length) {
|
} else if (ent.Length < length) {
|
||||||
// New region is larger, would become parent, so insert before this.
|
// New region is larger, would become parent, so insert before this.
|
||||||
break;
|
if (insIdx < 0) {
|
||||||
|
insIdx = i;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// New region is smaller and will be a child of this entry, so we want
|
// New region is smaller and will be a child of this entry, so we want
|
||||||
// to insert *after* this point. Loop again to see if the following
|
// to insert *after* this point. Loop again to see if the following
|
||||||
// entry is also a parent for this new one.
|
// entry is also a parent for this new one.
|
||||||
Debug.Assert(ent.Length > length);
|
Debug.Assert(ent.Length > length);
|
||||||
}
|
}
|
||||||
}
|
} else if (ent.Offset < offset) {
|
||||||
}
|
|
||||||
|
|
||||||
// The insertion index indicates the entry we want to insert before. We need to
|
|
||||||
// confirm that the new block doesn't straddle the blocks on either side. If we're
|
|
||||||
// inserting into a bunch of blocks with coincident start points, it's possible for
|
|
||||||
// the blocks appearing before and after to share the same start offset.
|
|
||||||
|
|
||||||
if (insIdx > 0) {
|
|
||||||
// Check previous block. We know that its offset is <= the new offset, so
|
|
||||||
// either its a parent or a sibling.
|
|
||||||
AddressMapEntry ent = mMapEntries[insIdx - 1];
|
|
||||||
if (ent.Offset == offset) {
|
|
||||||
// Previous is our parent. These things were checked earlier.
|
|
||||||
Debug.Assert(length != FLOATING_LEN && ent.Length != FLOATING_LEN);
|
|
||||||
Debug.Assert(ent.Length > length);
|
|
||||||
} else {
|
|
||||||
// Existing block starts before this new one. The existing block must either
|
// Existing block starts before this new one. The existing block must either
|
||||||
// be floating, be completely before this, or completely envelop this.
|
// be floating, be completely before this, or completely envelop this.
|
||||||
Debug.Assert(ent.Offset < offset);
|
|
||||||
if (ent.Length == FLOATING_LEN) {
|
if (ent.Length == FLOATING_LEN) {
|
||||||
// sibling -- must end before us
|
// sibling -- must end before us
|
||||||
} else if (ent.Offset + ent.Length <= offset) {
|
} else if (ent.Offset + ent.Length <= offset) {
|
||||||
@ -480,20 +468,12 @@ namespace CommonUtil {
|
|||||||
// whoops
|
// whoops
|
||||||
return AddResult.StraddleExisting;
|
return AddResult.StraddleExisting;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if (insIdx < mMapEntries.Count) {
|
|
||||||
// Check following block. We know that its offset is >= the new offset, so it's
|
|
||||||
// either a child or a sibling.
|
|
||||||
AddressMapEntry ent = mMapEntries[insIdx];
|
|
||||||
if (ent.Offset == offset) {
|
|
||||||
// Following block is our child. These things were checked earlier.
|
|
||||||
Debug.Assert(length != FLOATING_LEN && ent.Length != FLOATING_LEN);
|
|
||||||
Debug.Assert(ent.Length < length);
|
|
||||||
} else {
|
} else {
|
||||||
// Existing block starts after this new one. The existing block must either
|
// Existing block starts after this new one. The existing block must either
|
||||||
// be floating, be completely after this, or be completely enveloped by this.
|
// be floating, be completely after this, or be completely enveloped by this.
|
||||||
Debug.Assert(ent.Offset > offset);
|
if (insIdx < 0) {
|
||||||
|
insIdx = i;
|
||||||
|
}
|
||||||
if (ent.Length == FLOATING_LEN) {
|
if (ent.Length == FLOATING_LEN) {
|
||||||
// child or sibling, depending on start offset
|
// child or sibling, depending on start offset
|
||||||
} else if (offset + length <= ent.Offset) {
|
} else if (offset + length <= ent.Offset) {
|
||||||
@ -509,6 +489,10 @@ namespace CommonUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (insIdx < 0) {
|
||||||
|
insIdx = mMapEntries.Count;
|
||||||
|
}
|
||||||
|
|
||||||
outInsIdx = insIdx;
|
outInsIdx = insIdx;
|
||||||
return AddResult.Okay;
|
return AddResult.Okay;
|
||||||
}
|
}
|
||||||
@ -549,13 +533,6 @@ namespace CommonUtil {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if adding the specified region is a valid action.
|
|
||||||
// ??? do we want to do this, or just ask "does region exist"? Depends on
|
|
||||||
// flow in edit dialog.
|
|
||||||
//public bool CanAddRegion(int offset, int length) {
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of the entries with the specified offset value.
|
/// Gets a list of the entries with the specified offset value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1097,7 +1074,7 @@ namespace CommonUtil {
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// We use inclusive Offset values for both start and end. If we don't do this, the
|
/// We use inclusive Offset values for both start and end. If we don't do this, the
|
||||||
/// offset for end records will be outside the file bounds. It also gets a bit painful
|
/// offset for end records will be outside the file bounds. It also gets a bit painful
|
||||||
/// when the display list tries to update [M,N] if put the end at N+1.
|
/// when the display list tries to update [M,N] if the end is actually held at N+1.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class AddressChange {
|
public class AddressChange {
|
||||||
// True if this is a region start, false if a region end.
|
// True if this is a region start, false if a region end.
|
||||||
@ -1451,6 +1428,8 @@ namespace CommonUtil {
|
|||||||
map.AddEntry(off0 + 1, len0, 0x1000));
|
map.AddEntry(off0 + 1, len0, 0x1000));
|
||||||
Test_Expect(AddResult.InvalidValue, ref result,
|
Test_Expect(AddResult.InvalidValue, ref result,
|
||||||
map.AddEntry(off0, mapLen + 1, 0x1000));
|
map.AddEntry(off0, mapLen + 1, 0x1000));
|
||||||
|
Test_Expect(AddResult.StraddleExisting, ref result,
|
||||||
|
map.AddEntry(off0 + 1, off2 - off0, 0x1000));
|
||||||
|
|
||||||
// One region to wrap them all. Add then remove.
|
// One region to wrap them all. Add then remove.
|
||||||
Test_Expect(AddResult.Okay, ref result,
|
Test_Expect(AddResult.Okay, ref result,
|
||||||
@ -1596,9 +1575,6 @@ namespace CommonUtil {
|
|||||||
Test_Expect(0x002100, ref result, map.AddressToOffset(0x002300, 0x5000));
|
Test_Expect(0x002100, ref result, map.AddressToOffset(0x002300, 0x5000));
|
||||||
Test_Expect(0x003100, ref result, map.AddressToOffset(0x003000, 0x5000));
|
Test_Expect(0x003100, ref result, map.AddressToOffset(0x003000, 0x5000));
|
||||||
|
|
||||||
string mapStr = map.FormatAddressMap(); // DEBUG - format the map and
|
|
||||||
Debug.WriteLine(mapStr); // DEBUG - print it to the console
|
|
||||||
|
|
||||||
result &= map.DebugValidate();
|
result &= map.DebugValidate();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1699,6 +1675,39 @@ namespace CommonUtil {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool Test_OddOverlap() {
|
||||||
|
const int mapLen = 0x1000;
|
||||||
|
AddressMap map = new AddressMap(mapLen);
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
// Top region spans full map.
|
||||||
|
Test_Expect(AddResult.Okay, ref result, map.AddEntry(0x000000, mapLen, 0x1000));
|
||||||
|
// Parent region covers next two.
|
||||||
|
Test_Expect(AddResult.Okay, ref result, map.AddEntry(0x000000, 0x0400, 0x1000));
|
||||||
|
// Floating region.
|
||||||
|
Test_Expect(AddResult.Okay, ref result, map.AddEntry(0x000100, FLOATING_LEN, 0x2000));
|
||||||
|
// Fixed region follows.
|
||||||
|
Test_Expect(AddResult.Okay, ref result, map.AddEntry(0x000200, 0x0100, 0x3000));
|
||||||
|
|
||||||
|
string mapStr = map.FormatAddressMap(); // DEBUG - format the map and
|
||||||
|
Debug.WriteLine(mapStr); // DEBUG - print it to the console
|
||||||
|
|
||||||
|
// Add a region that starts in the middle of the floating region (becoming
|
||||||
|
// a sibling), and ends after the fixed region (becoming its parent).
|
||||||
|
Test_Expect(AddResult.Okay, ref result, map.AddEntry(0x000180, 0x0200, 0x4000));
|
||||||
|
// Remove it.
|
||||||
|
Test_Expect(true, ref result, map.RemoveEntry(0x000180, 0x0200));
|
||||||
|
|
||||||
|
// Add a region that starts in the middle of the floating region and ends after
|
||||||
|
// the parent. Since this crosses the parent's end boundary and doesn't share
|
||||||
|
// the parent's start offset, this is invalid.
|
||||||
|
Test_Expect(AddResult.StraddleExisting, ref result,
|
||||||
|
map.AddEntry(0x000180, 0x0400, 0x4000));
|
||||||
|
|
||||||
|
result &= map.DebugValidate();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool Test() {
|
public static bool Test() {
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
ok &= Test_Primitives();
|
ok &= Test_Primitives();
|
||||||
@ -1708,6 +1717,7 @@ namespace CommonUtil {
|
|||||||
ok &= Test_Nested();
|
ok &= Test_Nested();
|
||||||
ok &= Test_Cross();
|
ok &= Test_Cross();
|
||||||
ok &= Test_Pyramids();
|
ok &= Test_Pyramids();
|
||||||
|
ok &= Test_OddOverlap();
|
||||||
|
|
||||||
Debug.WriteLine("AddressMap: test complete (ok=" + ok + ")");
|
Debug.WriteLine("AddressMap: test complete (ok=" + ok + ")");
|
||||||
return ok;
|
return ok;
|
||||||
|
@ -594,9 +594,24 @@ namespace SourceGen.AsmGen {
|
|||||||
OutputLine("*", "=", SourceFormatter.FormatHexValue(0, 4), string.Empty);
|
OutputLine("*", "=", SourceFormatter.FormatHexValue(0, 4), string.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AddressMap.AddressRegion region = change.Region;
|
||||||
|
string addrStr;
|
||||||
|
if (region.IsRelative && region.PreLabelAddress != Address.NON_ADDR) {
|
||||||
|
int diff = nextAddress - region.PreLabelAddress;
|
||||||
|
string pfxStr;
|
||||||
|
if (diff >= 0) {
|
||||||
|
pfxStr = "*+";
|
||||||
|
} else {
|
||||||
|
pfxStr = "*-";
|
||||||
|
diff = -diff;
|
||||||
|
}
|
||||||
|
addrStr = pfxStr + SourceFormatter.FormatHexValue(diff, 4);
|
||||||
|
} else {
|
||||||
|
addrStr = SourceFormatter.FormatHexValue(nextAddress, 4);
|
||||||
|
}
|
||||||
OutputLine(string.Empty,
|
OutputLine(string.Empty,
|
||||||
SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective),
|
SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective),
|
||||||
SourceFormatter.FormatHexValue(nextAddress, 4) + " {",
|
addrStr + " {",
|
||||||
string.Empty);
|
string.Empty);
|
||||||
mPcDepth++;
|
mPcDepth++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -550,6 +550,7 @@ namespace SourceGen.AsmGen {
|
|||||||
|
|
||||||
// IGenerator
|
// IGenerator
|
||||||
public void FlushArDirectives() {
|
public void FlushArDirectives() {
|
||||||
|
// TODO(someday): handle IsRelative
|
||||||
OutputLine(string.Empty,
|
OutputLine(string.Empty,
|
||||||
SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective),
|
SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective),
|
||||||
SourceFormatter.FormatHexValue(mNextAddress, 4),
|
SourceFormatter.FormatHexValue(mNextAddress, 4),
|
||||||
|
@ -501,6 +501,7 @@ namespace SourceGen.AsmGen {
|
|||||||
|
|
||||||
// IGenerator
|
// IGenerator
|
||||||
public void FlushArDirectives() {
|
public void FlushArDirectives() {
|
||||||
|
// TODO(someday): handle IsRelative
|
||||||
OutputLine(string.Empty,
|
OutputLine(string.Empty,
|
||||||
SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective),
|
SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective),
|
||||||
SourceFormatter.FormatHexValue(mNextAddress, 4),
|
SourceFormatter.FormatHexValue(mNextAddress, 4),
|
||||||
|
@ -697,9 +697,25 @@ namespace SourceGen.AsmGen {
|
|||||||
//OutputLine("*", "=", SourceFormatter.FormatHexValue(0, 4), string.Empty);
|
//OutputLine("*", "=", SourceFormatter.FormatHexValue(0, 4), string.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddressMap.AddressRegion region = change.Region;
|
||||||
|
string addrStr;
|
||||||
|
if (region.IsRelative && region.PreLabelAddress != Address.NON_ADDR) {
|
||||||
|
int diff = nextAddress - region.PreLabelAddress;
|
||||||
|
string pfxStr;
|
||||||
|
if (diff >= 0) {
|
||||||
|
pfxStr = "*+";
|
||||||
|
} else {
|
||||||
|
pfxStr = "*-";
|
||||||
|
diff = -diff;
|
||||||
|
}
|
||||||
|
addrStr = pfxStr + SourceFormatter.FormatHexValue(diff, 4);
|
||||||
|
} else {
|
||||||
|
addrStr = SourceFormatter.FormatHexValue(nextAddress, 4);
|
||||||
|
}
|
||||||
OutputLine(string.Empty,
|
OutputLine(string.Empty,
|
||||||
SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective),
|
SourceFormatter.FormatPseudoOp(sDataOpNames.ArStartDirective),
|
||||||
SourceFormatter.FormatHexValue(nextAddress, 4),
|
addrStr,
|
||||||
string.Empty);
|
string.Empty);
|
||||||
mPcDepth++;
|
mPcDepth++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -584,9 +584,12 @@ namespace SourceGen.AsmGen {
|
|||||||
if (change.Region.ActualLength != 2) {
|
if (change.Region.ActualLength != 2) {
|
||||||
Debug.WriteLine("PRG test: first entry is not a two-byte region");
|
Debug.WriteLine("PRG test: first entry is not a two-byte region");
|
||||||
}
|
}
|
||||||
// Confirm there's an address map entry at offset 2.
|
// Confirm there's a single address map entry at offset 2. If there's more than
|
||||||
if (project.AddrMap.GetEntries(0x000002).Count == 0) {
|
// one we likely have a situation where the first one is a "full-file" region, and
|
||||||
//Debug.WriteLine("PRG test: no ORG at +2");
|
// the second determines the address. This weird scenario causes problems with
|
||||||
|
// code generation, so we just don't support it.
|
||||||
|
if (project.AddrMap.GetEntries(0x000002).Count != 1) {
|
||||||
|
//Debug.WriteLine("PRG test: wrong #of entries at +000002");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// See if the address at offset 2 matches the value at 0/1.
|
// See if the address at offset 2 matches the value at 0/1.
|
||||||
|
@ -1086,6 +1086,17 @@ namespace SourceGen {
|
|||||||
string addrStr;
|
string addrStr;
|
||||||
if (region.Address == Address.NON_ADDR) {
|
if (region.Address == Address.NON_ADDR) {
|
||||||
addrStr = Address.NON_ADDR_STR;
|
addrStr = Address.NON_ADDR_STR;
|
||||||
|
} else if (change.Region.IsRelative &&
|
||||||
|
change.Region.PreLabelAddress != Address.NON_ADDR) {
|
||||||
|
int diff = region.Address - change.Region.PreLabelAddress;
|
||||||
|
string pfxStr;
|
||||||
|
if (diff >= 0) {
|
||||||
|
pfxStr = "*+";
|
||||||
|
} else {
|
||||||
|
pfxStr = "*-";
|
||||||
|
diff = -diff;
|
||||||
|
}
|
||||||
|
addrStr = pfxStr + mFormatter.FormatHexValue(diff, 4);
|
||||||
} else {
|
} else {
|
||||||
addrStr = mFormatter.FormatHexValue(region.Address, 4);
|
addrStr = mFormatter.FormatHexValue(region.Address, 4);
|
||||||
}
|
}
|
||||||
|
@ -1532,7 +1532,9 @@ namespace SourceGen {
|
|||||||
break;
|
break;
|
||||||
case LineListGen.Line.Type.ArStartDirective:
|
case LineListGen.Line.Type.ArStartDirective:
|
||||||
case LineListGen.Line.Type.ArEndDirective:
|
case LineListGen.Line.Type.ArEndDirective:
|
||||||
if (CanEditAddress()) {
|
if ((CodeListColumn)col == CodeListColumn.Opcode) {
|
||||||
|
JumpToOperandTarget(line, false);
|
||||||
|
} else if (CanEditAddress()) {
|
||||||
EditAddress();
|
EditAddress();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1807,9 +1809,10 @@ namespace SourceGen {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If multiple lines with code/data are selected, there must not be an address change
|
// If multiple lines with code/data are selected, there must not be a .arstart
|
||||||
// between them unless we're resizing a region. Determining whether or not a resize
|
// between them unless we're resizing a region. Determining whether or not a resize
|
||||||
// is valid is left to the edit dialog.
|
// is valid is left to the edit dialog. It's okay for a .arend to be in the middle
|
||||||
|
// so long as the corresponding .arstart is at the current offset.
|
||||||
if (selLine.LineType == LineListGen.Line.Type.ArStartDirective) {
|
if (selLine.LineType == LineListGen.Line.Type.ArStartDirective) {
|
||||||
// Skip overlapping region check.
|
// Skip overlapping region check.
|
||||||
return true;
|
return true;
|
||||||
@ -1821,14 +1824,18 @@ namespace SourceGen {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute exclusive end point of selected range.
|
// Anything else is too complicated to be worth messing with here. We could do
|
||||||
int nextOffset = lastOffset + CodeLineList[lastIndex].OffsetSpan;
|
// the work, but we have no good way of telling the user what went wrong.
|
||||||
|
// Let the dialog explain it.
|
||||||
|
|
||||||
if (!mProject.AddrMap.IsRangeUnbroken(firstOffset, nextOffset - firstOffset)) {
|
//// Compute exclusive end point of selected range.
|
||||||
Debug.WriteLine("Found mid-selection AddressMap entry (len=" +
|
//int nextOffset = lastOffset + CodeLineList[lastIndex].OffsetSpan;
|
||||||
(nextOffset - firstOffset) + ")");
|
|
||||||
return false;
|
//if (!mProject.AddrMap.IsRangeUnbroken(firstOffset, nextOffset - firstOffset)) {
|
||||||
}
|
// Debug.WriteLine("Found mid-selection AddressMap entry (len=" +
|
||||||
|
// (nextOffset - firstOffset) + ")");
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
|
||||||
//Debug.WriteLine("First +" + firstOffset.ToString("x6") +
|
//Debug.WriteLine("First +" + firstOffset.ToString("x6") +
|
||||||
// ", last +" + lastOffset.ToString("x6") + ",next +" + nextOffset.ToString("x6"));
|
// ", last +" + lastOffset.ToString("x6") + ",next +" + nextOffset.ToString("x6"));
|
||||||
|
@ -107,6 +107,9 @@ namespace SourceGen {
|
|||||||
sb.Append(formatter.FormatOffset24(change.Offset));
|
sb.Append(formatter.FormatOffset24(change.Offset));
|
||||||
PrintDepthLines(sb, depth, false);
|
PrintDepthLines(sb, depth, false);
|
||||||
sb.Append("+- " + "end");
|
sb.Append("+- " + "end");
|
||||||
|
if (change.Region.IsFloating) {
|
||||||
|
sb.Append(" (floating)");
|
||||||
|
}
|
||||||
//PrintAddress(sb, formatter, change.Address, showBank);
|
//PrintAddress(sb, formatter, change.Address, showBank);
|
||||||
//sb.Append(")");
|
//sb.Append(")");
|
||||||
sb.Append(CRLF);
|
sb.Append(CRLF);
|
||||||
|
BIN
SourceGen/SGTestData/20250-nested-regions
Normal file
BIN
SourceGen/SGTestData/20250-nested-regions
Normal file
Binary file not shown.
161
SourceGen/SGTestData/20250-nested-regions.dis65
Normal file
161
SourceGen/SGTestData/20250-nested-regions.dis65
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
### 6502bench SourceGen dis65 v1.0 ###
|
||||||
|
{
|
||||||
|
"_ContentVersion":5,
|
||||||
|
"FileDataLength":156,
|
||||||
|
"FileDataCrc32":1681364707,
|
||||||
|
"ProjectProps":{
|
||||||
|
"CpuName":"6502",
|
||||||
|
"IncludeUndocumentedInstr":false,
|
||||||
|
"TwoByteBrk":false,
|
||||||
|
"EntryFlags":32702671,
|
||||||
|
"AutoLabelStyle":"Simple",
|
||||||
|
"AnalysisParams":{
|
||||||
|
"AnalyzeUncategorizedData":true,
|
||||||
|
"DefaultTextScanMode":"C64Petscii",
|
||||||
|
"MinCharsForString":4,
|
||||||
|
"SeekNearbyTargets":true,
|
||||||
|
"UseRelocData":false,
|
||||||
|
"SmartPlpHandling":false,
|
||||||
|
"SmartPlbHandling":true},
|
||||||
|
|
||||||
|
"PlatformSymbolFileIdentifiers":["RT:Commodore/C64-Kernal.sym65"],
|
||||||
|
"ExtensionScriptFileIdentifiers":["RT:Commodore/VisC64.cs"],
|
||||||
|
"ProjectSyms":{
|
||||||
|
}},
|
||||||
|
|
||||||
|
"AddressMap":[{
|
||||||
|
"Offset":2,
|
||||||
|
"Addr":4096,
|
||||||
|
"Length":154,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":true},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":2,
|
||||||
|
"Addr":8192,
|
||||||
|
"Length":18,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":true},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":2,
|
||||||
|
"Addr":12288,
|
||||||
|
"Length":12,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":true},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":26,
|
||||||
|
"Addr":-1025,
|
||||||
|
"Length":-1024,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":false},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":58,
|
||||||
|
"Addr":16384,
|
||||||
|
"Length":74,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":false},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":74,
|
||||||
|
"Addr":20480,
|
||||||
|
"Length":16,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":false},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":106,
|
||||||
|
"Addr":20488,
|
||||||
|
"Length":16,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":false},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":132,
|
||||||
|
"Addr":53248,
|
||||||
|
"Length":24,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":true},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":139,
|
||||||
|
"Addr":57344,
|
||||||
|
"Length":17,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":false},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":145,
|
||||||
|
"Addr":61440,
|
||||||
|
"Length":-1024,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":false}],
|
||||||
|
"TypeHints":[{
|
||||||
|
"Low":2,
|
||||||
|
"High":2,
|
||||||
|
"Hint":"Code"},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Low":74,
|
||||||
|
"High":74,
|
||||||
|
"Hint":"Code"},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Low":106,
|
||||||
|
"High":106,
|
||||||
|
"Hint":"Code"}],
|
||||||
|
"StatusFlagOverrides":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Comments":{
|
||||||
|
"0":"load address"},
|
||||||
|
|
||||||
|
"LongComments":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Notes":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"UserLabels":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"OperandFormats":{
|
||||||
|
"0":{
|
||||||
|
"Length":2,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
|
"27":{
|
||||||
|
"Length":25,
|
||||||
|
"Format":"StringNullTerm",
|
||||||
|
"SubFormat":"C64Petscii",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
|
"53":{
|
||||||
|
"Length":2,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Address",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
|
"55":{
|
||||||
|
"Length":2,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Address",
|
||||||
|
"SymbolRef":null}},
|
||||||
|
|
||||||
|
"LvTables":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Visualizations":[],
|
||||||
|
"VisualizationAnimations":[],
|
||||||
|
"VisualizationSets":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"RelocList":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"DbrValues":{
|
||||||
|
}}
|
BIN
SourceGen/SGTestData/20252-nested-regions
Normal file
BIN
SourceGen/SGTestData/20252-nested-regions
Normal file
Binary file not shown.
96
SourceGen/SGTestData/20252-nested-regions.dis65
Normal file
96
SourceGen/SGTestData/20252-nested-regions.dis65
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
### 6502bench SourceGen dis65 v1.0 ###
|
||||||
|
{
|
||||||
|
"_ContentVersion":5,
|
||||||
|
"FileDataLength":40,
|
||||||
|
"FileDataCrc32":-539266680,
|
||||||
|
"ProjectProps":{
|
||||||
|
"CpuName":"65816",
|
||||||
|
"IncludeUndocumentedInstr":false,
|
||||||
|
"TwoByteBrk":false,
|
||||||
|
"EntryFlags":32702671,
|
||||||
|
"AutoLabelStyle":"Simple",
|
||||||
|
"AnalysisParams":{
|
||||||
|
"AnalyzeUncategorizedData":true,
|
||||||
|
"DefaultTextScanMode":"LowHighAscii",
|
||||||
|
"MinCharsForString":4,
|
||||||
|
"SeekNearbyTargets":true,
|
||||||
|
"UseRelocData":false,
|
||||||
|
"SmartPlpHandling":false,
|
||||||
|
"SmartPlbHandling":true},
|
||||||
|
|
||||||
|
"PlatformSymbolFileIdentifiers":[],
|
||||||
|
"ExtensionScriptFileIdentifiers":[],
|
||||||
|
"ProjectSyms":{
|
||||||
|
}},
|
||||||
|
|
||||||
|
"AddressMap":[{
|
||||||
|
"Offset":0,
|
||||||
|
"Addr":69632,
|
||||||
|
"Length":40,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":true},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":0,
|
||||||
|
"Addr":135168,
|
||||||
|
"Length":24,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":true},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":0,
|
||||||
|
"Addr":200704,
|
||||||
|
"Length":16,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":true},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":32,
|
||||||
|
"Addr":-1025,
|
||||||
|
"Length":6,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":true}],
|
||||||
|
"TypeHints":[{
|
||||||
|
"Low":0,
|
||||||
|
"High":0,
|
||||||
|
"Hint":"Code"},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Low":32,
|
||||||
|
"High":32,
|
||||||
|
"Hint":"Code"}],
|
||||||
|
"StatusFlagOverrides":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Comments":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"LongComments":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Notes":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"UserLabels":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"OperandFormats":{
|
||||||
|
"34":{
|
||||||
|
"Length":4,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Address",
|
||||||
|
"SymbolRef":null}},
|
||||||
|
|
||||||
|
"LvTables":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Visualizations":[],
|
||||||
|
"VisualizationAnimations":[],
|
||||||
|
"VisualizationSets":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"RelocList":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"DbrValues":{
|
||||||
|
}}
|
97
SourceGen/SGTestData/Expected/20250-nested-regions_64tass.S
Normal file
97
SourceGen/SGTestData/Expected/20250-nested-regions_64tass.S
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
.cpu "6502"
|
||||||
|
* = $0000
|
||||||
|
.word $3000 ;load address
|
||||||
|
|
||||||
|
.logical $1000
|
||||||
|
.logical *+$1000
|
||||||
|
.logical *+$1000
|
||||||
|
L3000 bit L3000
|
||||||
|
_L3003 lda _L3003
|
||||||
|
and _LD003
|
||||||
|
jmp _L200C
|
||||||
|
|
||||||
|
.here
|
||||||
|
_L200C bit _L200C
|
||||||
|
jmp _L1012
|
||||||
|
|
||||||
|
.here
|
||||||
|
_L1012 bit _L1012
|
||||||
|
jsr _L4000
|
||||||
|
.logical $0000
|
||||||
|
.byte $00
|
||||||
|
.null "Null-term PETSCII string"
|
||||||
|
.byte $80
|
||||||
|
.word _L3003
|
||||||
|
.word _LD003
|
||||||
|
.byte $80
|
||||||
|
.here
|
||||||
|
|
||||||
|
.logical $4000
|
||||||
|
_L4000 bit _L4000
|
||||||
|
bit _L5000
|
||||||
|
bit _L500F
|
||||||
|
bit _L500F
|
||||||
|
nop
|
||||||
|
jmp _L4020
|
||||||
|
|
||||||
|
.logical $5000
|
||||||
|
_L5000 bit _L5000
|
||||||
|
bit _L4000
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
_L5008 bit _L5008
|
||||||
|
bit _L5017
|
||||||
|
nop
|
||||||
|
_L500F rts
|
||||||
|
|
||||||
|
.here
|
||||||
|
_L4020 bit _L4020
|
||||||
|
bit _L500F
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
jmp _L4040
|
||||||
|
|
||||||
|
.logical $5008
|
||||||
|
_L5008_0 bit _L5008_0
|
||||||
|
bit _L5000
|
||||||
|
nop
|
||||||
|
_L500F_0 bit _L500F_0
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
_L5017 rts
|
||||||
|
|
||||||
|
.here
|
||||||
|
_L4040 bit _L4040
|
||||||
|
bit _L5017
|
||||||
|
nop
|
||||||
|
jmp _LD000
|
||||||
|
|
||||||
|
.here
|
||||||
|
.logical *+$bf7e
|
||||||
|
_LD000 bit _L200C
|
||||||
|
_LD003 nop
|
||||||
|
jmp _LE000
|
||||||
|
|
||||||
|
.logical $e000
|
||||||
|
_LE000 bit _LE000
|
||||||
|
jmp _LF000
|
||||||
|
|
||||||
|
.logical $f000
|
||||||
|
_LF000 bit _LF000
|
||||||
|
lda _L3003
|
||||||
|
and _LD003
|
||||||
|
nop
|
||||||
|
rts
|
||||||
|
|
||||||
|
.here
|
||||||
|
.here
|
||||||
|
.here
|
||||||
|
.here
|
97
SourceGen/SGTestData/Expected/20250-nested-regions_acme.S
Normal file
97
SourceGen/SGTestData/Expected/20250-nested-regions_acme.S
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
!cpu 6502
|
||||||
|
* = $0000
|
||||||
|
!word $3000 ;load address
|
||||||
|
|
||||||
|
!pseudopc $1000 {
|
||||||
|
!pseudopc *+$1000 {
|
||||||
|
!pseudopc *+$1000 {
|
||||||
|
L3000 bit L3000
|
||||||
|
@L3003 lda @L3003
|
||||||
|
and @LD003
|
||||||
|
jmp @L200C
|
||||||
|
|
||||||
|
}
|
||||||
|
@L200C bit @L200C
|
||||||
|
jmp @L1012
|
||||||
|
|
||||||
|
}
|
||||||
|
@L1012 bit @L1012
|
||||||
|
jsr @L4000
|
||||||
|
!pseudopc $0000 {
|
||||||
|
!byte $00
|
||||||
|
!pet "Null-term PETSCII string",$00
|
||||||
|
!byte $80
|
||||||
|
!word @L3003
|
||||||
|
!word @LD003
|
||||||
|
!byte $80
|
||||||
|
}
|
||||||
|
|
||||||
|
!pseudopc $4000 {
|
||||||
|
@L4000 bit @L4000
|
||||||
|
bit @L5000
|
||||||
|
bit @L500F
|
||||||
|
bit @L500F
|
||||||
|
nop
|
||||||
|
jmp @L4020
|
||||||
|
|
||||||
|
!pseudopc $5000 {
|
||||||
|
@L5000 bit @L5000
|
||||||
|
bit @L4000
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
@L5008 bit @L5008
|
||||||
|
bit @L5017
|
||||||
|
nop
|
||||||
|
@L500F rts
|
||||||
|
|
||||||
|
}
|
||||||
|
@L4020 bit @L4020
|
||||||
|
bit @L500F
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
jmp @L4040
|
||||||
|
|
||||||
|
!pseudopc $5008 {
|
||||||
|
@L5008_0 bit @L5008_0
|
||||||
|
bit @L5000
|
||||||
|
nop
|
||||||
|
@L500F_0 bit @L500F_0
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
@L5017 rts
|
||||||
|
|
||||||
|
}
|
||||||
|
@L4040 bit @L4040
|
||||||
|
bit @L5017
|
||||||
|
nop
|
||||||
|
jmp @LD000
|
||||||
|
|
||||||
|
}
|
||||||
|
!pseudopc *+$bf7e {
|
||||||
|
@LD000 bit @L200C
|
||||||
|
@LD003 nop
|
||||||
|
jmp @LE000
|
||||||
|
|
||||||
|
!pseudopc $e000 {
|
||||||
|
@LE000 bit @LE000
|
||||||
|
jmp @LF000
|
||||||
|
|
||||||
|
!pseudopc $f000 {
|
||||||
|
@LF000 bit @LF000
|
||||||
|
lda @L3003
|
||||||
|
and @LD003
|
||||||
|
nop
|
||||||
|
rts
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
90
SourceGen/SGTestData/Expected/20250-nested-regions_cc65.S
Normal file
90
SourceGen/SGTestData/Expected/20250-nested-regions_cc65.S
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
.setcpu "6502"
|
||||||
|
.org $0000
|
||||||
|
.word $3000 ;load address
|
||||||
|
|
||||||
|
.org $3000
|
||||||
|
L3000: bit L3000
|
||||||
|
@L3003: lda @L3003
|
||||||
|
and @LD003
|
||||||
|
jmp @L200C
|
||||||
|
|
||||||
|
.org $200c
|
||||||
|
@L200C: bit @L200C
|
||||||
|
jmp @L1012
|
||||||
|
|
||||||
|
.org $1012
|
||||||
|
@L1012: bit @L1012
|
||||||
|
jsr @L4000
|
||||||
|
.org $0000
|
||||||
|
.byte $00
|
||||||
|
.byte $ce,$55,$4c,$4c,$2d,$54,$45,$52,$4d,$20,$d0,$c5,$d4,$d3,$c3,$c9
|
||||||
|
.byte $c9,$20,$53,$54,$52,$49,$4e,$47,$00
|
||||||
|
.byte $80
|
||||||
|
.word @L3003
|
||||||
|
.word @LD003
|
||||||
|
.byte $80
|
||||||
|
|
||||||
|
.org $4000
|
||||||
|
@L4000: bit @L4000
|
||||||
|
bit @L5000
|
||||||
|
bit @L500F
|
||||||
|
bit @L500F
|
||||||
|
nop
|
||||||
|
jmp @L4020
|
||||||
|
|
||||||
|
.org $5000
|
||||||
|
@L5000: bit @L5000
|
||||||
|
bit @L4000
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
@L5008: bit @L5008
|
||||||
|
bit @L5017
|
||||||
|
nop
|
||||||
|
@L500F: rts
|
||||||
|
|
||||||
|
.org $4020
|
||||||
|
@L4020: bit @L4020
|
||||||
|
bit @L500F
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
jmp @L4040
|
||||||
|
|
||||||
|
.org $5008
|
||||||
|
@L5008_0: bit @L5008_0
|
||||||
|
bit @L5000
|
||||||
|
nop
|
||||||
|
@L500F_0: bit @L500F_0
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
@L5017: rts
|
||||||
|
|
||||||
|
.org $4040
|
||||||
|
@L4040: bit @L4040
|
||||||
|
bit @L5017
|
||||||
|
nop
|
||||||
|
jmp @LD000
|
||||||
|
|
||||||
|
.org $d000
|
||||||
|
@LD000: bit @L200C
|
||||||
|
@LD003: nop
|
||||||
|
jmp @LE000
|
||||||
|
|
||||||
|
.org $e000
|
||||||
|
@LE000: bit @LE000
|
||||||
|
jmp @LF000
|
||||||
|
|
||||||
|
.org $f000
|
||||||
|
@LF000: bit @LF000
|
||||||
|
lda @L3003
|
||||||
|
and @LD003
|
||||||
|
nop
|
||||||
|
rts
|
||||||
|
|
@ -0,0 +1,9 @@
|
|||||||
|
# 6502bench SourceGen generated linker script for 20250-nested-regions
|
||||||
|
MEMORY {
|
||||||
|
MAIN: file=%O, start=%S, size=65536;
|
||||||
|
}
|
||||||
|
SEGMENTS {
|
||||||
|
CODE: load=MAIN, type=rw;
|
||||||
|
}
|
||||||
|
FEATURES {}
|
||||||
|
SYMBOLS {}
|
@ -0,0 +1,88 @@
|
|||||||
|
org $0000
|
||||||
|
dw $3000 ;load address
|
||||||
|
|
||||||
|
org $3000
|
||||||
|
L3000 bit L3000
|
||||||
|
:L3003 lda :L3003
|
||||||
|
and :LD003
|
||||||
|
jmp :L200C
|
||||||
|
|
||||||
|
org $200c
|
||||||
|
:L200C bit :L200C
|
||||||
|
jmp :L1012
|
||||||
|
|
||||||
|
org $1012
|
||||||
|
:L1012 bit :L1012
|
||||||
|
jsr :L4000
|
||||||
|
org $0000
|
||||||
|
dfb $00
|
||||||
|
hex ce554c4c2d5445524d20d0c5d4d3c3c9c920535452494e4700
|
||||||
|
dfb $80
|
||||||
|
dw :L3003
|
||||||
|
dw :LD003
|
||||||
|
dfb $80
|
||||||
|
|
||||||
|
org $4000
|
||||||
|
:L4000 bit :L4000
|
||||||
|
bit :L5000
|
||||||
|
bit :L500F
|
||||||
|
bit :L500F
|
||||||
|
nop
|
||||||
|
jmp :L4020
|
||||||
|
|
||||||
|
org $5000
|
||||||
|
:L5000 bit :L5000
|
||||||
|
bit :L4000
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
:L5008 bit :L5008
|
||||||
|
bit :L5017
|
||||||
|
nop
|
||||||
|
:L500F rts
|
||||||
|
|
||||||
|
org $4020
|
||||||
|
:L4020 bit :L4020
|
||||||
|
bit :L500F
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
jmp :L4040
|
||||||
|
|
||||||
|
org $5008
|
||||||
|
:L5008_0 bit :L5008_0
|
||||||
|
bit :L5000
|
||||||
|
nop
|
||||||
|
:L500F_0 bit :L500F_0
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
:L5017 rts
|
||||||
|
|
||||||
|
org $4040
|
||||||
|
:L4040 bit :L4040
|
||||||
|
bit :L5017
|
||||||
|
nop
|
||||||
|
jmp :LD000
|
||||||
|
|
||||||
|
org $d000
|
||||||
|
:LD000 bit :L200C
|
||||||
|
:LD003 nop
|
||||||
|
jmp :LE000
|
||||||
|
|
||||||
|
org $e000
|
||||||
|
:LE000 bit :LE000
|
||||||
|
jmp :LF000
|
||||||
|
|
||||||
|
org $f000
|
||||||
|
:LF000 bit :LF000
|
||||||
|
lda :L3003
|
||||||
|
and :LD003
|
||||||
|
nop
|
||||||
|
rts
|
||||||
|
|
30
SourceGen/SGTestData/Expected/20252-nested-regions_64tass.S
Normal file
30
SourceGen/SGTestData/Expected/20252-nested-regions_64tass.S
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
.cpu "65816"
|
||||||
|
.logical $011000
|
||||||
|
.logical *+$010000
|
||||||
|
.logical *+$010000
|
||||||
|
.as
|
||||||
|
.xs
|
||||||
|
L31000 lda L31000
|
||||||
|
_L31004 lda _L31004
|
||||||
|
and _L1101F
|
||||||
|
jml _L21010
|
||||||
|
|
||||||
|
.here
|
||||||
|
_L21010 lda _L21010
|
||||||
|
jml _L11018
|
||||||
|
|
||||||
|
.here
|
||||||
|
_L11018 lda _L11018
|
||||||
|
jmp _L11026
|
||||||
|
|
||||||
|
_L1101F .byte $80
|
||||||
|
.logical *-$011020
|
||||||
|
.byte $ea
|
||||||
|
.byte $60
|
||||||
|
.dword _L31004
|
||||||
|
.here
|
||||||
|
|
||||||
|
_L11026 nop
|
||||||
|
rts
|
||||||
|
|
||||||
|
.here
|
@ -0,0 +1,6 @@
|
|||||||
|
;ACME can't handle 65816 code that lives outside bank zero
|
||||||
|
* = $0000
|
||||||
|
!pseudopc $031000 {
|
||||||
|
!hex af001003af0410032f1f10015c101002af1010025c181001af1810014c261080
|
||||||
|
!hex ea6004100300ea60
|
||||||
|
}
|
27
SourceGen/SGTestData/Expected/20252-nested-regions_cc65.S
Normal file
27
SourceGen/SGTestData/Expected/20252-nested-regions_cc65.S
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
.setcpu "65816"
|
||||||
|
.org $031000
|
||||||
|
.a8
|
||||||
|
.i8
|
||||||
|
L31000: lda L31000
|
||||||
|
@L31004: lda @L31004
|
||||||
|
and f:@L1101F
|
||||||
|
jml @L21010
|
||||||
|
|
||||||
|
.org $021010
|
||||||
|
@L21010: lda @L21010
|
||||||
|
jml @L11018
|
||||||
|
|
||||||
|
.org $011018
|
||||||
|
@L11018: lda @L11018
|
||||||
|
jmp @L11026 & $ffff
|
||||||
|
|
||||||
|
@L1101F: .byte $80
|
||||||
|
.org $0000
|
||||||
|
.byte $ea
|
||||||
|
.byte $60
|
||||||
|
.dword @L31004
|
||||||
|
|
||||||
|
.org $011026
|
||||||
|
@L11026: nop
|
||||||
|
rts
|
||||||
|
|
@ -0,0 +1,9 @@
|
|||||||
|
# 6502bench SourceGen generated linker script for 20252-nested-regions
|
||||||
|
MEMORY {
|
||||||
|
MAIN: file=%O, start=%S, size=65536;
|
||||||
|
}
|
||||||
|
SEGMENTS {
|
||||||
|
CODE: load=MAIN, type=rw;
|
||||||
|
}
|
||||||
|
FEATURES {}
|
||||||
|
SYMBOLS {}
|
@ -0,0 +1,24 @@
|
|||||||
|
org $031000
|
||||||
|
L31000 ldal L31000
|
||||||
|
:L31004 ldal :L31004
|
||||||
|
andl :L1101F
|
||||||
|
jml :L21010
|
||||||
|
|
||||||
|
org $021010
|
||||||
|
:L21010 ldal :L21010
|
||||||
|
jml :L11018
|
||||||
|
|
||||||
|
org $011018
|
||||||
|
:L11018 ldal :L11018
|
||||||
|
jmp :L11026
|
||||||
|
|
||||||
|
:L1101F dfb $80
|
||||||
|
org $0000
|
||||||
|
dfb $ea
|
||||||
|
dfb $60
|
||||||
|
adrl :L31004
|
||||||
|
|
||||||
|
org $011026
|
||||||
|
:L11026 nop
|
||||||
|
rts
|
||||||
|
|
137
SourceGen/SGTestData/Source/20250-nested-regions.S
Normal file
137
SourceGen/SGTestData/Source/20250-nested-regions.S
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
; Copyright 2021 faddenSoft. All Rights Reserved.
|
||||||
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
|
;
|
||||||
|
; Test nested address regions.
|
||||||
|
;
|
||||||
|
; Assembler: 64tass
|
||||||
|
; % tass64 --ascii --case-sensitive --nostart 20250-nested-regions.S
|
||||||
|
|
||||||
|
.cpu "6502"
|
||||||
|
* = $1000
|
||||||
|
START
|
||||||
|
.word $3000
|
||||||
|
|
||||||
|
; NOTE: leave PRG header as a 2-byte hole with no explicit region
|
||||||
|
|
||||||
|
; Start with 3 nested regions that share a starting address.
|
||||||
|
|
||||||
|
; EDIT: create region starting at $1000, ending at REGION_END
|
||||||
|
; EDIT: make all 3 of these relative (especially the first one, which follows non-addr)
|
||||||
|
|
||||||
|
|
||||||
|
; EDIT: create these as fixed-end regions; first one spans full file
|
||||||
|
.logical $1000
|
||||||
|
.logical $2000
|
||||||
|
.logical $3000
|
||||||
|
|
||||||
|
part3k bit part3k
|
||||||
|
early lda early
|
||||||
|
and late
|
||||||
|
jmp part2k
|
||||||
|
|
||||||
|
.here ;$3000; now $20xx
|
||||||
|
|
||||||
|
part2k bit part2k
|
||||||
|
jmp part1k
|
||||||
|
|
||||||
|
.here ;$2000; now $10xx
|
||||||
|
|
||||||
|
part1k bit part1k
|
||||||
|
jsr overhole ;let execution try to fall into non-addr
|
||||||
|
|
||||||
|
REGION1_END
|
||||||
|
|
||||||
|
; EDIT: next chunk is a *floating* non-addr region
|
||||||
|
|
||||||
|
brk
|
||||||
|
.null "Null-term PETSCII string"
|
||||||
|
.byte $80
|
||||||
|
.word early
|
||||||
|
.word late
|
||||||
|
.byte $80
|
||||||
|
|
||||||
|
; 4000-40xx, with two overlapping regions in the $5000 area. Tests order
|
||||||
|
; of resolution and descent into children. (This is mostly tested internally
|
||||||
|
; by the AddressMap unit tests, so we don't need to go crazy here.)
|
||||||
|
|
||||||
|
.logical $4000
|
||||||
|
overhole
|
||||||
|
a4000 bit a4000
|
||||||
|
bit b5000
|
||||||
|
bit b500f ;CHECK: resolves to b500f
|
||||||
|
bit c500f ;CHECK: also resolves to b500f
|
||||||
|
nop
|
||||||
|
jmp a4020
|
||||||
|
|
||||||
|
; EDIT: set region, add code start tag
|
||||||
|
.logical $5000
|
||||||
|
b5000 bit b5000
|
||||||
|
b5003 bit a4000
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
b5008 bit b5008 ;CHECK: resolves locally
|
||||||
|
bit c5017 ;CHECK: resolves to other segment
|
||||||
|
nop
|
||||||
|
b500f rts
|
||||||
|
.here ;$5000, now at $4010
|
||||||
|
|
||||||
|
a4020 bit a4020
|
||||||
|
bit c500f
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
jmp a4040
|
||||||
|
|
||||||
|
; EDIT: set region, add code start tag
|
||||||
|
.logical $5008
|
||||||
|
c5008 bit c5008 ;CHECK: resolves locally
|
||||||
|
bit b5000 ;CHECK: resolves to other segment
|
||||||
|
nop
|
||||||
|
c500f bit c500f
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
c5017 rts
|
||||||
|
.here ;$5008
|
||||||
|
|
||||||
|
a4040 bit a4040
|
||||||
|
bit c5017
|
||||||
|
nop
|
||||||
|
jmp tailend
|
||||||
|
.here ;$4000
|
||||||
|
|
||||||
|
|
||||||
|
; EDIT: create region starting at $d000, ending at REGION2_END; relative
|
||||||
|
.logical $d000
|
||||||
|
tailend
|
||||||
|
partdk bit part2k
|
||||||
|
late nop
|
||||||
|
jmp partek
|
||||||
|
|
||||||
|
; EDIT: create
|
||||||
|
.logical $e000
|
||||||
|
|
||||||
|
partek bit partek
|
||||||
|
jmp partfk
|
||||||
|
|
||||||
|
; EDIT: create, make it floating
|
||||||
|
.logical $f000
|
||||||
|
|
||||||
|
partfk bit partfk
|
||||||
|
lda early
|
||||||
|
and late
|
||||||
|
|
||||||
|
end
|
||||||
|
nop
|
||||||
|
rts
|
||||||
|
REGION2_END
|
||||||
|
.here ;$f000
|
||||||
|
.here ;$e000
|
||||||
|
.here ;$d000
|
||||||
|
.here ;$1000
|
47
SourceGen/SGTestData/Source/20252-nested-regions.S
Normal file
47
SourceGen/SGTestData/Source/20252-nested-regions.S
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
; Copyright 2021 faddenSoft. All Rights Reserved.
|
||||||
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
|
;
|
||||||
|
; Test nested address regions.
|
||||||
|
;
|
||||||
|
; Assembler: 64tass
|
||||||
|
; % tass64 --ascii --case-sensitive --nostart 20252-nested-regions.S
|
||||||
|
|
||||||
|
.cpu "65816"
|
||||||
|
* = $081000
|
||||||
|
START
|
||||||
|
|
||||||
|
; Start with 3 nested regions that share a starting address.
|
||||||
|
|
||||||
|
; EDIT: create these as fixed-end regions; first one spans full file
|
||||||
|
.logical $011000
|
||||||
|
.logical $021000
|
||||||
|
.logical $031000
|
||||||
|
|
||||||
|
part3k lda @lpart3k
|
||||||
|
early lda early
|
||||||
|
and late
|
||||||
|
jmp part2k
|
||||||
|
|
||||||
|
.here ;031000
|
||||||
|
|
||||||
|
part2k lda @lpart2k
|
||||||
|
jmp part1k
|
||||||
|
|
||||||
|
.here ;021000
|
||||||
|
|
||||||
|
part1k lda @lpart1k
|
||||||
|
jmp end
|
||||||
|
|
||||||
|
late .byte $80
|
||||||
|
|
||||||
|
; EIDT: make this a non-addressable region
|
||||||
|
; EDIT: put a code start tag here
|
||||||
|
tag nop
|
||||||
|
rts
|
||||||
|
.dword early
|
||||||
|
|
||||||
|
end
|
||||||
|
nop
|
||||||
|
rts
|
||||||
|
REGION2_END
|
||||||
|
.here ;$011000
|
@ -33,25 +33,47 @@ limitations under the License.
|
|||||||
<system:String x:Key="str_HdrCreate">Creating new address region</system:String>
|
<system:String x:Key="str_HdrCreate">Creating new address region</system:String>
|
||||||
<system:String x:Key="str_HdrEdit">Editing existing address region:</system:String>
|
<system:String x:Key="str_HdrEdit">Editing existing address region:</system:String>
|
||||||
|
|
||||||
|
<system:String x:Key="str_OptEditAsIsSummary">
|
||||||
|
Edit only.
|
||||||
|
</system:String>
|
||||||
<system:String x:Key="str_OptEditAsIs">
|
<system:String x:Key="str_OptEditAsIs">
|
||||||
Edit the region's attributes. Region length will not be changed.
|
Edit the region's attributes. Region length will not be changed.
|
||||||
</system:String>
|
</system:String>
|
||||||
|
<system:String x:Key="str_OptEditAndFixSummary">
|
||||||
|
Set fixed size.
|
||||||
|
</system:String>
|
||||||
<system:String x:Key="str_OptEditAndFix">
|
<system:String x:Key="str_OptEditAndFix">
|
||||||
Edit the region's attributes, and convert the floating end to a fixed end.
|
Edit the region's attributes, and convert the floating end to a fixed end.
|
||||||
</system:String>
|
</system:String>
|
||||||
|
<system:String x:Key="str_OptResizeSummary">
|
||||||
|
Resize.
|
||||||
|
</system:String>
|
||||||
<system:String x:Key="str_OptResize">
|
<system:String x:Key="str_OptResize">
|
||||||
Edit the region's attributes, and resize it to the selection. The new
|
Edit the region's attributes, and resize it to the selection. The new
|
||||||
end offset will be {0}, for a length of {1}.
|
end offset will be {0}, for a length of {1}.
|
||||||
</system:String>
|
</system:String>
|
||||||
<system:String x:Key="str_OptResizeFail">
|
<system:String x:Key="str_OptResizeFail">
|
||||||
Cannot resize to the selection.
|
Resize not available: cannot resize to the selection. {0}
|
||||||
|
</system:String>
|
||||||
|
<system:String x:Key="str_CreateFixedSummary">
|
||||||
|
Create fixed.
|
||||||
</system:String>
|
</system:String>
|
||||||
<system:String x:Key="str_CreateFixed">
|
<system:String x:Key="str_CreateFixed">
|
||||||
Create a new region, with a fixed end point. The region will start at {0}
|
Create a new region, with a fixed end point. The region will start at {0}
|
||||||
and have a length of {1}.
|
and have a length of {1}.
|
||||||
</system:String>
|
</system:String>
|
||||||
|
<system:String x:Key="str_CreateFixedAlreadyFixed">
|
||||||
|
Create fixed not available: can't convert to fixed end point because it's already fixed.
|
||||||
|
</system:String>
|
||||||
<system:String x:Key="str_CreateFixedFail">
|
<system:String x:Key="str_CreateFixedFail">
|
||||||
Unable to create a new region with a fixed end point here.
|
Create fixed not available: unable to create a new region with a fixed end point here.
|
||||||
|
</system:String>
|
||||||
|
<system:String x:Key="str_CreateFixedFailStraddle">
|
||||||
|
Create fixed not available: unable to create a new region with a fixed end point
|
||||||
|
here, because it would straddle an existing region.
|
||||||
|
</system:String>
|
||||||
|
<system:String x:Key="str_CreateFloatingSummary">
|
||||||
|
Create floating.
|
||||||
</system:String>
|
</system:String>
|
||||||
<system:String x:Key="str_CreateFloating">
|
<system:String x:Key="str_CreateFloating">
|
||||||
Create a new region, with a floating end point. The region will start at {0}
|
Create a new region, with a floating end point. The region will start at {0}
|
||||||
@ -59,13 +81,13 @@ limitations under the License.
|
|||||||
may change as other regions are added and removed.
|
may change as other regions are added and removed.
|
||||||
</system:String>
|
</system:String>
|
||||||
<system:String x:Key="str_CreateFloatingFail">
|
<system:String x:Key="str_CreateFloatingFail">
|
||||||
Unable to create a new region with a floating end point here.
|
Create floating not available: unable to create a new region with a floating end point here.
|
||||||
</system:String>
|
</system:String>
|
||||||
|
|
||||||
<system:String x:Key="str_ErrInternal">Internal error.</system:String>
|
<system:String x:Key="str_ErrInternal">Internal error.</system:String>
|
||||||
<system:String x:Key="str_ErrInvalidValue">Internal error (invalid value).</system:String>
|
<system:String x:Key="str_ErrInvalidValue">Internal error (invalid value).</system:String>
|
||||||
<system:String x:Key="str_ErrOverlapExisting">
|
<system:String x:Key="str_ErrOverlapExisting">
|
||||||
The new region has the same start offset and length as an existing region.
|
The new region would have the same start offset and length as an existing region.
|
||||||
</system:String>
|
</system:String>
|
||||||
<system:String x:Key="str_ErrOverlapFloating">
|
<system:String x:Key="str_ErrOverlapFloating">
|
||||||
The start offset of the new region is the same as the start offset of an existing
|
The start offset of the new region is the same as the start offset of an existing
|
||||||
@ -77,7 +99,7 @@ limitations under the License.
|
|||||||
</Window.Resources>
|
</Window.Resources>
|
||||||
|
|
||||||
<StackPanel Margin="8">
|
<StackPanel Margin="8">
|
||||||
<TextBlock Text="{Binding OperationStr, FallbackValue=Editing existing region}"/>
|
<TextBlock Text="{Binding OperationStr, FallbackValue=Editing existing address region:}"/>
|
||||||
<Grid Visibility="{Binding ShowExistingRegion, Converter={StaticResource BoolToVis}}">
|
<Grid Visibility="{Binding ShowExistingRegion, Converter={StaticResource BoolToVis}}">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
@ -114,7 +136,7 @@ limitations under the License.
|
|||||||
IsEnabled="{Binding EnableOption1}"
|
IsEnabled="{Binding EnableOption1}"
|
||||||
IsChecked="{Binding CheckOption1}">
|
IsChecked="{Binding CheckOption1}">
|
||||||
<RadioButton.Content>
|
<RadioButton.Content>
|
||||||
<TextBlock TextWrapping="Wrap" Text="{Binding Option1Str, FallbackValue=Option 1}"/>
|
<TextBlock Name="option1TextBlock" TextWrapping="Wrap" Text="Option 1"/>
|
||||||
</RadioButton.Content>
|
</RadioButton.Content>
|
||||||
</RadioButton>
|
</RadioButton>
|
||||||
<RadioButton Name="radioOption2" Margin="0,4,0,0"
|
<RadioButton Name="radioOption2" Margin="0,4,0,0"
|
||||||
@ -122,7 +144,7 @@ limitations under the License.
|
|||||||
IsEnabled="{Binding EnableOption2}"
|
IsEnabled="{Binding EnableOption2}"
|
||||||
IsChecked="{Binding CheckOption2}">
|
IsChecked="{Binding CheckOption2}">
|
||||||
<RadioButton.Content>
|
<RadioButton.Content>
|
||||||
<TextBlock TextWrapping="Wrap" Text="{Binding Option2Str, FallbackValue=Option 2}"/>
|
<TextBlock Name="option2TextBlock" TextWrapping="Wrap" Text="Option 2"/>
|
||||||
</RadioButton.Content>
|
</RadioButton.Content>
|
||||||
</RadioButton>
|
</RadioButton>
|
||||||
|
|
||||||
@ -151,8 +173,8 @@ limitations under the License.
|
|||||||
</TextBox>
|
</TextBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<TextBlock Text="• Enter 16-bit or 24-bit address, e.g. $1000 or 01/be00." Margin="0,4,0,0"/>
|
<TextBlock Text="• Enter 16-bit or 24-bit address, e.g. $1000 or 01/be00" Margin="0,4,0,0"/>
|
||||||
<TextBlock Text="• Enter 'NA' if the region is non-addressable."/>
|
<TextBlock Text="• Enter 'NA' to mark the region non-addressable"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel IsEnabled="{Binding EnableAttributeControls}">
|
<StackPanel IsEnabled="{Binding EnableAttributeControls}">
|
||||||
@ -173,9 +195,9 @@ limitations under the License.
|
|||||||
<TextBlock Text=")"/>
|
<TextBlock Text=")"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<TextBlock Text="• Must be valid label syntax; may not be a local label." Margin="0,4,0,0"/>
|
<TextBlock Text="• Must be valid label syntax; may not be a local label" Margin="0,4,0,0"/>
|
||||||
<TextBlock Text="• Must not be a duplicate of an existing label."/>
|
<TextBlock Text="• Must not be a duplicate of an existing label"/>
|
||||||
<TextBlock Text="• Will not appear if parent region is non-addressable."/>
|
<TextBlock Text="• Will not appear if parent region is non-addressable"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -18,7 +18,8 @@ using System.ComponentModel;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Documents;
|
||||||
using Asm65;
|
using Asm65;
|
||||||
using CommonUtil;
|
using CommonUtil;
|
||||||
|
|
||||||
@ -109,18 +110,6 @@ namespace SourceGen.WpfGui {
|
|||||||
}
|
}
|
||||||
private bool mCheckOption2;
|
private bool mCheckOption2;
|
||||||
|
|
||||||
public string Option1Str {
|
|
||||||
get { return mOption1Str; }
|
|
||||||
set { mOption1Str = value; OnPropertyChanged(); }
|
|
||||||
}
|
|
||||||
private string mOption1Str;
|
|
||||||
|
|
||||||
public string Option2Str {
|
|
||||||
get { return mOption2Str; }
|
|
||||||
set { mOption2Str = value; OnPropertyChanged(); }
|
|
||||||
}
|
|
||||||
private string mOption2Str;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Address at which a pre-label would be placed. This is determined by the parent
|
/// Address at which a pre-label would be placed. This is determined by the parent
|
||||||
/// region, so its value is fixed.
|
/// region, so its value is fixed.
|
||||||
@ -279,6 +268,11 @@ namespace SourceGen.WpfGui {
|
|||||||
CheckOption1 = true;
|
CheckOption1 = true;
|
||||||
EnableAttributeControls = true;
|
EnableAttributeControls = true;
|
||||||
|
|
||||||
|
string option1Summ;
|
||||||
|
string option1Msg;
|
||||||
|
string option2Summ;
|
||||||
|
string option2Msg;
|
||||||
|
|
||||||
if (curRegion != null) {
|
if (curRegion != null) {
|
||||||
// Editing an existing region.
|
// Editing an existing region.
|
||||||
CanDeleteRegion = true;
|
CanDeleteRegion = true;
|
||||||
@ -304,14 +298,18 @@ namespace SourceGen.WpfGui {
|
|||||||
mResultEntry1 = new AddressMap.AddressMapEntry(curRegion.Offset,
|
mResultEntry1 = new AddressMap.AddressMapEntry(curRegion.Offset,
|
||||||
curRegion.Length, curRegion.Address, curRegion.PreLabel,
|
curRegion.Length, curRegion.Address, curRegion.PreLabel,
|
||||||
curRegion.IsRelative);
|
curRegion.IsRelative);
|
||||||
Option1Str = (string)FindResource("str_OptEditAsIs");
|
option1Summ = (string)FindResource("str_OptEditAsIsSummary");
|
||||||
Option2Str = (string)FindResource("str_OptEditAndFix");
|
option1Msg = (string)FindResource("str_OptEditAsIs");
|
||||||
|
|
||||||
if (curRegion.IsFloating) {
|
if (curRegion.IsFloating) {
|
||||||
|
option2Summ = (string)FindResource("str_OptEditAndFixSummary");
|
||||||
|
option2Msg = (string)FindResource("str_OptEditAndFix");
|
||||||
mResultEntry2 = new AddressMap.AddressMapEntry(curRegion.Offset,
|
mResultEntry2 = new AddressMap.AddressMapEntry(curRegion.Offset,
|
||||||
curRegion.ActualLength, curRegion.Address, curRegion.PreLabel,
|
curRegion.ActualLength, curRegion.Address, curRegion.PreLabel,
|
||||||
curRegion.IsRelative);
|
curRegion.IsRelative);
|
||||||
} else {
|
} else {
|
||||||
|
option2Summ = string.Empty;
|
||||||
|
option2Msg = (string)FindResource("str_CreateFixedAlreadyFixed");
|
||||||
mResultEntry2 = null;
|
mResultEntry2 = null;
|
||||||
EnableOption2 = false; // show it, but disabled
|
EnableOption2 = false; // show it, but disabled
|
||||||
}
|
}
|
||||||
@ -328,11 +326,13 @@ namespace SourceGen.WpfGui {
|
|||||||
curRegion.Length, curRegion.Address, curRegion.PreLabel,
|
curRegion.Length, curRegion.Address, curRegion.PreLabel,
|
||||||
curRegion.IsRelative);
|
curRegion.IsRelative);
|
||||||
|
|
||||||
|
option1Summ = (string)FindResource("str_OptResizeSummary");
|
||||||
string fmt = (string)FindResource("str_OptResize");
|
string fmt = (string)FindResource("str_OptResize");
|
||||||
Option1Str = string.Format(fmt,
|
option1Msg = string.Format(fmt,
|
||||||
mFormatter.FormatOffset24(curRegion.Offset + selectionLen - 1),
|
mFormatter.FormatOffset24(curRegion.Offset + selectionLen - 1),
|
||||||
FormatLength(selectionLen));
|
FormatLength(selectionLen));
|
||||||
Option2Str = (string)FindResource("str_OptEditAsIs");
|
option2Summ = (string)FindResource("str_OptEditAsIsSummary");
|
||||||
|
option2Msg = (string)FindResource("str_OptEditAsIs");
|
||||||
|
|
||||||
Debug.Assert(selectionLen > 0);
|
Debug.Assert(selectionLen > 0);
|
||||||
AddressMap.AddResult ares;
|
AddressMap.AddResult ares;
|
||||||
@ -340,7 +340,9 @@ namespace SourceGen.WpfGui {
|
|||||||
curRegion.Address, out ares);
|
curRegion.Address, out ares);
|
||||||
if (ares != AddressMap.AddResult.Okay) {
|
if (ares != AddressMap.AddResult.Okay) {
|
||||||
// Can't resize the new region, so disable that option (still visible).
|
// Can't resize the new region, so disable that option (still visible).
|
||||||
Option1Str = (string)FindResource("str_OptResizeFail");
|
option1Summ = string.Empty;
|
||||||
|
string fmta = (string)FindResource("str_OptResizeFail");
|
||||||
|
option1Msg = string.Format(fmta, GetErrorString(ares));
|
||||||
EnableOption1 = false;
|
EnableOption1 = false;
|
||||||
CheckOption2 = true;
|
CheckOption2 = true;
|
||||||
}
|
}
|
||||||
@ -378,13 +380,19 @@ namespace SourceGen.WpfGui {
|
|||||||
mResultEntry1 = new AddressMap.AddressMapEntry(newEntry.Offset,
|
mResultEntry1 = new AddressMap.AddressMapEntry(newEntry.Offset,
|
||||||
newRegion1.ActualLength, newEntry.Address, string.Empty, false);
|
newRegion1.ActualLength, newEntry.Address, string.Empty, false);
|
||||||
|
|
||||||
|
option1Summ = (string)FindResource("str_CreateFixedSummary");
|
||||||
string fmt = (string)FindResource("str_CreateFixed");
|
string fmt = (string)FindResource("str_CreateFixed");
|
||||||
Option1Str = string.Format(fmt,
|
option1Msg = string.Format(fmt,
|
||||||
mFormatter.FormatOffset24(newEntry.Offset),
|
mFormatter.FormatOffset24(newEntry.Offset),
|
||||||
FormatLength(newRegion1.ActualLength));
|
FormatLength(newRegion1.ActualLength));
|
||||||
mPreLabelAddress = newRegion1.PreLabelAddress;
|
mPreLabelAddress = newRegion1.PreLabelAddress;
|
||||||
} else {
|
} else {
|
||||||
Option1Str = (string)FindResource("str_CreateFixedFail");
|
option1Summ = string.Empty;
|
||||||
|
if (ares1 == AddressMap.AddResult.StraddleExisting) {
|
||||||
|
option1Msg = (string)FindResource("str_CreateFixedFailStraddle");
|
||||||
|
} else {
|
||||||
|
option1Msg = (string)FindResource("str_CreateFixedFail");
|
||||||
|
}
|
||||||
CheckOption2 = true;
|
CheckOption2 = true;
|
||||||
EnableOption1 = false;
|
EnableOption1 = false;
|
||||||
}
|
}
|
||||||
@ -392,13 +400,15 @@ namespace SourceGen.WpfGui {
|
|||||||
mResultEntry2 = new AddressMap.AddressMapEntry(newEntry.Offset,
|
mResultEntry2 = new AddressMap.AddressMapEntry(newEntry.Offset,
|
||||||
AddressMap.FLOATING_LEN, newEntry.Address, string.Empty, false);
|
AddressMap.FLOATING_LEN, newEntry.Address, string.Empty, false);
|
||||||
|
|
||||||
|
option2Summ = (string)FindResource("str_CreateFloatingSummary");
|
||||||
string fmt = (string)FindResource("str_CreateFloating");
|
string fmt = (string)FindResource("str_CreateFloating");
|
||||||
Option2Str = string.Format(fmt,
|
option2Msg = string.Format(fmt,
|
||||||
mFormatter.FormatOffset24(newEntry.Offset),
|
mFormatter.FormatOffset24(newEntry.Offset),
|
||||||
FormatLength(newRegion2.ActualLength));
|
FormatLength(newRegion2.ActualLength));
|
||||||
mPreLabelAddress = newRegion2.PreLabelAddress;
|
mPreLabelAddress = newRegion2.PreLabelAddress;
|
||||||
} else {
|
} else {
|
||||||
Option2Str = (string)FindResource("str_CreateFloatingFail");
|
option2Summ = string.Empty;
|
||||||
|
option2Msg = (string)FindResource("str_CreateFloatingFail");
|
||||||
CheckOption1 = true;
|
CheckOption1 = true;
|
||||||
CheckOption2 = false; // required for some reason
|
CheckOption2 = false; // required for some reason
|
||||||
EnableOption2 = false;
|
EnableOption2 = false;
|
||||||
@ -412,6 +422,20 @@ namespace SourceGen.WpfGui {
|
|||||||
SetErrorString(ares1);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string FormatLength(int len) {
|
private string FormatLength(int len) {
|
||||||
@ -442,7 +466,7 @@ namespace SourceGen.WpfGui {
|
|||||||
return newRegion;
|
return newRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetErrorString(AddressMap.AddResult result) {
|
private string GetErrorString(AddressMap.AddResult result) {
|
||||||
string rsrc;
|
string rsrc;
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case AddressMap.AddResult.InternalError:
|
case AddressMap.AddResult.InternalError:
|
||||||
@ -458,15 +482,18 @@ namespace SourceGen.WpfGui {
|
|||||||
rsrc = "str_ErrOverlapFloating";
|
rsrc = "str_ErrOverlapFloating";
|
||||||
break;
|
break;
|
||||||
case AddressMap.AddResult.StraddleExisting:
|
case AddressMap.AddResult.StraddleExisting:
|
||||||
rsrc = "str_ErrStraddelExisting";
|
rsrc = "str_ErrStraddleExisting";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Debug.Assert(false);
|
Debug.Assert(false);
|
||||||
rsrc = "str_ErrInternal";
|
rsrc = "str_ErrInternal";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return(string)FindResource(rsrc); // throws exception on failure
|
||||||
|
}
|
||||||
|
|
||||||
ErrorMessageStr = (string)FindResource(rsrc); // throws exception on failure
|
private void SetErrorString(AddressMap.AddResult result) {
|
||||||
|
ErrorMessageStr = GetErrorString(result);
|
||||||
ShowErrorMessage = true;
|
ShowErrorMessage = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ limitations under the License.
|
|||||||
<TextBlock Name="firstLetterLabel" Text="• Must start with a letter or underscore"/>
|
<TextBlock Name="firstLetterLabel" Text="• Must start with a letter or underscore"/>
|
||||||
<TextBlock Name="validCharsLabel" Text="• Valid characters are ASCII letters, numbers, and underscore"/>
|
<TextBlock Name="validCharsLabel" Text="• Valid characters are ASCII letters, numbers, and underscore"/>
|
||||||
<TextBlock Name="notDuplicateLabel" Text="• Must not be a duplicate of an existing label"/>
|
<TextBlock Name="notDuplicateLabel" Text="• Must not be a duplicate of an existing label"/>
|
||||||
|
<TextBlock Visibility="{Binding NonAddrWarningVis}" Foreground="Blue"
|
||||||
|
Text="• NOTE: label is in a non-addressable data area"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<GroupBox Grid.Column="0" Grid.Row="1" Header="Label Type" Padding="2,4" Margin="0,12,0,0">
|
<GroupBox Grid.Column="0" Grid.Row="1" Header="Label Type" Padding="2,4" Margin="0,12,0,0">
|
||||||
|
@ -121,6 +121,8 @@ namespace SourceGen.WpfGui {
|
|||||||
set { mIsExportedEnabled = value; OnPropertyChanged(); }
|
set { mIsExportedEnabled = value; OnPropertyChanged(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Visibility NonAddrWarningVis { get; private set; }
|
||||||
|
|
||||||
// INotifyPropertyChanged implementation
|
// INotifyPropertyChanged implementation
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
||||||
@ -142,6 +144,12 @@ namespace SourceGen.WpfGui {
|
|||||||
|
|
||||||
string fmt = (string)FindResource("str_NonUniqueLocalFmt");
|
string fmt = (string)FindResource("str_NonUniqueLocalFmt");
|
||||||
NonUniqueButtonLabel = string.Format(fmt, mFormatter.NonUniqueLabelPrefix);
|
NonUniqueButtonLabel = string.Format(fmt, mFormatter.NonUniqueLabelPrefix);
|
||||||
|
|
||||||
|
if (mAddress == Address.NON_ADDR) {
|
||||||
|
NonAddrWarningVis = Visibility.Visible;
|
||||||
|
} else {
|
||||||
|
NonAddrWarningVis = Visibility.Collapsed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||||
|
@ -425,12 +425,12 @@ limitations under the License.
|
|||||||
<MenuItem Command="{StaticResource ViewAddressMapCmd}"/>
|
<MenuItem Command="{StaticResource ViewAddressMapCmd}"/>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Name="actionsMenu" Header="_Actions">
|
<MenuItem Name="actionsMenu" Header="_Actions">
|
||||||
<MenuItem Command="{StaticResource EditAddressCmd}"/>
|
|
||||||
<MenuItem Command="{StaticResource EditStatusFlagsCmd}"/>
|
|
||||||
<MenuItem Command="{StaticResource EditLabelCmd}"/>
|
|
||||||
<MenuItem Command="{StaticResource EditOperandCmd}"/>
|
<MenuItem Command="{StaticResource EditOperandCmd}"/>
|
||||||
|
<MenuItem Command="{StaticResource EditLabelCmd}"/>
|
||||||
<MenuItem Command="{StaticResource EditCommentCmd}" InputGestureText="Ctrl+;"/>
|
<MenuItem Command="{StaticResource EditCommentCmd}" InputGestureText="Ctrl+;"/>
|
||||||
<MenuItem Command="{StaticResource EditLongCommentCmd}"/>
|
<MenuItem Command="{StaticResource EditLongCommentCmd}"/>
|
||||||
|
<MenuItem Command="{StaticResource EditAddressCmd}"/>
|
||||||
|
<MenuItem Command="{StaticResource EditStatusFlagsCmd}"/>
|
||||||
<MenuItem Command="{StaticResource EditDataBankCmd}"/>
|
<MenuItem Command="{StaticResource EditDataBankCmd}"/>
|
||||||
<MenuItem Command="{StaticResource EditNoteCmd}"/>
|
<MenuItem Command="{StaticResource EditNoteCmd}"/>
|
||||||
<MenuItem Command="{StaticResource EditProjectSymbolCmd}"/>
|
<MenuItem Command="{StaticResource EditProjectSymbolCmd}"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user