Skip to content

Copper: The Amiga's Display Coprocessor

Three instructions, timed to the video beam

The copper is a small coprocessor inside the Amiga's Agnus chip. It runs a list of instructions from Chip memory every frame, waiting for the video beam to reach a position and then writing values into the custom chip registers. With it a program can change colours on any scan line, split the screen into bands with different modes, and reload pointers, while the 68000 does something else.

The copper is the part of the Amiga that watches the television picture being drawn. It is a coprocessor with three instructions, built into the Agnus chip, and its only job is to write values into the other custom chips’ registers at exact moments in the frame. Commodore’s Hardware Reference Manual lists what that allows: “mid-screen changes to the color palette, splitting the screen into multiple horizontal slices each having different video resolutions and color depths, beam-synchronized interrupt generation for the 680x0, and more.”

The most visible result was colour. A 32-colour screen could show a sky that faded through far more shades than its palette held, because the copper rewrote the background colour on every line as the beam went down the screen. By 1994 The One could say that nearly every Amiga game “uses the Copper list to graduate the colour of the ground and sky”. The magazine was previewing Guardian, a 3D shoot-’em-up by Mark Sibly of Acid Software, and what impressed it was that Sibly’s gradient tilted “with the ship’s movement”, which it had never seen before. Demo programmers wore the effect out even sooner. Reviewing Cyborx’s first demo, Total Deception, in 1992, Amiga Format found “a few vectors and copper bars” among elements “reminiscent of a couple of years ago”, and told the group: “Liven up! This is 1992!”

On a Commodore 64 the same effects need a raster interrupt and the processor’s time. On the Amiga the copper runs its list every frame on its own, and the 68000 is left to run the game.

Fast facts

  • Location: inside Agnus, next to the blitter. Its registers are Agnus registers.
  • Instructions: three. MOVE writes a value to a register, WAIT waits for a beam position, and SKIP skips the next instruction if the beam has passed a position.
  • Format: every instruction is two 16-bit words, fetched by DMA from Chip memory only.
  • Speed: a MOVE takes four memory-cycle times, about 1.1 microseconds. A WAIT takes six, then nothing at all while it waits.
  • Resolution: a WAIT can pick any scan line and any of 113 horizontal positions, one every 4 low-resolution pixels.
  • Program: a list in Chip memory, restarted from the address in COP1LC at every vertical blank.
  • Switch: bit 7 of DMACON, COPEN, turns copper DMA on and off.

Waiting costs nothing

The copper’s economy is in one sentence of the manual: “while the Copper is waiting for the beam to reach a specific position, it does not use the memory bus at all.” A WAIT is not a loop. The copper compares the beam position counter directly and stays off the bus until the comparison comes true.

When it does run, it takes little. It asks for the bus only on odd-numbered memory cycles, and the manual explains why: audio, disk, memory refresh, sprites and most low-resolution display fetches use only the even ones, so the copper does not collide with them. (The manual’s chapter on DMA numbers them the other way round, giving the even cycles to the 68000; the Agnus entry sets out the inconsistency. Either way, the copper and the fixed DMA channels take alternate cycles.) It needs priority only over the 68000 and the blitter. A MOVE or SKIP fetches two words in two memory cycles, which takes four memory-cycle times because only every other cycle is the copper’s. A WAIT costs one more cycle, six cycle times, to fetch and to wake up.

The limit is the display itself. The Amiga system entry explains how four high-resolution bitplanes take every memory cycle during the visible part of a line, and the manual notes that this locks out “the blitter or Copper” as well as the processor until the horizontal blank.

The three instructions

MOVE

The first word holds the register’s address, as an offset from the custom chips’ base at $DFF000, with bit 0 clear. The second word is the value to write.

68000 assembly
    dc.w    $0180,$0f00        ; MOVE $0F00 (red) into COLOR00, the background colour
    dc.w    $00e0,$0002        ; MOVE $0002 into BPL1PTH, bitplane 1 pointer, high word

WAIT

The first word holds the beam position to wait for: the vertical position (bits 15-8) and the horizontal position (bits 7-1), with bit 0 set. The second word holds a mask saying which of those bits to compare, with bit 0 clear. The copper waits until the beam counter is equal to or greater than the position.

68000 assembly
    dc.w    $9601,$ff00        ; WAIT for line 150 ($96), ignoring the horizontal position
    dc.w    $2c07,$fffe        ; WAIT for line $2C, horizontal position $06 or later
    dc.w    $ffff,$fffe        ; WAIT for a position that never comes: the end of the list

