From bd5b556a7fa68c3b3a4038b606ce7f4fa4d07c48 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Fri, 4 Sep 2020 13:26:41 -0700 Subject: [PATCH] Show "ptr" for pointer use in cross-reference list Consider: LDA $00 loads a value from address $00 LDA $00,X might load from $00, or might not LDA ($00),Y dereferences $00 as a 16-bit pointer LDA ($00,X) dereferences a pointer, not necessarily from $00 When perusing the cross-reference list, it's useful to be able to tell whether an instruction is accessing the location, using it as a base address, or deferencing it as a pointer. We now show "ptr" in the list for pointer dereferences. (We already showed "idx" for indexed accesses.) --- Asm65/OpDef.cs | 17 +++++++++++++++++ SourceGen/DisasmProject.cs | 19 ++++++++++++------- SourceGen/MainController.cs | 13 ++++++++++--- SourceGen/RuntimeData/Help/mainwin.html | 4 ++++ SourceGen/XrefSet.cs | 23 ++++++++++++++++++----- 5 files changed, 61 insertions(+), 15 deletions(-) diff --git a/Asm65/OpDef.cs b/Asm65/OpDef.cs index f5b5270..af96638 100644 --- a/Asm65/OpDef.cs +++ b/Asm65/OpDef.cs @@ -253,6 +253,23 @@ namespace Asm65 { } } + /// + /// True for instructions that dereference the operand. + /// + public bool IsPointerAccessInstruction { + get { + return AddrMode == AddressMode.DPIndexXInd || + AddrMode == AddressMode.DPInd || + AddrMode == AddressMode.DPIndLong || + AddrMode == AddressMode.DPIndIndexY || + AddrMode == AddressMode.DPIndIndexYLong || + // indirect JMP/JSR + AddrMode == AddressMode.AbsInd || + AddrMode == AddressMode.AbsIndLong || + AddrMode == AddressMode.AbsIndexXInd; + } + } + /// /// True if this is an absolute-address instruction whose operand is combined with /// the Program Bank Register. diff --git a/SourceGen/DisasmProject.cs b/SourceGen/DisasmProject.cs index 418581f..33bff66 100644 --- a/SourceGen/DisasmProject.cs +++ b/SourceGen/DisasmProject.cs @@ -1550,7 +1550,7 @@ namespace SourceGen { XrefSet.XrefType xrefType = XrefSet.XrefType.Unknown; OpDef.MemoryEffect accType = OpDef.MemoryEffect.Unknown; - bool isIndexedDirect = false; + XrefSet.Xref.AccessFlags accessFlags = XrefSet.Xref.AccessFlags.None; if (attr.IsInstruction) { OpDef op = CpuDef.GetOpDef(FileData[offset]); if (op.IsSubroutineCall) { @@ -1560,7 +1560,12 @@ namespace SourceGen { } else { xrefType = XrefSet.XrefType.MemAccessOp; accType = op.MemEffect; - isIndexedDirect = op.IsIndexedAccessInstruction; + } + if (op.IsIndexedAccessInstruction) { + accessFlags |= XrefSet.Xref.AccessFlags.Indexed; + } + if (op.IsPointerAccessInstruction) { + accessFlags |= XrefSet.Xref.AccessFlags.Pointer; } } else if (attr.IsData || attr.IsInlineData) { xrefType = XrefSet.XrefType.RefFromData; @@ -1589,7 +1594,7 @@ namespace SourceGen { } AddXref(symOffset, new XrefSet.Xref(offset, true, xrefType, accType, - isIndexedDirect, adj)); + accessFlags, adj)); if (adj == 0) { hasZeroOffsetSym = true; } @@ -1601,7 +1606,7 @@ namespace SourceGen { adj = defSym.Value - operandOffset; } defSym.Xrefs.Add(new XrefSet.Xref(offset, true, xrefType, accType, - isIndexedDirect, adj)); + accessFlags, adj)); } } else if (SymbolTable.TryGetValue(dfd.SymbolRef.Label, out Symbol sym)) { // Is this a reference to a project/platform symbol? @@ -1628,7 +1633,7 @@ namespace SourceGen { // to tweak the adjustment math appropriately. } defSym.Xrefs.Add(new XrefSet.Xref(offset, true, xrefType, accType, - isIndexedDirect, adj)); + accessFlags, adj)); } else { // Can get here if somebody creates an address operand symbol // that refers to a local variable. @@ -1668,7 +1673,7 @@ namespace SourceGen { Debug.WriteLine("HEY: found unlabeled addr ref at +" + offset.ToString("x6")); AddXref(targetOffset, new XrefSet.Xref(offset, false, xrefType, - accType, isIndexedDirect, 0)); + accType, accessFlags, 0)); } } @@ -1678,7 +1683,7 @@ namespace SourceGen { // it for the label localizer and possibly the label refactorer.) if (!hasZeroOffsetSym && attr.IsInstructionStart && attr.OperandOffset >= 0) { AddXref(attr.OperandOffset, new XrefSet.Xref(offset, false, xrefType, - accType, isIndexedDirect, 0)); + accType, accessFlags, 0)); } } diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs index 1c9fdb6..8a3c544 100644 --- a/SourceGen/MainController.cs +++ b/SourceGen/MainController.cs @@ -3741,9 +3741,6 @@ namespace SourceGen { typeStr = "??! "; break; } - if (xr.IsIndexedAccess) { - idxStr = "idx "; - } break; default: Debug.Assert(false); @@ -3751,6 +3748,14 @@ namespace SourceGen { break; } + // "LDA (dp,X)" gets both of these + if (xr.IsIndexedAccess) { + idxStr += "idx "; + } + if (xr.IsPointerAccess) { + idxStr += "ptr "; + } + MainWindow.ReferencesListItem rli = new MainWindow.ReferencesListItem(xr.Offset, formatter.FormatOffset24(xr.Offset), formatter.FormatAddress(mProject.GetAnattrib(xr.Offset).Address, showBank), @@ -3759,6 +3764,8 @@ namespace SourceGen { mMainWin.ReferencesList.Add(rli); } + + // TODO(maybe): set the selection to something, instead of just inheriting it? } #endregion References panel diff --git a/SourceGen/RuntimeData/Help/mainwin.html b/SourceGen/RuntimeData/Help/mainwin.html index cb1ac3d..f91919c 100644 --- a/SourceGen/RuntimeData/Help/mainwin.html +++ b/SourceGen/RuntimeData/Help/mainwin.html @@ -259,6 +259,10 @@ data operand, and provides an indication of the nature of the reference:

References from instructions that use indexed addressing (e.g. LDA addr,Y) will also show "idx" to indicate that the instruction is using the location as a base address.

+

References from instructions that treat the address as a pointer +(e.g. LDA (dp),Y) will show "ptr". This makes it easy +to identify the locations that are reading or writing through the +pointer from those that are reading or writing the pointer itself.

This will be prefixed with "Sym" or "Oth" to indicate whether or not the reference used the label at the current address. To understand this, consider that addresses can be referenced in different ways. diff --git a/SourceGen/XrefSet.cs b/SourceGen/XrefSet.cs index 8f163d2..72fe1e3 100644 --- a/SourceGen/XrefSet.cs +++ b/SourceGen/XrefSet.cs @@ -69,11 +69,24 @@ namespace SourceGen { ///

public Asm65.OpDef.MemoryEffect AccType { get; private set; } + [Flags] + public enum AccessFlags { + None = 0, + Indexed = 1 << 0, + Pointer = 1 << 1 + } + /// - /// For Type==MemAccessOp, true if the instruction applies an index offset, to + /// For Type==MemAccessOp, true if the instruction applies an index offset to /// the operand, meaning the referenced address might not actually be accessed. /// - public bool IsIndexedAccess { get; private set; } + public AccessFlags Flags { get; private set; } + public bool IsIndexedAccess { + get { return (Flags & AccessFlags.Indexed) != 0; } + } + public bool IsPointerAccess { + get { return (Flags & AccessFlags.Pointer) != 0; } + } /// /// Adjustment to symbol. For example, "LDA label+2" adds an xref entry to @@ -82,18 +95,18 @@ namespace SourceGen { public int Adjustment { get; private set; } public Xref(int offset, bool isByName, XrefType type, - Asm65.OpDef.MemoryEffect accType, bool isIndexedAccess, int adjustment) { + Asm65.OpDef.MemoryEffect accType, AccessFlags accessFlags, int adjustment) { Offset = offset; IsByName = isByName; Type = type; AccType = accType; - IsIndexedAccess = isIndexedAccess; + Flags = accessFlags; Adjustment = adjustment; } public override string ToString() { return "Xref off=+" + Offset.ToString("x6") + " sym=" + IsByName + - " type=" + Type + " accType= " + AccType + " idx=" + IsIndexedAccess + + " type=" + Type + " accType= " + AccType + " flags=" + Flags + " adj=" + Adjustment; } }