I'm looking to replace the following snippet with something that doesn't use decimal mode. It should increment TRIES if its lower nibble is under 9, or add 7 if that nibble equals 9. All other cases are "don't care".
; Precondition: A = 0
SEC
SED
ADC TRIES ; ADD 1 TO TRIES IN DECIMAL MODE
STA TRIES
CLD
The replacement doesn't have to be in situ (that would surely be impossible). Speed is not important. Of course I know how to write something straightforward that works. But I'm hoping there's an amazingly clever bit trick out there that is just begging to be used.
I came up with this 15 byte routine using an ADC designed to roll over if 9+ is input, with a BBC basic wrapper for testing. If the target byte were in zero page it would shave off a couple of bytes, but it's still too big.
REM BCD increment test
DIM code 30
FOR X%=0 TO 3 STEP 3
P%=code
[OPT X%
.byte
EQUB 0
EQUB 0
.start
LDA #&F7
CLC
ADC byte
BCS ten
SBC #5
.ten
SBC #&F0
STA byte
RTS
]
NEXT
FOR X%=0 TO 9
?byte=X%
CALL start
PRINT;~X%," ";~?byte
NEXT
The output is as expected for 0 to 9 (the ~ forces BBC basic to output numbers in hex)
Of course I know how to write something straightforward that works. But I'm hoping there's an amazingly clever bit trick out there that is just begging to be used.
I am not aware of much beyond masking the nibbles and testing for overflow method for generic BCD math.
If the goal is to count to 10, then this will work.
Plus1:
LDA tries
AND #$F
CMP #9
BNE :+
LDA #$F
: ORA tries
STA tries
INC tries
RTS
This is 16 bytes, 22 cycles (without the RTS since you can inline this), and avoids the looping. It could be 15 bytes, 19 cycles if specialised for a CMOS 6502, which I'm pretty sure got used in the Tamagotchi toys: