30 Commits
Author SHA1 Message Date
ApfelTeeSaft 9aec398919 Implement "IsSelfModifying" flag 2026-01-21 18:30:40 +01:00
ApfelTeeSaft 8242ffb49b Merge pull request #13 from KallDrexx/loopback_instruction_fix
Loopback jumps should occur on the same cpu address of the jump
v1.1.3
2026-01-17 17:55:48 +01:00
KallDrexx e76cec3d6d Loopback jumps should occur on the same cpu address of the jump
When a function is decompiled in the middle of a function, and that function
has a jump point prior to the function's entry point, we need to add a
fake virtual instruction that jumps back to the start of the function.

The virtual instruction needs to be the last instruction in the
ordered instruction set.

We previously accomplished that by adding an instruction at the
location of the function entrypiont minus one. However, this was
failing in cases where a system would cause an interrupt right on
the virtual address. Emulators would then save the virtual
instruction's address to the stack, and jump back into that address
once RTI occurs.

This fails because the virtual address can't be decompiled, because
legit code doesn't exist at that address.

To fix this, I updated the `SubAddressOrder` property to allow for negative
values. This allows the loopback instruction to be on the correct CPUAddress
while still being ordered as expected.

Also ensured that virtual addresses do not get labels, as they are not
actually valid jump targets.
2026-01-17 11:44:40 -05:00
ApfelTeeSaft 26af1f4aa6 close enough ig v1.1.2 2025-10-23 11:34:11 +02:00
Matthew Shapiro bc3da6b960 Decompilation should be possible from the first byte of a code region (#12) v1.1.1 2025-10-17 20:30:54 -04:00
Matthew Shapiro c71aa4d6b2 Consider an invalid instruction the end of a function trace (#11)
When tracing a function, previously we were throwing an exception
if we encountered an invalid / unknown op code. This is needed because
we don't know how many bytes the instruction contains and thus can't
accurately predict where the next instruction would be.

However, some roms (like super mario bros) use an always taken
branch instruction to save bytes instead of a jump. In this case
the next byte after the branch is an invalid op code that will never
actually be hit.

So this change makes it so that invalid operations act as an end
of function markers, but throw a warning in the console. That
allows unconditional/always branches to work, and for games that
actually use these unofficial op codes they are able to get hints
in the debug window.
2025-10-12 14:31:27 -04:00
Matthew Shapiro bcd9ed4b87 Merge pull request #10 from KallDrexx/support_virtual_instructions
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:17:12 -04:00
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
Matthew Shapiro c05b7199c9 Merge pull request #9 from KallDrexx/single_function_decompile_wraparound
Fix wraparound bug
2025-10-11 21:10:03 -04:00
KallDrexx ab9a1fa313 Fix wraparound bug
Since the entry point for analysis could be in the middle of a loop,
we need to guarantee that a jump is dedicated to the entrypoint, so
that an instruction that comes before the "entrypoint" will redirect
back to the entrypoint after execution
2025-10-11 21:00:22 -04:00
Matthew Shapiro bbcd2a6aad Merge pull request #8 from KallDrexx/single_function_decompile
Add code path to decompile/disassemble a single function
2025-10-11 16:03:41 -04:00
KallDrexx 826747aacb Fixed incorrect ordering of instructions 2025-10-11 15:49:10 -04:00
KallDrexx 8e811e2cbc Some fixes 2025-10-10 23:26:38 -04:00
KallDrexx 6d3ec6c2c8 Initial single function decompiler implementation 2025-10-10 23:06:03 -04:00
ApfelTeeSaft 11b9943c09 Update build-release.yml v1.1.0 2025-10-09 14:04:39 +02:00
ApfelTeeSaft 54b9e3d3df Update build-release.yml 2025-10-09 14:01:44 +02:00
ApfelTeeSaft a9f323722f Add CI/CD workflow 2025-10-09 13:58:18 +02:00
ApfelTeeSaft e8a57399ce Merge pull request #7 from KallDrexx/16kb_fix
Fix 16KB roms not decompiling
2025-09-29 08:47:45 +02:00
KallDrexx 9068403d56 Fix 16KB roms not decompiling
Roms with only 16KB of program code had the incorrect base address during the disassembly process. This caused the instructions not to be found.

Fixed by making sure the base address is adjusted based on the prgRomData size.
2025-09-28 21:16:37 -04:00
ApfelTeeSaft bc76d20895 Merge pull request #6 from KallDrexx/loop_unreferenced_instruction_analysis
Loop EnsureReferencedAddressesAreDisassembled
2025-09-28 20:23:11 +02:00
KallDrexx 40743c6889 Loop EnsureReferencedAddressesAreDisassembled
`EnsureReferencedAddressesAreDisassembled is needed to be run because
a jump/branch may occur that targets interwoven instructions that would
not have been picked up on the first pass.

However, an interwoven instruction may actually end up with a branch
into another interwoven instruction. These instructions wouldn't be
picked seen by the end of the 2nd pass.

So the logic in this function is now set to loop (with a maximum) until
all target addresses that are directly referenced have been
disassembled.
2025-09-28 11:20:12 -04:00
ApfelTeeSaft 32e3d78e6d Merge pull request #5 from KallDrexx/nmi_decompiling
Decompile direct jumps to instructions that are in between other instructions
2025-09-26 14:19:51 +02:00
KallDrexx b627bc2a48 Decompiler direct jumps to instructions that are in between other instructions 2025-09-25 21:59:20 -04:00
ApfelTeeSaft 1e9899b9bc Merge pull request #4 from KallDrexx/nmi_decompiling
Add decompililng of other entrypoints, and add specific support for NMI and IRQ vectors
2025-09-25 02:52:33 +02:00
KallDrexx e592c31a0c Add decompililng of other entrypoints, and add specific support for NMI and IRQ vectors 2025-09-24 20:33:38 -04:00
KallDrexx b968b151d0 Fix nullability warnings 2025-09-10 21:30:08 -04:00
ApfelTeeSaft 588841b46b Merge pull request #2 from KallDrexx/instruction_tostring_fix
Fixed instruction ToString() formatting.
2025-09-08 02:03:51 +02:00
KallDrexx c1e0b17bb3 Fixed instruction ToString() formatting.
`GetOperandFormat` was accidentally using C++ style format strings
instead of C# ones, and thus the values were not being properly
displayed. For example, `LDA #00` was showing as `LDA #$02X`, making it
a bit hard to reason about what value the operand is.
2025-09-07 14:03:35 -04:00
ApfelTeeSaft 4d955c2104 create readme 1.0.0 2025-05-15 14:35:29 +02:00
ApfelTeeSaft 810f1458cb Initial commit 2025-05-15 14:33:41 +02:00