Merge remote-tracking branch 'nullablevoid/master' into master

Port m4a from pokeemerald into pmd-red
This commit is contained in:
Seth Barberee 2020-10-20 13:08:42 -05:00
commit 0271952426
7 changed files with 709 additions and 965 deletions

View File

@ -63,8 +63,7 @@ $(BUILD_DIR)/src/agb_flash.o : CC1FLAGS := -O -mthumb-interwork
$(BUILD_DIR)/src/agb_flash_1m.o: CC1FLAGS := -O -mthumb-interwork
$(BUILD_DIR)/src/agb_flash_mx.o: CC1FLAGS := -O -mthumb-interwork
$(BUILD_DIR)/src/m4a_2.o: CC1 := tools/agbcc/bin/old_agbcc
$(BUILD_DIR)/src/m4a_4.o: CC1 := tools/agbcc/bin/old_agbcc
$(BUILD_DIR)/src/m4a.o: CC1 := tools/agbcc/bin/old_agbcc
#### Main Rules ####

View File

@ -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:
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 _080AFB00
subs r0, 0x1
ldr r1, [sp, 0x4]
strb r0, [r1, 0xA]
b _080AFB06
.pool
_080AFB00:
movs r0, 0xE
ldr r2, [sp, 0x4]
strb r0, [r2, 0xA]
_080AFB06:
movs r6, 0x1
ldr r0, [sp, 0x4]
ldr r4, [r0, 0x1C]
_080AFB0C:
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 _080AFB22
b _080AFF0C
_080AFB22:
cmp r6, 0x2
beq _080AFB54
cmp r6, 0x2
bgt _080AFB30
cmp r6, 0x1
beq _080AFB36
b _080AFB8C
_080AFB30:
cmp r6, 0x3
beq _080AFB6C
b _080AFB8C
_080AFB36:
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 _080AFB9C
.pool
_080AFB54:
ldr r0, =REG_NR10 + 1
str r0, [sp, 0x8]
ldr r7, =REG_NR21
ldr r2, =REG_NR22
b _080AFB94
.pool
_080AFB6C:
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 _080AFB9C
.pool
_080AFB8C:
ldr r0, =REG_NR30 + 1
str r0, [sp, 0x8]
ldr r7, =REG_NR41
ldr r2, =REG_NR42
_080AFB94:
str r2, [sp, 0xC]
adds r0, 0xB
str r0, [sp, 0x10]
adds r2, 0x4
_080AFB9C:
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 _080AFC92
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 _080AFCB6
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 _080AFC04
cmp r6, 0x2
bgt _080AFBF8
cmp r6, 0x1
beq _080AFBFE
b _080AFC58
.pool
_080AFBF8:
cmp r6, 0x3
beq _080AFC10
b _080AFC58
_080AFBFE:
ldrb r0, [r4, 0x1F]
ldr r2, [sp, 0x8]
strb r0, [r2]
_080AFC04:
ldr r0, [r4, 0x24]
lsls r0, 6
ldrb r1, [r4, 0x1E]
adds r0, r1, r0
strb r0, [r7]
b _080AFC64
_080AFC10:
ldr r1, [r4, 0x24]
ldr r0, [r4, 0x28]
cmp r1, r0
beq _080AFC38
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]
_080AFC38:
ldr r0, [sp, 0x8]
strb r5, [r0]
ldrb r0, [r4, 0x1E]
strb r0, [r7]
ldrb r0, [r4, 0x1E]
cmp r0, 0
beq _080AFC50
movs r0, 0xC0
b _080AFC72
.pool
_080AFC50:
movs r1, 0x80
negs r1, r1
strb r1, [r4, 0x1A]
b _080AFC74
_080AFC58:
ldrb r0, [r4, 0x1E]
strb r0, [r7]
ldr r0, [r4, 0x24]
lsls r0, 3
ldr r2, [sp, 0x10]
strb r0, [r2]
_080AFC64:
ldrb r0, [r4, 0x4]
adds r0, 0x8
mov r8, r0
ldrb r0, [r4, 0x1E]
cmp r0, 0
beq _080AFC72
movs r0, 0x40
_080AFC72:
strb r0, [r4, 0x1A]
_080AFC74:
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 _080AFC8E
b _080AFDCA
_080AFC8E:
strb r2, [r4, 0x9]
b _080AFDF8
_080AFC92:
movs r0, 0x4
ands r0, r2
cmp r0, 0
beq _080AFCC4
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 _080AFCB6
b _080AFE0A
_080AFCB6:
lsls r0, r6, 24
lsrs r0, 24
bl CgbOscOff
movs r0, 0
strb r0, [r4]
b _080AFF08
_080AFCC4:
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 _080AFD04
movs r0, 0x3
ands r0, r1
cmp r0, 0
beq _080AFD04
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 _080AFD36
movs r0, 0x1
ldrb r1, [r4, 0x1D]
orrs r0, r1
strb r0, [r4, 0x1D]
cmp r6, 0x3
beq _080AFDF8
ldrb r2, [r4, 0x7]
mov r8, r2
b _080AFDF8
_080AFD04:
ldrb r0, [r4, 0xB]
cmp r0, 0
bne _080AFDF8
cmp r6, 0x3
bne _080AFD16
movs r0, 0x1
ldrb r1, [r4, 0x1D]
orrs r0, r1
strb r0, [r4, 0x1D]
_080AFD16:
adds r0, r4, 0
bl CgbModVol
movs r0, 0x3
ldrb r2, [r4]
ands r0, r2
cmp r0, 0
bne _080AFD6A
ldrb r0, [r4, 0x9]
subs r0, 0x1
strb r0, [r4, 0x9]
movs r1, 0xFF
ands r0, r1
lsls r0, 24
cmp r0, 0
bgt _080AFD66
_080AFD36:
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 _080AFCB6
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 _080AFE0A
movs r2, 0x8
mov r8, r2
b _080AFE0A
_080AFD66:
ldrb r0, [r4, 0x7]
b _080AFDF6
_080AFD6A:
cmp r0, 0x1
bne _080AFD76
_080AFD6E:
ldrb r0, [r4, 0x19]
strb r0, [r4, 0x9]
movs r0, 0x7
b _080AFDF6
_080AFD76:
cmp r0, 0x2
bne _080AFDBA
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 _080AFDB6
_080AFD8E:
ldrb r0, [r4, 0x6]
cmp r0, 0
bne _080AFD9E
movs r0, 0xFC
ldrb r1, [r4]
ands r0, r1
strb r0, [r4]
b _080AFD36
_080AFD9E:
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 _080AFD6E
movs r0, 0x8
mov r8, r0
b _080AFD6E
_080AFDB6:
ldrb r0, [r4, 0x5]
b _080AFDF6
_080AFDBA:
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 _080AFDF4
_080AFDCA:
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 _080AFD8E
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 _080AFDF8
ldrb r2, [r4, 0x5]
mov r8, r2
b _080AFDF8
_080AFDF4:
ldrb r0, [r4, 0x4]
_080AFDF6:
strb r0, [r4, 0xB]
_080AFDF8:
ldrb r0, [r4, 0xB]
subs r0, 0x1
strb r0, [r4, 0xB]
ldr r0, [sp]
cmp r0, 0
bne _080AFE0A
subs r0, 0x1
str r0, [sp]
b _080AFD04
_080AFE0A:
movs r0, 0x2
ldrb r1, [r4, 0x1D]
ands r0, r1
cmp r0, 0
beq _080AFE82
cmp r6, 0x3
bgt _080AFE4A
movs r0, 0x8
ldrb r2, [r4, 0x1]
ands r0, r2
cmp r0, 0
beq _080AFE4A
ldr r0, =REG_SOUNDBIAS + 1
ldrb r0, [r0]
cmp r0, 0x3F
bgt _080AFE3C
ldr r0, [r4, 0x20]
adds r0, 0x2
ldr r1, =0x000007fc
b _080AFE46
.pool
_080AFE3C:
cmp r0, 0x7F
bgt _080AFE4A
ldr r0, [r4, 0x20]
adds r0, 0x1
ldr r1, =0x000007fe
_080AFE46:
ands r0, r1
str r0, [r4, 0x20]
_080AFE4A:
cmp r6, 0x4
beq _080AFE5C
ldr r0, [r4, 0x20]
ldr r1, [sp, 0x10]
strb r0, [r1]
b _080AFE6A
.pool
_080AFE5C:
ldr r2, [sp, 0x10]
ldrb r0, [r2]
movs r1, 0x8
ands r1, r0
ldr r0, [r4, 0x20]
orrs r0, r1
strb r0, [r2]
_080AFE6A:
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]
_080AFE82:
movs r0, 0x1
ldrb r2, [r4, 0x1D]
ands r0, r2
cmp r0, 0
beq _080AFF08
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 _080AFED4
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 _080AFF08
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 _080AFF08
.pool
_080AFED4:
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 _080AFF08
ldr r0, [sp, 0x8]
ldrb r1, [r0]
movs r0, 0x8
ands r0, r1
cmp r0, 0
bne _080AFF08
ldrb r0, [r4, 0x1A]
orrs r0, r2
ldr r1, [sp, 0x14]
strb r0, [r1]
_080AFF08:
movs r0, 0
strb r0, [r4, 0x1D]
_080AFF0C:
mov r6, r10
mov r4, r9
cmp r6, 0x4
bgt _080AFF16
b _080AFB0C
_080AFF16:
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.

