[resolved][puzzle] Drifter, The
kuroneko
Posts: 3,623
The attached program upsets the video h/w to generate a 32MHz pixel clock based on an 80MHz system clock, i.e. one pixel lasts 2.5 system clocks. After we synchronised to the waitvid hand-off point (WHOP) we delay for a frame and subsequently use a cmp insn in a 40 cycle loop (16 pixels per frame, 16 * 2.5 = 40 system clocks). Which works well up to a point, then the WHOP has drifted into the neighbouring insns and the video h/w outputs a guard pattern instead of the intended match pattern (demoboard LED bar). This is no surprise given that the frqx setup is not a power of two value.
Objective: Stabilise the WHOP so it stays within the designated compare insn.
Objective: Stabilise the WHOP so it stays within the designated compare insn.
waitvid zero, #0
mov dira, mask ' drive outputs
'-----------------------------------------------
[COLOR="orange"]waitvid zero, #0[/COLOR] ' sync point
[COLOR="blue"]mov cnt, cnt[/COLOR] '
[COLOR="blue"]add cnt, #9{14} + 19[/COLOR] '
[COLOR="blue"]waitcnt cnt, #0[/COLOR] ' adjust for one frame
'-----------------------------------------------
:loop [COLOR="red"]cmp match, #0[/COLOR] ' WHOP
cmp guard, #0
cmp guard, #0
cmp guard, #0
cmp guard, #0 ' +20
cmp guard, #0
cmp guard, #0
cmp guard, #0
cmp guard, #0
jmpret guard, #:loop nr ' +40


Comments
:loop cmp match, #0 ' WHOP add frqa, #1 cmp guard, #0 cmp guard, #0 cmp guard, #0 ' +20 cmp guard, #0 cmp guard, #0 sub frqa, #1 cmp guard, #0 jmpret guard, #:loop nr ' +40So far, it hasn't slipped.
-Phil
Addendum: 'Checked back after an hour; still no slippage evident.
@all: The fact that puzzle and Phil both start with the letter P doesn't mean that only he can participate!
-Phil
The original solution simply sampled an appropriate phsa which is then inserted in the loop later (at the same offset). While picking a hard-wired value works, care must be taken to pick one far enough away from the critical points. Also, given that we are sync'd already the new/forced value shouldn't upset the PLL from that point onward. FWIW, using $19999999 gives you $04444444 stable NCO cycles which amounts to ~9sec @80MHz. Plenty of room.
CON _clkmode = XTAL1|PLL16X _xinfreq = 5_000_000 PUB drifter cognew(@entry, 0) DAT org 0 entry movi ctra, #%0_00001_101 ' PLL, VCO/4 mov frqa, frqx ' 8MHz * 16 / 4 = 32MHz movd vscl, #1 << (12 - 9) ' 1 clock per pixel movs vscl, #16 ' 16 clocks per frame movd vcfg, #2 ' pin group movs vcfg, #%0_11111111 ' pins movi vcfg, #%0_01_0_00_000 ' VGA, 2 colour mode rdlong cnt, #0 ' shr cnt, #10 ' ~1ms add cnt, cnt ' waitcnt cnt, #0 ' PLL needs to settle waitvid zero, #0 mov dira, mask ' drive outputs '----------------------------------------------- waitvid zero, #0 ' sync point mov cnt, cnt ' add cnt, #9{14} + 19 ' waitcnt cnt, #0 ' adjust for one frame '----------------------------------------------- cmp match, #0 {0} ' WHOP mov sync, frqa {1} ' frqa * 1 add sync, frqa {2} ' frqa * 2 add sync, phsa {3} ' frqa * 2 + phsa(-2) (%%) mov cnt, cnt ' add cnt, #9{14} + 10 ' waitcnt cnt, #0 ' complete sample frame '- - - - - - - - - - - - - - - - - - - - - - - - :loop [COLOR="red"]cmp match, #0[/COLOR] {0} ' WHOP cmp guard, #0 {1} cmp guard, #0 {2} mov phsa, sync {3} ' rewind/lock (%%) cmp guard, #0 ' +20 cmp guard, #0 cmp guard, #0 cmp guard, #0 cmp guard, #0 jmpret guard, #:loop nr ' +40 ' initialised data and/or presets mask long $00FF0000 frqx long $19999999 ' clkfreq/10 (stable for ~9 sec, $0444_4444 NCO cycles) match long $24242424 guard long $3C3C3C3C ' uninitialised data and/or temporaries sync res 1 fit CON zero = $1F0 ' par DAT