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++; }