mirror of https://github.com/fadden/6502bench.git
175 lines
6.7 KiB
C#
175 lines
6.7 KiB
C#
/*
|
|
* Copyright 2021 faddenSoft
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Text;
|
|
|
|
using Asm65;
|
|
using CommonUtil;
|
|
using AddressChange = CommonUtil.AddressMap.AddressChange;
|
|
|
|
namespace SourceGen {
|
|
/// <summary>
|
|
/// Functions for generating a human-readable form of the address map.
|
|
/// </summary>
|
|
/// A graphical / interactive visualization would be nicer, but this can be pasted
|
|
/// into bug reports.
|
|
/// </remarks>
|
|
public static class RenderAddressMap {
|
|
private const string CRLF = "\r\n";
|
|
|
|
/// <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();
|
|
}
|
|
|
|
private static void PrintDepthLines(StringBuilder sb, int depth, bool doIndent) {
|
|
if (doIndent) {
|
|
sb.Append(" ");
|
|
}
|
|
sb.Append(" ");
|
|
while (depth-- > 0) {
|
|
sb.Append("| ");
|
|
}
|
|
}
|
|
|
|
private static void PrintAddressInfo(StringBuilder sb, Formatter formatter, int depth,
|
|
int startAddr, int length, bool showBank) {
|
|
//PrintDepthLines(sb, depth);
|
|
//sb.Append(CRLF);
|
|
|
|
PrintDepthLines(sb, depth, true);
|
|
sb.Append(' ');
|
|
if (startAddr == Address.NON_ADDR) {
|
|
sb.Append("-" + Address.NON_ADDR_STR + "-");
|
|
} else {
|
|
PrintAddress(sb, formatter, startAddr, showBank);
|
|
sb.Append(" - ");
|
|
PrintAddress(sb, formatter, startAddr + length - 1, showBank);
|
|
}
|
|
sb.Append(" length=" + length + " ($" + length.ToString("x4") + ")");
|
|
sb.Append(CRLF);
|
|
|
|
//PrintDepthLines(sb, depth, true);
|
|
//sb.Append(CRLF);
|
|
}
|
|
|
|
private static void PrintAddress(StringBuilder sb, Formatter formatter, int addr,
|
|
bool showBank) {
|
|
if (addr == Address.NON_ADDR) {
|
|
sb.Append("-" + Address.NON_ADDR_STR + "-");
|
|
} else {
|
|
sb.Append("$");
|
|
sb.Append(formatter.FormatAddress(addr, showBank));
|
|
}
|
|
}
|
|
}
|
|
}
|