Here are some extraction from an article: Missing Cycles
by Pasi 'Albert' Ojala. In short, VIC
needs to fetch the sprite data from memory. For each sprite it needs to fetch 3 bytes (one line of sprite shape) for each scanline.
If there are sprites on the screen, the VIC needs even more cycles to
fetch all of the graphics data. Scan lines are time divided so that
there is enough time for all action during one line. On each line, the
sprite image pointers are fetched during phase 1. If the sprite is to
be displayed on that line, the three bytes of image data are fetched
right after that. Out of these three fetches, two take place during
phase 2 of the clock, so the processor will lose these. On average,
two clock cycles are lost for each sprite that is displayed on that
line.
The most interesting part is that it should take 24 cycles (8 sprites * 3 bytes), but in fact it takes only 16-19 cycles. This is caused by special case of sharing the bus
between VIC
and CPU
.
When the VIC wants to use the bus, the BA (Bus Available) signal goes
inactive. This will happen three cycles before the bus must be
released ! During these three cycles, the CPU must complete all memory
accesses or delay them until it has the bus again.
The CPU either completes the current instruction in the remaining
cycles or sits and waits for the bus to become available again. It
can't execute a new instruction as long as it doesn't have the bus.
This is why cycles seem to be lost (besides those stolen directly for
the sprites). Usually, all 8 sprites take 17 cycles while one sprite
takes three cycles. However, the CPU may continue to execute an
instruction if it does not use the bus.
So VIC
is 'stealing' some cycles. Here are some examples:
Let's suppose that all the sprites are enabled and on the same scan
line. Then, the VIC steals 16 cycles (2 cycles for each sprite) for
the memory fetches and 3 cycles as overhead for the BA signal, for a
total of 19 cycles. However, it will be usually less because the CPU
will use some of the cycles when the bus request is pending.
If we now disable sprite 4, no cycles are released for the CPU's use.
This is because during the previous sprite 4 data fetch, the VIC
already signals that it needs the bus for the sprite 5 data fetch and
BA stays low (Refer to the timing chart). Thus, the CPU never sees BA
go high during sprite 4 and 2 cycles are still lost.
Accordingly, if we only turn off sprites 1, 3 and 5 we get no cycles
back from the VIC. So in time-critical raster routines, always use
sprites in order.
And the concluding timing table for missing cycles:
012345678901234567890123456789012345678901234567890123456789012 cycles
Normal scan line, 0 sprites
ggggggggggggggggggggggggggggggggggggggggrrrrr p p p p p p p p phi-1 VIC
phi-2 VIC
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx phi-2 6510
63 cycles available
Normal scan line, 8 sprites
ggggggggggggggggggggggggggggggggggggggggrrrrr pspspspspspspsps phi-1 VIC
ssssssssssssssss phi-2 VIC
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxXXX phi-2 6510
46-49 cycles available
Normal scan line, 4 sprites
ggggggggggggggggggggggggggggggggggggggggrrrrr psp psp psp psp phi-1 VIC
ss ss ss ss phi-2 VIC
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxXXX xx phi-2 6510
48-51 cycles available
Bad scan line, 0 sprites
ggggggggggggggggggggggggggggggggggggggggrrrrr p p p p p p p p phi-1 VIC
cccccccccccccccccccccccccccccccccccccccc phi-2 VIC
xxxxxxxxxxxxxxxxxxxxxxx phi-2 6510
23 cycles available
Bad scan line, 8 sprites
ggggggggggggggggggggggggggggggggggggggggrrrrr pspspspspspspsps phi-1 VIC
cccccccccccccccccccccccccccccccccccccccc ssssssssssssssss phi-2 VIC
xxxxXXX phi-2 6510
4-7 cycles available
g= grafix data fetch (character images or graphics data)
r= refresh
p= sprite image pointer fetch
c= character and color CODE fetch during a bad scan line
s= sprite data fetch
x= processor executing instructions
X= processor executing an instruction, bus request pending
You can use it to synchronize raster line using sprites.
For more information (including demonstration program), please refer to the full article: "Missing Cycles" by Pasi 'Albert' Ojala.