Skip to content

INL: refuse every flash-program opcode — nabu only ever reads carts#30

Merged
pathawks merged 2 commits into
mainfrom
inl-flash-write-guard
Jun 14, 2026
Merged

INL: refuse every flash-program opcode — nabu only ever reads carts#30
pathawks merged 2 commits into
mainfrom
inl-flash-write-guard

Conversation

@pathawks

Copy link
Copy Markdown
Owner

nabu is a read-only dumper: it drives mapper registers to select banks but never programs a cartridge's flash. INLDevice.nes now rejects the firmware's whole NES flash-PROGRAM family (NES_FLASH_WRITE_OPCODES: the 0x07-0x14 per-mapper PRG/CHR byte-program block + MMC3S at 0x26) before any transfer goes out, at any address — so a stray flash command can never reach a cart that should only be read.

Prompted by an earlier one-off experiment that aimed MMC3_PRG_FLASH_WR at $5xxx mapper registers as a burst-write primitive. That couldn't actually program flash (the data write lands with /ROMSEL deasserted, and the board rejected the writes anyway), but the opcode has no place in a dumper at all — so the guard is the whole family, not just that address misuse. Ordinary register/serial writes (NES_CPU_WR, NES_MMC1_WR) are untouched.

nabu is a read-only dumper: it drives mapper registers to select banks
but never programs a cartridge's flash. INLDevice.nes now rejects the
firmware's whole NES flash-PROGRAM family (NES_FLASH_WRITE_OPCODES:
the 0x07-0x14 per-mapper PRG/CHR byte-program block + MMC3S at 0x26)
before any transfer goes out, at any address — so a stray flash command
can never reach a cart that should only be read.

Prompted by an earlier one-off experiment that aimed MMC3_PRG_FLASH_WR
at $5xxx mapper registers as a burst-write primitive. That couldn't
actually program flash (the data write lands with /ROMSEL deasserted,
and the board rejected the writes anyway), but the opcode has no place
in a dumper at all — so the guard is the whole family, not just that
address misuse. Ordinary register/serial writes (NES_CPU_WR,
NES_MMC1_WR) are untouched.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a safety guard to the INL NES command path so nabu (as a read-only dumper) refuses all known INL firmware flash-program opcodes before any USB transfer is issued, preventing accidental cart flash programming.

Changes:

  • Added NES_FLASH_WRITE_OPCODES (0x07–0x14 plus 0x26) to document and centralize the firmware flash-program opcode family.
  • Added a hard rejection in INLDevice.nes() for any opcode in that flash-program set.
  • Added unit tests verifying the guard triggers pre-USB-transfer and does not block required bank-select write primitives.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/lib/drivers/inl/inl-opcodes.ts Documents and exports the firmware flash-program opcode set as NES_FLASH_WRITE_OPCODES.
src/lib/drivers/inl/inl-device.ts Rejects flash-program opcodes in INLDevice.nes() before issuing any control transfer.
src/lib/drivers/inl/inl-device.test.ts Adds tests to ensure flash opcodes are refused and required dump-related writes still pass through.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/drivers/inl/inl-device.ts
controlIn() transmits only the low 8 bits (opcode & 0xff), so an opcode
outside 0-255 could slip a flash-program byte past the guard: nes(0x107)
checks 0x107 (not in NES_FLASH_WRITE_OPCODES) yet would transmit 0x07
(MMC3_PRG_FLASH_WR), and returnLength was sized from the unmasked value.
Mask opcode up front so the guard and returnLength both reflect the byte
actually sent. No current caller passes an out-of-range opcode; this keeps
the safety backstop airtight regardless, and adds a test for the disguised
0x107 case.

Per PR review.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@pathawks pathawks merged commit ee27e5b into main Jun 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants