[time-nuts] ANFSCD - Synchronizing time in home video recorders
kevin-usenet at horizon.com
kevin-usenet at horizon.com
Wed Feb 15 23:50:39 UTC 2012
> It's possible to use Bresenham with two integers 10,000,000 and
> 32,768 but I found no way to perform all the 24-bit calculations
> on an 8-bit PIC quick enough. Removing the GCD often helps
> but in this case the accumulator remains 3-bytes wide.
Huh? Dividing 10,000,000 by 4 (to match the PIC instruction timing)
and multiplying 32768 by 2 (since you have to generate both edges),
you want to generate an edge every 2500000/65536 instruction
cycles.
That's every 38 or 39 cycles. To be precise, 38 instructions
most of the time and 39 instructions 9632/65536 of the time.
Since the divisor is a power of 2, this fits conveniently
into a 16-bit accumulator. Let me see if I can put the code
together...
cblock 0x20
gpcopy
lsb
msb
tmp
endc
step equ d'9632'
loop: ; Cycles at end of instruction
comf gpcopy,f ; 1
movf gpcopy,w ; 2
movwf GPIO ; 3
movlw 8 ; 4
movwf tmp ; 5
delay:
decfsz tmp,f ; 6, 9,12,15,18,21,24,27
goto delay ; 8,11,14,17,20,23,26
nop ; 29
movlw step&0xff ; 30
addwf lsb, f ; 31
movlw step>>8 ; 32
skpnc ; 33
movlw (step>>8)+1 ; 34
addwf msb, f ; 35
skpc ; 36
goto loop ; 38
goto loop ; 39
The minimum length of this loop is 12/13 cycles, but it depends on a
power-of-2 output frequency (after modulo reduction, so you could have
powers of 5 as well).
With some clever unrolling, it can be reduced to 10/11 cycles:
loop:
clrf GPIO ; 1
movlw step&0xff ; 2
addwf lsb, f ; 3
movlw step>>8 ; 4
skpnc ; 5
movlw (step>>8)+1 ; 6
addwf msb, f ; 7
skpnc ; 8
goto $+1 ; 10
movlw 0xff ; 10/11
movwf GPIO ; 1
movlw step&0xff ; 2
addwf lsb, f ; 3
movlw step>>8 ; 4
skpnc ; 5
movlw (step>>8)+1 ; 6
addwf msb, f ; 7
skpc ; 8
goto loop ; 10
goto loop ; 11
An arbitrary divisor will complicate this somewhat, but not actually
add very much time. You just need two matched code paths, which add
"step", or "step + 65536-divisor" to the accumulator as appropriate.
There may also be some way to use higher-order Bresenham to reduce things
to 8 bits, at the expense of needing the subroutine stack.
Here, we have 38 instructions most of the time, and 39 instructions
9632/65536 = 301/2048 of the time. That means that the pattern is
either 5x38+39 or 6x38+39, with the latter happening (2048%301)/301 =
242/301 of the time.
Since we have the 5x38+39 pattern happening 59/301 of the time, you
have 5x(6x38+39)+(5x38+39) some of the time, and 6x(6x38+39)+(5x38+39)
the rest of the time. My brain is getting tangled figuring out which is
which, but it's one of them (301%59)/59 = 6/59 of the time and
the other 53/59 of the time. You could use a 1-byte accumulator, or
just open-code that part of the pattern.
More information about the Time-nuts_lists.febo.com
mailing list