The Blitter is an arrangment of logic gates, registers, and counters that may be used to copy rectangular areas up to 127×127 pixels from Sprite RAM to the framebuffer. This copy runs in parallel to CPU execution and copies at a rate of 1 pixel per CPU clock cycle. If the DMA_IRQ flag is set, the Blitter will assert an IRQ signal when a copy operation completes.
Using the blitter is roughly analogous to using ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
in Javascript.
There are seven registers used for preparing a copy operation and an additional address used for initiating the copy operation. In order to access these registers, DMA_ENABLE must be set.
Addr | Name | Use |
---|---|---|
$4000 | VX | X coordinate in framebuffer of left column of drawing |
$4001 | VY | Y coordinate in framebuffer of top row of drawing |
$4002 | GX | X coordinate in Sprite RAM for first column of source data |
$4003 | GY | Y coordinate in Sprite RAM for first row of source data |
$4004 | WIDTH | Width of drawing operation. Bit 7 controls horizontal flipping. |
$4005 | HEIGHT | Height of drawing operation. Bit 7 controls vertical flipping. |
$4006 | START | Write 1 to clear IRQ and begin a blit operation. Write 0 to clear IRQ without starting a blit. |
$4007 | COLOR | Value to use for Color Fill Mode. Value is inverted. Only used when DMA_COLORFILL_ENABLE is set. |
VX, GX, and WIDTH are read both at the start of a blit and at the end of every row. COLOR is read for every pixel in color fill mode. Modifying these during a blit operation with careful timing can produce a variety of effects. However, if you want to copy the sprite normally these registers should be left alone during a blit.
For solid color fills, the value written to the COLOR register should be inverted from the expected color number. So to write a color with value 213 set the register to 42.
The values of GX and GY last used by the Blitter will also influence which part of Sprite RAM the CPU can access in addition to the Banking Register. The video section of the memory map is only big enough for a 128×128 region. So the quadrant of Sprite RAM available to the CPU is determined by the most significant bit in the Sprite RAM coordinate counters. Typically these would be set before loading sprites by running a single-pixel blit operation copying from the target quadrant to an off-screen portion of the framebuffer.
Every blit takes the same number of cycles as pixels it covers, including skipped transparent pixels. The blitter runs on the same clock as the CPU, which happens to be set at the NTSC colorburst frequency. This can be calculated as exactly 315/88 MHz, or 315,000,000/88 pixels per second. Dividing by 60, we get the theoretical maximum number of pixels that can be drawn at 60Hz: 59,659 pixels per frame which is roughly 3.6 times the size of a frame buffer.
However, this 59659 figure doesn't account for CPU time spent managing the blitter or finishing up other tasks before it can trigger the next blit. So it's at best a rough measure of how much you can draw before the blitter becomes the bottleneck.