- Blitter (4 channels)
- Bitplanes (6 channels)
- Copper (1 channel)
- Audio (4 channels)
- Sprites (8 channels)
- Disk (1 channel)
- Memory Refresh (1 channel)
The DMA controller interleaves DMA access so that normally, the CPU can run at full speed using at most alternate "colour" clock cycles (I'll explain this in a minute). The DMA channels are prioritised so that the most important functions always get serviced.
Excluding the Memory Refresh DMA which always happens first, the highest priority channels are the Disk, Audio, Sprite and Bitplane. Bitplane DMA can have priority over Sprites and steal some of their time slots when a wider than normal display is being used.
The Copper has the next priority, then the Blitter and finally the 68000.
If a device does not request one of it's allocated time slots, the slot can be used by something else.
The time slots are allocated during each horizontal scan of the video beam. Each horizontal scanline is broken up into "colour" clock cycles. A colour clock cycle is approx. 280 nanoseconds. A horizontal scanline is about 63 microseconds duration and contains 227.5 colour clock cycles or time slots. Out of the 227.5 cycles, only 226 are available to be allocated.
The time slots are allocated like this:
- 4 slots for Memory Refresh
- 3 slots for Disk DMA
- 4 slots for Audio DMA (2 bytes per channel)
- 16 slots for Sprite DMA (2 words per channel)
- 80 slots for Bitplane DMA.
The challenge is how to emulate this behaviour. My current emulation loop which basically just fetches the next CPU instruction and executes it, obviously won't cut it any more.
My thoughts are to create some kind of a prioritised queue mechanism where components request time slots. But it needs to be fast. Some major head scratching and beard stroking coming up.