Mapper overrides are a scripting language and system tool built into USB-NES that provides end-users a way to patch in support for new games that otherwise can’t be auto-detected properly by a virgin unit. It also provides a convenient way to experiment with cartridge hardware to potentially develop patches for completely unknown or currently unsupported NES/Famicom boardsets.
This page details the legacy binary override mapper abstracts; the newer text-based scripts are 100% compatible with the documentation here.
Enable the Mapper Override Mode
After updating your USB-NES firmware to version 0.71, In the SETTINGS.TXT file go to the NES_2.0___Enable line and change the value assigned there to 2. Save the file and reset and/or remount the USB-NES drive to the host. In the root directory, this will expose the OVERRIDE.BIN file. Setting values (default_map_index + NES_2.0___Enable – 2) determine the mapper override offset in the file.
Note that you can always revert the USB-NES back to the autodetect mode by resetting the NES_2.0___enable setting back to 0 or 1 and saving the file.



Override Sequence Error Reporting
When the unit is configured to run in the mapper override mode, the DETECT.TXT and/or REPORT.TXT file will either report the override being used by the unit (as it normally does in autodetect mode), or it will report a syntax error indicating the problem with the mapper override abstract code.
Error Code | Meaning |
---|---|
ERR. 0 | Mapper abstract not found / unknown error |
ERR. 1 | Header signature 1 not found |
ERR. 2 | Header signature 2 not found |
ERR. 3 | PRG-ROM size is set to zero |
ERR. 4 | Bad initialization sequence |
ERR. 5 | Bad power-down sequence |
ERR. 6 | Bad PRG bankswitching sequence |
ERR. 7 | Bad CHR bankswitching sequence |
ERR. 8 | Bad SAV bankswitching sequence |
ERR. 9 | Bad TEST sequence |
ERR. 10 | Mapper abstract exceeds limit of OVERRIDE.TXT/BIN file |
The mapper type abstracts have to be defined in a specific format using specific signatures to ensure the overall integrity of the sequence. Moreover, if there is an error, the indexed mapper abstract will be rejected and an error file will be generated. There are 11 possible error types to aid the user in troubleshooting mapper abstract sequences; the following paragraphs fully document the mapper abstracts.

OVERRIDE.BIN File Format

1. MMC1 with 128KB PRG + 128KB CHR + 8KB SAV file + write enable + write protect.
2. MMC3 with 256 KB PRG + 128 KB CHR.
3. UNROM with bankswitching table located at $FFD0.
4. BTTD Group NES-RED-PILL-02 with 512 KB PRG FLASH + 512 KB CHR FLASH.
Each USB-NES mapper descriptor contains one 32-byte header, and can contain additional 32-byte sequences that describe how bank address bits map to hardware registers specific to mapper bankswitching. Up to eight simultaneous mapper abstracts can be defined in a single OVERRIDE.BIN file composed of 512 bytes.
Mapper Abstracts
A mapper abstract is a method of connecting resources on the NES cartridge to the USB file system to provide a seamless data interface. Based on analyzing NES cart boardset tech for over 30 years, we can see the most essential resource abstracts required to describe nearly any NES/Famicom cartridge boardset:
- PRG-ROM bank access
- CHR-ROM bank access
- SAV-RAM bank access (usually on the PRG side)
- PRG bankswitching port access
- CHR bankswitching port access
- SAV bankswitching port access
- Power-up policy (like disable write-protect on the SAV-RAM)
- Shutdown policy (like write protect the SAV-RAM)
- PRG.BIN flash write abstract file
- CHR.BIN flash write abstract file
Mapper Header Descriptor Type
This defines the core layout of a single mapper override type, and indicates what related descriptor sequences are expected to follow.
Offset | Size | Description |
---|---|---|
0x00 | 16 | NES 2.0 spec1,7 |
0x10 | 2 | PRG-ROM bank offset address |
0x12 | 2 | CHR-ROM bank offset address |
0x14 | 2 | PRG-NVRAM bank offset address5,6 |
0x16 | 2 | CHR-NVRAM bank offset address5,6 |
0x18 | 1 | PRG ROM bank address bit count |
0x19 | 1 | CHR ROM bank address bit count |
0x1A | 1 | PRG NVRAM bank address bit count5,6 |
0x1B | 1 | CHR NVRAM bank address bit count5,6 |
0x1C | 1 | Sequence Flags2,8 —- -tsp p: Mapper power-up sequence present s: Mapper shutdown sequence present t: Mapper test sequence present10,11 |
0x1D | 1 | Mode flags MRB- –CP P: Create a PRG-ROM FLASH3 abstraction file PRG.BIN C: Create a CHR-ROM FLASH3 abstraction file CHR.BIN B: Bankswitch helper flag12,13 R: Redirect9,10 CHR-ROM access to PRG-ROM port M: MMC1 mode4 |
0x1E | 2 | End-of-descriptor header signature 2 Always CR+LF = 0x0A0D |
0x20 |
2. These descriptor sequences follow any PRG, CHR & NVRAM sections.
3. Byte program and sector erase protocol as per the SST39SF040 device.
4. Resets the MMC1 on power-up, and automatically serializes writes of bits D0-4 over D0 when A15=1 and D7=0.
5. USB-NES can only support one source of NVRAM and defaults to PRG-NVRAM in a simultaneous use case.
6. Do not use these parameters to describe any FLASH boardset chips (such as for PRG-ROM). Instead, set bit 0 of location 0x1D to create a write-only programming interface abstract file PRG.BIN in the root directory of USB-NES. Likewise, bit 1 can be set to abstract a theoretical CHR.BIN flash device.
7. Location 0x00 – 0x03 contains header signature 1.
8. Sequence order follows bit ordering here starting from the least significant bit.
9. Some newer NES carts have a large amount of CHR-RAM that emulates CHR-ROM after a boot loader loads the CHR graphics from the PRG-ROM after reset. In these cases, there may not be a currently known iNES or NES 2.0 mapper number to describe the PRG-ROM of this cart in its purely accurate state, but the cart can be functionally described as a simpler mapper type (usually MMC3) if the CHR-ROM is deferred to the PRG-ROM using this redirection flag.
10. With firmware version 0.70 or later.
11. Override test sequences are invoked following the completion of all other internal USB-NES auto-detection tests. These test sequences use equality comparisons statements to reject the mapper override selection in short-circuit evaluation style, otherwise this mapper override is used as default by USB-NES to access cart media
12. When the ROM contents are being read by the host, the bankswitch helper sends a bankswitch command to the boardset after every file sector transfer (512 bytes), as opposed to only when the ROM bank window changes (considerably less often). Some mappers require the constant refreshing of bankswitch registers as a copy-protection means when reading the ROM; this helper mechanism provides timely superfluous writes to the boardset during ROM access to more closely simulate operation as on a real console.
13. With firmware version 0.75 or later.
Mapper Sequence Descriptor Type
Following the mapper override header descriptor, any sequences that need to be defined to describe the bankswitching policy for access to PRG-ROM, CHR-ROM, NVRAM, as well as the INIT and SHUTDOWN abstracts are defined using one or more sequences of this descriptor type.
Offset | Size | Description |
---|---|---|
0x00 | 16 | 16-bit address map, MSB first2,6 16 alphanumeric text characters are used to describe the map here. “0”, “1”: map constant data “a” … “z”: map a bank address line (bank_sel)5 “A” … “Z”: map a bank address line plus one3,5 |
0x10 | 1 | Sequence operation “.” read cartridge operation7 “=” read1 + write-back operation “?” compare for equality operation4,5,6 |
0x11 | 8 | 8-bit data map, MSB first2 8 alphanumeric text characters are used to describe the map here. “-“: use original read data1,5 “0”, “1”: map constant binary data “a” … “z”: map a bank address line (bank_sel)5,7 “A” … “Z”: map a bank address line inverted4,5,7 |
0x19 | 1 | Descriptor signature Always = “.” |
0x1A | 3 | Sequence write signature This tag indicates the origin of the ROM cartridge access. “PRG”: CPU bus access “CHR”: PPU bus access (A14-15 ignored) |
0x1D | 1 | Sequence terminator ” “: another descriptor follows in this sequence “!”: last descriptor in this abstraction sequence |
0x1E | 2 | End-of-descriptor signature Always CR+LF = 0x0A0D |
0x20 |
2. “a” … “z” represent the bankswitching address lines used to access additional banks in the memory device, where “a” is the LSB line.
3. For carts that use bus-contention boardsets, occasionally it is necessary to add constant data to the bank select address when the bankswitching table in ROM is not 2n boundary-aligned.
4. With firmware version 0.70 or later.
5. Compare for equality will read the address formed by the 16-bit address map, and compare the data returned with the 8-bit data map excluding any bits where a “-” (dash) is present. If alphabet letters are present in the 16-bit address map or 8-bit data map, those letter variables will be iterated with all possible binary combinations once as a built-in looping function of the compare for equality operation. If the compare operation requires multiple compare iterations, they are evaluated short-circuit style and the loop exits early on the first data mismatch.
6. Compare for equality operations have access to a secret memory map located at PRG address range $0000 – $01FF, outlined later in this documentation.
7. When a read sequence is invoked, bank address lines mapped into the 8-bit data map are loaded with read data.
Mapper Footer Descriptor Type
Immediately following all the mapper sequence descriptors for an override, the footer descriptor may be optionally present to provide a name when reporting on the boardset info.
Offset | Size | Description |
---|---|---|
0x00 | 16 | Mapper override name in text |
0x10 | 12 | Reserved (all bytes = ” “) |
0x1C | 2 | Signature “@!” |
0x1E | 2 | Signature 0x0A0D |
0x20 |
Secret Test Memory Map
This area contains the internally auto-detected mapper header descriptor type of the inserted cartridge boardset in the first 512 bytes starting @ PRG $0000, and can be used as a way for a mapper override test script to identify carts that are detected by USB-NES incorrectly. There is also access to the IRQ flag, VRAM A10 line, and a series of delay macros that permit the generation of semi-precise delays ranging from 1 uS to up to half a second. The secret test memory map is read-only and can only be accessed with compare for equality descriptor sequences.
PRG Address1 | Size | Description |
---|---|---|
0x0000 | 32 | Mapper Header Descriptor Type This auto-generated information can be used by a mapper override test sequence to help detect an incorrectly identified boardset |
0x0020 | 224 | Reserved |
0x0100 | 1 | IRQ Port 000 000i i: Boardset IRQ line (cart pin 15) |
0x0101 | 1 | NTRAM A10 Port 0000 000n n: Boardset NTRAM A10 line (pin 22) |
0x0102 | 14 | Reserved |
0x0110 | 240 | Time Delay Macros dddd ssss (low 8 address bits) dddd: Delay in microseconds (1-15) ssss: Delay left shift bit count (0-15) Access to any of these ports invoke a delay based off the 8-bit address. Note these macros always return 0. |
0x0200 |
Custom Descriptor: Mapper 2 – UNROM Type
On the surface, the UNROM type is one of the simplest mapper types to implement. However, because it is a bus contention mapper type, it is necessary to know where a bankswitching table exists in the ROM before you can dump the game so easily.
In the case that the cart ROM data is unknown or cannot be referenced, the first dump of a cart like this will be wrong because you will have to take an educated guess at where the bankswitch table is. In this case, the banks will be mixed up in some way when read out, so you’ll have to manually identify the address of a parallel bankswitch table being used across ROM banks in the first dump, before subsequent reliable dumps can be easily acquired.
In this case, location $FFD0 is commonly used for bankswitching tables in Konami UNROM games from this era, such as with Top Gun and Double Dribble. However, there is no rule or specification whatsoever that says anything about how or where the developers of bus-contention NES software may allocate these kinds of bankswitching tables, or even if at all. A lot of them however, prefer to put bankswitch tables somewhere in the last 256 bytes of the PRG-ROM bank. Moreover, if the mapper sports any fixed PRG-ROM banks like the UNROM does at CPU address rage $C000-$FFFF, then there is a really high probability you will find a bankswitch table in this address range and won’t need to locate parallel tables used across all the banks either.
Developing a mapper abstract to dump unknown NES carts with bus-contention issues can be a difficult challenge. However if you figure out how to read a cart like this, you can share your OVERRIDE.BIN file with the USB-NES community so they may benefit from your work to read the same games much more easily now.

