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
The Copper is a coprocessor that executes a list of instructions in sync with the display beam. It can wait for specific scanlines and write to custom chip registers, enabling per-scanline colour changes, sprite multiplexing, and complex visual effects. A dedicated graphics program can use its own list; an OS-managed application can leave display setup to the system.
Code
; =============================================================================
; COPPER LIST BASICS - AMIGA
; Simple copper list with colours and sprite pointer
; Taught: Game 1 (Signal), Unit 1
; Memory: Variable (depends on complexity)
; =============================================================================
CUSTOM equ $dff000
COP1LC equ $080 ; Copper list 1 pointer
COPJMP1 equ $088 ; Copper jump strobe
DMACON equ $096
COLOR00 equ $180 ; Background colour
SPR0PTH equ $120 ; Sprite 0 pointer high
SPR0PTL equ $122 ; Sprite 0 pointer low
section code,code_c
start:
lea CUSTOM,a5
move.w #$7fff,$09a(a5) ; exclusive, reset-to-leave caller
move.w #$7fff,$09c(a5)
move.w #$7fff,DMACON(a5)
move.w #$0200,$100(a5) ; colour display, zero bitplanes
; --- Set sprite pointer in copper list ---
lea sprite_data,a0
move.l a0,d0
swap d0 ; High word first
lea sprpth_val,a1
move.w d0,(a1) ; Store high word
swap d0
lea sprptl_val,a1
move.w d0,(a1) ; Store low word
; Disabled sprite blocks for the other seven DMA channels.
lea disabled_sprite,a0
move.l a0,d0
lea $dff128,a0
moveq #6,d1
.clear_other_sprites:
move.l d0,(a0)
addq.l #8,a0
dbra d1,.clear_other_sprites
; --- Install copper list ---
lea copperlist,a0
move.l a0,COP1LC(a5) ; Set copper list address
move.w d0,COPJMP1(a5) ; Strobe to start copper
; --- Enable DMA ---
move.w #$82a0,DMACON(a5) ; Master + copper + sprites
mainloop:
bra.s mainloop
; === COPPER LIST ===
copperlist:
; Set background colour
dc.w COLOR00,$0048 ; Blue background
; Set sprite palette (colours 17-19)
dc.w $01a2,$00f0 ; Sprite colour 1: bright green
dc.w $01a4,$0ff0 ; Sprite colour 2: yellow
dc.w $01a6,$0000 ; Sprite colour 3: black
; Sprite 0 pointer (filled in by code)
dc.w SPR0PTH
sprpth_val: dc.w $0000
dc.w SPR0PTL
sprptl_val: dc.w $0000
; Wait for specific scanline and change colour
dc.w $8007,$fffe ; WAIT for line $80
dc.w COLOR00,$0080 ; Change to green
dc.w $c007,$fffe ; WAIT for line $C0
dc.w COLOR00,$0444 ; Change to grey
; End copper list
dc.w $ffff,$fffe ; WAIT forever (end marker)
disabled_sprite: dc.w 0,0
; === SPRITE DATA ===
even
sprite_data:
dc.w $6050,$7000 ; Control words (beam Y=96, beam X=160, height=16)
; Sixteen rows, two words per row.
dc.w $0000,0,$07e0,0,$1ff8,0,$3ffc,0
dc.w $7ffe,0,$ffff,0,$ffff,0,$ffff,0
dc.w $ffff,0,$ffff,0,$ffff,0,$7ffe,0
dc.w $3ffc,0,$1ff8,0,$07e0,0,$0000,0
dc.w $0000,$0000 ; End markerTrade-offs
| Aspect | Cost |
|---|---|
| CPU | No per-line polling; list setup and patching still cost CPU time |
| Memory | 4 bytes per MOVE, 4 bytes per WAIT |
| Limitation | Can only write to custom chip registers |
When to use: A dedicated display needing beam-synchronised custom-register writes.
When to avoid: An OS-managed window where the graphics system owns the display.
Copper Instructions
MOVE and WAIT are the main instructions used here; SKIP is described below.
WAIT
Wait for the beam to reach a position:
dc.w $VVHH,$fffeVV= Vertical position (scanline, $00-$FF)HH= Horizontal position (usually$07for “any horizontal”)$fffe= WAIT instruction marker
MOVE
Write a value to a register:
dc.w REGISTER,VALUE- Register must be in range
$000-$1FE - A MOVE needs available Copper bus slots; earlier WAITs and DMA load affect its timing.
Colour Register Reference
| Register | Purpose |
|---|---|
$0180 (COLOR00) |
Background/border |
$0182 (COLOR01) |
Bitplane colour 1 |
$0184 (COLOR02) |
Bitplane colour 2 |
$01A2-$01A6 (COLOR17-19) |
Sprites 0 and 1 colours 1, 2, 3 |
$01AA-$01AE (COLOR21-23) |
Sprites 2 and 3 colours 1, 2, 3 |
$01B2-$01B6 (COLOR25-27) |
Sprites 4 and 5 colours 1, 2, 3 |
$01BA-$01BE (COLOR29-31) |
Sprites 6 and 7 colours 1, 2, 3 |
Sprite palettes are shared in pairs — sprite 0 and sprite 1 both draw from the same three colours. Use attached sprites to combine a pair into a single 15-colour sprite (see Sprite Control Words).
Colour Format
Amiga colours are 12-bit RGB:
$0RGBWhere R, G, B are each 0-F (4 bits).
Examples:
$0F00= Red$00F0= Green$000F= Blue$0FFF= White$0000= Black$0888= Grey
Two copper lists
The Copper has two program pointers: COP1LC ($DFF080) and COP2LC ($DFF084), with corresponding strobes COPJMP1 ($DFF088) and COPJMP2 ($DFF08A). Strobing either one restarts the Copper at that list. A common pattern:
- COP1 = short setup list run from VBlank — set up display window, palette, restart COP2
- COP2 = the per-frame “main” list with all the WAIT/MOVE work
To jump from COP1 to COP2: have COP1 end with a strobe-write to COPJMP2, and COP2 ends with dc.w $ffff,$fffe (wait forever). This way you can swap COP2 between frames (double-buffer copper lists) without disturbing COP1.
SKIP instruction
Beyond MOVE and WAIT, the Copper has a SKIP instruction — same word format as WAIT but with bit 0 of the second word set:
dc.w $4007,$ffff ; SKIP: skip next instruction if beam past line $40
dc.w COLOR00,$0f00 ; Skipped if condition metSKIP enables limited conditional branching. Standard idiom: SKIP followed by a “jump back to start” MOVE that strobes COPJMP1 — a poor-man’s loop.
Related
Patterns: Copper Colour Bars, VBlank Game Loop, Sprite Control Words
Vault: Commodore Amiga | Copper
The list and complete sprite block must be word-aligned Chip RAM and remain valid during DMA. This exclusive boot example has no OS-return path. It changes A0/A1/A5/D0/D1 and condition codes and owns all eight sprite channels, its palette entries, the Copper and background colour. A reusable application must establish its display window/fetch configuration.