Kevin Smith

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

INLretro programmer-dumper on a desk

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:

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.

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.

Comments

comments powered by Disqus