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