OpenSNES
Modern Open-Source SNES Development SDK
Loading...
Searching...
No Matches
dma.h File Reference

SNES DMA (Direct Memory Access). More...

#include <snes/types.h>

Go to the source code of this file.

Functions

void dmaClearVRAM (void)
 Clear all VRAM to zero.
void dmaCopyCGram (const u8 *source, u16 startColor, u16 size)
 Copy palette data to CGRAM (PVSnesLib compatible).
void dmaCopyCGramBank (const u8 *source, u8 bank, u16 startColor, u16 size)
 Copy palette data to CGRAM with explicit source bank byte.
void dmaCopyOam (const u8 *source, u16 size)
 Copy OAM data (PVSnesLib compatible).
void dmaCopyVram (const u8 *source, u16 vramAddr, u16 size)
 Copy data to VRAM (PVSnesLib compatible).
void dmaCopyVramBank (const u8 *source, u8 bank, u16 vramAddr, u16 size)
 Copy data to VRAM with explicit source bank byte.
void dmaCopyVramMode7 (const u8 *tilemap, u16 tilemapSize, const u8 *tiles, u16 tilesSize)
 Load Mode 7 interleaved data to VRAM.
void dmaFillVRAM (u16 value, u16 dest, u16 size)
 Set VRAM to a value.
void dmaTransfer (u8 channel, u8 mode, u8 srcBank, u16 srcAddr, u8 destReg, u16 size)
 Perform generic DMA transfer.

Detailed Description

SNES DMA (Direct Memory Access).

Functions for fast memory transfers using DMA.

DMA Overview

DMA allows fast transfers between:

  • Work RAM ↔ VRAM (video RAM)
  • Work RAM ↔ CGRAM (palette RAM)
  • Work RAM ↔ OAM (sprite RAM)

DMA is much faster than CPU copying and should be used for all bulk transfers during VBlank.

VBlank Timing Requirement

Warning
CRITICAL: VRAM, CGRAM, and OAM can only be safely accessed during VBlank (vertical blanking period) or when the screen is in force blank mode (INIDISP bit 7 set). Accessing these memories during active display causes visual corruption and undefined behavior.
VBlank Budget: You have approximately 2,200 CPU cycles during VBlank for DMA transfers. This translates to roughly 4KB of data that can be safely transferred per frame. While the theoretical maximum is higher, 4KB is a safe practical limit that accounts for NMI handler overhead.

Banks

Note
Every dmaCopy* function takes a far pointer and uses its bank byte, so the source may live in any bank — a SUPERFREE section, a bank you pinned yourself, anywhere. This has been true since the A6 chantier made pointer arguments 4 bytes; the *Bank variants remain for the case where an address and its bank are held separately.

This header claimed the opposite ("source data must be in bank $00") long after it stopped being true, and that prose is why the RPG template shipped a pointless semifree bank 0 section for its palettes — and why issue #122 carried a bank-$00 claim about dmaCopyCGram that testing then had to retract.

Author
OpenSNES Team

Function Documentation

◆ dmaClearVRAM()

void dmaClearVRAM ( void )

Clear all VRAM to zero.

Clears all 64KB of VRAM. Should be called during force blank.

◆ dmaCopyCGram()

void dmaCopyCGram ( const u8 * source,
u16 startColor,
u16 size )

Copy palette data to CGRAM (PVSnesLib compatible).

Copies palette data from ROM or RAM to CGRAM using DMA.

Parameters
sourceSource address (can be ROM or RAM)
startColorStarting color index (0-255)
sizeNumber of bytes to copy (2 bytes per color)
extern char palette[];
dmaCopyCGram(palette, 0, 32); // 16 colors * 2 bytes
u8 palette[]
void WaitForVBlank(void)
Wait for next VBlank period.
void dmaCopyCGram(const u8 *source, u16 startColor, u16 size)
Copy palette data to CGRAM (PVSnesLib compatible).
Warning
Must be called during VBlank or forced blank — setScreenOff(), INIDISP bit 7. setBrightness(0) blacks the screen but leaves the PPU fetching and the write is rejected.
Note
The bank comes from source's own bank byte: a palette may live in any bank. dmaCopyCGramBank() exists for the case where the address and the bank are held separately.

◆ dmaCopyCGramBank()

void dmaCopyCGramBank ( const u8 * source,
u8 bank,
u16 startColor,
u16 size )

Copy palette data to CGRAM with explicit source bank byte.

Same as dmaCopyCGram() but allows specifying the ROM bank for data in banks other than $00 (e.g., SUPERFREE sections placed by linker).