Note that as no CHR-ROM is defined in this abstract (location 0x05 = 0), the value for the CHR ROM bank address bit count in location 0x19 is ignored.
Offset | Size | Value | Description |
---|---|---|---|
0x04 | 1 | 0x08 | PRG-ROM 16KB chunk count = 128 KB |
0x06 | 1 | 0x20 | Mapper number = 2 |
0x10 | 2 | 0x8000 | PRG-ROM bank offset |
0x18 | 1 | 0x0E | PRG-ROM bank address bit count 214 = 16 KB bank size |
0x20 | 16 | 0xFFDx | Bankswitch table offset Effective target address is: 0xFFD0 + (bank_sel & 7) |
0x30 | 1 | “=” | Indicates a write cycle to be invoked |
0x31 | 8 | “——–“ | Write ROM data unaltered Data at address is read in, and then written back unaltered. This is standard fare for handling all bus-contention mapper types. |
0x3D | 1 | “!” | End of mapper abstraction sequence |

Custom Descriptor: Mapper 1 – MMC1 Type
The MMC1 is second most popular mapper used on NES cart boardsets. The pain dealing with the MMC1 comes in its serial data interface; it only accepts one bit at a time and requires both a bus read cycle and write cycle. Moreover, defining an abstract to program one single 5-bit PRG bankswitching register takes 5 descriptor slots (with at least one bit in the data map marked as “-” to force a read cycle between writes). In retrospect, the OVERRIDE.BIN file has a maximum of 15 sequence descriptor slots available, and so this does not leave enough room to do a full-blown MMC1 mapper abstract implementation.
To solve this problem, the mapper descriptor has a flag in bit 7 of location 0x1D that when set, invokes a mode of serializing the data specified in the sequence descriptors so that one descriptor can now do the work that originally took five. Moreover, this automatic serialization only occurs for write cycles with data bit 7 clear to addresses in the $8000-$FFFF CPU (PRG) address range. Now it is possible to define a full-blown MMC1 abstract using only five additional sequence descriptors: a PRG and CHR bankswitch abstract, as well as a MMC1 mode set and NVRAM enable on power-up sequence and write-protect on power down sequence as well.

