From af05a2979f97d00eab36261374af1eaf2ac3c833 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 27 Apr 2021 12:36:28 +0200 Subject: Add DMA control macros and small memory copy test --- src/common.h | 69 ++++++++++++++++++++++++++++++++++++++++++ src/main.c | 96 +++++++++++++++++------------------------------------------ src/sprites.h | 1 - src/text.h | 9 +++--- 4 files changed, 101 insertions(+), 74 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) { } // Unpack N tiles packed at 1bpp. +static inline void unpack_tiles(u32 *src, u32 *dst, size_t n_tiles) { u32 *target_src = src + n_tiles * 2; while (src != target_src) { @@ -316,4 +317,72 @@ unpack_tiles(u32 *src, u32 *dst, size_t n_tiles) { } } +// +// Direct Memory Access (DMA) +// + + +// Source, destination, and control registers. +#define DMA_SRC(N) *((vu32*) 0x040000B0 + (N) * 12) +#define DMA_DST(N) *((vu32*) 0x040000B4 + (N) * 12) +#define DMA_CTRL(N) *((vu32*) 0x040000B8 + (N) * 12) + +// DMA control bits. +#define DMA_DST_INC (0 << 0x15) +#define DMA_DST_DEC (1 << 0x15) +#define DMA_DST_FIXED (2 << 0x15) +#define DMA_DST_RELOAD (3 << 0x15) +#define DMA_SRC_INC (0 << 0x17) +#define DMA_SRC_DEC (1 << 0x17) +#define DMA_SRC_FIXED (2 << 0x17) +#define DMA_REPEAT (1 << 0x19) +#define DMA_CHUNK_16 (0 << 0x1A) +#define DMA_CHUNK_32 (1 << 0x1A) +#define DMA_NOW (0 << 0x1C) +#define DMA_VBLANK (1 << 0x1C) +#define DMA_HBLANK (2 << 0x1C) +#define DMA_REFRESH (3 << 0x1C) +#define DMA_IRQ (1 << 0x1E) +#define DMA_ENABLE (1 << 0x1F) + +// Custom struct for cleaner DMA transfer functions. +typedef struct DmaStr { + const void *src; + void *dst; + u32 ctrl; +} DmaStr; + +#define DMA_TRANSFER ((volatile DmaStr*) 0x040000B0) + +// Transfer `count` number of chunks from src to dst using a DMA channel. Note +// that chunks are not bytes, but instead configured based on bits set by +// DMA_CTRL. +inline void +dma_transfer_copy(void *dst, const void *src, u32 count, int channel, u32 options) { + DMA_TRANSFER[channel].ctrl = 0; + DMA_TRANSFER[channel].src = src; + DMA_TRANSFER[channel].dst = dst; + DMA_TRANSFER[channel].ctrl = count | options; +} + +inline void +dma_transfer_fill(void *dst, volatile u32 src, u32 count, int channel, u32 options) { + DMA_TRANSFER[channel].ctrl = 0; + DMA_TRANSFER[channel].src = (const void *)&src; + DMA_TRANSFER[channel].dst = dst; + DMA_TRANSFER[channel].ctrl = count | options | DMA_SRC_FIXED; +} + +// Copy N number of bytes using a DMA channel. +inline void +dma_copy(void *dst, const void *src, u32 size, int channel) { + dma_transfer_copy(dst, src, size / 4, channel, DMA_CHUNK_32 | DMA_ENABLE); +} + +// Fill the dst location with the word set at src. +inline void +dma_fill(void *dst, const void *src, u32 size, int channel) { + dma_transfer_fill(dst, src, size / 4, channel, DMA_CHUNK_32 | DMA_ENABLE); +} + #endif // GBAEXP_COMMON_H diff --git a/src/main.c b/src/main.c index 3bd5865..efd460f 100644 --- a/src/main.c +++ b/src/main.c @@ -22,83 +22,43 @@ int main(void) { init_sprite_pal(0, COLOR_WHITE); init_sprites(0); init_button_sprites(); + Color colors[16] = { + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + COLOR_BLUE, + }; + // These should be equivalent here, but remember that the dma_copy and + // dma_fill functions will always work on U32 chunks. + // + // memcpy(&PAL_BUFFER_SPRITES[0], colors, 16 * sizeof(Color)); + // dma_copy(&PAL_BUFFER_SPRITES[0], colors, 16 * sizeof(Color), 3); + + u32 color = COLOR_RED | COLOR_RED << 16; + dma_fill(&PAL_BUFFER_SPRITES[0], color, 16 * sizeof(Color), 3); // Initialize text engine. - txt_init(0, COLOR_RED, 0); - txt_position(0, 6); - txt_printf("Strings: %s\n", "Hello World"); - txt_printf("Signed ints: %d\n", -100000); - txt_printf("Unsigned ints: %u\n", 1234567); - txt_printf("Hex values: 0x%x\n", 1024); + // txt_init(0, COLOR_RED, 0); + // txt_printf("TEST"); int frame_counter = 0; - int x = 0; - int y = 0; while(true) { wait_vsync(); poll_keys(); - txt_position(0, 0); - txt_printf("Frame counter: %d\n", frame_counter); - - if (key_hold(KEY_DOWN)) { - y += 3; - } - if (key_hold(KEY_UP)) { - y -= 3; - } - if (key_hold(KEY_LEFT)) { - x -= 3; - } - if (key_hold(KEY_RIGHT)) { - x += 3; - } - - if (key_pressed(KEY_A)) { - txt_clear_line(); - txt_printf("Pressed key: A"); - } - if (key_pressed(KEY_B)) { - txt_clear_line(); - txt_printf("Pressed key: B"); - } - if (key_pressed(KEY_L)) { - txt_clear_line(); - txt_printf("Pressed key: L"); - } - if (key_pressed(KEY_R)) { - txt_clear_line(); - txt_printf("Pressed key: R"); - } - if (key_pressed(KEY_START)) { - txt_clear_line(); - txt_printf("Pressed key: Start"); - } - if (key_pressed(KEY_SELECT)) { - txt_clear_line(); - txt_printf("Pressed key: Select"); - } - if (key_pressed(KEY_UP)) { - txt_clear_line(); - txt_printf("Pressed key: Up"); - } - if (key_pressed(KEY_DOWN)) { - txt_clear_line(); - txt_printf("Pressed key: Down"); - } - if (key_pressed(KEY_LEFT)) { - txt_clear_line(); - txt_printf("Pressed key: Left"); - } - if (key_pressed(KEY_RIGHT)) { - txt_clear_line(); - txt_printf("Pressed key: Right"); - } - frame_counter++; - // BG_H_SCROLL_0 = x; - // BG_V_SCROLL_0 = y; - update_button_sprites(); }; diff --git a/src/sprites.h b/src/sprites.h index 88ca787..0b55f0d 100644 --- a/src/sprites.h +++ b/src/sprites.h @@ -73,7 +73,6 @@ init_sprite_pal(size_t starting_index, Color col) { for (size_t i = 0; i < 16; ++i) { PAL_BUFFER_SPRITES[i + starting_index] = col; } - } #endif // GBAEXP_SPRITES_H diff --git a/src/text.h b/src/text.h index e38c220..c852fc2 100644 --- a/src/text.h +++ b/src/text.h @@ -2,6 +2,7 @@ #define GBAEXP_TILES_H #include +#include #include "common.h" #include "bd-font.c" @@ -75,11 +76,9 @@ txt_printf(char *msg, ...) { va_list arg_list; va_start(arg_list, msg); char c; - char prev_c; while ((c = *msg++) != '\0') { if (c != '%') { txt_putc(c); - prev_c = c; continue; } c = *msg++; @@ -88,19 +87,19 @@ txt_printf(char *msg, ...) { txt_puts(va_arg(arg_list, char *)); } break; case 'd': { - char buf[32] = {0}; + char buf[12] = {0}; int x = va_arg(arg_list, int); sprintf(buf, "%d", x); txt_puts(buf); } break; case 'u': { - char buf[32] = {0}; + char buf[12] = {0}; unsigned int x = va_arg(arg_list, unsigned int); sprintf(buf, "%u", x); txt_puts(buf); } break; case 'x': { - char buf[32] = {0}; + char buf[12] = {0}; unsigned int x = va_arg(arg_list, unsigned int); sprintf(buf, "%x", x); txt_puts(buf); -- cgit v1.2.1