diff --git a/SourceGen/DisasmProject.cs b/SourceGen/DisasmProject.cs
index 9e74dda..fe3069e 100644
--- a/SourceGen/DisasmProject.cs
+++ b/SourceGen/DisasmProject.cs
@@ -1069,6 +1069,8 @@ namespace SourceGen {
for (int offset = 0; offset < mAnattribs.Length; ) {
Anattrib attr = mAnattribs[offset];
+ Symbol sym;
+ int address;
if (attr.IsInstructionStart && attr.DataDescriptor == null &&
attr.OperandAddress >= 0 && attr.OperandOffset < 0) {
// Has an operand address, but not an offset, meaning it's a reference
@@ -1083,29 +1085,56 @@ namespace SourceGen {
// Using the full symbol table is potentially a tad less efficient than
// looking for a match exclusively in project/platform symbols, but it's
// the correct thing to do.
- Symbol sym = SymbolTable.FindAddressByValue(attr.OperandAddress);
+ address = attr.OperandAddress;
+ sym = SymbolTable.FindNonVariableByAddress(address);
+ } else if (attr.IsDataStart && attr.DataDescriptor != null &&
+ attr.DataDescriptor.IsNumeric &&
+ attr.DataDescriptor.FormatSubType == FormatDescriptor.SubType.Address) {
+ // Found a Numeric/Address item that matches. Data items don't have
+ // OperandAddress or OperandOffset set, so we need to check manually to
+ // see if the address falls within the project. In most situations this
+ // isn't really necessary, because the data analysis pass will have resolved
+ // interal references to auto-generated labels.
+ //
+ // This is only firing if the item is explicitly formatted as an
+ // Address, so we're essentially "upgrading" the user format.
+ address = RawData.GetWord(mFileData, offset, attr.DataDescriptor.Length,
+ attr.DataDescriptor.FormatType == FormatDescriptor.Type.NumericBE);
+ if (AddrMap.AddressToOffset(offset, address) < 0) {
+ sym = SymbolTable.FindNonVariableByAddress(address);
+ } else {
+ Debug.WriteLine("Found unhandled internal data addr ref at +" +
+ offset.ToString("x6"));
+ address = -1; // don't touch interior stuff
+ sym = null;
+ }
+ } else {
+ address = -1;
+ sym = null;
+ }
+ if (address >= 0) {
// If we didn't find it, check addr-1. This is very helpful when working
// with pointers, because it gets us references to "PTR+1" when "PTR" is
// defined. (It's potentially helpful in labeling the "near side" of an
// address map split as well, since the first byte past is an external
// address, and a label at the end of the current region will be offset
// from by this.)
- if (sym == null && (attr.OperandAddress & 0xffff) > 0 && checkNearby) {
- sym = SymbolTable.FindAddressByValue(attr.OperandAddress - 1);
+ if (sym == null && (address & 0xffff) > 0 && checkNearby) {
+ sym = SymbolTable.FindNonVariableByAddress(address - 1);
}
// If that didn't work, try addr-2. Good for 24-bit addresses and jump
// vectors that start with a JMP instruction.
- if (sym == null && (attr.OperandAddress & 0xffff) > 1 && checkNearby) {
- sym = SymbolTable.FindAddressByValue(attr.OperandAddress - 2);
+ if (sym == null && (address & 0xffff) > 1 && checkNearby) {
+ sym = SymbolTable.FindNonVariableByAddress(address - 2);
}
// Still nothing, try addr+1. Sometimes indexed addressing will use
// "STA addr-1,y". This will also catch "STA addr-1" when addr is the
// very start of a segment, which means we're actually finding a label
// reference rather than project/platform symbol; only works if the
// location already has a label.
- if (sym == null && (attr.OperandAddress & 0xffff) < 0xffff && checkNearby) {
- sym = SymbolTable.FindAddressByValue(attr.OperandAddress + 1);
+ if (sym == null && (address & 0xffff) < 0xffff && checkNearby) {
+ sym = SymbolTable.FindNonVariableByAddress(address + 1);
if (sym != null && sym.SymbolSource != Symbol.Source.Project &&
sym.SymbolSource != Symbol.Source.Platform) {
Debug.WriteLine("Applying non-platform in GeneratePlatform: " + sym);
@@ -1118,11 +1147,6 @@ namespace SourceGen {
mAnattribs[offset].DataDescriptor =
FormatDescriptor.Create(mAnattribs[offset].Length,
new WeakSymbolRef(sym.Label, WeakSymbolRef.Part.Low), false);
-
- // Used to do this here; now do it in GenerateXrefs() so we can
- // pick up user-edited operand formats that reference project symbols.
- //(sym as DefSymbol).Xrefs.Add(new XrefSet.Xref(offset,
- // XrefSet.XrefType.NameReference, 0));
}
}
diff --git a/SourceGen/RuntimeData/Apple/Applesoft.sym65 b/SourceGen/RuntimeData/Apple/Applesoft.sym65
index 35f7a41..b5cee6a 100644
--- a/SourceGen/RuntimeData/Apple/Applesoft.sym65
+++ b/SourceGen/RuntimeData/Apple/Applesoft.sym65
@@ -6,6 +6,7 @@
*SYNOPSIS Applesoft BASIC addresses and constants
+USRVEC @ $0A ;USR() command vector
HCOLOR1 @ $1C ;hi-res color mask
COUNTH @ $1D ;hi-res high-order byte of step for line
HBASL @ $26 ;base address for hi-res drawing
@@ -23,6 +24,7 @@ CURLIN @ $75 ;Applesoft current line number (2b)
FACMO @ $A0 ;middle-order byte of mantissa of FAC
FACLO @ $A1 ;low-order byte of mantissa of FAC
FACSIGN @ $A2 ;single byte sign of FAC
+PRGEND @ $AF ;pointer to end of program (2b)
CHRGET @ $B1 ;get next character or Applesoft token
CHRGOT @ $B7 ;get next, but don't advance TXTPTR
TXTPTR @ $B8 ;points at next char or token
diff --git a/SourceGen/RuntimeData/Apple/F8-ROM.sym65 b/SourceGen/RuntimeData/Apple/F8-ROM.sym65
index 2c5f2f2..e2e992b 100644
--- a/SourceGen/RuntimeData/Apple/F8-ROM.sym65
+++ b/SourceGen/RuntimeData/Apple/F8-ROM.sym65
@@ -13,7 +13,10 @@ WNDTOP @ $22 ;top of scroll window
WNDBTM @ $23 ;bottom of scsroll window
CH @ $24 ;cursor horizontal displacement
CV @ $25 ;cursor vertical displacement
-GBASL @ $26 ;base address for lo-res drawing
+GBASL @ $26 ;base address for lo-res drawing (lo)
+GBASH @ $27 ;base address for lo-res drawing (hi)
+H2 @ $2C ;right end of horizontal line drawn by HLINE
+V2 @ $2D ;bottom of vertical line drawn by VLINE
INVFLAG @ $32 ;text mask (255=normal, 127=flash, 63=inv)
PROMPT @ $33 ;prompt character
CSWL @ $36 ;character output hook (lo)
@@ -24,12 +27,14 @@ PCL @ $3A ;program counter save
PCH @ $3B ;program counter save
A1L @ $3C ;general purpose
A1H @ $3D ;general purpose
+A2L @ $3E ;general purpose
+A2H @ $3F ;general purpose
-SPDBYT @ $E7 ;text output speed limiter
+SPDBYT @ $F1 ;text output speed limiter
-BRKV @ $03f0 ;address of BRK handler
-SOFTEVEC @ $03f2 ;address of RESET handler
-PWREDUP @ $03f4 ;power-up RESET checksum
+BRKV @ $03F0 ;address of BRK handler
+SOFTEVEC @ $03F2 ;address of RESET handler
+PWREDUP @ $03F4 ;power-up RESET checksum
USRADDR @ $03F8 ;jump to function that handles monitor Ctrl-Y
NMIVEC @ $03FB ;jump to function that handles NMI
IRQADDR @ $03FE ;address of IRQ handler
diff --git a/SourceGen/SGTestData/2019-local-variables.dis65 b/SourceGen/SGTestData/2019-local-variables.dis65
index e7eb92c..ba3f3cd 100644
--- a/SourceGen/SGTestData/2019-local-variables.dis65
+++ b/SourceGen/SGTestData/2019-local-variables.dis65
@@ -2,7 +2,7 @@
{
"_ContentVersion":2,"FileDataLength":137,"FileDataCrc32":708791740,"ProjectProps":{
"CpuName":"65816","IncludeUndocumentedInstr":false,"EntryFlags":32702671,"AutoLabelStyle":"Simple","AnalysisParams":{
-"AnalyzeUncategorizedData":true,"DefaultTextScanMode":"LowHighAscii","MinCharsForString":4,"SeekNearbyTargets":true,"SmartPlpHandling":false},
+"AnalyzeUncategorizedData":true,"DefaultTextScanMode":"LowHighAscii","MinCharsForString":4,"SeekNearbyTargets":false,"SmartPlpHandling":false},
"PlatformSymbolFileIdentifiers":[],"ExtensionScriptFileIdentifiers":[],"ProjectSyms":{
"CONST_ONE":{
"DataDescriptor":{
@@ -31,7 +31,7 @@
"Low":0,"High":0,"Hint":"Code"}],"StatusFlagOverrides":{
},
"Comments":{
-},
+"4":"could be PROJ_ONE+2, but \"nearby\" is off"},
"LongComments":{
"-2147483647":{
"Text":"Edited to have duplicate labels (PROJ_ZERO, DPCODE).","BoxMode":false,"MaxWidth":80,"BackgroundColor":0},
diff --git a/SourceGen/SGTestData/Expected/2019-local-variables_64tass.S b/SourceGen/SGTestData/Expected/2019-local-variables_64tass.S
index 4b9e10e..ae249e5 100644
--- a/SourceGen/SGTestData/Expected/2019-local-variables_64tass.S
+++ b/SourceGen/SGTestData/Expected/2019-local-variables_64tass.S
@@ -9,7 +9,7 @@ CONST_ZERO = $f0 ;project const
.xs
ldy PROJ_ZERO
lda (PROJ_ONE),y
- sta $03
+ sta $03 ;could be PROJ_ONE+2, but "nearby" is off
ldx $04
lda CONST_ZERO,s
sta $f1,s
diff --git a/SourceGen/SGTestData/Expected/2019-local-variables_Merlin32.S b/SourceGen/SGTestData/Expected/2019-local-variables_Merlin32.S
index 1c2e82e..9a21569 100644
--- a/SourceGen/SGTestData/Expected/2019-local-variables_Merlin32.S
+++ b/SourceGen/SGTestData/Expected/2019-local-variables_Merlin32.S
@@ -6,7 +6,7 @@ CONST_ZERO equ $f0 ;project const
org $1000
ldy PROJ_ZERO
lda (PROJ_ONE),y
- sta $03
+ sta $03 ;could be PROJ_ONE+2, but "nearby" is off
ldx $04
lda CONST_ZERO,S
sta $f1,S
diff --git a/SourceGen/SGTestData/Expected/2019-local-variables_acme.S b/SourceGen/SGTestData/Expected/2019-local-variables_acme.S
index f4d88ce..86746b4 100644
--- a/SourceGen/SGTestData/Expected/2019-local-variables_acme.S
+++ b/SourceGen/SGTestData/Expected/2019-local-variables_acme.S
@@ -9,7 +9,7 @@ CONST_ZERO = $f0 ;project const
!rs
ldy PROJ_ZERO
lda (PROJ_ONE),y
- sta $03
+ sta $03 ;could be PROJ_ONE+2, but "nearby" is off
ldx $04
lda CONST_ZERO,S
sta $f1,S
diff --git a/SourceGen/SGTestData/Expected/2019-local-variables_cc65.S b/SourceGen/SGTestData/Expected/2019-local-variables_cc65.S
index 6dc2cb2..92f34eb 100644
--- a/SourceGen/SGTestData/Expected/2019-local-variables_cc65.S
+++ b/SourceGen/SGTestData/Expected/2019-local-variables_cc65.S
@@ -10,7 +10,7 @@ CONST_ZERO = $f0 ;project const
.i8
ldy PROJ_ZERO
lda (PROJ_ONE),y
- sta $03
+ sta $03 ;could be PROJ_ONE+2, but "nearby" is off
ldx $04
lda CONST_ZERO,S
sta $f1,S
diff --git a/SourceGen/SymbolTable.cs b/SourceGen/SymbolTable.cs
index 6ab4c45..a66f8e2 100644
--- a/SourceGen/SymbolTable.cs
+++ b/SourceGen/SymbolTable.cs
@@ -144,11 +144,12 @@ namespace SourceGen {
}
///
- /// Searches the table for symbols with matching address values. Ignores constants.
+ /// Searches the table for symbols with matching address values. Ignores constants and
+ /// variables.
///
/// Value to find.
/// First matching symbol found, or null if nothing matched.
- public Symbol FindAddressByValue(int value) {
+ public Symbol FindNonVariableByAddress(int value) {
// Get sorted list of values. This is documented as efficient.
IList values = mSymbolsByValue.Values;
@@ -169,8 +170,9 @@ namespace SourceGen {
while (mid > 0 && values[mid - 1].Value == value) {
mid--;
}
- // now skip past constants
- while (mid < values.Count && values[mid].SymbolType == Symbol.Type.Constant) {
+ // now skip past constants and variables
+ while (mid < values.Count && (values[mid].SymbolType == Symbol.Type.Constant ||
+ values[mid].SymbolSource == Symbol.Source.Variable)) {
//Debug.WriteLine("disregarding " + values[mid]);
mid++;
}