Hurray, more hardware projects. This one is a bit esoteric, and probably won't appeal to any but the most dedicated retro gamer.
But that's OK with me.
It started when I was getting frustrated with the quality of gamepads available for DOS games. Analog Joysticks are easy, but quality gamepads are few and far between. I had two criteria for a gamepad:
- It had to have a good D-pad
- It had to support both 2 and 4 button games, with reasonable button arrangements for each
The 'classic' Gravis Gamepad passes on the second point with the 2 to 4 button switch, but fails quite dramatically on the first one. Most other gamepads I looked up mirrored the Gravis pad's four button arrangement, but unfortunately this is absolutely terrible for 2-button games.
So I made an adaptor. I picked the Sega Genesis (3 button) gamepad as my source, because, if you count the start button, it has exactly four buttons. And I recently made my Genesis arcade stick, so I'd like to use that for DOS games too.
This is certainly not a new idea; Retoconnection has a good general topic on adaptors, and epanorama has a great discussion on interfacing with Gameport. While it's possible to make a completely passive adaptor for simpler pads like the master system or Atari/Commodore/etc joysticks, the multiplexer puts a bit of a wrench in the Genesis converter idea.
So I just used a simple microprocessor. I decided on the Arduino Pro Mini (5 V logic version) due to its size and ease of use. The form factor lets me easily incorporate it in my adaptor box once I solder everything together.
The only other concern was simulating the analog axes with the Genesis digital commands. Since PC joysticks typically use a 100 kOhm potentiometer which isn't something I had a direct way to simulate. The original approach was to create a voltage divider to drive either 0 V, 2.5 V or 5 V to the PC... which really didn't work at all. The PC uses a rather different method of reading the potentiometer than a regular ADC, so it completely misinterpreted what I was attempting to send it.
So I needed to make the PC 'look' like it sees either 0 ohms, 50 kOhms or 100 kOhms at will, which required some rewiring of my resistors and an extra discrete line from the CPU. Here's my eventual circuit:
(original Eagle schematic file)
Each axis has a pair of 50 kOhm resistors with a discrete out connected to either the near, middle or far position from the gameport pin. To simulate a specific wiper position, one of the three discretes is configured as an output and drives 5 V/high. The other two discretes are switched to input mode to act as high impedence to avoid affecting the circuit. The end result is the PC sees either 0 ohms, 50 kOhms or 100 kOhms between the port and where the 5V is injected.
For the rest of the wiring, the gameport power powers the Arduino and the downstream Genesis pad, while ground is connected appropriately. Each pin from the Genesis pad is wired directly to a discrete in or out of the Arduino to be read, or in the case of the mux, periodically toggled. Similarly, four discretes are used to drive the four gameport buttons (A0-A3 lines in my setup).
Coding is dead simple: read half of the genesis directions/buttons; switch the mux and wait for them to settle, then read the other half. Then drive the gameport to match, and repeat. Here is the Arduino project code if anyone is curious.
Yes, I need to pick up more flexable wiring...