N64 Controller Serial Protocol Analyzer
“Gamecube Hacking. • 4 “serial” controllers (N64-compatible). Game controller interface serial proprietary digital pixeldata output SDRAM. HHD Software Serial Monitor/Sniffer/Protocol Analyzer User Testimonials.
May 1st I decided I wanted to tackle a big project. I wanted to do something that no one had attempted before and was beyond my current skill set. I had seen numerous inquiries on the forums from people who wanted to know how hard it was to use “X” controller with the Xbox 360. It always boggles my mind how little people know about this stuff and how 90% of the time they simply assume they can just cut the connector off of any cable, twist some wires together and call it a day.
I wanted to do something to show everyone that these things were not impossible, nor were they that simple. I eventually decided to build an adapter that would allow me to use a Sega Saturn controller on the Xbox 360. I chose the Saturn controller because the data protocol seemed simple and straight forward but complex enough that the circuit design would be interesting and challenging. I assumed that the converted output from the circuit would work easily with the Xbox 360 controller without any major problems, that turned out to not be the case.
I started off under the assumption that since the data from the Saturn controller was a simply multiplexed across four channels I could use some demultiplexers and get some good results. I didn’t know much about multiplexers/demultiplexer and as it turns out they don’t work the way I thought they did. So this didn’t work out. After the false start with the multiplexer I went back to the drawing board and started researching microcontrollers. I had limited experience with microcontrollers in the past but I knew enough that I knew it would work and that I would be able to figure out how to make it work. I eventually decided to go with a Microchip PIC solution using the PICkit2 and its included microcontroller. The first test was successful.
After that I did a simple test to interface the microcontroller output to the Xbox 360 controller using transistors. This test was also a success. I had to actually use the guts of an Xbox 360 controller for communication between the console and the Saturn controller due to Microsoft’s security system. All major peripherals, especially the wireless ones have their communications encrypted and require a special chip sold only from Microsoft.
This is also the reason no 3rd party wireless controllers have become available yet. Once I scaled the transistor solution across all of the buttons I soon learned that the transistors would not work as anticipated. While my prior test had seemed to work, it had some side effects that were not immediately apparent. I rebuild the whole section of the circuit between the controller and the microcontroller and I ran a ribbon cable from the controller to the bread board just for my own piece of mind.
This actually worked great but I was having the occasional voltage problems since the circuit was so large and drawing so much power. The power issues were worked out by simply adding more batteries. This ended up being the final version of the adapter. There were a few loose ends that I never tied up but I had met the goals that I had set out to achieve.
I showed that controller adapters were possible albeit not easy either. To my Surprise this project caught the attention of A LOT of gaming news organizations. The one I am most proud of however is an interview I had with Official Xbox Magazine in the UK.
I got two whole pages dedicated to the interview and pictures as well as a teaser blurb on the front cover and main index. It has since been sans pictures. Here is a link list of all the other websites that covered it: • • • • • • • • • • • • • • • • • If you know of other news sites or corners of the web that ran an article or had some comments on it, let me know.
If you’re interested in the more technical side of the project can be found on the Xbox-Scene forums. There is also a with all the important bits in one place. Another interesting bit is a fellow by the name of SaturnAR posted with some in-depth which is well worth reading and he remains the only source of this info that I’ve ever seen. Hey This could be a real challenge for youbut had you thought about the possibility of making the controller completely wireless? With the Saturn 3D Analogue pad you couldif you could figure out the interface on it.
The lead clips off, so you could make a clip on wireless XBox 360 adaptor with a battery case and XBox Guide button on it, and you would have the ultimate controller! It wouldn’t require modifying the Saturn controller, just a clip on attachment. I wonder how small you could make it! I remember you originally were thinking about extending the project to include other retro console controllers so I keep coming back here to check on further developments. I finally decided to register just so I could ask you to pick this project back up! It’s just such a great idea for 360 and PC gamers – everyone salivated and you got a lot of buzz for it.
It’s really amazing compared to most hack jobs but that also makes it a little difficult for the average hobbyist. I *really* want one of course but totally lack the experience to make it – do you know if someone picked up this project or if I could find someone to build one for me at a reasonable price?
To my knowledge no one else picked it up, which is unfortunate. One interesting thing though is that one of the “teams” who modify controllers for macro functionality was able to control the buttons directly with their chip, as opposed to using an external switch. This ability would open the potential for a circuit about 1/8th the size, small enough to fit inside the controller entirely. Unfortunately they never released their code, and I don’t have an O-scope so without one I cant determine HOW to control the pins directly. (without an o-scope it’s analogous to a blind and deaf man trying to teach himself Japanese). I did originally plan to branch out into other classic consoles. Right now though I’ve got a few dozen other major projects going, and I don’t really have the tools at my disposal that would make continuing with this one fun or fruitful.
If I had access to a high powered o-scope I could figure out how the controller actually works, and from there I could develop a more advanced version of this that would be easy enough for me to sell. Really I only ever did this project because everyone kept asking stupid questions about controller adapting and not listening to the answers I gave them at least I never see any stupid questions getting posted anymore. Quote: “This ability would open the potential for a circuit about 1/8th the size, small enough to fit inside the controller entirely.” Wow, that would be amazing!
You could just make adapters that hook directly to the modded XBox controller for virtually any kind of console controller. Sorry but I think I just came a little 🙂 Thanks for whetting my appetite and then denying me food! Please keep this project in mind for the future because the potential is crazy!
Due to the 360’s security restrictions, I really like the idea of creating a standard interface allowing people to interface with the 360 controller. This would be really great! The official accessory port would be cool, I believe it’s just a USB port though Of course it’s not publicly documented anywhere and I don’t have the tools to make it happen. This should make you happy though I’ve contacted the guys behind the acid mods controller hack to see if I could figure out how they’re talking with the 360 controller to see if it’s any different, the rapid fire controller uses transistors, I tried transistors early on but had problems with cross-talk, they use them in a slightly different way than I did, but hopefully I can find some time to talk to the guys behind the spitfire mod (they’re willing to talk but we’re playing phone tag) and figure out if that system is any different and if it would be of any benefit to this mod. I also looked into a low pin count connector the idea of using a 4 segment 3.5mm jack as a mini-serial port would work well for this. Essentially I’d have a small circuit inside the controller that would output to what looks like a headphone jack and then the actual adapters can plug into that 😀 depending on the info I get from the spit fire guys will determine if I re-open this project or not basically it comes down to this: If I can streamline it enough that I can make it self contained and of simple enough construction that I can build and sell a few of them then I will open it if I can’t make it sell-able than it’s staying right where it is. This is *great* news (potentially)!
Taking preorders yet? П™‚ Wouldn’t it be possible (with these design changes) to power the adapters from the controller’s batterypack? I suppose the expansion port (since it is USB) could be used for this or perhaps easier for the user if a single connector with more pins is used? Just food for thought. In case you are curious, there is work being done with the chatpad that might be interesting: Well, you’ve made my weekend – I hope your discussion goes well! Sorry for the link dump, but you may also be interested in the Universal PCB project: It allows arcade controls to be adapted to virtually any console system.
He made some interesting design choices that you may consider. By using a connector with more pins than necessary, he can “autodetect” the console system attached (because each console cable has a specific configuration of empty pins). If you are considering making this project expandable to other controllers in the future (fingers crossed) this may be an interesting way to go. For example, you could create a single adapter that plugs into your modded xbox controller (low pin count). The user could buy/make cables to connect their favorite gamepads to the adapter (high pin count).
The firmware could automatically determine what type of controller was attached and make the proper signal conversion. So support for new controllers could be added over time through firmware updates and new cable designs. This would be insanely awesome. The creator of the Universal PCB knows a great deal about the signal protocols of most major console controllers – his source code may be helpful if you ever go down that road. Woah, I set my mind the other day on trying to make an adapter to use my Saturn pad on my original xbox. After studying it a little i came with the idea of using a chip that does the opposite of the one in the saturn controller (demultiplexer ive since learned).
I started searching on the subject and I stumble on this page. Seems its all been tried already and is WAY more complicated than i ever expected lol. I salute Twistedsymphony for all this great work but i no longer feel like i am up to that at this point.
Makes me feel like studying electronics to get better at it though. Hey twistedsymphony, long time no see (XS).
For whatever reason here lately, I’ve been tinkering around with different controller protocols. The Sony neGcon then PSX controllers first, then the N64 controller (what a timing witch) and then I remembered the work you did on this thing here.
I don’t really get assembly at all, and what I know about C could probably fill a thimble, but I’ve been messing with it for awhile now anyway. I had the original Saturn 6 button pad working after a little bit, but wasn’t really content with that, so I moved on to the 3D controller. Which started off being a real PITA, until I put the parking brake on. The PIC can run much faster and miss, skip and just plain get all kind of things wrong, so after I drilled it way back to timings closer to how it actually ‘talks’ to the Saturn it was just one step after another then.
The 6 button pad can take being run a whole lot faster, but the 3D pad doesn’t like that one bit. The first 5 pics and vid are of the work I just did. The rest are from close to 3 years ago when I decided to open one up and poke around in there with a scope to see what was going on. The 3D controller uses Hall Sensors on the ‘Stick’ and L/R Triggers, as does it’s successor the Dreamcast controller, but only the ‘Stick’ is Analog on the 3D, while the DC had Analog triggers as well. Anyway, figured this was about the best place to post this since you already cracked open the door here. I’m actually curious about this one myself, and if the thing wasn’t so crazy expensive I’d already have one here connected up to see what is different there. I know the way the Twin Stick works in game differs from when the Digital pad is used, D-pad up moves forward while on the TS both sticks have to be moved up, so it must be reporting as some other type of controller when it’s plugged in.
My guess would be it reports as an Analog stick there, and just uses fixed values for the movements, 255, 128, and 0 in there when the sticks are moved for one direction, center and the other direction. The 3D controller does something like this for the L and R Triggers when it’s in the Analog mode.
Even though they aren’t Analog, they each have a full Byte for it, but unpressed the values read as 0, and pressed they are 255, but there’s no middle ground there at all on them as the controller isn’t made for it. If you, or anyone that happens across this, has a Twin Stick and VO game that’s just sitting around, or is also curious about how it works, I wouldn’t mind borrowing it for a few days and seeing what it looks like on the Logic Analyzer. No screw would be touched on it at all, unless I have permission to open it up fro pics and a look see, but it’s all done using an extension cable I tap into so the thing wouldn’t be ‘violated’ in any way.
I have a few old N64 controllers lying around and figured that it would be pretty cool to use them to control other things. In this article I will describe in detail every step I took to achieve this. I've used a PIC microcontroller, but it should not be too hard to port the code to any other architecture.
Connector The N64 controller has three connections. From right to left with the round side up: Ground, Data and VCC ( 3.3V). Just plug some cables in the holes and you're ready to go. Hardware The circuit I created for reading out the controller is shown in the schematic below. It is based around a PIC18F2550.
I chose a pic from the 18F range, because I am interested in the USB capabilities, as I might try to use the N64 controller with a computer some day (future article maybe?). I did however limit my oscillator frequency to 20 MHz, so that everything should work on a 16F pic as well if you don't need USB. I've connected three LED's to RB5, RB4 and RB3. They will provide some visual feedback so we can see if everything works properly.
A 3.3V voltage regulator provides the voltage for the board. The maximum voltage the N64 controller can handle is 3.6V, so don't exceed that. If you use 5V you will risk frying your controller. The N64 controller is connected to the board with a simple screw connector. Here the supply voltage is given, and the data pin is connected to the RB7 pin of the PIC18F2550. I've also connected a header (JP1) for the. This allows me to program the PIC without having to take it out of the circuit ().
At the moment it also provides the supply voltage to the board because I am to lazy to find a good power supply. Make sure you set the PICKit to 3.3V instead of the default 5V for the reason I mentioned earlier. The image below shows the fully built circuit built on perfboard. Sap Press Books Download Free. The rectangular thing to the right of the microcontroller is a wireless RF transmitter. I will talk about this in a next article, but it is of no importance to us now. Interface Now we're going to take a quick look at the communication with the Nintendo 64 controller.
The interface looks a little bit like, but is still different. It's a serial interface, which means that all the signals discussed here, will take place on one pin: the DATA (middle) pin of the connector (white wire in the pictures above). Signal Shapes The signal shapes used by the N64 controller for one and zero are shown below. As you can see these signals are very fast with a period of 4 uS and a resolution of 1 us! On a PIC microcontroller, one instruction cycle equals 4 oscillator cycles, which means that with a 20 MHz oscillator, 1 uS takes only 5 instruction cycles! To generate these signals, we will need a like assembly, as C just won't cut it. I will give as much information as needed, so if this is your first experience with assembly, you will be able to follow easily.
A good reference for the PIC instruction set can be found here:. Zero One movlw 0x00 movwf PORTB nop nop nop nop nop nop nop nop nop nop nop nop nop movlw 0x80 movwf PORTB nop nop nop 5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 2 3 4 movlw 0x00 movwf PORTB nop nop nop movlw 0x80 movwf PORTB nop nop nop nop nop nop nop nop nop nop nop nop nop 15 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Below both signal shapes I have included a very simple program to generate the signal in asm (of course there are other possibilities e.g. With bsf and bcf). There are only three different instructions used: • movlw: place the value that you indicate in the W register. • movwf: place the value that is currently in the W register, in the register that you indicate.
• nop: do nothing. It's easy to see that a combo of movlw with movwf can set a pin by modifying the PORTB register. As our N64 controller is connected to pin RB7, we set this pin high by sending the binary signal 0b10000000 to PORTB, which is 0x80 in hexadecimals. Ofcouse sending 0x00 makes the pin 0. All three instructions we used take 1 instruction cycle (check the PIC 18F instruction set ). This means that it is very easy to count every step. As I said previously: 1 uS takes 5 instruction cycles.
That means that, to generate a zero, we have to set pin RB7 low, wait for 15 instructions, and then set it high for 5 instructions. I have counted and indicated the instructions that the pin is high with a bold font, and the instructions that it is low with a gray font. You have to think about these code blocks as if a lot of them are cascaded after each other, so that the first instruction of every code block, is actually the last instruction of the previous block. This will make the timing exact. Of course this code will only work with an oscillator frequency of 20 MHz on a PIC microcontroller.
If you have another oscillator you can easily calculate how many instruction cycles you need for 1 uS though. If you are using another architecture (AVR, ARM.) you have to figure out how many oscillator cycles one instruction takes first (it is usually less than 4, which makes it easier to use C on those architectures). Controller Data The N64 controller data consists of a 32 bit (4 bytes), which gives you the status (on/off) of all buttons and the joystick position (2 bytes) and one stop bit. The array is built up like this: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-23 24-31 32 A B Z Start Up Down Left Right / / L R C-Up C-Down C-Left C-Right X-Axis Y-Axis Stop bit (1) e.g.
If the Z button is pressed, the 3th element of this array will read one etc. The position of the joystick can be determined from the two bytes given by 'X-Axis' and 'Y-Axis'. Polling Signal To receive the data array from the controller, a polling signal has to be sent first. This signal is: 0b000000011 (9 bits). After this signal is sent, the controller will respond with the 33 bit array (4 bytes + stop bit).
This is shown in the picture below. The B-button is pushed so the second bit of the response is 1. The assembly code used to generate the polling signal is shown below.
Instead of copy pasting 7 zero blocks and 2 one blocks from above (which would work perfectly). I used the decfsz (decrement file, skip if zero) instruction to create loops. This instruction will decrement the register you indicate, and skip the next instruction if this register becomes zero.
It takes two instruction cycles if it skips, else one! The registers d1, d2 and d3 can be defined in the beginning of the program using a cblock. After the decfsz instruction there is a goto instruction, which will move the program counter to the instruction after the word that you have indicated. It should be clear to see how a combo of these two instructions create a loop. All instructions use one instruction cycle (4 oscillator cycles), except for: goto, which uses 2 instruction cycles. Of course decfsz also takes two instruction cycles when it skips, as mentioned earlier. Its not so hard to distinguish the two code blocks we saw earlier, only this time I tried to make them a little shorter by replacing some of the nop's with loops (zeroloop, oneloop).
If you take the time to count the instruction cycles carefully for each loop (which I strongly recommend), you will see that there would be no difference if we would copy paste 7 zero's and 2 one's from the previous code. Bcf TRISB, 7; make RB7 output; 0b000000011 movlw 0x07; number of zeros that need to be sent movwf d2 movlw 0x02; number of ones that need to be sent movwf d3 zero movlw 0x00 movwf PORTB movlw 0x03 movwf d1 zeroloop; 3 instruction cycles * 3 = 9 decfsz d1, f goto zeroloop nop nop movlw 0x80 movwf PORTB decfsz d2 goto zero one movlw 0x00 movwf PORTB nop nop nop movlw 0x80 movwf PORTB movlw 0x02 movwf d1 oneloop; 4 instruction cycles * 2 = 8 nop decfsz d1, f goto oneloop decfsz d3 goto one note: the pin RB7 is set to function as an output pin by setting the TRISB register (duh!). In the image below you can see a picture of an oscilloscope measuring the polling signal generated with the code above. You can clearly see the signal 0b00000011. This is a close up of the 7th (0) and 8th (1) bit of the polling signal. The timebase is set to 1 uS. As you can see, the signal is extremely correct.
If you now connect the N64 controller, you should see that it responds immediately after the polling signal was sent. I have shown this in the pictures below. In the second picture the B button is pressed, so you can see that the second bit of the response is a 1.
Once you attach the controller, the signal wil deform because of its impedance. This is normal and not really a problem for us.
Reading The Controller Data Now we succeeded in triggering the Nintendo 64 controller so that it sends its data, we have to find a way to read & store this data properly. The easiest way to do this, is to wait until the middle of the signal (approx 2 uS) and then see if it is one or zero with the btfss (bit file, skip if set) instruction. This instruction will check the bit you indicate (e.g. 'PORTB, 7' ->7th bit of the PORTB register) and then skip the next instruction if this bit is one.
It will take one instruction cycle, except if it skips when it will take 2 instruction cycles (it compensates automatically for the skipped instruction - nice!). Of course, we have to switch the RB7 pin to an intput now by setting it to 1 in the TRISB register.
Microsoft Speech Voices Download Windows 7 more. Once we know if the bit was a 0 or a 1, we can store this somewhere in the RAM by using. The INDF0 register contains the value of the register pointed to by FSR0L, so if we increment FSR0L, we go to the next adress etc. We can now read and store all values, so we will do this 33 times as there are 33 bits in the N64 array (see higher). Movlw 0x22; 0x21 = 33 bits movwf d4; contains the number of buttons movlw 0x20; set up the array adress for indirect adressing movwf FSR0L bsf TRISB, 7; RB7 as input readLoop; read all 33 bits and store them on locations 0x20 etc.
Nop; Wait nop nop nop nop nop nop movlw 0xFF; if bit is one btfss PORTB, 7; read the bit (9th instruction) movlw 0x00; if bit is zero movwf INDF0; Wait & store the value of the bit in the array incf FSR0L; Go to next adres in the array nop nop nop nop nop decfsz d4; end loop if all 33 bits are read goto readLoop note 1: the syntax for indirect addressing is a little bit different on 16F architectures. They use FSR and INDF. Note 2: this is definitely not the best way to read out a serial signal. A better way would be to re-sync the signal after every bit, by searching for a rising edge and then falling edge. This way you know for sure that you are at the beginning of the pulse form.
I have tried to do this, but it seemed impossible with the slow pic (4 oscillator cycles / instruction cycle). You might succeed with this approach on an AVR though (1 oscillator cycle / instruction). Please let me know if you find a cleaner way! (This works perfectly though.) The Full Assembly (ASM) program The full assembly program is given below.
It blinks the leds RB3, RB4 and RB5 respectively when the buttons A, B & Z are pressed. I made use of the mpasm (v5.46) compiler which comes with the MPLAB X IDE. It's probably pretty easy to figure out what everything does if you look up the instructions on the I referred to earlier, so I won't go into detail here. #include CONFIG WDT = OFF; disable watchdog timer CONFIG FOSC = HS; Oscillator crystal of 20MHz!