diff options
Diffstat (limited to 'src/common.h')
-rw-r--r-- | src/common.h | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/common.h b/src/common.h index 669fb6e..e3405be 100644 --- a/src/common.h +++ b/src/common.h | |||
@@ -305,6 +305,7 @@ unpack_1bb(u8 hex) { | |||
305 | } | 305 | } |
306 | 306 | ||
307 | // Unpack N tiles packed at 1bpp. | 307 | // Unpack N tiles packed at 1bpp. |
308 | static inline void | ||
308 | unpack_tiles(u32 *src, u32 *dst, size_t n_tiles) { | 309 | unpack_tiles(u32 *src, u32 *dst, size_t n_tiles) { |
309 | u32 *target_src = src + n_tiles * 2; | 310 | u32 *target_src = src + n_tiles * 2; |
310 | while (src != target_src) { | 311 | while (src != target_src) { |
@@ -316,4 +317,72 @@ unpack_tiles(u32 *src, u32 *dst, size_t n_tiles) { | |||
316 | } | 317 | } |
317 | } | 318 | } |
318 | 319 | ||
320 | // | ||
321 | // Direct Memory Access (DMA) | ||
322 | // | ||
323 | |||
324 | |||
325 | // Source, destination, and control registers. | ||
326 | #define DMA_SRC(N) *((vu32*) 0x040000B0 + (N) * 12) | ||
327 | #define DMA_DST(N) *((vu32*) 0x040000B4 + (N) * 12) | ||
328 | #define DMA_CTRL(N) *((vu32*) 0x040000B8 + (N) * 12) | ||
329 | |||
330 | // DMA control bits. | ||
331 | #define DMA_DST_INC (0 << 0x15) | ||
332 | #define DMA_DST_DEC (1 << 0x15) | ||
333 | #define DMA_DST_FIXED (2 << 0x15) | ||
334 | #define DMA_DST_RELOAD (3 << 0x15) | ||
335 | #define DMA_SRC_INC (0 << 0x17) | ||
336 | #define DMA_SRC_DEC (1 << 0x17) | ||
337 | #define DMA_SRC_FIXED (2 << 0x17) | ||
338 | #define DMA_REPEAT (1 << 0x19) | ||
339 | #define DMA_CHUNK_16 (0 << 0x1A) | ||
340 | #define DMA_CHUNK_32 (1 << 0x1A) | ||
341 | #define DMA_NOW (0 << 0x1C) | ||
342 | #define DMA_VBLANK (1 << 0x1C) | ||
343 | #define DMA_HBLANK (2 << 0x1C) | ||
344 | #define DMA_REFRESH (3 << 0x1C) | ||
345 | #define DMA_IRQ (1 << 0x1E) | ||
346 | #define DMA_ENABLE (1 << 0x1F) | ||
347 | |||
348 | // Custom struct for cleaner DMA transfer functions. | ||
349 | typedef struct DmaStr { | ||
350 | const void *src; | ||
351 | void *dst; | ||
352 | u32 ctrl; | ||
353 | } DmaStr; | ||
354 | |||
355 | #define DMA_TRANSFER ((volatile DmaStr*) 0x040000B0) | ||
356 | |||
357 | // Transfer `count` number of chunks from src to dst using a DMA channel. Note | ||
358 | // that chunks are not bytes, but instead configured based on bits set by | ||
359 | // DMA_CTRL. | ||
360 | inline void | ||
361 | dma_transfer_copy(void *dst, const void *src, u32 count, int channel, u32 options) { | ||
362 | DMA_TRANSFER[channel].ctrl = 0; | ||
363 | DMA_TRANSFER[channel].src = src; | ||
364 | DMA_TRANSFER[channel].dst = dst; | ||
365 | DMA_TRANSFER[channel].ctrl = count | options; | ||
366 | } | ||
367 | |||
368 | inline void | ||
369 | dma_transfer_fill(void *dst, volatile u32 src, u32 count, int channel, u32 options) { | ||
370 | DMA_TRANSFER[channel].ctrl = 0; | ||
371 | DMA_TRANSFER[channel].src = (const void *)&src; | ||
372 | DMA_TRANSFER[channel].dst = dst; | ||
373 | DMA_TRANSFER[channel].ctrl = count | options | DMA_SRC_FIXED; | ||
374 | } | ||
375 | |||
376 | // Copy N number of bytes using a DMA channel. | ||
377 | inline void | ||
378 | dma_copy(void *dst, const void *src, u32 size, int channel) { | ||
379 | dma_transfer_copy(dst, src, size / 4, channel, DMA_CHUNK_32 | DMA_ENABLE); | ||
380 | } | ||
381 | |||
382 | // Fill the dst location with the word set at src. | ||
383 | inline void | ||
384 | dma_fill(void *dst, const void *src, u32 size, int channel) { | ||
385 | dma_transfer_fill(dst, src, size / 4, channel, DMA_CHUNK_32 | DMA_ENABLE); | ||
386 | } | ||
387 | |||
319 | #endif // GBAEXP_COMMON_H | 388 | #endif // GBAEXP_COMMON_H |