controller is actually very easy
to connect to a microcontroller — in fact, it behaves
just like a big shift register.
The difference is that it has
separate data in (called Command) and data out (called
Data) lines. When we used the BASIC Stamp SHIFTOUT
and SHIFTIN were used, but this created a problem with
the last bit of data when using an analog controller. What
we ended up doing was synthesizing a routine that could
send and receive bytes at the same time, but in PBASIC,
that’s a little on the slow side. Not so with the SX, in fact,
we now have to consider speed for the other side so that
we don’t do things too quickly.
Figure 1 shows the signal timing and relationships
between the host and the PlayStation controller.
Communication is initiated by bringing the PsxAttn (
attention) pin low. After a 20 microsecond delay, the bits are
clocked in and out, with everything happening based on
the falling edge of the clock signal.
From a programming standpoint, we need to put a bit
(starting with the LSB) on the PsxCmd pin before pulling
the clock line low. After the clock has been pulled low and
we allow a bit of setup time, we can read a bit from the
PsxData pin. We’ll get into the specific code mechanics a
Figure 2 shows the relationship of input and output
bytes. The host transmits $01 (start) and $42 (get data), the
PlayStation controller sends back its type, $5A (ready),
then two (digital controller) or six data bytes (analog
controller). Note that the controller transmits its type while
the host is sending the $42 byte. What we’re going to do as
we develop this program is create a routine that does the
equivalent of SHIFTOUT and SHIFTIN — but at the same
■ FIGURE 2. PSX exchange
SUB 1, 2
SUB 1, 2
SUB 0, 1
Here’s a secret: Only the last two subroutines are
specific to this project; all the others form the core of most
of the serial accessory projects I developed using the SX.
Looking at the code you’ll see that each subroutine has a
name, followed by the keyword SUB, and then information
on parameters used by each subroutine. Notice that not
every subroutine requires parameters sent to it (like
RX_BYTE) and most actually have a variable number of
parameters. WAIT_US (a shell for PAUSEUS), for example,
requires one parameter and can take two.
With the subroutines defined, we can jump into the main
body of the program. As with similar devices, the PlayStation
Helper chip is going to wait on a specific command header
from the host and respond as instructed. We’re going to use
open-baudmode style serial communications with this
product so that it’s compatible with other serial accessories.
By doing that, we could connect this device to a BASIC Stamp
using the same serial line that commands a Parallax Servo
Controller (PSC). With a BASIC Stamp, a PSC, and the
PlayStation Helper you could put together a very cool robot.
The Parallax AppMod
■ FIGURE 3. PSX packet bits
THE TAO OF SX/B
Okay, I know that’s a bit of a cheeky section title, since almost every programming
language can be manipulated in any way by
an experienced programmer. So this is my Tao
of SX/B, at least for serial accessory devices.
Let’s start at the top.
One of the features I like best about SX/B
is the ability to define subroutines with
the SUB keyword. This serves two important
functions: 1) It causes the compiler to create
a jump table that lets us put the subroutine
code anywhere in memory (remember, in the
SX, subroutines usually have to be in the top
half of a code page unless a jump table is
used); and 2) It lets us tell the compiler how
many parameters are used by the subroutine.
This allows the compiler to do syntax checks
on our custom routines — very handy! Here
are the subroutines used in the PlayStation
January 2006 19