Tutorial.12 DMA †DMA(Direct Memory Access)はCPUを介さず、 GBAのDMAでは0〜3の4つのチャンネルがあり、それぞれ特徴が異なります。
I/Oアドレス †アドレス、設定について見ていきましょう。 #define REG_DMA0SAD *(vu32*)(REG_BASE + 0x0b0) #define REG_DMA0DAD *(vu32*)(REG_BASE + 0x0b4) #define REG_DMA0CNT *(vu32*)(REG_BASE + 0x0b8) #define REG_DMA1SAD *(vu32*)(REG_BASE + 0x0bc) #define REG_DMA1DAD *(vu32*)(REG_BASE + 0x0c0) #define REG_DMA1CNT *(vu32*)(REG_BASE + 0x0c4) #define REG_DMA2SAD *(vu32*)(REG_BASE + 0x0c8) #define REG_DMA2DAD *(vu32*)(REG_BASE + 0x0cc) #define REG_DMA2CNT *(vu32*)(REG_BASE + 0x0d0) #define REG_DMA3SAD *(vu32*)(REG_BASE + 0x0d4) #define REG_DMA3DAD *(vu32*)(REG_BASE + 0x0d8) #define REG_DMA3CNT *(vu32*)(REG_BASE + 0x0dc)
REG_DMxSAD、REG_DMxDAD †アライメントの関係で転送元、転送先のアドレスの最後の桁に注意してください。
でないと失敗します。 #define ALIGN(m) __attribute__((aligned (m))) u16 dataBuf[64] ALIGN(4); u16 buf[SCREEN_CX][SCREEN_CY] ALIGN(4); DMA転送に関わるすべての変数については、ALIGNマクロをつけておく事をおすすめします。 REG_DMxCNT_L †転送したいバイト数を登録します。 ただし転送サイズが32ビットの場合は4で、 REG_DMxCNT_H †#define DMA_DST_INC (0<<21) #define DMA_DST_DEC (1<<21) #define DMA_DST_FIXED (2<<21) // 固定 #define DMA_DST_RELOAD (3<<21) #define DMA_SRC_INC (0<<23) #define DMA_SRC_DEC (1<<23) #define DMA_SRC_FIXED (2<<23) // 固定 転送アドレスをどう変化させるかの設定です。 #define DMA_REPEAT (1<<25) 一度のDMA転送が終了したあとに次回のDMA転送を繰り返し行うか行わないかの設定です。 #define DMA_IRQ (1<<30) DMAの転送終了時に割り込みを発生させるかの設定です。 #define DMA_ENABLE (1<<31) DMAが有効になります。 #define DMA_IMMEDIATE (0<<28) #define DMA_VBLANK (1<<28) #define DMA_HBLANK (2<<28) #define DMA_SPECIAL (3<<28) DMA_ENABLE設定後の、転送開始のタイミングです。 Mode3で画像をDMA転送例 †#include "lib/gba.h" #include "res.h" //--------------------------------------------------------------------------- void WaitForVsync(void) { while(*(vu16*)0x4000006 >= 160) {}; while(*(vu16*)0x4000006 < 160) {}; } //--------------------------------------------------------------------------- int main(void) { // モード設定 SetMode(MODE_3 | BG2_ENABLE); // 画像の読み込み REG_DMA3SAD = (u32)&imageBitmap; REG_DMA3DAD = (u32)VRAM; REG_DMA3CNT = (u32)(240*160) | (DMA_SRC_INC | DMA_DST_INC | DMA16 | DMA_ENABLE); for(;;) { WaitForVsync(); } } 動作画面 †![]() 履歴 †
|