How romhacker infidelity ported the NES Zelda to the Super Nintendo

Using emulator tools, infidelity rebuilt Zelda without its flickering sprites and with new high quality audio support and a laundry list of QoL fixes.

How romhacker infidelity ported the NES Zelda to the Super Nintendo

Last week’s Read Only Memo was stuffed with news, so I ran out of time to include this very cool project and do it justice. So here we go: bonus issue time!!

A little before I figured out I could download emulators on my PC, one of the many Legend of Zelda fansites I visited religiously turned me onto something that felt like a borderline holy object: Zelda Classic, a version of the original Nintendo Entertainment System game I could play on my PC. I remember it being baffling, but forget now if I was savvy enough to figure out exactly what it was: a fan-made port, painstakingly recreated to play near identically to the original game and run on even modest PCs. I may have assumed that it was sanctioned by Nintendo since it was allowed to exist and available as a free download. I’m still surprised dit survived — maybe it was just too old a game, too small potatoes, for Nintendo to bother nuking.

But for a teenager with a budding interest in the history of games older than me and a cringey “Know Your Roots” NES t-shirt ensuring I was really obnoxious about it, Zelda on PC was a treasure. 20 years later, I’m again smitten with a fan-made port of the game, but this one isn’t for the PC — it’s for the Super Nintendo.

There’s real “why the hell not?” energy to spending months porting a game from 1986 to a console that was last hot tech in, like, 1994, which makes it in my opinion the best kind of hobby project. It’s the third such port that romhacker infidelity has made since 2020, after 15 years of modifying NES games.

“I was finally starting to feel that I've done all that I could on the NES since 2005,” infidelity says. After porting Mega Man 2 and Mega Man 4 to the SNES, infidelity’s wife suggested Zelda should be next up, with Tears of the Kingdom on the horizon. So he set out to Super-ify Link’s first adventure.

Here’s what that process looks like at the beginning:

“The Mesen2 debugger shown here is where I'm about to start doing my custom edits,” infidelity says. “I use the memory viewer to add my code in hex, I have the debugger open so I can step through my code one instruction at a time, to see in real time the results, and the Tile Viewer is open so I can see the tiles being inserted.”

Both the NES and SNES are programmed with 6502 Assembly, but there are obviously differences between the two systems that affect how they interface with the hardware. That means infidelity has to open up the game’s code in hex form and figure out what it’s doing on the NES — then figure out how to translate what it’s doing to the SNES:

“I have 2 emulators open. I have the original game running on [NES emulator] FCEUX, with its hex editor open, then I have my empty [Super Famicom ROM] file open in Mesen2, with its hex editor open, and I begin copying what I see on the NES side, and paste/write onto the SNES side. The things that need modification on the SNES side, are things like NMI enable disable, PPU rendering enable disable, background/sprite enable disable, converting NES OAM DMA to SNES OAM, converting NES palettes to get their SNES CGRAM equivalents. In other words, I simply can't transfer perfectly the NES hardware operations, over to the SNES, I need to make modifications and changes on the SNES side.”
(I know there’s a lot of jargon in there, so if you’re really interested in the intricacies of SNES romhacking, here’s some further reading.)
- SNES Assembly language tutorial
- An explainer on NMI (non-mask interrupts)
- What the heck PPU, OAM, and CGRAM are

Why go through all this effort? Well, other than that “Why the hell not?” romhacker ethos, there are some obvious advantages to this sort of port, even when keeping it nearly identical to the original game: The leap from the NES’s 1.79MHz CPU and paltry memory to the SNES’s 3.58MHz and more generous supply of RAM make a big difference.

“The SNES can run in either SlowROM (2.68 MHz), or FastROM (3.58 MHz),” infidelity says. “As of this article, my ports utilize FastROM, and the ports that I have done benefited greatly with the speed performance!” (Check out the May 14 ROM for a bit more detail on SNES fastrom). In practice, the game no longer suffers from slowdown with multiple enemies on screen at once, and the NES’s notorious sprite flickering is also a thing of the past.

