diff --git a/CommonUtil/AddressMap.cs b/CommonUtil/AddressMap.cs index 8d6a640..bccf941 100644 --- a/CommonUtil/AddressMap.cs +++ b/CommonUtil/AddressMap.cs @@ -977,7 +977,7 @@ namespace CommonUtil { /// /// /// This is NOT intended to say whether the sequence of addresses has a hiccup. The goal - /// is to identify multi-byte elements that have a .arstart/.arend statement in the middle. + /// is to identify multi-byte elements that have an arstart/arend statement in the middle. /// /// We can do this in a couple of different ways: /// 1. Find the node that holds the offset, confirm that it spans offset+length, and diff --git a/SourceGen/AsmGen/AsmCc65.cs b/SourceGen/AsmGen/AsmCc65.cs index 954ada4..e2c4121 100644 --- a/SourceGen/AsmGen/AsmCc65.cs +++ b/SourceGen/AsmGen/AsmCc65.cs @@ -112,8 +112,8 @@ namespace SourceGen.AsmGen { { "EquDirective", "=" }, { "VarDirective", ".set" }, { "ArStartDirective", ".org" }, - //ArEndDirective - //RegWidthDirective // .a8, .a16, .i8, .i16 + { "ArEndDirective", ".adrend" }, // on-screen display only + //RegWidthDirective // .a8, .a16, .i8, .i16 //DataBankDirective { "DefineData1", ".byte" }, { "DefineData2", ".word" }, @@ -123,12 +123,12 @@ namespace SourceGen.AsmGen { //DefineBigData3 //DefineBigData4 { "Fill", ".res" }, - { "Dense", ".byte" }, // not really dense, just comma-separated bytes + { "Dense", ".byte" }, // really just just comma-separated bytes //Junk { "StrGeneric", ".byte" }, //StrReverse { "StrNullTerm", ".asciiz" }, - //StrLen8 // macro with .strlen? + //StrLen8 // TODO(maybe): macro with .strlen? //StrLen16 //StrDci }); diff --git a/SourceGen/AsmGen/AsmMerlin32.cs b/SourceGen/AsmGen/AsmMerlin32.cs index 05d6224..7662a29 100644 --- a/SourceGen/AsmGen/AsmMerlin32.cs +++ b/SourceGen/AsmGen/AsmMerlin32.cs @@ -106,7 +106,7 @@ namespace SourceGen.AsmGen { { "EquDirective", "equ" }, { "VarDirective", "equ" }, { "ArStartDirective", "org" }, - { "ArEndDirective", "org_end" }, // not actually used + { "ArEndDirective", "adrend" }, // on-screen display only //RegWidthDirective //DataBankDirective { "DefineData1", "dfb" }, diff --git a/SourceGen/Exporter.cs b/SourceGen/Exporter.cs index 2ab8ef8..8dddb9f 100644 --- a/SourceGen/Exporter.cs +++ b/SourceGen/Exporter.cs @@ -735,9 +735,15 @@ namespace SourceGen { } if ((mLeftFlags & ActiveColumnFlags.Address) != 0) { if (!string.IsNullOrEmpty(parts.Addr)) { - string str = parts.Addr + ":"; + string str; + if (parts.IsNonAddressable) { + str = "" + parts.Addr + ""; + } else { + str = parts.Addr; + } + str += ":"; colPos = AddSpacedString(sb, colPos, mColStart[(int)Col.Address], - str, str.Length); + str, parts.Addr.Length + 1); } } if ((mLeftFlags & ActiveColumnFlags.Bytes) != 0) { diff --git a/SourceGen/LineListGen.cs b/SourceGen/LineListGen.cs index 3ceb91c..eeef4b4 100644 --- a/SourceGen/LineListGen.cs +++ b/SourceGen/LineListGen.cs @@ -282,8 +282,8 @@ namespace SourceGen { int topOffset = dl[topIndex].FileOffset; int firstIndex = dl.FindLineIndexByOffset(topOffset); Debug.Assert(topIndex >= firstIndex); - savedSel.mTopPosition = - new NavStack.Location(topOffset, topIndex - firstIndex, false); + savedSel.mTopPosition = new NavStack.Location(topOffset, topIndex - firstIndex, + NavStack.GoToMode.JumpToAdjIndex); List lineList = dl.mLineList; Debug.Assert(lineList.Count == sel.Length); @@ -832,7 +832,7 @@ namespace SourceGen { // Blank lines and comments can appear before or after code/data. They // must have the offset of the associated line, and a span of zero. if (line.FileOffset != expectedOffset && line.FileOffset != lastOffset) { - // .arend directives are associated with the last byte of a region, so + // arend directives are associated with the last byte of a region, so // we need to make a special exemption for them. if (line.LineType == Line.Type.ArEndDirective && line.FileOffset == expectedOffset - 1) { @@ -1035,7 +1035,7 @@ namespace SourceGen { // Insert long comments and notes. These may span multiple display lines, // and require word-wrap, so it's easiest just to render them fully here. - // Set "spaceAdded" to true so .arstart doesn't try to add one after the comment. + // Set "spaceAdded" to true so arstart doesn't try to add one after the comment. // // TODO: integrate into FormattedOperandCache so we don't have to // regenerate them unless they change. Use the MLC as the dependency. @@ -1066,7 +1066,7 @@ namespace SourceGen { AddressMap.AddressRegion region = change.Region; if (region.Offset == 0 && hasPrgHeader) { - // Suppress the .arstart at offset zero. We know there's another one + // Suppress the arstart at offset zero. We know there's another one // at offset +000002, and that it matches the value at +0/1. addrIter.MoveNext(); continue; @@ -1079,7 +1079,7 @@ namespace SourceGen { lines.Add(GenerateBlankLine(offset)); } spaceAdded = false; // next one will need a blank line - multiStart = true; // unless it's another .arstart immediately + multiStart = true; // unless it's another arstart immediately if (region.HasValidPreLabel) { Line preLine = @@ -1109,16 +1109,19 @@ namespace SourceGen { } else { addrStr = mFormatter.FormatHexValue(region.Address, 4); } -#if DEBUG +#if DEBUG1 string comment = mFormatter.FormatEolComment("ends at " + mFormatter.FormatOffset24(region.Offset + region.ActualLength - 1) + (region.IsFloating ? " (floating)" : string.Empty)); -#else - string comment = string.Empty; -#endif if (change.IsSynthetic) { comment += " (auto-generated)"; } +#else + string comment = string.Empty; + if (change.IsSynthetic) { + comment = mFormatter.FormatEolComment("(auto-generated)"); + } +#endif newLine.Parts = FormattedParts.CreateFullDirective(string.Empty, mFormatter.FormatPseudoOp(mPseudoOpNames.ArStartDirective), addrStr, comment); @@ -1284,10 +1287,10 @@ namespace SourceGen { // Check for address region ends, which will be positioned one byte before the // updated offset (unless they somehow got embedded inside something else). // - // The .arend can only appear on the same offset as .arstart in a single-byte + // The arend can only appear on the same offset as arstart in a single-byte // region, and we can't have more than one of those at the same offset. // If this is not a single-byte region, we need to reset the sub-line count. - // (Alternatively: track the offset of the last .arstart, and reset subline + // (Alternatively: track the offset of the last arstart, and reset subline // if they differ.) if (addrIter.Current != null && addrIter.Current.Region.Length != 1) { arSubLine = 0; @@ -1302,7 +1305,7 @@ namespace SourceGen { } if (change.Region.Offset == 0 && hasPrgHeader) { - // Suppress the .arend at offset +000001. + // Suppress the arend at offset +000001. addrIter.MoveNext(); arSubLine++; // need to track address map continue; @@ -1330,7 +1333,7 @@ namespace SourceGen { // Put a blank line before the next thing. // TODO(maybe): this gets lost in a partial update, e.g. you add a - // long comment right after a .arend with no following .arstart and + // long comment right after a arend with no following arstart and // then hit "undo", because the blank is logically part of the // following offset. addBlank = true; @@ -1649,7 +1652,7 @@ namespace SourceGen { } public AddressMap.AddressRegion GetAddrRegionFromLine(Line line, out bool isSynth) { - // A given offset can have one or more .arstart lines and one or more .arend lines. + // A given offset can have one or more arstart lines and one or more arend lines. // You can't have an end followed by a start, because that would mean the regions // overlap. If there's both start and end present, we have a 1-byte region. int offset = line.FileOffset; @@ -1666,14 +1669,14 @@ namespace SourceGen { while (addrIter.Current != null && addrIter.Current.Offset == offset) { AddressMap.AddressChange change = addrIter.Current; if (count == 0) { - // Could be pre-label or .arstart that follows it. Both go to the same place. + // Could be pre-label or arstart that follows it. Both go to the same place. isSynth = change.IsSynthetic; return change.Region; } if (change.IsStart && change.Region.HasValidPreLabel) { count--; if (count == 0) { - // This is the .arstart following the pre-label. + // This is the arstart following the pre-label. isSynth = change.IsSynthetic; return change.Region; } diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs index 4e9a8be..34f21d9 100644 --- a/SourceGen/MainController.cs +++ b/SourceGen/MainController.cs @@ -1664,7 +1664,8 @@ namespace SourceGen { } if (line.IsAddressRangeDirective) { - // TODO(someday): make this jump to the actual directive rather than nearby code + // TODO(someday): make this jump to the specific directive rather than the first + // (should be able to do it with LineDelta) AddressMap.AddressRegion region = CodeLineList.GetAddrRegionFromLine(line, out bool unused); if (region == null) { @@ -1674,13 +1675,12 @@ namespace SourceGen { if (!testOnly) { if (line.LineType == LineListGen.Line.Type.ArStartDirective) { // jump to end - GoToLocation( - new NavStack.Location(region.Offset + region.ActualLength - 1, 0, true), - GoToMode.JumpToCodeData, true); + GoToLocation(new NavStack.Location(region.Offset + region.ActualLength - 1, + 0, NavStack.GoToMode.JumpToArEnd), true); } else { // jump to start - GoToLocation(new NavStack.Location(region.Offset, 0, true), - GoToMode.JumpToCodeData, true); + GoToLocation(new NavStack.Location(region.Offset, + 0, NavStack.GoToMode.JumpToArStart), true); } } return true; @@ -1706,9 +1706,11 @@ namespace SourceGen { int labelOffset = mProject.FindLabelOffsetByName(dfd.SymbolRef.Label); if (labelOffset >= 0) { if (!testOnly) { - // TODO(org): jump to .arstart - GoToLocation(new NavStack.Location(labelOffset, 0, false), - GoToMode.JumpToCodeData, true); + NavStack.GoToMode mode = NavStack.GoToMode.JumpToCodeData; + if (sym.SymbolSource == Symbol.Source.AddrPreLabel) { + mode = NavStack.GoToMode.JumpToArStart; + } + GoToLocation(new NavStack.Location(labelOffset, 0, mode), true); } return true; } @@ -1719,8 +1721,8 @@ namespace SourceGen { if (mProject.ActiveDefSymbolList[i] == sym) { int offset = LineListGen.DefSymOffsetFromIndex(i); if (!testOnly) { - GoToLocation(new NavStack.Location(offset, 0, false), - GoToMode.JumpToCodeData, true); + GoToLocation(new NavStack.Location(offset, 0, + NavStack.GoToMode.JumpToCodeData), true); } return true; } @@ -1737,8 +1739,8 @@ namespace SourceGen { // Operand has an in-file target offset. We can resolve it as a numeric reference. // Find the line for that offset and jump to it. if (!testOnly) { - GoToLocation(new NavStack.Location(attr.OperandOffset, 0, false), - GoToMode.JumpToCodeData, true); + GoToLocation(new NavStack.Location(attr.OperandOffset, 0, + NavStack.GoToMode.JumpToCodeData), true); } return true; } else if (attr.IsDataStart || attr.IsInlineDataStart) { @@ -1748,8 +1750,8 @@ namespace SourceGen { int operandOffset = DataAnalysis.GetDataOperandOffset(mProject, line.FileOffset); if (operandOffset >= 0) { if (!testOnly) { - GoToLocation(new NavStack.Location(operandOffset, 0, false), - GoToMode.JumpToCodeData, true); + GoToLocation(new NavStack.Location(operandOffset, 0, + NavStack.GoToMode.JumpToCodeData), true); } return true; } @@ -1809,15 +1811,15 @@ namespace SourceGen { int lastIndex = mMainWin.CodeListView_GetLastSelectedIndex(); - // Can only start with .arend if it's single-selection. + // Can only start with arend if it's single-selection. if (selIndex != lastIndex && selLine.LineType == LineListGen.Line.Type.ArEndDirective) { return false; } - // If multiple lines with code/data are selected, there must not be a .arstart + // If multiple lines with code/data are selected, there must not be an arstart // between them unless we're resizing a region. Determining whether or not a resize - // is valid is left to the edit dialog. It's okay for a .arend to be in the middle - // so long as the corresponding .arstart is at the current offset. + // is valid is left to the edit dialog. It's okay for an arend to be in the middle + // so long as the corresponding arstart is at the current offset. if (selLine.LineType == LineListGen.Line.Type.ArStartDirective) { // Skip overlapping region check. return true; @@ -1856,7 +1858,7 @@ namespace SourceGen { int nextOffset = lastOffset + CodeLineList[lastIndex].OffsetSpan; AddressMap addrMap = mProject.AddrMap; - // The offset of a .arend directive is the last byte in the address region. It + // The offset of an arend directive is the last byte in the address region. It // has a span length of zero because it's a directive, so if it's selected as // the last offset then our nextOffset calculation will be off by one. (This would // be avoided by using an exclusive end offset, but that causes other problems.) @@ -1865,13 +1867,13 @@ namespace SourceGen { nextOffset++; } - // Compute length of selection. May be zero if it's entirely .arstart/.arend. + // Compute length of selection. May be zero if it's entirely arstart/arend. int selectedLen = nextOffset - firstOffset; AddressMap.AddressRegion curRegion; if (CodeLineList[selIndex].LineType == LineListGen.Line.Type.ArStartDirective || CodeLineList[selIndex].LineType == LineListGen.Line.Type.ArEndDirective) { - // First selected line was .arstart/.arend, find the address map entry. + // First selected line was arstart/arend, find the address map entry. curRegion = CodeLineList.GetAddrRegionFromLine(CodeLineList[selIndex], out bool isSynth); Debug.Assert(curRegion != null); @@ -1888,7 +1890,7 @@ namespace SourceGen { } else { if (selectedLen == 0) { // A length of zero is only possible if nothing but directives were selected, - // but since the first entry wasn't .arstart/.arend this can't happen. + // but since the first entry wasn't arstart/arend this can't happen. Debug.Assert(false); return; } @@ -2820,20 +2822,20 @@ namespace SourceGen { GotoBox dlg = new GotoBox(mMainWin, mProject, offset, mFormatter); if (dlg.ShowDialog() == true) { - GoToLocation(new NavStack.Location(dlg.TargetOffset, 0, false), - GoToMode.JumpToCodeData, true); + GoToLocation(new NavStack.Location(dlg.TargetOffset, 0, + NavStack.GoToMode.JumpToCodeData), true); //mMainWin.CodeListView_Focus(); } } - public enum GoToMode { Unknown = 0, JumpToCodeData, JumpToNote, JumpToAdjIndex }; /// /// Moves the view and selection to the specified offset. We want to select stuff /// differently if we're jumping to a note vs. jumping to an instruction. /// - /// Offset to jump to. + /// Location to jump to. + /// Interesting set of lines within that offset. /// If set, push new offset onto navigation stack. - public void GoToLocation(NavStack.Location loc, GoToMode mode, bool doPush) { + public void GoToLocation(NavStack.Location newLoc, bool doPush) { NavStack.Location prevLoc = GetCurrentlySelectedLocation(); //Debug.WriteLine("GoToLocation: " + loc + " mode=" + mode + " doPush=" + doPush + // " (curLoc=" + prevLoc + ")"); @@ -2844,8 +2846,7 @@ namespace SourceGen { // entry in the symbol table for the current offset, we want to move the selection, // so we don't want to bail out if the offset matches. Easiest thing to do is to // do the move but not push it. - bool jumpToNote = (mode == GoToMode.JumpToNote); - if (loc.Offset == prevLoc.Offset && jumpToNote == prevLoc.IsNote) { + if (newLoc.Offset == prevLoc.Offset && newLoc.Mode == prevLoc.Mode) { // we're jumping to ourselves? if (doPush) { Debug.WriteLine("Ignoring push for goto to current offset"); @@ -2853,27 +2854,30 @@ namespace SourceGen { } } - int topLineIndex = CodeLineList.FindLineIndexByOffset(loc.Offset); + int topLineIndex = CodeLineList.FindLineIndexByOffset(newLoc.Offset); if (topLineIndex < 0) { - Debug.Assert(false, "failed goto offset +" + loc.Offset.ToString("x6")); + Debug.Assert(false, "failed goto offset +" + newLoc.Offset.ToString("x6")); return; } int lastLineIndex; - if (mode == GoToMode.JumpToNote) { + if (newLoc.Mode == NavStack.GoToMode.JumpToNote) { // Select all note lines, disregard the rest. while (CodeLineList[topLineIndex].LineType != LineListGen.Line.Type.Note) { + if (CodeLineList[topLineIndex].FileOffset != newLoc.Offset) { + // This can happen if the note got deleted. + break; + } topLineIndex++; - Debug.Assert(CodeLineList[topLineIndex].FileOffset == loc.Offset); } lastLineIndex = topLineIndex + 1; while (lastLineIndex < CodeLineList.Count && CodeLineList[lastLineIndex].LineType == LineListGen.Line.Type.Note) { lastLineIndex++; } - } else if (loc.Offset < 0) { + } else if (newLoc.Offset < 0) { // This is the offset of the header comment or a .EQ directive. Don't mess with it. lastLineIndex = topLineIndex + 1; - } else if (mode == GoToMode.JumpToCodeData) { + } else if (newLoc.Mode == NavStack.GoToMode.JumpToCodeData) { // Advance to the code or data line. while (CodeLineList[topLineIndex].LineType != LineListGen.Line.Type.Code && CodeLineList[topLineIndex].LineType != LineListGen.Line.Type.Data) { @@ -2881,14 +2885,35 @@ namespace SourceGen { } lastLineIndex = topLineIndex + 1; - } else if (mode == GoToMode.JumpToAdjIndex) { + } else if (newLoc.Mode == NavStack.GoToMode.JumpToAdjIndex) { // Adjust the line position by the line delta. If the adjustment moves us to // a different element, ignore the adjustment. if (CodeLineList[topLineIndex].FileOffset == - CodeLineList[topLineIndex + loc.LineDelta].FileOffset) { - topLineIndex += loc.LineDelta; + CodeLineList[topLineIndex + newLoc.LineDelta].FileOffset) { + topLineIndex += newLoc.LineDelta; } lastLineIndex = topLineIndex + 1; + } else if (newLoc.Mode == NavStack.GoToMode.JumpToArStart || + newLoc.Mode == NavStack.GoToMode.JumpToArEnd) { + LineListGen.Line.Type matchType = LineListGen.Line.Type.ArStartDirective; + if (newLoc.Mode != NavStack.GoToMode.JumpToArStart) { + matchType = LineListGen.Line.Type.ArEndDirective; + } + // Find first instance of specified type. + LineListGen.Line tmpLine = CodeLineList[topLineIndex]; + while (CodeLineList[topLineIndex].LineType != matchType) { + if (CodeLineList[topLineIndex].FileOffset > newLoc.Offset) { + // This can happen if the region got deleted. + break; + } + topLineIndex++; + } + lastLineIndex = topLineIndex + 1; + // If there's multiple lines, make sure they're all on screen. + while (lastLineIndex < CodeLineList.Count && + CodeLineList[lastLineIndex].LineType == matchType) { + lastLineIndex++; + } } else { Debug.Assert(false); lastLineIndex = topLineIndex + 1; @@ -3029,7 +3054,8 @@ namespace SourceGen { int offset = CodeLineList[index].FileOffset; int lineDelta = index - CodeLineList.FindLineIndexByOffset(offset); bool isNote = (CodeLineList[index].LineType == LineListGen.Line.Type.Note); - return new NavStack.Location(offset, lineDelta, isNote); + return new NavStack.Location(offset, lineDelta, + isNote ? NavStack.GoToMode.JumpToNote : NavStack.GoToMode.JumpToAdjIndex); } public void GotoLastChange() { @@ -3076,11 +3102,11 @@ namespace SourceGen { } if (isNote) { - GoToLocation(new NavStack.Location(offset, 0, true), - GoToMode.JumpToNote, true); + GoToLocation(new NavStack.Location(offset, 0, NavStack.GoToMode.JumpToNote), + true); } else { - GoToLocation(new NavStack.Location(offset, 0, false), - GoToMode.JumpToCodeData, true); + GoToLocation(new NavStack.Location(offset, 0, NavStack.GoToMode.JumpToCodeData), + true); } } @@ -3090,8 +3116,7 @@ namespace SourceGen { public void NavigateBackward() { Debug.Assert(mNavStack.HasBackward); NavStack.Location backLoc = mNavStack.MoveBackward(GetCurrentlySelectedLocation()); - GoToLocation(backLoc, - backLoc.IsNote ? GoToMode.JumpToNote : GoToMode.JumpToAdjIndex, false); + GoToLocation(backLoc, false); } public bool CanNavigateForward() { @@ -3100,8 +3125,7 @@ namespace SourceGen { public void NavigateForward() { Debug.Assert(mNavStack.HasForward); NavStack.Location fwdLoc = mNavStack.MoveForward(GetCurrentlySelectedLocation()); - GoToLocation(fwdLoc, - fwdLoc.IsNote ? GoToMode.JumpToNote : GoToMode.JumpToAdjIndex, false); + GoToLocation(fwdLoc, false); } /// @@ -3111,8 +3135,9 @@ namespace SourceGen { public void GoToLabel(Symbol sym) { int offset = mProject.FindLabelOffsetByName(sym.Label); if (offset >= 0) { - GoToLocation(new NavStack.Location(offset, 0, false), - GoToMode.JumpToCodeData, true); + // TODO(someday): jump to correct line for address region pre-labels + GoToLocation(new NavStack.Location(offset, 0, NavStack.GoToMode.JumpToCodeData), + true); } else { Debug.WriteLine("DClick symbol: " + sym + ": label not found"); } @@ -4045,14 +4070,23 @@ namespace SourceGen { esb.Append(" (floating)"); } esb.Append(CRLF); + esb.Append("Pre-label: "); + if (!string.IsNullOrEmpty(region.PreLabel)) { + esb.Append("'"); + esb.Append(region.PreLabel); + if (region.PreLabelAddress == Address.NON_ADDR) { + esb.Append("' (non-addressable)"); + } else { + esb.Append("' addr=$"); + esb.Append(mFormatter.FormatAddress(region.PreLabelAddress, + !mProject.CpuDef.HasAddr16)); + } + } else { + esb.Append("none"); + } + esb.Append(CRLF); esb.Append("Synthetic: " + isSynth); esb.Append(CRLF); - if (!string.IsNullOrEmpty(region.PreLabel)) { - esb.Append("Pre-label: '" + region.PreLabel + "' addr=$"); - esb.Append(mFormatter.FormatAddress(region.PreLabelAddress, - !mProject.CpuDef.HasAddr16)); - esb.Append(CRLF); - } esb.Append("Relative: " + region.IsRelative); esb.Append(CRLF); mMainWin.InfoPanelDetail1 = esb.ToString(); diff --git a/SourceGen/NavStack.cs b/SourceGen/NavStack.cs index a973ef2..103be4b 100644 --- a/SourceGen/NavStack.cs +++ b/SourceGen/NavStack.cs @@ -38,6 +38,15 @@ namespace SourceGen { // TODO(someday): change the back button to a pop-up list of locations (like the way // VS 2017 does it). + public enum GoToMode { + Unknown = 0, + JumpToCodeData, // destination is first byte of code or data at target offset + JumpToNote, // destination is Note at target offset + JumpToAdjIndex, // destination is first line at target offset plus LineDelta + JumpToArStart, // destination is arstart at target offset. + JumpToArEnd, // destination is arend at target offset + }; + /// /// Holds enough information to get us back where we were, in style. /// @@ -49,7 +58,7 @@ namespace SourceGen { /// /// Number of lines between the first line at the specified offset, and the - /// line we actually want to land on. + /// line we actually want to land on. Used when Mode=JumpToAdjIndex. /// /// /// It's possible this line no longer exists. Easiest test is to compare the @@ -59,21 +68,22 @@ namespace SourceGen { public int LineDelta { get; set; } /// - /// True if the target is the note at the given offset, rather than the code/data. + /// Specifies interesting things to find at the target offset. /// - /// - /// This is an alternative to LineDelta. - /// - public bool IsNote { get; set; } + public GoToMode Mode { get; set; } - public Location(int offset, int lineDelta, bool isNote) { + public Location(int offset, int lineDelta, GoToMode mode) { Offset = offset; LineDelta = lineDelta; - IsNote = isNote; + Mode = mode; + + //if (lineDelta != 0 && mode != GoToMode.JumpToAdjIndex) { + // Debug.WriteLine("HEY: lineDelta=" + lineDelta + " mode=" + mode); + //} } public override string ToString() { - return string.Format("[+{0:x6},{1},{2}]", Offset, LineDelta, IsNote); + return string.Format("[+{0:x6},{1},{2}]", Offset, LineDelta, Mode); } public static bool operator ==(Location a, Location b) { @@ -83,7 +93,7 @@ namespace SourceGen { if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) { return false; // one is null } - return a.Offset == b.Offset && a.LineDelta == b.LineDelta && a.IsNote == b.IsNote; + return a.Offset == b.Offset && a.LineDelta == b.LineDelta && a.Mode == b.Mode; } public static bool operator !=(Location a, Location b) { return !(a == b); @@ -92,7 +102,7 @@ namespace SourceGen { return obj is Location && this == (Location)obj; } public override int GetHashCode() { - return Offset + (LineDelta * 1000000) + (IsNote ? (1<<24) : 0); + return Offset + (LineDelta * 1000000) + ((int)Mode << 24); } } diff --git a/SourceGen/PseudoOp.cs b/SourceGen/PseudoOp.cs index 04a8c90..52d3631 100644 --- a/SourceGen/PseudoOp.cs +++ b/SourceGen/PseudoOp.cs @@ -228,8 +228,8 @@ namespace SourceGen { new PseudoOpNames(new Dictionary { { "EquDirective", ".eq" }, { "VarDirective", ".var" }, - { "ArStartDirective", ".arstart" }, - { "ArEndDirective", ".arend" }, + { "ArStartDirective", ".addrs" }, + { "ArEndDirective", ".adrend" }, { "RegWidthDirective", ".rwid" }, { "DataBankDirective", ".dbank" }, diff --git a/SourceGen/RenderAddressMap.cs b/SourceGen/RenderAddressMap.cs index 001b7db..88bbf73 100644 --- a/SourceGen/RenderAddressMap.cs +++ b/SourceGen/RenderAddressMap.cs @@ -45,7 +45,7 @@ namespace SourceGen { int prevAddr = 0; int lastEndOffset = -1; - sb.AppendLine("Address region map for " + project.DataFileName); + sb.AppendLine("Address region map for \"" + project.DataFileName + "\""); sb.Append(CRLF); IEnumerator iter = addrMap.AddressChangeIterator; @@ -67,12 +67,6 @@ namespace SourceGen { } // Start following end, or start following start after a gap. - if (!string.IsNullOrEmpty(change.Region.PreLabel)) { - PrintDepthLines(sb, depth, true); - sb.Append("| pre='" + change.Region.PreLabel + "' "); - PrintAddress(sb, formatter, change.Region.PreLabelAddress, showBank); - sb.Append(CRLF); - } sb.Append(formatter.FormatOffset24(change.Offset)); PrintDepthLines(sb, depth, false); sb.Append("+- " + "start"); @@ -83,10 +77,16 @@ namespace SourceGen { // If there's a label here, show it. Anattrib attr = project.GetAnattrib(change.Offset); if (attr.Symbol != null && !string.IsNullOrEmpty(attr.Symbol.Label)) { - sb.Append(" : "); - sb.Append(attr.Symbol.Label); + sb.Append(" '"); + sb.Append(attr.Symbol.GenerateDisplayLabel(formatter)); + sb.Append("'"); } } + if (change.Region.HasValidPreLabel) { + sb.Append(" pre='"); + sb.Append(change.Region.PreLabel); + sb.Append("'"); + } sb.Append(CRLF); diff --git a/SourceGen/RuntimeData/SGStyle.css b/SourceGen/RuntimeData/SGStyle.css index 3be2f60..10f492d 100644 --- a/SourceGen/RuntimeData/SGStyle.css +++ b/SourceGen/RuntimeData/SGStyle.css @@ -1,6 +1,10 @@ /* * 6502bench SourceGen disassembly output style. */ + +/* + * General formatting. + */ body { font-family: Arial, Helvetica, sans-serif; font-size: 14px; /* 16 recommended for mobile */ @@ -11,6 +15,9 @@ table, th, td { border: 1px solid black; border-collapse: collapse; } +.greytext { + color: grey; +} /* * Blue underlined text is distracting. Change internal links to be diff --git a/SourceGen/SGTestData/20170-external-symbols-1.sym65 b/SourceGen/SGTestData/20170-external-symbols-1.sym65 index fdec8cd..2ee61e4 100644 --- a/SourceGen/SGTestData/20170-external-symbols-1.sym65 +++ b/SourceGen/SGTestData/20170-external-symbols-1.sym65 @@ -52,7 +52,8 @@ OverVar @ $40 4 BankWrap @ $fff0 $20 ; Width specifiers on constants should be ignored. -FatConst = $4000 8 +; Uses a leading '_' to test special 64tass handling. +_FatConst = $4000 8 ; Overlapping multi-byte items with exact and inexact matches. OverA_0 @ $6000 8 ;should win, alphabetically diff --git a/SourceGen/SGTestData/20170-external-symbols.dis65 b/SourceGen/SGTestData/20170-external-symbols.dis65 index 049369a..78df66a 100644 --- a/SourceGen/SGTestData/20170-external-symbols.dis65 +++ b/SourceGen/SGTestData/20170-external-symbols.dis65 @@ -27,7 +27,7 @@ "OperandFormats":{ "207":{ "Length":3,"Format":"NumericLE","SubFormat":"Symbol","SymbolRef":{ -"Label":"FatConst","Part":"Low"}}}, +"Label":"_FatConst","Part":"Low"}}}, "LvTables":{ "192":{ "Variables":[{ diff --git a/SourceGen/SGTestData/20260-pre-labels b/SourceGen/SGTestData/20260-pre-labels new file mode 100644 index 0000000..5f523b4 Binary files /dev/null and b/SourceGen/SGTestData/20260-pre-labels differ diff --git a/SourceGen/SGTestData/20260-pre-labels.dis65 b/SourceGen/SGTestData/20260-pre-labels.dis65 new file mode 100644 index 0000000..2d7fef3 --- /dev/null +++ b/SourceGen/SGTestData/20260-pre-labels.dis65 @@ -0,0 +1,219 @@ +### 6502bench SourceGen dis65 v1.0 ### +{ +"_ContentVersion":5, +"FileDataLength":95, +"FileDataCrc32":482033261, +"ProjectProps":{ +"CpuName":"6502", +"IncludeUndocumentedInstr":false, +"TwoByteBrk":false, +"EntryFlags":32702671, +"AutoLabelStyle":"Simple", +"AnalysisParams":{ +"AnalyzeUncategorizedData":true, +"DefaultTextScanMode":"LowHighAscii", +"MinCharsForString":4, +"SeekNearbyTargets":false, +"UseRelocData":false, +"SmartPlpHandling":false, +"SmartPlbHandling":true}, + +"PlatformSymbolFileIdentifiers":[], +"ExtensionScriptFileIdentifiers":[], +"ProjectSyms":{ +"part2":{ +"DataDescriptor":{ +"Length":1, +"Format":"NumericLE", +"SubFormat":"Hex", +"SymbolRef":null}, + +"Comment":"precedence test", +"HasWidth":false, +"Direction":"ReadWrite", +"MultiMask":null, +"Label":"part2", +"Value":4155, +"Source":"Project", +"Type":"ExternalAddr", +"LabelAnno":"None"}, + +"zzz":{ +"DataDescriptor":{ +"Length":1, +"Format":"NumericLE", +"SubFormat":"Hex", +"SymbolRef":null}, + +"Comment":"", +"HasWidth":false, +"Direction":"ReadWrite", +"MultiMask":null, +"Label":"zzz", +"Value":4155, +"Source":"Project", +"Type":"ExternalAddr", +"LabelAnno":"None"}}}, + +"AddressMap":[{ +"Offset":0, +"Addr":-1025, +"Length":2, +"PreLabel":"", +"IsRelative":false}, + +{ +"Offset":2, +"Addr":4096, +"Length":-1024, +"PreLabel":"b4_begin", +"IsRelative":false}, + +{ +"Offset":11, +"Addr":8192, +"Length":48, +"PreLabel":"b4_part2", +"IsRelative":false}, + +{ +"Offset":35, +"Addr":12288, +"Length":-1024, +"PreLabel":"b4_part3", +"IsRelative":false}, + +{ +"Offset":59, +"Addr":16384, +"Length":31, +"PreLabel":"b4_part4b", +"IsRelative":false}, + +{ +"Offset":59, +"Addr":20480, +"Length":21, +"PreLabel":"b4_part4a", +"IsRelative":false}, + +{ +"Offset":59, +"Addr":24576, +"Length":12, +"PreLabel":"_b4_part4", +"IsRelative":false}, + +{ +"Offset":90, +"Addr":61440, +"Length":3, +"PreLabel":"", +"IsRelative":false}], +"TypeHints":[{ +"Low":2, +"High":2, +"Hint":"Code"}], +"StatusFlagOverrides":{ +}, + +"Comments":{ +}, + +"LongComments":{ +}, + +"Notes":{ +}, + +"UserLabels":{ +"2":{ +"Label":"begin", +"Value":4096, +"Source":"User", +"Type":"GlobalAddr", +"LabelAnno":"None"}, + +"11":{ +"Label":"part2", +"Value":8192, +"Source":"User", +"Type":"GlobalAddr", +"LabelAnno":"None"}, + +"33":{ +"Label":"local1", +"Value":8214, +"Source":"User", +"Type":"NonUniqueLocalAddr", +"LabelAnno":"None"}, + +"34":{ +"Label":"local2", +"Value":8215, +"Source":"User", +"Type":"NonUniqueLocalAddr", +"LabelAnno":"None"}, + +"57":{ +"Label":"local3", +"Value":12310, +"Source":"User", +"Type":"NonUniqueLocalAddr", +"LabelAnno":"None"}, + +"58":{ +"Label":"local4", +"Value":12311, +"Source":"User", +"Type":"NonUniqueLocalAddr", +"LabelAnno":"None"}, + +"35":{ +"Label":"part3", +"Value":12288, +"Source":"User", +"Type":"NonUniqueLocalAddr", +"LabelAnno":"None"}, + +"81":{ +"Label":"part4b", +"Value":16406, +"Source":"User", +"Type":"GlobalAddr", +"LabelAnno":"None"}, + +"71":{ +"Label":"part4a", +"Value":20492, +"Source":"User", +"Type":"GlobalAddr", +"LabelAnno":"None"}, + +"59":{ +"Label":"part4", +"Value":24576, +"Source":"User", +"Type":"GlobalAddr", +"LabelAnno":"None"}}, + +"OperandFormats":{ +"0":{ +"Length":2, +"Format":"NumericLE", +"SubFormat":"None", +"SymbolRef":null}}, + +"LvTables":{ +}, + +"Visualizations":[], +"VisualizationAnimations":[], +"VisualizationSets":{ +}, + +"RelocList":{ +}, + +"DbrValues":{ +}} diff --git a/SourceGen/SGTestData/Expected/20170-external-symbols_64tass.S b/SourceGen/SGTestData/Expected/20170-external-symbols_64tass.S index b0633f1..d025d6b 100644 --- a/SourceGen/SGTestData/Expected/20170-external-symbols_64tass.S +++ b/SourceGen/SGTestData/Expected/20170-external-symbols_64tass.S @@ -1,5 +1,5 @@ .cpu "6502" -FatConst = $4000 +X_FatConst = $4000 OverVar = $40 CodeWrap = $0f00 ;encases program @@ -116,7 +116,7 @@ LocalVar .var $41 ldx OverVar+3 ldx $44 nop - lda FatConst-1 + lda X_FatConst-1 lda $4000 lda $4001 lda BankWrap+8 diff --git a/SourceGen/SGTestData/Expected/20170-external-symbols_acme.S b/SourceGen/SGTestData/Expected/20170-external-symbols_acme.S index 15fd1c6..f6329c7 100644 --- a/SourceGen/SGTestData/Expected/20170-external-symbols_acme.S +++ b/SourceGen/SGTestData/Expected/20170-external-symbols_acme.S @@ -1,5 +1,5 @@ !cpu 6502 -FatConst = $4000 +_FatConst = $4000 OverVar = $40 CodeWrap = $0f00 ;encases program @@ -117,7 +117,7 @@ L1000 lda CodeWrap+255 ldx OverVar+3 ldx $44 nop - lda FatConst-1 + lda _FatConst-1 lda $4000 lda $4001 lda BankWrap+8 diff --git a/SourceGen/SGTestData/Expected/20170-external-symbols_cc65.S b/SourceGen/SGTestData/Expected/20170-external-symbols_cc65.S index 1378fa4..7777382 100644 --- a/SourceGen/SGTestData/Expected/20170-external-symbols_cc65.S +++ b/SourceGen/SGTestData/Expected/20170-external-symbols_cc65.S @@ -1,5 +1,5 @@ .setcpu "6502" -FatConst = $4000 +_FatConst = $4000 OverVar = $40 CodeWrap = $0f00 ;encases program @@ -116,7 +116,7 @@ LocalVar .set $41 ldx OverVar+3 ldx $44 nop - lda FatConst-1 + lda _FatConst-1 lda $4000 lda $4001 lda BankWrap+8 diff --git a/SourceGen/SGTestData/Expected/20170-external-symbols_merlin32.S b/SourceGen/SGTestData/Expected/20170-external-symbols_merlin32.S index e5b578d..b3030fb 100644 --- a/SourceGen/SGTestData/Expected/20170-external-symbols_merlin32.S +++ b/SourceGen/SGTestData/Expected/20170-external-symbols_merlin32.S @@ -1,4 +1,4 @@ -FatConst equ $4000 +_FatConst equ $4000 OverVar equ $40 CodeWrap equ $0f00 ;encases program @@ -115,7 +115,7 @@ L1000 lda CodeWrap+255 ldx OverVar+3 ldx $44 nop - lda FatConst-1 + lda _FatConst-1 lda $4000 lda $4001 lda BankWrap+8 diff --git a/SourceGen/SGTestData/Expected/20260-pre-labels_64tass.S b/SourceGen/SGTestData/Expected/20260-pre-labels_64tass.S new file mode 100644 index 0000000..1cb8ed3 --- /dev/null +++ b/SourceGen/SGTestData/Expected/20260-pre-labels_64tass.S @@ -0,0 +1,76 @@ + .cpu "6502" +zzz = $103b + + +* = $1000 +begin bit begin + nop + nop + nop + jmp part2 + + .logical $2000 +part2 bit part2 + nop + lda _local1 + lda local2 + lda local4 + nop + nop + nop + bit b4_part3 + jmp part3 + +_local1 .byte $81 +local2 .byte $82 + +b4_part3 + .logical $3000 +part3 bit part3 + nop + lda local2 + lda _local3 + lda local4 + nop + nop + nop + bit X_b4_part4 + jmp part4 + +_local3 .byte $83 +local4 .byte $84 + .here + .here + + .logical $4000 +b4_part4a + .logical $5000 +X_b4_part4 + .logical $6000 +part4 bit part4 + bit X_b4_part4 + nop + nop + nop + jmp part4a + + .here +part4a bit part4a + bit b4_part4a + jsr part4b + .here + .byte $00 + +part4b bit part4b + bit zzz + jmp _LF000 + + .here + .logical $f000 +_LF000 nop + bne $f003 + .here + .logical $0000 + .byte $ea + .byte $00 + .here diff --git a/SourceGen/SGTestData/Expected/20260-pre-labels_acme.S b/SourceGen/SGTestData/Expected/20260-pre-labels_acme.S new file mode 100644 index 0000000..eae9d0b --- /dev/null +++ b/SourceGen/SGTestData/Expected/20260-pre-labels_acme.S @@ -0,0 +1,79 @@ + !cpu 6502 +zzz = $103b + +* = $0000 + !word $1000 + + !pseudopc $1000 { +begin bit begin + nop + nop + nop + jmp part2 + + } + !pseudopc $2000 { +part2 bit part2 + nop + lda @local1 + lda local2 + lda local4 + nop + nop + nop + bit b4_part3 + jmp part3 + +@local1 !byte $81 +local2 !byte $82 + +b4_part3 + !pseudopc $3000 { +part3 bit part3 + nop + lda local2 + lda @local3 + lda local4 + nop + nop + nop + bit _b4_part4 + jmp part4 + +@local3 !byte $83 +local4 !byte $84 + } + } + + !pseudopc $4000 { +b4_part4a + !pseudopc $5000 { +_b4_part4 + !pseudopc $6000 { +part4 bit part4 + bit _b4_part4 + nop + nop + nop + jmp part4a + + } +part4a bit part4a + bit b4_part4a + jsr part4b + } + !byte $00 + +part4b bit part4b + bit zzz + jmp @LF000 + + } + !pseudopc $f000 { +@LF000 nop + bne $f003 + } + !pseudopc $0000 { + !byte $ea + !byte $00 + } diff --git a/SourceGen/SGTestData/Expected/20260-pre-labels_cc65.S b/SourceGen/SGTestData/Expected/20260-pre-labels_cc65.S new file mode 100644 index 0000000..bfe1d84 --- /dev/null +++ b/SourceGen/SGTestData/Expected/20260-pre-labels_cc65.S @@ -0,0 +1,73 @@ + .setcpu "6502" +zzz = $103b + + .org $0000 + .word $1000 + + .org $1000 +begin: bit begin + nop + nop + nop + jmp part2 + + .org $2000 +part2: bit part2 + nop + lda @local1 + lda local2 + lda local4 + nop + nop + nop + bit b4_part3 + jmp part3 + +@local1: .byte $81 +local2: .byte $82 + +b4_part3: + .org $3000 +part3: bit part3 + nop + lda local2 + lda @local3 + lda local4 + nop + nop + nop + bit _b4_part4 + jmp part4 + +@local3: .byte $83 +local4: .byte $84 + + .org $4000 +b4_part4a: + .org $5000 +_b4_part4: + .org $6000 +part4: bit part4 + bit _b4_part4 + nop + nop + nop + jmp part4a + + .org $500c +part4a: bit part4a + bit b4_part4a + jsr part4b + .org $4015 + .byte $00 + +part4b: bit part4b + bit zzz + jmp @LF000 + + .org $f000 +@LF000: nop + bne $f003 + .org $0000 + .byte $ea + .byte $00 diff --git a/SourceGen/SGTestData/Expected/20260-pre-labels_cc65.cfg b/SourceGen/SGTestData/Expected/20260-pre-labels_cc65.cfg new file mode 100644 index 0000000..cd98926 --- /dev/null +++ b/SourceGen/SGTestData/Expected/20260-pre-labels_cc65.cfg @@ -0,0 +1,9 @@ +# 6502bench SourceGen generated linker script for 20260-pre-labels +MEMORY { + MAIN: file=%O, start=%S, size=65536; +} +SEGMENTS { + CODE: load=MAIN, type=rw; +} +FEATURES {} +SYMBOLS {} diff --git a/SourceGen/SGTestData/Expected/20260-pre-labels_merlin32.S b/SourceGen/SGTestData/Expected/20260-pre-labels_merlin32.S new file mode 100644 index 0000000..4b5455c --- /dev/null +++ b/SourceGen/SGTestData/Expected/20260-pre-labels_merlin32.S @@ -0,0 +1,72 @@ +zzz equ $103b + + org $0000 + dw $1000 + + org $1000 +begin bit begin + nop + nop + nop + jmp part2 + + org $2000 +part2 bit part2 + nop + lda :local1 + lda local2 + lda local4 + nop + nop + nop + bit b4_part3 + jmp part3 + +:local1 dfb $81 +local2 dfb $82 + +b4_part3 + org $3000 +part3 bit part3 + nop + lda local2 + lda :local3 + lda local4 + nop + nop + nop + bit _b4_part4 + jmp part4 + +:local3 dfb $83 +local4 dfb $84 + + org $4000 +b4_part4a + org $5000 +_b4_part4 + org $6000 +part4 bit part4 + bit _b4_part4 + nop + nop + nop + jmp part4a + + org $500c +part4a bit part4a + bit b4_part4a + jsr part4b + org $4015 + dfb $00 + +part4b bit part4b + bit zzz + jmp :LF000 + + org $f000 +:LF000 nop + bne $f003 + org $0000 + dfb $ea + dfb $00 diff --git a/SourceGen/SGTestData/Source/20260-pre-labels.S b/SourceGen/SGTestData/Source/20260-pre-labels.S new file mode 100644 index 0000000..4b00437 --- /dev/null +++ b/SourceGen/SGTestData/Source/20260-pre-labels.S @@ -0,0 +1,111 @@ +; Copyright 2021 faddenSoft. All Rights Reserved. +; See the LICENSE.txt file for distribution terms (Apache 2.0). +; +; Test address region pre-labels. +; +; Assembler: 64tass +; % tass64 --ascii --case-sensitive --nostart 20260-nested-regions.S + + .cpu "6502" +* = $1000 + +; EDIT: create project symbol with same name as pre-label (pre-label should win) +; FILE-EDIT: change pre-label to match user label + +; EDIT: create explicit 2-byte NON_ADDR region here. +START + .word $1000 + + + .logical $1000 +; EDIT: create floating address region with pre-label here ($1000) +; (label should not appear because parent is non-addr) +begin bit begin + nop + nop + nop + jmp part2 + .here + +; EDIT: create fixed address region with pre-label here ($2000) +; (label should not appear because parent is non-addr) + .logical $2000 +part2 bit part2 + nop + lda _local1 + lda _local2 + lda _local4 ;this should force global conv +; (don't do _local3 here, or it gets promoted to global and interferes +; with local access to both _local3 and _local 4 later on) + nop + nop + nop + bit _b4_part3 + jmp _part3 + +_local1 .byte $81 ;data item with local label +_local2 .byte $82 ;data item with local label + +; EDIT: create floating address region with pre-label here ($3000) +_b4_part3 + .logical $3000 +_part3 bit _part3 ;NOTE: label must be declared local + nop + lda _local2 ;this should force global conv + lda _local3 + lda _local4 + nop + nop + nop + bit b4_part4 + jmp part4 + +_local3 .byte $83 ;data item with local label +_local4 .byte $84 ;data item with local label + +; the $2000 range ends here; the $3000 floater also ends here + .here + .here + +; Stack up multiple pre-labels at same offset. + + +; EDIT: create fixed address region with pre-label here ($4000) +; (label should not appear) +b4_part4b ;(not accessible) + .logical $4000 +; EDIT: create fixed address region with pre-label here ($5000) +b4_part4a + .logical $5000 +; EDIT: create fixed address region with pre-label here ($6000) +b4_part4 + .logical $6000 +part4 bit part4 + bit b4_part4 + nop + nop + nop + jmp part4a + .here +part4a bit part4a + bit b4_part4a + jsr part4b ;JSR to test code analysis halt + .here + brk ;shouldn't reach here +part4b bit part4b + bit b4_part4b + jmp end + .here + + + +; EDIT: created fixed 3-byte address region + .logical $f000 +end + nop + bne past ;BNE operand should be shown as hex value + +; EDIT: put actual end here, before the nop +past nop + .here + brk diff --git a/SourceGen/WpfGui/EditAddress.xaml.cs b/SourceGen/WpfGui/EditAddress.xaml.cs index f43fba3..4ee4264 100644 --- a/SourceGen/WpfGui/EditAddress.xaml.cs +++ b/SourceGen/WpfGui/EditAddress.xaml.cs @@ -309,7 +309,7 @@ namespace SourceGen.WpfGui { mPreLabelAddress = curRegion.PreLabelAddress; if (isSingleLine) { - // Only thing selected was .arstart/.arend. First action is to edit + // Only thing selected was arstart/arend. First action is to edit // the region properties, second action is to convert floating end // to fixed. mResultEntry1 = new AddressMap.AddressMapEntry(curRegion.Offset, @@ -332,7 +332,7 @@ namespace SourceGen.WpfGui { } } else { - // Selection started with .arstart and included multiple lines. First + // Selection started with arstart and included multiple lines. First // action is to resize region. Second action is edit without resize. // If resize is illegal (e.g. new region exactly overlaps another), // first action is disabled. diff --git a/SourceGen/WpfGui/MainWindow.xaml.cs b/SourceGen/WpfGui/MainWindow.xaml.cs index 30e5e1c..afbb059 100644 --- a/SourceGen/WpfGui/MainWindow.xaml.cs +++ b/SourceGen/WpfGui/MainWindow.xaml.cs @@ -1672,8 +1672,8 @@ namespace SourceGen.WpfGui { ReferencesListItem rli = (ReferencesListItem)item; // Jump to the offset, then shift the focus back to the code list. - mMainCtrl.GoToLocation(new NavStack.Location(rli.OffsetValue, 0, false), - MainController.GoToMode.JumpToCodeData, true); + mMainCtrl.GoToLocation(new NavStack.Location(rli.OffsetValue, 0, + NavStack.GoToMode.JumpToCodeData), true); codeListView.Focus(); } @@ -1716,8 +1716,8 @@ namespace SourceGen.WpfGui { NotesListItem nli = (NotesListItem)item; // Jump to the offset, then shift the focus back to the code list. - mMainCtrl.GoToLocation(new NavStack.Location(nli.OffsetValue, 0, true), - MainController.GoToMode.JumpToNote, true); + mMainCtrl.GoToLocation(new NavStack.Location(nli.OffsetValue, 0, + NavStack.GoToMode.JumpToNote), true); codeListView.Focus(); } @@ -2098,8 +2098,8 @@ namespace SourceGen.WpfGui { MessageListItem mli = (MessageListItem)item; // Jump to the offset, then shift the focus back to the code list. - mMainCtrl.GoToLocation(new NavStack.Location(mli.OffsetValue, 0, false), - MainController.GoToMode.JumpToCodeData, true); + mMainCtrl.GoToLocation(new NavStack.Location(mli.OffsetValue, 0, + NavStack.GoToMode.JumpToCodeData), true); codeListView.Focus(); }