For Commodore 64
Jeremy ZulloThis sophisticated utility allows the Commodore 64 to display as many as 32 sprites on the screen at the same time. (It also works on the Commodore 128 in 64 mode.) The "Sprite BASIC" enhancement program adds several new sprite commands to BASIC 2.0. For machine language programmers, the "Sprite Kernal" utility offers the same capabilities for ML programming. Demonstration programs show how to use the technique in both BASIC and machine language. A disk drive is required.
You probably know that the Commodore 64 is designed to display a maximum of eight sprites on the screen at one time. That's enough for most purposes, but there are many situations, particularly in game programming, where extra sprites would be useful. The programs accompanying this article let you display as many as 32 sprites on the screen at once. Though the programs are written in machine language, you can use them without being a machine language expert.
"Sprite 32" is the first program you'll need; it handles the mechanics of displaying the extra sprites. The second utility, a BASIC enhancement called "Sprite BASIC,' adds nine new sprite commands to the 64's BASIC 2.0. The third ML program, called "Sprite Kernal,” offers a convenient way for machine language programmers to access all of the Sprite 32 functions.
Begin by entering Programs 1, 2, and 3. Because these programs are written in machine language, you must enter them with the "MLX" machine language entry program listed elsewhere in this issue. Before you type in the programs, read the information below about which file names to use when saving them. If you don't intend to program in machine language, you need not type in Program 3; however, you may want to enter it anyway to view the machine language demonstration (see below). Here are the addresses you need to enter each program with MLX:
Starting address: C000
Ending address: C4C7
Starting address: C600
Ending address: C997
Starting address: C600
Ending address: C80F
If you wish to use the demo programs included with this article, you must save Programs 1, 2, and 3 with the exact filenames listed here:
Program 1: SPRITE 32
Program 2: SPRITE BASIC
Program 3: SPRITE KERNAL
After you've saved Programs 1-3, you may want to enter Program 4, the BASIC demonstration. Before entering this program, however, you must activate Sprite BASIC. Load the program with the command LOAD"SPRITE BASIC" ,8,1. When the load is finished, enter NEW to reset the computer's memory pointers, then type SYS 50688 and press RETURN to install Sprite BASIC. It is very important that you install Sprite BASIC before typing in Program 4. If you omit this step, the program will not work correctly.
After Sprite BASIC is installed, enter Program 4. Don't worry about the unfamiliar commands; they'll be explained in the next section. Save a copy of the program, then run it. After loading Sprite 32 and Sprite BASIC, the program displays 32 sprites on the screen, LISTs itself, and returns to ready mode.
Note that Sprite 32 works completely in the background: The sprites remain stable even after the READY prompt and blinking cursor reappear. You can LIST the program, edit it, and with one exception (see below) use BASIC in the normal way.
Let's examine some Sprite BASIC commands. With 32 sprites still on the screen, type this statement and press RETURN:
All of the sprites disappear. Now enter the command SPRITE 1: All of the sprites instantly reappear.
The SPRITE command turns the Sprite 32 utility on and off. This command is important because you must always disable Sprite 32 before using the disk or tape drive. If you try to save or load a program while Sprite 32 is still active, you may crash the system (no harm is done to the computer, but you might lose whatever program is in memory).
Here are some additional commands to try. Type in each of the lines listed here, pressing RETURN at the end of each line:
FOR J = 0 TO 7:DISABLE 3,J:NEXT
FOR J = 1 TO 7:ENABLE 3,J:NEXT
The ENABLE and DISABLE commands let you turn individual sprites on and off. The first number after the command indicates the sprite's group number. There are four sprite groups, numbered 0-3. Each group contains eight sprites, and group 0 is always located at the top of the screen. Within each group, sprites are numbered from 0-7; in this demo, sprite 0 is at the leftmost screen position.
The second parameter in the ENABLE and DISABLE commands identifies which sprite within the group you wish to affect. Thus, DISABLE 3,0 turns off sprite 0 in group 3 (the bottom group). ENABLE 2,7 turns on the rightmost sprite in group 2, and so on.
Sprite 32 divides the screen horizontally into four separate zones, one for each group of eight sprites. When all 32 sprites are on the screen, each group is confined to its own horizontal zone. For example, you cannot move a group 3 sprite into the zone for group 2. However, by sacrificing sprites from other zones, you can allow a sprite to move freely through two or more zones. The basic method is to DISABLE the corresponding sprite in the next higher-numbered zone.
For instance, if you disable sprite 0 in group 3, then sprite 0 in group 2 can move anywhere within zones 2 and 3. By sacrificing three corresponding sprites, you can allow a sprite from group 0 to go anywhere on the screen. To illustrate, enter these lines, pressing RETURN at the end of each line:
FOR J = 1 TO 3:DISABLE J,0:NEXT
FOR J = 60 TO 250:PLACE 0,0,30,J:NEXT
FOR J = 250 TO 60 STEP -1:PLACE 0,0,30,J:NEXT
Sprite 0 from group 0 moves all the way down through zones 1, 2, and 3, then returns to its original position. While this method reduces the total number of sprites you can display, it does permit you to have some sprites that aren't confined to particular screen areas.
One word of warning: Do not disable any of the sprites in group 0, or you may get unpredictable results.
Sprite BASIC Commands
Here is a list of ail the Sprite BASIC commands:
DISABLE sprite group, sprite number Turn off a sprite. The sprite group parameter can range from 0-3 and identifies which of four groups the sprite belongs to. The sprite number can range from 0-7 and identifies an individual sprite within the group (see above).
ENABLE sprite group, sprite number Turn on the sprite specified by sprite group and sprite number (see above).
KILL Deactivate Sprite BASIC. After you perform KILL, Sprite BASIC is disabled and the 64's BASIC works exactly as usual. This is not the same as a SPRITE 0 statement (see below), which disables the Sprite 32 utility but does not affect Sprite BASIC.
OFF sprite group, sprite number
Make the designated sprite invisible. Use the PUTS command (see below) to make a sprite visible again. Note the difference between OFF and DISABLE: An OFF statement makes the sprite disappear from the screen but has no effect on the ability of other sprites to venture into that sprite's zone. A DISABLE statement allows another sprite to move through the disabled sprite's territory and also makes the sprite disappear.
PLACE sprite group, sprite number, X coord, Y coord Place the designated sprite at the screen coordinates indicated by X coord and Y coord. The horizontal coordinate X coord can be any value from 0-512, but only coordinates from 24-343 are visible on the screen. The vertical coordinate Y coord. can be any value from 0-255, but only coordinates from 50-249 are visible on the screen. (No special tricks are required to move sprites past the "seam" into horizontal positions greater than 255; Sprite 32 automatically handles the most significant bit for horizontal positioning.)
PUTS sprite group, sprite number The opposite of OFF, this statement makes a sprite visible.
RASTL boundary number, new raster The RASTL (RASTer Line) statement lets you change the boundary between two sprite zones; since the zones are contiguous, this also changes the size of those zones. The first parameter, boundary number, identifies which zone boundary you wish to change. There are three boundaries, numbered 0-2, which separate the four sprite zones. Boundary 0 separates zones 0 and 1; boundary 1 separates zones 1 and 2; and boundary 2 separates zones 2 and 3.
The second parameter, new raster, specifies the raster line where the specified boundary should be located. The visible screen contains 200 raster lines, numbered 50-249, with line 50 at the very top of the screen. The default position for boundary 0 is raster line 99. To move this boundary 20 lines higher on the screen (to line 79), use the statement RASTL,0,79. Now the lower portion of zone 0 ends at screen line 79 and the upper portion of zone 1 begins at line 80.
SET sprite group, sprite number, shape, color SET defines the shape and color of the individual sprite specified by sprite group and sprite number. The shape parameter tells the 64 where to find the shape data for the sprite. This is the same value you would POKE into one of the shape pointer locations from 2040- 2047 under normal circumstances. The color value can range from 0-15 and corresponds to the usual 64 color numbers (color 0 is black, and so forth). Your user's manual contains more information about colors and sprite shape pointers.
SPRITE toggle Turn Sprite 32 on or off. Because Sprite 32 interferes with disk and tape operations (including saving and loading programs), you must always turn it off before using disk or tape. Use SPRITE 0 to deactivate Sprite 32, and SPRITE 1 to activate it. This statement does not affect Sprite BASIC, which must always be active in order to use a program that contains Sprite BASIC commands. For instance, after loading Sprite BASIC into memory, Program 4 activates it with SYS 50688 before performing any Sprite BASIC commands.
When placing sprites on the screen, keep in mind that no part of the sprite can cross the boundaries of its zone unless you have DISABLEd other sprites to permit multizone movement.
For example, the default location for zone 0 is from raster lines 0-99. Since a sprite can be as many as 21 lines high, you should not attempt to PLACE a group 0 sprite using a vertical coordinate greater than 78 (99-21=78). Similarly, zone 1 stretches from lines 100-149, so a zone 1 sprite can move between lines 100-128 (149-21 = 128). If you try to position a sprite outside its permitted zone, it may flicker or disappear completely. Within its horizontal zone, a sprite can have any horizontal location.
There are certain aspects of sprite behavior which Sprite 32 doesn't affect at all. For instance, sprite-to-sprite display priorities are exactly the same as usual: When two or more sprites overlap, lower-numbered sprites always appear in front of higher-numbered ones.
You may change the sprite-to-background priority of a sprite in the usual way, but the change affects every sprite of the same number. That is, if you change the sprite/background priority for sprite 0, it is changed for sprite 0 in every sprite group.
The same is true of horizontal or vertical expansion. Expansion affects every like-numbered sprite on the screen.
Machine Language Demo
For machine language programming, BASIC commands are not particularly convenient. Program 3, the Sprite Kernal, provides all the features of Sprite 32 to machine language programmers. Even if you don't understand machine language, you may want to enter and run the remaining programs to see an impressive demonstration. Program 5 illustrates the power of machine language by moving 17 sprites on the screen simultaneously. This program must be entered with MLX, using these addresses:
Starting address: 6000
Ending address: 62B7
If you have been using Sprite 32 or Sprite BASIC, turn the computer off and on before you load and run MLX. Be sure to save Program 5 with the filename ML DEMO.
Next, type in and save Program 6 (you do not have to install Sprite BASIC before typing this program). This is a short BASIC loader that installs the necessary ML programs in memory, then starts ML DEMO with the statement SYS 24576.
When you run Program 6, the screen fills immediately with 17 bouncing sprites. Note that several of the sprites move through more than one sprite zone; one of them, the light blue sprite, is able to move anywhere on the screen. As explained earlier, it is necessary to sacrifice a certain number of sprites to achieve this effect.
"Sprite 32" allows the Commodore 64 to display as many as 32 sprites on the screen simultaneously.
Press RUN/STOP-RESTORE to stop the program. To restart it, enter SYS 24576.
The Sprite Kernal
Like Sprite BASIC, the Sprite Kernal also requires that Sprite 32 be in memory. Here are the starting addresses for each Sprite Kernal routine:
Routine JSR address
The Sprite Kernal routines perform the same functions as their Sprite BASIC equivalents. However, a different procedure is used to pass each routine the information it needs. The basic method is to store the parameters in memory locations beginning at 50688 ($C600), then call the Sprite Kernal routine with JSR. For an explanation of the parameters required by each routine, see "Sprite BASIC Commands" above.
Since the SPRITE routine takes only one parameter (1 or 0), you need to supply only one value before calling it. For example, to perform the equivalent of the Sprite BASIC statement SPRITE 1, you would execute LDA #1:STA $C600: JSR $C612. To do the equivalent of SPRITE 0, use LDA #0:STA $C600: JSR $C612. All of the remaining Sprite Kernal routines require two or more parameters. Here is an outline of how to call them:
PLACE ($C615/50709) Store the sprite group value in $C600/50688 and the sprite number value in $C601/50689. Locations $C602-$C603/50690-50691 hold the low byte and high byte of the sprite's horizontal (X) position. Store the sprite's vertical (Y) position in location $C604/50692.
SET ($C617/50712) Store the sprite group value in $C600/50688 and the sprite number value in $C601/ 50689. Store the shape pointer value in $C602/50690 and the color value in $C603/50691.
OFF ($C61B/50715) Only two values are required. Store the sprite group value in $C600/50688 and the sprite number value in $C601/ 50689.
PUTS ($C61E/50718) The converse of OFF. Store the sprite group value in $C600/50688 and the sprite number value in $C601/50689.
DISABLE ($C621/50721) Only two values are required. Store the sprite group value in $C600/50688 and the sprite number value in $C601/ 50689.
ENABLE ($C624/50724) The converse of DISABLE. Store the sprite group value in $C600/50688 and the sprite number value in $C601/ 50689.
RASTL ($C627/50727) Store the boundary number value in $C600/ 50688 and the new raster value in $C601/50689.
Here is a short example of how to use Sprite Kernal routines. This program displays sprite 4 in group 2. You will need a machine language assembler to create the object code for this routine. The comments following the semicolons are optional and need not be included.
LDA #$01 ;turn on
STA $C600 ;Sprite 32
LDA #$04 ;sprite number
LDA #$02 ;sprite group
LDA #$A0 ;low and high
STA $C602 ;bytes of the
LDA #$00 ;sprite's
STA $C603 ;X coordinate
STA $C604 ;Y coordinate
JSR $C615 ;PLACE
When Sprite 32 is active, the 64's IRQ vector is diverted from its normal address to the custom routines used to display extra sprites. If you activate another interrupt-driven routine at the same time, the conflict may produce unexpected results.