DMA: Difference between revisions

From WSdev Wiki
Jump to navigationJump to search
No edit summary
No edit summary
 
(8 intermediate revisions by 2 users not shown)
Line 11: Line 11:


<pre>
<pre>
23  bit 16 15  bit  8 7  bit  0
23  bit 16 15  bit  8   7  bit  0
  ---- ---- ---- ---- ---- ----
  ---- ----   ---- ----   ---- ----
  .... hhhh llll llll llll llll
  .... hhhh   llll llll   llll lll.
       ++++--++++-++++--++++-++++- Linear source address
      ||||  |||| ||||  |||| |||
                                  ($00000 - $FFFFF)
       ++++---++++-++++---++++-++++- Linear source address
                                    ($00000 - $FFFFE)
</pre>
</pre>


DMA allows source addresses in IRAM and ROM; any attempt to access SRAM causes DMA to immediately return, even if in the middle of a transfer.
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.
 
TODO: What about source addresses in ROM configured as 8-bit?


{{Anchor|GDMA Destination Address}}
{{Anchor|GDMA Destination Address}}
Line 28: Line 27:
15  bit  8  7  bit  0
15  bit  8  7  bit  0
  ---- ----  ---- ----
  ---- ----  ---- ----
  aaaa aaaa  aaaa aaaa
  aaaa aaaa  aaaa aaa.
  ++++-++++--++++-++++- Destination address in IRAM
|||| ||||  |||| |||
  ++++-++++--++++-+++-- Destination address in IRAM
</pre>
</pre>


Line 40: Line 40:
15  bit  8  7  bit  0
15  bit  8  7  bit  0
  ---- ----  ---- ----
  ---- ----  ---- ----
  bbbb bbbb  bbbb bbbb
  bbbb bbbb  bbbb bbb.
  ++++-++++--++++-++++- Transfer length, in bytes
|||| ||||  |||| |||
  ++++-++++--++++-+++-- Transfer length, in words
                      (if including bit 0: in bytes)
</pre>
</pre>


Line 51: Line 53:
---- ----
---- ----
ed.. ....
ed.. ....
||
|+-------- Direction: 0 = increment, 1 = decrement
|+-------- Direction: 0 = increment, 1 = decrement
+--------- Enable DMA: 0 = off, 1 = on
+--------- Enable DMA: 0 = off, 1 = on
</pre>
</pre>


The CPU is stalled immediately after General DMA is enabled. General DMA takes <code>(5 + 2 * length)</code> cycles to complete.
The CPU is stalled immediately after General DMA is enabled. General DMA takes <code>(5 + 2 * words)</code> cycles to complete, where <code>words</code> is the number of words (2-bytes) transferred.


== Sound DMA ==
== Sound DMA ==


Sound DMA is a specialized form of General DMA with a hard-coded destination and built-in timer logic. As such, all of the rules for GDMA apply to SDMA as well.
Sound DMA allows copying sample data to either Channel 2 or Hyper Voice automatically while incurring a much lower cost than that of a CPU interrupt.
 
Features:
 
* 4000, 6000, 12000, 24000 Hz sample rates.
* '''Auto-repeat''': If enabled, every time the length counter reaches 0, a shadowed copy of the offset and length as written to the I/O ports will be restored. If disabled, bit 7 will automatically clear on transfer completion, same as with General DMA.
* '''Holding''': If enabled, the offset/length counters will be paused, and $00 will be written on every Sound DMA tick as opposed to the value in memory. This does not impact the timing of Sound DMA.
 
When playing back sound, the visible ports ($4A-$4C, $4E-$50) are the ones updated live; any edits to them are reflected immediately, as well as written to the shadow copy used for auto-repeat.


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 <code>{117, 118, 119, 120, 121, 122, 123} mod 128</code>.
The enable/disable bit of Sound DMA does not affect the offset/length counters in any way; for example, if a sample is stopped mid-playthrough, then started again, it will pick up right where it left off.


TODO: How does Sound DMA interact with the cartridge waitstate configuration?
Unlike General DMA, Sound DMA copies data per byte. 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 the duration of Sound DMA. Due to its need to access the external cartridge bus, Sound DMA must use cycles normally reserved for the CPU; it uses <code>6 + N</code> cycles every 128 cycles, always starting from cycle <code>117 mod 128</code>. <code>N</code> refers to the access time of the area from which audio is being streamed from, and is typically 1 cycle.


{{Anchor|SDMA Source Address Low}}
{{Anchor|SDMA Source Address Low}}
Line 70: Line 81:


