bogax wrote:
Omegamatrix wrote:
I have written a number of division routines in 6502 assembly, and I'm posting them here for other people to use.
These routines start with any value (0-255) in the accumulator and finish with the integer division result in the accumulator. They are all constant cycles and do not use X or Y. Most do require 1 temp register. I've listed all divisions from 2 to 32 below, including the trivial divide by powers of 2 cases (for sake of completion).
I always thought it was a pity that you didn't keep
(or maybe even look for) routines of less accuracy.
eg if you know your dividend will never be >40
you might get by with less code.
Funny you should mention that, as I was just staring at the routines I posted and it occurred to me that in some cases I might be able to go quicker by doing a division up front to reduce the sum, and follow with a cruder approximation second. As simple as that sound it never occurred to me when I wrote them.
So... I was immediately able to make five of the routines better.
I am going to update the first post but in summary here are the updated routines:
Old:
Code:
;Divide by 6
;1/6 = 1/3 * 1/2
;19 bytes, 32 cycles
sta temp
lsr
adc #21
lsr
adc temp
ror
lsr
adc temp
ror
lsr
adc temp
ror
lsr
lsr
;Divide by 10
;1/10 = 1/5 * 1/2
;19 bytes, 32 cycles
sta temp
lsr
adc #13
adc temp
ror
lsr
lsr
adc temp
ror
adc temp
ror
lsr
lsr
lsr
;Divide by 20
;1/20 = 1/5 * 1/4
;20 bytes, 34 cycles
sta temp
lsr
adc #13
adc temp
ror
lsr
lsr
adc temp
ror
adc temp
ror
lsr
lsr
lsr
lsr
;Divide by 24
;1/24 = 1/3 * 1/8
;21 bytes, 36 cycles
sta temp
lsr
adc #21
lsr
adc temp
ror
lsr
adc temp
ror
lsr
adc temp
ror
lsr
lsr
lsr
lsr
;Divide by 26
;1/26 = 1/13 * 1/2
;22 bytes, 39 cycles
sta temp
lsr
adc temp
ror
adc temp
ror
adc temp
ror
lsr
lsr
clc
adc temp
ror
lsr
lsr
lsr
lsr
And new:
Code:
;Divide by 6
;17 bytes, 30 cycles
lsr
sta temp
lsr
lsr
adc temp
ror
lsr
adc temp
ror
lsr
adc temp
ror
lsr
;Divide by 10
;17 bytes, 30 cycles
lsr
sta temp
lsr
adc temp
ror
lsr
lsr
adc temp
ror
adc temp
ror
lsr
lsr
;Divide by 20
;18 bytes, 32 cycles
lsr
lsr
sta temp
lsr
adc temp
ror
lsr
lsr
adc temp
ror
adc temp
ror
lsr
lsr
;Divide by 24
;15 bytes, 27 cycles
lsr
lsr
lsr
sta temp
lsr
lsr
adc temp
ror
lsr
adc temp
ror
lsr
;Divide by 26
;21 bytes, 37 cycles
lsr
sta temp
lsr
adc temp
ror
adc temp
ror
adc temp
ror
lsr
lsr
adc temp
ror
lsr
lsr
lsr
I am very happy that a new solution for divide by 10 has been found.
Edit - Divide by 12 has also been superseded!
Double Edit - Divide by 28 too!
old:
Code:
;Divide by 12
;1/12 = 1/3 * 1/4
;20 bytes, 34 cycles
sta temp
lsr
adc #21
lsr
adc temp
ror
lsr
adc temp
ror
lsr
adc temp
ror
lsr
lsr
lsr
;Divide by 28
;1/28 = 1/7 * 1/4
;17 bytes, 31 cycles
sta temp
lsr
lsr
lsr
adc temp
ror
lsr
lsr
adc temp
ror
lsr
lsr
lsr
lsr
new:
Code:
;Divide by 12
;17 bytes, 30 cycles
lsr
lsr
sta temp
lsr
adc temp
ror
lsr
adc temp
ror
lsr
adc temp
ror
lsr
;Divide by 28
;14 bytes, 24 cycles
lsr
lsr
sta temp
lsr
adc #2
lsr
lsr
adc temp
ror
lsr
lsr