A Delorean Would be Nice
I’ve always had this feeling that I was born 10 years too late; getting to develop games on the PS2 but totally missing the glory days of other consoles. The NES was always my favourite and it’s pretty awesome to know that there’s a homebrew scene even now. You can even get tutorials! Seems like 10 years doesn’t matter after all. The first thing I wanted to get set up was a real NES pad interfacing with a NES emulator. Turns out there’s a way to do that…
Many Ways In Fact
There’s a great blog post by Eskerda who distills the solutions down into different applications of micro controllers. Having an Arduino Uno to hand made this pretty appealing so I thought I’d have a go. At a high level we need to:
- Using a microcontroller, read the input from a NES pad.
- EITHER using the serial (COM) communication, liase with a program on the machine that reinterprets the data as virtual keyboard inputs.
- OR implement as a USB HID.
(Pretty much variants of this):
Reading the input, and cheating at it
There are a number of resources on getting the input read using a micro controller. Picking one of the most popular resources I dug into an Instructable created by Prodigity. It’s a fantastic resource with example code, explanations on the wiring and most importantly, a completed project represented in images. There were some minor issues in the code but Prodigity was nice enough to let me host a more up to date version on a GitHub Repository. If you choose to tackle it the same way here’s what your NES pad will end up looking like:
The benefit of inserting wires into the controller is that it’s relatively unobtrusive and will still work in as a regular NES input device when you’re finished. To put it another way, this is the best approach without soldering new components in the casing.
An alternative to getting a bit pokey with the wires is to get a control port replacement made, or remove them from a non-functioning NES. I decided to just tidy the wires a bit and hide the complexity in a case.
The science bit
An MIT Paper shows the setup for a NES controller.
There are 3 useable pins and two for power with the rest not attached:
By attaching these 5 pins to the Arduino we can simulate the NES hardware requests:
The NES Controller contains a (4021) 8 Bit Shift Register. Shift Registers are generally used to convert between parallel and serial modes. Here the parallel input from 8 different sensors needs to be processed linearly.
The number of sensors is particularly interesting, if we bitpack the information it will snugly fit into a single byte and make transmission a breeze. What’s even more interesting is that the hardware itself would usually stop up/down and left/right from being pressed at the same time but there’s no reason both those signals need to be mutually exclusive. In fact, in the FCEUX emulator (in my personal opinion, the best NES emulator out there), there is an option to allow just that!
Getting to the code, to query the controller we need to do the following:
initialise byte for state
Send a signal to the latch (locks the input)
for i = 0 to button_count(8) - 1
Query the data pin
Left shift that value by i
Pack that value into a state byte
Send a signal to the pulse/clock
Wait for hardware (12 microseconds)
The one other factor to bear in mind here is that my default all buttons are ‘pulled up’, specifically they register as On/1 when not pressed and Off/0 when pressed. We can wire this up on the Arduino with +5V and GND for the power pins, then using pins 2, 3, 4 for the Latch, Clock and Data.
As it turns out there’s actually a really decent implementation of that logic implemented in the NESpad library. It can be used easily with Arduino to control general electronics projects too.
Using the serial (COM) communication, liase with a program on the target machine
Arduino has a great setup for communicating with a target machine via the “Processing” Language. The Instructable had already taken this in its stride when I initially started emulating the same process. This Processing Application reads the serial inputs using the same library as Arduino, synchronised by the same Baud Rate. Each bit can be logically AND’ed against the relevant button press and re-emitted as a virtual keyboard press to be consumed by the emulator.
Implement as a USB HID
So here’s the pain with the Arduino Uno approach, you can’t just plug it into your machine and have it picked up as a controller without either running a Processing App, or flashing the Arduino to DFU. Here’s where I decided to go off piste a bit. Though the instructions for flashing an Arduino R3 to DFU mode were relatively straightforwards I didn’t want to have to circumvent the architecture of the board. To be honest when my expensive toy needs a new connection, potentially a new resistor soldering and a new firmware installing I’m just not onboard without a massive payoff… not when Arduino already provide two other boards designed to work as USB devices: The Leonardo and the Micro.
The next concern is how to communicate over a complex protocol such as USB. LUFA is a USB framework for AVRs that should allow devices to register as joysticks. In fact that’s what Eskerda says he did, so probably works a treat.
There would be little point in blogging about an identical approach however, so another avenue was needed. Doesn’t Arduino already have USB libraries for keyboard and mouse?
A GitHub Repository belonging to Dominik Blunck uses an Arduino Leonardo and a modified Arduino USB library for a USB Game Controller. This all in turn relies on generic joystick work done by “That Guy” in a blog post where he was using Arduino for MAME input.
Phew! What could go wrong?
So I got a “for Arduino” Leonardo, downloaded Dominik’s code, plugged into the PC and got a USB HID device with the ‘Arduino Leonardo’ identifier! A quick test showed everything working just fine… but then (super minor) tragedy struck. The code explicitly covers common combination cases (e.g. right and B, left and A) instead of covering all 256 logical combinations out of the box and my “down and A” just wasn’t working! I fixed up the code and submitted a Git Pull Request which Dominik hadn’t taken at the time of writing this, but you should be able to grab the code from my fork.
I did get stuck at one point, at an early stage as a programmer you’re trained not to assume operator precedence, generally for readability reasons but also for covering changes to the standard and different orderings in different languages. I’ve always adhered to this apart from lhs/rhs conditional logic (e.g. lhs==rhs). When the Arduino compiler is doing its magic the lhs and rhs aren’t necessarily evaluated separately. This code:
// If my controller data does not have the 4th bit set :)
if((controller_data & B00001000) == 0)
Is definitely not the same as this code:
// If the 4th bit mask is equal to zero, then bitwise AND against 'true'
if(controller_data & B00001000 == 0)
Every day’s a school day! In the case where the first bit was set, a bitwise comparison with true was valid and caused a bit of confusion in my braincage.
To finish off the project I got some old PC Speakers, gutted them and stripped them of their accessories. Almost a perfect fit for the Leonardo, a little glue gun action in there and it seems like a keeper, I can even see the status lights through the hole in the belt. Next stop, NES Homebrew Hamlet!
Does it Work?
This is the tough point. Though it’s quite legal to have a NES emulator it’s quite illegal to posses most ROMs. What I will say is that it works very well with the Nerdy Nights homebrew tutorials. I hear that the minus world in SMB would make a good test, it looks very precise…
NES Emulation With a Real NES Pad
These guys know their stuff. Here are the resources I looked at in the order I bookmarked them, probably the order I read them: