snespp
snespp is a FreeBSD kernel module for Super NES/Famicon controllers interfaced via a parallel port. It appears as a keyboard: buttons on the controllers send key strokes to the operating system. snespp works under both the system console and X windows, using the microseq interface to reduce overhead.
The module and source are available under a revised BSD license from here (or on GitHub). It used to be a part of the FreeBSD ports collection (emulators/snespp), but I no longer have the time to maintain it.
SNESPP(4) BSD Kernel Interfaces Manual SNESPP(4)
NAME
snespp -- parallel port interface for Super Nintendo controllers
SYNOPSIS
kldload snespp.ko
DESCRIPTION
The snespp interface communciates with Super Nintendo (SNES) controllers through the parallel port. It presents itself as a keyboard to the rest of the operating system. Buttons pushed on a controller are sent as keys to the system console or X window session. The device file can also be opened and read as a joy(4) joystick. Hardware Interface The controller has 7 pins, of which 5 are used: +---------+------- | P C L D | X X G ) +---------+------- P: power, C: clock, L: latch, D: data, G: ground. The controller contains chips that sample the state of all buttons when latch is asserted. The button states are transmitted serially on the data line in response to pulses on the clock signal. The controller signals may be connected to a parallel port as follows: pin# function controller 2 d0 clock 3 d1 latch 4-9 da2-7 power 16-19 gnd ground 10 nAck data(1) 11 Busy data(3) 12 PaperEnd data(2) 13 Select data(4) 15 nError data(5) The power pins (da2-7) must be connected to the controller via diodes (such as 1N4148), with the cathode (the end with the band) toward the controller. The others may be connected directly. Multiple controllers share signals except for the data lines which are numbered in the table above. The voltage swing of parallel port pins in many laptops is insuf- ficient to trigger a controller. Additional circuitry is required. Communication Protocol The controller state is sampled and communicated in response to the sequence: 1. drive latch high for 12usec, 2. wait 6usec then lower clock, 3. sample data, 4. wait 6usec then raise clock, 5. repeat another 11 times from step 2. The snespp driver implements the sequence using microseq(9). It is repeated every 16.6msec (60Hz) when the driver is active. OS Interface By default the snespp driver registers itself as a keyboard. Make and break events are generated as controller buttons are pushed and released respectively. The table below shows which keys are sent for the first two controllers. button data(1) data(2) B b z Y y c Select p s Start o Enter Up q KP8 Down w KP2 Left e KP4 Right u KP6 A a KP+ X x KP0 L l 1 R r 2 The controller should be automatically attached by kbdmux(4). It is also possible to access the data(1) controller using the interface described in joy(4) by opening and reading from /dev/snespp0. In this case the Y button is treated as button 1 and the B button as button 2. The other buttons are ignored. The driver does not support the Linux joy- stick interface (devel/linux-js).
IMPLEMENTATION
The serial protocol runs over ppbus(4) using efficient microseq(9) sequences. A kernel thread executes the communication protocol at regular intervals. It compares alternating snapshots of the button states to determine which push and release events have occurred. Events are queued into a circular buffer. Every six cycles a taskqueue(9) task is queued to clear the buffer. The buffer clearing task executes the keyboard callback function which polls the keyboard interface for key events. Key events will be lost if the clearing task does not operate frequently enough.
BUGS
Ideally the driver would stop polling the controller when not attached as a keyboard. However, this feature is not currently possible due to a bug in kbdmux(4).
NOTES
By default the snespp driver polls for two controllers. Should more con- trollers be connected the SNESPP_NUM_CONTROLLERS constant in <snespp.h> should be changed and the driver recompiled. The ppbus is held while the driver is active. Thus, the driver should be unloaded before attaching another device to the parallel port.
SEE ALSO
kbdcontrol(1), joy(4), ppbus(4), microseq(9), kbdmux(4). The Jim Christy post to Sci.Electronics.
AUTHORS
Timothy Bourke <tim@tbrk.org> Using protocol and wiring information from several www sites. FreeBSD 6.2 March 25, 2007 FreeBSD 6.2