The second form, $xx07,$fffe, is a common one: all the mask bits set, and a horizontal position near the start of the line.

The horizontal position counts from $00 to $E2. Its lowest bit is not compared, which is where the 113 positions come from, each 4 low-resolution pixels apart. There is no stop instruction, so a list ends by waiting for $FFFF,$FFFE: line 255 exists, but horizontal position $FE never does, and the copper sits there until the next frame restarts it.

Only eight bits hold the line number, but a PAL frame has 312 lines. Past line 255 the vertical position wraps round to 0, so to reach the lower part of a tall display a list first waits for line 255 and then waits for the low line number again. The Amiga pattern Copper Colour Bars shows the idiom.

Bit 15 of the second word is not a mask bit. It is BFD, “blitter-finished disable”. Normally set, it can be cleared to make the copper wait for the blitter to finish as well as for the beam. Because of this, the top bit of the line number can never be masked, a limitation the manual works around in its own examples.

SKIP

SKIP is a WAIT with bit 0 of the second word set. Instead of waiting, it skips the next instruction if the beam has already reached the position. Followed by a MOVE to one of the copper’s jump registers, it makes a conditional branch, and the manual uses the pair to build a loop that interrupts the processor every 16 lines.

Copper lists

A copper program is called a copper list. The manual’s complete example sets two bitplane pointers and four colours at the top of the screen, waits for line 150, changes all four colours and ends:

68000 assembly
copperlist:
    dc.w    $00e0,$0002        ; BPL1PTH \ bitplane 1 at $21000
    dc.w    $00e2,$1000        ; BPL1PTL /
    dc.w    $00e4,$0002        ; BPL2PTH \ bitplane 2 at $25000
    dc.w    $00e6,$5000        ; BPL2PTL /
    dc.w    $0180,$0fff        ; COLOR00 white
    dc.w    $0182,$0f00        ; COLOR01 red
    dc.w    $0184,$00f0        ; COLOR02 green
    dc.w    $0186,$000f        ; COLOR03 blue
    dc.w    $0100,$2200        ; BPLCON0: two low-resolution bitplanes, colour on
    dc.w    $9601,$ff00        ; WAIT for line 150
    dc.w    $0180,$0000        ; COLOR00 black
    dc.w    $0182,$0ff0        ; COLOR01 yellow
    dc.w    $0184,$00ff        ; COLOR02 cyan
    dc.w    $0186,$0f0f        ; COLOR03 magenta
    dc.w    $ffff,$fffe        ; end of list

A list must follow the beam, top to bottom. Because a WAIT is satisfied by any later position, an instruction out of order does not hang the copper; it just runs at once. Several MOVEs can follow one WAIT.

Starting and restarting

The copper has two location registers, COP1LC and COP2LC, and a jump strobe for each, COPJMP1 and COPJMP2. It has only one program counter. Writing to a strobe loads the counter from the matching location register, and the copper can write to the strobes itself, which is how a list jumps. At the start of every vertical blank the copper restarts from COP1LC automatically, so a list set up once runs every frame.

Register Address Purpose
COP1LCH, COP1LCL $DFF080, $DFF082 First list address, restarted every frame
COP2LCH, COP2LCL $DFF084, $DFF086 Second list address
COPJMP1 $DFF088 Strobe: jump to COP1LC
COPJMP2 $DFF08A Strobe: jump to COP2LC
COPCON $DFF02E Control: bit 1 is CDANG

Starting it from the processor takes three writes:

68000 assembly
    lea     $dff000,a1
    lea     copperlist,a0          ; must be in Chip memory
    move.l  a0,$080(a1)            ; COP1LC: the list's address
    move.w  $088(a1),d0            ; strobe COPJMP1: load the program counter from COP1LC
    move.w  #$8380,$096(a1)        ; DMACON: SET + DMAEN + BPLEN + COPEN

The manual warns that one location register must be loaded and its strobe hit before copper DMA is switched on, so that the copper starts from a known address.

Because COP1LC is reloaded every frame, changing which list it points to is how a program swaps lists. An interlaced display, whose odd and even fields need different bitplane pointers, is handled that way in the manual. Games that change a list every frame keep two copies and swap between them, as the pattern Copper Split Screen describes.

What the copper can and cannot touch

