Agnus: The Amiga's Memory Master
DMA controller, Blitter, and Copper in one package
Agnus coordinated all memory access on the Amiga, housing the Blitter for fast graphics and the Copper for beam-synchronised effects.
Agnus was the Amiga’s traffic controller. Every memory access—from the 68000, the Blitter, the display hardware, audio playback—flowed through Agnus. It allocated time slots fairly, ensuring smooth graphics and audio while letting the CPU work during the gaps.
Fast facts
- Function: DMA controller, Blitter engine, Copper coprocessor.
- Versions: 8361 (NTSC), 8367 (PAL), 8370/8372 (Fat Agnus), 8375 (Super Agnus).
- Chip RAM: 512KB (original), 1MB (Fat), 2MB (Super/ECS).
- DMA channels: 25 independent channels for different purposes.
The priority ladder
The entry says Agnus allocated slots “fairly”. The manual is more specific, and less fair: there is a strict ranking, and the processor is at the bottom of it.
| Priority | Device |
|---|---|
| Highest | disk, audio, display and sprite DMA |
| the Copper | |
| the blitter | |
| Lowest | the 68000 |
Commodore explains each placement. The four DMA channels come first “because missed DMA cycles can cause lost data, noise in the sound output, or on-screen interruptions”. The Copper follows “because it has to perform its operations at the same time during each display frame to remain synchronized with the display beam”. And at the bottom:
The lowest priorities are assigned to the blitter and the 68000, in that order. The blitter is given the higher priority because it performs data copying, modifying, and line drawing operations much faster than the 68000.
The processor is last because it is the slowest thing in the machine at the jobs that matter. That is the Amiga’s design thesis stated as a scheduling rule.
One line stops this being merely hierarchical: “If a device does not request one of its allocated time slots, the slot is open for other uses.” Slots are reserved but not wasted, which is what lets a narrow display leave room for everything else.
227.5 cycles, and where they go
A horizontal line is “about 63 microseconds”, holding “227.5 ‘color clocks’, or memory access cycles”, each around 280 nanoseconds. Before any picture is drawn, a fixed tithe comes off the top:
| Cycles | Purpose |
|---|---|
| 4 | memory refresh |
| 3 | disk DMA |
| 4 | audio DMA (2 bytes per channel) |
| 16 | sprite DMA |
Then the display takes what it needs, and a wide deep display takes nearly everything: four hires bitplanes come to “40 * 4 = 160 time slots”, which “effectively locks out the 68000 (as well as the blitter or Copper) from any memory access during the display”.
Why the 68000 does not notice
The remarkable part is that this is invisible most of the time, and deliberately so:
The 68000 uses only the even-numbered memory access cycles. The 68000 spends about half of a complete processor instruction time doing internal operations and the other half accessing memory. Therefore, the allocation of alternate memory cycles to the 68000 makes it appear to the 68000 that it has the memory all of the time, and it will run at full speed.
The processor is not being starved; it is being interleaved. Its own duty cycle — half thinking, half fetching — is matched to a bus that hands it every other slot. The contention only becomes visible when an instruction “does not match perfectly with the allocation of even cycles”, or when the display grows large enough to take the odd slots as well.
The instruction the Amiga cannot run
The clearest evidence of how deep this goes is a warning in a box:
Avoid the TAS instruction. The 68000 test-and-set instruction (TAS) should never be used in the Amiga; the indivisible read-modify-write cycle that is used only in this instruction will not fit into a DMA memory access slot.
TAS is a normal 68000 instruction, present on every other machine using the
chip. On the Amiga it is unusable — not because of an operating system rule or a
software convention, but because the bus schedule has no room for an access that
refuses to be interrupted.
Every other system in this Vault negotiates between processor and display for memory. The Amiga is the one where the negotiation reaches back into the processor’s instruction set and removes an entry.
DMA slot allocation
Agnus divides each scanline into time slots. The standard PAL/NTSC layout interleaves memory refresh with disk on the early slots:
| Slots | Purpose |
|---|---|
| 0, 2, 4 | Memory refresh (DRAM) |
| 1, 3, 5 | Disk DMA |
| 7, 9, 11, 13 | Audio channels 0-3 |
| 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45 | Sprites 0-7 (two slots each) |
| 0x38-0xD0 (display window) | Bitplane DMA |
| Remaining | Copper, Blitter, CPU |
Outside bitplane DMA the CPU and Blitter alternate cycles by default — odd cycles for the CPU, even for the Blitter — so the Blitter operates concurrently with the CPU rather than starving it. Setting the BLITHOG bit (BLTCON1 bit 1) gives the Blitter every available cycle, halting the CPU until the blit completes; this is faster but blocks CPU work, so games tend to leave BLITHOG clear unless the blit is short.
Full DMA priority chain
When multiple DMA channels need the same cycle, Agnus arbitrates in this fixed order (highest to lowest):
- Memory refresh
- Disk
- Audio
- Sprites (during sprite DMA window)
- Bitplanes (during display window)
- Copper
- Blitter
- CPU (gets whatever slots remain)
Chip versions
| Chip | Chip RAM | Notes |
|---|---|---|
| 8361/8367 | 512KB | Original A1000, early A500 |
| 8370/8372 | 1MB | “Fat Agnus” - larger package |
| 8375 | 2MB | ECS “Super Agnus” |
| Alice | 2MB | AGA replacement in A1200/A4000 |
The Blitter
The Blitter is a DMA engine within Agnus that performs:
- Block copies: rectangular memory moves.
- Logic operations: combine up to three sources with minterm logic.
- Area fill: flood-fill between edges.
- Line drawing: hardware-accelerated lines.
Blitter sources
| Source | Purpose |
|---|---|
| A | Source/mask data |
| B | Source data |
| C | Destination read (for merge) |
| D | Destination write |
Minterm operations
The Blitter combines sources using an 8-bit minterm value:
Result = (A AND B AND C) * bit7 +
(A AND B AND NOT C) * bit6 +
... and so on for all 8 combinations
Common minterms:
$F0: Copy A to D (ignore B, C)$CA: Cookie-cut (A masks B onto C)$5A: XOR A with C
The Copper
The Copper is a coprocessor with just three instructions:
| Instruction | First-word bit 0 | Second-word bit 0 | Purpose |
|---|---|---|---|
| MOVE | 0 | (don’t care) | Write to register |
| WAIT | 1 | 0 | Wait for beam position |
| SKIP | 1 | 1 | Skip next instruction if beam past position |
WAIT and SKIP share the same first-word encoding; the second word’s low bit distinguishes them.
Copper list example
dc.w $0180, $0000 ; COLOR00 = black
dc.w $2c07, $fffe ; WAIT for line $2c
dc.w $0180, $0f00 ; COLOR00 = red
dc.w $5007, $fffe ; WAIT for line $50
dc.w $0180, $00f0 ; COLOR00 = green
dc.w $ffff, $fffe ; End (wait forever)
Copper capabilities
- Palette changes: different colours per scanline (copper rainbows).
- Mode switches: change resolution mid-screen.
- Sprite repositioning: move sprites to different locations per frame.
- Register pokes: modify nearly any hardware register.
Key registers
| Register | Address | Purpose |
|---|---|---|
| DMACON | $DFF096 | DMA control |
| DMACONR | $DFF002 | DMA control read |
| BLTCON0 | $DFF040 | Blitter control |
| COP1LC | $DFF080 | Copper list 1 pointer |
| COP2LC | $DFF084 | Copper list 2 pointer |
| COPJMP1 | $DFF088 | Restart Copper list 1 |