Skip to content
This repository has been archived by the owner on Oct 24, 2023. It is now read-only.

Commit

Permalink
libseven 0.12.0: simplify DMA module
Browse files Browse the repository at this point in the history
  • Loading branch information
LunarLambda committed Nov 20, 2022
1 parent 53ce22c commit 28a01a3
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 228 deletions.
2 changes: 1 addition & 1 deletion dist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ make_dist() {

[ ! -d "$DIST" ] && mkdir "$DIST"

(PROJECT=libseven VERSION=0.11.0 make_dist)
(PROJECT=libseven VERSION=0.12.0 make_dist)
(PROJECT=minrt VERSION=0.2.0 make_dist)
4 changes: 2 additions & 2 deletions libseven/include/seven/base/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#include <seven/base.h>

#define LIBSEVEN_VERSION_MAJOR 0
#define LIBSEVEN_VERSION_MINOR 10
#define LIBSEVEN_VERSION_PATCH 1
#define LIBSEVEN_VERSION_MINOR 12
#define LIBSEVEN_VERSION_PATCH 0

#define LIBSEVEN_VERSION \
_LIBSEVEN_STR2(LIBSEVEN_VERSION_MAJOR) "." \
Expand Down
84 changes: 46 additions & 38 deletions libseven/include/seven/hw/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@

_LIBSEVEN_EXTERN_C

// RAM ROM Transfer limit
// DMA 0 R/W - 16K
// DMA 1 R/W R 16K
// DMA 2 R/W R 16K
// DMA 3 R/W R/W 64K
// DMA RAM ROM Transfer limit
// 0 R/W - 16K
// 1 R/W R 16K
// 2 R/W R 16K
// 3 R/W R/W 64K

#define REG_DMA0SRC VOLADDR(0x040000B0, const void *)
#define REG_DMA0DST VOLADDR(0x040000B4, void *)
Expand All @@ -37,27 +37,30 @@ _LIBSEVEN_EXTERN_C
#define REG_DMA3LEN VOLADDR(0x040000DC, u16)
#define REG_DMA3CNT VOLADDR(0x040000DE, u16)

#define BF_DMA_DST_OFFSET 5
#define BF_DMA_DST_LENGTH 2

#define DMA_DST(n) BITFIELD(DMA_DST, (n))

#define BF_DMA_SRC_OFFSET 7
#define BF_DMA_SRC_LENGTH 2

#define DMA_SRC(n) BITFIELD(DMA_SRC, (n))

#define BF_DMA_START_OFFSET 12
#define BF_DMA_START_LENGTH 2

#define DMA_START(n) BITFIELD(DMA_START, (n))
struct DMA
{
const void *src;
void *dst;
u16 len;
u16 cnt;
};

enum DMAControl
{
#define BF_DMA_DST_OFFSET 5
#define BF_DMA_DST_LENGTH 2

#define DMA_DST(n) BITFIELD(DMA_DST, (n))

DMA_DST_INCREMENT = DMA_DST(0),
DMA_DST_DECREMENT = DMA_DST(1),
DMA_DST_FIXED = DMA_DST(2),
DNA_DST_RELOAD = DMA_DST(3),
DMA_DST_RELOAD = DMA_DST(3),

#define BF_DMA_SRC_OFFSET 7
#define BF_DMA_SRC_LENGTH 2

#define DMA_SRC(n) BITFIELD(DMA_SRC, (n))

DMA_SRC_INCREMENT = DMA_SRC(0),
DMA_SRC_DECREMENT = DMA_SRC(1),
Expand All @@ -68,39 +71,44 @@ enum DMAControl
DMA_32BIT = BIT(10),
DMA_16BIT = !DMA_32BIT,

#define BF_DMA_START_OFFSET 12
#define BF_DMA_START_LENGTH 2

#define DMA_START(n) BITFIELD(DMA_START, (n))

DMA_START_NOW = DMA_START(0),
DMA_START_HBLANK = DMA_START(1),
DMA_START_VBLANK = DMA_START(2),
DMA_START_SPECIAL = DMA_START(3),

// DMA1, DMA2
DMA_START_SOUND = DMA_START_SPECIAL,
DMA_START_SOUND = DMA_START(3),
// DMA3
DMA_START_CAPTURE = DMA_START_SPECIAL,
DMA_START_CAPTURE = DMA_START(3),

// On transfer completion
DMA_IRQ_ENABLE = BIT(14),
DMA_ENABLE = BIT(15),
};

extern void dmaEnable(u32 num);
extern void dmaDisable(u32 num);

// General purpose memory copy using DMA3
extern void dmaCopy16(const void *src, void *dst, u32 len);
extern void dmaCopy32(const void *src, void *dst, u32 len);

// Repeating Sound FIFO A transfer using DMA1
extern void dmaSoundFifoATransfer(const void *src, u16 flags);
enum DMAControlPreset
{
DMA_PRESET_COPY16 = DMA_16BIT,
DMA_PRESET_COPY32 = DMA_32BIT,
DMA_PRESET_FILL16 = DMA_16BIT | DMA_SRC_FIXED,
DMA_PRESET_FILL32 = DMA_32BIT | DMA_SRC_FIXED,
DMA_PRESET_HBLANK = DMA_REPEAT | DMA_START_HBLANK,
DMA_PRESET_VBLANK = DMA_REPEAT | DMA_START_VBLANK,
DMA_PRESET_SOUND = DMA_REPEAT | DMA_START_SOUND,
DMA_PRESET_CAPTURE = DMA_REPEAT | DMA_START_CAPTURE,
};

// Repeating Sound FIFO B transfer using DMA2
extern void dmaSoundFifoBTransfer(const void *src, u16 flags);
#define DMA_LEN(len, flags) \
((flags) & DMA_32BIT ? (len) >> 2 : (len) >> 1)

// Repeating H-Blank transfer using DMA0.
extern void dmaHBlankTransfer(const void *src, void *dst, u32 len, u16 flags);
#define DMA_BUILD(src, dst, len, flags) \
((struct DMA){ src, dst, DMA_LEN(len, flags), flags })

// Atomically sets up a DMA channel, using a byte count
extern void dmaAtomicSet(u32 num, const void *src, void *dst, u32 len, u16 flags);
extern void dmaSet(u32 channel, struct DMA dma);

_LIBSEVEN_EXTERN_C_END

Expand Down
2 changes: 1 addition & 1 deletion libseven/meson.build
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = '0.11.1'
version = '0.12.0'

sources = [
'src/hw/bios.s',
Expand Down
193 changes: 8 additions & 185 deletions libseven/src/hw/dma.s
Original file line number Diff line number Diff line change
Expand Up @@ -10,199 +10,22 @@
.include "constants.s"
.include "macros.s"

@ void dmaEnable(u32 num)
@
@ r0 num
fn dmaEnable thumb
fn dmaSet thumb
@ Bounds check
cmp r0, #3
bgt .Leout

@ * 8
lsls r1, r0, #3
@ * 4
lsls r0, r0, #2
@ = * 12
adds r0, r0, r1

@ Read DMA0CNT
ldr r1, =REG_DMA0CNT
ldrh r2, [r1, r0]

@ Add DMA_ENABLE
movs r3, #0x80
lsls r3, r3, #8
orrs r2, r2, r3

strh r2, [r1, r0]
.Leout:
bx lr
endfn

@ void dmaDisable(u32 num)
@
@ r0 num
fn dmaDisable thumb
cmp r0, #3

bgt .Ldout
@ * 8
lsls r1, r0, #3
@ * 4
lsls r0, r0, #2
@ = * 12
adds r0, r0, r1

@ Read DMA0CNT
ldr r1, =REG_DMA0CNT
ldrh r2, [r1, r0]

@ Remove DMA_ENABLE
movs r3, #0x80
lsls r3, r3, #8
bics r2, r2, r3

strh r2, [r1, r0]
.Ldout:
bx lr
endfn

@ void dmaCopy16(const void *src, void *dst, u32 len)
@
@ r0 src
@ r1 dst
@ r2 len
fn dmaCopy16 thumb
@ DMA_ENABLE
movs r3, #0x80
lsls r3, r3, #24
@ len = (len / 2) & 0xFFFF
lsls r2, r2, #15
lsrs r2, r2, #16
orrs r2, r2, r3
ldr r3, =REG_DMA3SRC
stm r3!, {r0, r1, r2}
bx lr
endfn

@ void dmaCopy32(const void *src, void *dst, u32 len)
@
@ r0 src
@ r1 dst
@ r2 len
fn dmaCopy32 thumb
@ DMA_ENABLE | DMA_32BIT
movs r3, #0x84
lsls r3, r3, #24
@ len = (len / 4) & 0xFFFF
lsls r2, r2, #14
lsrs r2, r2, #16
orrs r2, r2, r3
ldr r3, =REG_DMA3SRC
stm r3!, {r0, r1, r2}
bx lr
endfn

@ void dmaSoundFifoATransfer(const void *src)
@
@ r0 src
fn dmaSoundFifoATransfer thumb
lsls r3, r1, #16
ldr r1, =SOUND_FIFO_A
@ DMA_REPEAT | DMA_START_SOUND
movs r2, #0x32
lsls r2, r2, #24
orrs r2, r2, r3
ldr r3, =REG_DMA1SRC
stm r3!, {r0, r1, r2}
bx lr
endfn

@ void dmaSoundFifoBTransfer(const void *src)
@
@ r0 src
fn dmaSoundFifoBTransfer thumb
lsls r3, r1, #16
ldr r1, =SOUND_FIFO_B
movs r2, #0x32
lsls r2, r2, #24
orrs r2, r2, r3
ldr r3, =REG_DMA2SRC
stm r3!, {r0, r1, r2}
bx lr
endfn

@ void dmaHBlankTransfer(const void *src, void *dst, u32 len, u16 flags);
@
@ r0 src
@ r1 dst
@ r2 len
@ r3 flags
fn dmaHBlankTransfer thumb
@ Clear DMA_START flags
mov r12, r4
movs r4, #0x30
lsls r4, r4, #8
bics r3, r3, r4
@ Add DMA_START_HBLANK | DMA_REPEAT
movs r4, #0x22
lsls r4, r4, #8
orrs r3, r3, r4
@ Check for DMA_32BIT and adjust byte count
lsrs r4, r3, #11
mov r4, r12
bcs 1f
lsls r2, r2, #1
1:
lsls r2, r2, #14
lsrs r2, r2, #16

lsls r3, r3, #16
orrs r2, r2, r3
ldr r3, =REG_DMA0SRC
stm r3!, {r0, r1, r2}
bx lr
endfn

@ void dmaAtomicSet(u32 num, const void *src, void *dst, u32 len, u16 flags);
@
@ r0 num
@ r1 src
@ r2 dst
@ r3 len
@ [sp] flags
fn dmaAtomicSet thumb
cmp r0, #3
bgt .Lsout
bhi 1f
push {r4, r5}

@ num *= 12
lsls r4, r0, #3
lsls r0, r0, #2
adds r0, r0, r4

@ Final Address
@ Register address
movs r4, 12
muls r0, r4
ldr r4, =REG_DMA0SRC
adds r0, r0, r4

@ Load flags
ldr r4, [sp]

@ Adjust byte count
lsrs r5, r4, #11
bcs 1f
lsls r3, r3, #1
1:
lsls r3, r3, #14
lsrs r3, r3, #16

@ Merge Length and Flags
lsls r4, r4, #16
orrs r3, r3, r4

@ Write with STM to prevent interrupts from IRQ or DMA
stm r0!, {r1, r2, r3}

pop {r4, r5}
.Lsout:
1:
bx lr
endfn

Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
project('sdk-seven', 'c',
version: '0.7.0',
version: '0.8.0',
license: 'Zlib',
meson_version: '>=0.60.0',
default_options: ['warning_level=2', 'c_std=c99'])
Expand Down

0 comments on commit 28a01a3

Please sign in to comment.