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)


     snespp -- parallel port interface for Super Nintendo controllers


     kldload snespp.ko


     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
           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

           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).


     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.


     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).


     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.


     kbdcontrol(1), joy(4), ppbus(4), microseq(9), kbdmux(4).

     The Jim Christy post to Sci.Electronics.


     Timothy Bourke <>

     Using protocol and wiring information from several www sites.

FreeBSD 6.2                     March 25, 2007                     FreeBSD 6.2