Offset | Size | Value | Description |
---|---|---|---|
0x04 | 1 | 0x08 | PRG-ROM 16KB chunk count = 128 KB |
0x05 | 1 | 0x10 | CHR-ROM 8KB chunk count = 128 KB |
0x06 | 1 | 0x12* | Mapper number = 1 *Battery flag set in D1. |
0x0A | 1 | 0x70 | PRG-NVRAM size 2(7+6) = 8 KB |
0x10 | 2 | 0x8000 | PRG-ROM bank offset |
0x12 | 2 | 0x0000 | CHR-ROM bank offset |
0x14 | 2 | 0x6000 | PRG-NVRAM bank offset address |
0x18 | 1 | 0x0E | PRG-ROM bank address bit count 214 = 16 KB bank size |
0x19 | 1 | 0x0D | CHR-ROM bank address bit count 213 = 8 KB bank size |
0x1A | 1 | 0x0D | PRG-NVRAM bank address bit count 213 = 8 KB bank size |
0x1C | 1 | 0x03* | Sequence flags *INIT sequence present *SHUTDOWN sequence present |
0x1D | 1 | 0x80# | Mode flags #MMC1 mode enabled |

Offset | Size | Address | Data | Description |
---|---|---|---|---|
0x20 | 0x20 | 0xE000 | bank_sel & 15 | PRG bankswitch abstract – set PRG bank @ $8000 |
0x40 | 0x20 | 0xA000 | bank_sel << 1 | CHR bankswitch abstract – set CHR bank @ $0000 |
0x60 | 0x40 | 0x8000 0xE000 | 0x0C* 0x00# | Power-up abstract *16 KB PRG-ROM @ $8000 *8KB CHR-ROM @ $0000 #Enable SRAM (D4 = 0) |
0xA0 | 0x20 | 0xE000 | 0x10 | Shutdown abstract – Disable SRAM |
Custom Descriptor: Mapper 4- MMC3 Type
The MMC3 is the most common mapper type and is reasonably easy to implement an abstraction for. There are 2 main registers used for bankswitching on the MMC3 and as such, bankswitch abstracts for both ROM types require two descriptors each.
This MMC3 definition is only a basic type for reading PRG & CHR ROMs; it does not define any NVRAM (location 0x0A = 0), nor include any abstracts to enable the SRAM on the boardset.

Note that as no PRG-NVRAM is defined in this abstract (location 0x0A = 0), the values for the PRG-NVRAM bank offset address (location 0x14) and address bit count (location 0x1A) are ignored.
Offset | Size | Value | Description |
---|---|---|---|
0x04 | 1 | 0x10 | PRG-ROM 16KB chunk count = 256 KB |
0x05 | 1 | 0x10 | CHR-ROM 8KB chunk count = 128 KB |
0x06 | 1 | 0x40 | Mapper number = 4 |
0x10 | 2 | 0x8000 | PRG-ROM bank offset |
0x12 | 2 | 0x0000 | CHR-ROM bank offset |
0x18 | 1 | 0x0D | PRG-ROM bank address bit count 213 = 8 KB bank size |
0x19 | 1 | 0x0B | CHR-ROM bank address bit count 211 = 2 KB bank size |

Offset | Size | Address | Data | Description |
---|---|---|---|---|
0x20 | 0x40 | 0x8000 0x8001 | 0x26 bank_sel | PRG bankswitch abstract – Set 8 KB PRG bank @ $8000 |
0x60 | 0x40 | 0x8000 0x8001 | 0x20 bank_sel << 1 | CHR bankswitch abstract – Set 2 KB CHR bank @ $0000 |
Custom Descriptor: Mapper 30 – FLASH Mode
When mapper 30 is configured to be self-flashable, there is no bus contention issue when writing to the mapper port and thus the requirement for a bankswitching table can be omitted in this mapper definition.
The main notes on this mapper are the UNROM-like characteristics it has; that is having a 16 KB swapable bank and a 16 KB fixed bank. The flashing is permitted only to the first swapable bank, and the bankswitch register can be written via the second fixed bank. In this case, this mapper uses bit 0 in the mode flags to create the PRG.BIN write-only abstraction file in the root directory of USB-NES.

Note that the value in location 0x0A is not checked by USB-NES because the PRG-NVRAM bank address bit count in location 0x1A is set to 0.
Offset | Size | Value | Description |
---|---|---|---|
0x04 | 1 | 0x20 | PRG-ROM 16KB chunk count = 512 KB |
0x06 | 1 | 0xE2* | Lo mapper number *Battery flag set in D1. |
0x07 | 1 | 0x10 | Hi mapper number (0x10 + 0xE) = 30 |
0x0A | 1 | 0xD0 | PRG-NVRAM size 2(13+6) = 512 KB |
0x10 | 2 | 0x8000 | PRG-ROM bank offset |
0x18 | 1 | 0x0E | PRG-ROM bank address bit count 214 = 16 KB bank size |
0x1D | 1 | 0x01# | Mode flags #Create PRG.BIN FLASH abstraction file |

Offset | Size | Address | Data | Description |
---|---|---|---|---|
0x20 | 0x20 | 0xC000 | bank_sel & 31 | PRG bankswitch abstract – Set 16 KB PRG bank @ $8000 |
Custom Descriptor: Mapper 111 – GTROM
GTROM is similar to Mapper 30 with few differences. It moves the bankswitch ports outside the PRG ROM address space so the FLASH chip can be allocated as a full 32 KB bank @ $8000-$FFFF. The main advantage of this comes when flashing the PRG: the flash protocol requires the back-to-back manipulation of fifteen address bits on the PRG-FLASH chip, and all 15 of these address bits are mapped directly to the PRG bank. Moreover, it is not necessary to constantly program the bankswitch register in this case and PRG flashing performance is improved as a result.

Note that the value in location 0x0A is not checked by USB-NES because the PRG-NVRAM bank address bit count in location 0x1A is set to 0.
Offset | Size | Value | Description |
---|---|---|---|
0x04 | 1 | 0x20 | PRG-ROM 16KB chunk count = 512 KB |
0x06 | 1 | 0xF2* | Lo mapper number *Battery flag set in D1. |
0x07 | 1 | 0x60 | Hi mapper number (0x60 + 0xF) = 111 |
0x0A | 1 | 0xD0 | PRG-NVRAM size 2(13+6) = 512 KB |
0x10 | 2 | 0x8000 | PRG-ROM bank offset |
0x18 | 1 | 0x0F | PRG-ROM bank address bit count 215 = 32 KB bank size |
0x1D | 1 | 0x01# | Mode flags #Create PRG.BIN FLASH abstraction file |

Offset | Size | Address | Data | Description |
---|---|---|---|---|
0x20 | 0x20 | 0x5000 | bank_sel & 15 | PRG bankswitch abstract – Set 32 KB PRG bank @ $8000 |