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.
MOVEwrites a value to a register,WAITwaits for a beam position, andSKIPskips 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
MOVEtakes four memory-cycle times, about 1.1 microseconds. AWAITtakes six, then nothing at all while it waits. - Resolution: a
WAITcan 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
COP1LCat 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.
dc.w $0180,$0f00 ; MOVE $0F00 (red) into COLOR00, the background colour
dc.w $00e0,$0002 ; MOVE $0002 into BPL1PTH, bitplane 1 pointer, high wordWAIT
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.
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 listThe 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:
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 listA 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:
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 + COPENThe 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:
move.w #$0002,$dff02e ; COPCON: set CDANGThe 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
WAITand oneMOVEper 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
BPLCON0changes 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
MOVEtoINTREQraises 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),WAITand 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,COPCONandCDANG(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),BFDand 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:COPCONon 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
- Agnus: the chip that contains the copper.
- Blitter: the other coprocessor in Agnus, which the copper can drive.
- The Amiga custom chipset and Denise: the registers the copper writes.
- Commodore Amiga: the machine, and how display DMA shares the bus.
- Raster effects and Raster interrupts: the same ideas on other machines.
- Demoscene: where copper bars became a cliché.