Dump NES ROM using an INLretro programmer-dumper
This guide will walk you through dumping NES cartridges on Linux using an INLretro programmer-dumper from Infinite NES Lives.
Note: this guide was written with Debian-based distros in mind (Ubuntu, etc.). Your mileage may vary with other distros.
Check out my homebrew NES Game project, if that’s also your thing.
Resource | Link | Description |
---|---|---|
INLretro programmer-dumper | link | Hardware |
inlretro | link | Software |
NES Cart Database | link | NES Cart Database |
NES Header Database | link | NES Header Database |
DAT-o-MATIC | link | Database of ROM Checksums |
Prepare INLretro programmer-dumper
This guide will make sure the INLretro programmer-dumper and your Linux user
are both in the plugdev
group with read / write permissions.
When the INLretro programmer-dumper is plugged in, it will appear as a USB device.
$ lsusb
..
Bus 005 Device 005: ID 16c0:05dc Van Ooijen Technische Informatica shared ID for use with libusb
..
The 16c0:05dc
hex values are the vendor and product ID. We’ll take these IDs
and create a udev rule that assigns this specific USB device to the plugdev
group.
Create a file called /etc/udev/rules.d/99-inlretro.rules
with the following contents.
# 05dc is INLretro
# 05df is INLretro in bootloader mode
SUBSYSTEM=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df", GROUP="plugdev"
Tell udev to reload rules.
sudo udevadm control --reload-rules
You’ll need to unplug and plug back in the device for the new rule to take affect.
Use the groups
command to see which groups you are in.
$ groups
kevin adm cdrom sudo dip plugdev
If you don’t see plugdev
, add your user to it with adduser
.
sudo adduser $USER plugdev
You’ll need to log out before the group changes will take affect.
Alternatively, you can use newgrp
to temporarily login to the new group.
However, only that one terminal will be logged in.
newgrp plugdev
Build inlretro
Install dependencies.
sudo apt install build-essential
sudo apt install libusb-1.0-0-dev
Clone the repository.
git clone https://gitlab.com/InfiniteNesLives/INL-retro-progdump.git
Build the inlretro
binary.
cd INL-retro-progdump/host/
make unix
Dump ROM
Use the inlretro
binary to dump the ROM data.
cd INL-retro-progdump/host/
There are a few game / cartridge-specific values you will need to determine, as
inlretro
does not use any database to magically look it up for you.
Look up the game you are dumping on NES Cart Database. You’re looking for:
- PRG ROM size in kilobytes
- CHR ROM size in kilobytes
- Type of mapper
Many games had either the mmc1 or mmc3 mapper. The following mappers are supported by this dumper:
action53,bnrom,cdream,cninja,cnrom,dualport,easynsf,fme7,
mapper30,mmc1,mmc3,mmc4,mmc5,nrom,unrom
Games were released in different regions, different publishers, etc. Be as exacting as you can when looking for your game.
Attach the game cartridge and dump a ROM file.
./inlretro -s scripts/inlretro2.lua -c NES -m <mapper> -x <PRG size> -y <CHR size> -d <output file>
Options used:
-m mapper action53,bnrom,cdream,cninja,cnrom,dualport,easynsf,fme7,
mapper30,mmc1,mmc3,mmc4,mmc5,nrom,unrom
-x size_kbytes size of PRG-ROM in kilobytes
-y size_kbytes size of CHR-ROM in kilobytes
Here’s an example command to dump Tetris (USA) published by Nintendo (not the Tengen version).
./inlretro -s scripts/inlretro2.lua -c NES -m mmc1 -x 32 -y 16 -d Tetris.nes
Verify ROM
Lastly, it’s a good idea to verify the integrity of your ROM data before you declare victory.
There are many online databases which have lists of known good hashes for each game. None of them seem 100% complete or accurate, so you may need to reference multiple. Here are a few good ones:
Lookup the game you backed up and compare the hashes or checksums to your file. MD5 or SHA-1 will do just fine.
The hashes and checksums you’ll find do not include the 16-byte iNES header. So, skip the first 16 bytes of your ROM file:
$ dd if=Tetris.nes bs=1 skip=16 status=none | md5sum
5b0e571558c8c796937b96af469561c6 -
$ dd if=Tetris.nes bs=1 skip=16 status=none | sha1sum
fd9079cb5e8479eb06d93c2ae5175bfce871746a -
Convert iNES Headers to NES 2.0 (optional)
The inlretro
command automatically prepends an iNES
header to the ROM data. However,
this iNES header has a number of shortcomings and has been superceded by the
NES 2.0 header format.
The NES 2.0 format is backwards-compatible with iNES, so it’s purely an upgrade to a superior format, but is optional.
To create a NES 2.0 header, you would take the NES 2.0 XML Database, look-up your ROM file by hash and then build a NES 2.0 header following the NES 2.0 specification.
Luckily, others have already made tools to automate that process.
- Python: NES Header Repair Tool
- Go: NES20Tool
Update Firmware (optional)
You may want to update your firmware to get new features or bug fixes.
There are many versions of the INLretro programmer-dumper, and it matters which you have when you update firmware. Paul from InfiniteNesLives, has a YouTube video where he shows different models.
The official Git repository’s documentation isn’t the best. But, there was a commit in 2019 that made it much easier to update firmware on PCB versions 2.0, 2.1 or 2.0N. Make sure you read this commit message for the details.
These steps are only for PCB versions 2.0, 2.1 or 2.0N.
cd INL-retro-progdump/host/
The PCB version 2.1 has a silkscreen on the bottom of the PCB that says it’s version.
TODO: add picture of board
# PCB version 2.0 or 2.1 (large square PCB with option for 6 connectors):
./inlretro -s scripts\inlretro_inl6fwupdate.lua
# PCB version 2.0N (smaller PCB with NES connector only):
./inlretro -s scripts\inlretro_inlNESfwupdate.lua
Troubleshooting
The mapper, PRG and CHR sizes must be correct for the cartridge you are dumping. Sometimes the ROM database you use may be incorrect. Look up your game in multiple ROM databases to compare and select the best values.
Check out the INL-retro-progdump GitLab repository (link) for more troubleshooting tips.