N64 to Gamecube/Wii Adapter and Hori pad mod
I was asked to produce a Nintendo 64 to Gamecube/Wii adapter for a Hori N64 pad. As well as producing the adapter, I modified the pad to have to independent Z buttons.
|Adapter hardware||Hori controller|
Normally the N64 pad's joystick is mapped to the Gamecube left joystick. The optional shift button swaps it to the Gamecube c-stick when held down.
The N64 controller is automatically calibrated, and then read hundreds of times per second. The time between the last read and sending the data to the Gamecube is always less than 5ms, or 1/200th of second, and is usually much lower. As such, there is no perceptable lag.
(looking at the console, pin 1 marked)
An AVR ATtiny461 microcontroller handles the conversion. A tiny261 would also be fine, as the firmware is only 1246 bytes.
The AVR runs at 15MHz. To run at that speed it must be powered by 5V from the Gamecube. As the Gamecube and N64 data buses use 3.3V signalling, two 1k pull-up resistors attached to the 3.3V supply are used instead of the AVR's internal pull-ups. To control the data lines, the AVR either pulls them low or "lets go" (changes from output low to input without pull-ups mode).
The firmware is written entirely in assembler. Other than the stack, no RAM is used, all variables fit in to the AVR's registers.
The firmware polls the N64 controller until it gets a valid response. It then requests calibration data, stores it enabled interrupts. INT0 is triggered by the Gamecube starting communication on the data line. The main loop continually polls the N64 controller and converts data read from it into the correct format for the Gamecube. The interrupt responds to the Gamecube with this data.
By having the main loop convert the data from the N64 pad to GC format, the design of the interrupt is greatly simplified since all it has to do is send back the pre-formatted data. In actual fact, it does have to do a little bit more than that, such as responding to queries for calibration data, but it does not need to do any processing as such.
The main loop is responsible for turning the rumble motor on and off. It also keeps a count of failed reads from the N64 controller, and if there are more than 20 consecutive failures (because an interrupt happening in the middle of a read can cause a failure occasionally) it assumes the pad is disconnected, so disables the interrupt and starts polling for a valid response and calibration data agin. Turn off the interrupt also makes the pad appear disconnected to the Gamecube.