Sub-pages
Sprite Overview
Sprites are independent graphical objects that can be positioned anywhere on screen, regardless of the playfield display. Each sprite is 16 pixels wide and can be as tall as the visible display area. Normally, sprites appear in front of the playfield, obscuring whatever is behind them — the mouse pointer is a classic example.
The Amiga provides 8 hardware sprite channels (SPR0 through SPR7). Each sprite can display 3 colors plus transparency, for a total of 4 possible values per pixel. By combining two sprites into an attached pair, up to 15 colors plus transparency can be achieved.
How Sprite Colors Work
Each sprite line consists of two 16-bit data words, functioning like two mini-bitplanes. The color of each pixel is determined by combining the corresponding bits from both words:
- Bit 15 of both words determines the color of the leftmost pixel
- Bit 0 of both words determines the color of the rightmost pixel
- The two-bit combination selects one of 4 values:
00= transparent,01/10/11= three colors
Sprites do not have their own color registers. Instead, they share the upper half of the color palette (registers 16–31). Sprites are grouped in pairs, with each pair using 3 consecutive color registers:
Since sprites share palette entries 16–31 with the playfield, color conflicts arise when the playfield uses more than 16 colors. The 00 combination always means transparent — whatever is behind the sprite shows through.
Sprite DMA and Data Structure
Programming sprites on the Amiga is straightforward because the DMA controller handles most of the work. To display a sprite, you prepare a sprite data list in Chip RAM and point the corresponding DMA channel to it.
Each of the 8 sprites has its own DMA channel. However, each channel can only read two words per raster line — this is the fundamental reason sprites are limited to 16 pixels wide and 4 colors. Because two data words are read every line, the sprite height is limited only by the display window.
Sprite Data List Format
A sprite data list is a sequence of word pairs. Each pair contains either two control words (defining position) or two data words (defining pixels for one line).
The DMA controller reads the control words first, places them in the SPRxPOS and SPRxCTL registers, and waits until the beam reaches the starting line (VSTART). Then, at each subsequent line, it reads two data words and DENISE displays 16 pixels at the correct horizontal position. This continues until the ending line (VSTOP) is reached. The next two words are interpreted as new control words — if both are zero, the DMA channel goes idle until the next frame.
Control Word Layout
There are 9 bits each for horizontal and vertical positioning. Vertical resolution is one raster line, and horizontal resolution is one low-resolution pixel. These are independent of the playfield resolution mode.
The start position defines the upper-left corner of the sprite. VSTOP is the first line after the sprite (last line + 1). The sprite height is therefore VSTOP - VSTART lines.
Sprite positioning is constrained by the display window defined by DIWSTRT and DIWSTOP. If the control word coordinates fall outside the window, the sprite will be partially or fully clipped.
Example: 3-Color Sprite
A simple 8-line target pattern, using color values 0–3:
0000000222000000
0000220000220000
0002200330022000
0022003113002200
0022003113002200
0002200330022000
0000220000220000
0000000222000000
In the sprite data list, the two data words are separated (data word 1 = lower bitplane, data word 2 = upper bitplane):
Start:
dc.w $A05A,$A800 ; HSTART=$B4, VSTART=$A0, VSTOP=$A8
dc.w %0000000000000000,%0000001111000000 ; line 1
dc.w %0000000000000000,%0000110000110000 ; line 2
dc.w %0000000110000000,%0001100110011000 ; line 3
dc.w %0000001111000000,%0011001001001100 ; line 4
dc.w %0000001111000000,%0011001001001100 ; line 5
dc.w %0000000110000000,%0001100110011000 ; line 6
dc.w %0000000000000000,%0000110000110000 ; line 7
dc.w %0000000000000000,%0000001111000000 ; line 8
dc.w 0,0 ; end of sprite data
Attached Sprites (15-Color Mode)
When 3 colors are not enough, two sprites can be attached to form a single 15-color sprite. The two data words from each sprite combine into a 4-bit value per pixel, pointing into 15 color registers (value 0000 remains transparent).
To enable attachment, set the AT bit (bit 7 of SPRxCTL) on the odd-numbered sprite of a pair. For example, setting AT on sprite 1 causes its data bits to be combined with sprite 0's data bits.
The bit ordering for the 4-bit color value is:
All four possible sprite pairs (0&1, 2&3, 4&5, 6&7) can form attached sprites, and in this mode they use COLOR16 through COLOR31. The two sprites must have identical position control words for attachment to work properly. If positions do not match, the system falls back to normal 3-color mode.
Multiple Sprites on One DMA Channel
After a sprite finishes displaying, its DMA channel becomes free. Instead of terminating with two zero words, the data list can contain new control words for a second sprite on the same channel.
There is one restriction: the DMA channel needs one blank line between sprites to read the new control words. If the first sprite's last line is at raster line 163, the control words are read at line 164, and the second sprite begins at line 165.
Start:
; First sprite at line $A0, horizontal $B4
dc.w $A05A,$A800
dc.w %0000000000000000,%0000001111000000
; ... (sprite data) ...
dc.w %0000000000000000,%0000001111000000
; Second sprite follows immediately — new control words
dc.w $B096,$B800 ; different position
dc.w %0000000000000000,%0000001111000000
; ... (sprite data) ...
dc.w %0000000000000000,%0000001111000000
dc.w 0,0 ; end of sprite data list
This technique allows displaying many more than 8 sprites per frame by multiplexing DMA channels, as long as sprites sharing a channel do not overlap vertically (plus the one-line gap).
Sprite Registers
Each sprite channel has a pointer register pair and four control/data registers. The pointer registers are used to initialize DMA; the control and data registers are written automatically by the DMA controller during display.
The DMA controller uses these as running pointers into the sprite data list. After processing a complete list, the pointer has advanced past the end. To display the same sprite again next frame, the pointer must be reloaded during vertical blank — typically by the Copper:
; Copper list: reload sprite pointers each frame
MOVE #StartSprite0H,SPR0PTH
MOVE #StartSprite0L,SPR0PTL
MOVE #StartSprite1H,SPR1PTH
MOVE #StartSprite1L,SPR1PTL
; ... repeat for all 8 channels ...
WAIT $FFFE ; end of Copper list
When a value is written to SPRxCTL (by DMA or the 68000), DENISE disables that sprite's output until the beam reaches VSTART. Writing to SPRxDATA reactivates sprite output. The DMA controller uses SPRxPOS and SPRxCTL to compare against the current beam position for correct horizontal placement.
There is no individual enable/disable for each sprite DMA channel. The SPREN bit (bit 5) in DMACON enables all 8 sprite DMA channels simultaneously:
MOVE.W #$8220,$DFF096 ; set SPREN + DMAEN in DMACON
Unused sprite channels must still be initialized — point their SPRxPT to a memory location containing two zero words (the terminator of any active sprite list will do).
Sprite-Playfield Priority
When sprites and playfields overlap, a priority system determines which element appears in front. Among sprites, priority is determined by sprite number: sprite 0 has the highest priority and cannot be obscured by any other sprite.
For sprite-vs-playfield priority, sprites are grouped in pairs: 0&1, 2&3, 4&5, 6&7. The playfield can be inserted at any position among these four pairs, giving 5 possible priority positions for each playfield:
This is controlled by the BPLCON2 register ($DFF104, write only):
In Dual-Playfield mode, each playfield can be independently positioned among the sprite pairs. The PF2PRI bit controls which playfield appears in front of the other, and this inter-playfield priority takes precedence over sprite-playfield priority. In single-playfield mode, only PF1Px is relevant; PF2PRI and PF2Px have no effect.
Collision Detection
The Amiga hardware can automatically detect collisions between sprites and between sprites and playfields. A collision occurs when non-transparent pixels from two elements overlap at the same screen position.
CLXDAT — Collision Data Register ($DFF00E, read only)
CLXCON — Collision Control Register ($DFF098, write only)
The CLXCON register controls which elements participate in collision detection. The ENSPx bits enable collision testing for odd-numbered sprites (even-numbered sprites always participate). The ENBPx/MVBPx bits select which bitplane color combinations can trigger playfield collisions — allowing fine-grained control such as "only red pixels trigger collisions."
When an ENBPx bit is set, the corresponding bitplane's pixel value must match the MVBPx bit for a collision to register. If ENBPx is clear, that bitplane is ignored in the comparison (any value matches). Setting all ENBPx to 0 means every playfield pixel can trigger a collision. For attached sprite pairs, the corresponding ENSPx bit must be set for correct collision detection.