sgdk: dma.h File Reference

sgdk

- Main Page
- Related Pages
- Classes
- Files

- File List
- File Members

Classes | Defines | Enumerations | Functions | Variables
dma.h File Reference

DMA support. More...

`#include "config.h"`
`#include "types.h"`

Go to the source code of this file.

## Classes

struct | DMAOpInfo
| DMA transfer definition (used for DMA queue) More...

## Defines

#define | DMA_VRAM 0
| VRAM destination for DMA operation.
#define | DMA_CRAM 1
| CRAM destination for DMA operation.
#define | DMA_VSRAM 2
| VSRAM destination for DMA operation.
#define | DMA_QUEUE_SIZE_DEFAULT 80
#define | DMA_QUEUE_SIZE_MIN 32
#define | DMA_TRANSFER_CAPACITY_NTSC 7200
#define | DMA_TRANSFER_CAPACITY_PAL_LOW 8000
#define | DMA_TRANSFER_CAPACITY_PAL_MAX 15000
#define | DMA_BUFFER_SIZE_NTSC DMA_TRANSFER_CAPACITY_NTSC
#define | DMA_BUFFER_SIZE_PAL_LOW DMA_TRANSFER_CAPACITY_PAL_LOW
#define | DMA_BUFFER_SIZE_PAL_MAX (14 * 1024)
#define | DMA_BUFFER_SIZE_MIN (2 * 1024)

## Enumerations

enum | TransferMethod { CPU = 0, DMA = 1, DMA_QUEUE = 2, DMA_QUEUE_COPY = 3 }
| VRAM transfer method. More...

## Functions

void | DMA_init ()
| Initialize the DMA queue sub system with default settings.
void | DMA_initEx (u16 size, u16 capacity, u16 bufferSize)
| Initialize the DMA queue sub system.
u16 | DMA_getAutoFlush ()
| Returns TRUE if the DMA_flushQueue() method is automatically called at VBlank to process DMA operations pending in the queue.
void | DMA_setAutoFlush (bool value)
| If set to TRUE (default) then the DMA_flushQueue() method is automatically called at VBlank to process DMA operations pending in the queue otherwise you have to call the DMA_flushQueue() method by yourself.
u16 | DMA_getMaxQueueSize ()
| Returns the maximum allowed number of pending transfer in the queue (allocated queue size).
void | DMA_setMaxQueueSize (u16 value)
| Sets the maximum allowed number of pending transfer in the queue (allocated queue size). WARNING: changing the queue size will clear the DMA queue.
void | DMA_setMaxQueueSizeToDefault ()
| Sets the maximum allowed number of pending transfer in the queue (allocated queue size) to default value (64). WARNING: changing the queue size will clear the DMA queue.
u16 | DMA_getMaxTransferSize ()
| Returns the maximum allowed size (in bytes) to transfer per DMA_flushQueue() call. A value of 0 means there is no DMA limit.
void | DMA_setMaxTransferSize (u16 value)
| Sets the maximum amount of data (in bytes) to transfer per DMA_flushQueue() call. VBlank period allows to transfer up to 7.2 KB on NTSC system and 15 KB on PAL system. By default there is no size limit (0)
void | DMA_setMaxTransferSizeToDefault ()
| Sets the maximum amount of data (in bytes) to default value (7.2 KB on NTSC system and 15 KB on PAL system).
u16 | DMA_getBufferSize ()
| Returns the size (in bytes) of the temporary data buffer which can be used to store data that will be transferred through the DMA queue.
void | DMA_setBufferSize (u16 value)
| Sets the size (in bytes) of the temporary data buffer which can be used to store data that will be transferred through the DMA queue. WARNING: changing the buffer size will clear the DMA queue.
void | DMA_setBufferSizeToDefault ()
| Sets the size (in bytes) of the temporary data buffer to default value (8 KB on NTSC system and 14 KB on PAL system).
u16 | DMA_getIgnoreOverCapacity ()
| Return TRUE means that we ignore future DMA operation when we reach the maximum capacity (see DMA_setIgnoreOverCapacity(..) method).
void | DMA_setIgnoreOverCapacity (bool value)
| Set the "over capacity" DMA queue strategy (default is FALSE).
void | DMA_clearQueue ()
| Clears the DMA queue (all queued operations are lost).
void | DMA_flushQueue ()