Still, there were a lot of problems to solve with the move from one system to the other. As infidelity highlighted in this Twitter thread from May, the SNES’s ability to display 32 sprites per scanline, rather than the NES’s 8, meant that some tricks the original programmers used no longer worked. The wallmaster hands suddenly started clipping through the walls, which required some tricky programming to using a technique called window masking to correct. So while the game is technically functioning differently, you can’t tell while playing.

His style of romhacking doesn’t involve working with a modern, human-readable programming language — all his work is done in hexadecimal, extensively and painstakingly modifying some very low level code. “I don't use, nor know how to use, any kind of assemblers, I do everything through hex editing,” infidelity says:

“I can view the entire original games code, it's not a source file like you would see in an assembler, but I know how to read hex, so I know what is what just by viewing the hex values. It doesn't show what RAM registers are for what, that stuff I need to figure out while I’m debugging the ROM. If there is an NES game that has already been studied and its RAM/ROM locations are noted down, that's very helpful. If not, it's no big deal to me since I can make everything match from the NES to the SNES side of things when I code.

Emulators are a huge factor in getting these ports done. Without Mesen2 & bsnes, I wouldn't have been able to accomplish what I've done. Mesen2 has really helped me with porting, it has an incredible amount of features and gives the user so much information about everything that is happening on the screen & behind the scenes… it even has an event viewer which can simulate an electron beam, showing you exactly where your code is taking place on the screen!”

The Zelda SNES port includes several nice quality of life upgrades from the original game:

  • Much faster screen transitions in the style of A Link to the Past’s
  • Smoother vertical scrolling
  • Swapping inventory items with L/R, without opening the menu
  • Swapping between a bunch of optional color palettes while paused with L/R
  • Access to the save menu from controller 1, by pressing Up+B in menu
  • Instantly filling heart containers instead of slowly one-by-one
  • Less frequent beeping when Link is at low health

Also, one addition that I think is kind of hilarious: infidelity included a deep-cut sound effect from the 1989 animated series that plays whenever Link kills an enemy. Like the last two bullets above, however, it’s optional, and included as a patch you can apply to the game ROM to enable or disable. So if you want to hear that obnoxious beep at its exact original cadence, you’re covered.

Most exciting is that there are two versions of the patch, one of which supports the MSU-1, a custom software SNES coprocessor developed by bsnes emulator author Near. “On certain emulators & flashcarts, you can play CD quality audio in your games” using the MSU-1, infidelity explains. “The reason why my ports have two different soundtrack selections, is that I'm a huge fan of the work Memblers did, writing the [NES] sound emulator for the [SNES]. I've always wanted to hear NES quality music/sfx on the SNES. And it was back in 2020 on snesdev, that users pointed me to his SPC700 [SNES sound chip] player. So I wanted to incorporate that into my ports, because I love the sounds from the NES.”

Essentially, the vanilla version emulates the functioning of the NES sound chip on the SNES, while the MSU-1 version lets you stream in any higher fidelity external .pcm audio files you choose. If you want to play an orchestral version of the Zelda overworld theme or The Day Robert Palins Murdered Me on loop instead of the original midi? Go for it.

Here’s someone playing the MSU-1 version of the port with a custom soundtrack:

One last benefit of the move to the Super Nintendo is its increased fidelity. The NES uses 2 bits per pixel or 2BPP graphics; the minimum on the SNES is 4BPP. "After learning about that I decided to have the background gfx all use 4BPP as well,” infidelity says says. “I decided on that so that if my ports get in the hands of gfx artists, they can beef up these 8-bit games to look 16-bit.”

If someone wants to, then, they could potentially build on top of infidelity’s port to make the original Zelda look more like, say, A Link to the Past, while keeping the gameplay and level design intact. A SNES graphicsified redo won’t be quite as snazzy as a full remake in the Switch Link’s Awakening engine, but it’s probably a lot more likely!

After a few rounds of bugfixes, infidelity’s port is likely finished. You can download it on Archive.org and keep an eye on his Twitter for future updates — including on his next SNES port, which is already underway.