Hardware hackery and the Dual Shock protocol

The hardware-tinkering mood I’ve been in lately shows no sign of subsiding. The theme this time: Everything over cat5.

Backing up a bit… It’s summer! Hooray. So, how does one make the most of the season without actually doing something crazy like going outdoors? Of course the answer is to play video games in a different room which has more fresh air and a better view of the day-star.

Some people would pick up the Playstation and move it to the other room, but my solution is to run the video over inexpensive cat5 cable. This isn’t a new idea, or even a complicated one, but component-video-over-cat5 baluns still sell for around $80 each! I recently made my own pair out of a couple more altoids tins and some parts from the junk drawer.

These work really well. There is a little bit of ghosting visible on a black screen, but during normal use the quality looks perfect, or at least no worse than the quality of the TV it’s connected to. Unfortunately, and I started testing it with a little Megaman 2 and quickly noticed an unrelated problem: the distance is a little too much for our wireless controllers. Time to build a Playstation-controller-over-cat5 extender.

I can think of three different approaches for building such an extender:

  1. Purely electrical: Each PSX signal gets an RS-422 driver and a separate twisted pair. This is very simple, but it would require two cat5 cables per controller! I want at least two controllers running over a single cable.
  2. Low-level multiplexing: Compress multiple signals onto each twisted pair by multiplexing below the protocol level. This would be bit-for-bit identical to plugging a controller in locally, but it has a few big disadvantages. It requires quite a fast clock on the twisted pair, since it requires several bits of information to be sent for every bit in the original protocol. It also doesn’t add any flexibility. You couldn’t, for example, add a crossbar switch for controllers which could let you switch one controller between multiple video game consoles via a button combination.
  3. High-level multiplexing: The console-end of the link includes an FPGA which fully emulates one or more Dual Shock controllers. The controller-end consists of a microcontroller that polls a bank of controller ports and sends updates over an RS-485 link to the FPGA. This is very powerful, and it’s the method used by my old Unicone (Universal Controller Emulator) project. Unfortunately, it’s also relatively complex and it introduces a few milliseconds of latency.

I’m currently working on (3), but I haven’t ruled out (2) completely. First step, I need to know how to emulate a Dual Shock controller. The internet is full of pages that describe the very basics of the Playstation controller protocol, but I couldn’t find a single document that described the protocol in anywhere near enough detail to emulate a controller properly. Time for some reverse engineering…

This was quite a lot like the job I did a while ago to reverse engineer the Nintendo 64 controller protocol (navi-misc/wasabi/devices/cube64/notes/n64-observations) enough to build a microcontroller that could emulate a controller. Instead of an HP logic analyzer borrowed from work, this time I have a Saxo board from fpga4fun acting as a real-time Playstation packet sniffer. I should be able to use the same packet sniffer setup to finish reverse-engineering the Playstation 2 memory card protocol so that I can add PS2 support to my psxcard USB adaptor. 🙂

A Verilog core to emulate the Dual Shock controller will hopefully be coming up soon. In the mean time, I published my Notes on the Playstation 2 Dual Shock controller protocol. It’s actually surprisingly more complex than I was expecting. There are several backward-compatibility features, two rumble motors (one with 8-bit speed control), analog buttons… The protocol has several features that the Dual Shock controller doesn’t take advantage of, like support for 254 different force-feedback actuators that you can arbitrarily map into your polling packets. Crazy.