mirror of
https://github.com/fadden/6502bench.git
synced 2025-02-10 03:30:45 +00:00
Expand set of things that work with double-click on opcode
If you double-click on the opcode of "JSR label", the code view selection jumps to the label. This now works for partial operands, e.g. "LDA #<label". Some changes to the find-label-offset code affected the cc65 "is it a forward reference to a direct-page label" logic. The regression test now correctly identifies an instruction that refers to itself as not being a forward reference.
This commit is contained in:
parent
a7e6b101c4
commit
2f74fce80b
@ -84,7 +84,7 @@ namespace SourceGen.AppForms {
|
|||||||
|
|
||||||
// Try it as a label. If they give the label a hex name (e.g. "A001") they
|
// Try it as a label. If they give the label a hex name (e.g. "A001") they
|
||||||
// can prefix it with '$' to disambiguate the address.
|
// can prefix it with '$' to disambiguate the address.
|
||||||
int labelOffset = mProject.FindLabelByName(input);
|
int labelOffset = mProject.FindLabelOffsetByName(input);
|
||||||
if (labelOffset >= 0) {
|
if (labelOffset >= 0) {
|
||||||
TargetOffset = labelOffset;
|
TargetOffset = labelOffset;
|
||||||
} else if (Address.ParseAddress(input, 1<<24, out int addr)) {
|
} else if (Address.ParseAddress(input, 1<<24, out int addr)) {
|
||||||
|
@ -2069,23 +2069,28 @@ namespace SourceGen.AppForms {
|
|||||||
// statements and header comment earlier.
|
// statements and header comment earlier.
|
||||||
if (line.FileOffset >= 0) {
|
if (line.FileOffset >= 0) {
|
||||||
Anattrib attr = mProject.GetAnattrib(line.FileOffset);
|
Anattrib attr = mProject.GetAnattrib(line.FileOffset);
|
||||||
|
FormatDescriptor dfd = attr.DataDescriptor;
|
||||||
|
|
||||||
// Does this have an operand with an in-file target offset?
|
// Does this have an operand with an in-file target offset?
|
||||||
|
// (Resolve it as a numeric reference.)
|
||||||
if (attr.OperandOffset >= 0) {
|
if (attr.OperandOffset >= 0) {
|
||||||
// Yup, find the line for that offset and jump to it.
|
// Yup, find the line for that offset and jump to it.
|
||||||
GoToOffset(attr.OperandOffset, false, true);
|
GoToOffset(attr.OperandOffset, false, true);
|
||||||
//int targetIndex =
|
} else if (dfd != null && dfd.HasSymbol) {
|
||||||
// mDisplayList.FindLineIndexByOffset(attr.OperandOffset);
|
// Operand has a symbol, do a symbol lookup.
|
||||||
//GoToOffset(mDisplayList[targetIndex].FileOffset);
|
int labelOffset = mProject.FindLabelOffsetByName(
|
||||||
|
dfd.SymbolRef.Label);
|
||||||
|
if (labelOffset >= 0) {
|
||||||
|
GoToOffset(labelOffset, false, true);
|
||||||
|
}
|
||||||
} else if (attr.IsDataStart || attr.IsInlineDataStart) {
|
} else if (attr.IsDataStart || attr.IsInlineDataStart) {
|
||||||
// If it's an Address or Symbol, we can try to resolve
|
// If it's an Address or Symbol, we can try to resolve
|
||||||
// the value.
|
// the value. (Symbols should have been resolved by the
|
||||||
|
// previous clause, but Address entries would not have been.)
|
||||||
int operandOffset = DataAnalysis.GetDataOperandOffset(
|
int operandOffset = DataAnalysis.GetDataOperandOffset(
|
||||||
mProject, line.FileOffset);
|
mProject, line.FileOffset);
|
||||||
if (operandOffset >= 0) {
|
if (operandOffset >= 0) {
|
||||||
GoToOffset(operandOffset, false, true);
|
GoToOffset(operandOffset, false, true);
|
||||||
//int targetIndex =
|
|
||||||
// mDisplayList.FindLineIndexByOffset(operandOffset);
|
|
||||||
//GoToOffset(mDisplayList[targetIndex].FileOffset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3753,7 +3758,7 @@ namespace SourceGen.AppForms {
|
|||||||
Symbol sym = mSymbolSubset.GetSubsetItem(row);
|
Symbol sym = mSymbolSubset.GetSubsetItem(row);
|
||||||
|
|
||||||
if (sym.SymbolSource == Symbol.Source.Auto || sym.SymbolSource == Symbol.Source.User) {
|
if (sym.SymbolSource == Symbol.Source.Auto || sym.SymbolSource == Symbol.Source.User) {
|
||||||
int offset = mProject.FindLabelByName(sym.Label);
|
int offset = mProject.FindLabelOffsetByName(sym.Label);
|
||||||
if (offset >= 0) {
|
if (offset >= 0) {
|
||||||
GoToOffset(offset, false, true);
|
GoToOffset(offset, false, true);
|
||||||
codeListView.Focus();
|
codeListView.Focus();
|
||||||
|
@ -322,28 +322,11 @@ namespace SourceGen.AsmGen {
|
|||||||
if (dfd == null || !dfd.HasSymbol) {
|
if (dfd == null || !dfd.HasSymbol) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!proj.SymbolTable.TryGetValue(dfd.SymbolRef.Label, out Symbol sym)) {
|
int labelOffset = proj.FindLabelOffsetByName(dfd.SymbolRef.Label);
|
||||||
|
if (labelOffset <= offset) {
|
||||||
|
// Doesn't exist, or is backward reference.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sym.IsInternalLabel) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// It's an internal label reference. We don't currently have a data structure
|
|
||||||
// that lets us go from label name to file offset. This situation is sufficiently
|
|
||||||
// rare that an O(n) approach is acceptable. We may need to fix this someday.
|
|
||||||
//
|
|
||||||
// We only want to know if it is defined after the current instruction. This is
|
|
||||||
// probably being used for a direct-page reference, which is probably at the start
|
|
||||||
// of the file, so we run from the start to the current instruction.
|
|
||||||
for (int i = 0; i < offset; i++) {
|
|
||||||
Anattrib attr = proj.GetAnattrib(i);
|
|
||||||
if (attr.Symbol != null && attr.Symbol == sym) {
|
|
||||||
// Found it earlier in file.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Must appear later in file.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,8 @@ namespace SourceGen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extracts the operand offset from a data item.
|
/// Extracts the operand offset from a data item. Only useful for numeric/Address
|
||||||
|
/// and numeric/Symbol.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="proj">Project reference.</param>
|
/// <param name="proj">Project reference.</param>
|
||||||
/// <param name="offset">Offset of data item.</param>
|
/// <param name="offset">Offset of data item.</param>
|
||||||
|
@ -1584,7 +1584,7 @@ namespace SourceGen {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">Label to find.</param>
|
/// <param name="name">Label to find.</param>
|
||||||
/// <returns>File offset associated with label, or -1 if not found.</returns>
|
/// <returns>File offset associated with label, or -1 if not found.</returns>
|
||||||
public int FindLabelByName(string name) {
|
public int FindLabelOffsetByName(string name) {
|
||||||
// We're interested in user labels and auto-generated labels. Do a lookup in
|
// We're interested in user labels and auto-generated labels. Do a lookup in
|
||||||
// SymbolTable to find the symbol, then if it's user or auto, we do a second
|
// SymbolTable to find the symbol, then if it's user or auto, we do a second
|
||||||
// search to find the file offset it's associated with. The second search
|
// search to find the file offset it's associated with. The second search
|
||||||
@ -1593,10 +1593,11 @@ namespace SourceGen {
|
|||||||
//
|
//
|
||||||
// This will not find "hidden" labels, i.e. labels that are in the middle of an
|
// This will not find "hidden" labels, i.e. labels that are in the middle of an
|
||||||
// instruction or multi-byte data area, because those are removed from SymbolTable.
|
// instruction or multi-byte data area, because those are removed from SymbolTable.
|
||||||
|
|
||||||
if (!SymbolTable.TryGetValue(name, out Symbol sym)) {
|
if (!SymbolTable.TryGetValue(name, out Symbol sym)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (sym.SymbolSource != Symbol.Source.Auto && sym.SymbolSource != Symbol.Source.User) {
|
if (!sym.IsInternalLabel) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < mAnattribs.Length; i++) {
|
for (int i = 0; i < mAnattribs.Length; i++) {
|
||||||
|
@ -286,7 +286,7 @@ L122A: sbc (L0080),y
|
|||||||
sbc f:L0089,x
|
sbc f:L0089,x
|
||||||
.org $0080
|
.org $0080
|
||||||
L0080: bit z:L0082
|
L0080: bit z:L0082
|
||||||
L0082: bit z:L0082
|
L0082: bit L0082
|
||||||
bit L0082
|
bit L0082
|
||||||
L0086: bit a:L0086
|
L0086: bit a:L0086
|
||||||
L0089: lda f:L0089
|
L0089: lda f:L0089
|
||||||
|
@ -26,12 +26,12 @@ namespace SourceGen {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum Source {
|
public enum Source {
|
||||||
// These are in order of highest to lowest precedence. This matters when
|
// These are in order of highest to lowest precedence. This matters when
|
||||||
// looking up a symbol by value.
|
// looking up a symbol by value, since multiple symbols can have the same value.
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
User, // user-defined label
|
User, // user-defined label
|
||||||
Project, // from project configuration file
|
Project, // from project configuration file
|
||||||
Platform, // from platform definition file
|
Platform, // from platform definition file
|
||||||
Auto // auto-generated
|
Auto // auto-generated label
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -48,15 +48,13 @@ namespace SourceGen {
|
|||||||
Constant // constant value
|
Constant // constant value
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if the symbol's type is an internal label (auto or user). Returns
|
/// Returns true if the symbol's type is an internal label (auto or user). Returns
|
||||||
/// false for external addresses and constants.
|
/// false for external addresses and constants.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsInternalLabel {
|
public bool IsInternalLabel {
|
||||||
get {
|
get {
|
||||||
return SymbolType == Type.LocalOrGlobalAddr ||
|
// Could also check Type instead. Either works for now.
|
||||||
SymbolType == Type.GlobalAddr ||
|
return SymbolSource == Source.User || SymbolSource == Source.Auto;
|
||||||
SymbolType == Type.GlobalAddrExport;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user