Transfer the content of the DMA queue to the VDP:
Each pending DMA operation is sent to the VDP and processed as quickly as possible.
This method returns when all DMA operations present in the queue has been transferred (or when maximum capacity has been reached).
Note that this method is automatically called at VBlank time and you shouldn't call yourself except if you want to process it before vblank (if you manually extend blank period with h-int for instance) in which case you can disable the auto flush feature (see DMA_setAutoFlush(...))

u16 | DMA_getQueueSize ()
| Returns the number of transfer currently pending in the DMA queue.
u16 | DMA_getQueueTransferSize ()
| Returns the size (in byte) of data to be transferred currently present in the DMA queue. NTSC frame allows about 7.6 KB of data to be transferred during VBlank (in H40) while PAL frame allows about 17 KB (in H40).
void * | DMA_allocateTemp (u16 len)

Tool method allowing to allocate memory from the DMA temporary buffer if you need a very temporary buffer.
Don't forget to release memory using DMA_releaseTemp(..).
WARNING: it's very important to disable interrupts while using the temporary DMA buffer as DMA buffer can be flushed on interrupt.

void | DMA_releaseTemp (u16 len)
| Tool method allowing to release memory previously allocated using DMA_allocateTemp(..). WARNING: it's very important to disable interrupts while using the temporary DMA buffer as DMA buffer can be flushed on interrupt.
bool | DMA_transfer (TransferMethod tm, u8 location, void *from, u16 to, u16 len, u16 step)
| General method to transfer data to VDP memory.
bool | DMA_canQueue (u8 location, u16 len)
| Return TRUE if we have enough DMA capacity to transfer the given data block len (see DMA_setMaxTransferSize(..))
void * | DMA_allocateAndQueueDma (u8 location, u16 to, u16 len, u16 step)

Allocate temporary memory and queues the DMA transfer operation in the DMA queue.
The idea of the DMA queue is to burst all DMA operations during VBLank to maximize bandwidth usage.
IMPORTANT: You need to fill the returned data buffer before DMA occurs so it's a good practise to disable interrupts before calling this method and re-enable them *after* you filled the buffer to avoid DMA queue flush operation happening in between.

