Jaguar USB Tap: Wrapup
Busy month, but I'm elated to have, finally, nailed down the hardware design and have working firmware!
A few words on USB ...
In ye olde' days, such as when the Jaguar was developed, connections with the outside world were often turn-key and very simple. On the Jaguar controller, a selection of pins are used as address selectors and each data pin is tested in turn. Easy to code for and cheap hardware to build, little more than latches and diodes. However, such interfaces are not portable and there's no connector on a modern PC which could be contrived to be made compatible with such a scheme (maybe the old parallel port with a suitable breakout?). USB seeks to solve this problem by being the Ultimate Protocol, fully configrable and compatable with any imaginable use-case, from gamepads to webcams. Normally, I'd regard such ambitious goals as unrealistic and error prone. If you recall the early days of USB, and the extremely buggy drivers stacks of the time, this concern was clearly warranted. Having said that, something about the scheme works as over a decade later it's become a ubiquitous standard that actually kind of works.
Being every solution to every problem means that USB is huge. It takes a surprising amount of processing power to drive even a simple USB connection and the description of the specification itself is voluminous, a >100MB download. All this to say that almost all the code, and almost all the processing power, in the Jaguar USB Tap is devoted just to the task of driving USB. I don't know if it's progress, but the scope of it leaves me awed.
The Jag stuff
This was the easy part: all I needed to do is continually poll the Jaguar controller pins and check for changes in state from the previous check. Something like:
for (all buttons): if (this button's address not set) { set the pins for this button's address } read some pins if (these pins are different from the last time I checked) { print readout on the UART send a USB message }
The USB stuff is a bit convoluted, but essentially I send a table of data:
USAGE_PAGE (Generic Desktop)USAGE (Gamepad)USAGE_PAGE (Button)[... 17 one-bit states for all the buttons ...][... followed by 7 bits of padding as USB frames must be byte aligned ...]USAGE_PAGE[... Two axis, one byte each, for the D-pad ...]END_COLLECTION
Even though the D-pad is made out of digital buttons I still treat it as if it were a piece of analog data. This follows a convention in USB gamepads to distinguish direction from action buttons, but the uC also has the ability to read analog values. Maybe one day I can get my hands on a rotary modded controller and will be able to support Tempest 2K as Jeff Minter intended.
One last thing ...
USB devices use unique vendor ID (VID) and product ID (PID) codes to identify themselves and to prevent driver collision. This is a reasonable thing to do but it costs $5000 to register a VID! Very hostile to small businesses and community projects. Fortunately, one very gracious small-business has gifted their VID for community usage and unique PIDs can be requested from http://pid.codes for hobby scaled projects. I've made a request and, if I get the PID, can embed it into the firmware going forward.
Wrapup
I can now play Jaguar games with the control scheme the original developers intended, and enjoy a speed advantage where emulation performs better than a real console (granted, the opposite is the case for most games. Emulation is hard so I really appreciate the work that's gone into virtualjaguar. Thanks, guys!). I've also grown quite fond of the controller itself. The groves on the back allow it to sit comfortably and I don't find myself cramping my hands to reach all the controls so it makes a pretty decent controller for other consoles too. The Mega Drive is a particularly nice fit as it shares the D-pad + three primary action button layout.
0 Comments
Recommended Comments
There are no comments to display.