summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDizzyEggg <jajkodizzy@wp.pl>2019-02-01 00:25:31 +0100
committerDizzyEggg <jajkodizzy@wp.pl>2019-02-01 00:25:31 +0100
commit7750a8126ded530e3088b6229cd742797b1e7c37 (patch)
treee4d027a2b8f91e31043930ed0053f9760869813a
parentd2c17c7fb3ba6149b4e278bd3b644cd4d4d240e2 (diff)
CgbSound is decompiled.
-rw-r--r--Makefile1
-rw-r--r--asm/m4a_3.s574
-rw-r--r--include/gba/m4a_internal.h65
-rw-r--r--ld_script.txt2
-rw-r--r--src/m4a_3.c324
5 files changed, 359 insertions, 607 deletions
diff --git a/Makefile b/Makefile
index 32cc9df73..4b13d59db 100644
--- a/Makefile
+++ b/Makefile
@@ -131,6 +131,7 @@ $(C_BUILDDIR)/agb_flash_1m.o: CFLAGS := -O -mthumb-interwork
$(C_BUILDDIR)/agb_flash_mx.o: CFLAGS := -O -mthumb-interwork
$(C_BUILDDIR)/m4a_2.o: CC1 := tools/agbcc/bin/old_agbcc
+$(C_BUILDDIR)/m4a_3.o: CC1 := tools/agbcc/bin/old_agbcc
$(C_BUILDDIR)/m4a_4.o: CC1 := tools/agbcc/bin/old_agbcc
$(C_BUILDDIR)/record_mixing.o: CFLAGS += -ffreestanding
diff --git a/asm/m4a_3.s b/asm/m4a_3.s
deleted file mode 100644
index a842ae925..000000000
--- a/asm/m4a_3.s
+++ /dev/null
@@ -1,574 +0,0 @@
- .include "asm/macros.inc"
- .include "constants/gba_constants.inc"
- .include "constants/m4a_constants.inc"
-
- .syntax unified
-
- .text
-
- thumb_func_start CgbSound
-CgbSound: @ 81DEA70
- push {r4-r7,lr}
- mov r7, r10
- mov r6, r9
- mov r5, r8
- push {r5-r7}
- sub sp, 0x1C
- ldr r0, =SOUND_INFO_PTR
- ldr r0, [r0]
- str r0, [sp, 0x4]
- ldrb r0, [r0, 0xA]
- cmp r0, 0
- beq _081DEA94
- subs r0, 0x1
- ldr r1, [sp, 0x4]
- strb r0, [r1, 0xA]
- b _081DEA9A
- .pool
-_081DEA94:
- movs r0, 0xE
- ldr r2, [sp, 0x4]
- strb r0, [r2, 0xA]
-_081DEA9A:
- movs r6, 0x1
- ldr r0, [sp, 0x4]
- ldr r4, [r0, 0x1C]
-_081DEAA0:
- ldrb r1, [r4]
- movs r0, 0xC7
- ands r0, r1
- adds r2, r6, 0x1
- mov r10, r2
- movs r2, 0x40
- adds r2, r4
- mov r9, r2
- cmp r0, 0
- bne _081DEAB6
- b _081DEEA0
-_081DEAB6:
- cmp r6, 0x2
- beq _081DEAE8
- cmp r6, 0x2
- bgt _081DEAC4
- cmp r6, 0x1
- beq _081DEACA
- b _081DEB20
-_081DEAC4:
- cmp r6, 0x3
- beq _081DEB00
- b _081DEB20
-_081DEACA:
- ldr r0, =REG_NR10
- str r0, [sp, 0x8]
- ldr r7, =REG_NR11
- ldr r2, =REG_NR12
- str r2, [sp, 0xC]
- adds r0, 0x4
- str r0, [sp, 0x10]
- adds r2, 0x2
- b _081DEB30
- .pool
-_081DEAE8:
- ldr r0, =REG_NR10 + 1
- str r0, [sp, 0x8]
- ldr r7, =REG_NR21
- ldr r2, =REG_NR22
- b _081DEB28
- .pool
-_081DEB00:
- ldr r0, =REG_NR30
- str r0, [sp, 0x8]
- ldr r7, =REG_NR31
- ldr r2, =REG_NR32
- str r2, [sp, 0xC]
- adds r0, 0x4
- str r0, [sp, 0x10]
- adds r2, 0x2
- b _081DEB30
- .pool
-_081DEB20:
- ldr r0, =REG_NR30 + 1
- str r0, [sp, 0x8]
- ldr r7, =REG_NR41
- ldr r2, =REG_NR42
-_081DEB28:
- str r2, [sp, 0xC]
- adds r0, 0xB
- str r0, [sp, 0x10]
- adds r2, 0x4
-_081DEB30:
- str r2, [sp, 0x14]
- ldr r0, [sp, 0x4]
- ldrb r0, [r0, 0xA]
- str r0, [sp]
- ldr r2, [sp, 0xC]
- ldrb r0, [r2]
- mov r8, r0
- adds r2, r1, 0
- movs r0, 0x80
- ands r0, r2
- cmp r0, 0
- beq _081DEC26
- movs r3, 0x40
- adds r0, r3, 0
- ands r0, r2
- lsls r0, 24
- lsrs r5, r0, 24
- adds r0, r6, 0x1
- mov r10, r0
- movs r1, 0x40
- adds r1, r4
- mov r9, r1
- cmp r5, 0
- bne _081DEC4A
- movs r0, 0x3
- strb r0, [r4]
- strb r0, [r4, 0x1D]
- adds r0, r4, 0
- str r3, [sp, 0x18]
- bl CgbModVol
- ldr r3, [sp, 0x18]
- cmp r6, 0x2
- beq _081DEB98
- cmp r6, 0x2
- bgt _081DEB8C
- cmp r6, 0x1
- beq _081DEB92
- b _081DEBEC
- .pool
-_081DEB8C:
- cmp r6, 0x3
- beq _081DEBA4
- b _081DEBEC
-_081DEB92:
- ldrb r0, [r4, 0x1F]
- ldr r2, [sp, 0x8]
- strb r0, [r2]
-_081DEB98:
- ldr r0, [r4, 0x24]
- lsls r0, 6
- ldrb r1, [r4, 0x1E]
- adds r0, r1, r0
- strb r0, [r7]
- b _081DEBF8
-_081DEBA4:
- ldr r1, [r4, 0x24]
- ldr r0, [r4, 0x28]
- cmp r1, r0
- beq _081DEBCC
- ldr r2, [sp, 0x8]
- strb r3, [r2]
- ldr r1, =REG_WAVE_RAM
- ldr r2, [r4, 0x24]
- ldr r0, [r2]
- str r0, [r1]
- adds r1, 0x4
- ldr r0, [r2, 0x4]
- str r0, [r1]
- adds r1, 0x4
- ldr r0, [r2, 0x8]
- str r0, [r1]
- adds r1, 0x4
- ldr r0, [r2, 0xC]
- str r0, [r1]
- str r2, [r4, 0x28]
-_081DEBCC:
- ldr r0, [sp, 0x8]
- strb r5, [r0]
- ldrb r0, [r4, 0x1E]
- strb r0, [r7]
- ldrb r0, [r4, 0x1E]
- cmp r0, 0
- beq _081DEBE4
- movs r0, 0xC0
- b _081DEC06
- .pool
-_081DEBE4:
- movs r1, 0x80
- negs r1, r1
- strb r1, [r4, 0x1A]
- b _081DEC08
-_081DEBEC:
- ldrb r0, [r4, 0x1E]
- strb r0, [r7]
- ldr r0, [r4, 0x24]
- lsls r0, 3
- ldr r2, [sp, 0x10]
- strb r0, [r2]
-_081DEBF8:
- ldrb r0, [r4, 0x4]
- adds r0, 0x8
- mov r8, r0
- ldrb r0, [r4, 0x1E]
- cmp r0, 0
- beq _081DEC06
- movs r0, 0x40
-_081DEC06:
- strb r0, [r4, 0x1A]
-_081DEC08:
- ldrb r1, [r4, 0x4]
- movs r2, 0
- strb r1, [r4, 0xB]
- movs r0, 0xFF
- ands r0, r1
- adds r1, r6, 0x1
- mov r10, r1
- movs r1, 0x40
- adds r1, r4
- mov r9, r1
- cmp r0, 0
- bne _081DEC22
- b _081DED5E
-_081DEC22:
- strb r2, [r4, 0x9]
- b _081DED8C
-_081DEC26:
- movs r0, 0x4
- ands r0, r2
- cmp r0, 0
- beq _081DEC58
- ldrb r0, [r4, 0xD]
- subs r0, 0x1
- strb r0, [r4, 0xD]
- movs r2, 0xFF
- ands r0, r2
- lsls r0, 24
- adds r1, r6, 0x1
- mov r10, r1
- movs r2, 0x40
- adds r2, r4
- mov r9, r2
- cmp r0, 0
- ble _081DEC4A
- b _081DED9E
-_081DEC4A:
- lsls r0, r6, 24
- lsrs r0, 24
- bl CgbOscOff
- movs r0, 0
- strb r0, [r4]
- b _081DEE9C
-_081DEC58:
- movs r0, 0x40
- ands r0, r1
- adds r2, r6, 0x1
- mov r10, r2
- movs r2, 0x40
- adds r2, r4
- mov r9, r2
- cmp r0, 0
- beq _081DEC98
- movs r0, 0x3
- ands r0, r1
- cmp r0, 0
- beq _081DEC98
- movs r0, 0xFC
- ands r0, r1
- movs r2, 0
- strb r0, [r4]
- ldrb r1, [r4, 0x7]
- strb r1, [r4, 0xB]
- movs r0, 0xFF
- ands r0, r1
- cmp r0, 0
- beq _081DECCA
- movs r0, 0x1
- ldrb r1, [r4, 0x1D]
- orrs r0, r1
- strb r0, [r4, 0x1D]
- cmp r6, 0x3
- beq _081DED8C
- ldrb r2, [r4, 0x7]
- mov r8, r2
- b _081DED8C
-_081DEC98:
- ldrb r0, [r4, 0xB]
- cmp r0, 0
- bne _081DED8C
- cmp r6, 0x3
- bne _081DECAA
- movs r0, 0x1
- ldrb r1, [r4, 0x1D]
- orrs r0, r1
- strb r0, [r4, 0x1D]
-_081DECAA:
- adds r0, r4, 0
- bl CgbModVol
- movs r0, 0x3
- ldrb r2, [r4]
- ands r0, r2
- cmp r0, 0
- bne _081DECFE
- ldrb r0, [r4, 0x9]
- subs r0, 0x1
- strb r0, [r4, 0x9]
- movs r1, 0xFF
- ands r0, r1
- lsls r0, 24
- cmp r0, 0
- bgt _081DECFA
-_081DECCA:
- ldrb r2, [r4, 0xC]
- ldrb r1, [r4, 0xA]
- adds r0, r2, 0
- muls r0, r1
- adds r0, 0xFF
- asrs r0, 8
- movs r1, 0
- strb r0, [r4, 0x9]
- lsls r0, 24
- cmp r0, 0
- beq _081DEC4A
- movs r0, 0x4
- ldrb r2, [r4]
- orrs r0, r2
- strb r0, [r4]
- movs r0, 0x1
- ldrb r1, [r4, 0x1D]
- orrs r0, r1
- strb r0, [r4, 0x1D]
- cmp r6, 0x3
- beq _081DED9E
- movs r2, 0x8
- mov r8, r2
- b _081DED9E
-_081DECFA:
- ldrb r0, [r4, 0x7]
- b _081DED8A
-_081DECFE:
- cmp r0, 0x1
- bne _081DED0A
-_081DED02:
- ldrb r0, [r4, 0x19]
- strb r0, [r4, 0x9]
- movs r0, 0x7
- b _081DED8A
-_081DED0A:
- cmp r0, 0x2
- bne _081DED4E
- ldrb r0, [r4, 0x9]
- subs r0, 0x1
- strb r0, [r4, 0x9]
- movs r1, 0xFF
- ands r0, r1
- lsls r0, 24
- ldrb r2, [r4, 0x19]
- lsls r1, r2, 24
- cmp r0, r1
- bgt _081DED4A
-_081DED22:
- ldrb r0, [r4, 0x6]
- cmp r0, 0
- bne _081DED32
- movs r0, 0xFC
- ldrb r1, [r4]
- ands r0, r1
- strb r0, [r4]
- b _081DECCA
-_081DED32:
- ldrb r0, [r4]
- subs r0, 0x1
- strb r0, [r4]
- movs r0, 0x1
- ldrb r2, [r4, 0x1D]
- orrs r0, r2
- strb r0, [r4, 0x1D]
- cmp r6, 0x3
- beq _081DED02
- movs r0, 0x8
- mov r8, r0
- b _081DED02
-_081DED4A:
- ldrb r0, [r4, 0x5]
- b _081DED8A
-_081DED4E:
- ldrb r0, [r4, 0x9]
- adds r0, 0x1
- strb r0, [r4, 0x9]
- movs r1, 0xFF
- ands r0, r1
- ldrb r2, [r4, 0xA]
- cmp r0, r2
- bcc _081DED88
-_081DED5E:
- ldrb r0, [r4]
- subs r0, 0x1
- movs r2, 0
- strb r0, [r4]
- ldrb r1, [r4, 0x5]
- strb r1, [r4, 0xB]
- movs r0, 0xFF
- ands r0, r1
- cmp r0, 0
- beq _081DED22
- movs r0, 0x1
- ldrb r1, [r4, 0x1D]
- orrs r0, r1
- strb r0, [r4, 0x1D]
- ldrb r0, [r4, 0xA]
- strb r0, [r4, 0x9]
- cmp r6, 0x3
- beq _081DED8C
- ldrb r2, [r4, 0x5]
- mov r8, r2
- b _081DED8C
-_081DED88:
- ldrb r0, [r4, 0x4]
-_081DED8A:
- strb r0, [r4, 0xB]
-_081DED8C:
- ldrb r0, [r4, 0xB]
- subs r0, 0x1
- strb r0, [r4, 0xB]
- ldr r0, [sp]
- cmp r0, 0
- bne _081DED9E
- subs r0, 0x1
- str r0, [sp]
- b _081DEC98
-_081DED9E:
- movs r0, 0x2
- ldrb r1, [r4, 0x1D]
- ands r0, r1
- cmp r0, 0
- beq _081DEE16
- cmp r6, 0x3
- bgt _081DEDDE
- movs r0, 0x8
- ldrb r2, [r4, 0x1]
- ands r0, r2
- cmp r0, 0
- beq _081DEDDE
- ldr r0, =REG_SOUNDBIAS + 1
- ldrb r0, [r0]
- cmp r0, 0x3F
- bgt _081DEDD0
- ldr r0, [r4, 0x20]
- adds r0, 0x2
- ldr r1, =0x000007fc
- b _081DEDDA
- .pool
-_081DEDD0:
- cmp r0, 0x7F
- bgt _081DEDDE
- ldr r0, [r4, 0x20]
- adds r0, 0x1
- ldr r1, =0x000007fe
-_081DEDDA:
- ands r0, r1
- str r0, [r4, 0x20]
-_081DEDDE:
- cmp r6, 0x4
- beq _081DEDF0
- ldr r0, [r4, 0x20]
- ldr r1, [sp, 0x10]
- strb r0, [r1]
- b _081DEDFE
- .pool
-_081DEDF0:
- ldr r2, [sp, 0x10]
- ldrb r0, [r2]
- movs r1, 0x8
- ands r1, r0
- ldr r0, [r4, 0x20]
- orrs r0, r1
- strb r0, [r2]
-_081DEDFE:
- movs r0, 0xC0
- ldrb r1, [r4, 0x1A]
- ands r0, r1
- adds r1, r4, 0
- adds r1, 0x21
- ldrb r1, [r1]
- adds r0, r1, r0
- strb r0, [r4, 0x1A]
- movs r2, 0xFF
- ands r0, r2
- ldr r1, [sp, 0x14]
- strb r0, [r1]
-_081DEE16:
- movs r0, 0x1
- ldrb r2, [r4, 0x1D]
- ands r0, r2
- cmp r0, 0
- beq _081DEE9C
- ldr r1, =REG_NR51
- ldrb r0, [r1]
- ldrb r2, [r4, 0x1C]
- bics r0, r2
- ldrb r2, [r4, 0x1B]
- orrs r0, r2
- strb r0, [r1]
- cmp r6, 0x3
- bne _081DEE68
- ldr r0, =gCgb3Vol
- ldrb r1, [r4, 0x9]
- adds r0, r1, r0
- ldrb r0, [r0]
- ldr r2, [sp, 0xC]
- strb r0, [r2]
- movs r1, 0x80
- adds r0, r1, 0
- ldrb r2, [r4, 0x1A]
- ands r0, r2
- cmp r0, 0
- beq _081DEE9C
- ldr r0, [sp, 0x8]
- strb r1, [r0]
- ldrb r0, [r4, 0x1A]
- ldr r1, [sp, 0x14]
- strb r0, [r1]
- movs r0, 0x7F
- ldrb r2, [r4, 0x1A]
- ands r0, r2
- strb r0, [r4, 0x1A]
- b _081DEE9C
- .pool
-_081DEE68:
- movs r0, 0xF
- mov r1, r8
- ands r1, r0
- mov r8, r1
- ldrb r2, [r4, 0x9]
- lsls r0, r2, 4
- add r0, r8
- ldr r1, [sp, 0xC]
- strb r0, [r1]
- movs r2, 0x80
- ldrb r0, [r4, 0x1A]
- orrs r0, r2
- ldr r1, [sp, 0x14]
- strb r0, [r1]
- cmp r6, 0x1
- bne _081DEE9C
- ldr r0, [sp, 0x8]
- ldrb r1, [r0]
- movs r0, 0x8
- ands r0, r1
- cmp r0, 0
- bne _081DEE9C
- ldrb r0, [r4, 0x1A]
- orrs r0, r2
- ldr r1, [sp, 0x14]
- strb r0, [r1]
-_081DEE9C:
- movs r0, 0
- strb r0, [r4, 0x1D]
-_081DEEA0:
- mov r6, r10
- mov r4, r9
- cmp r6, 0x4
- bgt _081DEEAA
- b _081DEAA0
-_081DEEAA:
- add sp, 0x1C
- pop {r3-r5}
- mov r8, r3
- mov r9, r4
- mov r10, r5
- pop {r4-r7}
- pop {r0}
- bx r0
- thumb_func_end CgbSound
-
- .align 2, 0 @ Don't pad with nop.
diff --git a/include/gba/m4a_internal.h b/include/gba/m4a_internal.h
index 339a0774e..e2836c6f6 100644
--- a/include/gba/m4a_internal.h
+++ b/include/gba/m4a_internal.h
@@ -69,38 +69,38 @@ struct ToneData
struct CgbChannel
{
- u8 sf;
- u8 ty;
- u8 rightVolume;
- u8 leftVolume;
- u8 at;
- u8 de;
- u8 su;
- u8 re;
- u8 ky;
- u8 ev;
- u8 eg;
- u8 ec;
- u8 echoVolume;
- u8 echoLength;
- u8 d1;
- u8 d2;
- u8 gt;
- u8 mk;
- u8 ve;
- u8 pr;
- u8 rp;
- u8 d3[3];
- u8 d5;
- u8 sg;
- u8 n4;
- u8 pan;
- u8 panMask;
- u8 mo;
- u8 le;
- u8 sw;
- u32 fr;
- u32 wp;
+ u8 sf; // 0x0
+ u8 ty; // 0x1
+ u8 rightVolume; // 0x2
+ u8 leftVolume; // 0x3
+ u8 at; // 0x4
+ u8 de; // 0x5
+ u8 su; // 0x6
+ u8 re; // 0x7
+ u8 ky; // 0x8
+ u8 ev; // 0x9
+ u8 eg; // 0xA
+ u8 ec; // 0xB
+ u8 echoVolume; // 0xC
+ u8 echoLength; // 0xD
+ u8 d1; // 0xE
+ u8 d2; // 0xF
+ u8 gt; // 0x10
+ u8 mk; // 0x11
+ u8 ve; // 0x12
+ u8 pr; // 0x13
+ u8 rp; // 0x14
+ u8 d3[3]; // 0x15, 0x16, 0x17
+ u8 d5; // 0x18
+ u8 sg; // 0x19
+ u8 n4; // 0x1A
+ u8 pan; // 0x1B
+ u8 panMask; // 0x1C
+ u8 mo; // 0x1D
+ u8 le; // 0x1E
+ u8 sw; // 0x1F
+ u32 fr; // 0x20
+ u32 *wp;
u32 cp;
u32 tp;
u32 pp;
@@ -397,6 +397,7 @@ void m4aSoundMode(u32 mode);
void MPlayOpen(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track, u8 a3);
void CgbSound(void);
void CgbOscOff(u8);
+void CgbModVol(struct CgbChannel *chan);
u32 MidiKeyToCgbFreq(u8, u8, u8);
void DummyFunc(void);
void MPlayJumpTableCopy(void **mplayJumpTable);
diff --git a/ld_script.txt b/ld_script.txt
index caac5c0bd..d1219cb3e 100644
--- a/ld_script.txt
+++ b/ld_script.txt
@@ -320,7 +320,7 @@ SECTIONS {
asm/libgcnmultiboot.o(.text);
asm/m4a_1.o(.text);
src/m4a_2.o(.text);
- asm/m4a_3.o(.text);
+ src/m4a_3.o(.text);
src/m4a_4.o(.text);
src/agb_flash.o(.text);
src/agb_flash_1m.o(.text);
diff --git a/src/m4a_3.c b/src/m4a_3.c
new file mode 100644
index 000000000..77d0087c0
--- /dev/null
+++ b/src/m4a_3.c
@@ -0,0 +1,324 @@
+#include "gba/m4a_internal.h"
+
+extern const u8 gCgb3Vol[];
+
+void CgbSound(void)
+{
+ s32 ch;
+ struct CgbChannel *channels;
+ s32 evAdd;
+ s32 prevC15;
+ struct SoundInfo *soundInfo = SOUND_INFO_PTR;
+ vu8 *nrx0ptr;
+ vu8 *nrx1ptr;
+ vu8 *nrx2ptr;
+ vu8 *nrx3ptr;
+ vu8 *nrx4ptr;
+
+ // Most comparision operations that cast to s8 perform 'and' by 0xFF.
+ int xFF = 0xff;
+
+ if (soundInfo->c15)
+ soundInfo->c15--;
+ else
+ soundInfo->c15 = 14;
+
+ for (ch = 1, channels = soundInfo->cgbChans; ch <= 4; ch++, channels++)
+ {
+ if (!(channels->sf & 0xc7))
+ continue;
+
+ switch (ch)
+ {
+ case 1:
+ nrx0ptr = (vu8 *)(REG_ADDR_NR10);
+ nrx1ptr = (vu8 *)(REG_ADDR_NR11);
+ nrx2ptr = (vu8 *)(REG_ADDR_NR12);
+ nrx3ptr = (vu8 *)(REG_ADDR_NR13);
+ nrx4ptr = (vu8 *)(REG_ADDR_NR14);
+ break;
+ case 2:
+ nrx0ptr = (vu8 *)(REG_ADDR_NR10+1);
+ nrx1ptr = (vu8 *)(REG_ADDR_NR21);
+ nrx2ptr = (vu8 *)(REG_ADDR_NR22);
+ nrx3ptr = (vu8 *)(REG_ADDR_NR23);
+ nrx4ptr = (vu8 *)(REG_ADDR_NR24);
+ break;
+ case 3:
+ nrx0ptr = (vu8 *)(REG_ADDR_NR30);
+ nrx1ptr = (vu8 *)(REG_ADDR_NR31);
+ nrx2ptr = (vu8 *)(REG_ADDR_NR32);
+ nrx3ptr = (vu8 *)(REG_ADDR_NR33);
+ nrx4ptr = (vu8 *)(REG_ADDR_NR34);
+ break;
+ default:
+ nrx0ptr = (vu8 *)(REG_ADDR_NR30+1);
+ nrx1ptr = (vu8 *)(REG_ADDR_NR41);
+ nrx2ptr = (vu8 *)(REG_ADDR_NR42);
+ nrx3ptr = (vu8 *)(REG_ADDR_NR43);
+ nrx4ptr = (vu8 *)(REG_ADDR_NR44);
+ break;
+ }
+
+ prevC15 = soundInfo->c15;
+ evAdd = *nrx2ptr;
+
+ if (channels->sf & 0x80)
+ {
+ if (!(channels->sf & 0x40))
+ {
+ channels->sf = 3;
+ channels->mo = 3;
+ CgbModVol(channels);
+ switch (ch)
+ {
+ case 1:
+ *nrx0ptr = channels->sw;
+ // fallthrough
+ case 2:
+ *nrx1ptr = ((u32)channels->wp << 6) + channels->le;
+ goto loc_82E0E30;
+ break;
+ case 3:
+ if ((u32)channels->wp != channels->cp)
+ {
+ *nrx0ptr = 0x40;
+ REG_WAVE_RAM0 = channels->wp[0];
+ REG_WAVE_RAM1 = channels->wp[1];
+ REG_WAVE_RAM2 = channels->wp[2];
+ REG_WAVE_RAM3 = channels->wp[3];
+ channels->cp = (u32)channels->wp;
+ }
+ *nrx0ptr = 0;
+ *nrx1ptr = channels->le;
+ if (channels->le)
+ channels->n4 = -64;
+ else
+ channels->n4 = -128;
+ break;
+ default:
+ *nrx1ptr = channels->le;
+ *nrx3ptr = (u32)channels->wp << 3;
+ loc_82E0E30:
+ evAdd = channels->at + 8;
+ if (channels->le)
+ channels->n4 = 64;
+ else
+ channels->n4 = 0;
+ break;
+ }
+ channels->ec = channels->at;
+ if ((s8)(channels->at & xFF))
+ {
+ channels->ev = 0;
+ goto EC_MINUS;
+ }
+ else
+ {
+ goto loc_82E0F96;
+ }
+ }
+ else
+ {
+ goto loc_82E0E82;
+ }
+ }
+ else if (channels->sf & 0x04)
+ {
+ channels->echoLength--;
+ if ((s8)(channels->echoLength & xFF) <= 0)
+ {
+ loc_82E0E82:
+ CgbOscOff(ch);
+ channels->sf = 0;
+ goto LAST_LABEL;
+ }
+ goto loc_82E0FD6;
+ }
+ else if ((channels->sf & 0x40) && (channels->sf & 0x03))
+ {
+ channels->sf &= 0xfc;
+ channels->ec = channels->re;
+ if ((s8)(channels->re & xFF))
+ {
+ channels->mo |= 1;
+ if (ch != 3)
+ {
+ evAdd = channels->re;
+ }
+ goto EC_MINUS;
+ }
+ else
+ {
+ goto loc_82E0F02;
+ }
+ }
+ else
+ {
+ loc_82E0ED0:
+ if (channels->ec == 0)
+ {
+ if (ch == 3)
+ {
+ channels->mo |= 1;
+ }
+ CgbModVol(channels);
+ if ((channels->sf & 0x3) == 0)
+ {
+ channels->ev--;
+ if ((s8)(channels->ev & xFF) <= 0)
+ {
+ loc_82E0F02:
+ channels->ev = ((channels->eg * channels->echoVolume) + 0xFF) >> 8;
+ if (channels->ev)
+ {
+ channels->sf |= 0x4;
+ channels->mo |= 1;
+ if (ch != 3)
+ {
+ evAdd = 8;
+ }
+ goto loc_82E0FD6;
+ }
+ else
+ {
+ goto loc_82E0E82;
+ }
+ }
+ else
+ {
+ channels->ec = channels->re;
+ }
+ }
+ else if ((channels->sf & 0x3) == 1)
+ {
+ loc_82E0F3A:
+ channels->ev = channels->sg;
+ channels->ec = 7;
+ }
+ else if ((channels->sf & 0x3) == 2)
+ {
+ int ev, sg;
+
+ channels->ev--;
+ ev = (s8)(channels->ev & xFF);
+ sg = (s8)(channels->sg);
+ if (ev <= sg)
+ {
+ loc_82E0F5A:
+ if (channels->su == 0)
+ {
+ channels->sf &= 0xfc;
+ goto loc_82E0F02;
+ }
+ else
+ {
+ channels->sf--;
+ channels->mo |= 1;
+ if (ch != 3)
+ {
+ evAdd = 8;
+ }
+ goto loc_82E0F3A;
+ }
+ }
+ else
+ {
+ channels->ec = channels->de;
+ }
+ }
+ else
+ {
+ channels->ev++;
+ if ((u8)(channels->ev & xFF) >= channels->eg)
+ {
+ loc_82E0F96:
+ channels->sf--;
+ channels->ec = channels->de;
+ if ((u8)(channels->ec & xFF))
+ {
+ channels->mo |= 1;
+ channels->ev = channels->eg;
+ if (ch != 3)
+ {
+ evAdd = channels->de;
+ }
+ }
+ else
+ {
+ goto loc_82E0F5A;
+ }
+ }
+ else
+ {
+ channels->ec = channels->at;
+ }
+ }
+ }
+ }
+
+ EC_MINUS:
+ channels->ec--;
+ if (prevC15 == 0)
+ {
+ prevC15--;
+ goto loc_82E0ED0;
+ }
+
+ loc_82E0FD6:
+ if (channels->mo & 0x2)
+ {
+ if (ch < 4 && (channels->ty & 0x08))
+ {
+ int biasH = REG_SOUNDBIAS_H;
+
+ if (biasH < 64)
+ {
+ channels->fr = (channels->fr + 2) & 0x7fc;
+ }
+ else if (biasH < 128)
+ {
+ channels->fr = (channels->fr + 1) & 0x7fe;
+ }
+ }
+ if (ch != 4)
+ {
+ *nrx3ptr = channels->fr;
+ }
+ else
+ {
+ *nrx3ptr = (*nrx3ptr & 0x08) | channels->fr;
+ }
+ channels->n4 = (channels->n4 & 0xC0) + (*((u8*)(&channels->fr) + 1));
+ *nrx4ptr = (s8)(channels->n4 & xFF);
+ }
+
+ if (channels->mo & 1)
+ {
+ REG_NR51 = (REG_NR51 & ~channels->panMask) | channels->pan;
+ if (ch == 3)
+ {
+ *nrx2ptr = gCgb3Vol[channels->ev];
+ if (channels->n4 & 0x80)
+ {
+ *nrx0ptr = 0x80;
+ *nrx4ptr = channels->n4;
+ channels->n4 &= 0x7f;
+ }
+ }
+ else
+ {
+ evAdd &= 0xf;
+ *nrx2ptr = (channels->ev << 4) + evAdd;
+ *nrx4ptr = channels->n4 | 0x80;
+ if (ch == 1 && !(*nrx0ptr & 0x08))
+ {
+ *nrx4ptr = channels->n4 | 0x80;
+ }
+ }
+ }
+
+ LAST_LABEL:
+ channels->mo = 0;
+ }
+}