INL: refuse every flash-program opcode — nabu only ever reads carts#30
Merged
Conversation
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.
There was a problem hiding this comment.
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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.