Code status: illustrative code. Adapt the listing to your program and check it on your target machine. This page links no assembly or execution record for the listing itself.
Overview
Amiga sprites have two control words at the start of their data that define vertical start/stop positions and horizontal position. Update these each frame to move sprites around the screen. The encoding packs multiple values into 16-bit words.
Code
; =============================================================================
; SPRITE CONTROL WORDS - AMIGA
; Calculate sprite position from X/Y coordinates
; Taught: Game 1 (Signal), Unit 2
; Cost depends on the assembled caller and memory placement.
; =============================================================================
SPRITE_HEIGHT equ 16 ; Sprite height in pixels
; Update sprite control words (simple version)
; ASSUMES: even beam X in0..510 and Y+SPRITE_HEIGHT <256
; (no VSTART[8] / VSTOP[8] support). Use update_sprite_full for those cases.
;
; Input: A0 = sprite data address
; frog_pixel_x, frog_pixel_y = coordinates
update_sprite:
move.w frog_pixel_y,d0 ; D0 = Y position (VSTART)
move.w frog_pixel_x,d1 ; D1 = X position (HSTART)
; === Control word 1: VSTART and HSTART ===
; Format: VSTART[7:0] in high byte, HSTART[8:1] in low byte
move.w d0,d2 ; D2 = VSTART
lsl.w #8,d2 ; Shift to high byte
lsr.w #1,d1 ; HSTART / 2 (lose bit 0)
or.b d1,d2 ; Combine
move.w d2,(a0) ; Write control word 1
; === Control word 2: VSTOP and control bits ===
; Format: VSTOP[7:0] in high byte, control bits in low byte
add.w #SPRITE_HEIGHT,d0 ; VSTOP = VSTART + height
lsl.w #8,d0 ; Shift to high byte
; Low byte contains: ATTACH, unused, VSTOP[8], VSTART[8], HSTART[0]
; Zero here means: not attached, even X, Y < 256
move.w d0,2(a0) ; Write control word 2
rts
frog_pixel_x: dc.w 160 ; Screen X coordinate
frog_pixel_y: dc.w 100 ; Screen Y coordinateExtended version with all control bits:
; Full control word calculation with all bits
; Handles sprites in lower screen area (Y > 255)
update_sprite_full:
move.w frog_pixel_y,d0 ; VSTART
move.w frog_pixel_x,d1 ; HSTART
move.w d0,d2
add.w #SPRITE_HEIGHT,d2 ; VSTOP
; Control word 1
move.w d0,d3 ; VSTART[7:0]
lsl.w #8,d3
move.w d1,d4
lsr.w #1,d4 ; HSTART[8:1]
or.b d4,d3
move.w d3,(a0)
; Control word 2
move.w d2,d3 ; VSTOP[7:0]
lsl.w #8,d3
; Build low byte: bit 7=ATTACH, bit 2=VSTOP[8], bit 1=VSTART[8], bit 0=HSTART[0]
moveq #0,d4
btst #8,d2 ; VSTOP bit 8?
beq.s .no_vstop8
bset #2,d4
.no_vstop8:
btst #8,d0 ; VSTART bit 8?
beq.s .no_vstart8
bset #1,d4
.no_vstart8:
btst #0,d1 ; HSTART bit 0?
beq.s .no_hstart0
bset #0,d4
.no_hstart0:
or.b d4,d3
move.w d3,2(a0)
rtsTrade-offs
| Aspect | Cost |
|---|---|
| CPU | Not measured for this illustrative listing; include the caller and hardware scheduling costs |
| Memory | Assemble the selected routines and caller to obtain code and state sizes |
| Limitation | Must update every frame for moving sprites |
When to use: Any program using hardware sprites.
When to avoid: Never - sprites always need valid control words.
Control Word Format
Word 1 (offset 0):
Bit 15-8: VSTART[7:0] - Vertical start position (low 8 bits)
Bit 7-0: HSTART[8:1] - Horizontal position (bits 8-1, divided by 2)Word 2 (offset 2):
Bit 15-8: VSTOP[7:0] - Vertical stop position (low 8 bits)
Bit 7: ATTACH - Attach to previous sprite (for 15-colour sprites)
Bit 6-3: Unused
Bit 2: VSTOP[8] - Vertical stop bit 8
Bit 1: VSTART[8] - Vertical start bit 8
Bit 0: HSTART[0] - Horizontal position bit 0Position Ranges
| Axis | Hardware register | Visible area |
|---|---|---|
| X | 9 bits (0-511) | ~64-448 in lowres (depends on display window) |
| Y | 9 bits (0-511, but used 0-312 PAL / 0-262 NTSC) | ~44-300 PAL / ~21-260 NTSC |
Setting HSTART[0] (bit 0 of word 2) lets you position to odd-pixel X. Without it, sprites can only sit on even X coordinates. Setting VSTART[8] (bit 1 of word 2) and VSTOP[8] (bit 2 of word 2) extends Y past 255 — required for sprites in the lower half of an interlaced or PAL screen.
Sprite attach (15-colour sprites)
Setting bit 7 of word 2 on an odd sprite (sprite 1, 3, 5, or 7) attaches it to the previous even sprite. The pair then displays one combined 15-colour sprite:
- Each pixel uses 2 bits from sprite N + 2 bits from sprite N+1 = 4 bits total
- 4 bits = 16 entries, of which entry 0 is transparent → 15 visible colours
- The pair must have matching VSTART/VSTOP/HSTART; only sprite N+1 needs ATTACH set
Practical use: bosses, rich playfield characters, status bars where 3-colour sprites look cheap.
; Setting ATTACH on sprite 1 (the odd partner of sprite 0)
; ... compute control word 2 in D3 as usual ...
bset #7,d3 ; ATTACH = 1
move.w d3,2(a0) ; A0 = sprite 1's dataRelated
Patterns: Copper List Basics
Vault: Commodore Amiga
With height16 the simple routine accepts beam Y in0–239. The full version accepts9-bit beam coordinates only while the end Y also fits0–511. These are beam positions, not window-relative pixel coordinates: apply the display origin separately. A0 points to a word-aligned sprite buffer in Chip RAM. The simple routine changes D0–D2/CCR; the full one D0–D4/CCR. Both clear ATTACH unless the caller sets it afterwards. Update an inactive buffer and publish its pointer at an agreed beam point; live two-word writes can otherwise be observed half-updated.
Explore the cross-platform sprite family for software drawing, hardware limits, restoration and overload policies.