Sub-pages
$DFF120

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:

Sprite Pair Data Bits Color Register Notes
0 & 100Transparent
0 & 101COLOR17$DFF1A2
0 & 110COLOR18$DFF1A4
0 & 111COLOR19$DFF1A6
2 & 300Transparent
2 & 301COLOR21$DFF1AA
2 & 310COLOR22$DFF1AC
2 & 311COLOR23$DFF1AE
4 & 500Transparent
4 & 501COLOR25$DFF1B2
4 & 510COLOR26$DFF1B4
4 & 511COLOR27$DFF1B6
6 & 700Transparent
6 & 701COLOR29$DFF1BA
6 & 710COLOR30$DFF1BC
6 & 711COLOR31$DFF1BE

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.

$DFF120

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).

Start 1st and 2nd control wordsPosition and height
Start+4 1st and 2nd data words — line 1Pixel data
Start+8 1st and 2nd data words — line 2Pixel data
... 1st and 2nd data words — line NPixel data
Start+4*(N+1) $0000, $0000 — End of sprite dataTerminator

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

Word Bits Name Function
1st (SPRxPOS)15–8E7–E0VSTART — vertical start position (bits 7–0)
1st (SPRxPOS)7–0H8–H1HSTART — horizontal start position (bits 8–1)
2nd (SPRxCTL)15–8L7–L0VSTOP — vertical stop position (bits 7–0)
2nd (SPRxCTL)7ATAttach control bit (for 15-color mode)
2nd (SPRxCTL)6–4Unused (0)
2nd (SPRxCTL)3E8VSTART bit 8
2nd (SPRxCTL)2L8VSTOP bit 8
2nd (SPRxCTL)1H0HSTART bit 0

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
$DFF120

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:

Bit Position Weight Source Description
3MSBOdd sprite, data word 2Highest color bit
2Odd sprite, data word 1
1Even sprite, data word 2
0LSBEven sprite, data word 1Lowest color bit

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).

$DFF120

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.

Sprite Pointer Registers (write only)
$DFF120SPR0PTH — Sprite 0 data pointer (bits 16–18)
$DFF122SPR0PTL — Sprite 0 data pointer (bits 0–15)
$DFF124SPR1PTH — Sprite 1 data pointer (bits 16–18)
$DFF126SPR1PTL — Sprite 1 data pointer (bits 0–15)
$DFF128SPR2PTH — Sprite 2 data pointer (bits 16–18)
$DFF12ASPR2PTL — Sprite 2 data pointer (bits 0–15)
$DFF12CSPR3PTH — Sprite 3 data pointer (bits 16–18)
$DFF12ESPR3PTL — Sprite 3 data pointer (bits 0–15)
$DFF130SPR4PTH — Sprite 4 data pointer (bits 16–18)
$DFF132SPR4PTL — Sprite 4 data pointer (bits 0–15)
$DFF134SPR5PTH — Sprite 5 data pointer (bits 16–18)
$DFF136SPR5PTL — Sprite 5 data pointer (bits 0–15)
$DFF138SPR6PTH — Sprite 6 data pointer (bits 16–18)
$DFF13ASPR6PTL — Sprite 6 data pointer (bits 0–15)
$DFF13CSPR7PTH — Sprite 7 data pointer (bits 16–18)
$DFF13ESPR7PTL — Sprite 7 data pointer (bits 0–15)

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
Per-Sprite Control and Data Registers
SPRxPOSFirst control word — VSTART (bits 15–8), HSTART (bits 7–0)
SPRxCTLSecond control word — VSTOP (bits 15–8), AT/E8/L8/H0 (bits 7–0)
SPRxDATAFirst data word for current line (low bitplane)
SPRxDATBSecond data word for current line (high bitplane)

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).

$DFF120

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:

Pos 0 PLF > SPR0&1 > SPR2&3 > SPR4&5 > SPR6&7Playfield in front
Pos 1 SPR0&1 > PLF > SPR2&3 > SPR4&5 > SPR6&7
Pos 2 SPR0&1 > SPR2&3 > PLF > SPR4&5 > SPR6&7
Pos 3 SPR0&1 > SPR2&3 > SPR4&5 > PLF > SPR6&7
Pos 4 SPR0&1 > SPR2&3 > SPR4&5 > SPR6&7 > PLFPlayfield behind

This is controlled by the BPLCON2 register ($DFF104, write only):

Bit Name Function Description
15–7Unused
6PF2PRIPF2 priorityIf set, playfield 2 appears in front of playfield 1
5–3PF2P2–PF2P0PF2 sprite priorityPosition of playfield 2 among sprite pairs (0–4)
2–0PF1P2–PF1P0PF1 sprite priorityPosition of playfield 1 among sprite pairs (0–4)

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.

$DFF120

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)

Bit Collision Between
14SPR4(5) and SPR6(7)
13SPR2(3) and SPR6(7)
12SPR2(3) and SPR4(5)
11SPR0(1) and SPR6(7)
10SPR0(1) and SPR4(5)
9SPR0(1) and SPR2(3)
8Playfield 2 and SPR6(7)
7Playfield 2 and SPR4(5)
6Playfield 2 and SPR2(3)
5Playfield 2 and SPR0(1)
4Playfield 1 and SPR6(7)
3Playfield 1 and SPR4(5)
2Playfield 1 and SPR2(3)
1Playfield 1 and SPR0(1)
0Playfield 1 and Playfield 2

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."

Bit Name Function
15ENSP7Enable collision for sprite 7
14ENSP5Enable collision for sprite 5
13ENSP3Enable collision for sprite 3
12ENSP1Enable collision for sprite 1
11–6ENBP6–ENBP1Enable bitplane comparisonSelect which bitplanes participate
5–0MVBP6–MVBP1Match value for bitplanesRequired bit value for collision

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.