Commodore 64 Sprites
The Commodore 64 has the ability to generate sprite graphics over a character background. When this data area is created and a sprite is moving over the background, that data will not be erased. This is because the sprites are located in a different area of memory that do not conflict with the screen data. This independence gives it a great advantage when creating games. Any data or graphics remains in its own independent space.
A sprite is drawn as 24 x 21 (503 bits) or 63 bytes of memory. So a sprite can be 24 bits wide, and 21 bits high. This area is also known as an MOB (Moveable Object Block). Up to 8 sprites can be displayed, animated, and moved on the screen. However, using a technique known as sprite multiplexing, even more sprites can be occupied with raster line timing. Basic is too slow to move sprites effectively, so assembly language is the best bet when trying to create smooth movement.
The bytes are separated into individual bits for each row (ranging from 0-7), with the 0 bit being on the right. The values for each section (in an 7 bit layer) is displayed as 128,64,32,16,8,4,2, and 1. The total sum of these values in 255 which would draw a complete line across the width of the sprite.
Multicolor Sprites
Sprites can be in one color or in multiple colors, when a special mode known as multicolor is activated using memory locations ($D025 – $D02E), which is listed as 53287-53294 in Basic decimal mode. These multicolors are displayed when the sprites are grouped in pairs. As a result this expands a pixel to twice the width of a high resolution pixel. When lining up these bits during the design phase, a sprite can contain up to 4 colors (0-4). The bit pair of 00 will be transparent. The bit pair of 01 will be linked to the color in $D025 (53285). The bit pair of 11 will be linked to address $D026 (53286). Finally the bit pair of 10 will take on the color of a sprite in memory locations $D025-$D02E (53287-53294).
It is quite tedious to create a sprite on graph paper, but it can be accomplished. Essentially you will divide each area into 3 rows that occupy 8 bytes each and the height will designed the same way. Most people prefer using a Sprite Editor to accomplish this. Windows has made room for a popular editor known as SpritePad. By using this tool, you can quickly create a whole slew of sprites, add their multicolors, and even animate them.
Sprite Positions
Commodore 64 Sprites are positioned horizontally and vertically using the registers $D000-$D00F (53248-53263). So for example Sprite 0 could be positioned on the screen in a position ranging from left to right by using memory location $D000. However, there is a limit to the horizontal position up to byte 255. The vertical position of Sprite 0 can be placed using memory location $D001.
As mentioned earlier, sprites have a limited (due to their width range) area that can be placed on the screen and require another memory location to reset the horizontal position of a sprite’s high byte. The memory location that handles this is $D010 (53264). By passing in a bit from 0-7 here you can set that sprite’s appropriate horizontal most significant bit at that position.
Each of the Commodore 64 Sprites require the ability to have it turned on or off. The memory location that handles this is $D015. This is accomplished by setting a bit from 0-7 for the appropriate sprite once again. A zero contained here turns that sprite off and a 1 activates it so it displays on the screen.
A sprite can be expanded to double it’s height with memory location $D017 (53271). The expansion is controlled by setting a bit with a 0 or 1. As identical to the sprite enable function, setting a zero here turns off the expansion, and placing a 1 here will activate the sprite vertical expansion. Often in games, this could be used to create a boss character since they tend to be larger.
The Foreground Display Priority Register at memory location $D01B (53275) controls when a sprite will exist in front of a foreground or behind it. This is done again, by setting it to bit 0 or 1. If a game contains a multicolor graphics mode, the sprite will be shown behind other sprite graphics even though the priority is set here for the foreground graphics, due to the 01 bit pair being set.
Sprite Bit Pairs
A sprite can contain multiple colors within it’s bit pairs using memory location $D01C (53276). To activate this, set bit 1 here, and turn it off by replacing with bit 0. When it is turned on, the sprite shape data is gathered into pairs. Each pair controls a double wide pixel of the sprite display. Since the sprite has had the horizontal resolution reduced, it is now only 12 dots wide. This now allows the ability for using two new colors. According to Mapping the Commodore 64 the four possible combinations affecting these bit pairs get their color from the data below.
00 Background Color Register 0 (transparent)
01 Sprite Multicolor Register 0 (53285, $D025)
10 Sprite Color Registers (53287, $D027-E)
11 Sprite Multicolor Register 1 (53286, $D026)
Each sprite also contains the ability to have three foreground colors, which that color being unique to that sprite.
Sprite to Sprite Collision
The collision of a sprite is stored in registers ($D01E-$D01F) or 53278-53279 memory registers. There is some conflict when using this register however. Although a sprite can confirm with sprites overlapped each other (bit 1 is set), it is unable to accurately determine a collision when Commodore 64 Sprites are stacked up in a row. When that occurs, this register would still trigger a collision even if they are not touching each other. A collision is tracked when a bit (dot) of a sprite’s data moves over another dot that does not contain zero data in that area. Sprites that utilize this memory area, can also detect a collision even when it climbs behind the border or off the screen. Likewise setting a zero here will usually clear the collision, if multiple sprites are not conflicting with each other.
Sprite Foreground Collision
Just like it’s counterpart, memory location $D01F (53279) has the ability to see when Commodore 64 Sprites have collided with the foreground. By checking to see if a bit 0 or 1 is contained here, it can act on that information. Yet there are still conflicts that can occur so use it wisely, ensuring that sprite bits are not crossing over each other.
A sprite’s multicolor is set within memory locations $D025- $D026 as discussed earlier. It is necessary for the system to find a zero or 1 here so that sprite’s data can be set accordingly. The default color set for $D025 on power up is purple, and $D026 will contain the color black.
A standard Commodore 64 Sprites color is set and turned off using locations $D027-$D02E (53287-53294) in memory. Each corresponding sprite once again contains a default color when the computer is first turned on, but they can be changed here.
Sprite Shape Data and Animation
Memory locations $07F8-$07FF (2040-2047) contain an area that reserves sprite data. This is useful for animation. The data is contained here for each pointer to match the appropriate shape in memory. Each of the Commodore 64 Sprites, ranging from 0-7 occupy it’s own data containment in these memory addresses. The pointer value is multiplied by 64, which is equal to the starting location of that sprite’s data table. A simple calculation as found in Mapping the Commodore 64 is using Sprite 0 at memory address 704 (11*64=704) to point to the appropriate area of memory. This then leaves room for 63 bytes up to memory address 767. By cycling through data contained in these registers, simple animation is quite possible with your sprites.
Below is a simple sprite example program extracted from the book Commodore 64C Personal Computer System Guide.
You can view the program completely here in PDF form and it is broken down further below the page.
[wonderplugin_pdf src=”https://www.c64brain.com/wp-content/uploads/2021/05/Commodore-64-Sprites.pdf” width=”100%” height=”600px” style=”border:0;”]
10 PRINT CHR$(147)
15 POKE 53280,1: REM Change the border color to white
17 POKE 53281,1: REM Change the background color to white
20 POKE53269,128
30 POKE2047,192
35 POKE 2046,192:REM Set sprite 6 data pointer to 12288
37 POKE 2045,192:REM Set sprite 5 data pointer to 12288
43 poke 53293,6:REM Color sprite 6 blue
45 POKE 53292,2:REM Color sprite 5 red
50 FORN=0TO62
55 POKE53271,128
57 POKE 53277,128
60 READ Q
70 POKE12288+N, Q
80 NEXT
85 FORZ=1TO200
90 POKE53262, Z
92 POKE 53260, Z:REM Set sprite 6 horizontal position
94 POKE 53258,100:REM Set sprite 5 horizontal position
95 POKE53263, Z
96 POKE 53261,100:REM Set sprite 6 vertical position
97 POKE 53259, Z:REM Set sprite 6 vertical position
98 NEXT
99 GOTO 85
100 DATA 0,0,0
110 DATA 0,126,0
120 DATA 1,129,128
130 DATA 2,0,64
140 DATA 12,0,48
150 DATA 8,0,16
160 DATA 19,197,200
170 DATA 16,0,8
180 DATA 32,195,4
190 DATA 32,195,4
200 DATA 32,24,4
210 DATA 32,24,4
220 DATA 32,24,4
230 DATA 16,126,8
240 DATA 17,60,136
250 DATA 8,129,16
260 DATA 8,126,16
270 DATA 4,0,32
280 DATA 2,0,64
290 DATA 1,129,128
300 DATA 0,126,0
[…] feel free to read the Commodore 64 Sprite article that teaches you how to create your own sprites using the Commodore 64 Sprite Registers […]
Hi. Cool tutorial, soo informative. But how I use just “0 and “1 for sprites creation?