Parameters
sourceSource address (16-bit offset within bank)
bankSource bank byte ($00-$3F for LoROM, $00-$7D for HiROM)
startColorStarting color index (0-255)
sizeNumber of bytes to transfer (2 bytes per color)
Warning
Must be called during VBlank or force blank!

◆ dmaCopyOam()

void dmaCopyOam ( const u8 * source,
u16 size )

Copy OAM data (PVSnesLib compatible).

Parameters
sourceSource address (544 bytes)
sizeNumber of bytes to copy (usually 544)
dmaCopyOam(oamBuffer, 544);
void dmaCopyOam(const u8 *source, u16 size)
Copy OAM data (PVSnesLib compatible).

◆ dmaCopyVram()

void dmaCopyVram ( const u8 * source,
u16 vramAddr,
u16 size )

Copy data to VRAM (PVSnesLib compatible).

Copies data from ROM or RAM to VRAM using DMA. This function handles 24-bit source addresses, so it works with ROM data defined via extern.

Parameters
sourceSource address (can be ROM or RAM)
vramAddrDestination word address in VRAM
sizeNumber of bytes to copy
extern char tileset[];
extern char tileset_end[];
void dmaCopyVram(const u8 *source, u16 vramAddr, u16 size)
Copy data to VRAM (PVSnesLib compatible).
u8 tileset
BG1 tileset tile data (4bpp) – start label.
u8 tileset_end[]
Definition main.c:44
Warning
Must be called during VBlank or forced blank. During active display the PPU rejects VRAM writes and the transfer is silently lost.

Forced blank means setScreenOff() — INIDISP bit 7. setBrightness(0) blacks the screen but leaves the PPU fetching, so it does NOT open the write window.

Warning
VBlank fits roughly 4 KB. A larger transfer has its tail dropped during active display, and the failure is partial: the first few KB land, so the screen is half right. Anything bigger than a few KB belongs between setScreenOff() and setScreenOn(), not in VBlank.
Note
The bank is taken from source's own bank byte, so the data may live in ANY bank — a SUPERFREE section, a bank you pinned yourself. dmaCopyVramBank() exists for the case where the address and the bank are held separately.

◆ dmaCopyVramBank()

void dmaCopyVramBank ( const u8 * source,
u8 bank,
u16 vramAddr,
u16 size )

Copy data to VRAM with explicit source bank byte.

Same as dmaCopyVram() but allows specifying the ROM bank for data in banks other than $00 (e.g., SUPERFREE sections placed by linker).

Parameters
sourceSource address (16-bit offset within bank)
bankSource bank byte ($00-$3F for LoROM, $00-$7D for HiROM)
vramAddrVRAM destination word address
sizeNumber of bytes to transfer
Warning
Must be called during VBlank or force blank!

◆ dmaCopyVramMode7()

void dmaCopyVramMode7 ( const u8 * tilemap,
u16 tilemapSize,
const u8 * tiles,
u16 tilesSize )

Load Mode 7 interleaved data to VRAM.

Mode 7 stores tilemap in VRAM low bytes and tile pixels in VRAM high bytes. This function performs two DMA transfers with appropriate VMAIN settings:

  1. Tilemap -> VMDATAL (VMAIN=$00, increment after low byte)
  2. Tiles -> VMDATAH (VMAIN=$80, increment after high byte)

VRAM destination is always $0000 (Mode 7 uses the full 32K word space).

Parameters
tilemapTilemap data source (.mp7 file, 128x128 = 16384 bytes)
tilemapSizeTilemap data size in bytes
tilesTile pixel data source (.pc7 file, 256 tiles x 64 bytes)
tilesSizeTile pixel data size in bytes
Warning
Must be called during forced blank (INIDISP=$80) or VBlank.

◆ dmaFillVRAM()

void dmaFillVRAM ( u16 value,
u16 dest,
u16 size )

Set VRAM to a value.

Parameters
valueValue to fill (repeated as word)
destDestination word address in VRAM
sizeNumber of bytes to fill — 0 means 65536 (the full VRAM), which is how dmaClearVRAM() uses it
Note
Uses DMA channel 0 with a fixed source address, like the other lib DMA helpers (oamUpdate, dmaCopyVram). Safe when calls are sequential from the main loop; do NOT call from an NMI callback while a main-thread DMA setup on channel 0 may be in flight.
Warning
Must be called during forced blank (INIDISP=$80) or VBlank — the PPU silently ignores VRAM writes during active display.

◆ dmaTransfer()

void dmaTransfer ( u8 channel,
u8 mode,
u8 srcBank,
u16 srcAddr,
u8 destReg,
u16 size )

Perform generic DMA transfer.

Parameters
channelDMA channel (0-7)
modeDMA mode byte
srcBankSource bank
srcAddrSource address
destRegDestination B-bus register
sizeTransfer size