The copper can only write. It cannot read a register or test a value, and the only condition it can check is the beam position, with the blitter-finished flag as an option. It cannot write memory directly either, although, as the manual points out, it can set up and start the blitter, which can.

Nor can it write every register. On the original chip set the manual divides the register space into three:

Register offsets Copper access
$00-$3E Never
$40-$7E Only when CDANG is set; this range holds the blitter registers
$80 and up Always

DMACON, INTENA, INTREQ, the colours, the bitplane and sprite pointers and the audio registers are all above $80, so a copper list can always write them. The protection is for the blitter. CDANG, bit 1 of COPCON, is short for “Copper danger”, and the manual gives the reason for it: shutting the copper out of the blitter registers “prevents a runaway Copper (caused by a poorly formed instruction list) from accidentally affecting system memory.” The bit is cleared at reset. A program that wants the copper to drive the blitter sets it from the processor:

68000 assembly
    move.w  #$0002,$dff02e         ; COPCON: set CDANG

The Enhanced Chip Set moved the line. On ECS machines the copper can write from $40 up without the bit, and with it set, every register.

The Hardware Reference Manual has a bit called danger here and, in DMACON, a bit it says programmers called “blitter-nasty”. Both describe what one custom chip can do to the rest of the machine if it is allowed.

What it made possible

  • Colour gradients. One WAIT and one MOVE per line change the background colour 256 times down a screen. That is the “copper bars” and sky gradients of countless games and demos. Writing to a playfield colour instead recolours the artwork band by band.
  • Split screens. Rewriting the bitplane pointers, scroll and modulo registers part-way down gives a scrolling play area above a fixed status panel. Rewriting BPLCON0 changes the resolution and number of colours from one band to the next.
  • Sprites that change. The manual’s example waits for the last line of one use of a sprite and changes its colours before the next, so a reused sprite can look different further down the screen.
  • Interrupts on cue. A MOVE to INTREQ raises a copper interrupt at a chosen beam position, for the jobs the copper cannot do itself.

The copper also reached programmers who never wrote a copper list. AMOS managed the copper list for its screens, and Amiga Computing’s AMOS column in October 1990 used its Rainbow commands, “the simplest way to set up a custom display”, to put graded bands of colour behind a game, and planned “four big copper bars bouncing up and down the screen” for the next month.

How fine the timing is

A WAIT can resolve 4 low-resolution pixels across the line. A MOVE takes four memory-cycle times, and at 280 nanoseconds a memory cycle that is about 1.1 microseconds, the time the beam takes to draw 8 low-resolution pixels. Back-to-back MOVEs to a colour register can therefore change it at most once every 8 pixels along a line, while a change at the start of each line can be as fine as the display allows.

Sources

  • Amiga Hardware Reference Manual, 3rd edition (Commodore-Amiga, Addison-Wesley, 1991): the copper among the Amiga’s features (p. 3); chapter 2, “Coprocessor Hardware”: what the copper is and waiting off the bus (p. 19), odd memory cycles, the three instructions and their timing, Chip memory only, affecting memory through the blitter (p. 20), MOVE (p. 21), WAIT and the end-of-list wait (pp. 22-23), horizontal and vertical positions and the line-255 wrap (pp. 23-24), location registers and restart at vertical blank (p. 25), jump strobes, COPCON and CDANG (p. 26), building a list and changing sprite colours (pp. 26-27), the complete sample list (pp. 28-29), starting and stopping, COPEN (p. 30), SKIP (p. 31), masks, the unmaskable top bit and the loop example (pp. 32-33), interlace (pp. 34-35), BFD and interrupting the 680x0 (p. 35), instruction summary (p. 36). DMA and four high-resolution bitplanes (pp. 196-197); the “blitter-nasty” bit (p. 198). Appendix A: copper registers (pp. 273-276) and the 280 ns memory cycle (p. 275). Appendix C: COPCON on the Enhanced Chip Set (p. 310).
  • The One, issue 66, March 1994: David Upchurch, work-in-progress feature on Acid Software’s Guardian.
  • Amiga Format, issue 35, June 1992: public-domain review of Cyborx’s Total Deception.
  • Amiga Computing, October 1990: AMOS column, copper lists and rainbows.
  • AmigaWorld, January 1995, p. 13: the Amiga 1000’s launch in July 1985 and shipping in September.

See also

Checked. Verified against primary sources and signed off by a person.