summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Panzlaff <michael.panzlaff@fau.de>2021-07-01 00:09:40 +0200
committerMichael Panzlaff <michael.panzlaff@fau.de>2021-08-25 18:03:42 +0200
commit45bbe700e7686ab96b7fc805ea2ea6d024f6077f (patch)
treea31d9d99c250a5ad2350f110cf1b3ae99389bd66
parentd049ab8b4a071b7718461dc8b513f34466fec931 (diff)
arm7: decompile SND_exChannel
-rw-r--r--arm7/asm/SND_channel.s28
-rw-r--r--arm7/asm/SND_exChannel.s645
-rw-r--r--arm7/asm/SND_util.s10
-rw-r--r--arm7/asm/wram2.s16
-rw-r--r--arm7/global.inc21
-rw-r--r--arm7/lib/include/SND_channel.h3
-rw-r--r--arm7/lib/include/SND_exChannel.h25
-rw-r--r--arm7/lib/include/SND_lockChannel.h4
-rw-r--r--arm7/lib/include/SND_util.h7
-rw-r--r--arm7/lib/src/SND_exChannel.c346
-rw-r--r--arm7/lib/src/SND_lockChannel.c18
11 files changed, 427 insertions, 696 deletions
diff --git a/arm7/asm/SND_channel.s b/arm7/asm/SND_channel.s
index 850c06f3..44744493 100644
--- a/arm7/asm/SND_channel.s
+++ b/arm7/asm/SND_channel.s
@@ -3,8 +3,8 @@
.text
- arm_func_start FUN_037FC530
-FUN_037FC530: ; 0x037FC530
+ arm_func_start ExChannelLfoUpdate
+ExChannelLfoUpdate: ; 0x037FC530
stmdb sp!, {r4, r5, r6, lr}
mov r6, r0
mov r5, r1
@@ -50,8 +50,8 @@ _037FC5C0:
ldmia sp!, {r4, r5, r6, lr}
bx lr
- arm_func_start FUN_037FC5CC
-FUN_037FC5CC: ; 0x037FC5CC
+ arm_func_start ExChannelSweepUpdate
+ExChannelSweepUpdate: ; 0x037FC5CC
stmdb sp!, {r4, r5, lr}
sub sp, sp, #4
mov r4, r0
@@ -82,8 +82,8 @@ _037FC630:
ldmia sp!, {r4, r5, lr}
bx lr
- arm_func_start FUN_037FC63C
-FUN_037FC63C: ; 0x037FC63C
+ arm_func_start ExChannelVolumeCmp
+ExChannelVolumeCmp: ; 0x037FC63C
stmfd sp!, {lr}
sub sp, sp, #4
ldrh lr, [r0, #36] ; 0x24
@@ -92,7 +92,7 @@ FUN_037FC63C: ; 0x037FC63C
and r0, ip, #255 ; 0xff
mov r2, r2, lsl #4
mov r3, r0, lsl #4
- ldr r1, _037FC698 ; =_03807294
+ ldr r1, _037FC698 ; =sSampleDataShiftTable
ldrb r0, [r1, lr, asr #8]
mov r2, r2, asr r0
ldrb r0, [r1, ip, asr #8]
@@ -109,10 +109,10 @@ _037FC68C:
add sp, sp, #4
ldmia sp!, {lr}
bx lr
-_037FC698: .word _03807294
+_037FC698: .word sSampleDataShiftTable
- arm_func_start FUN_037FC69C
-FUN_037FC69C: ; 0x037FC69C
+ arm_func_start ExChannelStart
+ExChannelStart: ; 0x037FC69C
stmdb sp!, {r4, lr}
mov r4, r0
ldr r0, _037FC6E4 ; =0xFFFE9680
@@ -133,8 +133,8 @@ FUN_037FC69C: ; 0x037FC69C
bx lr
_037FC6E4: .word 0xFFFE9680
- arm_func_start FUN_037FC6E8
-FUN_037FC6E8: ; 0x037FC6E8
+ arm_func_start ExChannelSetup
+ExChannelSetup: ; 0x037FC6E8
stmdb sp!, {r4, lr}
mov r4, r0
mov ip, #0
@@ -179,8 +179,8 @@ FUN_037FC6E8: ; 0x037FC6E8
ldmia sp!, {r4, lr}
bx lr
- arm_func_start FUN_037FC794
-FUN_037FC794: ; 0x037FC794
+ arm_func_start CalcDecayCoeff
+CalcDecayCoeff: ; 0x037FC794
stmfd sp!, {lr}
sub sp, sp, #4
mov r1, r0
diff --git a/arm7/asm/SND_exChannel.s b/arm7/asm/SND_exChannel.s
deleted file mode 100644
index f6e8fe4d..00000000
--- a/arm7/asm/SND_exChannel.s
+++ /dev/null
@@ -1,645 +0,0 @@
- .include "asm/macros.inc"
- .include "global.inc"
-
- .text
-
- arm_func_start SND_FreeExChannel
-SND_FreeExChannel: ; 0x037FCB80
- cmp r0, #0
- movne r1, #0
- strne r1, [r0, #72] ; 0x48
- strne r1, [r0, #76] ; 0x4c
- bx lr
-
- arm_func_start SND_AllocExChannel
-SND_AllocExChannel: ; 0x037FCB94
- stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
- sub sp, sp, #4
- mov sl, r0
- mov r9, r1
- mov fp, r3
- ldr r0, _037FCCBC ; =sUnlockedChannelMask
- ldr r0, [r0]
- mvn r0, r0
- and sl, sl, r0
- cmp r2, #0
- ldreq r0, _037FCCC0 ; =sLockedChannelMask
- ldreq r0, [r0]
- mvneq r0, r0
- andeq sl, sl, r0
- mov r8, #0
- mov r7, r8
- mov r5, #1
- mov r4, #84 ; 0x54
-_037FCBDC:
- ldr r0, _037FCCC4 ; =_03807298
- ldrb r1, [r0, r7]
- mov r0, r5, lsl r1
- ands r0, sl, r0
- beq _037FCC34
- ldr r0, _037FCCC8 ; =SNDi_Work
- mla r6, r1, r4, r0
- cmp r8, #0
- moveq r8, r6
- beq _037FCC34
- ldrb r1, [r8, #34] ; 0x22
- ldrb r0, [r6, #34] ; 0x22
- cmp r0, r1
- bhi _037FCC34
- cmp r0, r1
- bne _037FCC30
- mov r0, r8
- mov r1, r6
- bl FUN_037FC63C
- cmp r0, #0
- bge _037FCC34
-_037FCC30:
- mov r8, r6
-_037FCC34:
- add r7, r7, #1
- cmp r7, #16
- blt _037FCBDC
- cmp r8, #0
- moveq r0, #0
- beq _037FCCB0
- ldrb r0, [r8, #34] ; 0x22
- cmp r9, r0
- movlt r0, #0
- blt _037FCCB0
- ldr r3, [r8, #72] ; 0x48
- cmp r3, #0
- beq _037FCC7C
- mov r0, r8
- mov r1, #0
- ldr r2, [r8, #76] ; 0x4c
- mov lr, pc
- bx r3
-_037FCC7C:
- ldrb r0, [r8, #3]
- bic r0, r0, #248 ; 0xf8
- orr r0, r0, #16
- strb r0, [r8, #3]
- ldrb r0, [r8, #3]
- bic r0, r0, #1
- strb r0, [r8, #3]
- mov r0, r8
- mov r1, fp
- ldr r2, [sp, #40] ; 0x28
- mov r3, r9
- bl FUN_037FC6E8
- mov r0, r8
-_037FCCB0:
- add sp, sp, #4
- ldmia sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
- bx lr
-_037FCCBC: .word sUnlockedChannelMask
-_037FCCC0: .word sLockedChannelMask
-_037FCCC4: .word _03807298
-_037FCCC8: .word SNDi_Work
-
- arm_func_start SND_IsExChannelActive
-SND_IsExChannelActive: ; 0x037FCCCC
- ldrb r0, [r0, #3]
- mov r0, r0, lsl #31
- mov r0, r0, lsr #31
- bx lr
-
- arm_func_start SND_ReleaseExChannel
-SND_ReleaseExChannel: ; 0x037FCCDC
- mov r1, #3
- strb r1, [r0, #2]
- bx lr
-
- arm_func_start SND_SetExChannelRelease
-SND_SetExChannelRelease: ; 0x037FCCE8
- stmdb sp!, {r4, lr}
- mov r4, r0
- mov r0, r1
- bl FUN_037FC794
- strh r0, [r4, #32]
- ldmia sp!, {r4, lr}
- bx lr
-
- arm_func_start SND_SetExChannelSustain
-SND_SetExChannelSustain: ; 0x037FCD04
- strb r1, [r0, #29]
- bx lr
-
- arm_func_start SND_SetExChannelDecay
-SND_SetExChannelDecay: ; 0x037FCD0C
- stmdb sp!, {r4, lr}
- mov r4, r0
- mov r0, r1
- bl FUN_037FC794
- strh r0, [r4, #30]
- ldmia sp!, {r4, lr}
- bx lr
-
- arm_func_start SND_SetExChannelAttack
-SND_SetExChannelAttack: ; 0x037FCD28
- cmp r1, #109 ; 0x6d
- rsblt r1, r1, #255 ; 0xff
- strltb r1, [r0, #28]
- rsbge r2, r1, #127 ; 0x7f
- ldrge r1, _037FCD48 ; =_038072A8
- ldrgeb r1, [r1, r2]
- strgeb r1, [r0, #28]
- bx lr
-_037FCD48: .word _038072A8
-
- arm_func_start SND_UpdateExChannelEnvelope
-SND_UpdateExChannelEnvelope: ; 0x037FCD4C
- cmp r1, #0
- beq _037FCDF0
- ldrb r1, [r0, #2]
- cmp r1, #3
- addls pc, pc, r1, lsl #2
- b _037FCDF0
- b _037FCD74
- b _037FCDA4
- b _037FCDF0
- b _037FCDE0
-_037FCD74:
- ldr r1, [r0, #16]
- rsb r2, r1, #0
- ldrb r1, [r0, #28]
- mul r1, r2, r1
- mov r1, r1, asr #8
- rsb r1, r1, #0
- str r1, [r0, #16]
- ldr r1, [r0, #16]
- cmp r1, #0
- moveq r1, #1
- streqb r1, [r0, #2]
- b _037FCDF0
-_037FCDA4:
- ldrb r1, [r0, #29]
- mov r2, r1, lsl #1
- ldr r1, _037FCDFC ; =SNDi_DecibelSquareTable
- ldrsh r1, [r1, r2]
- mov r3, r1, lsl #7
- ldr r2, [r0, #16]
- ldrh r1, [r0, #30]
- sub r1, r2, r1
- str r1, [r0, #16]
- ldr r1, [r0, #16]
- cmp r1, r3
- strle r3, [r0, #16]
- movle r1, #2
- strleb r1, [r0, #2]
- b _037FCDF0
-_037FCDE0:
- ldr r2, [r0, #16]
- ldrh r1, [r0, #32]
- sub r1, r2, r1
- str r1, [r0, #16]
-_037FCDF0:
- ldr r0, [r0, #16]
- mov r0, r0, asr #7
- bx lr
-_037FCDFC: .word SNDi_DecibelSquareTable
-
- arm_func_start SND_StartExChannelNoise
-SND_StartExChannelNoise: ; 0x037FCE00
- stmfd sp!, {lr}
- sub sp, sp, #4
- ldrb r2, [r0]
- cmp r2, #14
- movcc r0, #0
- bcc _037FCE3C
- cmp r2, #15
- movhi r0, #0
- bhi _037FCE3C
- mov r2, #2
- strb r2, [r0, #1]
- ldr r2, _037FCE48 ; =0x00001F46
- strh r2, [r0, #60] ; 0x3c
- bl FUN_037FC69C
- mov r0, #1
-_037FCE3C:
- add sp, sp, #4
- ldmia sp!, {lr}
- bx lr
-_037FCE48: .word 0x00001F46
-
- arm_func_start SND_StartExChannelPsg
-SND_StartExChannelPsg: ; 0x037FCE4C
- stmfd sp!, {lr}
- sub sp, sp, #4
- ldrb r3, [r0]
- cmp r3, #8
- movcc r0, #0
- bcc _037FCE90
- cmp r3, #13
- movhi r0, #0
- bhi _037FCE90
- mov r3, #1
- strb r3, [r0, #1]
- str r1, [r0, #68] ; 0x44
- ldr r1, _037FCE9C ; =0x00001F46
- strh r1, [r0, #60] ; 0x3c
- mov r1, r2
- bl FUN_037FC69C
- mov r0, #1
-_037FCE90:
- add sp, sp, #4
- ldmia sp!, {lr}
- bx lr
-_037FCE9C: .word 0x00001F46
-
- arm_func_start SND_StartExChannelPcm
-SND_StartExChannelPcm: ; 0x037FCEA0
- stmdb sp!, {r4, lr}
- mov r4, r0
- mov lr, r2
- mov r0, #0
- strb r0, [r4, #1]
- add ip, r4, #56 ; 0x38
- ldmia r1, {r0, r1, r2}
- stmia ip, {r0, r1, r2}
- str lr, [r4, #68] ; 0x44
- mov r0, r4
- mov r1, r3
- bl FUN_037FC69C
- mov r0, #1
- ldmia sp!, {r4, lr}
- bx lr
-
- arm_func_start SND_ExChannelMain
-SND_ExChannelMain: ; 0x037FCEDC
- stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
- sub sp, sp, #28
- mov r6, r0
- mov r4, #0
- mov fp, r4
- mov r7, #1
- str r4, [sp, #8]
- mov r0, #127 ; 0x7f
- str r0, [sp, #20]
- str r4, [sp, #16]
- str r4, [sp, #12]
- str r4, [sp, #4]
- str r4, [sp]
-_037FCF10:
- ldr r8, [sp]
- mov sl, r8
- mov r9, r8
- mov r1, #84 ; 0x54
- ldr r0, _037FD1E4 ; =SNDi_Work
- mla r5, r4, r1, r0
- ldrb r1, [r5, #3]
- mov r0, r1, lsl #31
- movs r0, r0, lsr #31
- beq _037FD1CC
- mov r0, r1, lsl #30
- movs r0, r0, lsr #31
- beq _037FCF74
- bic r0, r1, #248 ; 0xf8
- mov r1, r1, lsl #24
- mov r1, r1, lsr #27
- orr r1, r1, #1
- and r1, r1, #255 ; 0xff
- and r1, r1, #31
- orr r0, r0, r1, lsl #3
- strb r0, [r5, #3]
- ldrb r0, [r5, #3]
- bic r0, r0, #2
- strb r0, [r5, #3]
- b _037FCFC0
-_037FCF74:
- mov r0, r4
- bl SND_IsChannelActive
- cmp r0, #0
- bne _037FCFC0
- ldr r3, [r5, #72] ; 0x48
- cmp r3, #0
- streqb fp, [r5, #34] ; 0x22
- beq _037FCFA8
- mov r0, r5
- mov r1, r7
- ldr r2, [r5, #76] ; 0x4c
- mov lr, pc
- bx r3
-_037FCFA8:
- ldr r0, [sp, #4]
- strh r0, [r5, #36] ; 0x24
- ldrb r0, [r5, #3]
- bic r0, r0, #1
- strb r0, [r5, #3]
- b _037FD1CC
-_037FCFC0:
- ldrb r0, [r5, #9]
- mov r1, r0, lsl #1
- ldr r0, _037FD1E8 ; =SNDi_DecibelSquareTable
- ldrsh r0, [r0, r1]
- add r8, r8, r0
- ldrb r1, [r5, #8]
- ldrb r0, [r5, #5]
- sub r0, r1, r0
- add sl, sl, r0, lsl #6
- mov r0, r5
- mov r1, r6
- bl SND_UpdateExChannelEnvelope
- add r8, r8, r0
- mov r0, r5
- mov r1, r6
- bl FUN_037FC5CC
- add r2, sl, r0
- ldrsh r0, [r5, #12]
- add r1, r8, r0
- ldrsh r0, [r5, #6]
- add r8, r1, r0
- ldrsh r0, [r5, #14]
- add sl, r2, r0
- mov r0, r5
- mov r1, r6
- bl FUN_037FC530
- ldrb r1, [r5, #40] ; 0x28
- cmp r1, #0
- beq _037FD05C
- cmp r1, #1
- beq _037FD048
- cmp r1, #2
- addeq r9, r9, r0
- b _037FD060
-_037FD048:
- mov r1, #32768 ; 0x8000
- rsb r1, r1, #0
- cmp r8, r1
- addgt r8, r8, r0
- b _037FD060
-_037FD05C:
- add sl, sl, r0
-_037FD060:
- ldrsb r0, [r5, #10]
- add r9, r9, r0
- ldrb r0, [r5, #4]
- cmp r0, #127 ; 0x7f
- mulne r0, r9, r0
- addne r0, r0, #64 ; 0x40
- movne r9, r0, asr #7
- ldrsb r0, [r5, #11]
- add r9, r9, r0
- ldrb r0, [r5, #2]
- cmp r0, #3
- bne _037FD0EC
- ldr r0, _037FD1EC ; =0xFFFFFD2D
- cmp r8, r0
- bgt _037FD0EC
- ldrb r0, [r5, #3]
- bic r0, r0, #248 ; 0xf8
- orr r0, r0, #16
- strb r0, [r5, #3]
- ldr r3, [r5, #72] ; 0x48
- cmp r3, #0
- ldreq r0, [sp, #8]
- streqb r0, [r5, #34] ; 0x22
- beq _037FD0D4
- mov r0, r5
- mov r1, r7
- ldr r2, [r5, #76] ; 0x4c
- mov lr, pc
- bx r3
-_037FD0D4:
- ldr r0, [sp, #12]
- strh r0, [r5, #36] ; 0x24
- ldrb r0, [r5, #3]
- bic r0, r0, #1
- strb r0, [r5, #3]
- b _037FD1CC
-_037FD0EC:
- mov r0, r8
- bl SND_CalcChannelVolume
- mov r8, r0
- ldrh r0, [r5, #60] ; 0x3c
- mov r1, sl
- bl SND_CalcTimer
- ldrb r1, [r5, #1]
- cmp r1, #1
- ldreq r1, _037FD1F0 ; =0x0000FFFC
- andeq r0, r0, r1
- moveq r0, r0, lsl #16
- moveq r0, r0, lsr #16
- adds r9, r9, #64 ; 0x40
- ldrmi r9, [sp, #16]
- bmi _037FD130
- cmp r9, #127 ; 0x7f
- ldrgt r9, [sp, #20]
-_037FD130:
- ldrh r1, [r5, #36] ; 0x24
- cmp r8, r1
- beq _037FD164
- strh r8, [r5, #36] ; 0x24
- ldrb r2, [r5, #3]
- bic r1, r2, #248 ; 0xf8
- mov r2, r2, lsl #24
- mov r2, r2, lsr #27
- orr r2, r2, #8
- and r2, r2, #255 ; 0xff
- and r2, r2, #31
- orr r1, r1, r2, lsl #3
- strb r1, [r5, #3]
-_037FD164:
- ldrh r1, [r5, #38] ; 0x26
- cmp r0, r1
- beq _037FD198
- strh r0, [r5, #38] ; 0x26
- ldrb r0, [r5, #3]
- bic r1, r0, #248 ; 0xf8
- mov r0, r0, lsl #24
- mov r0, r0, lsr #27
- orr r0, r0, #4
- and r0, r0, #255 ; 0xff
- and r0, r0, #31
- orr r0, r1, r0, lsl #3
- strb r0, [r5, #3]
-_037FD198:
- ldrb r0, [r5, #35] ; 0x23
- cmp r9, r0
- beq _037FD1CC
- strb r9, [r5, #35] ; 0x23
- ldrb r0, [r5, #3]
- bic r1, r0, #248 ; 0xf8
- mov r0, r0, lsl #24
- mov r0, r0, lsr #27
- orr r0, r0, #16
- and r0, r0, #255 ; 0xff
- and r0, r0, #31
- orr r0, r1, r0, lsl #3
- strb r0, [r5, #3]
-_037FD1CC:
- add r4, r4, #1
- cmp r4, #16
- blt _037FCF10
- add sp, sp, #28
- ldmia sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
- bx lr
-_037FD1E4: .word SNDi_Work
-_037FD1E8: .word SNDi_DecibelSquareTable
-_037FD1EC: .word 0xFFFFFD2D
-_037FD1F0: .word 0x0000FFFC
-
- arm_func_start SND_UpdateExChannel
-SND_UpdateExChannel: ; 0x037FD1F4
- stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
- sub sp, sp, #24
- mov r8, #0
- mov r4, #2
- mov r5, #1
- mov r6, r8
- ldr r7, _037FD3DC ; =SNDi_Work
- mov sl, #84 ; 0x54
-_037FD214:
- mla r9, r8, sl, r7
- ldrb r0, [r9, #3]
- mov r0, r0, lsl #24
- movs r0, r0, lsr #27
- beq _037FD374
- ands r0, r0, #2
- beq _037FD23C
- mov r0, r8
- mov r1, r6
- bl SND_StopChannel
-_037FD23C:
- ldrb r0, [r9, #3]
- mov r0, r0, lsl #24
- mov r1, r0, lsr #27
- ands r0, r1, #1
- beq _037FD318
- ldrb r0, [r9, #1]
- cmp r0, #0
- beq _037FD270
- cmp r0, #1
- beq _037FD2C8
- cmp r0, #2
- beq _037FD2F4
- b _037FD374
-_037FD270:
- ldrb r0, [r9, #57] ; 0x39
- cmp r0, #0
- movne r3, r5
- moveq r3, r4
- ldrh r1, [r9, #36] ; 0x24
- ldrh r0, [r9, #62] ; 0x3e
- str r0, [sp]
- ldr r0, [r9, #64] ; 0x40
- str r0, [sp, #4]
- and r0, r1, #255 ; 0xff
- str r0, [sp, #8]
- mov r0, r1, asr #8
- str r0, [sp, #12]
- ldrh r0, [r9, #38] ; 0x26
- str r0, [sp, #16]
- ldrb r0, [r9, #35] ; 0x23
- str r0, [sp, #20]
- mov r0, r8
- ldr r1, [r9, #68] ; 0x44
- ldrb r2, [r9, #56] ; 0x38
- bl SND_SetupChannelPcm
- b _037FD374
-_037FD2C8:
- ldrh r3, [r9, #36] ; 0x24
- ldrh r0, [r9, #38] ; 0x26
- str r0, [sp]
- ldrb r0, [r9, #35] ; 0x23
- str r0, [sp, #4]
- mov r0, r8
- ldr r1, [r9, #68] ; 0x44
- and r2, r3, #255 ; 0xff
- mov r3, r3, asr #8
- bl SND_SetupChannelPsg
- b _037FD374
-_037FD2F4:
- ldrh r2, [r9, #36] ; 0x24
- ldrb r0, [r9, #35] ; 0x23
- str r0, [sp]
- mov r0, r8
- and r1, r2, #255 ; 0xff
- mov r2, r2, asr #8
- ldrh r3, [r9, #38] ; 0x26
- bl SND_SetupChannelNoise
- b _037FD374
-_037FD318:
- ands r0, r1, #4
- beq _037FD32C
- mov r0, r8
- ldrh r1, [r9, #38] ; 0x26
- bl SND_SetChannelTimer
-_037FD32C:
- ldrb r0, [r9, #3]
- mov r0, r0, lsl #24
- mov r0, r0, lsr #27
- ands r0, r0, #8
- beq _037FD354
- ldrh r2, [r9, #36] ; 0x24
- mov r0, r8
- and r1, r2, #255 ; 0xff
- mov r2, r2, asr #8
- bl SND_SetChannelVolume
-_037FD354:
- ldrb r0, [r9, #3]
- mov r0, r0, lsl #24
- mov r0, r0, lsr #27
- ands r0, r0, #16
- beq _037FD374
- mov r0, r8
- ldrb r1, [r9, #35] ; 0x23
- bl SND_SetChannelPan
-_037FD374:
- add r8, r8, #1
- cmp r8, #16
- blt _037FD214
- mov r5, #0
- ldr r3, _037FD3DC ; =SNDi_Work
- mov r1, #84 ; 0x54
-_037FD38C:
- mla r4, r5, r1, r3
- ldrb r0, [r4, #3]
- mov r0, r0, lsl #24
- movs r0, r0, lsr #27
- beq _037FD3C4
- ands r0, r0, #1
- movne r0, r5, lsl #4
- addne r0, r0, #67108864 ; 0x4000000
- ldrneb r2, [r0, #1027] ; 0x403
- orrne r2, r2, #128 ; 0x80
- strneb r2, [r0, #1027] ; 0x403
- ldrb r0, [r4, #3]
- bic r0, r0, #248 ; 0xf8
- strb r0, [r4, #3]
-_037FD3C4:
- add r5, r5, #1
- cmp r5, #16
- blt _037FD38C
- add sp, sp, #24
- ldmia sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
- bx lr
-_037FD3DC: .word SNDi_Work
-
- arm_func_start SND_ExChannelInit
-SND_ExChannelInit: ; 0x037FD3E0
- mov ip, #0
- ldr r2, _037FD434 ; =SNDi_Work
- mov r0, #84 ; 0x54
-_037FD3EC:
- mul r1, ip, r0
- add r3, r2, r1
- strb ip, [r2, r1]
- ldrb r1, [r3, #3]
- bic r1, r1, #248 ; 0xf8
- strb r1, [r3, #3]
- ldrb r1, [r3, #3]
- bic r1, r1, #1
- strb r1, [r3, #3]
- add ip, ip, #1
- cmp ip, #16
- blt _037FD3EC
- mov r1, #0
- ldr r0, _037FD438 ; =sUnlockedChannelMask
- str r1, [r0]
- ldr r0, _037FD43C ; =sLockedCHannelMask
- str r1, [r0]
- bx lr
-_037FD434: .word SNDi_Work
-_037FD438: .word sUnlockedChannelMask
-_037FD43C: .word sLockedChannelMask
diff --git a/arm7/asm/SND_util.s b/arm7/asm/SND_util.s
index 4d136781..7964fe4e 100644
--- a/arm7/asm/SND_util.s
+++ b/arm7/asm/SND_util.s
@@ -28,18 +28,18 @@ _037FC088: .word 0x3C6EF35F
arm_func_start SND_SinIdx
SND_SinIdx: ; 0x037FC08C
cmp r0, #32
- ldrlt r1, _037FC0F4 ; =_03807170
+ ldrlt r1, _037FC0F4 ; =sLfoSinTable
ldrltsb r0, [r1, r0]
bxlt lr
cmp r0, #64 ; 0x40
rsblt r1, r0, #64 ; 0x40
- ldrlt r0, _037FC0F4 ; =_03807170
+ ldrlt r0, _037FC0F4 ; =sLfoSinTable
ldrltsb r0, [r0, r1]
bxlt lr
cmp r0, #96 ; 0x60
bge _037FC0D4
sub r1, r0, #64 ; 0x40
- ldr r0, _037FC0F4 ; =_03807170
+ ldr r0, _037FC0F4 ; =sLfoSinTable
ldrsb r0, [r0, r1]
rsb r0, r0, #0
mov r0, r0, lsl #24
@@ -48,13 +48,13 @@ SND_SinIdx: ; 0x037FC08C
_037FC0D4:
sub r0, r0, #96 ; 0x60
rsb r1, r0, #32
- ldr r0, _037FC0F4 ; =_03807170
+ ldr r0, _037FC0F4 ; =sLfoSinTable
ldrsb r0, [r0, r1]
rsb r0, r0, #0
mov r0, r0, lsl #24
mov r0, r0, asr #24
bx lr
-_037FC0F4: .word _03807170
+_037FC0F4: .word sLfoSinTable
arm_func_start SND_CalcChannelVolume
SND_CalcChannelVolume: ; 0x037FC0F8
diff --git a/arm7/asm/wram2.s b/arm7/asm/wram2.s
index 7191db9d..6dfeea6f 100644
--- a/arm7/asm/wram2.s
+++ b/arm7/asm/wram2.s
@@ -962,8 +962,8 @@ _u32_div_not_0_f: ;@ 0x03806F94
mov r1, r3
bx lr
- .global _03807170
-_03807170:
+ .global sLfoSinTable
+sLfoSinTable:
.byte 0
.byte 6
.byte 12
@@ -1132,15 +1132,15 @@ SNDi_DecibelSquareTable:
.short -1
.short 0
- .global _03807294
-_03807294:
+ .global sSampleDataShiftTable
+sSampleDataShiftTable:
.byte 0
.byte 1
.byte 2
.byte 4
- .global _03807298
-_03807298:
+ .global sChannelAllocationOrder
+sChannelAllocationOrder:
.byte 4
.byte 5
.byte 6
@@ -1158,8 +1158,8 @@ _03807298:
.byte 15
.byte 13
- .global _038072A8
-_038072A8:
+ .global sAttackCoeffTable
+sAttackCoeffTable:
.byte 0
.byte 1
.byte 5
diff --git a/arm7/global.inc b/arm7/global.inc
index b89a6c21..d7f446e1 100644
--- a/arm7/global.inc
+++ b/arm7/global.inc
@@ -203,12 +203,11 @@
.extern SND_UpdateExChannel
.extern SND_UpdateLfo
.extern SND_UpdateSharedWork
-.extern FUN_037FC530
-.extern FUN_037FC5CC
-.extern FUN_037FC63C
-.extern FUN_037FC69C
-.extern FUN_037FC6E8
-.extern FUN_037FC794
+.extern ExChannelLfoUpdate
+.extern ExChannelSweepUpdate
+.extern ExChannelVolumeCmp
+.extern ExChannelStart
+.extern ExChannelSetup
.extern FUN_037FD440
.extern FUN_037FD4C0
.extern FUN_037FD548
@@ -350,11 +349,11 @@
.extern _ll_udiv
.extern _s32_div_f
.extern _u32_div_f
-.extern _03807170
+.extern sLfoSinTable
.extern SNDi_DecibelSquareTable
-.extern _03807294
-.extern _03807298
-.extern _038072A8
+.extern sSampleDataShiftTable
+.extern sChannelAllocationOrder
+.extern sAttackCoeffTable
.extern _038072BC
.extern _038072C0
.extern _038072C4
@@ -427,8 +426,6 @@
.extern _03807A54
.extern _03807A74
.extern _03807AA0
-.extern sLockedChannelMask
-.extern sUnlockedChannelMask
.extern _03807F4C
.extern _03807F50
.extern _03807F58
diff --git a/arm7/lib/include/SND_channel.h b/arm7/lib/include/SND_channel.h
index 5f90aa66..718e7e2b 100644
--- a/arm7/lib/include/SND_channel.h
+++ b/arm7/lib/include/SND_channel.h
@@ -39,4 +39,7 @@ void SND_SetChannelVolume(s32 chnIdx, s32 volume, s32 volumeDiv);
void SND_SetChannelPan(s32 chnIdx, s32 pan);
void SND_SetChannelTimer(s32 chnIdx, s32 timer);
+// TODO move this function to SND_exChannel.c
+u16 CalcDecayCoeff(s32 value);
+
#endif //GUARD_SND_CHANNEL_H
diff --git a/arm7/lib/include/SND_exChannel.h b/arm7/lib/include/SND_exChannel.h
index cc07d34f..dfd93f21 100644
--- a/arm7/lib/include/SND_exChannel.h
+++ b/arm7/lib/include/SND_exChannel.h
@@ -3,14 +3,33 @@
#include "nitro/types.h"
+#include "nitro/SND_exChannel_shared.h"
#include "nitro/SND_main_shared.h"
+typedef void (*SNDExChannelCallback)(struct SNDExChannel *chn, s32 status, void *userData);
+
void SND_ExChannelInit(void);
-BOOL SND_IsChannelActive(s32 idx);
void SND_UpdateExChannel(void);
-void SND_ExChannelMain(BOOL update);
+void SND_ExChannelMain(BOOL step);
+BOOL SND_StartExChannelPcm(struct SNDExChannel *chn, const struct SNDWaveParam *wave, const void *data, s32 length);
+BOOL SND_StartExChannelPsg(struct SNDExChannel *chn, s32 duty, s32 length);
+BOOL SND_StartExChannelNoise(struct SNDExChannel *chn, s32 length);
+s32 SND_UpdateExChannelEnvelope(struct SNDExChannel *chn, BOOL step);
+void SND_SetExChannelAttack(struct SNDExChannel *chn, s32 attack);
+void SND_SetExChannelDecay(struct SNDExChannel *chn, s32 decay);
+void SND_SetExChannelSustain(struct SNDExChannel *chn, s32 sustain);
+void SND_SetExChannelRelease(struct SNDExChannel *chn, s32 release);
+void SND_ReleaseExChannel(struct SNDExChannel *chn);
+BOOL SND_IsExChannelActive(struct SNDExChannel *chn);
+struct SNDExChannel *SND_AllocExChannel(u32 channelMask, int priority, u32 flags, SNDExChannelCallback callback, void *callbackUserData);
void SND_FreeExChannel(struct SNDExChannel *chn);
+BOOL SND_IsChannelActive(s32 idx);
-typedef void (*SNDExChannelCallback)(struct SNDExChannel *chn, s32 status, void *userData);
+// TODO internal functions, move these so exChannel
+s32 ExChannelSweepUpdate(struct SNDExChannel *chn, BOOL step);
+s32 ExChannelLfoUpdate(struct SNDExChannel *chn, BOOL step);
+void ExChannelStart(struct SNDExChannel *chn, s32);
+s32 ExChannelVolumeCmp(struct SNDExChannel *chn_a, struct SNDExChannel *chn_b);
+void ExChannelSetup(struct SNDExChannel *, SNDExChannelCallback callback, void *callbackUserData, s32 priority);
#endif //GUARD_SND_EXCHANNEL_H
diff --git a/arm7/lib/include/SND_lockChannel.h b/arm7/lib/include/SND_lockChannel.h
index ed7fd872..9673fb51 100644
--- a/arm7/lib/include/SND_lockChannel.h
+++ b/arm7/lib/include/SND_lockChannel.h
@@ -8,4 +8,8 @@ void SND_LockChannel(u32 channelMask, u32 locked);
void SND_UnlockChannel(u32 channelMask, u32 locked);
u32 SND_GetLockedChannel(u32 locked);
+// TODO remove these externs if lockChannel is merged with exChannel
+extern u32 sLockedChannelMask;
+extern u32 sWeakLockedChannelMask;
+
#endif //GUARD_SND_LOCKCHANNEL_H
diff --git a/arm7/lib/include/SND_util.h b/arm7/lib/include/SND_util.h
index babf2a87..1bfdb7a8 100644
--- a/arm7/lib/include/SND_util.h
+++ b/arm7/lib/include/SND_util.h
@@ -3,6 +3,13 @@
#include "nitro/types.h"
+#define SND_DECIBEL_SQUARE_TABLE_COUNT
+
u32 SND_CalcRandom(void);
+u16 SND_CalcChannelVolume(s32 value);
+u16 SND_CalcTimer(s32 timer, s32 pitch);
+
+extern const s16 SNDi_DecibelSquareTable[128];
+
#endif //GUARD_SND_UTIL_H
diff --git a/arm7/lib/src/SND_exChannel.c b/arm7/lib/src/SND_exChannel.c
new file mode 100644
index 00000000..7919b5f7
--- /dev/null
+++ b/arm7/lib/src/SND_exChannel.c
@@ -0,0 +1,346 @@
+#include "SND_exChannel.h"
+
+#include "SND_channel.h"
+#include "SND_main.h"
+#include "SND_work.h"
+#include "SND_lockChannel.h"
+#include "SND_util.h"
+
+#include "registers.h"
+
+// TODO import these tables into here if they belong here
+extern u8 sChannelAllocationOrder[SND_CHANNEL_COUNT];
+extern u8 sAttackCoeffTable[19];
+
+void SND_ExChannelInit(void) {
+ struct SNDExChannel *chn;
+ s32 i;
+
+ for (i = 0; i < SND_CHANNEL_COUNT; i++) {
+ chn = &SNDi_Work.channels[i];
+
+ chn->id = (u8)i;
+ chn->flags.syncFlag = 0;
+ chn->flags.active = FALSE;
+ }
+
+ sLockedChannelMask = 0;
+ sWeakLockedChannelMask = 0;
+}
+
+void SND_UpdateExChannel(void) {
+ struct SNDExChannel *chn;
+ s32 i;
+
+ for (i = 0; i < SND_CHANNEL_COUNT; i++) {
+ chn = &SNDi_Work.channels[i];
+
+ if (chn->flags.syncFlag == 0)
+ continue;
+
+ if (chn->flags.syncFlag & SND_CHN_SYNC_STOP)
+ SND_StopChannel(i, 0);
+
+ if (chn->flags.syncFlag & SND_CHN_SYNC_START) {
+ switch (chn->type) {
+ case SND_CHN_TYPE_PCM:
+ SND_SetupChannelPcm(
+ i,
+ chn->waveDataPtr,
+ chn->waveParam.format,
+ chn->waveParam.loopEnabled ? 1 : 2,
+ (s32)chn->waveParam.loopStart,
+ (s32)chn->waveParam.loopLength,
+ chn->volume & 0xFF,
+ chn->volume >> 8,
+ chn->timer,
+ chn->pan
+ );
+ break;
+ case SND_CHN_TYPE_PSG:
+ SND_SetupChannelPsg(
+ i,
+ chn->dutyCycle,
+ chn->volume & 0xFF,
+ chn->volume >> 8,
+ chn->timer,
+ chn->pan
+ );
+ break;
+ case SND_CHN_TYPE_NOISE:
+ SND_SetupChannelNoise(
+ i,
+ chn->volume & 0xFF,
+ chn->volume >> 8,
+ chn->timer,
+ chn->pan
+ );
+ break;
+ }
+ } else {
+ if (chn->flags.syncFlag & SND_CHN_SYNC_TIMER) {
+ SND_SetChannelTimer(i, chn->timer);
+ }
+ if (chn->flags.syncFlag & SND_CHN_SYNC_VOLUME) {
+ SND_SetChannelVolume(i, chn->volume & 0xFF, chn->volume >> 8);
+ }
+ if (chn->flags.syncFlag & SND_CHN_SYNC_PAN) {
+ SND_SetChannelPan(i, chn->pan);
+ }
+ }
+ }
+
+ for (i = 0; i < SND_CHANNEL_COUNT; i++) {
+ chn = &SNDi_Work.channels[i];
+
+ if (!chn->flags.syncFlag)
+ continue;
+
+ if (chn->flags.syncFlag & SND_CHN_SYNC_START)
+ reg_SOUNDxCNT_STAT(i) |= 0x80;
+ chn->flags.syncFlag = 0;
+ }
+}
+
+void SND_ExChannelMain(BOOL step) {
+ struct SNDExChannel *chn;
+ s32 i;
+ s32 vol;
+ s32 pitch;
+ s32 pan;
+ s32 lfo;
+ u16 newTimer;
+
+ for (i = 0; i < SND_CHANNEL_COUNT; i++) {
+ vol = 0;
+ pitch = 0;
+ pan = 0;
+ chn = &SNDi_Work.channels[i];
+
+ if (!chn->flags.active)
+ continue;
+
+ if (chn->flags.start) {
+ chn->flags.syncFlag |= SND_CHN_SYNC_START;
+ chn->flags.start = FALSE;
+ } else if (!SND_IsChannelActive(i)) {
+ if (chn->callback)
+ chn->callback(chn, 1, chn->callbackUserData);
+ else
+ chn->priority = 0;
+ chn->volume = 0;
+ chn->flags.active = FALSE;
+ continue;
+ }
+
+ vol += SNDi_DecibelSquareTable[chn->velocity];
+ pitch += (chn->midiKey - chn->rootMidiKey) * 0x40;
+
+ vol += SND_UpdateExChannelEnvelope(chn, step);
+ pitch += ExChannelSweepUpdate(chn, step);
+
+ vol += chn->userDecay;
+ vol += chn->userDecay2;
+ pitch += chn->userPitch;
+
+ lfo = ExChannelLfoUpdate(chn, step);
+
+ switch (chn->lfo.param.target) {
+ case SND_LFO_VOLUME:
+ if (vol > -0x8000)
+ vol += lfo;
+ break;
+ case SND_LFO_PAN:
+ pan += lfo;
+ break;
+ case SND_LFO_PITCH:
+ pitch += lfo;
+ break;
+ }
+
+ pan += chn->initPan;
+ if (chn->panRange != 127) {
+ pan = (pan * chn->panRange + 0x40) >> 7;
+ }
+ pan += chn->userPan;
+
+ if (chn->envStatus == SND_ENV_RELEASE && vol <= -723) {
+ chn->flags.syncFlag = SND_CHN_SYNC_STOP;
+ if (chn->callback)
+ chn->callback(chn, 1, chn->callbackUserData);
+ else
+ chn->priority = 0;
+ chn->volume = 0;
+ chn->flags.active = 0;
+ } else {
+ vol = SND_CalcChannelVolume(vol);
+ newTimer = SND_CalcTimer(chn->waveParam.timer, pitch);
+
+ if (chn->type == SND_CHN_TYPE_PSG)
+ newTimer &= 0xFFFC;
+
+ pan += 0x40;
+ if (pan < 0)
+ pan = 0;
+ else if (pan > 127)
+ pan = 127;
+
+ if (vol != chn->volume) {
+ chn->volume = (u16)vol;
+ chn->flags.syncFlag |= SND_CHN_SYNC_VOLUME;
+ }
+ if (newTimer != chn->timer) {
+ chn->timer = (u16)newTimer;
+ chn->flags.syncFlag |= SND_CHN_SYNC_TIMER;
+ }
+ if (pan != chn->pan) {
+ chn->pan = (u8)pan;
+ chn->flags.syncFlag |= SND_CHN_SYNC_PAN;
+ }
+ }
+ }
+}
+
+BOOL SND_StartExChannelPcm(struct SNDExChannel *chn, const struct SNDWaveParam *wave, const void *data, s32 length) {
+ chn->type = SND_CHN_TYPE_PCM;
+ chn->waveParam = *wave;
+ chn->waveDataPtr = data;
+ ExChannelStart(chn, length);
+ return TRUE;
+}
+
+BOOL SND_StartExChannelPsg(struct SNDExChannel *chn, s32 duty, s32 length) {
+ if (chn->id < 8) {
+ return FALSE;
+ } else if (chn->id > 13) {
+ return FALSE;
+ } else {
+ chn->type = SND_CHN_TYPE_PSG;
+ chn->dutyCycle = duty;
+ chn->waveParam.timer = 8006;
+ ExChannelStart(chn, length);
+ return TRUE;
+ }
+}
+
+BOOL SND_StartExChannelNoise(struct SNDExChannel *chn, s32 length) {
+ if (chn->id < 14) {
+ return FALSE;
+ } else if (chn->id > 15) {
+ return FALSE;
+ } else {
+ chn->type = SND_CHN_TYPE_NOISE;
+ chn->waveParam.timer = 8006;
+ ExChannelStart(chn, length);
+ return TRUE;
+ }
+}
+
+s32 SND_UpdateExChannelEnvelope(struct SNDExChannel *chn, BOOL step) {
+ s32 sustain;
+
+ if (step) {
+ switch (chn->envStatus) {
+ case SND_ENV_ATTACK:
+ chn->envAttenuation = -((-chn->envAttenuation * chn->envAttack) >> 8);
+ if (chn->envAttenuation == 0)
+ chn->envStatus = SND_ENV_DECAY;
+ break;
+ case SND_ENV_DECAY:
+ sustain = SNDi_DecibelSquareTable[chn->envSustain] << 7;
+ chn->envAttenuation -= chn->envDecay;
+ if (chn->envAttenuation <= sustain) {
+ chn->envAttenuation = sustain;
+ chn->envStatus = SND_ENV_SUSTAIN;
+ }
+ break;
+ case SND_ENV_SUSTAIN:
+ break;
+ case SND_ENV_RELEASE:
+ chn->envAttenuation -= chn->envRelease;
+ break;
+ }
+ }
+
+ return chn->envAttenuation >> 7;
+}
+
+void SND_SetExChannelAttack(struct SNDExChannel *chn, s32 attack) {
+ if (attack < 109)
+ chn->envAttack = (u8)(255 - attack);
+ else
+ chn->envAttack = sAttackCoeffTable[127 - attack];
+}
+
+void SND_SetExChannelDecay(struct SNDExChannel *chn, s32 decay) {
+ chn->envDecay = CalcDecayCoeff(decay);
+}
+
+void SND_SetExChannelSustain(struct SNDExChannel *chn, s32 sustain) {
+ chn->envSustain = (u8)sustain;
+}
+
+void SND_SetExChannelRelease(struct SNDExChannel *chn, s32 release) {
+ chn->envRelease = CalcDecayCoeff(release);
+}
+
+void SND_ReleaseExChannel(struct SNDExChannel *chn) {
+ chn->envStatus = SND_ENV_RELEASE;
+}
+
+BOOL SND_IsExChannelActive(struct SNDExChannel *chn) {
+ return chn->flags.active;
+}
+
+struct SNDExChannel *SND_AllocExChannel(u32 channelMask, int priority, u32 flags, SNDExChannelCallback callback, void *callbackUserData) {
+ struct SNDExChannel *chnPrev;
+ int i;
+ struct SNDExChannel *chn;
+ u8 channelCandidate;
+
+ channelMask &= ~sLockedChannelMask;
+ if (flags == 0)
+ channelMask &= ~sWeakLockedChannelMask;
+
+ chnPrev = NULL;
+
+ for (i = 0; i < SND_CHANNEL_COUNT; i++) {
+ channelCandidate = sChannelAllocationOrder[i];
+
+ if (channelMask & (1 << channelCandidate)) {
+ chn = &SNDi_Work.channels[channelCandidate];
+
+ if (chnPrev == NULL) {
+ chnPrev = chn;
+ continue;
+ }
+
+ if (chn->priority > chnPrev->priority)
+ continue;
+
+ if (chn->priority != chnPrev->priority || ExChannelVolumeCmp(chnPrev, chn) < 0)
+ chnPrev = chn;
+ }
+ }
+
+ if (chnPrev == NULL)
+ return NULL;
+
+ if (priority < chnPrev->priority)
+ return NULL;
+
+ if (chnPrev->callback)
+ chnPrev->callback(chnPrev, 0, chnPrev->callbackUserData);
+
+ chnPrev->flags.syncFlag = 2;
+ chnPrev->flags.active = 0;
+ ExChannelSetup(chnPrev, callback, callbackUserData, priority);
+ return chnPrev;
+}
+
+void SND_FreeExChannel(struct SNDExChannel *chn) {
+ if (chn) {
+ chn->callback = NULL;
+ chn->callbackUserData = NULL;
+ }
+}
diff --git a/arm7/lib/src/SND_lockChannel.c b/arm7/lib/src/SND_lockChannel.c
index cecfd871..92e04e5e 100644
--- a/arm7/lib/src/SND_lockChannel.c
+++ b/arm7/lib/src/SND_lockChannel.c
@@ -5,8 +5,8 @@
#include "SND.h"
// TODO make these vars static after merging this file with exChannel
-u32 sUnlockedChannelMask;
u32 sLockedChannelMask;
+u32 sWeakLockedChannelMask;
void SND_StopUnlockedChannel(u32 channelMask) {
struct SNDExChannel *chn;
@@ -17,7 +17,7 @@ void SND_StopUnlockedChannel(u32 channelMask) {
chn = &SNDi_Work.channels[i];
- if (sUnlockedChannelMask & (1 << i))
+ if (sLockedChannelMask & (1 << i))
continue;
if (chn->callback)
@@ -42,7 +42,7 @@ void SND_LockChannel(u32 channelMask, u32 locked) {
chn = &SNDi_Work.channels[i];
- if (sUnlockedChannelMask & (1 << i))
+ if (sLockedChannelMask & (1 << i))
continue;
if (chn->callback)
@@ -56,24 +56,24 @@ void SND_LockChannel(u32 channelMask, u32 locked) {
}
if (locked & 1) {
- sLockedChannelMask |= channelMask;
+ sWeakLockedChannelMask |= channelMask;
} else {
- sUnlockedChannelMask |= channelMask;
+ sLockedChannelMask |= channelMask;
}
}
void SND_UnlockChannel(u32 channelMask, u32 locked) {
if (locked & 1) {
- sLockedChannelMask &= ~channelMask;
+ sWeakLockedChannelMask &= ~channelMask;
} else {
- sUnlockedChannelMask &= ~channelMask;
+ sLockedChannelMask &= ~channelMask;
}
}
u32 SND_GetLockedChannel(u32 locked) {
if (locked & 1) {
- return sLockedChannelMask;
+ return sWeakLockedChannelMask;
} else {
- return sUnlockedChannelMask;
+ return sLockedChannelMask;
}
}