System and Video RAM DMA

From C256 Foenix Wiki
Revision as of 14:12, 19 January 2021 by PJW (talk | contribs) (Proper Sequencing)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

NOTE: this section to be fleshed out later.

When using DMA to transfer data between system and video RAM, both the System DMA Block and the Video DMA Block have to be configured and used together. For example, if a program needs to copy data from system RAM into video RAM (e.g. bitmap data) it needs to configure the system DMA block to grab the needed block of system RAM as the source, and it needs to configure the video DMA block to store that block in the correct area of video RAM. The two DMA blocks will cooperate to do the actual transfer.

Proper Sequencing

There are a couple of details to keep in mind with sequencing these sorts of DMA transfers.

First, although VDMA will not stop the processor, SDMA will. You therefore cannot trigger the VDMA after the SDMA has been triggered, because you will not be able to trigger the VDMA before the SDMA block stops the CPU.

Second, when transferring from system RAM to video RAM, the VDMA is not necessarily finished when the SDMA is done. Writes can still be pending. This is important to keep in mind because you cannot access video RAM while a VDMA is going on, and you cannot start another VDMA operation while another is still going. So it is recommended that you make sure your VDMA is finished before continuing with your program.

The recommended sequence of actions in setting up system and video DMA operations is:

  1. Enable and configure the VDMA but do not trigger it.
  2. Enable and configure the SDMA but do not trigger it.
  3. Trigger the VDMA.
  4. Trigger the SDMA.
  5. Execute several NOP instructions to wait for the SDMA controller to halt the CPU.
  6. Turn off the SDMA controller
  7. Wait for the VDMA controller to finish.
  8. Turn off the VDMA controller

The following example illustrates the correct triggering, wait, and shutdown sequence:

; Begin Transfer
        ; Start the VDMA Controller First
        LDA VDMA_CONTROL_REG
        ORA #VDMA_CTRL_Start_TRF
        STA @l VDMA_CONTROL_REG

        ; Then, Start the SDMA Controller

        LDA SDMA_CTRL_REG0
        ORA #SDMA_CTRL0_Start_TRF
        STA @l SDMA_CTRL_REG0
        NOP ; When the transfer is started the CPU will be put on Hold (RDYn)...
        NOP ; Before it actually gets to stop it will execute a couple more instructions
        NOP ; From that point on, the CPU is halted (keep that in mind) No IRQ will be processed either during that time
        NOP
        NOP
        NOP
        NOP
        NOP

        LDA #$00
        STA @l SDMA_CTRL_REG0

NOTFINISHED:
        LDA @l VDMA_STATUS_REG
        AND #$80
        CMP #$80
        BEQ NOTFINISHED
        LDA #$00
        STA @l VDMA_CONTROL_REG