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

133 lines
4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[← Home](../README.md) · [Graphics](README.md)
# 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](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`:
```c
#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` | `COLOR00``COLOR31` | 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` | `BPL1PT``BPL8PT` | Bitplane pointers |
---
## References
- HRM: *Amiga Hardware Reference Manual* — Copper chapter
- NDK39: `graphics/copper.h`, `graphics/gfxmacros.h`
- ADCD 2.1: `CINIT`, `CMOVE`, `CWAIT`, `CEND`