On 11/23/2021 at 6:43 AM, Ed Minchau said:
That's what my little algorithm above does. The result isn't 16.8, but can be shifted there.
Yes, I was replying to a comment in the first page of the comments without reading the second page yet.
On 11/23/2021 at 4:35 AM, paulscottrobson said:
As it's a 16 bit value you could probably just divide the upper byte by 1024, which would be >> 8x >> 2 which would be quicker and only marginally less accurate. ...
Though for a 16.8 result, the high six bits of the lower byte are still part of the result, and the second from the bottom bit could be used for rounding ... indeed, do the /1024 second, so that the second from the bottom bit is in the carry. However, the /1024 means that high byte of the result is 0, so can be omitted. I get about 45 bytes.
proc calculate_tick_rate: near
; X/Y = tick rate (Hz) - divide by approximately 60 and store to zsm_steps
; use the ZP variable as tmp space
; Actually (X/64)+(X/1024), which is within 0.3% of X/60.
; use the ZP variable as tmp space
val1 := r11
frac1:= r12
val2 := r13
txa
sty val1
asl
rol val1
rol val1+1
asl
rol val1
asl val1+1
sta frac1
txa
sty val2
lsr val2
ror
lsr val2
ror
adc frac1
sta zsm_fracsteps
lda va1
adc val2
sta zsm_steps
lda val1+1
adc #0
sta zsm_steps+1
rts