bool | DMA_copyAndQueueDma (u8 location, void *from, u16 to, u16 len, u16 step)
| Same as DMA_queueDma(..) method except that it first copies the data to transfer through DMA queue into a temporary buffer. This is useful when you know that source data may be modified before DMA acutally occurs and want to avoid that.
bool | DMA_queueDma (u8 location, void *from, u16 to, u16 len, u16 step)
| Queues the specified DMA transfer operation in the DMA queue. The idea of the DMA queue is to burst all DMA operations during VBLank to maximize bandwidth usage.
bool | DMA_queueDmaFast (u8 location, void *from, u16 to, u16 len, u16 step)
| Same as DMA_queueDma(..) method except if doesn't check for 128 KB bank crossing on source.
void | DMA_doDma (u8 location, void *from, u16 to, u16 len, s16 step)
| Do DMA transfer operation immediately.
void | DMA_doDmaFast (u8 location, void *from, u16 to, u16 len, s16 step)
| Same as DMA_doDma(..) method except if doesn't check for 128 KB bank crossing on source.
void | DMA_doCPUCopy (u8 location, void *from, u16 to, u16 len, s16 step)
| Do software (CPU) copy to VDP memory (mainly for testing purpose as it's slower than using DMA)
void | DMA_doCPUCopyDirect (u32 cmd, void *from, u16 len, s16 step)
| Do software (CPU) copy to VDP memory (mainly for testing purpose as it's slower than using DMA)
void | DMA_doVRamFill (u16 to, u16 len, u8 value, s16 step)
| Do VRAM DMA fill operation.
void | DMA_doVRamCopy (u16 from, u16 to, u16 len, s16 step)
| Do VRAM DMA copy operation.
void | DMA_waitCompletion ()
| Wait current DMA fill/copy operation to complete (same as VDP_waitDMACompletion())

## Variables

DMAOpInfo * | dmaQueues
| DMA queue structure.
u16 * | dmaDataBuffer
| DMA queue structure.

## Detailed Description

DMA support.

Author:
  Stephane Dallongeville

Date:
  04/2015

This unit provides methods to use the hardware DMA capabilities.

## Enumeration Type Documentation

enum TransferMethod

VRAM transfer method.

Enumerator:

  CPU | Transfer through the CPU immediately (slower.. useful for testing purpose mainly)
  DMA | Transfer through DMA immediately, using DMA is faster but can lock Z80 execution
  DMA_QUEUE | Put in the DMA queue so it will be transferred at next VBlank. Using DMA is faster but can lock Z80 execution
  DMA_QUEUE_COPY | Copy the buffer and put in the DMA queue so it will be transferred at next VBlank. Using DMA is faster but can lock Z80 execution

## Function Documentation

void* DMA_allocateAndQueueDma | ( | u8 | location,
|  | u16 | to,
|  | u16 | len,
|  | u16 | step
| ) |  |

Allocate temporary memory and queues the DMA transfer operation in the DMA queue.
The idea of the DMA queue is to burst all DMA operations during VBLank to maximize bandwidth usage.
IMPORTANT: You need to fill the returned data buffer before DMA occurs so it's a good practise to disable interrupts before calling this method and re-enable them *after* you filled the buffer to avoid DMA queue flush operation happening in between.

Parameters:

  location

  Destination location.
  Accepted values:
  - DMA_VRAM (for VRAM transfer).
  - DMA_CRAM (for CRAM transfer).
  - DMA_VSRAM (for VSRAM transfer).

  to | VRAM/CRAM/VSRAM destination address.
  len | Number of word to allocate and transfer.
  step | destination (VRAM/VSRAM/CRAM) address increment step after each write (0 to 255). By default you should set it to 2 for normal copy operation but you can use different value for specific operation.

Returns:
  The source buffer pointer that will be used for the DMA transfer so you can fill its content.
  Returns NULL if the buffer is full or if the DMA queue operation failed (queue is full).

See also:
  DMA_queueDMA(..)
  DMA_copyAndQueueDma(..)

void* DMA_allocateTemp | ( | u16 | len | ) |

Tool method allowing to allocate memory from the DMA temporary buffer if you need a very temporary buffer.
Don't forget to release memory using DMA_releaseTemp(..).
WARNING: it's very important to disable interrupts while using the temporary DMA buffer as DMA buffer can be flushed on interrupt.

Parameters:

  len | Number of word to allocate.

Returns:
  The source buffer pointer if allocation succeeded,.
  Returns NULL if the buffer is full (or not big enough).

See also:
  DMA_releaseTemp(..)

bool DMA_canQueue | ( | u8 | location,
|  | u16 | len
| ) |  |

Return TRUE if we have enough DMA capacity to transfer the given data block len (see DMA_setMaxTransferSize(..))

Parameters:

  location

  Destination location.
  Accepted values:
  - DMA_VRAM (for VRAM transfer).
  - DMA_CRAM (for CRAM transfer).
  - DMA_VSRAM (for VSRAM transfer).

  len | Number of word we want to transfer.

Returns:
  TRUE if we have enough capacity, FALSE otherwise

See also:
  DMA_getMaxTransferSize(..)
  DMA_queueDma(..)

void DMA_clearQueue | ( |  | ) |

Clears the DMA queue (all queued operations are lost).

See also:
  DMA_flushQueue()

bool DMA_copyAndQueueDma | ( | u8 | location,
|  | void * | from,
|  | u16 | to,
|  | u16 | len,
|  | u16 | step
| ) |  |

Same as DMA_queueDma(..) method except that it first copies the data to transfer through DMA queue into a temporary buffer.
This is useful when you know that source data may be modified before DMA acutally occurs and want to avoid that.

Parameters:

  location

  Destination location.
  Accepted values:
  - DMA_VRAM (for VRAM transfer).
  - DMA_CRAM (for CRAM transfer).
  - DMA_VSRAM (for VSRAM transfer).

  from | Source buffer.
  to | VRAM/CRAM/VSRAM destination address.
  len | Number of word to transfer.
  step | destination (VRAM/VSRAM/CRAM) address increment step after each write (0 to 255). By default you should set it to 2 for normal copy operation but you can use different value for specific operation.

Returns:
  FALSE if the operation failed (queue is full)

See also:
  DMA_doDma(..)
  DMA_queueDma(..)

void DMA_doCPUCopy | ( | u8 | location,
|  | void * | from,
|  | u16 | to,
|  | u16 | len,
|  | s16 | step
| ) |  |

Do software (CPU) copy to VDP memory (mainly for testing purpose as it's slower than using DMA)

Parameters:

  location

  Destination location.
  Accepted values:
  - DMA_VRAM (for VRAM transfer).
  - DMA_CRAM (for CRAM transfer).
  - DMA_VSRAM (for VSRAM transfer).

  from | Source buffer.
  to | VRAM/CRAM/VSRAM destination address.
  len | Number of word to transfer.
  step | destination (VRAM/VSRAM/CRAM) address increment step after each write (-1 to keep current step). By default you should set it to 2 for normal copy operation but you can use different value for specific operation.

void DMA_doCPUCopyDirect | ( | u32 | cmd,
|  | void * | from,
|  | u16 | len,
|  | s16 | step
| ) |  |

Do software (CPU) copy to VDP memory (mainly for testing purpose as it's slower than using DMA)

Parameters:

  cmd | VDP packed control command (contains operation and destination address).
  from | Source buffer.
  len | Number of word to transfer.
  step | destination (VRAM/VSRAM/CRAM) address increment step after each write (-1 to keep current step). By default you should set it to 2 for normal copy operation but you can use different value for specific operation.

void DMA_doDma | ( | u8 | location,
|  | void * | from,
|  | u16 | to,
|  | u16 | len,
|  | s16 | step
| ) |  |

Do DMA transfer operation immediately.

Parameters:

  location

  Destination location.
  Accepted values:
  - DMA_VRAM (for VRAM transfer).
  - DMA_CRAM (for CRAM transfer).
  - DMA_VSRAM (for VSRAM transfer).

  from | Source buffer address.
  to | VRAM/CRAM/VSRAM destination address.
  len | Number of word to transfer.
  step | destination (VRAM/VSRAM/CRAM) address increment step after each write (-1 to keep current step). By default you should set it to 2 for normal copy operation but you can use different value for specific operation.

See also:
  DMA_queue(..)

void DMA_doDmaFast | ( | u8 | location,
|  | void * | from,
|  | u16 | to,
|  | u16 | len,
|  | s16 | step
| ) |  |

Same as DMA_doDma(..) method except if doesn't check for 128 KB bank crossing on source.

See also:
  DMA_doDma(..)

void DMA_doVRamCopy | ( | u16 | from,
|  | u16 | to,
|  | u16 | len,
|  | s16 | step
| ) |  |

Do VRAM DMA copy operation.

Parameters:

  from | VRAM Source address.
  to | VRAM destination address.
  len | Number of byte to copy.
  step | VRAM address increment step after each write (-1 to keep current step). should be 1 for a classic copy operation but you can use different value for specific operation.

void DMA_doVRamFill | ( | u16 | to,
|  | u16 | len,
|  | u8 | value,
|  | s16 | step
| ) |  |

Do VRAM DMA fill operation.

Parameters:

  to | VRAM destination address.
  len | Number of byte to fill (minimum is 2 for even addr destination and 3 for odd addr destination). A value of 0 mean 0x10000.
  value | Fill value (byte).
  step | VRAM address increment step after each write (-1 to keep current step). should be 1 for a classic fill operation but you can use different value for specific operation.

void DMA_flushQueue | ( |  | ) |

Transfer the content of the DMA queue to the VDP:
Each pending DMA operation is sent to the VDP and processed as quickly as possible.
This method returns when all DMA operations present in the queue has been transferred (or when maximum capacity has been reached).
Note that this method is automatically called at VBlank time and you shouldn't call yourself except if you want to process it before vblank (if you manually extend blank period with h-int for instance) in which case you can disable the auto flush feature (see DMA_setAutoFlush(...))

See also:
  DMA_queue(...)
  DMA_setAutoFlush(...)

u16 DMA_getAutoFlush | ( |  | ) |

Returns TRUE if the DMA_flushQueue() method is automatically called at VBlank to process DMA operations pending in the queue.

See also:
  DMA_setAutoFlush()
  DMA_flushQueue()

u16 DMA_getBufferSize | ( |  | ) |

Returns the size (in bytes) of the temporary data buffer which can be used to store data that will be transferred through the DMA queue.

See also:
  DMA_setBufferSize()

u16 DMA_getIgnoreOverCapacity | ( |  | ) |

Return TRUE means that we ignore future DMA operation when we reach the maximum capacity (see DMA_setIgnoreOverCapacity(..) method).

See also:
  DMA_setIgnoreOverCapacity()

u16 DMA_getMaxQueueSize | ( |  | ) |

Returns the maximum allowed number of pending transfer in the queue (allocated queue size).

See also:
  DMA_setMaxQueueSize()

u16 DMA_getMaxTransferSize | ( |  | ) |

Returns the maximum allowed size (in bytes) to transfer per DMA_flushQueue() call.
A value of 0 means there is no DMA limit.

See also:
  DMA_setMaxTransferSize()

void DMA_init | ( |  | ) |

Initialize the DMA queue sub system with default settings.

SGDK automatically call this method on hard reset so you don't need to call it again unless you want to change the default parameters in which casse you should use DMA_initEx(..)

See also:
  DMA_initEx(..)

void DMA_initEx | ( | u16 | size,
|  | u16 | capacity,
|  | u16 | bufferSize
| ) |  |

Initialize the DMA queue sub system.

Parameters:

  size | The queue size (0 = default size = 64, min size = 20).
  capacity | The maximum allowed size (in bytes) to transfer per DMA_flushQueue() call (0 = default = no limit). Depending the current selected strategy, furthers transfers can be ignored (by default all transfers are done whatever is the limit). See the DMA_setIgnoreOverCapacity(..) method to change the strategy to adopt when capacity limit is reached.
  bufferSize | Size of the buffer (in bytes) to store temporary data that will be transferred through the DMA queue (0 = default size = 8192 on NTSC and 14336 on PAL). The buffer should be big enough to contains all temporary that you need to store before next DMA_flushQueue() call.

SGDK automatically call this method on hard reset so you don't need to call it again unless you want to change the default parameters.

See also:
  DMA_setIgnoreOverCapacity(..)

bool DMA_queueDma | ( | u8 | location,
|  | void * | from,
|  | u16 | to,
|  | u16 | len,
|  | u16 | step
| ) |  |

Queues the specified DMA transfer operation in the DMA queue.
The idea of the DMA queue is to burst all DMA operations during VBLank to maximize bandwidth usage.

Parameters:

  location

  Destination location.
  Accepted values:
  - DMA_VRAM (for VRAM transfer).
  - DMA_CRAM (for CRAM transfer).
  - DMA_VSRAM (for VSRAM transfer).

  from | Source buffer address.
  to | VRAM/CRAM/VSRAM destination address.
  len | Number of word to transfer.
  step | destination (VRAM/VSRAM/CRAM) address increment step after each write (0 to 255). By default you should set it to 2 for normal copy operation but you can use different value for specific operation.

Returns:
  FALSE if the operation failed (queue is full)

See also:
  DMA_doDma(..)

bool DMA_queueDmaFast | ( | u8 | location,
|  | void * | from,
|  | u16 | to,
|  | u16 | len,
|  | u16 | step
| ) |  |

Same as DMA_queueDma(..) method except if doesn't check for 128 KB bank crossing on source.

See also:
  DMA_queueDma(..)

void DMA_releaseTemp | ( | u16 | len | ) |

Tool method allowing to release memory previously allocated using DMA_allocateTemp(..).
WARNING: it's very important to disable interrupts while using the temporary DMA buffer as DMA buffer can be flushed on interrupt.

Parameters:

  len | Number of word to release.

See also:
  DMA_allocateTemp(..)

void DMA_setAutoFlush | ( | bool | value | ) |

If set to TRUE (default) then the DMA_flushQueue() method is automatically called at VBlank to process DMA operations pending in the queue otherwise you have to call the DMA_flushQueue() method by yourself.

See also:
  DMA_flushQueue()

void DMA_setBufferSize | ( | u16 | value | ) |

Sets the size (in bytes) of the temporary data buffer which can be used to store data that will be transferred through the DMA queue.
WARNING: changing the buffer size will clear the DMA queue.

Parameters:

  value | The size of the temporary data buffer (in bytes). Minimum allowed buffer size if 2048 (internals methods require a minimal buffer size)

See also:
  DMA_getBufferSize()
  DMA_setBufferSizeToDefault()

void DMA_setBufferSizeToDefault | ( |  | ) |

Sets the size (in bytes) of the temporary data buffer to default value (8 KB on NTSC system and 14 KB on PAL system).

See also:
  DMA_setBufferSize()

void DMA_setIgnoreOverCapacity | ( | bool | value | ) |

Set the "over capacity" DMA queue strategy (default is FALSE).

When set to TRUE any DMA operation queued after we reached the maximum defined transfer capacity with DMA_setMaxTransferSize(..) are ignored.
When set to FALSE all DMA operations are done even when we are over the maximum capacity (which can lead to important slowdown).

See also:
  DMA_setMaxTransferSize()

void DMA_setMaxQueueSize | ( | u16 | value | ) |

Sets the maximum allowed number of pending transfer in the queue (allocated queue size).
WARNING: changing the queue size will clear the DMA queue.

Parameters:

  value | The queue size (minimum allowed size = 20)

See also:
  DMA_getMaxQueueSize()
  DMA_setMaxQueueSizeToDefault()

void DMA_setMaxQueueSizeToDefault | ( |  | ) |

Sets the maximum allowed number of pending transfer in the queue (allocated queue size) to default value (64).
WARNING: changing the queue size will clear the DMA queue.

See also:
  DMA_setMaxQueueSize()

void DMA_setMaxTransferSize | ( | u16 | value | ) |

Sets the maximum amount of data (in bytes) to transfer per DMA_flushQueue() call.
VBlank period allows to transfer up to 7.2 KB on NTSC system and 15 KB on PAL system.
By default there is no size limit (0)

Parameters:

  value | The maximum amount of data (in bytes) to transfer during DMA_flushQueue() operation. Use 0 for no limit.

See also:
  DMA_flushQueue()

void DMA_setMaxTransferSizeToDefault | ( |  | ) |

Sets the maximum amount of data (in bytes) to default value (7.2 KB on NTSC system and 15 KB on PAL system).

See also:
  DMA_setMaxTransferSize()

bool DMA_transfer | ( | TransferMethod | tm,
|  | u8 | location,
|  | void * | from,
|  | u16 | to,
|  | u16 | len,
|  | u16 | step
| ) |  |

General method to transfer data to VDP memory.

Parameters:

  tm

  Transfer method.
  Accepted values are:
  - CPU
  - DMA
  - DMA_QUEUE
  - DMA_QUEUE_COPY

  location

  Destination location.
  Accepted values:
  - DMA_VRAM (for VRAM transfer).
  - DMA_CRAM (for CRAM transfer).
  - DMA_VSRAM (for VSRAM transfer).

  from | Source buffer.
  to | VRAM/CRAM/VSRAM destination address.
  len | Number of word to allocate and transfer.
  step | destination (VRAM/VSRAM/CRAM) address increment step after each write (0 to 255). By default you should set it to 2 for normal copy operation but you can use different value for specific operation.

Returns:
  TRUE if the operation succeeded, FALSE otherwise (buffer or queue full).

See also:
  DMA_queueDMA(..)

All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines