Writing an NES emulator in Swift

A project I don’t suspect I’ll complete 🫣

I bought myself an Anbernic RG35XX Plus late last year and I’ve been enjoying going back and experiencing some of the video game history I missed when I was a kid. (My parents allowed computer use, but no game consoles!) I’ve primarily been playing old Nintendo stuff – some NES games like Super Mario Bros and a fan translation of the original Japanese Fire Emblem game, some SNES stuff (I played Chrono Trigger for the very first time this year, and wow is that a great game!), Pokemon Blue on Game Boy, and so on.

I’ve had a very (very) rough idea of how some of these systems worked, having seen videos about background vs sprite planes on NES and mode 7 on SNES. I even made a basic ROM hack of Dr Mario for my wife that replaced the “Dr Mario” graphic with “Dr Jason” and gave Mario myself a beard instead of a moustache.

On a lark a few days ago, I decided to try my hand at writing an NES emulator. I’ve never implemented anything approaching a virtual machine, and I thought it would be an interesting challenge to do it in Swift, given that most emulators tend to be written in C or C++. I found a good (albeit not comprehensive) series of videos on YouTube of someone building a basic emulator in C++, which gave me an overview of the system and a basis to get started, and I went off to the races!

Things will eventually get very complicated, but for now I just set up a bus with a CPU and some RAM on it, and I’ve been implementing all of the CPU instructions.

It’s obvious in retrospect, but I’d never considered that many instructions have more than one matching opcode! Each specifies a different way of reading or writing the data that the instruction operates on. There are several of these addressing modes, from using absolute raw addresses (Absolute) to indexing into a table of pointers and following the pointer to another memory location ((Indirect,X)). Each is relatively straightforward but some have easy-to-miss requirements like taking an extra clock cycle if an indexed address is in a different memory page than the base address.

I’m a little over half-way through all of the instructions, and looking forward to attaching more devices to the bus later like the cartridge, before tackling more difficult things like implementing the PPU, the chip that displays things on the screen. Interesting times ahead!

The code (such as it is) is on Github if you’re interested in following along.


To respond on your own website, enter the URL of your response which should contain a link to this post's permalink URL. (Learn More)

Likes

Mentions

Mentions

  • Jason Sadler