[← Home](../../README.md) · [Hardware](../README.md) · [OCS](README.md)

# OCS Chipset Internals

## Architecture

The three OCS chips share a common **chip bus** (also called the chip bus or DMA bus). Agnus is the bus master — it arbitrates between the CPU, Copper, Blitter, and DMA channels.

```mermaid
block-beta
    columns 3
    CPU["68000 CPU"] Agnus["Agnus\n(DMA Master)"] ChipRAM["Chip RAM\n512 KB"]
    space Paula["Paula\n(Audio/Disk/Serial)"] space
    space Denise["Denise\n(Display)"] space
    CPU-- "bus request" -->Agnus
    Agnus-- "DMA cycles" -->ChipRAM
    Paula-- "DMA req" -->Agnus
    Denise-- "bitplane/sprite data" -->Agnus
```

## DMA Channels and Priorities

Agnus schedules DMA cycles across a fixed priority scheme within each horizontal raster line (228 color clocks per line, PAL):

| Priority | DMA Channel | Register Bits |
|---|---|---|
| 1 (highest) | Disk | `DMACONR[4]` DSKEN |
| 2 | Sprite | `DMACONR[2]` SPREN |
| 3 | Bitplane | `DMACONR[8]` BPLEN |
| 4 | Copper | `DMACONR[7]` COPEN |
| 5 | Blitter | `DMACONR[6]` BLTEN |
| 6 | Audio ch 0–3 | `DMACONR[0..3]` AUD0–AUD3 |
| 7 (lowest) | CPU | Remaining cycles |

The CPU only gets cycles not consumed by DMA — this is why heavy DMA usage (e.g., full-screen bitplanes + sprites + audio) can starve the CPU noticeably on OCS.

## DMACON Register

Write `$DFF096` (DMACON), read `$DFF002` (DMACONR):

```
bit 15: SET/CLR  — write: 1=set bits, 0=clear bits (read: always 0)
bit 14: BBUSY    — blitter busy (read only)
bit 13: BZERO    — blitter zero flag (read only)
bit 10: (reserved)
bit  9: MASTER   — master DMA enable (must be set for any DMA)
bit  8: BPLEN    — bitplane DMA
bit  7: COPEN    — Copper DMA
bit  6: BLTEN    — Blitter DMA
bit  5: SPREN    — Sprite DMA
bit  4: DSKEN    — Disk DMA
bit  3: AUD3EN   — Audio channel 3 DMA
bit  2: AUD2EN   — Audio channel 2 DMA
bit  1: AUD1EN   — Audio channel 1 DMA
bit  0: AUD0EN   — Audio channel 0 DMA
```

Enable all standard DMA:
```asm
move.w  #$8380,DMACON    ; SET + MASTER + BPLEN + COPEN
move.w  #$800F,DMACON    ; SET + AUD0-3
```

## INTENA / INTREQ — Interrupt System

Write `$DFF09A` (INTENA), read `$DFF01C` (INTENAR):
Write `$DFF09C` (INTREQ), read `$DFF01E` (INTREQR):

```
bit 14: INTEN   — global interrupt enable (INTENA only)
bit 13: EXTER   — external/CIA interrupt (IPL6)
bit 12: DSKSYNC — disk sync (IPL5)
bit 11: RBF     — serial receive buffer full (IPL5)
bit 10: AUD3    — audio channel 3 (IPL4)
bit  9: AUD2    — audio channel 2 (IPL4)
bit  8: AUD1    — audio channel 1 (IPL4)
bit  7: AUD0    — audio channel 0 (IPL4)
bit  6: BLIT    — blitter finished (IPL3)
bit  5: VERTB   — vertical blank (IPL3)
bit  4: COPPER  — copper interrupt (IPL3)
bit  3: PORTS   — CIA-A port interrupts (IPL2)
bit  2: SOFT    — software interrupt (IPL1)
bit  1: DSKBLK  — disk block finished (IPL1)
bit  0: TBE     — serial transmit buffer empty (IPL1)
```

To enable vertical blank interrupt:
```asm
move.w  #$C020,INTENA   ; SET + INTEN + VERTB
```

## Agnus: Bitplane DMA Timing

During each scan line, Agnus fetches bitplane data for the current line. For a 320-pixel wide, 4-bitplane display, Agnus takes 40 DMA cycles per line for bitplane fetch. On a standard PAL line with 227 clock cycles, this leaves ~187 cycles for CPU + other DMA.

**Bitplane DMA pointers** (set at start of each frame or via Copper):
```
BPL1PTH/BPL1PTL  $DFF0E0/$DFF0E2   Bitplane 1 pointer (high/low word)
BPL2PTH/BPL2PTL  $DFF0E4/$DFF0E6
... up to BPL6 for OCS (6 bitplanes max)
```

## References

- ADCD 2.1 Hardware Manual — Agnus/DMA chapters
- NDK39: `hardware/dmabits.h`, `hardware/intbits.h`, `hardware/custom.h`
- *Amiga Hardware Reference Manual* 3rd ed.

## See Also

- [DMA Architecture](../common/dma_architecture.md) — scanline slot allocation, bus arbitration, bandwidth calculations
- [ECS Chipset](../ecs_a600_a3000/chipset_ecs.md) — Super Agnus and ECS Denise enhancements
- [AGA Chipset](../aga_a1200_a4000/chipset_aga.md) — Alice, Lisa, FMODE
- [Video Signal & Timing](../common/video_timing.md) — clock tree, beam counters, video output
