mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-28 16:31:17 +00:00
Correct handling of no-op .ORG statements
These were being overlooked because they didn't actually cause anything to happen (a no-op .ORG sets the address to what it would already have been). The assembly source generator works in a way that causes them to be skipped, so everybody was happy. This seemed like the sort of thing that was likely to cause problems down the road, however, so we now split regions correctly when a no-op .ORG is encountered. This affects the uncategorized data analyzer and selection grouping. This changed the behavior of the 2004-numeric-types test, which was visibly weird in the UI but generated correct output. Added the 2024-ui-edge-cases test to provide a place to exercise edge cases when testing the UI by hand. It has some value for the automated regression test, so it's included there. Also, changed the AddressMapEntry objects to be immutable. This is handy when passing lists of them around.
This commit is contained in:
parent
07d477fc70
commit
0bbb307d4e
@ -24,13 +24,13 @@ namespace CommonUtil {
|
|||||||
/// multiple ORG directives.
|
/// multiple ORG directives.
|
||||||
///
|
///
|
||||||
/// It's possible to generate code that would overlap once relocated at run time,
|
/// It's possible to generate code that would overlap once relocated at run time,
|
||||||
/// which means a given address could map to multiple offsets. For this reason
|
/// which means a given address can map to multiple offsets (overlays, bank-switched
|
||||||
/// it's useful to know the offset of the referring code when evaluating a
|
/// RAM, etc). For this reason it's useful to know the offset of the referring code
|
||||||
/// reference, so that a "local" match can take priority.
|
/// when evaluating a reference, so that "local" matches take priority.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This was part of the main SourceGen application, but I want to share it with
|
/// This was part of the main SourceGen application, but I want to share it with
|
||||||
/// script extensions.
|
/// the extension script mechanism.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class AddressMap : IEnumerable<AddressMap.AddressMapEntry> {
|
public class AddressMap : IEnumerable<AddressMap.AddressMapEntry> {
|
||||||
public const int NO_ENTRY_ADDR = -1; // address value indicating no entry
|
public const int NO_ENTRY_ADDR = -1; // address value indicating no entry
|
||||||
@ -44,31 +44,19 @@ namespace CommonUtil {
|
|||||||
/// entry in the list. It's convenient to maintain it explicitly however, as
|
/// entry in the list. It's convenient to maintain it explicitly however, as
|
||||||
/// the list is read far more often than it is updated.
|
/// the list is read far more often than it is updated.
|
||||||
///
|
///
|
||||||
/// Entries are mutable, but must only be altered by AddressMap. Don't retain
|
/// Instances are immutable.
|
||||||
/// instances of this across other activity.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// TODO: make this immutable. That should allow us to eliminate the copy constructor,
|
|
||||||
/// since we won't need to make copies of things.
|
|
||||||
/// </remarks>
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class AddressMapEntry {
|
public class AddressMapEntry {
|
||||||
public int Offset { get; set; }
|
public int Offset { get; private set; }
|
||||||
public int Addr { get; set; }
|
public int Addr { get; private set; }
|
||||||
public int Length { get; set; }
|
public int Length { get; private set; }
|
||||||
|
|
||||||
public AddressMapEntry(int offset, int addr, int len) {
|
public AddressMapEntry(int offset, int addr, int len) {
|
||||||
Offset = offset;
|
Offset = offset;
|
||||||
Addr = addr;
|
Addr = addr;
|
||||||
Length = len;
|
Length = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy constructor.
|
|
||||||
public AddressMapEntry(AddressMapEntry src) {
|
|
||||||
Offset = src.Offset;
|
|
||||||
Addr = src.Addr;
|
|
||||||
Length = src.Length;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -99,7 +87,7 @@ namespace CommonUtil {
|
|||||||
public AddressMap(List<AddressMapEntry> entries) {
|
public AddressMap(List<AddressMapEntry> entries) {
|
||||||
mTotalLength = entries[entries.Count - 1].Offset + entries[entries.Count - 1].Length;
|
mTotalLength = entries[entries.Count - 1].Offset + entries[entries.Count - 1].Length;
|
||||||
foreach (AddressMapEntry ent in entries) {
|
foreach (AddressMapEntry ent in entries) {
|
||||||
mAddrList.Add(new AddressMapEntry(ent));
|
mAddrList.Add(ent);
|
||||||
}
|
}
|
||||||
DebugValidate();
|
DebugValidate();
|
||||||
}
|
}
|
||||||
@ -111,7 +99,7 @@ namespace CommonUtil {
|
|||||||
public List<AddressMapEntry> GetEntryList() {
|
public List<AddressMapEntry> GetEntryList() {
|
||||||
List<AddressMapEntry> newList = new List<AddressMapEntry>(mAddrList.Count);
|
List<AddressMapEntry> newList = new List<AddressMapEntry>(mAddrList.Count);
|
||||||
foreach (AddressMapEntry ent in mAddrList) {
|
foreach (AddressMapEntry ent in mAddrList) {
|
||||||
newList.Add(new AddressMapEntry(ent));
|
newList.Add(ent);
|
||||||
}
|
}
|
||||||
return newList;
|
return newList;
|
||||||
}
|
}
|
||||||
@ -186,8 +174,7 @@ namespace CommonUtil {
|
|||||||
AddressMapEntry ad = mAddrList[i];
|
AddressMapEntry ad = mAddrList[i];
|
||||||
if (ad.Offset == offset) {
|
if (ad.Offset == offset) {
|
||||||
// update existing
|
// update existing
|
||||||
ad.Addr = addr;
|
mAddrList[i] = new AddressMapEntry(ad.Offset, addr, ad.Length);
|
||||||
mAddrList[i] = ad;
|
|
||||||
return;
|
return;
|
||||||
} else if (ad.Offset > offset) {
|
} else if (ad.Offset > offset) {
|
||||||
// The i'th entry is one past the interesting part.
|
// The i'th entry is one past the interesting part.
|
||||||
@ -199,8 +186,7 @@ namespace CommonUtil {
|
|||||||
AddressMapEntry prev = mAddrList[i - 1];
|
AddressMapEntry prev = mAddrList[i - 1];
|
||||||
int prevOldLen = prev.Length;
|
int prevOldLen = prev.Length;
|
||||||
int prevNewLen = offset - prev.Offset;
|
int prevNewLen = offset - prev.Offset;
|
||||||
prev.Length = prevNewLen;
|
mAddrList[i - 1] = new AddressMapEntry(prev.Offset, prev.Addr, prevNewLen);
|
||||||
mAddrList[i - 1] = prev;
|
|
||||||
|
|
||||||
mAddrList.Insert(i,
|
mAddrList.Insert(i,
|
||||||
new AddressMapEntry(offset, addr, prevOldLen - prevNewLen));
|
new AddressMapEntry(offset, addr, prevOldLen - prevNewLen));
|
||||||
@ -223,8 +209,8 @@ namespace CommonUtil {
|
|||||||
if (mAddrList[i].Offset == offset) {
|
if (mAddrList[i].Offset == offset) {
|
||||||
// Add the length to the previous entry.
|
// Add the length to the previous entry.
|
||||||
AddressMapEntry prev = mAddrList[i - 1];
|
AddressMapEntry prev = mAddrList[i - 1];
|
||||||
prev.Length += mAddrList[i].Length;
|
mAddrList[i - 1] = new AddressMapEntry(prev.Offset, prev.Addr,
|
||||||
mAddrList[i - 1] = prev;
|
prev.Length + mAddrList[i].Length);
|
||||||
|
|
||||||
mAddrList.RemoveAt(i);
|
mAddrList.RemoveAt(i);
|
||||||
DebugValidate();
|
DebugValidate();
|
||||||
@ -297,13 +283,14 @@ namespace CommonUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks to see if the specified range of offsets is in a contiguous range of
|
/// Checks to see if the specified range of offsets is in a single address range. Use
|
||||||
/// addresses. Use this to see if something crosses an address-change boundary.
|
/// this to see if something crosses an address-change boundary. This does not
|
||||||
|
/// handle no-op address changes specially.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="offset">Start offset.</param>
|
/// <param name="offset">Start offset.</param>
|
||||||
/// <param name="length">Length of region.</param>
|
/// <param name="length">Length of region.</param>
|
||||||
/// <returns>True if the data area is unbroken.</returns>
|
/// <returns>True if the data area is unbroken.</returns>
|
||||||
public bool IsContiguous(int offset, int length) {
|
public bool IsSingleAddrRange(int offset, int length) {
|
||||||
Debug.Assert(offset >= 0 && offset < mTotalLength);
|
Debug.Assert(offset >= 0 && offset < mTotalLength);
|
||||||
Debug.Assert(length > 0 && offset + length <= mTotalLength);
|
Debug.Assert(length > 0 && offset + length <= mTotalLength);
|
||||||
return (IndexForOffset(offset) == IndexForOffset(offset + length - 1));
|
return (IndexForOffset(offset) == IndexForOffset(offset + length - 1));
|
||||||
|
@ -1044,7 +1044,7 @@ namespace SourceGen {
|
|||||||
" label='" + label + "'; file length is" + mFileData.Length);
|
" label='" + label + "'; file length is" + mFileData.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mAddrMap.IsContiguous(offset, length)) {
|
if (!mAddrMap.IsSingleAddrRange(offset, length)) {
|
||||||
LogW(offset, "SIDF: format crosses address map boundary (len=" + length + ")");
|
LogW(offset, "SIDF: format crosses address map boundary (len=" + length + ")");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -533,8 +533,8 @@ namespace SourceGen {
|
|||||||
int startOffset = -1;
|
int startOffset = -1;
|
||||||
for (int offset = 0; offset < mAnattribs.Length; ) {
|
for (int offset = 0; offset < mAnattribs.Length; ) {
|
||||||
// We want to find a contiguous series of offsets which are not known
|
// We want to find a contiguous series of offsets which are not known
|
||||||
// to hold code or data. We stop if we encounter a user-defined label
|
// to hold code or data. We stop if we encounter a user-defined label,
|
||||||
// or format descriptor.
|
// format descriptor, or address override.
|
||||||
Anattrib attr = mAnattribs[offset];
|
Anattrib attr = mAnattribs[offset];
|
||||||
|
|
||||||
if (attr.IsInstruction || attr.IsInlineData || attr.IsDataStart) {
|
if (attr.IsInstruction || attr.IsInlineData || attr.IsDataStart) {
|
||||||
@ -572,19 +572,17 @@ namespace SourceGen {
|
|||||||
}
|
}
|
||||||
offset++;
|
offset++;
|
||||||
|
|
||||||
// Check to see if the address has changed from the previous entry.
|
// Check to see if we just crossed an address change.
|
||||||
// TODO(BUG): this test is insufficient -- they might have a .ORG that
|
|
||||||
// doesn't change the address. It's currently harmless because the
|
|
||||||
// .ORG is a no-op and gets swallowed up by the asm generator, but it
|
|
||||||
// looks wrong and could break things.
|
|
||||||
if (offset < mAnattribs.Length &&
|
if (offset < mAnattribs.Length &&
|
||||||
mAnattribs[offset-1].Address + 1 != mAnattribs[offset].Address) {
|
!mProject.AddrMap.IsSingleAddrRange(offset - 1, 2)) {
|
||||||
// Must be an ORG here. Scan previous region.
|
// Must be an ORG here. End region and scan.
|
||||||
AnalyzeRange(startOffset, offset - 1);
|
AnalyzeRange(startOffset, offset - 1);
|
||||||
startOffset = -1;
|
startOffset = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do the last bit.
|
||||||
if (startOffset >= 0) {
|
if (startOffset >= 0) {
|
||||||
AnalyzeRange(startOffset, mAnattribs.Length - 1);
|
AnalyzeRange(startOffset, mAnattribs.Length - 1);
|
||||||
}
|
}
|
||||||
|
@ -969,7 +969,7 @@ namespace SourceGen {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AddrMap.IsContiguous(offset, dfd.Length)) {
|
if (!AddrMap.IsSingleAddrRange(offset, dfd.Length)) {
|
||||||
string msg = "descriptor straddles address change; len=" + dfd.Length;
|
string msg = "descriptor straddles address change; len=" + dfd.Length;
|
||||||
genLog.LogE("+" + offset.ToString("x6") + ": " + msg);
|
genLog.LogE("+" + offset.ToString("x6") + ": " + msg);
|
||||||
Messages.Add(new MessageList.MessageEntry(
|
Messages.Add(new MessageList.MessageEntry(
|
||||||
|
@ -2479,7 +2479,7 @@ namespace SourceGen {
|
|||||||
// This must match what GroupedOffsetSetFromSelected() does.
|
// This must match what GroupedOffsetSetFromSelected() does.
|
||||||
if (!mProject.UserLabels.ContainsKey(nextOffset) &&
|
if (!mProject.UserLabels.ContainsKey(nextOffset) &&
|
||||||
!mProject.HasCommentNoteOrVis(nextOffset) &&
|
!mProject.HasCommentNoteOrVis(nextOffset) &&
|
||||||
thisAttr.Address == nextAttr.Address - 1) {
|
mProject.AddrMap.IsSingleAddrRange(nextOffset - 1, 2)) {
|
||||||
// Good to go.
|
// Good to go.
|
||||||
Debug.WriteLine("Grabbing second byte from +" + nextOffset.ToString("x6"));
|
Debug.WriteLine("Grabbing second byte from +" + nextOffset.ToString("x6"));
|
||||||
trs.Add(nextOffset, rng.Type);
|
trs.Add(nextOffset, rng.Type);
|
||||||
@ -3362,6 +3362,9 @@ namespace SourceGen {
|
|||||||
/// or a string. It should not be possible to select part of a formatted section,
|
/// or a string. It should not be possible to select part of a formatted section,
|
||||||
/// unless the user has been playing weird games with type hints to get overlapping
|
/// unless the user has been playing weird games with type hints to get overlapping
|
||||||
/// format descriptors.
|
/// format descriptors.
|
||||||
|
///
|
||||||
|
/// The type values used in the TypedRangeSet may not be contiguous. They're only
|
||||||
|
/// there to create group separation from otherwise contiguous address ranges.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns>TypedRangeSet with all offsets.</returns>
|
/// <returns>TypedRangeSet with all offsets.</returns>
|
||||||
private TypedRangeSet GroupedOffsetSetFromSelected() {
|
private TypedRangeSet GroupedOffsetSetFromSelected() {
|
||||||
@ -3394,12 +3397,18 @@ namespace SourceGen {
|
|||||||
if (attr.Address != expectedAddr) {
|
if (attr.Address != expectedAddr) {
|
||||||
// For a contiguous selection, this should only happen if there's a .ORG
|
// For a contiguous selection, this should only happen if there's a .ORG
|
||||||
// address change. For non-contiguous selection this is expected. In the
|
// address change. For non-contiguous selection this is expected. In the
|
||||||
// latter case, incrementing the group number is unnecessary but harmless.
|
// latter case, incrementing the group number is unnecessary but harmless
|
||||||
Debug.WriteLine("Address break: " + attr.Address + " vs. " + expectedAddr);
|
// (the TypedRangeSet splits at the gap).
|
||||||
//Debug.Assert(mProject.AddrMap.Get(offset) >= 0);
|
//Debug.WriteLine("Address break: $" + attr.Address.ToString("x4") + " vs. $"
|
||||||
|
// + expectedAddr.ToString("x4"));
|
||||||
expectedAddr = attr.Address;
|
expectedAddr = attr.Address;
|
||||||
groupNum++;
|
groupNum++;
|
||||||
|
} else if (offset > 0 && !mProject.AddrMap.IsSingleAddrRange(offset - 1, 2)) {
|
||||||
|
// Was the previous byte in a different address range? This is only
|
||||||
|
// strictly necessary if the previous byte was in the selection set (which
|
||||||
|
// it won't be if the selection starts at the beginning of an address
|
||||||
|
// range), but bumping the group number is harmless if it wasn't.
|
||||||
|
groupNum++;
|
||||||
} else if (mProject.UserLabels.ContainsKey(offset)) {
|
} else if (mProject.UserLabels.ContainsKey(offset)) {
|
||||||
//if (mProject.GetAnattrib(offset).Symbol != null) {
|
//if (mProject.GetAnattrib(offset).Symbol != null) {
|
||||||
// We consider auto labels when splitting regions for the data analysis,
|
// We consider auto labels when splitting regions for the data analysis,
|
||||||
|
@ -1,89 +1,248 @@
|
|||||||
### 6502bench SourceGen dis65 v1.0 ###
|
### 6502bench SourceGen dis65 v1.0 ###
|
||||||
{
|
{
|
||||||
"_ContentVersion":3,"FileDataLength":1200,"FileDataCrc32":1114187983,"ProjectProps":{
|
"_ContentVersion":3,
|
||||||
"CpuName":"6502","IncludeUndocumentedInstr":false,"TwoByteBrk":false,"EntryFlags":32702671,"AutoLabelStyle":"Simple","AnalysisParams":{
|
"FileDataLength":1200,
|
||||||
"AnalyzeUncategorizedData":true,"DefaultTextScanMode":"LowHighAscii","MinCharsForString":4,"SeekNearbyTargets":true,"SmartPlpHandling":true},
|
"FileDataCrc32":1114187983,
|
||||||
"PlatformSymbolFileIdentifiers":[],"ExtensionScriptFileIdentifiers":["PROJ:2004-numeric-types.cs"],"ProjectSyms":{
|
"ProjectProps":{
|
||||||
|
"CpuName":"6502",
|
||||||
|
"IncludeUndocumentedInstr":false,
|
||||||
|
"TwoByteBrk":false,
|
||||||
|
"EntryFlags":32702671,
|
||||||
|
"AutoLabelStyle":"Simple",
|
||||||
|
"AnalysisParams":{
|
||||||
|
"AnalyzeUncategorizedData":true,
|
||||||
|
"DefaultTextScanMode":"LowHighAscii",
|
||||||
|
"MinCharsForString":4,
|
||||||
|
"SeekNearbyTargets":true,
|
||||||
|
"SmartPlpHandling":true},
|
||||||
|
|
||||||
|
"PlatformSymbolFileIdentifiers":[],
|
||||||
|
"ExtensionScriptFileIdentifiers":["PROJ:2004-numeric-types.cs"],
|
||||||
|
"ProjectSyms":{
|
||||||
}},
|
}},
|
||||||
|
|
||||||
"AddressMap":[{
|
"AddressMap":[{
|
||||||
"Offset":0,"Addr":4096},
|
"Offset":0,
|
||||||
|
"Addr":4096},
|
||||||
|
|
||||||
{
|
{
|
||||||
"Offset":1032,"Addr":5128},
|
"Offset":1032,
|
||||||
|
"Addr":5128},
|
||||||
|
|
||||||
{
|
{
|
||||||
"Offset":1048,"Addr":5160}],"TypeHints":[{
|
"Offset":1048,
|
||||||
"Low":0,"High":0,"Hint":"Code"}],"StatusFlagOverrides":{
|
"Addr":5160}],
|
||||||
|
"TypeHints":[{
|
||||||
|
"Low":0,
|
||||||
|
"High":0,
|
||||||
|
"Hint":"Code"}],
|
||||||
|
"StatusFlagOverrides":{
|
||||||
},
|
},
|
||||||
|
|
||||||
"Comments":{
|
"Comments":{
|
||||||
"588":"comment on bulk","882":"incorrect alignment","1128":"end-of-line comment"},
|
"588":"comment on bulk",
|
||||||
|
"882":"incorrect alignment",
|
||||||
|
"1032":"note no-op .ORG",
|
||||||
|
"1048":"meaningful .ORG",
|
||||||
|
"1128":"end-of-line comment"},
|
||||||
|
|
||||||
"LongComments":{
|
"LongComments":{
|
||||||
"-2147483647":{
|
"-2147483647":{
|
||||||
"Text":"Project file was edited to get all big-endian data types, and to have an incorrect .junk alignment directive.","BoxMode":false,"MaxWidth":80,"BackgroundColor":0},
|
"Text":"Project file was edited to get all big-endian data types, and to have an incorrect .junk alignment directive.",
|
||||||
|
"BoxMode":false,
|
||||||
|
"MaxWidth":80,
|
||||||
|
"BackgroundColor":0},
|
||||||
|
|
||||||
"1112":{
|
"1112":{
|
||||||
"Text":"long comment\r\n","BoxMode":false,"MaxWidth":80,"BackgroundColor":0}},
|
"Text":"long comment\r\n",
|
||||||
|
"BoxMode":false,
|
||||||
|
"MaxWidth":80,
|
||||||
|
"BackgroundColor":0}},
|
||||||
|
|
||||||
"Notes":{
|
"Notes":{
|
||||||
"1144":{
|
"1144":{
|
||||||
"Text":":ETON","BoxMode":false,"MaxWidth":80,"BackgroundColor":0}},
|
"Text":":ETON",
|
||||||
|
"BoxMode":false,
|
||||||
|
"MaxWidth":80,
|
||||||
|
"BackgroundColor":0}},
|
||||||
|
|
||||||
"UserLabels":{
|
"UserLabels":{
|
||||||
"588":{
|
"588":{
|
||||||
"Label":"LABEL","Value":4684,"Source":"User","Type":"GlobalAddr","LabelAnno":"None"},
|
"Label":"LABEL",
|
||||||
|
"Value":4684,
|
||||||
|
"Source":"User",
|
||||||
|
"Type":"GlobalAddr",
|
||||||
|
"LabelAnno":"None"},
|
||||||
|
|
||||||
"1064":{
|
"1064":{
|
||||||
"Label":"UserLabel","Value":5176,"Source":"User","Type":"GlobalAddr","LabelAnno":"None"}},
|
"Label":"UserLabel",
|
||||||
|
"Value":5176,
|
||||||
|
"Source":"User",
|
||||||
|
"Type":"GlobalAddr",
|
||||||
|
"LabelAnno":"None"}},
|
||||||
|
|
||||||
"OperandFormats":{
|
"OperandFormats":{
|
||||||
"23":{
|
"23":{
|
||||||
"Length":1,"Format":"NumericLE","SubFormat":"Hex","SymbolRef":null},
|
"Length":1,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"24":{
|
"24":{
|
||||||
"Length":2,"Format":"NumericLE","SubFormat":"Hex","SymbolRef":null},
|
"Length":2,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"26":{
|
"26":{
|
||||||
"Length":3,"Format":"NumericLE","SubFormat":"Hex","SymbolRef":null},
|
"Length":3,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"29":{
|
"29":{
|
||||||
"Length":4,"Format":"NumericLE","SubFormat":"Hex","SymbolRef":null},
|
"Length":4,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"33":{
|
"33":{
|
||||||
"Length":1,"Format":"NumericBE","SubFormat":"Hex","SymbolRef":null},
|
"Length":1,
|
||||||
|
"Format":"NumericBE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"34":{
|
"34":{
|
||||||
"Length":2,"Format":"NumericBE","SubFormat":"Hex","SymbolRef":null},
|
"Length":2,
|
||||||
|
"Format":"NumericBE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"36":{
|
"36":{
|
||||||
"Length":3,"Format":"NumericBE","SubFormat":"Hex","SymbolRef":null},
|
"Length":3,
|
||||||
|
"Format":"NumericBE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"39":{
|
"39":{
|
||||||
"Length":4,"Format":"NumericBE","SubFormat":"Hex","SymbolRef":null},
|
"Length":4,
|
||||||
|
"Format":"NumericBE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"43":{
|
"43":{
|
||||||
"Length":2,"Format":"Fill","SubFormat":"None","SymbolRef":null},
|
"Length":2,
|
||||||
|
"Format":"Fill",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"46":{
|
"46":{
|
||||||
"Length":3,"Format":"Fill","SubFormat":"None","SymbolRef":null},
|
"Length":3,
|
||||||
|
"Format":"Fill",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"50":{
|
"50":{
|
||||||
"Length":4,"Format":"Fill","SubFormat":"None","SymbolRef":null},
|
"Length":4,
|
||||||
|
"Format":"Fill",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"55":{
|
"55":{
|
||||||
"Length":5,"Format":"Fill","SubFormat":"None","SymbolRef":null},
|
"Length":5,
|
||||||
|
"Format":"Fill",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"61":{
|
"61":{
|
||||||
"Length":256,"Format":"Fill","SubFormat":"None","SymbolRef":null},
|
"Length":256,
|
||||||
|
"Format":"Fill",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"318":{
|
"318":{
|
||||||
"Length":257,"Format":"Fill","SubFormat":"None","SymbolRef":null},
|
"Length":257,
|
||||||
|
"Format":"Fill",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"575":{
|
"575":{
|
||||||
"Length":1,"Format":"Dense","SubFormat":"None","SymbolRef":null},
|
"Length":1,
|
||||||
|
"Format":"Dense",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"577":{
|
"577":{
|
||||||
"Length":10,"Format":"Dense","SubFormat":"None","SymbolRef":null},
|
"Length":10,
|
||||||
|
"Format":"Dense",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"588":{
|
"588":{
|
||||||
"Length":64,"Format":"Dense","SubFormat":"None","SymbolRef":null},
|
"Length":64,
|
||||||
|
"Format":"Dense",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"653":{
|
"653":{
|
||||||
"Length":115,"Format":"Junk","SubFormat":"Align256","SymbolRef":null},
|
"Length":115,
|
||||||
|
"Format":"Junk",
|
||||||
|
"SubFormat":"Align256",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"769":{
|
"769":{
|
||||||
"Length":63,"Format":"Junk","SubFormat":"Align64","SymbolRef":null},
|
"Length":63,
|
||||||
|
"Format":"Junk",
|
||||||
|
"SubFormat":"Align64",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"833":{
|
"833":{
|
||||||
"Length":31,"Format":"Junk","SubFormat":"Align32","SymbolRef":null},
|
"Length":31,
|
||||||
|
"Format":"Junk",
|
||||||
|
"SubFormat":"Align32",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"864":{
|
"864":{
|
||||||
"Length":8,"Format":"Junk","SubFormat":"None","SymbolRef":null},
|
"Length":8,
|
||||||
|
"Format":"Junk",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"873":{
|
"873":{
|
||||||
"Length":8,"Format":"Junk","SubFormat":"None","SymbolRef":null},
|
"Length":8,
|
||||||
|
"Format":"Junk",
|
||||||
|
"SubFormat":"None",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"882":{
|
"882":{
|
||||||
"Length":2,"Format":"Junk","SubFormat":"Align128","SymbolRef":null},
|
"Length":2,
|
||||||
|
"Format":"Junk",
|
||||||
|
"SubFormat":"Align128",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"884":{
|
"884":{
|
||||||
"Length":140,"Format":"Junk","SubFormat":"Align256","SymbolRef":null},
|
"Length":140,
|
||||||
|
"Format":"Junk",
|
||||||
|
"SubFormat":"Align256",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
"1192":{
|
"1192":{
|
||||||
"Length":1,"Format":"NumericLE","SubFormat":"Binary","SymbolRef":null}},
|
"Length":1,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Binary",
|
||||||
|
"SymbolRef":null}},
|
||||||
|
|
||||||
"LvTables":{
|
"LvTables":{
|
||||||
"1096":{
|
"1096":{
|
||||||
"Variables":[],"ClearPrevious":true}},
|
"Variables":[],
|
||||||
|
"ClearPrevious":true}},
|
||||||
|
|
||||||
"Visualizations":[{
|
"Visualizations":[{
|
||||||
"Tag":"vis000488","VisGenIdent":"dummy","VisGenParams":{
|
"Tag":"vis000488",
|
||||||
}}],"VisualizationAnimations":[],"VisualizationSets":{
|
"VisGenIdent":"dummy",
|
||||||
|
"VisGenParams":{
|
||||||
|
}}],
|
||||||
|
"VisualizationAnimations":[],
|
||||||
|
"VisualizationSets":{
|
||||||
"1160":{
|
"1160":{
|
||||||
"Tags":["vis000488"]}}}
|
"Tags":["vis000488"]}}}
|
||||||
|
BIN
SourceGen/SGTestData/2024-ui-edge-cases
Normal file
BIN
SourceGen/SGTestData/2024-ui-edge-cases
Normal file
Binary file not shown.
71
SourceGen/SGTestData/2024-ui-edge-cases.dis65
Normal file
71
SourceGen/SGTestData/2024-ui-edge-cases.dis65
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
### 6502bench SourceGen dis65 v1.0 ###
|
||||||
|
{
|
||||||
|
"_ContentVersion":3,
|
||||||
|
"FileDataLength":50,
|
||||||
|
"FileDataCrc32":-1443914879,
|
||||||
|
"ProjectProps":{
|
||||||
|
"CpuName":"6502",
|
||||||
|
"IncludeUndocumentedInstr":false,
|
||||||
|
"TwoByteBrk":false,
|
||||||
|
"EntryFlags":32702671,
|
||||||
|
"AutoLabelStyle":"Simple",
|
||||||
|
"AnalysisParams":{
|
||||||
|
"AnalyzeUncategorizedData":true,
|
||||||
|
"DefaultTextScanMode":"LowHighAscii",
|
||||||
|
"MinCharsForString":4,
|
||||||
|
"SeekNearbyTargets":true,
|
||||||
|
"SmartPlpHandling":true},
|
||||||
|
|
||||||
|
"PlatformSymbolFileIdentifiers":["RT:Apple/F8-ROM.sym65",
|
||||||
|
"RT:Apple/Cxxx-IO.sym65",
|
||||||
|
"RT:Apple/DOS33.sym65"],
|
||||||
|
"ExtensionScriptFileIdentifiers":["RT:Apple/VisHiRes.cs"],
|
||||||
|
"ProjectSyms":{
|
||||||
|
}},
|
||||||
|
|
||||||
|
"AddressMap":[{
|
||||||
|
"Offset":0,
|
||||||
|
"Addr":8192},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":10,
|
||||||
|
"Addr":8202},
|
||||||
|
|
||||||
|
{
|
||||||
|
"Offset":16,
|
||||||
|
"Addr":8448}],
|
||||||
|
"TypeHints":[{
|
||||||
|
"Low":0,
|
||||||
|
"High":0,
|
||||||
|
"Hint":"Code"}],
|
||||||
|
"StatusFlagOverrides":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Comments":{
|
||||||
|
"3":"string should be split by no-op addr change",
|
||||||
|
"18":"edit this operand"},
|
||||||
|
|
||||||
|
"LongComments":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Notes":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"UserLabels":{
|
||||||
|
"44":{
|
||||||
|
"Label":"addr1",
|
||||||
|
"Value":8476,
|
||||||
|
"Source":"User",
|
||||||
|
"Type":"GlobalAddr",
|
||||||
|
"LabelAnno":"None"}},
|
||||||
|
|
||||||
|
"OperandFormats":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"LvTables":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Visualizations":[],
|
||||||
|
"VisualizationAnimations":[],
|
||||||
|
"VisualizationSets":{
|
||||||
|
}}
|
@ -63,10 +63,13 @@ LABEL .byte $00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff
|
|||||||
.byte $81
|
.byte $81
|
||||||
.fill 2,$dd ;incorrect alignment
|
.fill 2,$dd ;incorrect alignment
|
||||||
.align 256,$00
|
.align 256,$00
|
||||||
.fill 16,$82
|
.fill 8,$82
|
||||||
|
.logical $1408
|
||||||
|
.fill 8,$82 ;note no-op .ORG
|
||||||
.fill 8,$83
|
.fill 8,$83
|
||||||
|
.here
|
||||||
.logical $1428
|
.logical $1428
|
||||||
.fill 8,$83
|
.fill 8,$83 ;meaningful .ORG
|
||||||
.fill 8,$84
|
.fill 8,$84
|
||||||
UserLabel .fill 8,$84
|
UserLabel .fill 8,$84
|
||||||
.fill 8,$85
|
.fill 8,$85
|
||||||
|
@ -58,10 +58,12 @@ LABEL hex 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff
|
|||||||
dfb $81
|
dfb $81
|
||||||
ds 2,$dd ;incorrect alignment
|
ds 2,$dd ;incorrect alignment
|
||||||
ds \
|
ds \
|
||||||
ds 16,$82
|
ds 8,$82
|
||||||
|
org $1408
|
||||||
|
ds 8,$82 ;note no-op .ORG
|
||||||
ds 8,$83
|
ds 8,$83
|
||||||
org $1428
|
org $1428
|
||||||
ds 8,$83
|
ds 8,$83 ;meaningful .ORG
|
||||||
ds 8,$84
|
ds 8,$84
|
||||||
UserLabel ds 8,$84
|
UserLabel ds 8,$84
|
||||||
ds 8,$85
|
ds 8,$85
|
||||||
|
@ -59,10 +59,13 @@ LABEL !hex 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff
|
|||||||
!byte $81
|
!byte $81
|
||||||
!fill 2,$dd ;incorrect alignment
|
!fill 2,$dd ;incorrect alignment
|
||||||
!align 255,0,$00
|
!align 255,0,$00
|
||||||
!fill 16,$82
|
!fill 8,$82
|
||||||
|
!pseudopc $1408 {
|
||||||
|
!fill 8,$82 ;note no-op .ORG
|
||||||
!fill 8,$83
|
!fill 8,$83
|
||||||
|
} ;!pseudopc
|
||||||
!pseudopc $1428 {
|
!pseudopc $1428 {
|
||||||
!fill 8,$83
|
!fill 8,$83 ;meaningful .ORG
|
||||||
!fill 8,$84
|
!fill 8,$84
|
||||||
UserLabel !fill 8,$84
|
UserLabel !fill 8,$84
|
||||||
!fill 8,$85
|
!fill 8,$85
|
||||||
|
@ -62,11 +62,14 @@ LABEL: .byte $00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff
|
|||||||
.byte $81
|
.byte $81
|
||||||
.res 2,$dd ;incorrect alignment
|
.res 2,$dd ;incorrect alignment
|
||||||
.res 140,$00
|
.res 140,$00
|
||||||
.res 16,$82
|
.res 8,$82
|
||||||
|
; .segment "SEG001"
|
||||||
|
.org $1408
|
||||||
|
.res 8,$82 ;note no-op .ORG
|
||||||
.res 8,$83
|
.res 8,$83
|
||||||
; .segment "SEG002"
|
; .segment "SEG002"
|
||||||
.org $1428
|
.org $1428
|
||||||
.res 8,$83
|
.res 8,$83 ;meaningful .ORG
|
||||||
.res 8,$84
|
.res 8,$84
|
||||||
UserLabel: .res 8,$84
|
UserLabel: .res 8,$84
|
||||||
.res 8,$85
|
.res 8,$85
|
||||||
|
25
SourceGen/SGTestData/Expected/2024-ui-edge-cases_64tass.S
Normal file
25
SourceGen/SGTestData/Expected/2024-ui-edge-cases_64tass.S
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
.cpu "6502"
|
||||||
|
.enc sg_ascii
|
||||||
|
.cdef $20,$7e,$20
|
||||||
|
* = $2000
|
||||||
|
jmp L2100
|
||||||
|
|
||||||
|
.text "hello, " ;string should be split by no-op addr change
|
||||||
|
.logical $200a
|
||||||
|
.text "world"
|
||||||
|
.byte $80
|
||||||
|
|
||||||
|
.here
|
||||||
|
.logical $2100
|
||||||
|
L2100 lda #$00
|
||||||
|
sta addr1-1 ;edit this operand
|
||||||
|
sta addr1
|
||||||
|
sta addr1+1
|
||||||
|
jmp L2121
|
||||||
|
|
||||||
|
.text "testing stuff."
|
||||||
|
addr1 .text "!?---"
|
||||||
|
|
||||||
|
L2121 rts
|
||||||
|
|
||||||
|
.here
|
20
SourceGen/SGTestData/Expected/2024-ui-edge-cases_Merlin32.S
Normal file
20
SourceGen/SGTestData/Expected/2024-ui-edge-cases_Merlin32.S
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
org $2000
|
||||||
|
jmp L2100
|
||||||
|
|
||||||
|
asc 'hello, ' ;string should be split by no-op addr change
|
||||||
|
org $200a
|
||||||
|
asc 'world'
|
||||||
|
dfb $80
|
||||||
|
|
||||||
|
org $2100
|
||||||
|
L2100 lda #$00
|
||||||
|
sta addr1-1 ;edit this operand
|
||||||
|
sta addr1
|
||||||
|
sta addr1+1
|
||||||
|
jmp L2121
|
||||||
|
|
||||||
|
asc 'testing stuff.'
|
||||||
|
addr1 asc '!?---'
|
||||||
|
|
||||||
|
L2121 rts
|
||||||
|
|
23
SourceGen/SGTestData/Expected/2024-ui-edge-cases_acme.S
Normal file
23
SourceGen/SGTestData/Expected/2024-ui-edge-cases_acme.S
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
!cpu 6502
|
||||||
|
* = $2000
|
||||||
|
jmp L2100
|
||||||
|
|
||||||
|
!text "hello, " ;string should be split by no-op addr change
|
||||||
|
!pseudopc $200a {
|
||||||
|
!text "world"
|
||||||
|
!byte $80
|
||||||
|
|
||||||
|
} ;!pseudopc
|
||||||
|
!pseudopc $2100 {
|
||||||
|
L2100 lda #$00
|
||||||
|
sta addr1-1 ;edit this operand
|
||||||
|
sta addr1
|
||||||
|
sta addr1+1
|
||||||
|
jmp L2121
|
||||||
|
|
||||||
|
!text "testing stuff."
|
||||||
|
addr1 !text "!?---"
|
||||||
|
|
||||||
|
L2121 rts
|
||||||
|
|
||||||
|
} ;!pseudopc
|
24
SourceGen/SGTestData/Expected/2024-ui-edge-cases_cc65.S
Normal file
24
SourceGen/SGTestData/Expected/2024-ui-edge-cases_cc65.S
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
.setcpu "6502"
|
||||||
|
; .segment "SEG000"
|
||||||
|
.org $2000
|
||||||
|
jmp L2100
|
||||||
|
|
||||||
|
.byte "hello, " ;string should be split by no-op addr change
|
||||||
|
; .segment "SEG001"
|
||||||
|
.org $200a
|
||||||
|
.byte "world"
|
||||||
|
.byte $80
|
||||||
|
|
||||||
|
; .segment "SEG002"
|
||||||
|
.org $2100
|
||||||
|
L2100: lda #$00
|
||||||
|
sta addr1-1 ;edit this operand
|
||||||
|
sta addr1
|
||||||
|
sta addr1+1
|
||||||
|
jmp L2121
|
||||||
|
|
||||||
|
.byte "testing stuff."
|
||||||
|
addr1: .byte "!?---"
|
||||||
|
|
||||||
|
L2121: rts
|
||||||
|
|
15
SourceGen/SGTestData/Expected/2024-ui-edge-cases_cc65.cfg
Normal file
15
SourceGen/SGTestData/Expected/2024-ui-edge-cases_cc65.cfg
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# 6502bench SourceGen generated linker script for 2024-ui-edge-cases
|
||||||
|
MEMORY {
|
||||||
|
MAIN: file=%O, start=%S, size=65536;
|
||||||
|
# MEM000: file=%O, start=$2000, size=10;
|
||||||
|
# MEM001: file=%O, start=$200a, size=6;
|
||||||
|
# MEM002: file=%O, start=$2100, size=34;
|
||||||
|
}
|
||||||
|
SEGMENTS {
|
||||||
|
CODE: load=MAIN, type=rw;
|
||||||
|
# SEG000: load=MEM000, type=rw;
|
||||||
|
# SEG001: load=MEM001, type=rw;
|
||||||
|
# SEG002: load=MEM002, type=rw;
|
||||||
|
}
|
||||||
|
FEATURES {}
|
||||||
|
SYMBOLS {}
|
33
SourceGen/SGTestData/Source/2024-ui-edge-cases.S
Normal file
33
SourceGen/SGTestData/Source/2024-ui-edge-cases.S
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
; Copyright 2020 faddenSoft. All Rights Reserved.
|
||||||
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
|
;
|
||||||
|
; These tests are for exercising UI edge cases. They're not necessarily
|
||||||
|
; meaningful for the generate/assemble regression test.
|
||||||
|
;
|
||||||
|
; Assembler: Merlin 32
|
||||||
|
|
||||||
|
ORG $2000
|
||||||
|
|
||||||
|
jmp skip
|
||||||
|
|
||||||
|
asc 'hello, '
|
||||||
|
ORG $200a ;EDIT: add this no-op ORG statement
|
||||||
|
asc 'world' ;(string finder should split the string)
|
||||||
|
dfb $80
|
||||||
|
|
||||||
|
org $2100 ;EDIT: add this
|
||||||
|
skip
|
||||||
|
lda #$00
|
||||||
|
sta addr0 ;TEST: edit this operand ("addr1-1")
|
||||||
|
sta addr1
|
||||||
|
sta addr2
|
||||||
|
jmp done
|
||||||
|
|
||||||
|
L1 asc 'testing stuff'
|
||||||
|
addr0 asc '.'
|
||||||
|
addr1 asc '!' ;EDIT: place label here
|
||||||
|
addr2 asc '?'
|
||||||
|
asc '---'
|
||||||
|
|
||||||
|
|
||||||
|
done rts
|
Loading…
Reference in New Issue
Block a user