Difference between revisions of "Video DMA Block"
(→VDMA Size) |
|||
(10 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | = Overview = | ||
+ | |||
+ | The Video DMA block is a portion of the Vicky II chip which is responsible for high speed memory transfers to or from video memory. | ||
+ | The block supports several types of memory operations: | ||
+ | * Copying a contiguous block of data from one section of memory to another (1D or linear transfers) | ||
+ | * Copying a rectangular subset of a larger image from one section of memory to another (2D or block transfers) | ||
+ | * Filling a contiguous block of addresses in video memory with a single byte (1D fill) | ||
+ | * Filling a rectangular subset of a larger image with a single byte (2D fill) | ||
+ | |||
+ | VDMA can copy data between different locations within video RAM, or can be used in conjunction with the [[System DMA Block]] | ||
+ | to transfer data between video RAM and system RAM. | ||
+ | |||
+ | IMPORTANT! VDMA operates in the background and does not halt the CPU, but it will prevent the CPU from accessing video RAM while a VDMA | ||
+ | is in process. It is therefore critically important for any calling program to avoid accessing VRAM while VDMA is in progress. To repeat: do not | ||
+ | try to access video RAM while there is a VDMA in operation. | ||
+ | |||
+ | = Setting up a VDMA = | ||
+ | |||
+ | The process of starting a VDMA is as follows: | ||
+ | # Ensure that there is no VDMA already in operation by checking to make sure that the VDMA_STAT_VDMA_IPS bit of VDMA_STATUS_REG is | ||
+ | clear. This is somewhat optional. If you are certain no VDMA is in flight, you can skip this step. | ||
+ | # Set the VDMA_CONTROL_REG bits to enable the VDMA block, set 1D or 2D operation, set transfer or fill, and indicate if the source or | ||
+ | destination is system RAM. If your code will use interrupts, you may enable | ||
+ | VDMA interrupts with the VDMA_CTRL_Int_Enable bit. Do not set VDMA_CTRL_Start_TRF at this point. | ||
+ | # If the source of the data is in video RAM, set VDMA_SRC_ADDY. The address stored here is the offset within video RAM (so relative to $B0:0000). | ||
+ | # If the destination of the data is in video RAM, set VDMA_DST_ADDY. The address stored here is the offset within video RAM (so relative to $B0:0000). | ||
+ | # If the transfer is a 1D operation, set the size (number of bytes) in VDMA_SIZE. If the transfer is a 2D operation, set the width in VDMA_X_SIZE, and the height in VDMA_Y_SIZE. | ||
+ | # If the transfer is a 2D operation, set the source and destination stride values. | ||
+ | # Set the VDMA_CTRL_Start_TRF bit of VDMA_CONTROL_REG to begin the actual transfer. | ||
+ | # Either wait for interrupt or poll the VDMA_STAT_VDMA_IPS of VDMA_STATUS_REG until the VDMA is done. | ||
+ | # Clear the VDMA_CTRL_Start_TRF bit of VDMA_CONTROL_REG. | ||
+ | |||
+ | NOTE: If you are transferring data between system RAM and video RAM, you will have to set up both an SDMA and a VDMA operation, which has special considerations. | ||
+ | Please see [[System and Video RAM DMA]] for details. | ||
+ | |||
+ | = Video DMA Registers = | ||
+ | |||
{| class = "wikitable" | {| class = "wikitable" | ||
! Start Address | ! Start Address | ||
! Stop Address | ! Stop Address | ||
− | ! Register | + | ! Register Name |
! Additional Info | ! Additional Info | ||
|- | |- | ||
Line 47: | Line 84: | ||
|- | |- | ||
− | | $AF:0402 || $AF: | + | | $AF:0402 || $AF:0404 || VDMA_SRC_ADDY || 24-bit address of the source block (relative to start of video RAM) |
|- | |- | ||
− | | $AF: | + | | $AF:0405 || $AF:0407 || VDMA_DST_ADDY|| 24-bit address of the destination block (relative to start of video RAM) |
+ | |||
|- | |- | ||
− | | $AF: | + | | $AF:0408 || $AF:040A || VDMA_SIZE || For 1-D DMA, 24-bit size of transfer in bytes. |
+ | |||
|- | |- | ||
− | | $AF: | + | | $AF:0408 || $AF:0409 || VDMA_X_SIZE || For 2-D, 16-bit width of block |
|- | |- | ||
− | | $AF: | + | | $AF:040A || $AF:040B || VDMA_Y_SIZE || For 2-D transfer, 16-bit height of block |
+ | |||
|- | |- | ||
− | | $AF: | + | | $AF:040C || $AF:040D || VDMA_SRC_STRIDE || Number of bytes per row in a 2-D source block (16-bits) |
+ | |||
|- | |- | ||
− | + | | $AF:040E || $AF:040F || VDMA_DST_STRIDE || Number of bytes per row in a 2-D destination block (16-bits) | |
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | | $AF:040E || $AF: | ||
− | |||
− | |||
|} | |} | ||
Line 93: | Line 121: | ||
== VDMA Size == | == VDMA Size == | ||
− | The size of the block to transfer is specified in one of two ways. For a 1-D or linear transfer (bit VDMA_CTRL_1D_2D in the control register is clear), the size is specified as a 24-bit integer using | + | The size of the block to transfer is specified in one of two ways. For a 1-D or linear transfer (bit VDMA_CTRL_1D_2D in the control register is clear), the size is specified as a 24-bit integer using VDMA_SIZE. |
If the transfer is a 2-D or block transfer (bit VDMA_CTRL_1D_2D in the control register is set), the size is specified as a 16-bit width stored | If the transfer is a 2-D or block transfer (bit VDMA_CTRL_1D_2D in the control register is set), the size is specified as a 16-bit width stored | ||
− | in | + | in VDMA_X_SIZE, and a 16-bit height stored in VDMA_Y_SIZE. |
== Stride == | == Stride == | ||
Line 102: | Line 130: | ||
The block being transferred may be narrower than the total image. The stride along with the width of the block tells Vicky how many bytes to | The block being transferred may be narrower than the total image. The stride along with the width of the block tells Vicky how many bytes to | ||
skip between rows. Source and destination images can have different widths and therefore different strides. The stride of the source is specified by the two-byte register VDMA_SRC_STRIDE, and the stride of the destination by VDMA_DST_STRIDE. | skip between rows. Source and destination images can have different widths and therefore different strides. The stride of the source is specified by the two-byte register VDMA_SRC_STRIDE, and the stride of the destination by VDMA_DST_STRIDE. | ||
+ | |||
+ | The relationship between stride, width, and height of a block can be seen in the diagram below: | ||
+ | |||
+ | [[File:Vicky_Stride.png]] |
Latest revision as of 16:36, 18 January 2021
Contents
Overview
The Video DMA block is a portion of the Vicky II chip which is responsible for high speed memory transfers to or from video memory. The block supports several types of memory operations:
- Copying a contiguous block of data from one section of memory to another (1D or linear transfers)
- Copying a rectangular subset of a larger image from one section of memory to another (2D or block transfers)
- Filling a contiguous block of addresses in video memory with a single byte (1D fill)
- Filling a rectangular subset of a larger image with a single byte (2D fill)
VDMA can copy data between different locations within video RAM, or can be used in conjunction with the System DMA Block to transfer data between video RAM and system RAM.
IMPORTANT! VDMA operates in the background and does not halt the CPU, but it will prevent the CPU from accessing video RAM while a VDMA is in process. It is therefore critically important for any calling program to avoid accessing VRAM while VDMA is in progress. To repeat: do not try to access video RAM while there is a VDMA in operation.
Setting up a VDMA
The process of starting a VDMA is as follows:
- Ensure that there is no VDMA already in operation by checking to make sure that the VDMA_STAT_VDMA_IPS bit of VDMA_STATUS_REG is
clear. This is somewhat optional. If you are certain no VDMA is in flight, you can skip this step.
- Set the VDMA_CONTROL_REG bits to enable the VDMA block, set 1D or 2D operation, set transfer or fill, and indicate if the source or
destination is system RAM. If your code will use interrupts, you may enable VDMA interrupts with the VDMA_CTRL_Int_Enable bit. Do not set VDMA_CTRL_Start_TRF at this point.
- If the source of the data is in video RAM, set VDMA_SRC_ADDY. The address stored here is the offset within video RAM (so relative to $B0:0000).
- If the destination of the data is in video RAM, set VDMA_DST_ADDY. The address stored here is the offset within video RAM (so relative to $B0:0000).
- If the transfer is a 1D operation, set the size (number of bytes) in VDMA_SIZE. If the transfer is a 2D operation, set the width in VDMA_X_SIZE, and the height in VDMA_Y_SIZE.
- If the transfer is a 2D operation, set the source and destination stride values.
- Set the VDMA_CTRL_Start_TRF bit of VDMA_CONTROL_REG to begin the actual transfer.
- Either wait for interrupt or poll the VDMA_STAT_VDMA_IPS of VDMA_STATUS_REG until the VDMA is done.
- Clear the VDMA_CTRL_Start_TRF bit of VDMA_CONTROL_REG.
NOTE: If you are transferring data between system RAM and video RAM, you will have to set up both an SDMA and a VDMA operation, which has special considerations. Please see System and Video RAM DMA for details.
Video DMA Registers
Start Address | Stop Address | Register Name | Additional Info | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
$AF:0400 | $AF:0400 | VDMA_CONTROL_REG | VDMA control register
| ||||||||||||||||||||||||
$AF:0401 | $AF:0401 | VDMA_STATUS_REG / VDMA_BYTE_2_WRITE | On write, accepts the byte to use in the fill function.
On read, this register shows the status of the VDMA:
| ||||||||||||||||||||||||
$AF:0402 | $AF:0404 | VDMA_SRC_ADDY | 24-bit address of the source block (relative to start of video RAM) | ||||||||||||||||||||||||
$AF:0405 | $AF:0407 | VDMA_DST_ADDY | 24-bit address of the destination block (relative to start of video RAM) | ||||||||||||||||||||||||
$AF:0408 | $AF:040A | VDMA_SIZE | For 1-D DMA, 24-bit size of transfer in bytes. | ||||||||||||||||||||||||
$AF:0408 | $AF:0409 | VDMA_X_SIZE | For 2-D, 16-bit width of block | ||||||||||||||||||||||||
$AF:040A | $AF:040B | VDMA_Y_SIZE | For 2-D transfer, 16-bit height of block | ||||||||||||||||||||||||
$AF:040C | $AF:040D | VDMA_SRC_STRIDE | Number of bytes per row in a 2-D source block (16-bits) | ||||||||||||||||||||||||
$AF:040E | $AF:040F | VDMA_DST_STRIDE | Number of bytes per row in a 2-D destination block (16-bits)
|
VDMA_SRC_ADDY
This 3-byte register is set to the 24-bit address of the first byte of the source block to transfer. It must be an address within video RAM and the address is relative to the start of video RAM ($00:0000 - $3F:FFFF). This address is only used if video RAM is the source of the block. If the VDMA is a fill operation, or the source of the block is in system RAM, this register are not used.
VDMA_DST_ADDY
This 3-byte register is set to the 24-bit address of the first byte destination block. It must be an address within video RAM and the address is relative to the start of video RAM ($00:0000 - $3F:FFFF). This address is only used if video RAM is the destination of the VDMA. If the destination of the transfer is system RAM, this register is not used.
VDMA Size
The size of the block to transfer is specified in one of two ways. For a 1-D or linear transfer (bit VDMA_CTRL_1D_2D in the control register is clear), the size is specified as a 24-bit integer using VDMA_SIZE. If the transfer is a 2-D or block transfer (bit VDMA_CTRL_1D_2D in the control register is set), the size is specified as a 16-bit width stored in VDMA_X_SIZE, and a 16-bit height stored in VDMA_Y_SIZE.
Stride
For a 2-D transfer, there is the notion of a "stride," which is the total number of bytes in a row of a source or destination image. The block being transferred may be narrower than the total image. The stride along with the width of the block tells Vicky how many bytes to skip between rows. Source and destination images can have different widths and therefore different strides. The stride of the source is specified by the two-byte register VDMA_SRC_STRIDE, and the stride of the destination by VDMA_DST_STRIDE.
The relationship between stride, width, and height of a block can be seen in the diagram below: