Home > Sinclair BASIC > Using the Kempston Joystick in your own BASIC programs

Using the Kempston Joystick in your own BASIC programs

Traditionally, games in BASIC use the keyboard for player input and act accordingly. For eg, the keys Q, A, O and P may be used to move the player character around and M may be used to fire or other action. However, as anyone who has played ‘professional’ games (i.e written using machine code) on the speccy would know, using a joystick is a far better alternative especially in fast action games.

This article will tell you how to use the popular Kempston Joystick in your games for that ‘professional’ touch. 😉

To begin with, inputs from the Kempston Joystick are read via port 31. The Spectrum manual has more information on what a ‘port’ is and so I won’t be covering it here. Suffice to say, any external device connected to the speccy reads through a specific port, numbered 1 to 255. The Kempston Joystick uses port 31.

To read the ‘value’ in port 31 you simply do: LET kj = IN 31. Depending on what state the joystick is in, kj will hold a very specific value that can be interpreted as desired. Now then, the Kempston joystick  has only 5 states to deal with, namely ‘Fire’ (any of the fire buttons pressed), ‘Up’ (joystick pulled back), ‘Down’ (joystick pushed forward), ‘Left’ (joystick to the left) and ‘Right’ (joystick to the right).

This information is packed into a single byte in the following format: 000FUDLR. As you can see only the lower 5 bits are of interest to us, which means we can ignore any value of kj above 31. Depending on which bit is set (value of 1) we can assume the joystick is in that state. Multiple states are also possible – firing and moving for example, or moving diagonally for example. Obviously you can’t have states of ‘Up’ & ‘Down’ or ‘Left’ & ‘Right’ occurring simultaneously!

The table of basic values that we need to test is given below:

kj (IN 31) Bit pattern (lower 5 bits only) State
1 00001 Right
2 00010 Left
4 00100 Down
8 01000 Up
16 10000 Fire

For the purpose of this tutorial I’m going to ignore multiple directional states because BASIC doesn’t support the kind of bit level manipulation we would like to achieve detection of that. However, it will be useful to detect if we’re firing and moving so that will be on the agenda.

Let’s get the simple detection out of the way first!

10 LET x=10: LET y=10
20 LET kj=IN 31: REM get the state of joystick
30 PRINT AT y,x;"*"
40 IF (kj>31) OR (kj=0) THEN GO TO 20: REM ignore spurious inputs
45 BORDER 1: PRINT AT y,x;" ": REM overwrite at old position
50 IF kj=1 THEN LET x=x+1: REM left
60 IF kj=2 THEN LET x=x-1: REM right
70 IF kj=4 THEN LET y=y+1: REM Down
80 IF kj=8 THEN LET y=y-1: REM Up
90 IF kj=16 THEN BORDER 2: REM Fire
100 GO TO 20

The code is pretty simple. To see it in action we will print an asterisk on the screen that can be moved about by manipulating the joystick. Screen boundaries aren’t checked though to keep the code simple. We’ll also set the border to Red if the fire button is pressed. That’s it really.

To check for the event of fire and moving we’ll have to perform a simple trick. When firing and moving, kj will have bit 5 (for fire) and the bits for movement (any of them from 1 to 4) to be set, leading to a number  that is greater than 16 (since fire by alone is itself 16). So all we do then is check for this fact (kj > 16) and if so, note that the fire is being pressed and then subtract 16 from kj so that we can continue to check for the movement keys as normal.

The above code can be modified so (changed lines in blue):

10 LET x=10: LET y=10
20 LET fire=0: LET kj=IN 31: REM note: reset fire event every time!
30 PRINT AT y,x;"*"
40 IF (kj>31) OR (kj=0) THEN GO TO 20
45 BORDER 1: PRINT AT y,x;" "
46 IF kj>16 THEN LET kj=kj-16: LET fire=1: REM Check if firing AND moving
50 IF kj=1 THEN LET x=x+1
60 IF kj=2 THEN LET x=x-1
70 IF kj=4 THEN LET y=y+1
80 IF kj=8 THEN LET y=y-1
90 IF kj=16 OR fire THEN BORDER 2: REM fire by itself or firing and moving? If so red border
100 GO TO 20

That’s about it really. Doing the above in machine code is, in fact, easier because it has all the necessary operators to perform low level bit manipulation which you really need if you want to check for multiple states of the joystick. However, I believe the above will do very nicely for those BASIC games that do not need diagonal movement!

Experiment and enjoy!

Advertisements
  1. nuc1e0n
    January 6, 2017 at 2:04 am

    Here’s a version that bounds checks the screen coordinates and suports diagonal movement:

    1 LET l=SGN PI: LET n=-l: LET o=NOT PI: LET p=INT PI: LET a=l+l: LET b=a+a: LET c=a+p: LET d=a+c: LET e=d*p: LET f=d+a: LET g=b*b: LET h=VAL “31”: LET j=b*p: DIM t(c): DIM m(c): LET t(l)=l: LET t(a)=a: LET t(p)=b: LET t(b)=b+b: LET t(c)=g: LET x=c+c: LET x2=x: LET y=x: LET y2=x: BORDER l
    2 PRINT AT y,x;” “;AT y2,x2;”*”: LET y=y2: LET x=x2
    3 LET k=IN h: IF k=o OR k>h THEN GO TO p
    4 IF k=g THEN GO TO j
    5 FOR i=c TO l STEP n: IF k>=t(i) THEN LET m(i)=l: LET k=k-t(i): GO TO d
    6 LET m(i)=o
    7 NEXT i: IF m(l) AND xo THEN LET x2=x-l
    9 IF m(p) AND yo THEN LET y2=y-l
    11 GO TO a
    12 REM

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: