Merge pull request #5 from KallDrexx/nmi_decompiling

Decompile direct jumps to instructions that are in between other instructions
This commit is contained in:
ApfelTeeSaft
2025-09-26 14:19:51 +02:00
committed by GitHub
+35 -5
View File
@@ -209,6 +209,7 @@ namespace NESDecompiler.Core.Disassembly
TraceExecution();
IdentifyFunctions();
GenerateLabels();
EnsureReferencedAddressesAreDisassembled();
}
/// <summary>
@@ -225,20 +226,23 @@ namespace NESDecompiler.Core.Disassembly
/// <summary>
/// Performs a linear disassembly of the code data
/// </summary>
private void LinearDisassembly()
private void LinearDisassembly(int offset = 0)
{
try
{
int offset = 0;
ushort baseAddress = 0x8000;
while (offset < codeData.Length)
{
ushort cpuAddress = (ushort)(baseAddress + offset);
if (addressToInstruction.ContainsKey(cpuAddress))
{
// We have already disassembled this instruction and progressed from here,
// so we can stop.
break;
}
byte opcode = codeData[offset];
var instructionInfo = InstructionSet.GetInstruction(opcode);
if (!instructionInfo.IsValid)
@@ -280,13 +284,18 @@ namespace NESDecompiler.Core.Disassembly
/// <summary>
/// Traces execution from known entry points
/// </summary>
private void TraceExecution()
private void TraceExecution(ushort? additionalTraceAddress = null)
{
try
{
var toTrace = new Queue<ushort>(entryPoints);
var traced = new HashSet<ushort>();
if (additionalTraceAddress != null)
{
toTrace.Enqueue(additionalTraceAddress.Value);
}
while (toTrace.Count > 0)
{
ushort address = toTrace.Dequeue();
@@ -328,6 +337,7 @@ namespace NESDecompiler.Core.Disassembly
if (instruction.Info.Mnemonic == "JMP")
{
continue;
}
}
@@ -450,6 +460,26 @@ namespace NESDecompiler.Core.Disassembly
}
}
private void EnsureReferencedAddressesAreDisassembled()
{
const int baseAddress = 0x8000;
var unknownReferencedAddresses = referencedAddresses
.Where(x => !addressToInstruction.ContainsKey(x))
.Where(x => x > baseAddress)
.ToArray();
foreach (var referencedAddress in unknownReferencedAddresses)
{
var offset = referencedAddress - baseAddress;
LinearDisassembly(offset);
TraceExecution(referencedAddress);
}
// Update functions and labels
IdentifyFunctions();
GenerateLabels();
}
/// <summary>
/// Returns the disassembly as a formatted string
/// </summary>