Last active
June 3, 2023 12:08
-
-
Save cbmeeks/7f4c770915e5c53b70fa to your computer and use it in GitHub Desktop.
sprites.asm -- Commodore 64 Sprite Multiplexer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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