[GH-ISSUE #1641] [Feature] Add 6502 and 65816 (WDC) native analysis through Ghidra #554

Open
opened 2026-10-15 18:26:07 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @maluramichael on GitHub (Oct 10, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1641

Before submitting

  • I searched the open and closed issues and pull requests for a related proposal.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Native analysis or decompilation

Current limitation

REA's provider-neutral executable architecture type currently admits x86, x86_64, arm, arm64, and mips (BINARY_ARCHITECTURES in src/domain/binaryTargetTypes.ts), so a 6502 or 65816 (WDC 65C816) target cannot reach REA's Ghidra analysis workflow at all. These are the two dominant 8/16-bit CPUs behind a very large body of legally analyzable software (6502: NES/2A03, C64/6510, Apple II, Atari, BBC Micro; 65816: SNES, SA-1, Apple IIGS), and today none of it can flow through REA's ordinary native path.

The two cases are not symmetric and should be scoped separately:

  • 6502: Ghidra already ships a built-in 6502 processor (SLEIGH). The only gaps are REA-side: architecture admission plus a loader for the relevant raw/headered formats. This is close in shape to the generic-ELF admission work and comparatively cheap.
  • 65816: Ghidra has no built-in 65816/65C816 language; upstream declined it (NationalSecurityAgency/ghidra#250, closed as not planned). A working path therefore depends on a bring-your-own community SLEIGH spec plus a loader, and on handling the 65816's flag-dependent instruction width (see non-goals).

Use cases

For static investigation of legally obtained or self-authored 6502/65816 software (homebrew, open-source demos, preservation research, source-owned test binaries), I would like to use REA's normal native workflow to obtain functions, instructions, pseudocode, references, and Evidence through Ghidra, instead of dropping into a separate specialist disassembler that duplicates REA's session and evidence handling.

The desired paths are:

  • 6502 image → REA → Ghidra (built-in 6502 language) → read-only native operations.
  • 65816 image → REA → Ghidra + caller-supplied 65816 extension → read-only native operations.

Desired outcome and success criteria

A focused first milestone could:

  • Admit a supported 6502 target while preserving its 6502 identity through target classification and Evidence, and select Ghidra's built-in 6502 language.
  • Admit a supported 65816 target, preserving its 65816 identity, and select a caller-supplied 65816 language/loader when a compatible extension is already installed.
  • Expose REA's ordinary read-only native operations supported by the selected provider, recording provider/language id, version, and known limitations in Evidence.
  • Fail with an actionable error when a required language/extension or a compatible Ghidra version is unavailable (distinct messages for the built-in 6502 path vs. the bring-your-own 65816 path).
  • Verify import, language selection, function analysis, and decompilation with small source-owned fixtures assembled from an open toolchain (e.g. cc65/ca65, which targets both 6502 and 65816). No commercial game ROM fixture is needed.

Please make the supported Ghidra/extension pair explicit and test it rather than assuming patch-version compatibility; the available 65816 community modules target different Ghidra versions (see References).

Authority boundaries and non-goals

  • Static analysis only. No emulation, no runtime debugging, no PPU/APU/SPC700 modeling, no mapper or cartridge-hardware emulation.
  • The 65816 flag-dependent instruction width (M/X status flags change operand size, so the same opcode disassembles to different lengths) is a known hard limit for linear/automated disassembly. REA should preserve this as an explicit limitation in Evidence rather than imply complete coverage; emulator code/data logs (CDL) are the usual external aid and remain out of scope here.
  • Targets remain caller-supplied and read-only. Bank/memory mapping (LoROM/HiROM for SNES, headering such as iNES for NES) should be explicit and recorded, not silently assumed.
  • The requested outcome does not require vendoring any 65816 extension. A caller-supplied, version-compatible extension preserves upstream ownership and reduces duplicated maintenance, but the maintainers should choose the packaging and integration approach that best fits REA. Automatic extension installation is outside the initial milestone.
  • SPC700 (SNES audio CPU) is a separate processor and separate request; it is not part of this issue.

Alternatives considered

Standalone tools exist (DiztinGUIsh, TRaCER for SNES/NES; cc65 suite; emulator debuggers), and a separate Ghidra-MCP adapter with a 65816 extension works for one-off analysis. All of them duplicate the general session, operation, and Evidence workflows REA already provides for admitted native targets, and none give an agent the provider-neutral path REA is built around. Reusing an existing 65816 SLEIGH module would keep processor semantics in their upstream project while REA owns its agent-facing workflow.

Possible direction

Land 6502 first, since it only needs architecture admission plus a loader on top of Ghidra's built-in language; add 65816 after, gated on a caller-supplied extension and explicit M/X-flag limitations. Treat any 65816 module as bring-your-own and pin the supported Ghidra/extension versions. Source-owned cc65/ca65 fixtures can cover the boundary without distributing commercial data.

Open question for maintainers and the community: which 65816 Ghidra module is the best integration target today? The candidates below differ in completeness, p-code validation, and Ghidra-version support, and some are archived. Pointers to a maintained, oracle-validated 65816 SLEIGH spec would directly de-risk this.

References

Originally created by @maluramichael on GitHub (Oct 10, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1641 ### Before submitting - [x] I searched the open and closed issues and pull requests for a related proposal. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Native analysis or decompilation ### Current limitation REA's provider-neutral executable architecture type currently admits `x86`, `x86_64`, `arm`, `arm64`, and `mips` (`BINARY_ARCHITECTURES` in `src/domain/binaryTargetTypes.ts`), so a 6502 or 65816 (WDC 65C816) target cannot reach REA's Ghidra analysis workflow at all. These are the two dominant 8/16-bit CPUs behind a very large body of legally analyzable software (6502: NES/2A03, C64/6510, Apple II, Atari, BBC Micro; 65816: SNES, SA-1, Apple IIGS), and today none of it can flow through REA's ordinary native path. The two cases are not symmetric and should be scoped separately: - **6502**: Ghidra already ships a built-in `6502` processor (SLEIGH). The only gaps are REA-side: architecture admission plus a loader for the relevant raw/headered formats. This is close in shape to the generic-ELF admission work and comparatively cheap. - **65816**: Ghidra has no built-in 65816/65C816 language; upstream declined it (NationalSecurityAgency/ghidra#250, closed as not planned). A working path therefore depends on a bring-your-own community SLEIGH spec plus a loader, and on handling the 65816's flag-dependent instruction width (see non-goals). ### Use cases For static investigation of legally obtained or self-authored 6502/65816 software (homebrew, open-source demos, preservation research, source-owned test binaries), I would like to use REA's normal native workflow to obtain functions, instructions, pseudocode, references, and Evidence through Ghidra, instead of dropping into a separate specialist disassembler that duplicates REA's session and evidence handling. The desired paths are: - 6502 image → REA → Ghidra (built-in 6502 language) → read-only native operations. - 65816 image → REA → Ghidra + caller-supplied 65816 extension → read-only native operations. ### Desired outcome and success criteria A focused first milestone could: - Admit a supported 6502 target while preserving its 6502 identity through target classification and Evidence, and select Ghidra's built-in 6502 language. - Admit a supported 65816 target, preserving its 65816 identity, and select a caller-supplied 65816 language/loader when a compatible extension is already installed. - Expose REA's ordinary read-only native operations supported by the selected provider, recording provider/language id, version, and known limitations in Evidence. - Fail with an actionable error when a required language/extension or a compatible Ghidra version is unavailable (distinct messages for the built-in 6502 path vs. the bring-your-own 65816 path). - Verify import, language selection, function analysis, and decompilation with small source-owned fixtures assembled from an open toolchain (e.g. cc65/ca65, which targets both 6502 and 65816). No commercial game ROM fixture is needed. Please make the supported Ghidra/extension pair explicit and test it rather than assuming patch-version compatibility; the available 65816 community modules target different Ghidra versions (see References). ### Authority boundaries and non-goals - Static analysis only. No emulation, no runtime debugging, no PPU/APU/SPC700 modeling, no mapper or cartridge-hardware emulation. - The **65816 flag-dependent instruction width** (M/X status flags change operand size, so the same opcode disassembles to different lengths) is a known hard limit for linear/automated disassembly. REA should preserve this as an explicit limitation in Evidence rather than imply complete coverage; emulator code/data logs (CDL) are the usual external aid and remain out of scope here. - Targets remain caller-supplied and read-only. Bank/memory mapping (LoROM/HiROM for SNES, headering such as iNES for NES) should be explicit and recorded, not silently assumed. - The requested outcome does not require vendoring any 65816 extension. A caller-supplied, version-compatible extension preserves upstream ownership and reduces duplicated maintenance, but the maintainers should choose the packaging and integration approach that best fits REA. Automatic extension installation is outside the initial milestone. - SPC700 (SNES audio CPU) is a separate processor and separate request; it is not part of this issue. ### Alternatives considered Standalone tools exist (DiztinGUIsh, TRaCER for SNES/NES; cc65 suite; emulator debuggers), and a separate Ghidra-MCP adapter with a 65816 extension works for one-off analysis. All of them duplicate the general session, operation, and Evidence workflows REA already provides for admitted native targets, and none give an agent the provider-neutral path REA is built around. Reusing an existing 65816 SLEIGH module would keep processor semantics in their upstream project while REA owns its agent-facing workflow. ### Possible direction Land 6502 first, since it only needs architecture admission plus a loader on top of Ghidra's built-in language; add 65816 after, gated on a caller-supplied extension and explicit M/X-flag limitations. Treat any 65816 module as bring-your-own and pin the supported Ghidra/extension versions. Source-owned cc65/ca65 fixtures can cover the boundary without distributing commercial data. **Open question for maintainers and the community:** which 65816 Ghidra module is the best integration target today? The candidates below differ in completeness, p-code validation, and Ghidra-version support, and some are archived. Pointers to a maintained, oracle-validated 65816 SLEIGH spec would directly de-risk this. ### References - REA architecture type: https://github.com/morluto/rea/blob/main/src/domain/binaryTargetTypes.ts - REA Ghidra analysis profile: https://github.com/morluto/rea/blob/main/src/ghidra/GhidraAnalysisProfile.ts - Prior art in this repo (same shape, new arch via Ghidra): #718 (generic MIPS ELF), #1330 (PSP/Allegrex) - Upstream 65816 decision: https://github.com/NationalSecurityAgency/ghidra/issues/250 (closed, not planned) - joshleaves/ghidra-snes (65816 SLEIGH `65816:LE:24:snes` + SNES loader, LoROM/HiROM): https://github.com/joshleaves/ghidra-snes - achan1989/ghidra-65816 (original WDC 65816 module, archived) and achan1989/ghidra-snes-loader (archived, Ghidra 9.1-era): https://github.com/achan1989/ghidra-snes-loader - CBongo/ghidra-retro-machines (vendored 65816 SLEIGH `65816:LE:24:retro`, disassembly-only, p-code unvalidated): https://github.com/CBongo/ghidra-retro-machines - cc65/ca65 toolchain (open-source 6502/65816 assembler, for source-owned fixtures): https://github.com/cc65/cc65 - Adjacent, separate request: qwertymodo/SPCdra (SPC700 audio CPU): https://github.com/qwertymodo/SPCdra
Author
Owner

@matbrgz commented on GitHub (Oct 12, 2026):

Architecture & Processor Lane Review

Decomposing the 8/16-bit MOS/WDC processor lane into phased deliverables is the right approach:

  • Phase 1: 6502:
    • Ghidra bundles a first-class SLEIGH module (6502:LE:16:default).
    • Add "6502" to BINARY_ARCHITECTURES in src/domain/binaryTargetTypes.ts.
    • Connect with the iNES/NES container discussion in #2072 and raw binary loading with explicit load address.
  • Phase 2: 65816 (SNES / Apple IIGS):
    • Requires explicit verification of Ghidra's 65816 extension and handling direct page / accumulator width register flags (M/X bits in processor status).
<!-- gh-comment-id:6134645477 --> @matbrgz commented on GitHub (Oct 12, 2026): ### Architecture & Processor Lane Review Decomposing the 8/16-bit MOS/WDC processor lane into phased deliverables is the right approach: - **Phase 1: 6502:** - Ghidra bundles a first-class SLEIGH module (`6502:LE:16:default`). - Add `"6502"` to `BINARY_ARCHITECTURES` in `src/domain/binaryTargetTypes.ts`. - Connect with the iNES/NES container discussion in #2072 and raw binary loading with explicit load address. - **Phase 2: 65816 (SNES / Apple IIGS):** - Requires explicit verification of Ghidra's 65816 extension and handling direct page / accumulator width register flags (`M`/`X` bits in processor status).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#554
No description provided.