Quick Post: Commodore 64 Simple Addition Efficiency
By Michael Doornbos
- 3 minutes read - 438 wordsThere are many hacks you can do in Assembly language on the Commodore.
Here’s a very easy one with impressive results according to my analog stopwatch.
We want to count to $ffffff or 2563 (224) which is 16,777,216
We wont print to the screen to save a lot of time, and just put an “a” in the top right corner when we’re done.
One way (and yes, I want to know all the other ways you know of to do this) would be:
*=c000
counter
lda #0
loop clc
lda result
adc #1
sta result
lda result+1
adc #0
sta result+1
lda result+2
adc #0
sta result+2
cmp #$00
bne loop
lda #$01
sta $0400 ;print an a top left when done
rts
result .byte 0,0,0
This takes almost 12 minutes to complete on an NTSC Commodore 64. Not bad for a 1Mhz machine.
But we can skip some of this addition in our loop in 2 places using the same technique. Since the second and third additions are just adding the carry bit, we can skip it if carry is clear. So now we have:
*=c000
counter
lda #0
loop clc
lda result
adc #1
sta result
bcc ahead ; branch ahead if carry clear
lda result+1
adc #0
sta result+1
bcc ahead ; branch ahead if carry clear
lda result+2
adc #0
sta result+2
cmp #$00
ahead
bne loop
lda #$01
sta $0400 ;print an a top left when done
rts
result .byte 0,0,0
This takes 5.5 minutes. More than twice as fast.
Finally, we need to handle the remainder counts. There are probably about 50 ways to do this and this might not be the most efficient, but it works.
*=c000
counter
lda #0
loop clc
lda result
adc #1
sta result
bcc ahead ; branch ahead if carry clear
lda result+1
adc #0
sta result+1
bcc ahead ; branch ahead if carry clear
lda result+2
adc #0
sta result+2
cmp #$00
ahead
bne loop
lda result+1
remain1
cmp #$ff
beq ahead
clc
adc #1
sta result+1
jmp remain1
ahead1
lda result
remain
cmp #$ff
beq ahead
clc
adc #1
sta result
jmp remain
ahead
done
lda #$01
sta $0400 ;print an a top left when done
rts
result .byte 0,0,0
While I don’t think any of us is doing a ton of serious “work” on a Commodore any more, it’s definitely interesting to think about efficiencies like this. Solving this particular one helped me “see” a problem with a client in my day job and we managed to regain about 30% of server resources by looking at an existing problem for solutions like this.