VIC Joystick And Keyboard Routine
Michael Kleinert
Nanuet, NY
For VICs without memory expansion, these gaming routines will help speed up BASIC considerably.
In the Fall 1982 issue of Home and Educational COMPUTING! was an article by David Malmberg entitled "Using the VIC Joystick," which demonstrated a short BASIC routine for reading from the joystick. After adding that routine to one of my game programs, I discovered that BASIC can just be too slow for some games. My attempts to speed up that routine were unsuccessful, so I decided to write one in machine language for reading from the joystick. I designed the routine to be most suitable for game purposes, especially those in which you must guide an object around the screen by using the joystick.
Entering The Machine Coding
Type in the BASIC loader provided in Program 1. For those who may not have a joystick or might like to use the keyboard, I have included an identical routine for the keyboard in Program 2.
Using The Routines
Both routines are very similar. Each checks for up, down, left, and right. Accounting for diagonal directions would require longer and more complex programming. The keyboard version will look for the depressing of four keys, which I have defined as I (up), M (down), J (left), and K (right).
I designed the routines for controlling the movement of an object on the screen, and I suggest the following format:
10 POKE A, B : SYS 7168 : POKE A, 32 : A = A + PEEK(1)-PEEK(2) : GOTO 10
In the above line, A is the memory location of a character's position on the screen, and B is the character code of the desired character. First the character is POKEd onto the screen, and then the subroutine is called with SYS 7168. The subroutine checks for any movement of the joystick (or for keys being pressed). If it detects the joystick being pushed in any direction, it places an appropriate numerical value into location 1 or 2. These values will be used to update the position of the character being moved. First, the old character must be erased. This is accomplished by the command POKE A, 32. The character is erased by POKEing a space onto the same screen position (A). After it has been erased, its position can be updated by adding the contents of memory location 1 and subtracting the contents of memory location 2. Do this as shown above, with the command A = A + PEEK(1)-PEEK(2).
If the routine does not detect the joystick or keyboard being depressed, the values in these two memory locations will be set to zero, and the variable A (character's position) will remain the same.
Avoiding Leaving The Screen
If the joystick is pushed up (or the "I" key is pressed on the keyboard), the routine will place a value of 22 into memory location 2. This causes the number 22 to be subtracted from the current screen address contained in variable A, and is the basis for accomplishing upward movement of a character on the screen. Similarly, a character is moved right, left, and down in this fashion.
In order to keep the character from going off the top or the bottom of the screen, more complex programming is required. An appropriate method is illustrated in Program 3. The program is not a game, but simply a demonstration for the use of the routines. It will scatter several boxes, as obstacles, on the screen and will enable you only to move your "player" around the screen with the joystick or keyboard. It is the basic structure for a game.
If you are going to use the joystick, enter in lines 10 to 40 from Program 1. If you are using the keyboard, copy the lines from Program 2.
When you are ready to use one of the routines in your own BASIC program, do the following. Place lines 10 to 40 from Program 1 or lines 10 to 30 from Program 2 at the beginning of your program. Then, wherever you wish to utilize the routine in your program, give the command SYS 7168. To update the character's position, use the method which I described above.
Other Applications
There are many other uses for these routines. You may use them in simple delay loops to temporarily stop the program and wait until something is pressed.
To check for a desired direction on the joystick or a key on the keyboard, use the values from Figures 1 and 2. For example, if you are using the keyboard subroutine and want the program to wait until the letter "I" is pressed on the keyboard, you PEEK location 2 as follows:
100 SYS 7168 : IF PEEK (2) < > 22 THEN 100
This will call the subroutine, and the program will not proceed until the value in location 2 is equal to 22.
If you are using the joystick and want to wait until it is pushed to the right, you follow the same basic format: PEEK memory location 1 for a value of one. For example:
100 SYS 7168 : IF PEEK(1) < > 1 THEN 100
The Firing Button
A "firing" button is not accounted for in either of the two routines, since it would require a line of BASIC. If you would like to check for the firing button, you would place the following step into your program:
200 IF PEEK(37137) > 69 THEN GOSUB (Line number)
After the GOSUB, you would place the line number to which you wish to send the program if it finds the firing button depressed.
If you wish to check for a "firing" button on the keyboard, you may use the following line, which checks for any depressing of the SPACE BAR (the one I usually use).
200 IF PEEK(197) = 32 THEN GOSUB (LINE #)
The Demo Program
Briefly, here's a description of the function of each line in the demonstration, Program 3.
5 Limits the end of BASIC to protect the machine language routine, clears variables, and sets "A" equal to 7800 (the character's memory location on the screen).
10 READs the machine code from the DATA statements and POKEs the values into memory, starting at 7168.
20-40 Contain the machine code for the routine in DATA statements.
50 Clears the screen and then POKEs the color red onto each screen location.
60 Puts obstacles on the screen in 30 random screen locations.
70 POKEs the character onto the screen, calls the subroutine, and then sets "B" equal to the updated address.
80 If the new address is found to be off the screen, or if it is occupied by a box, the character remains stationary and the program goes back to line 70.
90 The new screen position has been accepted, so the old character is erased. The program goes back to line 70 to go through the same process.
Both routines can be used on a VIC with any amount of memory and can be placed anywhere in the user's RAM. In order to keep things relatively simple, I wrote the demonstration program for a 3.5K VIC; it will not work on a VIC with any memory expansion. These routines help speed up programs a great deal.
Program 1: Joystick Reader
10 FORM = 0 TO 65 : READN : POKE7168 + M, N : NEXT 20 DATA169, 128, 141, 19, 145, 169, 0, 133, 1, 133, 2, 169, 127, 141, 34, 145, 162, 119, 236, 32, 145 30 DATA208, 4, 169, 1, 133, 1, 169, 255, 141, 34, 145, 162, 118, 236, 17, 145, 208, 4, 169, 22, 133, 1 40 DATA162, 110, 236, 17, 145, 208, 4, 169, 1, 133, 2, 162, 122, 236, 17, 145, 208, 4, 169, 22, 133, 2, 96
Program 2 : Keyboard Reader
10 FORA = 0 TO 40 : READB: POKE 7168 + A, B : NEXT 20 DATA 169, 0, 133, 1, 133, 2, 165, 197, 201, 12, 208, 4, 162, 22, 134, 2, 201, 36, 208, 4, 162, 22, 134, 1 30 DATA 201, 44, 208, 4, 162, 1, 134, 1, 201, 20, 208, 4, 162, 1, 134, 2, 96
Program 3 : Demonstration
5 POKE 56, 28 : POKE 52, 28 : CLR : A = 7800 10 FORM = 0 TO 65 : READN : POKE7168 + M, N : NEXT 20 DATA169, 128, 141, 19, 145, 169, 0, 133, 1, 133, 2, 169, 127, 141, 34, 145, 162, 119, 236, 32, 145 30 DATA208, 4, 169, 1, 133, 1, 169, 255, 141, 34, 145, 162, 118, 236, 17, 145, 208, 4, 169, 22, 133, 1 40 DATA162, 110, 236, 17, 145, 208, 4, 169, 1, 133, 2, 162, 122, 236, 17, 145, 208, 4, 169, 22, 133, 2, 96 50 PRINT"{CLEAR}" : FORX = 38400TO38905 : POKE X, 2 : NEXT 60 FORX = 1TO25 : Y = INT (RND(1) * 500) + 1 : POKEY + 7680, 160 : NEXT 70 POKEA, 42 : SYS7168 : B = A + PEEK(1) - PEEK (2) 80 IFB > 8185ORB < 7680ORPEEK (B) = 160THEN70 90 POKEA, 32 : A = B : GOTO 70Figure 1 : Joystick Figure 2 : Keyboard