Files
NESDecompiler/NESDecompiler.Core/Decompilation/DecompiledFunction.cs
T
KallDrexx c0380bd198 Allow for sub address instructions.
When a wrap around scenario is detected during single function tracing,
if the address prior to the "entry point" is a single byte, then we do
not have any space to add the required jump call.

This fixes that by adding the concept of sub address instructions. This
allows adding instructions at runtime that get sorted correctly against
the real instructions from the ROM.

This not only solves the wrapping issue, but also allows for adding hooks
at runtime.
2025-10-11 23:11:37 -04:00

52 lines
1.9 KiB
C#

using NESDecompiler.Core.Disassembly;
namespace NESDecompiler.Core.Decompilation;
/// <summary>
/// Represents an independently decompiled function
/// </summary>
public class DecompiledFunction
{
/// <summary>
/// The CPU address where the address' first instruction is located
/// </summary>
public ushort Address { get; }
/// <summary>
/// The instructions that make up this function in the correct order in which they should be
/// executed.
/// </summary>
public IReadOnlyList<DisassembledInstruction> OrderedInstructions { get; }
/// <summary>
/// Location and the labels of all jump and branch targets within this function
/// </summary>
public IReadOnlyDictionary<ushort, string> JumpTargets { get; }
public DecompiledFunction(
ushort address,
IReadOnlyList<DisassembledInstruction> instructions,
IReadOnlySet<ushort> jumpTargets)
{
Address = address;
JumpTargets = instructions
.Where(x => jumpTargets.Contains(x.CPUAddress))
.Where(x => x.Label != null)
.ToDictionary(x => x.CPUAddress, x => x.Label!);
// We need to order the instructions so that the starting instruction is the first one encountered.
// We can't just rely on the CPU address, because a function may jump to a code point earlier than
// the first instruction.
var initialInstructions = instructions
.Where(x => x.CPUAddress >= address)
.OrderBy(x => x.CPUAddress)
.ThenBy(x => x.SubAddressOrder);
var trailingInstructions = instructions
.Where(x => x.CPUAddress < address)
.OrderBy(x => x.CPUAddress)
.ThenBy(x => x.SubAddressOrder); // real instructions before virtual ones
OrderedInstructions = initialInstructions.Concat(trailingInstructions).ToArray();
}
}