0
asmdiff.sh Normal file → Executable file
View File

View File

@ -100,7 +100,7 @@ struct CgbChannel
u8 le;
u8 sw;
u32 fr;
u32 wp;
u32* wp;
u32 cp;
u32 tp;
u32 pp;

View File

@ -120,9 +120,7 @@ SECTIONS {
src/code_80A7714.o(.text);
asm/code_80A7714.o(.text);
asm/m4a_1.o(.text);
src/m4a_2.o(.text);
asm/m4a_3.o(.text);
src/m4a_4.o(.text);
src/m4a.o(.text);
*libagbsyscall.a:CpuSet.o(.text);
*libagbsyscall.a:SoundBiasReset.o(.text);
*libagbsyscall.a:SoundBiasSet.o(.text);

View File

@ -1,6 +1,8 @@
#include "gba/m4a_internal.h"
#include "global.h"
extern const u8 gCgb3Vol[];
extern char SoundMainRAM_Buffer[0x400];
extern struct SoundInfo gSoundInfo;
@ -944,4 +946,707 @@ void CgbModVol(struct CgbChannel *chan)
"\tpop {r0}\n"
"\tbx r0\n");
#endif
}
}
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 mask = 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;
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 & mask))
{
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 & mask) <= 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 & mask))
{
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 & mask) <= 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 & mask);
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 & mask) >= channels->eg)
{
loc_82E0F96:
channels->sf--;
channels->ec = channels->de;
if ((u8)(channels->ec & mask))
{
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 & mask);
}
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;
}
}
void m4aMPlayTempoControl(struct MusicPlayerInfo *mplayInfo, u16 tempo)
{
if (mplayInfo->ident == ID_NUMBER)
{
mplayInfo->ident++;
mplayInfo->tempoU = tempo;
mplayInfo->tempoI = (mplayInfo->tempoD * mplayInfo->tempoU) >> 8;
mplayInfo->ident = ID_NUMBER;
}
}
void m4aMPlayVolumeControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16 volume)
{
s32 i;
u32 bit;
struct MusicPlayerTrack *track;
if (mplayInfo->ident != ID_NUMBER)
return;
mplayInfo->ident++;
i = mplayInfo->trackCount;
track = mplayInfo->tracks;
bit = 1;
while (i > 0)
{
if (trackBits & bit)
{
if (track->flags & MPT_FLG_EXIST)
{
track->volX = volume / 4;
track->flags |= MPT_FLG_VOLCHG;
}
}
i--;
track++;
bit <<= 1;
}
mplayInfo->ident = ID_NUMBER;
}
void m4aMPlayPitchControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s16 pitch)
{
s32 i;
u32 bit;
struct MusicPlayerTrack *track;
if (mplayInfo->ident != ID_NUMBER)
return;
mplayInfo->ident++;
i = mplayInfo->trackCount;
track = mplayInfo->tracks;
bit = 1;
while (i > 0)
{
if (trackBits & bit)
{
if (track->flags & MPT_FLG_EXIST)
{
track->keyShiftX = pitch >> 8;
track->pitX = pitch;
track->flags |= MPT_FLG_PITCHG;
}
}
i--;
track++;
bit <<= 1;
}
mplayInfo->ident = ID_NUMBER;
}
void m4aMPlayPanpotControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s8 pan)
{
s32 i;
u32 bit;
struct MusicPlayerTrack *track;
if (mplayInfo->ident != ID_NUMBER)
return;
mplayInfo->ident++;
i = mplayInfo->trackCount;
track = mplayInfo->tracks;
bit = 1;
while (i > 0)
{
if (trackBits & bit)
{
if (track->flags & MPT_FLG_EXIST)
{
track->panX = pan;
track->flags |= MPT_FLG_VOLCHG;
}
}
i--;
track++;
bit <<= 1;
}
mplayInfo->ident = ID_NUMBER;
}
void ClearModM(struct MusicPlayerTrack *track)
{
track->lfoSpeedC = 0;
track->modM = 0;
if (track->modT == 0)
track->flags |= MPT_FLG_PITCHG;
else
track->flags |= MPT_FLG_VOLCHG;
}
void m4aMPlayModDepthSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 modDepth)
{
s32 i;
u32 bit;
struct MusicPlayerTrack *track;
if (mplayInfo->ident != ID_NUMBER)
return;
mplayInfo->ident++;
i = mplayInfo->trackCount;
track = mplayInfo->tracks;
bit = 1;
while (i > 0)
{
if (trackBits & bit)
{
if (track->flags & MPT_FLG_EXIST)
{
track->mod = modDepth;
if (!track->mod)
ClearModM(track);
}
}
i--;
track++;
bit <<= 1;
}
mplayInfo->ident = ID_NUMBER;
}
void m4aMPlayLFOSpeedSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 lfoSpeed)
{
s32 i;
u32 bit;
struct MusicPlayerTrack *track;
if (mplayInfo->ident != ID_NUMBER)
return;
mplayInfo->ident++;
i = mplayInfo->trackCount;
track = mplayInfo->tracks;
bit = 1;
while (i > 0)
{
if (trackBits & bit)
{
if (track->flags & MPT_FLG_EXIST)
{
track->lfoSpeed = lfoSpeed;
if (!track->lfoSpeed)
ClearModM(track);
}
}
i--;
track++;
bit <<= 1;
}
mplayInfo->ident = ID_NUMBER;
}
#define MEMACC_COND_JUMP(cond) \
if (cond) \
goto cond_true; \
else \
goto cond_false; \
void ply_memacc(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
u32 op;
u8 *addr;
u8 data;
op = *track->cmdPtr;
track->cmdPtr++;
addr = mplayInfo->memAccArea + *track->cmdPtr;
track->cmdPtr++;
data = *track->cmdPtr;
track->cmdPtr++;
switch (op)
{
case 0:
*addr = data;
return;
case 1:
*addr += data;
return;
case 2:
*addr -= data;
return;
case 3:
*addr = mplayInfo->memAccArea[data];
return;
case 4:
*addr += mplayInfo->memAccArea[data];
return;
case 5:
*addr -= mplayInfo->memAccArea[data];
return;
case 6:
MEMACC_COND_JUMP(*addr == data)
return;
case 7:
MEMACC_COND_JUMP(*addr != data)
return;
case 8:
MEMACC_COND_JUMP(*addr > data)
return;
case 9:
MEMACC_COND_JUMP(*addr >= data)
return;
case 10:
MEMACC_COND_JUMP(*addr <= data)
return;
case 11:
MEMACC_COND_JUMP(*addr < data)
return;
case 12:
MEMACC_COND_JUMP(*addr == mplayInfo->memAccArea[data])
return;
case 13:
MEMACC_COND_JUMP(*addr != mplayInfo->memAccArea[data])
return;
case 14:
MEMACC_COND_JUMP(*addr > mplayInfo->memAccArea[data])
return;
case 15:
MEMACC_COND_JUMP(*addr >= mplayInfo->memAccArea[data])
return;
case 16:
MEMACC_COND_JUMP(*addr <= mplayInfo->memAccArea[data])
return;
case 17:
MEMACC_COND_JUMP(*addr < mplayInfo->memAccArea[data])
return;
default:
return;
}
cond_true:
{
void (*func)(struct MusicPlayerInfo *, struct MusicPlayerTrack *) = *(&gMPlayJumpTable[1]);
func(mplayInfo, track);
return;
}
cond_false:
track->cmdPtr += 4;
}
void ply_xcmd(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
u32 n = *track->cmdPtr;
track->cmdPtr++;
gXcmdTable[n](mplayInfo, track);
}
void ply_xxx(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
void (*func)(struct MusicPlayerInfo *, struct MusicPlayerTrack *) = *(&gMPlayJumpTable[0]);
func(mplayInfo, track);
}
#define READ_XCMD_BYTE(var, n) \
{ \
u32 byte = track->cmdPtr[(n)]; \
byte <<= n * 8; \
(var) &= ~(0xFF << (n * 8)); \
(var) |= byte; \
}
void ply_xwave(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
u32 wav;
READ_XCMD_BYTE(wav, 0) // UB: uninitialized variable
READ_XCMD_BYTE(wav, 1)
READ_XCMD_BYTE(wav, 2)
READ_XCMD_BYTE(wav, 3)
track->tone.wav = (struct WaveData *)wav;
track->cmdPtr += 4;
}
void ply_xtype(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.type = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xatta(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.attack = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xdeca(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.decay = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xsust(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.sustain = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xrele(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.release = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xiecv(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->echoVolume = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xiecl(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->echoLength = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xleng(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.length = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xswee(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.pan_sweep = *track->cmdPtr;
track->cmdPtr++;
}
void DummyFunc()
{
;
}

View File

@ -1,384 +0,0 @@
#include "gba/m4a_internal.h"
void m4aMPlayTempoControl(struct MusicPlayerInfo *mplayInfo, u16 tempo)
{
if (mplayInfo->ident == ID_NUMBER)
{
mplayInfo->ident++;
mplayInfo->tempoU = tempo;
mplayInfo->tempoI = (mplayInfo->tempoD * mplayInfo->tempoU) >> 8;
mplayInfo->ident = ID_NUMBER;
}
}
void m4aMPlayVolumeControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u16 volume)
{
s32 i;
u32 bit;
struct MusicPlayerTrack *track;
if (mplayInfo->ident != ID_NUMBER)
return;
mplayInfo->ident++;
i = mplayInfo->trackCount;
track = mplayInfo->tracks;
bit = 1;
while (i > 0)
{
if (trackBits & bit)
{
if (track->flags & MPT_FLG_EXIST)
{
track->volX = volume / 4;
track->flags |= MPT_FLG_VOLCHG;
}
}
i--;
track++;
bit <<= 1;
}
mplayInfo->ident = ID_NUMBER;
}
void m4aMPlayPitchControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s16 pitch)
{
s32 i;
u32 bit;
struct MusicPlayerTrack *track;
if (mplayInfo->ident != ID_NUMBER)
return;
mplayInfo->ident++;
i = mplayInfo->trackCount;
track = mplayInfo->tracks;
bit = 1;
while (i > 0)
{
if (trackBits & bit)
{
if (track->flags & MPT_FLG_EXIST)
{
track->keyShiftX = pitch >> 8;
track->pitX = pitch;
track->flags |= MPT_FLG_PITCHG;
}
}
i--;
track++;
bit <<= 1;
}
mplayInfo->ident = ID_NUMBER;
}
void m4aMPlayPanpotControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s8 pan)
{
s32 i;
u32 bit;
struct MusicPlayerTrack *track;
if (mplayInfo->ident != ID_NUMBER)
return;
mplayInfo->ident++;
i = mplayInfo->trackCount;
track = mplayInfo->tracks;
bit = 1;
while (i > 0)
{
if (trackBits & bit)
{
if (track->flags & MPT_FLG_EXIST)
{
track->panX = pan;
track->flags |= MPT_FLG_VOLCHG;
}
}
i--;
track++;
bit <<= 1;
}
mplayInfo->ident = ID_NUMBER;
}
void ClearModM(struct MusicPlayerTrack *track)
{
track->lfoSpeedC = 0;
track->modM = 0;
if (track->modT == 0)
track->flags |= MPT_FLG_PITCHG;
else
track->flags |= MPT_FLG_VOLCHG;
}
void m4aMPlayModDepthSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 modDepth)
{
s32 i;
u32 bit;
struct MusicPlayerTrack *track;
if (mplayInfo->ident != ID_NUMBER)
return;
mplayInfo->ident++;
i = mplayInfo->trackCount;
track = mplayInfo->tracks;
bit = 1;
while (i > 0)
{
if (trackBits & bit)
{
if (track->flags & MPT_FLG_EXIST)
{
track->mod = modDepth;
if (!track->mod)
ClearModM(track);
}
}
i--;
track++;
bit <<= 1;
}
mplayInfo->ident = ID_NUMBER;
}
void m4aMPlayLFOSpeedSet(struct MusicPlayerInfo *mplayInfo, u16 trackBits, u8 lfoSpeed)
{
s32 i;
u32 bit;
struct MusicPlayerTrack *track;
if (mplayInfo->ident != ID_NUMBER)
return;
mplayInfo->ident++;
i = mplayInfo->trackCount;
track = mplayInfo->tracks;
bit = 1;
while (i > 0)
{
if (trackBits & bit)
{
if (track->flags & MPT_FLG_EXIST)
{
track->lfoSpeed = lfoSpeed;
if (!track->lfoSpeed)
ClearModM(track);
}
}
i--;
track++;
bit <<= 1;
}
mplayInfo->ident = ID_NUMBER;
}
#define MEMACC_COND_JUMP(cond) \
if (cond) \
goto cond_true; \
else \
goto cond_false; \
void ply_memacc(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
u32 op;
u8 *addr;
u8 data;
op = *track->cmdPtr;
track->cmdPtr++;
addr = mplayInfo->memAccArea + *track->cmdPtr;
track->cmdPtr++;
data = *track->cmdPtr;
track->cmdPtr++;
switch (op)
{
case 0:
*addr = data;
return;
case 1:
*addr += data;
return;
case 2:
*addr -= data;
return;
case 3:
*addr = mplayInfo->memAccArea[data];
return;
case 4:
*addr += mplayInfo->memAccArea[data];
return;
case 5:
*addr -= mplayInfo->memAccArea[data];
return;
case 6:
MEMACC_COND_JUMP(*addr == data)
return;
case 7:
MEMACC_COND_JUMP(*addr != data)
return;
case 8:
MEMACC_COND_JUMP(*addr > data)
return;
case 9:
MEMACC_COND_JUMP(*addr >= data)
return;
case 10:
MEMACC_COND_JUMP(*addr <= data)
return;
case 11:
MEMACC_COND_JUMP(*addr < data)
return;
case 12:
MEMACC_COND_JUMP(*addr == mplayInfo->memAccArea[data])
return;
case 13:
MEMACC_COND_JUMP(*addr != mplayInfo->memAccArea[data])
return;
case 14:
MEMACC_COND_JUMP(*addr > mplayInfo->memAccArea[data])
return;
case 15:
MEMACC_COND_JUMP(*addr >= mplayInfo->memAccArea[data])
return;
case 16:
MEMACC_COND_JUMP(*addr <= mplayInfo->memAccArea[data])
return;
case 17:
MEMACC_COND_JUMP(*addr < mplayInfo->memAccArea[data])
return;
default:
return;
}
cond_true:
{
void (*func)(struct MusicPlayerInfo *, struct MusicPlayerTrack *) = *(&gMPlayJumpTable[1]);
func(mplayInfo, track);
return;
}
cond_false:
track->cmdPtr += 4;
}
void ply_xcmd(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
u32 n = *track->cmdPtr;
track->cmdPtr++;
gXcmdTable[n](mplayInfo, track);
}
void ply_xxx(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
void (*func)(struct MusicPlayerInfo *, struct MusicPlayerTrack *) = *(&gMPlayJumpTable[0]);
func(mplayInfo, track);
}
#define READ_XCMD_BYTE(var, n) \
{ \
u32 byte = track->cmdPtr[(n)]; \
byte <<= n * 8; \
(var) &= ~(0xFF << (n * 8)); \
(var) |= byte; \
}
void ply_xwave(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
u32 wav;
READ_XCMD_BYTE(wav, 0) // UB: uninitialized variable
READ_XCMD_BYTE(wav, 1)
READ_XCMD_BYTE(wav, 2)
READ_XCMD_BYTE(wav, 3)
track->tone.wav = (struct WaveData *)wav;
track->cmdPtr += 4;
}
void ply_xtype(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.type = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xatta(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.attack = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xdeca(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.decay = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xsust(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.sustain = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xrele(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.release = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xiecv(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->echoVolume = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xiecl(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->echoLength = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xleng(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.length = *track->cmdPtr;
track->cmdPtr++;
}
void ply_xswee(struct MusicPlayerInfo *mplayInfo, struct MusicPlayerTrack *track)
{
track->tone.pan_sweep = *track->cmdPtr;
track->cmdPtr++;
}
void DummyFunc()
{
;
}