Skip to content

Sticks and keys

INPUT stops and waits for a whole line. A game can't do that. These are the statements that read the controls without stopping.

INKEY

INKEY gives you the code of a key being held right now, or 0 if none. It does not wait:

10 K = INKEY
20 IF K = 0 THEN 10
30 PRINT "YOU PRESSED "; CHR$(K)

Those three lines are the "press any key" pattern, and line 20 is doing all the waiting. Leave it out and the program blinks past before anyone's touched anything.

The important part is what it lets you do instead of waiting:

10 K = INKEY
20 IF K = 65 THEN X = X - 1
30 IF K = 68 THEN X = X + 1
40 REM ... AND THE GAME CARRIES ON EITHER WAY
50 GOTO 10
basic
10 PRINT "PRESS FIVE KEYS"
20 FOR N = 1 TO 5
30 K = INKEY
40 IF K = 0 THEN 30
50 PRINT N; " YOU PRESSED "; CHR$(K); " (CODE"; K; ")"
60 NEXT N
70 PRINT "THAT IS FIVE"
RUN
PRESS FIVE KEYS
 1 YOU PRESSED A (CODE 65)
 2 YOU PRESSED B (CODE 66)
 3 YOU PRESSED C (CODE 67)
 4 YOU PRESSED D (CODE 68)
 5 YOU PRESSED E (CODE 69)
THAT IS FIVE

OK

CHR$(K) turns the code back into the character. A is 65, Z is 90, 0 is 48, and space is 32 — or just run the program above and press the key you're curious about.

Joysticks

JOY(1) and JOY(2) read the two joystick ports. Each gives you one number whose bits are the directions and buttons:

BitValue
7128right
664left
532down
416up
38Y
24X
12B
01A

The bits are active low. A stick doing nothing reads 255 — every bit set. Push it up and the up bit goes to zero. So the test is = 0:

10 J = JOY(1)
20 IF (J AND 16) = 0 THEN Y = Y - 1
30 IF (J AND 32) = 0 THEN Y = Y + 1
40 IF (J AND 64) = 0 THEN X = X - 1
50 IF (J AND 128) = 0 THEN X = X + 1
60 IF (J AND 1) = 0 THEN GOSUB 500

Write IF (J AND 16) THEN — without the = 0 — and your program moves upwards constantly except when the player pushes up. It is the single most common joystick bug and now you'll recognize it on sight.

Read the whole stick into a variable once per frame, as line 10 does, rather than calling JOY(1) five times. It's faster and it can't change its mind halfway down the list.

Both sticks in one go

J = JOY(1) : K = JOY(2) on one line, at the top of your game loop. Everything after that is arithmetic.

The joystick byte: eight bits, and a held control reads zero One byte from JOY(1) bit 7 Right $80 bit 6 Left $40 bit 5 Down $20 bit 4 Up $10 bit 3 Button Y $08 bit 2 Button X $04 bit 1 Button B $02 bit 0 Button A $01 nothing held11111111$FF pushed up11101111$EF A held direction or button reads 0, not 1. That is why the test is IF (JOY(1) AND 16) = 0
One byte, eight controls. Pushing the stick up turns bit 4 off, not on — which is why every test in this chapter ends in = 0.

PAUSE

PAUSE n does nothing for n hundredths of a second. It's how you slow a program down to a speed a person can watch:

10 PAUSE 50

That's half a second. In a game loop, a PAUSE 2 or PAUSE 3 is usually the difference between a smear and an animation.

WAIT

WAIT address, mask stops the program until reading that address and ANDing it with the mask gives something non-zero. Nothing else happens while it waits — not even Esc — so it's the one statement here that can genuinely wedge your machine if you point it at a bit that never arrives.

It's a hardware statement, and you want it about once a year. INKEY in a loop is the answer to almost every question that looks like it needs WAIT.

Next: keeping what you made.

Written for BIOS v1.5. Released under the MIT License.