amiga-bootcamp/08_graphics/copper/copper.md
Ilia Sharin 2283178f09 Add Copper ISA Complete Reference Manual
New file: 08_graphics/copper/copper_reference.md
- Full instruction set reference with opcode encoding table
- Bit-level encoding for MOVE, WAIT, SKIP (7-bit masks)
- Beam position encoding: V counter (8-bit), H counter (7-bit)
- Copper control registers (COP1LC, COP2LC, COPJMP, COPCON, DMACON)
- Copper list structure, dual lists, SKIP-based double buffering
- DMA timing budget calculations per scanline
- Register reference for all copper-writable targets
- OCS/ECS/AGA differences (AGA 24-bit color via BPLCON3 LOCT)
- Programming models: bare metal, OS-friendly UCopList, self-modifying
- Common patterns: rainbow, split screen, status bar, sprite mux
- Debugging: 8 common pitfalls with symptoms and fixes
- Mermaid fetch-execute cycle diagram

Updated files:
- 08_graphics/README.md: add copper_reference.md to index
- 08_graphics/copper/copper.md: cross-reference link, fix MOVE/WAIT
  encoding, fix UCopList CMOVE syntax
- 08_graphics/copper/copper_programming.md: cross-reference link, fix
  horizontal resolution (2 color clocks, not 4)
2026-06-01 14:39:43 -04:00

4 KiB
Raw Permalink Blame History

← Home · Graphics

Copper — Coprocessor Instructions and UCopList

Overview

The Copper is a simple coprocessor in the Amiga custom chips that executes a list of instructions synchronized to the video beam. It can write to any custom chip register at any beam position, enabling per-scanline color changes, split screens, and hardware-level display effects without CPU intervention.

For the complete ISA reference with full bit-level encoding, beam position details, control registers, timing, and debugging guidance, see copper_reference.md — the Copper ISA Complete Reference Manual.


Instruction Format

The Copper has only three instructions, each 32 bits (one longword):

MOVE — Write a Register

[register_offset] [value (16 bits)]
Word 1: 0000000R RRRRRRR0 (Offset)
Word 2: VVVVVVVV VVVVVVVV (Data)
  • Register offset is relative to $DFF000 (custom chip base)
  • Only even registers can be written (bit 0 = 0)
  • Example: $0180, $0FFF → write $0FFF to COLOR00 ($DFF180)

WAIT — Wait for Beam Position

[vpos (8 bits)] [hpos (7 bits)] [1]
Word 1: VVVVVVVV HHHHHHH1

[BFD (1 bit)] [vmask (7 bits)] [hmask (7 bits)] [0]
Word 2: Bvvvvvvv hhhhhhh0
  • Pauses until the beam reaches at least the specified (vpos, hpos)
  • Masks allow waiting on partial positions (e.g. any horizontal, specific vertical)

SKIP — Conditional Skip

Same as WAIT but bit 0 of second word = 1

If the beam has already passed the specified position, skip the next instruction.


Standard Copper Patterns

Per-Scanline Color Change (Rainbow)

WAIT   $2C01,$FFFE    ; wait for line $2C (44)
MOVE   $0180,$0F00    ; COLOR00 = red
WAIT   $2D01,$FFFE    ; wait for line $2D (45)
MOVE   $0180,$00F0    ; COLOR00 = green
WAIT   $2E01,$FFFE    ; wait for line $2E (46)
MOVE   $0180,$000F    ; COLOR00 = blue
...
WAIT   $FFDF,$FFFE    ; wait past line 255 (enables access to lines 256+)
WAIT   $FFFF,$FFFE    ; end-of-list (impossible position = halt)

End of Copper List

$FFFF, $FFFE          ; WAIT for beam position $FFFF — never reached

This is the standard "stop" marker. The Copper loops back to the start on the next vertical blank.


System Copper Lists

The OS manages copper lists through GfxBase:

Pointer Description
GfxBase->copinit System initialization copper list
GfxBase->LOFlist Long-frame copper list (even fields)
GfxBase->SHFlist Short-frame copper list (odd fields, interlace)

UCopList — User Copper Instructions

Applications can inject copper instructions into the system list via UCopList:

#include <hardware/custom.h>
extern struct Custom custom;

struct UCopList *ucl = AllocMem(sizeof(struct UCopList), MEMF_PUBLIC|MEMF_CLEAR);

CINIT(ucl, 100);                    /* init, max 100 instructions */
CWAIT(ucl, 44, 0);                  /* wait for line 44 */
CMOVE(ucl, custom.color[0], 0x0F00); /* COLOR00 = red */
CWAIT(ucl, 100, 0);
CMOVE(ucl, custom.color[0], 0x000F); /* COLOR00 = blue */
CEND(ucl);                          /* end of list */

viewport->UCopIns = ucl;
RethinkDisplay();                   /* rebuild system copper list */

Custom Chip Register Addresses (Copper-Relevant)

Address Name Description
$DFF180$DFF1BE COLOR00COLOR31 OCS/ECS palette (12-bit RGB)
$DFF100 BPLCON0 Bitplane control (depth, resolution)
$DFF102 BPLCON1 Scroll offsets
$DFF104 BPLCON2 Priority control
$DFF08E DIWSTRT Display window start
$DFF090 DIWSTOP Display window stop
$DFF092 DDFSTRT Data fetch start
$DFF094 DDFSTOP Data fetch stop
$DFF0E0$DFF0FE BPL1PTBPL8PT Bitplane pointers

References

  • HRM: Amiga Hardware Reference Manual — Copper chapter
  • NDK39: graphics/copper.h, graphics/gfxmacros.h
  • ADCD 2.1: CINIT, CMOVE, CWAIT, CEND