I recently had a need to decrement words (addresses) by two, which is not
quite so simple as
decrementing them by one. There's an obvious choice between using SUB or using DEC twice, so I coded up both to see which worked better. (Spoiler: SUB won by a mile.) You can look at the full
code and
test files if you like but here's the summary:
Code:
; The byte and cycle counts assume zero page addressing. The first cycle
; column is for the case where the MSB is not decremented, and the second
; for the case when it is.
;
; byte and cycle counts assume ZP addressing
; first cycle column is for branch taken
decw_sub: lda val ; 2b 2c
sec ; 1b 2c
sbc #2 ; 2b 2c
sta val ; 2b 3c
bcs .done ; 2b 3c 2c
dec val+1 ; 2b 5c
.done ; ────────────
rts ; 9b 12c 16c TOTALS
decw_dec: lda val ; 2b 2c
bne .nz1 ; 2b 3c 2c { at least one
dec val+1 ; 5c of these two
.nz1 dec val ; 2b 5c branches must
bne .nz2 ; 2b 3c 2c { be taken
dec val+1 ; 5c
.nz2 dec val ; 2b 5c
; ───────────
rts ; 10b 18c 22c TOTALS
The test values (input, output) I used are:
Code:
(0xFFFF, 0xFFFD), (0x8001, 0x7FFF), (0x7000, 0x6FFE), (0x0000, 0xFFFE)
Did I miss any test values that could expose a mistake, incorrect cycle counts, tricks for even faster (or smaller) ways of doing this, or anything else?
I also noticed that we don't seem to have anything in the 6502.org
Source Code Repository related to incrementing and decrementing. Maybe it's worth linking from there to the
Wikidot page (which I find pretty useful). If someone wants to add any of the above to either, I'm fine with that.