For Retro Computing Enthusiasts
,

Using Joysticks On The 64: A BASIC Tutorial

By Charles Brannon — originally published in COMPUTE!’s Gazette Volume 1, Issue 1

Taking advantage of the Commodore 64’s fascinating capabilities often involves PEEKs and POKEs which can be confusing at first. This article explains the essentials of using joysticks in your own BASIC programs.

First of all, if you don’t yet own a Commodore joystick, you can use the readily available Atari joysticks, or any Atari-compatible joystick – which gives you quite a choice. A number of “custom” sticks are available from outside companies. (This is fortunate, because Atari recently won a court order blocking Commodore from selling its Atari-lookalike joysticks, so it may be awhile before we see a redesigned model.)

The Inside Story

To really understand joysticks, you have to know how they work. Don’t worry; joysticks are no more complicated than a light switch. In fact, inside the base of the joystick are five switches that act like pushbuttons. When you press the joystick north (up), south (down), east (right), or west (left), or press the joybutton, a switch is closed.

You can also move the stick diagonally (NE, SE, SW, NW). How can four buttons give you eight directions? Simple. The joystick is designed so that diagonal movement closes two switches simultaneously.

Joy Bit

Each switch controls one part of a memory location inside your computer. These are called bits. A bit can hold only two values – either zero or one. Zero normally means nothing, false, empty, off. One means positive, true, on. Although it may seem confusing at first, the joystick bits are reversed. When the joystick is centered (not deflected in any direction), all the bits are “on.” They are all ones. But if you move the joystick up, the “north” bit will become a zero. If you move the joystick diagonally to the lower right, both the “south” and “east” bits will become zeros.

Siliconomics

Joysticks would be easier to use if each direction had its own separate memory location. That way, you could check the north, south, east, west, and joybutton bits separately. But to economize (and you always do when designing microchips, where the cost is more than proportional to the amount of silicon used), all the bits are grouped together into a single memory byte (eight bits = one byte). The bits are ordered like this:

Direction — Value When Off (Zero When On)
North: 1
South: 2
West: 4
East: 8
Button: 16

As we’ll explain shortly, your program will detect which way the joystick is deflected by looking at this byte. The number in the byte will be the sum of all these values. Here’s how it works.

Let’s ignore the joybutton for a moment. If the stick is not moved, the summed value in the byte would be 15 (1 + 2 + 4 + 8 = 15). If the stick were moved up (north), the north value would become zero, and the remaining numbers would add up to 14. If the joystick were moved left (west), the west value would become zero, and the remaining numbers would add up to 11.

The easiest way to use the joystick is to read the memory location with the BASIC command PEEK and use IF/THEN statements to take appropriate actions for each direction. Refer to this diagram:

A series of IF/THEN statements might look like this:

Line 10 reads the value of the joystick byte and keeps it in a variable, V. The number 56321 is the memory location for joystick port #1. PEEK reads this location, but you won’t get just values from 0-15. Other functions are also read here, such as the joybutton. The “AND15” isolates the values we’re looking for by turning off all the other unwanted bits. I won’t explain here why this works – just take my word for it!

Who’s On First?

You can read the second joystick (port #2) by substituting the number 56320 for 56321 in line 10. It might seem logical that the joystick which is read by PEEKing location 56320 should be the “first” joystick, since it has the lower number, but that’s not the way it works. You can’t argue with the lettering on the side of your Commodore 64 which clearly shows which is first and which is second.

Also, you’ll notice that the first joystick will seem to “press” certain keys on your keyboard. This is a hardware anomaly, but you can play some joystick games by pressing keys in the upper left part of your keyboard. It is not a reliable method, however.

Another Way

Although the sample program above will read the joystick, it’s not necessarily the best way. IF/THEN statements are among the slowest statements in BASIC, so if speed is important (as in games), there are better ways to go. Here’s a faster method. Change line 10 to:

10 V=15-(PEEK(56321)AND15)

Now the values returned will be:

Notice that the range is smaller here. You can now use the values as the index to an array. Watch how it works. Let’s shorten the example program:

MESSAGE$ (pronounced “message-string”) is a string array. A string array is a single variable name that holds a whole list of strings (a string is any series of characters). Each string has its own box or place in the array. We address the item in the list by calling its number. The READ loop on line 10 fills the MESSAGE$ array with the ten strings. If we say PRINT MESSAGE$(0) we’ll get “CENTER”. PRINT MESSAGE$(5) gives “NORTHWEST”.

Some of the DATA items are followed by two commas, which are separators. The computer interprets this to mean that between the commas there is a “null” (empty) string. It saves us from having to include items we don’t need (since some of the numbers in the range 0-10 don’t correspond to any joystick direction).

Table Look-Up For Speed

Printing the messages indirectly by using the joystick number is a form of table look-up. Instead of having the computer go through a bunch of IF/THENs, or searching a list for an answer, table look-up is direct and fast. All the answers are already determined. This is especially useful for games, where speed is important. For example, you could use a different character for any direction the player is facing, and put them into an array to be selected by the joystick number.

Tricky Techniques

You can also read the joystick by “masking” (isolating) the bits you are looking for. Remember that each direction has a number associated with it. If we want to check for north, we just check to see if the north bit has turned to zero. If we’re checking for north this way, we’ll capture northeast and northwest as well, which we wouldn’t have caught with a mere IF/THEN statement. Here we’ll “mask” out the north bit:

V=(15-PEEK(56321)AND15) AND 1

If V = 0, the joystick is not deflected north. If V = 1, the joystick is being moved north, northeast, or northwest.

To check for left (west):

V=(15-PEEK(56321)AND15) AND 4

If V = 0, there is no movement to the left. If V = 4 (yes, 4, not 1), then the stick is being pressed left, northwest, or southwest. See how you can separate the original four directions from the eight possible ones?

So, to check for any direction, use:

V=PEEK(15-PEEK(56321)AND15) AND number

V (or whatever variable you use) will be either zero (not deflected) or non-zero (deflected). Substitute 1, 2, 4, or 8 for number (1 = up, 2 = down, 4 = left, 8 = right).

The Joybutton

You can check for the joybutton, also called the fire button or trigger, with:

B1=PEEK(56321)AND16 (for port #1)
B2=PEEK(56320)AND16 (for port #2)

A zero value means the button is pushed. A non-zero value (16) means the button is not pushed. For example, if you are waiting for the user to press the button to begin a game, you could use a loop:

500 IF (PEEK(56321)AND16)<>0 THEN 500

It’s A Natural

Using a joystick in your next game will make it easier to play, since joysticks seem more “natural” than pressing keys on the keyboard. But remember that a joystick is just a tool. It will not move objects around for you – it will just tell you how the user is deflecting the joystick. Watch for future articles on how to achieve joystick-controlled animation.

There are other uses for joysticks besides games. Unlike the keyboard, with its 50-odd keys to deal with, the joystick limits input to just nine possibilities (the eight directions and the joybutton). The joystick can be used to select menu options, answer simple questions (left = no, right = yes), and even enter text (as you do with arcade games when you set the high score). Study the following example program for more ideas.

See program listing on page 125.

Companion disk Companion Disk (.d64)

Enjoyed this? It’s what we do every month.

The revived COMPUTE!’s Gazette brings the spirit of the golden era to today’s retro scene — Commodore, Atari, Amiga, and more, in full-color print and digital every month.