DMA
The WonderSwan Color introduced two DMA blocks:
- General DMA (GDMA) - allowing for fast IRAM/ROM -> IRAM transfers,
- Sound DMA (SDMA) - allowing for IRAM/ROM -> sound transfers in a much less CPU-intensive way than an interrupt.
General DMA
GDMA Source Address ($40, $41, $42)
23 bit 16 15 bit 8 7 bit 0 ---- ---- ---- ---- ---- ---- .... hhhh llll llll llll lll. |||| |||| |||| |||| ||| ++++---++++-++++---++++-++++- Linear source address ($00000 - $FFFFE)
DMA allows source addresses which can be accessed with a 16-bit width and without waitstates; any attempt to access SRAM (8-bit width) or "slow" ROM ($A0 bit 3 set) will cause DMA to immediately return, even if in the middle of a transfer.
GDMA Destination Address ($44, $45)
15 bit 8 7 bit 0 ---- ---- ---- ---- aaaa aaaa aaaa aaa. |||| |||| |||| ||| ++++-++++--++++-+++-- Destination address in IRAM
GDMA allows destination addresses in IRAM.
GDMA Length ($46, $47)
15 bit 8 7 bit 0 ---- ---- ---- ---- bbbb bbbb bbbb bbb. |||| |||| |||| ||| ++++-++++--++++-+++-- Transfer length, in words (if including bit 0: in bytes)
GDMA Control ($48)
7 bit 0 ---- ---- ed.. .... || |+-------- Direction: 0 = increment, 1 = decrement +--------- Enable DMA: 0 = off, 1 = on
The CPU is stalled immediately after General DMA is enabled. General DMA takes (5 + 2 * words)
cycles to complete, where words
is the number of words (2-bytes) transferred.
Sound DMA
Due to its need to access the external cartridge bus, Sound DMA steals 7 cycles - the same amount of time GDMA would take for transferring one byte - every 128 cycles. These are always cycles {117, 118, 119, 120, 121, 122, 123} mod 128
.
Sound DMA supports holding - if enabled, the offset/length counters will be paused, allowing for resuming without losing auto-repeat state. The DMA cycles still occur, but they write $00
to the target port instead of the in-memory value.
Sound DMA support repeat - if enabled, the offset/length counter will have their last written values restored upon the length counter reaching 0. The offset/length counters are copied when their respective ports are written to.
While General DMA uses word access, Sound DMA uses byte access. This means that SRAM is supported as an input source. Also unlike General DMA, streaming from "slow" (>1 cycle) locations is supported; doing so lengthens Sound DMA by the difference.
SDMA Source Address ($4A, $4B, $4C)
23 bit 16 15 bit 8 7 bit 0 ---- ---- ---- ---- ---- ---- .... hhhh llll llll llll llll |||| |||| |||| |||| |||| ++++---++++-++++---++++-++++- Linear source address ($00000 - $FFFFF)
SDMA Length ($4E, $4F, $50)
23 bit 16 15 bit 8 7 bit 0 ---- ---- ---- ---- ---- ---- .... hhhh llll llll llll llll |||| |||| |||| |||| |||| ++++---++++-++++---++++-++++- Transfer length, in bytes
SDMA Control ($52)
7 bit 0 ---- ---- ed.t rhff || | |||| || | ||++- Frequency/Rate: || | || 0 = 24000/6 = 4000 Hz || | || 1 = 24000/4 = 6000 Hz || | || 2 = 24000/2 = 12000 Hz || | || 3 = 24000/1 = 24000 Hz || | |+--- Hold: 0 = normal playback, 1 = hold || | +---- Repeat: 0 = one-shot, 1 = auto-repeat || +------ Target: || 0 = Channel 2 (port $89) || 1 = Hyper Voice |+-------- Direction: 0 = increment, 1 = decrement +--------- Enable DMA: 0 = off, 1 = on