sgdk
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

DMAOpInfodmaQueues
 DMA queue structure.
u16dmaDataBuffer
 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

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:
locationDestination location.
Accepted values:
  • DMA_VRAM (for VRAM transfer).
  • DMA_CRAM (for CRAM transfer).
  • DMA_VSRAM (for VSRAM transfer).
toVRAM/CRAM/VSRAM destination address.
lenNumber of word to allocate and transfer.
stepdestination (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:
lenNumber 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:
locationDestination location.
Accepted values:
  • DMA_VRAM (for VRAM transfer).
  • DMA_CRAM (for CRAM transfer).
  • DMA_VSRAM (for VSRAM transfer).
lenNumber 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:
locationDestination location.
Accepted values:
  • DMA_VRAM (for VRAM transfer).
  • DMA_CRAM (for CRAM transfer).
  • DMA_VSRAM (for VSRAM transfer).
fromSource buffer.
toVRAM/CRAM/VSRAM destination address.
lenNumber of word to transfer.
stepdestination (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:
locationDestination location.
Accepted values:
  • DMA_VRAM (for VRAM transfer).
  • DMA_CRAM (for CRAM transfer).
  • DMA_VSRAM (for VSRAM transfer).
fromSource buffer.
toVRAM/CRAM/VSRAM destination address.
lenNumber of word to transfer.
stepdestination (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:
cmdVDP packed control command (contains operation and destination address).
fromSource buffer.
lenNumber of word to transfer.
stepdestination (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:
locationDestination location.
Accepted values:
  • DMA_VRAM (for VRAM transfer).
  • DMA_CRAM (for CRAM transfer).
  • DMA_VSRAM (for VSRAM transfer).
fromSource buffer address.
toVRAM/CRAM/VSRAM destination address.
lenNumber of word to transfer.
stepdestination (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:
fromVRAM Source address.
toVRAM destination address.
lenNumber of byte to copy.
stepVRAM 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:
toVRAM destination address.
lenNumber of byte to fill (minimum is 2 for even addr destination and 3 for odd addr destination).
A value of 0 mean 0x10000.
valueFill value (byte).
stepVRAM 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:
sizeThe queue size (0 = default size = 64, min size = 20).
capacityThe 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.
bufferSizeSize 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:
locationDestination location.
Accepted values:
  • DMA_VRAM (for VRAM transfer).
  • DMA_CRAM (for CRAM transfer).
  • DMA_VSRAM (for VSRAM transfer).
fromSource buffer address.
toVRAM/CRAM/VSRAM destination address.
lenNumber of word to transfer.
stepdestination (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:
lenNumber 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:
valueThe 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:
valueThe 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:
valueThe 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:
tmTransfer method.
Accepted values are:
  • CPU
  • DMA
  • DMA_QUEUE
  • DMA_QUEUE_COPY
locationDestination location.
Accepted values:
  • DMA_VRAM (for VRAM transfer).
  • DMA_CRAM (for CRAM transfer).
  • DMA_VSRAM (for VSRAM transfer).
fromSource buffer.
toVRAM/CRAM/VSRAM destination address.
lenNumber of word to allocate and transfer.
stepdestination (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