Bogax's solution is 4 cycles faster too, despite the use of the stack.
But, in either case, that's damn slick, and represents a style of coding I'd generally not think of. I rarely think of the carry bit as a single-bit storage location, because it's so often overwritten by other CPU instructions.
This is a good example of keeping multiple views of data in your head at once -- a register isn't "just a number."
Bit Counting
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
ElEctric_EyE wrote:
Forgive my ignorance,but what is the point of a "CMP #$10" without a branch instruction afterwards?
x86? We ain't got no x86. We don't NEED no stinking x86!
ElEctric_EyE wrote:
Forgive my ignorance,but what is the point of a "CMP #$10" without a branch instruction afterwards?
affecting the accumulator.
Since in this case all bits to the left of the fourth bit are zero
and carry will be set (no borrow) if the accumulator is greater than
or equal to $10 ie if bit four of the accumulator is set, the effect
is to copy bit four (p) to the carry
edit: borrowed the castrated swine
Last edited by bogax on Sun Dec 20, 2009 10:53 am, edited 1 time in total.
bogax wrote:
ElEctric_EyE wrote:
Forgive my ignorance,but what is the point of a "CMP #$10" without a branch instruction afterwards?
affecting the accumulator.
Since in this case all bits to the left of the fourth bit are zero
carry will be set (no barrow) if the accumulator is greater than
or equal to $10 ie if bit four of the accumulator is set, in effect
copying bit four (p) to the carry
BigDumbDinosaur wrote:
Only to condition flags to facilitate or affect a later operation. CoMParisons don't necessarily have to be followed by branches. In the above case, the effect on carry is what is wanted to possibly modify the result of the following ADC #$F0 instruction.
The first copy is taken from C and added into the bottom of A (stu), while simultaneously the second copy is put back into C - so the carry flag doesn't change during the ADC.
--Greg
I think I've managed to do it without the stack (haven't tested it yet)
No longer runs in constant time but it is a little faster
No longer runs in constant time but it is a little faster
Code: Select all
hgfedcba ?
asl gfedcba0 h
bcc SKIP gfedcba0 h
adc #$7F Sfedcba0 S ;SS is the Sum h+g
SKIP
rol fedcba0S S
rol edcba0SS f
adc #$80 ?dcba0SS e
and #$7F 0dcba0SS e
adc #$C0 ??cbaSSS d
and #$3F 00cbaSSS d
adc #$E0 ???baSSS c
and #$1F 000baSSS c
adc #$F0 ????aSSS b
and #$0F 0000aSSS b
adc #$F8 ?????SSS a
and #$07 00000SSS a
adc #$00 0000SSSS 0
I don't think I can beat that, bogax...
Code: Select all
; C ---A----
; ? hgfedcba
asl ; h gfedcba.
rol ; g fedcba.h
adc #$80 ; f Fedcbapq pq = h+g
rol ; F edcbapqf
asl ; e dcbapqf.
rol ; d cbapqf.e
adc #$84 ; c CbapqFtu pq = h+g+f tu = e+d
and #$7b ; c .bapq.tu
adc #$c0 ; b BBapq.tu tu = e+d+c
and #$3b ; b ..apq.tu
adc #$e0 ; a AAApqstu stu = e+d+c+b
and #$1f ; a ...pqstu
adc #$f0 ; p PPPPqstu stu = e+d+c+b+a
adc #$18 ; P ..mnQstu stu = e+d+c+b+a+p mn = p+q
cmp #$10 ; k ..mnQstu k = m|n = p|q = h|g|f
adc #$e0 ; m MMMnQstu stu = e+d+c+b+a+p+p|q
and #$07 ; m .....stu
adc #$00 ; . ....rstu rstu = e+d+c+b+a+p+p|q+p&q
;31b 36c