Difference between revisions of "Video DMA Block"

From C256 Foenix Wiki
Jump to navigation Jump to search
(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 Description
+
! Register Name
 
! Additional Info
 
! Additional Info
 
|-
 
|-
Line 47: Line 84:
  
 
|-
 
|-
| $AF:0402 || $AF:0402 || VDMA_SRC_ADDY_L || 24-bit address of the source block (relative to start of video RAM)
+
| $AF:0402 || $AF:0404 || VDMA_SRC_ADDY || 24-bit address of the source block (relative to start of video RAM)
 
|-
 
|-
| $AF:0403 || $AF:0403 || VDMA_SRC_ADDY_M
+
| $AF:0405 || $AF:0407 || VDMA_DST_ADDY|| 24-bit address of the destination block (relative to start of video RAM)
 +
 
 
|-
 
|-
| $AF:0404 || $AF:0404 || VDMA_SRC_ADDY_H
+
| $AF:0408 || $AF:040A || VDMA_SIZE || For 1-D DMA, 24-bit size of transfer in bytes.
 +
 
 
|-
 
|-
| $AF:0405 || $AF:0405 || VDMA_DST_ADDY_L || 24-bit address of the source block (relative to start of video RAM)
+
| $AF:0408 || $AF:0409 || VDMA_X_SIZE || For 2-D, 16-bit width of block
 
|-
 
|-
| $AF:0406 || $AF:0406 || VDMA_DST_ADDY_M
+
| $AF:040A || $AF:040B || VDMA_Y_SIZE || For 2-D transfer, 16-bit height of block
 +
 
 
|-
 
|-
| $AF:0407 || $AF:0407 || VDMA_DST_ADDY_H
+
| $AF:040C || $AF:040D || VDMA_SRC_STRIDE || Number of bytes per row in a 2-D source block (16-bits)
 +
 
 
|-
 
|-
| $AF:0408 || $AF:0408 || VDMA_SIZE_L / VDMA_X_SIZE_L || For 1-D DMA, 24-bit size of transfer in bytes. For 2-D, 16-bit width of block
+
| $AF:040E || $AF:040F || VDMA_DST_STRIDE || Number of bytes per row in a 2-D destination block (16-bits)
|-
+
 
| $AF:0409 || $AF:0409 || VDMA_SIZE_M / VDMA_X_SIZE_H
 
|-
 
| $AF:040A || $AF:040A || VDMA_SIZE_H / VDMA_Y_SIZE_L || For 2-D transfer, 16-bit height of block
 
|-
 
| $AF:040B || $AF:040B || VDMA_RESERVED_0 / VDMA_Y_SIZE_H
 
|-
 
| $AF:040C || $AF:040C || VDMA_SRC_STRIDE_L || Number of bytes per row in a 2-D source block
 
|-
 
| $AF:040D || $AF:040D || VDMA_SRC_STRIDE_H
 
|-
 
| $AF:040E || $AF:040E || VDMA_DST_STRIDE_L || Number of bytes per row in a 2-D destination block
 
|-
 
| $AF:040F || $AF:040F || VDMA_DST_STRIDE_H
 
  
 
|}
 
|}
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 VDMA_SIZE_L, VDMA_SIZE_M, and VDMA_SIZE_H.
+
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 VDMA_X_SIZE_L and VDMA_X_SIZE_H, and a 16-bit height stored in VDMA_Y_SIZE_L and VDMA_Y_SIZE_L.
+
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

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:

  1. 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.

  1. 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.

  1. 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).
  2. 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).
  3. 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.
  4. If the transfer is a 2D operation, set the source and destination stride values.
  5. Set the VDMA_CTRL_Start_TRF bit of VDMA_CONTROL_REG to begin the actual transfer.
  6. Either wait for interrupt or poll the VDMA_STAT_VDMA_IPS of VDMA_STATUS_REG until the VDMA is done.
  7. 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
Bit Name Purpose
$01 VDMA_CTRL_Enable Enabled the VDMA transfer block
$02 VDMA_CTRL_1D_2D 0 - 1D (Linear) Transfer, 1 - 2D (Block) Transfer
$04 VDMA_CTRL_TRF_Fill 0 - Transfer Src -> Dst, 1 - Fill Destination with "Byte2Write"
$08 VDMA_CTRL_Int_Enable Set to 1 to Enable the Generation of Interrupt when the Transfer is over.
$10 VDMA_CTRL_SysRAM_Src Set to 1 to Indicate that the Source is the System Ram Memory
$20 VDMA_CTRL_SysRAM_Dst Set to 1 to Indicate that the Destination is the System Ram Memory
$80 VDMA_CTRL_Start_TRF Set to 1 To Begin Process, Need to Cleared before, you can start another
$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:

Bit Name Purpose
$01 VDMA_STAT_Size_Err If Set to 1, Overall Size is Invalid
$02 VDMA_STAT_Dst_Add_Err If Set to 1, Destination Address Invalid
$04 VDMA_STAT_Src_Add_Err If Set to 1, Source Address Invalid
$80 VDMA_STAT_VDMA_IPS If Set to 1, VDMA Transfer in Progress. Do not attempt to access VRAM while a VDMA is in progress!
$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:

Vicky Stride.png