Skip to content

Instantly share code, notes, and snippets.

@cbmeeks
Last active June 3, 2023 12:08
Show Gist options
  • Save cbmeeks/7f4c770915e5c53b70fa to your computer and use it in GitHub Desktop.
Save cbmeeks/7f4c770915e5c53b70fa to your computer and use it in GitHub Desktop.
sprites.asm -- Commodore 64 Sprite Multiplexer
.importonce
//***************************************************************************
// VIC II
// BANK 0: $0000 - $3FFF
// BANK 1: $4000 - $7FFF
// BANK 2: $8000 - $BFFF
// BANK 3: $C000 - $FFFF
//***************************************************************************
//***************************************************************************
// To calculate the sprite location use:
// LOCATION = (BANK * 16384) + (SPRITE POINTER VALUE * 64)
// Where BANK = 0 - 3 and SPRITE POINTER VALUE = 0 - 255.
// SPRITE POINTER VALUE: 0: 0 * 64 = 0 (beginning of current VIC bank)
// 1: 1 * 64 = 64 (beginning of current VIC bank + 64)
//***************************************************************************
.function fnSprite_ORA_Value(sprite) {
.if(sprite == 0) .return %00000001
.if(sprite == 1) .return %00000010
.if(sprite == 2) .return %00000100
.if(sprite == 3) .return %00001000
.if(sprite == 4) .return %00010000
.if(sprite == 5) .return %00100000
.if(sprite == 6) .return %01000000
.if(sprite == 7) .return %10000000
}
.function fnSprite_AND_Value(sprite) {
.if(sprite == 0) .return %11111110
.if(sprite == 1) .return %11111101
.if(sprite == 2) .return %11111011
.if(sprite == 3) .return %11110111
.if(sprite == 4) .return %11101111
.if(sprite == 5) .return %11011111
.if(sprite == 6) .return %10111111
.if(sprite == 7) .return %01111111
}
.macro SetSpritePointer(sprite, value) {
.var addr = SCR_BUFFER + [[1024 - 8] + sprite]
.print "SetSpritePointer"
.print " SCR_BUFFER = " + fnPrintMemoryAddress(SCR_BUFFER)
.print " DBL_BUFFER = " + fnPrintMemoryAddress(DBL_BUFFER)
.print " SCR_BUFFER + [[1024 - 8] + sprite] = "
+ fnPrintMemoryAddress(addr)
lda #value
sta addr
}
.macro EnableAllSprites() {
.print "EnableAllSprites"
lda #$FF
sta $D015
}
.macro DisableAllSprites() {
.print "DisableAllSprites"
lda #$00
sta $D015
}
.macro EnableSprite(sprite) {
.print "EnableSprite " + sprite
lda $D015
ora #fnSprite_ORA_Value(sprite)
sta $D015
}
.macro DisableSprite(sprite) {
.print "DisableSprite " + sprite
lda $D015
and #fnSprite_AND_Value(sprite)
sta $D015
}
.macro EnableSpriteMultiColor(sprite) {
.print "EnableSpriteMultiColor " + sprite
lda $D01C
ora #fnSprite_ORA_Value(sprite)
sta $D01C
}
.macro EnableAllSpritesMultiColor() {
.print "EnableAllSpritesMultiColor"
lda #$FF
sta $D01C
}
.macro SetSpriteColor(sprite, color) {
.print "SetSpriteColor"
.print " Sprite: " + sprite
.print " Color: " + fnPrintColorName(color)
lda #color
.if(sprite == 0) sta $D027
.if(sprite == 1) sta $D028
.if(sprite == 2) sta $D029
.if(sprite == 3) sta $D02A
.if(sprite == 4) sta $D02B
.if(sprite == 5) sta $D02C
.if(sprite == 6) sta $D02D
.if(sprite == 7) sta $D02E
}
.macro SetAllSpritesColor(color) {
.print "SetAllSpritesColor"
.print " Color: " + fnPrintColorName(color)
lda #color
sta $D027
sta $D028
sta $D029
sta $D02A
sta $D02B
sta $D02C
sta $D02D
sta $D02E
}
.macro SetSpriteMultiColor0(color) {
.print "SetSpriteMultiColor0 " + fnPrintColorName(color)
lda #color
sta $D025
}
.macro SetSpriteMultiColor1(color) {
.print "SetSpriteMultiColor1 " + fnPrintColorName(color)
lda #color
sta $D026
}
.macro SetSpriteX(sprite, xpos) {
.print "SetSpriteX"
.print " Sprite: " + sprite
.print " XPos: " + xpos
lda #xpos
.if(sprite == 0) sta $D000
.if(sprite == 1) sta $D002
.if(sprite == 2) sta $D004
.if(sprite == 3) sta $D006
.if(sprite == 4) sta $D008
.if(sprite == 5) sta $D00A
.if(sprite == 6) sta $D00C
.if(sprite == 7) sta $D00E
}
.macro SetSpriteY(sprite, ypos) {
.print "SetSpriteY"
.print " Sprite: " + sprite
.print " YPos: " + ypos
lda #ypos
.if(sprite == 0) sta $D001
.if(sprite == 1) sta $D003
.if(sprite == 2) sta $D005
.if(sprite == 3) sta $D007
.if(sprite == 4) sta $D009
.if(sprite == 5) sta $D00B
.if(sprite == 6) sta $D00D
.if(sprite == 7) sta $D00F
}
.macro DrawSprites() {
.print "DrawSprites: " + fnPrintMemoryAddress(*)
!drawstart:
ldx #$00
ldy #$00
!loop:
lda SORTSPRX, y
sta $D000, x
lda SORTSPRY, y
sta $D001, x
inx
inx
iny
cpy #$08
bne !loop-
clc
adc #$18
sta $D012
lda #<!drawstart+
sta $FFFE
lda #>!drawstart+
sta $FFFF
jmp !exit+
!drawstart:
ldx #$00
ldy #$08
!loop:
lda SORTSPRX, y
sta $D000, x
lda SORTSPRY, y
sta $D001, x
inx
inx
iny
cpy #$10
bne !loop-
clc
adc #$18
sta $D012
lda #<!drawstart+
sta $FFFE
lda #>!drawstart+
sta $FFFF
jmp !exit+
!drawstart:
ldx #$00
ldy #$10
!loop:
lda SORTSPRX, y
sta $D000, x
lda SORTSPRY, y
sta $D001, x
inx
inx
iny
cpy #$18
bne !loop-
clc
adc #$04
sta $D012
lda #<SortSprites
sta $FFFE
lda #>SortSprites
sta $FFFF
!exit:
}
//*****************************************************************************
// Map virtual sprites to physical ones
//*****************************************************************************
.macro MapSprites() {
}
.macro MoveSprites() {
.print "MoveSprites: " + fnPrintMemoryAddress(*)
ldx #$00
ldy #$00
!loop:
lda #$01
adc SPRY, y
// sta SPRY, y
iny
cmp #num_sprites
bne !loop-
}
//*****************************************************************************
// Sort the sprite arrays
//*****************************************************************************
.macro SortSprites() {
ldx #$00
!loop:
ldy SORTORDER + 1, x
lda SPRY, y
ldy SORTORDER, x
cmp SPRY, y
bcs !dontswap+
!swap:
lda SORTORDER + 1, x
sta SORTORDER, x
tya // Y still has previous value
sta SORTORDER + 1, x // This can be sped up with ZP
!dontswap:
inx
cpx #num_sprites - 1
bne !loop-
!donesorting:
// Now that the SORTORDER index is sorted,
// copy the sorted indexes to the SORT tables
ldx #$00
!loop:
ldy SORTORDER, x
lda SPRY, y
sta SORTSPRY, x
lda SPRX, y
sta SORTSPRX, x
lda SPRC, y
sta SORTSPRC, x
lda SPRF, y
sta SORTSPRF, x
inx
cpx #num_sprites
bne !loop-
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment