/// <summary> /// Generates a position string, which may be a file offset, an address, or a /// position delta. /// </summary> private static string PositionStr(int offset, int prevOffset, AddressMap addrMap, bool relMode) { if (prevOffset < 0 || !relMode) { // hex offset or address if (OUTPUT_ADDR) { return('$' + addrMap.OffsetToAddress(offset).ToString("x4")); } else { return('+' + offset.ToString("x6")); } } else { // decimal delta return('>' + (offset - prevOffset).ToString()); } }
/// <summary> /// Formats the address map for viewing. /// </summary> public static string GenerateString(DisasmProject project, Formatter formatter) { AddressMap addrMap = project.AddrMap; bool showBank = !project.CpuDef.HasAddr16; StringBuilder sb = new StringBuilder(); int depth = 0; int prevOffset = -1; int prevAddr = 0; int lastEndOffset = -1; sb.AppendLine("Address region map for \"" + project.DataFileName + "\""); sb.Append(CRLF); IEnumerator <AddressChange> iter = addrMap.AddressChangeIterator; while (iter.MoveNext()) { AddressChange change = iter.Current; if (change.IsStart) { //if (change.Offset == lastEndOffset) { // // Extra vertical space for a START following an END at the same offset. // PrintDepthLines(sb, depth, true); // sb.Append(CRLF); // lastEndOffset = -1; //} if (prevOffset >= 0 && change.Offset != prevOffset) { // Start of region at new offset. Output address info for space // between previous start or end. PrintAddressInfo(sb, formatter, depth, prevAddr, change.Offset - prevOffset, showBank); } // Start following end, or start following start after a gap. sb.Append(formatter.FormatOffset24(change.Offset)); PrintDepthLines(sb, depth, false); sb.Append("+- " + "start"); if (change.IsSynthetic) { sb.Append(" (auto-generated)"); } else { // 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.GenerateDisplayLabel(formatter)); sb.Append("'"); } } if (change.Region.HasValidPreLabel) { sb.Append(" pre='"); sb.Append(change.Region.PreLabel); sb.Append("'"); } sb.Append(CRLF); prevOffset = change.Offset; prevAddr = change.Address; depth++; } else { Debug.Assert(prevOffset >= 0); depth--; if (change.Offset + 1 != prevOffset) { // End of region at new offset. Output address info for space // between previous start or end. PrintAddressInfo(sb, formatter, depth + 1, prevAddr, change.Offset + 1 - prevOffset, showBank); } sb.Append(formatter.FormatOffset24(change.Offset)); PrintDepthLines(sb, depth, false); sb.Append("+- " + "end"); if (change.Region.IsFloating) { sb.Append(" (floating)"); } //PrintAddress(sb, formatter, change.Address, showBank); //sb.Append(")"); sb.Append(CRLF); // Add a blank line, but with the depth lines. if (depth > 0) { PrintDepthLines(sb, depth, true); } sb.Append(CRLF); // Use offset+1 here so it lines up with start records. prevOffset = lastEndOffset = change.Offset + 1; prevAddr = change.Address; } } Debug.Assert(depth == 0); return(sb.ToString()); }