<pre>
<pre>
23  bit 16 15  bit  8 7  bit  0
23  bit 16 15  bit  8   7  bit  0
  ---- ---- ---- ---- ---- ----
  ---- ----   ---- ----   ---- ----
  .... hhhh llll llll llll llll
  .... hhhh   llll llll   llll llll
       ++++--++++-++++--++++-++++- Linear source address
      ||||  |||| ||||  |||| ||||
       ++++---++++-++++---++++-++++- Linear source address
                                   ($00000 - $FFFFF)
                                   ($00000 - $FFFFF)
</pre>
</pre>
Upon writing to any of the bytes, said byte (and only said byte) is copied to a shadow register, used for restoring the offset/length counter when auto-repeat is enabled.


{{Anchor|SDMA Length}}
{{Anchor|SDMA Length}}
Line 81: Line 95:


<pre>
<pre>
23  bit 16 15  bit  8 7  bit  0
23  bit 16 15  bit  8   7  bit  0
  ---- ---- ---- ---- ---- ----
  ---- ----   ---- ----   ---- ----
  .... hhhh llll llll llll llll
  .... hhhh   llll llll   llll llll
       ++++--++++-++++--++++-++++- Transfer length, in bytes
      ||||  |||| ||||  |||| ||||
       ++++---++++-++++---++++-++++- Transfer length, in bytes
</pre>
</pre>
Upon writing to any of the bytes, said byte (and only said byte) is copied to a shadow register, used for restoring the offset/length counter when auto-repeat is enabled.


{{Anchor|SDMA Control}}
{{Anchor|SDMA Control}}
Line 93: Line 110:
7  bit  0
7  bit  0
---- ----
---- ----
ed.t r?ff
ed.t rhff
|| | | ++- Frequency/Rate:
|| | ||||
|| | |       0 = 24000/1 = 24000 Hz
|| | ||++- Frequency/Rate:
|| | |       1 = 24000/2 = 12000 Hz
|| | ||      0 = 24000/6 = 4000 Hz
|| | |       2 = 24000/4 = 6000 Hz
|| | ||      1 = 24000/4 = 6000 Hz
|| | |       3 = 24000/6 = 4000 Hz
|| | ||      2 = 24000/2 = 12000 Hz
|| | ||      3 = 24000/1 = 24000 Hz
|| | |+--- Hold: 0 = normal playback, 1 = hold
|| | +---- Repeat: 0 = one-shot, 1 = auto-repeat
|| | +---- Repeat: 0 = one-shot, 1 = auto-repeat
|| +------ Target:
|| +------ Target:
Line 106: Line 125:
+--------- Enable DMA: 0 = off, 1 = on
+--------- Enable DMA: 0 = off, 1 = on
</pre>
</pre>
The CPU is stalled immediately after General DMA is enabled. General DMA takes <code>(5 + 2 * length)</code> cycles to complete.

Latest revision as of 15:34, 2 September 2023

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

Sound DMA allows copying sample data to either Channel 2 or Hyper Voice automatically while incurring a much lower cost than that of a CPU interrupt.

Features:

  • 4000, 6000, 12000, 24000 Hz sample rates.
  • Auto-repeat: If enabled, every time the length counter reaches 0, a shadowed copy of the offset and length as written to the I/O ports will be restored. If disabled, bit 7 will automatically clear on transfer completion, same as with General DMA.
  • Holding: If enabled, the offset/length counters will be paused, and $00 will be written on every Sound DMA tick as opposed to the value in memory. This does not impact the timing of Sound DMA.

When playing back sound, the visible ports ($4A-$4C, $4E-$50) are the ones updated live; any edits to them are reflected immediately, as well as written to the shadow copy used for auto-repeat.

The enable/disable bit of Sound DMA does not affect the offset/length counters in any way; for example, if a sample is stopped mid-playthrough, then started again, it will pick up right where it left off.

Unlike General DMA, Sound DMA copies data per byte. 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 the duration of Sound DMA. Due to its need to access the external cartridge bus, Sound DMA must use cycles normally reserved for the CPU; it uses 6 + N cycles every 128 cycles, always starting from cycle 117 mod 128. N refers to the access time of the area from which audio is being streamed from, and is typically 1 cycle.

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)

Upon writing to any of the bytes, said byte (and only said byte) is copied to a shadow register, used for restoring the offset/length counter when auto-repeat is enabled.

SDMA Length ($4E, $4F, $50)

23  bit  16 15  bit  8   7  bit  0
 ---- ----   ---- ----   ---- ----
 .... hhhh   llll llll   llll llll
      ||||   |||| ||||   |||| ||||
      ++++---++++-++++---++++-++++- Transfer length, in bytes

Upon writing to any of the bytes, said byte (and only said byte) is copied to a shadow register, used for restoring the offset/length counter when auto-repeat is enabled.

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