Page 1 of 1
BCD increment without SED?
Posted: Sat Feb 22, 2020 8:26 pm
by mvk
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".
Code: Select all
; 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.
Context: I'm trying to achieve a slightly more faithful execution of this number guessing game on a certain system without decimal mode.
https://www.applefritter.com/files/Appl ... ermind.pdf
Re: BCD increment without SED?
Posted: Sun Feb 23, 2020 10:10 am
by mvk
This is my best shot. First put an escape in place with this JSR:
Code: Select all
JSR NXTBCD
ADC TRIES ; ADD 1 TO TRIES IN DECIMAL MODE
STA TRIES
Then do the work in these 13 extra bytes:
Code: Select all
NXTBCD: LDA TRIES
AND #$F ; Low nibble
CMP #9 ; Is it 9?
BEQ LOW9 ; If yes, add 7
LDA #4 ; Otherwise add 1
LOW9: SBC #3
RTS
Testing works. The game's try counter wraps from $09 to $10:
Re: BCD increment without SED?
Posted: Sun Feb 23, 2020 1:32 pm
by Martin A
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.
Code: Select all
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)
Code: Select all
0941 OPT X%
0941 .byte
0941 00 EQUB 0
0942 00 EQUB 0
0943 .start
0943 A9 F7 LDA #&F7
0945 18 CLC
0946 6D 41 09 ADC byte
0949 B0 02 BCS ten
094B E9 05 SBC #5
094D .ten
094D E9 F0 SBC #&F0
094F 8D 41 09 STA byte
0952 60 RTS
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
Re: BCD increment without SED?
Posted: Sun Feb 23, 2020 4:32 pm
by 8BIT
Sorry, I missed this part:
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.
Code: Select all
INC TRIES
LDA TRIES
CMP #$0A
BNE DONE
LDA #$10
STA TRIES
DONE
Actually, this will count to 19 correctly.
Hope that helps!
Daryl
Re: BCD increment without SED?
Posted: Sun Feb 23, 2020 10:01 pm
by barrym95838
Kind of slow, but smaller than the other patches and works through [edit:
up to] 99 (allegedly):
Code: Select all
plus1:
inc tries
lda tries
and #$0f
cmp #$0a
bcs plus1
You can turn the middle three instructions into a subroutine if you don't want to affect your original labels.
Re: BCD increment without SED?
Posted: Sun Feb 23, 2020 10:44 pm
by mvk
Kind of slow, but smaller than the other patches and works through 99 (allegedly):
That is 10 bytes. The original has 7, so you need 3 bytes to avoid SED. That passes as amazingly clever with me.
[Edited out some of my earlier confusion]
Re: BCD increment without SED?
Posted: Mon Feb 24, 2020 12:18 am
by GARTHWILSON
How far up does it need to count? Is 0-19 ok, or does it need to go further?
Re: BCD increment without SED?
Posted: Mon Feb 24, 2020 7:05 am
by mvk
How far up does it need to count? Is 0-19 ok, or does it need to go further?
Certainly past 19. A bad guesser needs many tries. But it doesn't really matter what happens after 99...
Re: BCD increment without SED?
Posted: Mon Feb 24, 2020 2:28 pm
by 8BIT
Kind of slow, but smaller than the other patches and works up to 99 (allegedly):
Code: Select all
plus1:
inc tries
lda tries
and #$0f
cmp #$0a
bcs plus1
You can turn the middle three instructions into a subroutine if you don't want to affect your original labels.
Nice work Mike! Since speed was not an issue, this is a tidy solution.
Daryl
Re: BCD increment without SED?
Posted: Tue Feb 25, 2020 1:48 am
by Chromatix
This seems like a straightforward way to do it, testing the lower nybble directly and conditionally forcing it to carry through:
Code: Select all
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:
Code: Select all
Plus1C:
LDA tries
AND #$F
CMP #9
BNE :+
LDA #$F
: ORA tries
INC A
STA tries
RTS
Re: BCD increment without SED?
Posted: Sat Feb 29, 2020 3:58 pm
by mvk
Kind of slow, but smaller than the other patches
I replaced my solution with yours. By keeping it inline, the original program grows with just 2 bytes to a grand total of 172. Bravo!
https://github.com/kervinck/gigatron-ro ... ae0d1307f6