Commodore 64 Assembly Sprite

In this lesson, we provided building block steps that will teach you how to get a Commodore 64 assembly sprite up on the screen and moving.  This C64 Assembly Sprite Tutorial was developed with the beginner in mind. It will be helpful if you do have a minor grasp on Basic as a lot of those techniques can be applied here.

For the first part we access the register $d020 (53280) in order to control the border color. The Commodore 64 utilizes memory “registers” to access specific functions that can be used within a program.  The hardware chip that manages the border color is known as VIC II (Video Interface Controller).

The Border color has the ability to produce colors from 1-16. These colors are set and cannot be changed. The first set from 0-8 is known as standard colors and the remaining 9-16 are the multi colors. The color palette is defined below for our Commodore 64 Assembly Sprite project.

Download Project

Below is a listing of the program in PDF format

Color 0 = Black

Color 1 = White

Color 2 = Red

Color 3 = Cyan (Blue/Green)

Color 4 = Purple

Color 5 = Green

Color 6 = Blue<

Color 7 = Yellow

Color 8 = Orange

Color 9 = Brown

Color 10 = Light Red

Color 11 = Dark Grey

Color 12 = Medium Grey

Color 13 = Light Green

Color 14 = Light Blue

Color 15 = Light Grey

The program starts off by setting the Commodore 64 border color.

Then we turn on the sprite, set the multi colors, sprite colors, background color, sprite x/y position, and set the sprite on the screen by setting the sprite shape pointer.

* = $8000

; Found on Youtube
; Title: Commodore 128D: Episode 3: Hardware Sprites
; Channel: Nybbles and Bytes

lda #13
sta $d020 ; border color
jsr $e544

lda #7
sta $d015 ; enable sprite
lda #7
sta $d01c ; activate multicolor bits
lda #$f4
sta $d025 ; sprite multicolor reg #1
lda #$f9
sta $d026 ; sprite color #0
lda #$05
sta $d027 ; sprite color #1
lda #0
sta $d021 ; background color
lda #24
sta $d000 ;sprite horizontal(x) position
sta $fb
sta $fc
lda #$90
sta $d001 ;sprite vertical(y) position
lda #$c0
sta $7f8 ; sprite shape pointer

Position upper left Sprite

The next section will position the example sprite to be visible in the upper left corner. Try changing the x and y coordinate values to see it move around the screen.

; show sprite 1 in corner
lda #24
sta $d002 ;sprite 1 X coordinate
lda #50
sta $d003 ;sprite 1 Y coordinate
lda #7
sta $d028 ; sprite 1 color reg
lda #$c4 ; sprite 1 shape data pointer
sta $7f9

; Now we begin to draw the ground under
; our sprite so they are not walking on air.

ldx #$28
draw_grnd
lda #102
sta $062f,x
lda #13
sta 55855,x
lda #78
sta 1623,x
lda #3
sta 55895,x
lda #77
sta 1663,x
lda #86
sta 1703,x
lda #5
sta 55975,x
dex
bne draw_grnd

Sprite data is read using labels “data1” through “data3”. These values exist further down in the Assembly language program.

; read in sprite data
ldx #64
rd_sp1
lda sprite_data1,x
sta $3000,x
dex
bne rd_sp1

ldx #64
rd_sp2
lda sprite_data2,x
sta 12352,x
dex
bne rd_sp2

ldx #64
rd_sp3
lda sprite_data3,x
sta 12416,x
dex
bne rd_sp3

ldx #64
rd_sp4
lda sprite_data2,x
sta 12480,x
dex
bne rd_sp4

ldx #64
rd_sp5
lda sprite_data2,x
sta 12544,x
dex
bne rd_sp5
ldx #0
stx $d000

Now we begin the sprite movement from left to right being sure to check the MSB (most significant bit) when the sprite has exceeded the 255th position. This forces the bit to reset and be placed in the Sprite X high byte in order to keep the sprite moving across the screen.

start
tax
tay
sty $fb
spr_loop
stx $d000 ; move sprite X from left to right
stx $d000 ; move sprite X from left to right
stx $d000 ; move sprite X from left to right
iny
bne spr_loop

inc $7f8 ; shift through sprite data animation frames
lda $7f8
cmp #$c4 ;check when to flip the frames
bne skip_anim
update_anim
lda #$c0
sta $07f8 ;reset sprite frame animation
inx

skip_anim

bne spr_loop
lda $d010 ; check Sprite X MSB
and #$01 ; Flip the Sprite we care about
eor #$01 ; Toggle the MSB for Sprite 0
sta $d010
;bit $d010
bne no_msbset ; skip if msb is not set

inc $d020 ; increase border color for effect
sta $d021 ; increase screen color for effect
inc $d027 ; store in sprite color

lda $d000 ; check if sprite MSB flips again
cmp #10
bcc no_msbset
lda #24
sta $d000 ; set sprite #0 position

no_msbset
jmp start

Finally we finish out the simple sprite animation program by filling memory with the sprite data (from sprite_data1 through sprite_data10).

; Pitfall Harry sprite data

sprite_data1 ; $c0
byte 0,60,0,0,20,0,0,20,0,0,16,0,0,40,0,0,40,0,0,40,0,0,40,128,0,42,128,0
byte 42,0,0,40,0,0,60,0,0,60,0,0,60,0,0,60,0,0,60,0,0,60,0,0,60,0,0
byte 63,0,0,48,0,0,60,0,0

sprite_data2 ; $c1
byte 0,60,0,0,20,0,0,20,0,0,16,0,0,40,0,0,40,0,0,168,0,0,168,128,0
byte 170,128,0,170,0,0,40,0,0,60,0,0,60,0,0,63,0,0,63,0,0,51,0,0,51,0,3
byte 243,0,3,0,240,3,0,192,0,0

sprite_data3 ; $c2
byte 0,60,0,0,20,0,0,20,0,0,16,0,0,40,0,0,40,0,0,40,0,0,40,0,0,40,0,0
byte 42,0,0,42,0,0,60,0,0,60,0,0,63,0,0,15,192,0,12,192,0,255,192,0
byte 204,0,0,204,0,0,12,0,0,15,0,0

sprite_data4 ; $c3
byte 0,60,0,0,20,0,0,20,0,0,16,0,0,40,0,0,40,0,0,168,0,0,168,128,0
byte 170,128,0,170,0,0,40,0,0,60,0,0,63,0,0,255,192,0,243,192,3,192,192,3
byte 192,192,15,0,240,12,0,0,12,0,0,0,0,0

sprite_data5 ; $c4
byte 0,60,0,0,20,0,0,20,0,0,16,0,0,40,0,0,40,128,0,170,128,2,170,0,2
byte 40,0,2,40,0,0,40,0,0,63,0,0,63,192,15,60,192,3,240,192,0,240,240
byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

; Left Man Data

sprite_data6
byte 0,60,0,0,20,0,0,20,0,0,4,0,0,40,0,0,40,0,2,40,0,2,168,0,0,168,0,0
byte 168,0,0,40,0,0,60,0,0,60,0,0,60,0,0,60,0,0,60,0,0,60,0,0,60,0,0
byte 252,0,0,12,0,0,60,0

sprite_data7
byte 0,60,0,0,20,0,0,20,0,0,4,0,0,40,0,0,40,0,0,42,0,2,42,0,2,170,0,0
byte 170,0,0,40,0,0,60,0,0,60,0,0,252,0,0,252,0,0,204,0,0,207,192,0
byte 192,192,15,0,192,3,0,0,0,0,0

sprite_data8
byte 0,60,0,0,20,0,0,20,0,0,4,0,0,40,0,0,40,0,0,40,0,0,40,0,0,40,0,0
byte 168,0,0,168,0,0,60,0,0,60,0,0,252,0,3,240,0,3,48,0,3,255,0,0
byte 51,0,0,51,0,0,48,0,0,240,0

sprite_data9
byte 0,60,0,0,20,0,0,20,0,0,4,0,0,40,0,0,40,0,0,40,0,0,40,0,0,168,0,0
byte 168,0,0,40,0,0,60,0,0,252,0,3,252,0,3,204,0,3,15,0,3,207,0,0
byte 195,0,3,3,0,0,3,0,0,12,0

sprite_data10
byte 0,60,0,0,20,0,0,20,0,0,4,0,0,40,0,0,40,0,0,42,0,2,42,0,2,170,0,0
byte 170,0,0,40,0,0,60,0,0,252,0,3,255,0,3,207,0,3,3,192,3,3,192,15
byte 0,240,0,0,48,0,0,48,0,0,0

If you enjoyed this article on Commodore 64 Assembly Sprites be sure to check out the section on this website called Machine Language Project which demonstrates how to create a professional application regarding sprites.

Please follow and like us: