Copper: Exact WAIT TimingThe Copper allows quite fine-grained raster timing for time-critical hardware register changes. This was a great improvement from the so-called "splits" on 8-bit computers and Atari ST where you waited with an interrupt and/or a CPU loop for a certain position.
On Amiga, it's done automatically in the background for you, without wasting cycles waiting.
Such a "split" is most often used to change colors, bitplane pointers or similar things at a certain position. It's easy to do with the Copper:
dc.w $4005,$fffe ;waits for vertical position $40, first raster stop position outside the left ;edge of the screen dc.w $180,$f0f ;sets the background-color to bright magenta
Each Copper command takes 8 cycles = 8 pixels = 4 increments of the raster position to execute on the OCS chipset.
$05 here is the stop position after horizontal blanking on OCS that results in the MOVE, executed 8 pixels later, modifying the background color visibly on the start of that line. Any lower position*, or a position such as $3fff or $3fdf, results in the background color being changed on the previous line.
Multiple MOVEsIf you need to load more than one register, you must subtract 4 from this virtual position for each MOVE.
For example, if you wanted to load a 15 color palette on each raster line (keeping the background color constant), you would calculate backwards from the horizontal point when the data for the next line has to be ready.
When does the data have to be ready?For palette colors as in the above example, it's enough that it's ready in time for the left edge of the screen, or $38 for the above standard screen. When this position is reached, DMA will load up to 6 bitplanes in 16 cycles.
The corresponding raster wait position for a MOVE to match up with the left edge is then position $3d.
For modulos, bitplane pointers, and other fixed DMA fetch positions, you would have to set them early to make sure they get picked up at their assigned time slots. Refer to the display timing diagram in Hardware Reference Manual for the exact positions.
In our palette example, for a standard 320px wide screen, you would start from the left edge wait position that included 1 MOVE (1 color), $3d. You have 14 more colors to move, so you would subtract 14*4 from $3d, giving you position $05.
NOTE: It's pure coincidence that this is the same as the first stop position on a new line.
If you wished to set the background color as well, you'd encounter the horizontal blanking. Any position from $e5..$03 would be the same as position $e5. Any position in this span is treated as if it were $e5. You could say "the position 4px before $05" is $e5.
We need 8px to set the extra color though, so our position must be $e3. Here is our 16 color example:
dc.w $3fe3,$fffe dc.w $180,$000 dc.w $182,$111 dc.w $184,$222 dc.w $186,$333 dc.w $188,$444 dc.w $18a,$555 dc.w $18c,$666 dc.w $18e,$777 dc.w $190,$888 dc.w $192,$999 dc.w $194,$aaa dc.w $196,$bbb dc.w $198,$ccc dc.w $19a,$ddd dc.w $19c,$eee dc.w $19e,$fff ;after this executes, raster should be at position $4038.