Code: Select all
; Prior to entry:
; a1 = $ffff8260 (i.e. 72Hz override)
; a0 = $ffff820a (i.e. 50/60Hz mode selection)
; d2 = 4, d4 = 0
; (and a3 = $ffff8240, the start of the palette, a5 = pointer to a colour table, d0 = line count-1)
4: move.b d2, (a1) ; switch to 72Hz at n = 8
12: move.b d4, (a1) ; switch to 50Hz at n = 16
20: moveq #20, d1
28...: dbf d1, loop
; d1 was loaded with 20, so loop occurs 21 times; in net,
; factoring in Dtack delay on the first access in the dbf each
; time, it costs:
; 20 *
; np [nop], n np np [dbf, branching] = 16
; + 1 *
; np [nop], n np np np [dbf, no branch due to counter expiry] = 20
; = 340 cycles total, and it started at n = 24
; => it ends at n = 364
376: move.b d4, (a0) ; switch to 60Hz at n = 380 [+ 1] = 381
384: move.b d3, (a0) ; switch to 50Hz at n = 388 [+ 1] = 389
444: move.b d2, (a1) ; switch to 72Hz at n = 448
456: move.b d4, (a1) ; switch to 50Hz at n = 460
464: move.w (a5)+, $1e(a3) ; palette change
500: dbf d0, begin ; branch taken, so +12 = 512, as expected.
Slightly weird formatting — I've added the number of cycles since the loop began as a first column. The +1s attributed to the moves at 376 and 384 are because the Wiki appears to attribute a one-cycle latency to `820a` changes.
Pulling out just the mode changes, I get relative spacings:
- 8: switch to 72Hz;
- 16: switch to 50Hz;
- 381: switch to 60Hz;
- 389: switch to 50Hz;
- 448: switch to 72Hz;
- 460: switch to 50Hz.
The demo synchronises itself to the state machine prior to entering this loop by watching for a change in current video address. You could probably guess, but specifically:
- the switch to 72Hz at the 8th cycle of the loop and to 50Hz on the 16th opens the left border by toggling into 72Hz mode across wiki cycle 4;
- the switch to 60Hz at 381 and back to 50Hz at 389 opens the right border by switching from 50 to 60 between wiki cycles 372 and 376; and
- the switch to 72Hz at 448 and back to 50Hz again at 460 removes horizontal blank by being in 72Hz mode during wiki cycle 450.
Actual questions, then:
If all of the above is correct, and the wiki information is sufficiently complete, DE will first go active at wiki cycle 4, and will remain active until hsync begins at wiki cycle 462.
That seems to imply 462 - 4 = 458 cycles of load being active. So 114 loads (and partway towards a 115th, but without reaching it).
114 isn't a multiple of four. It's 28 columns of four words, plus another two words.
So, question one: is 114 loads correct according to that evidence? Have I made any errors in my workings so far?
Questions two and onward: if 114 words is correct, what happens to the dangling two words? The wiki mentions a check as to whether the FIFO is full every 16 cycles — is that 16 cycles while load is active (rather than in geeneral), and is the count to 16 reset when load goes inactive? If so then is it correct to think the dangling two words will be fetched but not used?
I can't see how a model where the two words get used on the next line works, without ending up with pixels over the retrace period that would really mess up the output. But maybe my complete understanding of the Shifter side of things is amiss?