Table of Contents

Blitter

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.

Blitter Registers

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.

Blitter Limits

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.