The NES pad to XT adapter is a piece of hardware that allows you to interface with a NES pad through the keyboard port of the IBM 5150 PC, 5160 XT or compatibles. It consist of some simple logic to provide the correct signals, and some additional hardware to make it more flexible and userfriendly.
To understand how it works, it's importaint to understand how the keyboard interface of the PC and XT works, in comparasion to how the NES interfaces with the controller pads.
The PC and XT keyboard interface consist of one data line, one clock line, one reset line, and power lines. The data and clock line is open collector (or an equalent system in the form of tristate buffers pulled high by default), so both the lines can be controlled by the external device. However, only the clock line can be run by the computer under CPU controll. The reset line is derived from the CPU reset line, and the power lines comes from the +5V and GND from the posersupply.
The cirquit is based on a 9 bit (actually 8+1 bit) shift register, where an 1 in the ninth bit tiggers IRQ1 and locks up the data line and shift register; indicating that data is ready in the remaining 8 bits of the shift register. This basically means that the transfer protocol is one high start bit followed by 8 data bits. When one byte is successfully received; it can then be read by the CPU through an I/O port, and then the cirquit has to be manually reset by the CPU to allow another byte to be received.
The data line is directly connected to the data input of the shift register, and can't be used for anything else than data input. The clock line is first syncronized to a proccessed version of the CPU clock (4.77MHz), delayed by another tick of the same clock, inverted and forwarded to the shift register. Because of this, toggeling the clock line will make the shift register read data. In other words, data is read by the shift register anything from 210 to 420 nanoseconds after the falling edge of the clock. Because of this, data can be put on the data line at the same time as the clock toggles, as the delay will give the data line enough time to properly settle before it is read by the shift register. In the regular keyboard, both the data and clock line is controlled by a microcontroller in the keyboard itself, and the CPU has to mind the keyboard interface only after input is received.
The NES controller pads works in a sligthly different way. The controller consist of a single 8 bit shift-register (CMOS) and some buttons connected to the parallel inputs of the register. When it reveives a latch signal, the state of the buttons is recorded in the register, and it can then be clocked out one bit at a time (bit changes on the rising edge of the clock). The bits are then read by the CPU in the NES. All of the signals going to the controller is generated by the CPU in the NES.
It is clear that the two interfaces are similar in many ways. First of all, both are based on a serial datastream of 8 bits, which is clocked synchronous to a single clock signal. The only actual difference is the high start-bit in the XT keyboard interface, and the latch signal in the NES controller pad interface. Both of therse has to be generated within the adapter.
The start bit was the easiest addition, as can be added just by running the data through a flip-flop (acting like an 1-bit shift register) which is set simultaneously with the latch signal. This works very well, one of the reasons being that CMOS logics is slower than regular TTL logics. Because of this, the 1-bit shift register will be able to read the data from the adapter before it's 8-bit CMOS shift register shifts.
The latch signal is more difficult to implement, since there are no event that can directly trigger it. Because of this, there exist several posibilities of how it can be generated using the existing data and clock line. The method I chose was to divide the clock signal by 16 using 4 flip-flops, and then using a fifth flip-flop that is reset every clock to make a strobe every 16th clock. This strobe is used as the latch signal.
I also added some smaller parts to make the whole thing usable. This includes a pulldown on the NES controller pad input data line, as this will allow programs to se if a NES controller pad has been connected or not, and I also added an open collector buffer to the output, with nessecary resistors ( and etc.) to make the interface electrically compatible with the keyboard port. I also added enough filtering-capacitors.
Then comes the problem about using the adapter. In the original version, you had to physically unplug the keyboard and plug in the adapter. This turned the keyboard off, and it required a reset in order to work again. This reset could only be achieved by a cold hardware reset; by physically turning the machine off and on again. This was very inconvenient, so I decided to add some switches that assigned only the data and clock lines between the adapter and keyboard. This way the keyboard wouldn't turn off, and no reset was needed in order to restore keyboard operation. I also added a toggle switch that can be used to toggle the clock line of the adapter manually. This can be used by the user to signal the program, and it is required during initialazion as it is the only way to safely define that the clock line is not assigned to the keyboard. Manually toggeling the keyboards clock line while the keyboard is connected to it confuses the keyboard so much that it goes partally crazy, something which is a highly unwanted effect.
The final patch of the adapter was a proper debounce cirquit for the manual clock switch. This included the addition of a new IC, and I decided to use the remaining ports of that IC for LED drivers. The signals monitored by LEDs was decided to be all the clock and data signals, the strobe (latch) signal, and a LED to indicate that power is present. You can download the schematics from the link below.
When I had the schematics for the core logic done, I began thinking about constructing the actual device. I had tested the schematics several times in an emulator with great success, and all I needed was hardware. Thanks to the internet, getting the parts was a trival task, but I have to admit that the shipping itself did sum up to quite a bit (Thanks a lot, Parallax). I have no idea why such a small part can cost $60 USD to ship; most people could have done it for as little as approximately $10 USD.
I did plan to make a dedicated PCB for the design, but that just turned out to cost way too much money. The actual PCB trace-map was successfully made, but that was about it. Because of this, the initial design was put together using a small non-solder breadboard and some wires. This was quite easy and non-problematic, but akward regarding relability and size. It was not userfriendly at all, as it requiered the user to actually unplug the original keyboard and by the fact that a cold reboot is needed to reinitialize the original keyboard afterwards. I also made a (to be polite;) crude and incomplete wooden box for it, just in order to sligthly protect it.
So I decided to improve the design to never actually remove power from the keyboard. I simply placed bi-stable switches on the data and clock line; when the switch is in one position then the keyboard has control over that line, and when it is in the other position the adapter has control. I also added a switch to enable or disable the clock line, or to manually clock it if nessecary. I also decided to assemble it on an actual prototype-board as this would eliminate all the negative effects of the non-solder breadboard. I used the actual planned PCB tracing as source, and the final result ended up more compact than I expected. I can tell as much that it was a real pain in the @rse to solder it all together with the only soldering iron I have available; a low-power old device with a way too big head. If something was wrong, I would have had great difficulties fixing it. Luckily it still worked perfectly fine. I completed the (*Ehm*) wooden "box" and mounted the prototype PCB in there, then I patched up the switches. I also added clamp to the lid in order to keep it shut when it was supposed to be closed. After some months I also decided to give the box a major makeover using only some sandpaper and a wood-file.
Only one thing remained now; a proper debounce cirquit for the manual clock-line toggle. For this I needed to add a buffer, and that buffer had to be schmitt-triggered. Most of those puffers made today will invert the output, which means that I must add an inverter in addition to use those. Since I wanted to keep the part-count low, I decided to get one of the really old ones which did not invert it's outputs. Therse buffers comes in packages of 8 buffers per IC, of wich the debounce logic uses one. The other seven could be used too, for example to drive some LEDs. Thus I added LEDs to indicate the state of the clock and data lines for both the keyboard and adapter, including what was actually seen by the XT. Adding all of this requiered a ton of patchwork, and this in turn caused a lot of fustration and anger. However, after 6 hours of hard work and swearing; the final patch was finished.
To use the adapter in a program that has added support for it, just run the program with the /A parameter. If you just want to run the debug routine, then add the /D parameter in addition to the /A parameter. The program will go through the initialization routine to ensure correct operation. When it does this, always follow the exact instructions as given on the screen.
Using the adapter is simple from a programmers point of view. The adapter has an include file, and all you have to do is to call a routine from the include file toggle the clock line untill data appears. If data don't appear, then there is an error present somewhere or some of the switches are set to the wrong position. If the data is all zeroes, then the NES controller pad is not connected, and if it's all ones, then the pad is connected while no buttons are pressed, or some of the buttons are set to the wrong position, or nothing is connected to the computer's keyboard port. Anything else indicates that a key is pressed on the NES controller pad, or that the switches are set to wrong positions and the keyboard has become confused. You usually don't need to care about any of the erroneous causes, as those are taken care of by the dedicated initialization routine also included in the include file.
For more information on how to add support for the device in your programs, read the information present in the well-documented include file, and have a look at the sample program (the game of Snake, supports both the keyboard and adapter) presented in the link below.
Both of therse videos demostrates the first revision of the hardware, without any posibility to switch between the adapter and XT. I may make a video of the updated version if I get the time.
Demonstration of a prototype of the sample program: the game of "Snake"
Demonstration of an early version of the debug routine