diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/crt0.s | 199 | ||||
-rw-r--r-- | src/libagbsyscall.s | 116 | ||||
-rw-r--r-- | src/libgcnmultiboot.s | 550 | ||||
-rw-r--r-- | src/m4a_1.s | 1934 |
4 files changed, 2799 insertions, 0 deletions
diff --git a/src/crt0.s b/src/crt0.s new file mode 100644 index 000000000..9ed678968 --- /dev/null +++ b/src/crt0.s @@ -0,0 +1,199 @@ + .include "constants/gba_constants.inc" + + .syntax unified + + .global Start + + .text + + .arm + +Start: @ 8000000 + b Init + + .include "asm/rom_header.inc" + +@ 80000C0 + .word 0 + + .global GPIOPortData +GPIOPortData: @ 80000C4 + .2byte 0 + + .global GPIOPortDirection +GPIOPortDirection: @ 80000C6 + .2byte 0 + + .global GPIOPortReadEnable +GPIOPortReadEnable: @ 80000C8 + .2byte 0 + +@ 80000CA + .2byte 0 + +@ 80000CC + .space 0x34 + + .4byte 3 + .4byte 2 + + .ascii "pokemon emerald version" + .space 9 + + .4byte gMonFrontPicTable + .4byte gMonBackPicTable + .4byte gMonPaletteTable + .4byte gMonShinyPaletteTable + .4byte gMonIconTable + .4byte gMonIconPaletteIndices + .4byte gMonIconPaletteTable + .4byte gSpeciesNames + .4byte gMoveNames + .4byte gDecorations + + .4byte 0x00001270, 0x0000139c, 0x00000018, 0x00000988 + .4byte 0x00003b24, 0x00000046, 0x000008e4, 0x000008ac + .4byte 0x00000182 + + .byte 0x07, 0x0a, 0x0a, 0x0a, 0x0c, 0x0c, 0x06, 0x0c + .byte 0x06, 0x10, 0x12, 0x0c, 0x0f, 0x0b, 0x01, 0x08 + + .4byte 0x0000000c, 0x00000f2c, 0x00003d88, 0x00000234 + .4byte 0x00000238, 0x00000009, 0x0000000a, 0x00000000 + .4byte 0x00000008, 0x00000ca8, 0x00000ca8, 0x000031c7 + .4byte 0x000031b3, 0x00000000 + + .4byte gBaseStats + .4byte gAbilityNames + .4byte gAbilityDescriptionPointers + .4byte gItems + .4byte gBattleMoves + .4byte gBallSpriteSheets + .4byte gBallSpritePalettes + + .4byte 0x000000a8, 0x00000864, 0x0000089b + + .byte 0x1e, 0x1e, 0x10, 0x40 + + .4byte 0x0000322e, 0x00000498, 0x000031a8, 0x000031f8 + .4byte 0x00000034, 0x00000000, 0x00000000 + + .arm + .align 2, 0 + .global Init +Init: @ 8000204 + mov r0, PSR_IRQ_MODE + msr cpsr_cf, r0 + ldr sp, sp_irq + mov r0, PSR_SYS_MODE + msr cpsr_cf, r0 + ldr sp, sp_sys + ldr r1, =INTR_VECTOR + adr r0, IntrMain + str r0, [r1] + ldr r1, =AgbMain + 1 + mov lr, pc + bx r1 + b Init + + .align 2, 0 +sp_sys: .word IWRAM_END - 0x1c0 +sp_irq: .word IWRAM_END - 0x60 + + .pool + + .arm + .align 2, 0 + .global IntrMain +IntrMain: @ 8000248 + mov r3, REG_BASE + add r3, r3, 0x200 + ldr r2, [r3, OFFSET_REG_IE - 0x200] + ldrh r1, [r3, OFFSET_REG_IME - 0x200] + mrs r0, spsr + stmdb sp!, {r0-r3,lr} + mov r0, 0 + strh r0, [r3, OFFSET_REG_IME - 0x200] + and r1, r2, r2, lsr 16 + mov r12, 0 + ands r0, r1, INTR_FLAG_VCOUNT + bne IntrMain_FoundIntr + add r12, r12, 0x4 + mov r0, 0x1 + strh r0, [r3, OFFSET_REG_IME - 0x200] + ands r0, r1, INTR_FLAG_SERIAL + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_TIMER3 + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_HBLANK + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_VBLANK + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_TIMER0 + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_TIMER1 + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_TIMER2 + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_DMA0 + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_DMA1 + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_DMA2 + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_DMA3 + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_KEYPAD + bne IntrMain_FoundIntr + add r12, r12, 0x4 + ands r0, r1, INTR_FLAG_GAMEPAK + strbne r0, [r3, OFFSET_REG_SOUNDCNT_X - 0x200] + bne . @ spin +IntrMain_FoundIntr: + strh r0, [r3, OFFSET_REG_IF - 0x200] + bic r2, r2, r0 + ldr r0, =gRfuState + ldr r0, [r0] + ldrb r0, [r0, 0xA] + mov r1, 0x8 + mov r0, r1, lsl r0 + orr r0, r0, INTR_FLAG_GAMEPAK + orr r1, r0, INTR_FLAG_SERIAL | INTR_FLAG_TIMER3 | INTR_FLAG_VCOUNT | INTR_FLAG_HBLANK + and r1, r1, r2 + strh r1, [r3, OFFSET_REG_IE - 0x200] + mrs r3, cpsr + bic r3, r3, PSR_I_BIT | PSR_F_BIT | PSR_MODE_MASK + orr r3, r3, PSR_SYS_MODE + msr cpsr_cf, r3 + ldr r1, =gIntrTable + add r1, r1, r12 + ldr r0, [r1] + stmdb sp!, {lr} + adr lr, IntrMain_RetAddr + bx r0 +IntrMain_RetAddr: + ldmia sp!, {lr} + mrs r3, cpsr + bic r3, r3, PSR_I_BIT | PSR_F_BIT | PSR_MODE_MASK + orr r3, r3, PSR_I_BIT | PSR_IRQ_MODE + msr cpsr_cf, r3 + ldmia sp!, {r0-r3,lr} + strh r2, [r3, OFFSET_REG_IE - 0x200] + strh r1, [r3, OFFSET_REG_IME - 0x200] + msr spsr_cf, r0 + bx lr + + .pool + + .align 2, 0 @ Don't pad with nop. diff --git a/src/libagbsyscall.s b/src/libagbsyscall.s new file mode 100644 index 000000000..d5639f689 --- /dev/null +++ b/src/libagbsyscall.s @@ -0,0 +1,116 @@ + .include "constants/gba_constants.inc" + .include "asm/macros.inc" + + .syntax unified + + .text + + thumb_func_start ArcTan2 +ArcTan2: @ 82E7078 + swi 0xA + bx lr + thumb_func_end ArcTan2 + + thumb_func_start BgAffineSet +@ void BgAffineSet(BgAffineSet_src_data *src, BgAffineSet_dest_data *dest, int entry_count) +BgAffineSet: @ 82E707C + swi 0xE + bx lr + thumb_func_end BgAffineSet + + thumb_func_start CpuFastSet +@ void CpuFastSet(void *src, void *dest, unsigned int mode) +CpuFastSet: @ 82E7080 + swi 0xC + bx lr + thumb_func_end CpuFastSet + + thumb_func_start CpuSet +@ void CpuSet(void *src, void *dest, unsigned int mode) +CpuSet: @ 82E7084 + swi 0xB + bx lr + thumb_func_end CpuSet + + thumb_func_start Div +Div: @ 82E7088 + swi 0x6 + bx lr + thumb_func_end Div + + thumb_func_start LZ77UnCompVram +@ void LZ77UnCompVram(void *src, void *dest) +LZ77UnCompVram: @ 82E708C + swi 0x12 + bx lr + thumb_func_end LZ77UnCompVram + + thumb_func_start LZ77UnCompWram +@ void LZ77UnCompWram(void *src, void *dest) +LZ77UnCompWram: @ 82E7090 + swi 0x11 + bx lr + thumb_func_end LZ77UnCompWram + + thumb_func_start MultiBoot +@ s32 MultiBoot(struct MultiBootParam *mp) +MultiBoot: @ 82E7094 + movs r1, 0x1 + swi 0x25 + bx lr + thumb_func_end MultiBoot + + thumb_func_start ObjAffineSet +ObjAffineSet: @ 82E709C + swi 0xF + bx lr + thumb_func_end ObjAffineSet + + thumb_func_start RLUnCompVram +RLUnCompVram: @ 82E70A0 + swi 0x15 + bx lr + thumb_func_end RLUnCompVram + + thumb_func_start RLUnCompWram +RLUnCompWram: @ 82E70A4 + swi 0x14 + bx lr + thumb_func_end RLUnCompWram + + thumb_func_start RegisterRamReset +@ void RegisterRamReset(int ResetFlags) +RegisterRamReset: @ 82E70A8 + swi 0x1 + bx lr + thumb_func_end RegisterRamReset + + thumb_func_start SoftReset +@ void SoftReset() +SoftReset: @ 82E70AC + ldr r3, =REG_IME + movs r2, 0 + strb r2, [r3] + ldr r1, =0x3007F00 + mov sp, r1 + swi 0x1 + swi 0 + .pool + thumb_func_end SoftReset + + thumb_func_start Sqrt +@ s16 Sqrt(int) +Sqrt: @ 82E70C4 + swi 0x8 + bx lr + thumb_func_end Sqrt + + thumb_func_start VBlankIntrWait +@ void VBlankIntrWait() +VBlankIntrWait: @ 82E70C8 + movs r2, 0 + swi 0x5 + bx lr + thumb_func_end VBlankIntrWait + + .align 2, 0 @ Don't pad with nop. diff --git a/src/libgcnmultiboot.s b/src/libgcnmultiboot.s new file mode 100644 index 000000000..0e418e51f --- /dev/null +++ b/src/libgcnmultiboot.s @@ -0,0 +1,550 @@ +@ This library can be used to download and execute a multi-boot image from +@ a GameCube using the JOY Bus protocol over the link cable. + + .include "asm/macros.inc" + .include "constants/constants.inc" + + .equiv GCMB_STRUCT_BASE_DEST_PTR, 0x20 + .equiv GCMB_STRUCT_CUR_DEST_PTR, 0x24 + .equiv GCMB_STRUCT_SERIAL_INTR_HANDLER, 0x28 + + .equiv ROM_HEADER_NINTENDO_LOGO_OFFSET, 0x4 + + .syntax unified + + .text + + thumb_func_start GameCubeMultiBoot_Hash +GameCubeMultiBoot_Hash: @ 82DED70 + push {r4,lr} + ldr r4, pool_HashVal + eors r3, r1 + movs r2, 0x20 + +GameCubeMultiBoot_Hash_Loop: + lsrs r3, 1 + bcc GameCubeMultiBoot_Hash_SkipEor + + eors r3, r4 + +GameCubeMultiBoot_Hash_SkipEor: + subs r2, 0x1 + bne GameCubeMultiBoot_Hash_Loop + + pop {r4,pc} + thumb_func_end GameCubeMultiBoot_Hash + + thumb_func_start GameCubeMultiBoot_Main +@ void GameCubeMultiBoot_Main(struct GameCubeMultiBoot *mb); +GameCubeMultiBoot_Main: @ 82DED84 + ldr r1, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER] + cmp r1, 0 + beq _082DEDAA + ldrb r1, [r0, 0x1] + adds r1, 0x1 + strb r1, [r0, 0x1] + ldrb r1, [r0, 0x2] + cmp r1, 0x2 + beq _082DEDF4 + ldr r3, pool_InterruptRegs + ldrh r2, [r3, OFFSET_REG_IME - 0x200] + movs r1, 0 + strh r1, [r3, OFFSET_REG_IME - 0x200] + ldrb r1, [r0] + cmp r1, 0xA + bgt _082DEDA8 + adds r1, 0x1 + strb r1, [r0] +_082DEDA8: + strh r2, [r3, OFFSET_REG_IME - 0x200] +_082DEDAA: + bcs GameCubeMultiBoot_Init + ldrb r1, [r0, 0x2] + cmp r1, 0 + bne _082DEDF6 + ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR] + ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR] + subs r1, r2 + beq _082DEE76 + cmp r1, 0xA0 + bcc _082DEE76 + push {r4-r6} + movs r1, 0x98 + adds r2, ROM_HEADER_NINTENDO_LOGO_OFFSET + ldr r4, pool_NintendoLogo +_082DEDC6: + ldm r2!, {r5} + ldm r4!, {r6} + cmp r5, r6 + bne _082DEDDC + subs r1, 0x4 + bne _082DEDC6 + ldm r2!, {r5} + ldm r4!, {r6} + eors r5, r6 + lsrs r5, 8 + str r2, [r0, GCMB_STRUCT_BASE_DEST_PTR] +_082DEDDC: + pop {r4-r6} + bne GameCubeMultiBoot_Init + movs r1, 0x1 + strb r1, [r0, 0x2] + ldr r1, [r0, 0x4] + ldr r2, [r0, 0x8] + eors r1, r2 + str r1, [r0, 0x18] + ldr r2, pool_Kawa + muls r1, r2 + adds r1, 0x1 + str r1, [r0, 0x14] +_082DEDF4: + bx lr +_082DEDF6: + ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR] + mov r12, r1 + ldr r3, [r0, 0x18] + push {r4-r7} + ldr r4, [r0, GCMB_STRUCT_BASE_DEST_PTR] + ldr r5, pool_Kawa + ldr r6, [r0, 0x14] + ldr r7, pool_HashVal +_082DEE06: + cmp r4, r12 + bcs _082DEE26 + ldr r1, [r4] + eors r1, r6 + adds r1, r3 + stm r4!, {r1} + eors r3, r1 + movs r2, 0x20 +_082DEE16: + lsrs r3, 1 + bcc _082DEE1C + eors r3, r7 +_082DEE1C: + subs r2, 0x1 + bne _082DEE16 + muls r6, r5 + adds r6, 0x1 + b _082DEE06 +_082DEE26: + str r4, [r0, GCMB_STRUCT_BASE_DEST_PTR] + str r6, [r0, 0x14] + pop {r4-r7} + str r3, [r0, 0x18] + ldrh r1, [r0, 0x12] + cmp r1, 0 + bne _082DEE76 + ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR] + ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR] + cmp r1, r2 + bne _082DEE76 + ldr r1, [r0, 0xC] + cmp r1, 0 + beq _082DEE60 + ldrh r1, [r0, 0x10] + cmp r1, 0 + beq _082DEDF4 + mov r12, lr + movs r1, 0xBB + ldr r3, [r0, 0xC] + bl GameCubeMultiBoot_Hash + ldrh r1, [r0, 0x10] + mov lr, r12 + subs r1, r3 + bne GameCubeMultiBoot_Init + movs r1, 0x2 + strb r1, [r0, 0x2] + bx lr +_082DEE60: + mov r12, lr + ldrb r1, [r0, 0x3] + lsls r1, 24 + subs r1, 0x1 + str r1, [r0, 0xC] + bl GameCubeMultiBoot_Hash + lsls r3, 8 + adds r3, 0xFF + str r3, [r0, 0x1C] + bx r12 +_082DEE76: + bx lr + thumb_func_end GameCubeMultiBoot_Main + + .align 2, 0 + +pool_HashVal: .4byte 0xa1c1 + +pool_Kawa: .ascii "Kawa" @ name of BIOS developer + +pool_NintendoLogo: .4byte RomHeaderNintendoLogo + + thumb_func_start GameCubeMultiBoot_ExecuteProgram +@ void GameCubeMultiBoot_ExecuteProgram(struct GameCubeMultiBoot *mb); +GameCubeMultiBoot_ExecuteProgram: @ 82DEE84 + ldrb r1, [r0, 0x2] + cmp r1, 0x2 + bne GameCubeMultiBoot_ExecuteProgram_Fail + ldr r3, pool_InterruptRegs + movs r1, 0 + strh r1, [r3, OFFSET_REG_IME - 0x200] + ldr r1, pool_MultiBootLoadAddr + adds r1, 0xC0 + bx r1 +GameCubeMultiBoot_ExecuteProgram_Fail: + bx lr + thumb_func_end GameCubeMultiBoot_ExecuteProgram + + thumb_func_start GameCubeMultiBoot_Init +@ void GameCubeMultiBoot_Init(struct GameCubeMultiBoot *mb); +GameCubeMultiBoot_Init: @ 82DEE98 + ldr r3, pool_InterruptRegs + +@ Save IME register. + ldrh r2, [r3, OFFSET_REG_IME - 0x200] + +@ Disable interrupts. + movs r1, 0 + strh r1, [r3, OFFSET_REG_IME - 0x200] + +@ Set the handler to the "Stop" routine. +@ Unless the first command that is received is a device reset command, the +@ "Stop" routine will be executed and no further commands will be processed. + adr r3, GcMbIntrHandler_Stop + str r3, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER] + + ldrb r3, [r0, 0x3] + push {r3} + ldrb r3, [r0, 0x1] + push {r0,r3} + + adds r3, r0, 0 + adds r3, GCMB_STRUCT_BASE_DEST_PTR + +@ clear all but the last 3 fields of the struct +GameCubeMultiBoot_Init_ClearStructLoop: + stm r0!, {r1} + cmp r0, r3 + blo GameCubeMultiBoot_Init_ClearStructLoop + + pop {r0,r3} + lsrs r3, 1 + strb r3, [r0, 0x3] + pop {r3} + strb r3, [r0, 0x1] + + ldr r3, pool_SerialRegs + +@ Turn off JOY Bus mode. + lsls r0, r3, 10 + strh r0, [r3, OFFSET_REG_RCNT - 0x120] + +@ Turn on JOY Bus mode. + movs r0, 0xC0 + lsls r0, 8 + strh r0, [r3, OFFSET_REG_RCNT - 0x120] + +@ Init JOY Bus registers. + movs r0, 0x47 + strh r0, [r3, OFFSET_REG_JOYCNT - 0x120] + strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120] + + ldr r3, pool_InterruptRegs + +@ Acknowledge serial interrupt. + movs r0, INTR_FLAG_SERIAL + strh r0, [r3, OFFSET_REG_IF - 0x200] + +@ Enable serial interrupt. + ldrh r1, [r3, OFFSET_REG_IE - 0x200] + orrs r1, r0 + strh r1, [r3, OFFSET_REG_IE - 0x200] + +@ Restore IME register. + strh r2, [r3, OFFSET_REG_IME - 0x200] + + bx lr + thumb_func_end GameCubeMultiBoot_Init + + non_word_aligned_thumb_func_start GameCubeMultiBoot_HandleSerialInterrupt +@ void GameCubeMultiBoot_HandleSerialInterrupt(struct GameCubeMultiBoot *mb); +GameCubeMultiBoot_HandleSerialInterrupt: @ 82DEEE2 + ldr r3, pool_SerialRegs + +@ Acknowledge reset/receive/send flags. + ldrh r1, [r3, OFFSET_REG_JOYCNT - 0x120] + strh r1, [r3, OFFSET_REG_JOYCNT - 0x120] + + movs r2, 0 + strb r2, [r0] + + ldr r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER] + cmp r2, 0 + beq GameCubeMultiBoot_HandleSerialInterruptDone + + lsrs r1, 1 @ was a device reset command received? + bcs GameCubeMultiBoot_BeginHandshake @ branch if so + + mov pc, r2 + + .align 2, 0 + +@ Zero the status and the interrupt handler pointer. +@ Commands from the GameCube will not be processed after this is executed +@ unless GameCubeMultiBoot_Init() is called again. +GcMbIntrHandler_Stop: + movs r2, 0 + strh r2, [r3, OFFSET_REG_JOYSTAT - 0x120] + +GameCubeMultiBoot_SetInterruptHandler: + str r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER] + +GameCubeMultiBoot_ReadVCount: + ldr r3, pool_RegDispstat + ldrh r1, [r3, OFFSET_REG_VCOUNT - OFFSET_REG_DISPSTAT] + strb r1, [r0, 0x3] + +GameCubeMultiBoot_HandleSerialInterruptDone: + bx lr + +GameCubeMultiBoot_BeginHandshake: + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] + ldr r1, pool_RubyUSAGameCode + str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] + movs r1, 0x10 + strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120] + ldrb r1, [r0, 0x3] + strb r1, [r0, 0x9] + ldrb r1, [r0, 0x2] + cmp r1, 0 + bne GcMbIntrHandler_Stop + ldr r1, pool_MultiBootLoadAddr + str r1, [r0, GCMB_STRUCT_BASE_DEST_PTR] + str r1, [r0, GCMB_STRUCT_CUR_DEST_PTR] + adr r2, GcMbIntrHandler_CheckGameCodeSent + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_CheckGameCodeSent: @ 82DEF24 + lsls r1, 31 + bcc GcMbIntrHandler_Stop @ stop if send failed + bmi GameCubeMultiBoot_CheckHandshakeResponse @ branch if receive is complete + +@ If the response hasn't been fully received yet, +@ check again upon the next interrupt. + adr r2, GcMbIntrHandler_CheckHandshakeResponse + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_CheckHandshakeResponse: @ 82DEF30 + lsrs r1, 1 @ is receive complete? + bcc GcMbIntrHandler_Stop @ stop if not + +GameCubeMultiBoot_CheckHandshakeResponse: + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] + ldr r2, pool_RubyUSAGameCode + cmp r1, r2 + bne GcMbIntrHandler_Stop @ stop if the GameCube didn't reply with the same game code + ldrb r1, [r0, 0x3] + strb r1, [r0, 0xB] + adr r2, GcMbIntrHandler_82DEF44 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DEF44: @ 82DEF44 + lsrs r1, 1 @ is receive complete? + bcc GcMbIntrHandler_Stop @ branch if not + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] + lsrs r2, r1, 24 + cmp r2, 0xDD + bne GcMbIntrHandler_Stop + str r1, [r0, 0x4] + ldrb r1, [r0, 0x1] + strb r1, [r0, 0xA] + movs r2, 0 + movs r3, 0 + ldr r1, [r0, 0x8] + lsrs r1, 8 +_082DEF5E: + lsrs r1, 1 + adcs r2, r3 + cmp r1, 0 + bne _082DEF5E + cmp r2, 0xE + bgt _082DEF70 + cmp r2, 0x7 + bge _082DEF72 + movs r1, 0xFF +_082DEF70: + strb r1, [r0, 0xA] +_082DEF72: + ldr r1, [r0, 0x8] + adds r1, 0xEE + ldr r3, pool_SerialRegs + str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] + movs r1, 0x30 + strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120] + adr r2, GcMbIntrHandler_82DEF84 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DEF84: @ 82DEF84 + lsls r1, 31 + bcc GcMbIntrHandler_Stop @ stop if send failed + bmi _082DEF94 @ branch if receive is complete + adr r2, GcMbIntrHandler_82DEF90 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DEF90: @ 82DEF90 + lsrs r1, 1 @ is receive complete? + bcc GcMbIntrHandler_Stop @ branch if not +_082DEF94: + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] + ldr r2, _082DF034 + cmp r1, r2 + bhs GcMbIntrHandler_Stop + adds r1, 0x1 + adds r1, r1 + strh r1, [r0, 0x12] + ldrb r1, [r0, 0x2] + cmp r1, 0 +_082DEFA6: + bne GcMbIntrHandler_Stop + ldr r1, pool_MultiBootLoadAddr + str r1, [r0, GCMB_STRUCT_BASE_DEST_PTR] + str r1, [r0, GCMB_STRUCT_CUR_DEST_PTR] + adr r2, GcMbIntrHandler_82DEFB4 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DEFB4: @ 82DEFB4 + lsrs r1, 1 @ is receive complete? + bcc GcMbIntrHandler_Stop @ branch if not + ldr r2, [r0, GCMB_STRUCT_CUR_DEST_PTR] + movs r1, 0x4 + ands r1, r2 + adds r1, 0x8 + lsls r1, 2 + strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120] + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] + stm r2!, {r1} + str r2, [r0, GCMB_STRUCT_CUR_DEST_PTR] + ldrh r1, [r0, 0x12] + subs r1, 0x1 + strh r1, [r0, 0x12] + bne GameCubeMultiBoot_ReadVCount + +_082DEFD2: + ldrb r1, [r0, 0x1] + lsls r1, 8 + adds r1, 0xCC + str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] + adr r2, _082DEFE0 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +_082DEFE0: + lsls r1, 31 + +_082DEFE2: + bcc GcMbIntrHandler_Stop + ldr r1, [r0, 0x1C] + cmp r1, 0 + beq _082DEFD2 + str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120] + adr r2, GcMbIntrHandler_82DEFF0 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DEFF0: @ 82DEFF0 + lsls r1, 31 + bcc _082DEFE2 @ branch if send failed + bmi _082DF000 @ branch if receive is complete + adr r2, GcMbIntrHandler_82DEFFC + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DEFFC: @ 82DEFFC + lsrs r1, 1 @ is receive complete? + bcc _082DEFE2 @ branch if not + +_082DF000: + ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120] + lsrs r2, r1, 24 + cmp r2, 0xBB + bne _082DEFA6 + strh r1, [r0, 0x10] + adr r2, GcMbIntrHandler_82DF010 + b GameCubeMultiBoot_SetInterruptHandler + + .align 2, 0 + +GcMbIntrHandler_82DF010: @ 82DF010 + b GcMbIntrHandler_Stop + + thumb_func_end GameCubeMultiBoot_HandleSerialInterrupt + + non_word_aligned_thumb_func_start GameCubeMultiBoot_Quit +@ void GameCubeMultiBoot_Quit(); +GameCubeMultiBoot_Quit: @ 82DF012 + ldr r3, pool_InterruptRegs + +@ Save IME register. + ldrh r2, [r3, OFFSET_REG_IME - 0x200] + +@ Disable interrupts. + movs r1, 0 + strh r1, [r3, OFFSET_REG_IME - 0x200] + + ldr r3, pool_SerialRegs + +@ Acknowledge all JOYCNT flags. + movs r0, 0x7 + strh r0, [r3, OFFSET_REG_JOYCNT - 0x120] + +@ Turn off JOY Bus mode. + lsls r0, r3, 10 + strh r0, [r3, OFFSET_REG_RCNT - 0x120] @ store 0x8000 + + ldr r3, pool_InterruptRegs + +@ Acknowledge serial interrupt. + movs r0, INTR_FLAG_SERIAL + strh r0, [r3, OFFSET_REG_IF - 0x200] + +@ Disable serial interrupt. + ldrh r1, [r3, OFFSET_REG_IE - 0x200] + bics r1, r0 + strh r1, [r3, OFFSET_REG_IE - 0x200] + +@ Restore IME register. + strh r2, [r3, OFFSET_REG_IME - 0x200] + + bx lr + thumb_func_end GameCubeMultiBoot_Quit + + .align 2, 0 + +_082DF034: .4byte 0x4000 + +pool_InterruptRegs: .4byte REG_BASE + 0x200 + +pool_SerialRegs: .4byte REG_BASE + 0x120 + +pool_RegDispstat: .4byte REG_DISPSTAT + +pool_RubyUSAGameCode: .ascii "AXVE" + +pool_MultiBootLoadAddr: .4byte EWRAM_START + + .align 2, 0 @ Don't pad with nop. diff --git a/src/m4a_1.s b/src/m4a_1.s new file mode 100644 index 000000000..cab4ed174 --- /dev/null +++ b/src/m4a_1.s @@ -0,0 +1,1934 @@ + .include "asm/macros.inc" + .include "constants/gba_constants.inc" + .include "constants/m4a_constants.inc" + + .syntax unified + + .text + + thumb_func_start umul3232H32 +umul3232H32: + adr r2, __umul3232H32 + bx r2 + .arm +__umul3232H32: + umull r2, r3, r0, r1 + add r0, r3, 0 + bx lr + thumb_func_end umul3232H32 + + thumb_func_start SoundMain +SoundMain: + ldr r0, lt_SOUND_INFO_PTR + ldr r0, [r0] + ldr r2, lt_ID_NUMBER + ldr r3, [r0, o_SoundInfo_ident] + cmp r2, r3 + beq SoundMain_1 + bx lr @ Exit the function if ident doesn't match ID_NUMBER. +SoundMain_1: + adds r3, 1 + str r3, [r0, o_SoundInfo_ident] + push {r4-r7,lr} + mov r1, r8 + mov r2, r9 + mov r3, r10 + mov r4, r11 + push {r0-r4} + sub sp, 0x18 + ldrb r1, [r0, o_SoundInfo_maxLines] + cmp r1, 0 @ if maxLines is 0, there is no maximum + beq SoundMain_3 + ldr r2, lt_REG_VCOUNT + ldrb r2, [r2] + cmp r2, VCOUNT_VBLANK + bhs SoundMain_2 + adds r2, TOTAL_SCANLINES +SoundMain_2: + adds r1, r2 +SoundMain_3: + str r1, [sp, 0x14] + ldr r3, [r0, o_SoundInfo_func] + cmp r3, 0 + beq SoundMain_4 + ldr r0, [r0, o_SoundInfo_intp] + bl _081DD25E + ldr r0, [sp, 0x18] +SoundMain_4: + ldr r3, [r0, o_SoundInfo_CgbSound] + bl _081DD25E + ldr r0, [sp, 0x18] + ldr r3, [r0, o_SoundInfo_pcmSamplesPerVBlank] + mov r8, r3 + ldr r5, lt_o_SoundInfo_pcmBuffer + adds r5, r0 + ldrb r4, [r0, o_SoundInfo_pcmDmaCounter] + subs r7, r4, 1 + bls SoundMain_5 + ldrb r1, [r0, o_SoundInfo_pcmDmaPeriod] + subs r1, r7 + mov r2, r8 + muls r2, r1 + adds r5, r2 +SoundMain_5: + str r5, [sp, 0x8] + ldr r6, lt_PCM_DMA_BUF_SIZE + ldr r3, lt_SoundMainRAM_Buffer + bx r3 + + .align 2, 0 +lt_SOUND_INFO_PTR: .word SOUND_INFO_PTR +lt_ID_NUMBER: .word ID_NUMBER +lt_SoundMainRAM_Buffer: .word SoundMainRAM_Buffer + 1 +lt_REG_VCOUNT: .word REG_VCOUNT +lt_o_SoundInfo_pcmBuffer: .word o_SoundInfo_pcmBuffer +lt_PCM_DMA_BUF_SIZE: .word PCM_DMA_BUF_SIZE + thumb_func_end SoundMain + + thumb_func_start SoundMainRAM +SoundMainRAM: + ldrb r3, [r0, o_SoundInfo_reverb] + cmp r3, 0 + beq SoundMainRAM_NoReverb + adr r1, SoundMainRAM_Reverb + bx r1 + .arm +SoundMainRAM_Reverb: + cmp r4, 0x2 + addeq r7, r0, o_SoundInfo_pcmBuffer + addne r7, r5, r8 + mov r4, r8 +_081DCEC4: + ldrsb r0, [r5, r6] + ldrsb r1, [r5] + add r0, r0, r1 + ldrsb r1, [r7, r6] + add r0, r0, r1 + ldrsb r1, [r7], 0x1 + add r0, r0, r1 + mul r1, r0, r3 + mov r0, r1, asr 9 + tst r0, 0x80 + addne r0, r0, 0x1 + strb r0, [r5, r6] + strb r0, [r5], 0x1 + subs r4, r4, 0x1 + bgt _081DCEC4 + adr r0, _081DCF36 + 1 @ plus 1 because THUMB + bx r0 + .thumb +SoundMainRAM_NoReverb: + movs r0, 0 + mov r1, r8 + adds r6, r5 + lsrs r1, 3 + bcc SoundMainRAM_NoReverb_Ok + stm r5!, {r0} + stm r6!, {r0} +SoundMainRAM_NoReverb_Ok: + lsrs r1, 1 + bcc SoundMainRAM_NoReverb_Loop + stm r5!, {r0} + stm r6!, {r0} + stm r5!, {r0} + stm r6!, {r0} +SoundMainRAM_NoReverb_Loop: + stm r5!, {r0} + stm r6!, {r0} + stm r5!, {r0} + stm r6!, {r0} + stm r5!, {r0} + stm r6!, {r0} + stm r5!, {r0} + stm r6!, {r0} + subs r1, 1 + bgt SoundMainRAM_NoReverb_Loop +_081DCF36: + ldr r4, [sp, 0x18] + ldr r0, [r4, o_SoundInfo_divFreq] + mov r12, r0 + ldrb r0, [r4, o_SoundInfo_maxChans] + adds r4, o_SoundInfo_chans + +SoundMainRAM_ChanLoop: + str r0, [sp, 0x4] + ldr r3, [r4, o_SoundChannel_wav] + ldr r0, [sp, 0x14] + cmp r0, 0 + beq _081DCF60 + ldr r1, =REG_VCOUNT + ldrb r1, [r1] + cmp r1, VCOUNT_VBLANK + bhs _081DCF54 + adds r1, TOTAL_SCANLINES +_081DCF54: + cmp r1, r0 + blo _081DCF60 + b _081DD24A + + .pool + +_081DCF60: + ldrb r6, [r4, o_SoundChannel_status] + movs r0, 0xC7 + tst r0, r6 + bne _081DCF6A + b _081DD240 +_081DCF6A: + movs r0, 0x80 + tst r0, r6 + beq _081DCFA0 + movs r0, 0x40 + tst r0, r6 + bne _081DCFB0 + movs r6, 0x3 + strb r6, [r4, o_SoundChannel_status] + adds r0, r3, 0 + adds r0, 0x10 + ldr r1, [r4, o_SoundChannel_ct] + adds r0, r1 + str r0, [r4, o_SoundChannel_cp] + ldr r0, [r3, 0xC] + subs r0, r1 + str r0, [r4, o_SoundChannel_ct] + movs r5, 0 + strb r5, [r4, o_SoundChannel_ev] + str r5, [r4, o_SoundChannel_fw] + ldrb r2, [r3, 0x3] + movs r0, 0xC0 + tst r0, r2 + beq _081DCFF8 + movs r0, 0x10 + orrs r6, r0 + strb r6, [r4, o_SoundChannel_status] + b _081DCFF8 +_081DCFA0: + ldrb r5, [r4, o_SoundChannel_ev] + movs r0, 0x4 + tst r0, r6 + beq _081DCFB6 + ldrb r0, [r4, o_SoundChannel_iel] + subs r0, 1 + strb r0, [r4, o_SoundChannel_iel] + bhi _081DD006 +_081DCFB0: + movs r0, 0 + strb r0, [r4, o_SoundChannel_status] + b _081DD240 +_081DCFB6: + movs r0, 0x40 + tst r0, r6 + beq _081DCFD6 + ldrb r0, [r4, o_SoundChannel_release] + muls r5, r0 + lsrs r5, 8 + ldrb r0, [r4, o_SoundChannel_iev] + cmp r5, r0 + bhi _081DD006 +_081DCFC8: + ldrb r5, [r4, o_SoundChannel_iev] + cmp r5, 0 + beq _081DCFB0 + movs r0, 0x4 + orrs r6, r0 + strb r6, [r4, o_SoundChannel_status] + b _081DD006 +_081DCFD6: + movs r2, 0x3 + ands r2, r6 + cmp r2, 0x2 + bne _081DCFF4 + ldrb r0, [r4, o_SoundChannel_decay] + muls r5, r0 + lsrs r5, 8 + ldrb r0, [r4, o_SoundChannel_sustain] + cmp r5, r0 + bhi _081DD006 + adds r5, r0, 0 + beq _081DCFC8 + subs r6, 0x1 + strb r6, [r4, o_SoundChannel_status] + b _081DD006 +_081DCFF4: + cmp r2, 0x3 + bne _081DD006 +_081DCFF8: + ldrb r0, [r4, o_SoundChannel_attack] + adds r5, r0 + cmp r5, 0xFF + bcc _081DD006 + movs r5, 0xFF + subs r6, 0x1 + strb r6, [r4, o_SoundChannel_status] +_081DD006: + strb r5, [r4, o_SoundChannel_ev] + ldr r0, [sp, 0x18] + ldrb r0, [r0, o_SoundChannel_release] + adds r0, 0x1 + muls r0, r5 + lsrs r5, r0, 4 + ldrb r0, [r4, o_SoundChannel_rightVolume] + muls r0, r5 + lsrs r0, 8 + strb r0, [r4, o_SoundChannel_er] + ldrb r0, [r4, o_SoundChannel_leftVolume] + muls r0, r5 + lsrs r0, 8 + strb r0, [r4, o_SoundChannel_el] + movs r0, 0x10 + ands r0, r6 + str r0, [sp, 0x10] + beq _081DD03A + adds r0, r3, 0 + adds r0, 0x10 + ldr r1, [r3, 0x8] + adds r0, r1 + str r0, [sp, 0xC] + ldr r0, [r3, 0xC] + subs r0, r1 + str r0, [sp, 0x10] +_081DD03A: + ldr r5, [sp, 0x8] + ldr r2, [r4, o_SoundChannel_ct] + ldr r3, [r4, o_SoundChannel_cp] + adr r0, _081DD044 + bx r0 + .arm +_081DD044: + str r8, [sp] + ldr r9, [r4, o_SoundChannel_fw] + ldrb r10, [r4, o_SoundChannel_er] + ldrb r11, [r4, o_SoundChannel_el] + ldrb r0, [r4, o_SoundChannel_type] + tst r0, 0x30 + beq _081DD068 + bl sub_82DF49C + b _081DD228 +_081DD068: + mov r10, r10, lsl 16 + mov r11, r11, lsl 16 + ldrb r0, [r4, o_SoundChannel_type] + tst r0, 0x8 + beq _081DD19C +_081DD07C: + cmp r2, 0x4 + ble _081DD0EC + subs r2, r2, r8 + movgt r9, 0 + bgt _081DD0A8 + mov r9, r8 + add r2, r2, r8 + sub r8, r2, 0x4 + sub r9, r9, r8 + ands r2, r2, 0x3 + moveq r2, 0x4 +_081DD0A8: + ldr r6, [r5] + ldr r7, [r5, 0x630] +_081DD0B0: + ldrsb r0, [r3], 0x1 + mul r1, r10, r0 + bic r1, r1, 0xFF0000 + add r6, r1, r6, ror 8 + mul r1, r11, r0 + bic r1, r1, 0xFF0000 + add r7, r1, r7, ror 8 + adds r5, r5, 0x40000000 + bcc _081DD0B0 + str r7, [r5, 0x630] + str r6, [r5], 0x4 + subs r8, r8, 0x4 + bgt _081DD0A8 + adds r8, r8, r9 + beq _081DD22C +_081DD0EC: + ldr r6, [r5] + ldr r7, [r5, 0x630] +_081DD0F4: + ldrsb r0, [r3], 0x1 + mul r1, r10, r0 + bic r1, r1, 0xFF0000 + add r6, r1, r6, ror 8 + mul r1, r11, r0 + bic r1, r1, 0xFF0000 + add r7, r1, r7, ror 8 + subs r2, r2, 0x1 + beq _081DD164 +_081DD118: + adds r5, r5, 0x40000000 + bcc _081DD0F4 + str r7, [r5, 0x630] + str r6, [r5], 0x4 + subs r8, r8, 0x4 + bgt _081DD07C + b _081DD22C +_081DD134: + ldr r0, [sp, 0x18] + cmp r0, 0 + beq _081DD158 + ldr r3, [sp, 0x14] + rsb lr, r2, 0 +_081DD148: + adds r2, r0, r2 + bgt _081DD1FC + sub lr, lr, r0 + b _081DD148 +_081DD158: + pop {r4,r12} + mov r2, 0 + b _081DD174 +_081DD164: + ldr r2, [sp, 0x10] + cmp r2, 0 + ldrne r3, [sp, 0xC] + bne _081DD118 +_081DD174: + strb r2, [r4, o_SoundChannel_status] + mov r0, r5, lsr 30 + bic r5, r5, 0xC0000000 + rsb r0, r0, 0x3 + mov r0, r0, lsl 3 + mov r6, r6, ror r0 + mov r7, r7, ror r0 + str r7, [r5, 0x630] + str r6, [r5], 0x4 + b _081DD234 +_081DD19C: + push {r4,r12} + ldr r1, [r4, o_SoundChannel_freq] + mul r4, r12, r1 + ldrsb r0, [r3] + ldrsb r1, [r3, 0x1]! + sub r1, r1, r0 +_081DD1B4: + ldr r6, [r5] + ldr r7, [r5, 0x630] +_081DD1BC: + mul lr, r9, r1 + add lr, r0, lr, asr 23 + mul r12, r10, lr + bic r12, r12, 0xFF0000 + add r6, r12, r6, ror 8 + mul r12, r11, lr + bic r12, r12, 0xFF0000 + add r7, r12, r7, ror 8 + add r9, r9, r4 + movs lr, r9, lsr 23 + beq _081DD208 + bic r9, r9, 0x3F800000 + subs r2, r2, lr + ble _081DD134 + subs lr, lr, 0x1 + addeq r0, r0, r1 +_081DD1FC: + ldrsbne r0, [r3, lr]! + ldrsb r1, [r3, 0x1]! + sub r1, r1, r0 +_081DD208: + adds r5, r5, 0x40000000 + bcc _081DD1BC + str r7, [r5, 0x630] + str r6, [r5], 0x4 + subs r8, r8, 0x4 + bgt _081DD1B4 + sub r3, r3, 0x1 + pop {r4,r12} +_081DD228: + str r9, [r4, o_SoundChannel_fw] +_081DD22C: + str r2, [r4, o_SoundChannel_ct] + str r3, [r4, o_SoundChannel_cp] +_081DD234: + ldr r8, [sp] + add r0, pc, 0x1 + bx r0 + .thumb +_081DD240: + ldr r0, [sp, 0x4] + subs r0, 1 + ble _081DD24A + adds r4, SoundChannel_size + b SoundMainRAM_ChanLoop +_081DD24A: + ldr r0, [sp, 0x18] + ldr r3, =ID_NUMBER + str r3, [r0] + add sp, 0x1C + pop {r0-r7} + mov r8, r0 + mov r9, r1 + mov r10, r2 + mov r11, r3 + pop {r3} +_081DD25E: + bx r3 + .pool + thumb_func_end SoundMainRAM + + arm_func_start sub_82DF49C +sub_82DF49C: + ldr r6, [r4, o_SoundChannel_wav] + ldrb r0, [r4, o_SoundChannel_status] + tst r0, 0x20 + bne _081DD2B4 + orr r0, r0, 0x20 + strb r0, [r4, o_SoundChannel_status] + ldrb r0, [r4, o_SoundChannel_type] + tst r0, 0x10 + beq _081DD29C + ldr r1, [r6, 0xC] + add r1, r1, r6, lsl 1 + add r1, r1, 0x20 + sub r3, r1, r3 + str r3, [r4, o_SoundChannel_cp] +_081DD29C: + ldrh r0, [r6] + cmp r0, 0 + beq _081DD2B4 + sub r3, r3, r6 + sub r3, r3, 0x10 + str r3, [r4, o_SoundChannel_cp] +_081DD2B4: + push {r8,r12,lr} + mov r10, r10, lsl 16 + mov r11, r11, lsl 16 + ldr r1, [r4, o_SoundChannel_freq] + ldrb r0, [r4, o_SoundChannel_type] + tst r0, 0x8 + movne r8, 0x800000 + muleq r8, r12, r1 + ldrh r0, [r6] + cmp r0, 0 + beq _081DD468 + mov r0, 0xFF000000 + str r0, [r4, o_SoundChannel_xpi] + ldrb r0, [r4, o_SoundChannel_type] + tst r0, 0x10 + bne _081DD3C0 + bl sub_82DF758 + mov r0, r1 + add r3, r3, 0x1 + bl sub_82DF758 + sub r1, r1, r0 +_081DD308: + ldr r6, [r5] + ldr r7, [r5, 0x630] +_081DD310: + mul lr, r9, r1 + add lr, r0, lr, asr 23 + mul r12, r10, lr + bic r12, r12, 0xFF0000 + add r6, r12, r6, ror 8 + mul r12, r11, lr + bic r12, r12, 0xFF0000 + add r7, r12, r7, ror 8 + add r9, r9, r8 + movs lr, r9, lsr 23 + beq _081DD370 + bic r9, r9, 0x3F800000 + subs r2, r2, lr + ble _081DD398 + subs lr, lr, 0x1 + bne _081DD358 + add r0, r0, r1 + b _081DD364 +_081DD358: + add r3, r3, lr + bl sub_82DF758 + mov r0, r1 +_081DD364: + add r3, r3, 0x1 + bl sub_82DF758 + sub r1, r1, r0 +_081DD370: + adds r5, r5, 0x40000000 + bcc _081DD310 + str r7, [r5, 0x630] + str r6, [r5], 0x4 + ldr r6, [sp] + subs r6, r6, 0x4 + str r6, [sp] + bgt _081DD308 + sub r3, r3, 0x1 + b _081DD4F0 +_081DD398: + ldr r0, [sp, 0x1C] + cmp r0, 0 + beq _081DD4F4 + ldr r3, [r4, o_SoundChannel_wav] + ldr r3, [r3, 0x8] + rsb lr, r2, 0 +_081DD3B0: + adds r2, r2, r0 + bgt _081DD358 + sub lr, lr, r0 + b _081DD3B0 +_081DD3C0: + sub r3, r3, 0x1 + bl sub_82DF758 + mov r0, r1 + sub r3, r3, 0x1 + bl sub_82DF758 + sub r1, r1, r0 +_081DD3D8: + ldr r6, [r5] + ldr r7, [r5, 0x630] +_081DD3E0: + mul lr, r9, r1 + add lr, r0, lr, asr 23 + mul r12, r10, lr + bic r12, r12, 0xFF0000 + add r6, r12, r6, ror 8 + mul r12, r11, lr + bic r12, r12, 0xFF0000 + add r7, r12, r7, ror 8 + add r9, r9, r8 + movs lr, r9, lsr 23 + beq _081DD440 + bic r9, r9, 0x3F800000 + subs r2, r2, lr + ble _081DD4F4 + subs lr, lr, 0x1 + bne _081DD428 + add r0, r0, r1 + b _081DD434 +_081DD428: + sub r3, r3, lr + bl sub_82DF758 + mov r0, r1 +_081DD434: + sub r3, r3, 0x1 + bl sub_82DF758 + sub r1, r1, r0 +_081DD440: + adds r5, r5, 0x40000000 + bcc _081DD3E0 + str r7, [r5, 0x630] + str r6, [r5], 0x4 + ldr r6, [sp] + subs r6, r6, 0x4 + str r6, [sp] + bgt _081DD3D8 + add r3, r3, 0x2 + b _081DD4F0 +_081DD468: + ldrb r0, [r4, o_SoundChannel_type] + tst r0, 0x10 + beq _081DD4F0 + ldrsb r0, [r3, -0x1]! + ldrsb r1, [r3, -0x1] + sub r1, r1, r0 +_081DD480: + ldr r6, [r5] + ldr r7, [r5, 0x630] +_081DD488: + mul lr, r9, r1 + add lr, r0, lr, asr 23 + mul r12, r10, lr + bic r12, r12, 0xFF0000 + add r6, r12, r6, ror 8 + mul r12, r11, lr + bic r12, r12, 0xFF0000 + add r7, r12, r7, ror 8 + add r9, r9, r8 + movs lr, r9, lsr 23 + beq _081DD4CC + bic r9, r9, 0x3F800000 + subs r2, r2, lr + ble _081DD4F4 + ldrsb r0, [r3, -lr]! + ldrsb r1, [r3, -0x1] + sub r1, r1, r0 +_081DD4CC: + adds r5, r5, 0x40000000 + bcc _081DD488 + str r7, [r5, 0x630] + str r6, [r5], 0x4 + ldr r6, [sp] + subs r6, r6, 0x4 + str r6, [sp] + bgt _081DD480 + add r3, r3, 0x1 +_081DD4F0: + pop {r8,r12,pc} +_081DD4F4: + mov r2, 0 + strb r2, [r4, o_SoundChannel_status] + mov r0, r5, lsr 30 + bic r5, r5, 0xC0000000 + rsb r0, r0, 0x3 + mov r0, r0, lsl 3 + mov r6, r6, ror r0 + mov r7, r7, ror r0 + str r7, [r5, 0x630] + str r6, [r5], 0x4 + pop {r8,r12,pc} + arm_func_end sub_82DF49C + + arm_func_start sub_82DF758 +sub_82DF758: + push {r0,r2,r5-r7,lr} + mov r0, r3, lsr 6 + ldr r1, [r4, o_SoundChannel_xpi] + cmp r0, r1 + beq _081DD594 + str r0, [r4, o_SoundChannel_xpi] + mov r1, 0x21 + mul r2, r1, r0 + ldr r1, [r4, o_SoundChannel_wav] + add r2, r2, r1 + add r2, r2, 0x10 + ldr r5, =gUnknown_03001300 + ldr r6, =gDeltaEncodingTable + mov r7, 0x40 + ldrb lr, [r2], 1 + strb lr, [r5], 1 + ldrb r1, [r2], 1 + b _081DD57C +_081DD568: + ldrb r1, [r2], 1 + mov r0, r1, lsr 4 + ldrsb r0, [r6, r0] + add lr, lr, r0 + strb lr, [r5], 1 +_081DD57C: + and r0, r1, 0xF + ldrsb r0, [r6, r0] + add lr, lr, r0 + strb lr, [r5], 1 + subs r7, r7, 2 + bgt _081DD568 +_081DD594: + ldr r5, =gUnknown_03001300 + and r0, r3, 0x3F + ldrsb r1, [r5, r0] + pop {r0,r2,r5-r7,pc} + .pool + arm_func_end sub_82DF758 + + thumb_func_start SoundMainBTM +SoundMainBTM: + mov r12, r4 + movs r1, 0 + movs r2, 0 + movs r3, 0 + movs r4, 0 + stm r0!, {r1-r4} + stm r0!, {r1-r4} + stm r0!, {r1-r4} + stm r0!, {r1-r4} + mov r4, r12 + bx lr + thumb_func_end SoundMainBTM + + thumb_func_start RealClearChain +RealClearChain: + ldr r3, [r0, 0x2C] + cmp r3, 0 + beq _081DD5E2 + ldr r1, [r0, 0x34] + ldr r2, [r0, 0x30] + cmp r2, 0 + beq _081DD5D6 + str r1, [r2, 0x34] + b _081DD5D8 +_081DD5D6: + str r1, [r3, 0x20] +_081DD5D8: + cmp r1, 0 + beq _081DD5DE + str r2, [r1, 0x30] +_081DD5DE: + movs r1, 0 + str r1, [r0, 0x2C] +_081DD5E2: + bx lr + thumb_func_end RealClearChain + + thumb_func_start ply_fine +ply_fine: + push {r4,r5,lr} + adds r5, r1, 0 + ldr r4, [r5, o_MusicPlayerTrack_chan] + cmp r4, 0 + beq ply_fine_done +ply_fine_loop: + ldrb r1, [r4] + movs r0, 0xC7 + tst r0, r1 + beq ply_fine_ok + movs r0, 0x40 + orrs r1, r0 + strb r1, [r4] +ply_fine_ok: + adds r0, r4, 0 + bl RealClearChain + ldr r4, [r4, 0x34] + cmp r4, 0 + bne ply_fine_loop +ply_fine_done: + movs r0, 0 + strb r0, [r5] + pop {r4,r5} + pop {r0} + bx r0 + thumb_func_end ply_fine + + thumb_func_start MPlayJumpTableCopy +MPlayJumpTableCopy: + mov r12, lr + movs r1, 0x24 + ldr r2, lt_MPlayJumpTableTemplate +MPlayJumpTableCopy_Loop: + ldr r3, [r2] + bl chk_adr_r2 + stm r0!, {r3} + adds r2, 0x4 + subs r1, 0x1 + bgt MPlayJumpTableCopy_Loop + bx r12 + thumb_func_end MPlayJumpTableCopy + + .align 2, 0 + .thumb_func +ldrb_r3_r2: + ldrb r3, [r2] + +@ This attempts to protect against reading anything from the BIOS ROM +@ besides the jump table template. +@ It assumes that the jump table template is located at the end of the ROM. + .thumb_func +chk_adr_r2: + push {r0} + lsrs r0, r2, 25 + bne chk_adr_r2_done @ if adr >= 0x2000000 (i.e. not in BIOS ROM), accept it + ldr r0, lt_MPlayJumpTableTemplate + cmp r2, r0 + blo chk_adr_r2_reject @ if adr < gMPlayJumpTableTemplate, reject it + lsrs r0, r2, 14 + beq chk_adr_r2_done @ if adr < 0x40000 (i.e. in BIOS ROM), accept it +chk_adr_r2_reject: + movs r3, 0 +chk_adr_r2_done: + pop {r0} + bx lr + + .align 2, 0 +lt_MPlayJumpTableTemplate: .word gMPlayJumpTableTemplate + + thumb_func_start ld_r3_tp_adr_i +ld_r3_tp_adr_i: + ldr r2, [r1, 0x40] +_081DD64A: + adds r3, r2, 0x1 + str r3, [r1, 0x40] + ldrb r3, [r2] + b chk_adr_r2 + thumb_func_end ld_r3_tp_adr_i + + thumb_func_start ply_goto +ply_goto: + push {lr} +ply_goto_1: + ldr r2, [r1, o_MusicPlayerTrack_cmdPtr] + ldrb r0, [r2, 0x3] + lsls r0, 8 + ldrb r3, [r2, 0x2] + orrs r0, r3 + lsls r0, 8 + ldrb r3, [r2, 0x1] + orrs r0, r3 + lsls r0, 8 + bl ldrb_r3_r2 + orrs r0, r3 + str r0, [r1, o_MusicPlayerTrack_cmdPtr] + pop {r0} + bx r0 + thumb_func_end ply_goto + + thumb_func_start ply_patt +ply_patt: + ldrb r2, [r1, o_MusicPlayerTrack_patternLevel] + cmp r2, 3 + bhs ply_patt_done + lsls r2, 2 + adds r3, r1, r2 + ldr r2, [r1, o_MusicPlayerTrack_cmdPtr] + adds r2, 0x4 + str r2, [r3, o_MusicPlayerTrack_patternStack] + ldrb r2, [r1, o_MusicPlayerTrack_patternLevel] + adds r2, 1 + strb r2, [r1, o_MusicPlayerTrack_patternLevel] + b ply_goto +ply_patt_done: + b ply_fine + thumb_func_end ply_patt + + thumb_func_start ply_pend +ply_pend: + ldrb r2, [r1, o_MusicPlayerTrack_patternLevel] + cmp r2, 0 + beq ply_pend_done + subs r2, 1 + strb r2, [r1, o_MusicPlayerTrack_patternLevel] + lsls r2, 2 + adds r3, r1, r2 + ldr r2, [r3, o_MusicPlayerTrack_patternStack] + str r2, [r1, o_MusicPlayerTrack_cmdPtr] +ply_pend_done: + bx lr + thumb_func_end ply_pend + + thumb_func_start ply_rept +ply_rept: + push {lr} + ldr r2, [r1, o_MusicPlayerTrack_cmdPtr] + ldrb r3, [r2] + cmp r3, 0 + bne ply_rept_1 + adds r2, 1 + str r2, [r1, o_MusicPlayerTrack_cmdPtr] + b ply_goto_1 +ply_rept_1: + ldrb r3, [r1, o_MusicPlayerTrack_repN] + adds r3, 1 + strb r3, [r1, o_MusicPlayerTrack_repN] + mov r12, r3 + bl ld_r3_tp_adr_i + cmp r12, r3 + bhs ply_rept_2 + b ply_goto_1 +ply_rept_2: + movs r3, 0 + strb r3, [r1, o_MusicPlayerTrack_repN] + adds r2, 5 + str r2, [r1, o_MusicPlayerTrack_cmdPtr] + pop {r0} + bx r0 + thumb_func_end ply_rept + + thumb_func_start ply_prio +ply_prio: + mov r12, lr + bl ld_r3_tp_adr_i + strb r3, [r1, o_MusicPlayerTrack_priority] + bx r12 + thumb_func_end ply_prio + + thumb_func_start ply_tempo +ply_tempo: + mov r12, lr + bl ld_r3_tp_adr_i + lsls r3, 1 + strh r3, [r0, o_MusicPlayerInfo_tempoD] + ldrh r2, [r0, o_MusicPlayerInfo_tempoU] + muls r3, r2 + lsrs r3, 8 + strh r3, [r0, o_MusicPlayerInfo_tempoI] + bx r12 + thumb_func_end ply_tempo + + thumb_func_start ply_keysh +ply_keysh: + mov r12, lr + bl ld_r3_tp_adr_i + strb r3, [r1, o_MusicPlayerTrack_keyShift] + ldrb r3, [r1, o_MusicPlayerTrack_flags] + movs r2, 0xC + orrs r3, r2 + strb r3, [r1, o_MusicPlayerTrack_flags] + bx r12 + thumb_func_end ply_keysh + + thumb_func_start ply_voice +ply_voice: + mov r12, lr + ldr r2, [r1, o_MusicPlayerTrack_cmdPtr] + ldrb r3, [r2] + adds r2, 1 + str r2, [r1, o_MusicPlayerTrack_cmdPtr] + lsls r2, r3, 1 + adds r2, r3 + lsls r2, 2 + ldr r3, [r0, o_MusicPlayerInfo_tone] + adds r2, r3 + ldr r3, [r2] + bl chk_adr_r2 + str r3, [r1, o_MusicPlayerTrack_ToneData_type] + ldr r3, [r2, 0x4] + bl chk_adr_r2 + str r3, [r1, o_MusicPlayerTrack_ToneData_wav] + ldr r3, [r2, 0x8] + bl chk_adr_r2 + str r3, [r1, o_MusicPlayerTrack_ToneData_attack] + bx r12 + thumb_func_end ply_voice + + thumb_func_start ply_vol +ply_vol: + mov r12, lr + bl ld_r3_tp_adr_i + strb r3, [r1, o_MusicPlayerTrack_vol] + ldrb r3, [r1, o_MusicPlayerTrack_flags] + movs r2, 0x3 + orrs r3, r2 + strb r3, [r1, o_MusicPlayerTrack_flags] + bx r12 + thumb_func_end ply_vol + + thumb_func_start ply_pan +ply_pan: + mov r12, lr + bl ld_r3_tp_adr_i + subs r3, 0x40 + strb r3, [r1, o_MusicPlayerTrack_pan] + ldrb r3, [r1, o_MusicPlayerTrack_flags] + movs r2, 0x3 + orrs r3, r2 + strb r3, [r1, o_MusicPlayerTrack_flags] + bx r12 + thumb_func_end ply_pan + + thumb_func_start ply_bend +ply_bend: + mov r12, lr + bl ld_r3_tp_adr_i + subs r3, 0x40 + strb r3, [r1, o_MusicPlayerTrack_bend] + ldrb r3, [r1, o_MusicPlayerTrack_flags] + movs r2, 0xC + orrs r3, r2 + strb r3, [r1, o_MusicPlayerTrack_flags] + bx r12 + thumb_func_end ply_bend + + thumb_func_start ply_bendr +ply_bendr: + mov r12, lr + bl ld_r3_tp_adr_i + strb r3, [r1, o_MusicPlayerTrack_bendRange] + ldrb r3, [r1, o_MusicPlayerTrack_flags] + movs r2, 0xC + orrs r3, r2 + strb r3, [r1, o_MusicPlayerTrack_flags] + bx r12 + thumb_func_end ply_bendr + + thumb_func_start ply_lfodl +ply_lfodl: + mov r12, lr + bl ld_r3_tp_adr_i + strb r3, [r1, o_MusicPlayerTrack_lfoDelay] + bx r12 + thumb_func_end ply_lfodl + + thumb_func_start ply_modt +ply_modt: + mov r12, lr + bl ld_r3_tp_adr_i + ldrb r0, [r1, o_MusicPlayerTrack_modT] + cmp r0, r3 + beq _081DD7AA + strb r3, [r1, o_MusicPlayerTrack_modT] + ldrb r3, [r1, o_MusicPlayerTrack_flags] + movs r2, 0xF + orrs r3, r2 + strb r3, [r1, o_MusicPlayerTrack_flags] +_081DD7AA: + bx r12 + thumb_func_end ply_modt + + thumb_func_start ply_tune +ply_tune: + mov r12, lr + bl ld_r3_tp_adr_i + subs r3, 0x40 + strb r3, [r1, o_MusicPlayerTrack_tune] + ldrb r3, [r1, o_MusicPlayerTrack_flags] + movs r2, 0xC + orrs r3, r2 + strb r3, [r1, o_MusicPlayerTrack_flags] + bx r12 + thumb_func_end ply_tune + + thumb_func_start ply_port +ply_port: + mov r12, lr + ldr r2, [r1, o_MusicPlayerTrack_cmdPtr] + ldrb r3, [r2] + adds r2, 1 + ldr r0, =REG_SOUND1CNT_L @ sound register base address + adds r0, r3 + bl _081DD64A + strb r3, [r0] + bx r12 + .pool + thumb_func_end ply_port + + thumb_func_start m4aSoundVSync +m4aSoundVSync: + ldr r0, lt2_SOUND_INFO_PTR + ldr r0, [r0] + + @ Exit the function if ident is not ID_NUMBER or ID_NUMBER+1. + ldr r2, lt2_ID_NUMBER + ldr r3, [r0, o_SoundInfo_ident] + subs r3, r2 + cmp r3, 1 + bhi m4aSoundVSync_Done + + @ Decrement the PCM DMA counter. If it reaches 0, we need to do a DMA. + ldrb r1, [r0, o_SoundInfo_pcmDmaCounter] + subs r1, 1 + strb r1, [r0, o_SoundInfo_pcmDmaCounter] + bgt m4aSoundVSync_Done + + @ Reload the PCM DMA counter. + ldrb r1, [r0, o_SoundInfo_pcmDmaPeriod] + strb r1, [r0, o_SoundInfo_pcmDmaCounter] + + ldr r2, =REG_DMA1 + + ldr r1, [r2, 0x8] @ DMA1CNT + lsls r1, 7 + bcc m4aSoundVSync_SkipDMA1 @ branch if repeat bit isn't set + + ldr r1, =((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4 + str r1, [r2, 0x8] @ DMA1CNT + +m4aSoundVSync_SkipDMA1: + ldr r1, [r2, 0xC + 0x8] @ DMA2CNT + lsls r1, 7 + bcc m4aSoundVSync_SkipDMA2 @ branch if repeat bit isn't set + + ldr r1, =((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4 + str r1, [r2, 0xC + 0x8] @ DMA2CNT + +m4aSoundVSync_SkipDMA2: + + @ turn off DMA1/DMA2 + movs r1, DMA_32BIT >> 8 + lsls r1, 8 + strh r1, [r2, 0xA] @ DMA1CNT_H + strh r1, [r2, 0xC + 0xA] @ DMA2CNT_H + + @ turn on DMA1/DMA2 direct-sound FIFO mode + movs r1, (DMA_ENABLE | DMA_START_SPECIAL | DMA_32BIT | DMA_REPEAT) >> 8 + lsls r1, 8 @ LSB is 0, so DMA_SRC_INC is used (destination is always fixed in FIFO mode) + strh r1, [r2, 0xA] @ DMA1CNT_H + strh r1, [r2, 0xC + 0xA] @ DMA2CNT_H + +m4aSoundVSync_Done: + bx lr + + .pool + thumb_func_end m4aSoundVSync + + thumb_func_start MPlayMain +MPlayMain: + ldr r2, lt2_ID_NUMBER + ldr r3, [r0, o_MusicPlayerInfo_ident] + cmp r2, r3 + beq _081DD82E + bx lr +_081DD82E: + adds r3, 0x1 + str r3, [r0, o_MusicPlayerInfo_ident] + push {r0,lr} + ldr r3, [r0, o_MusicPlayerInfo_func] + cmp r3, 0 + beq _081DD840 + ldr r0, [r0, o_MusicPlayerInfo_intp] + bl call_r3 +_081DD840: + pop {r0} + push {r4-r7} + mov r4, r8 + mov r5, r9 + mov r6, r10 + mov r7, r11 + push {r4-r7} + adds r7, r0, 0 + ldr r0, [r7, o_MusicPlayerInfo_status] + cmp r0, 0 + bge _081DD858 + b _081DDA6C +_081DD858: + ldr r0, lt2_SOUND_INFO_PTR + ldr r0, [r0] + mov r8, r0 + adds r0, r7, 0 + bl FadeOutBody + ldr r0, [r7, o_MusicPlayerInfo_status] + cmp r0, 0 + bge _081DD86C + b _081DDA6C +_081DD86C: + ldrh r0, [r7, o_MusicPlayerInfo_tempoC] + ldrh r1, [r7, o_MusicPlayerInfo_tempoI] + adds r0, r1 + b _081DD9BC +_081DD874: + ldrb r6, [r7, o_MusicPlayerInfo_trackCount] + ldr r5, [r7, o_MusicPlayerInfo_tracks] + movs r3, 0x1 + movs r4, 0 +_081DD87C: + ldrb r0, [r5] + movs r1, 0x80 + tst r1, r0 + bne _081DD886 + b _081DD998 +_081DD886: + mov r10, r3 + orrs r4, r3 + mov r11, r4 + ldr r4, [r5, o_MusicPlayerTrack_chan] + cmp r4, 0 + beq _081DD8BA +_081DD892: + ldrb r1, [r4] + movs r0, 0xC7 + tst r0, r1 + beq _081DD8AE + ldrb r0, [r4, 0x10] + cmp r0, 0 + beq _081DD8B4 + subs r0, 0x1 + strb r0, [r4, 0x10] + bne _081DD8B4 + movs r0, 0x40 + orrs r1, r0 + strb r1, [r4] + b _081DD8B4 +_081DD8AE: + adds r0, r4, 0 + bl ClearChain +_081DD8B4: + ldr r4, [r4, 0x34] + cmp r4, 0 + bne _081DD892 +_081DD8BA: + ldrb r3, [r5, o_MusicPlayerTrack_flags] + movs r0, 0x40 + tst r0, r3 + beq _081DD938 + adds r0, r5, 0 + bl Clear64byte + movs r0, 0x80 + strb r0, [r5] + movs r0, 0x2 + strb r0, [r5, o_MusicPlayerTrack_bendRange] + movs r0, 0x40 + strb r0, [r5, o_MusicPlayerTrack_volX] + movs r0, 0x16 + strb r0, [r5, o_MusicPlayerTrack_lfoSpeed] + movs r0, 0x1 + adds r1, r5, 0x6 + strb r0, [r1, o_MusicPlayerTrack_ToneData_type - 0x6] + b _081DD938 +_081DD8E0: + ldr r2, [r5, o_MusicPlayerTrack_cmdPtr] + ldrb r1, [r2] + cmp r1, 0x80 + bhs _081DD8EC + ldrb r1, [r5, o_MusicPlayerTrack_runningStatus] + b _081DD8F6 +_081DD8EC: + adds r2, 0x1 + str r2, [r5, o_MusicPlayerTrack_cmdPtr] + cmp r1, 0xBD + bcc _081DD8F6 + strb r1, [r5, o_MusicPlayerTrack_runningStatus] +_081DD8F6: + cmp r1, 0xCF + bcc _081DD90C + mov r0, r8 + ldr r3, [r0, o_SoundInfo_plynote] + adds r0, r1, 0 + subs r0, 0xCF + adds r1, r7, 0 + adds r2, r5, 0 + bl call_r3 + b _081DD938 +_081DD90C: + cmp r1, 0xB0 + bls _081DD92E + adds r0, r1, 0 + subs r0, 0xB1 + strb r0, [r7, o_MusicPlayerInfo_cmd] + mov r3, r8 + ldr r3, [r3, o_SoundInfo_MPlayJumpTable] + lsls r0, 2 + ldr r3, [r3, r0] + adds r0, r7, 0 + adds r1, r5, 0 + bl call_r3 + ldrb r0, [r5, o_MusicPlayerTrack_flags] + cmp r0, 0 + beq _081DD994 + b _081DD938 +_081DD92E: + ldr r0, lt_gClockTable + subs r1, 0x80 + adds r1, r0 + ldrb r0, [r1] + strb r0, [r5, o_MusicPlayerTrack_wait] +_081DD938: + ldrb r0, [r5, o_MusicPlayerTrack_wait] + cmp r0, 0 + beq _081DD8E0 + subs r0, 0x1 + strb r0, [r5, o_MusicPlayerTrack_wait] + ldrb r1, [r5, o_MusicPlayerTrack_lfoSpeed] + cmp r1, 0 + beq _081DD994 + ldrb r0, [r5, o_MusicPlayerTrack_mod] + cmp r0, 0 + beq _081DD994 + ldrb r0, [r5, o_MusicPlayerTrack_lfoDelayC] + cmp r0, 0 + beq _081DD95A + subs r0, 0x1 + strb r0, [r5, o_MusicPlayerTrack_lfoDelayC] + b _081DD994 +_081DD95A: + ldrb r0, [r5, o_MusicPlayerTrack_lfoSpeedC] + adds r0, r1 + strb r0, [r5, o_MusicPlayerTrack_lfoSpeedC] + adds r1, r0, 0 + subs r0, 0x40 + lsls r0, 24 + bpl _081DD96E + lsls r2, r1, 24 + asrs r2, 24 + b _081DD972 +_081DD96E: + movs r0, 0x80 + subs r2, r0, r1 +_081DD972: + ldrb r0, [r5, o_MusicPlayerTrack_mod] + muls r0, r2 + asrs r2, r0, 6 + ldrb r0, [r5, o_MusicPlayerTrack_modM] + eors r0, r2 + lsls r0, 24 + beq _081DD994 + strb r2, [r5, o_MusicPlayerTrack_modM] + ldrb r0, [r5] + ldrb r1, [r5, o_MusicPlayerTrack_modT] + cmp r1, 0 + bne _081DD98E + movs r1, 0xC + b _081DD990 +_081DD98E: + movs r1, 0x3 +_081DD990: + orrs r0, r1 + strb r0, [r5, o_MusicPlayerTrack_flags] +_081DD994: + mov r3, r10 + mov r4, r11 +_081DD998: + subs r6, 0x1 + ble _081DD9A4 + movs r0, 0x50 + adds r5, r0 + lsls r3, 1 + b _081DD87C +_081DD9A4: + ldr r0, [r7, o_MusicPlayerInfo_clock] + adds r0, 0x1 + str r0, [r7, o_MusicPlayerInfo_clock] + cmp r4, 0 + bne _081DD9B6 + movs r0, 0x80 + lsls r0, 24 + str r0, [r7, o_MusicPlayerInfo_status] + b _081DDA6C +_081DD9B6: + str r4, [r7, o_MusicPlayerInfo_status] + ldrh r0, [r7, o_MusicPlayerInfo_tempoC] + subs r0, 0x96 +_081DD9BC: + strh r0, [r7, o_MusicPlayerInfo_tempoC] + cmp r0, 0x96 + bcc _081DD9C4 + b _081DD874 +_081DD9C4: + ldrb r2, [r7, o_MusicPlayerInfo_trackCount] + ldr r5, [r7, o_MusicPlayerInfo_tracks] +_081DD9C8: + ldrb r0, [r5, o_MusicPlayerTrack_flags] + movs r1, 0x80 + tst r1, r0 + beq _081DDA62 + movs r1, 0xF + tst r1, r0 + beq _081DDA62 + mov r9, r2 + adds r0, r7, 0 + adds r1, r5, 0 + bl TrkVolPitSet + ldr r4, [r5, o_MusicPlayerTrack_chan] + cmp r4, 0 + beq _081DDA58 +_081DD9E6: + ldrb r1, [r4, o_SoundChannel_status] + movs r0, 0xC7 + tst r0, r1 + bne _081DD9F6 + adds r0, r4, 0 + bl ClearChain + b _081DDA52 +_081DD9F6: + ldrb r0, [r4, o_SoundChannel_type] + movs r6, 0x7 + ands r6, r0 + ldrb r3, [r5, o_MusicPlayerTrack_flags] + movs r0, 0x3 + tst r0, r3 + beq _081DDA14 + bl ChnVolSetAsm + cmp r6, 0 + beq _081DDA14 + ldrb r0, [r4, o_CgbChannel_mo] + movs r1, 0x1 + orrs r0, r1 + strb r0, [r4, o_CgbChannel_mo] +_081DDA14: + ldrb r3, [r5, o_MusicPlayerTrack_flags] + movs r0, 0xC + tst r0, r3 + beq _081DDA52 + ldrb r1, [r4, o_SoundChannel_ky] + movs r0, 0x8 + ldrsb r0, [r5, r0] + adds r2, r1, r0 + bpl _081DDA28 + movs r2, 0 +_081DDA28: + cmp r6, 0 + beq _081DDA46 + mov r0, r8 + ldr r3, [r0, o_SoundInfo_MidiKeyToCgbFreq] + adds r1, r2, 0 + ldrb r2, [r5, o_MusicPlayerTrack_pitM] + adds r0, r6, 0 + bl call_r3 + str r0, [r4, o_CgbChannel_fr] + ldrb r0, [r4, o_CgbChannel_mo] + movs r1, 0x2 + orrs r0, r1 + strb r0, [r4, o_CgbChannel_mo] + b _081DDA52 +_081DDA46: + adds r1, r2, 0 + ldrb r2, [r5, o_MusicPlayerTrack_pitM] + ldr r0, [r4, o_SoundChannel_wav] + bl MidiKeyToFreq + str r0, [r4, o_SoundChannel_freq] +_081DDA52: + ldr r4, [r4, o_SoundChannel_np] + cmp r4, 0 + bne _081DD9E6 +_081DDA58: + ldrb r0, [r5, o_MusicPlayerTrack_flags] + movs r1, 0xF0 + ands r0, r1 + strb r0, [r5, o_MusicPlayerTrack_flags] + mov r2, r9 +_081DDA62: + subs r2, 0x1 + ble _081DDA6C + movs r0, 0x50 + adds r5, r0 + bgt _081DD9C8 +_081DDA6C: + ldr r0, lt2_ID_NUMBER + str r0, [r7, o_MusicPlayerInfo_ident] + pop {r0-r7} + mov r8, r0 + mov r9, r1 + mov r10, r2 + mov r11, r3 + pop {r3} + +call_r3: + bx r3 + + .align 2, 0 +lt_gClockTable: .word gClockTable +lt2_SOUND_INFO_PTR: .word SOUND_INFO_PTR +lt2_ID_NUMBER: .word ID_NUMBER + thumb_func_end MPlayMain + + thumb_func_start TrackStop +TrackStop: + push {r4-r6,lr} + adds r5, r1, 0 + ldrb r1, [r5, o_MusicPlayerTrack_flags] + movs r0, 0x80 + tst r0, r1 + beq TrackStop_Done + ldr r4, [r5, o_MusicPlayerTrack_chan] + cmp r4, 0 + beq TrackStop_3 + movs r6, 0 +TrackStop_Loop: + ldrb r0, [r4, o_SoundChannel_status] + cmp r0, 0 + beq TrackStop_2 + ldrb r0, [r4, o_SoundChannel_type] + movs r3, 0x7 + ands r0, r3 + beq TrackStop_1 + ldr r3, =SOUND_INFO_PTR + ldr r3, [r3] + ldr r3, [r3, o_SoundInfo_CgbOscOff] + bl call_r3 +TrackStop_1: + strb r6, [r4, o_SoundChannel_status] +TrackStop_2: + str r6, [r4, o_SoundChannel_track] + ldr r4, [r4, o_SoundChannel_np] + cmp r4, 0 + bne TrackStop_Loop +TrackStop_3: + str r4, [r5, o_MusicPlayerTrack_chan] +TrackStop_Done: + pop {r4-r6} + pop {r0} + bx r0 + .pool + thumb_func_end TrackStop + + thumb_func_start ChnVolSetAsm +ChnVolSetAsm: + ldrb r1, [r4, 0x12] + movs r0, 0x14 + ldrsb r2, [r4, r0] + movs r3, 0x80 + adds r3, r2 + muls r3, r1 + ldrb r0, [r5, 0x10] + muls r0, r3 + asrs r0, 14 + cmp r0, 0xFF + bls _081DDAE8 + movs r0, 0xFF +_081DDAE8: + strb r0, [r4, 0x2] + movs r3, 0x7F + subs r3, r2 + muls r3, r1 + ldrb r0, [r5, 0x11] + muls r0, r3 + asrs r0, 14 + cmp r0, 0xFF + bls _081DDAFC + movs r0, 0xFF +_081DDAFC: + strb r0, [r4, 0x3] + bx lr + thumb_func_end ChnVolSetAsm + + thumb_func_start ply_note +ply_note: + push {r4-r7,lr} + mov r4, r8 + mov r5, r9 + mov r6, r10 + mov r7, r11 + push {r4-r7} + sub sp, 0x18 + str r1, [sp] + adds r5, r2, 0 + ldr r1, =SOUND_INFO_PTR + ldr r1, [r1] + str r1, [sp, 0x4] + ldr r1, =gClockTable + adds r0, r1 + ldrb r0, [r0] + strb r0, [r5, o_MusicPlayerTrack_gateTime] + ldr r3, [r5, o_MusicPlayerTrack_cmdPtr] + ldrb r0, [r3] + cmp r0, 0x80 + bhs _081DDB46 + strb r0, [r5, o_MusicPlayerTrack_key] + adds r3, 0x1 + ldrb r0, [r3] + cmp r0, 0x80 + bhs _081DDB44 + strb r0, [r5, o_MusicPlayerTrack_velocity] + adds r3, 0x1 + ldrb r0, [r3] + cmp r0, 0x80 + bhs _081DDB44 + ldrb r1, [r5, o_MusicPlayerTrack_gateTime] + adds r1, r0 + strb r1, [r5, o_MusicPlayerTrack_gateTime] + adds r3, 0x1 +_081DDB44: + str r3, [r5, o_MusicPlayerTrack_cmdPtr] +_081DDB46: + movs r0, 0 + str r0, [sp, 0x14] + adds r4, r5, 0 + adds r4, o_MusicPlayerTrack_ToneData_type + ldrb r2, [r4] + movs r0, TONEDATA_TYPE_RHY | TONEDATA_TYPE_SPL + tst r0, r2 + beq _081DDB98 + ldrb r3, [r5, o_MusicPlayerTrack_key] + movs r0, TONEDATA_TYPE_SPL + tst r0, r2 + beq _081DDB66 + ldr r1, [r5, o_MusicPlayerTrack_ToneData_keySplitTable] + adds r1, r3 + ldrb r0, [r1] + b _081DDB68 +_081DDB66: + adds r0, r3, 0 +_081DDB68: + lsls r1, r0, 1 + adds r1, r0 + lsls r1, 2 + ldr r0, [r5, o_MusicPlayerTrack_ToneData_wav] + adds r1, r0 + mov r9, r1 + mov r6, r9 + ldrb r1, [r6] + movs r0, 0xC0 + tst r0, r1 + beq _081DDB80 + b _081DDCEA +_081DDB80: + movs r0, 0x80 + tst r0, r2 + beq _081DDB9C + ldrb r1, [r6, 0x3] + movs r0, 0x80 + tst r0, r1 + beq _081DDB94 + subs r1, 0xC0 + lsls r1, 1 + str r1, [sp, 0x14] +_081DDB94: + ldrb r3, [r6, 0x1] + b _081DDB9C +_081DDB98: + mov r9, r4 + ldrb r3, [r5, 0x5] +_081DDB9C: + str r3, [sp, 0x8] + ldr r6, [sp] + ldrb r1, [r6, 0x9] + ldrb r0, [r5, 0x1D] + adds r0, r1 + cmp r0, 0xFF + bls _081DDBAC + movs r0, 0xFF +_081DDBAC: + str r0, [sp, 0x10] + mov r6, r9 + ldrb r0, [r6] + movs r6, 0x7 + ands r6, r0 + str r6, [sp, 0xC] + beq _081DDBEC + ldr r0, [sp, 0x4] + ldr r4, [r0, 0x1C] + cmp r4, 0 + bne _081DDBC4 + b _081DDCEA +_081DDBC4: + subs r6, 0x1 + lsls r0, r6, 6 + adds r4, r0 + ldrb r1, [r4] + movs r0, 0xC7 + tst r0, r1 + beq _081DDC40 + movs r0, 0x40 + tst r0, r1 + bne _081DDC40 + ldrb r1, [r4, 0x13] + ldr r0, [sp, 0x10] + cmp r1, r0 + bcc _081DDC40 + beq _081DDBE4 + b _081DDCEA +_081DDBE4: + ldr r0, [r4, 0x2C] + cmp r0, r5 + bcs _081DDC40 + b _081DDCEA +_081DDBEC: + ldr r6, [sp, 0x10] + adds r7, r5, 0 + movs r2, 0 + mov r8, r2 + ldr r4, [sp, 0x4] + ldrb r3, [r4, 0x6] + adds r4, 0x50 +_081DDBFA: + ldrb r1, [r4] + movs r0, 0xC7 + tst r0, r1 + beq _081DDC40 + movs r0, 0x40 + tst r0, r1 + beq _081DDC14 + cmp r2, 0 + bne _081DDC18 + adds r2, 0x1 + ldrb r6, [r4, 0x13] + ldr r7, [r4, 0x2C] + b _081DDC32 +_081DDC14: + cmp r2, 0 + bne _081DDC34 +_081DDC18: + ldrb r0, [r4, 0x13] + cmp r0, r6 + bcs _081DDC24 + adds r6, r0, 0 + ldr r7, [r4, 0x2C] + b _081DDC32 +_081DDC24: + bhi _081DDC34 + ldr r0, [r4, 0x2C] + cmp r0, r7 + bls _081DDC30 + adds r7, r0, 0 + b _081DDC32 +_081DDC30: + bcc _081DDC34 +_081DDC32: + mov r8, r4 +_081DDC34: + adds r4, 0x40 + subs r3, 0x1 + bgt _081DDBFA + mov r4, r8 + cmp r4, 0 + beq _081DDCEA +_081DDC40: + adds r0, r4, 0 + bl ClearChain + movs r1, 0 + str r1, [r4, 0x30] + ldr r3, [r5, 0x20] + str r3, [r4, 0x34] + cmp r3, 0 + beq _081DDC54 + str r4, [r3, 0x30] +_081DDC54: + str r4, [r5, 0x20] + str r5, [r4, 0x2C] + ldrb r0, [r5, 0x1B] + strb r0, [r5, 0x1C] + cmp r0, r1 + beq _081DDC66 + adds r1, r5, 0 + bl clear_modM +_081DDC66: + ldr r0, [sp] + adds r1, r5, 0 + bl TrkVolPitSet + ldr r0, [r5, 0x4] + str r0, [r4, 0x10] + ldr r0, [sp, 0x10] + strb r0, [r4, 0x13] + ldr r0, [sp, 0x8] + strb r0, [r4, 0x8] + ldr r0, [sp, 0x14] + strb r0, [r4, 0x14] + mov r6, r9 + ldrb r0, [r6] + strb r0, [r4, 0x1] + ldr r7, [r6, 0x4] + str r7, [r4, 0x24] + ldr r0, [r6, 0x8] + str r0, [r4, 0x4] + ldrh r0, [r5, 0x1E] + strh r0, [r4, 0xC] + bl ChnVolSetAsm + ldrb r1, [r4, 0x8] + movs r0, 0x8 + ldrsb r0, [r5, r0] + adds r3, r1, r0 + bpl _081DDCA0 + movs r3, 0 +_081DDCA0: + ldr r6, [sp, 0xC] + cmp r6, 0 + beq _081DDCCE + mov r6, r9 + ldrb r0, [r6, 0x2] + strb r0, [r4, 0x1E] + ldrb r1, [r6, 0x3] + movs r0, 0x80 + tst r0, r1 + bne _081DDCBA + movs r0, 0x70 + tst r0, r1 + bne _081DDCBC +_081DDCBA: + movs r1, 0x8 +_081DDCBC: + strb r1, [r4, 0x1F] + ldrb r2, [r5, 0x9] + adds r1, r3, 0 + ldr r0, [sp, 0xC] + ldr r3, [sp, 0x4] + ldr r3, [r3, 0x30] + bl call_r3 + b _081DDCDC +_081DDCCE: + ldr r0, [r5, o_MusicPlayerTrack_unk_3C] + str r0, [r4, 0x18] + ldrb r2, [r5, 0x9] + adds r1, r3, 0 + adds r0, r7, 0 + bl MidiKeyToFreq +_081DDCDC: + str r0, [r4, 0x20] + movs r0, 0x80 + strb r0, [r4] + ldrb r1, [r5] + movs r0, 0xF0 + ands r0, r1 + strb r0, [r5] +_081DDCEA: + add sp, 0x18 + pop {r0-r7} + mov r8, r0 + mov r9, r1 + mov r10, r2 + mov r11, r3 + pop {r0} + bx r0 + .pool + thumb_func_end ply_note + + thumb_func_start ply_endtie +ply_endtie: + push {r4,r5} + ldr r2, [r1, o_MusicPlayerTrack_cmdPtr] + ldrb r3, [r2] + cmp r3, 0x80 + bhs _081DDD16 + strb r3, [r1, o_MusicPlayerTrack_key] + adds r2, 0x1 + str r2, [r1, o_MusicPlayerTrack_cmdPtr] + b _081DDD18 +_081DDD16: + ldrb r3, [r1, o_MusicPlayerTrack_key] +_081DDD18: + ldr r1, [r1, o_MusicPlayerTrack_chan] + cmp r1, 0 + beq _081DDD40 + movs r4, 0x83 + movs r5, 0x40 +_081DDD22: + ldrb r2, [r1, o_SoundChannel_status] + tst r2, r4 + beq _081DDD3A + tst r2, r5 + bne _081DDD3A + ldrb r0, [r1, o_SoundChannel_mk] + cmp r0, r3 + bne _081DDD3A + movs r0, 0x40 + orrs r2, r0 + strb r2, [r1, o_SoundChannel_status] + b _081DDD40 +_081DDD3A: + ldr r1, [r1, o_SoundChannel_np] + cmp r1, 0 + bne _081DDD22 +_081DDD40: + pop {r4,r5} + bx lr + thumb_func_end ply_endtie + + thumb_func_start clear_modM +clear_modM: + movs r2, 0 + strb r2, [r1, o_MusicPlayerTrack_modM] + strb r2, [r1, o_MusicPlayerTrack_lfoSpeedC] + ldrb r2, [r1, o_MusicPlayerTrack_modT] + cmp r2, 0 + bne _081DDD54 + movs r2, 0xC + b _081DDD56 +_081DDD54: + movs r2, 0x3 +_081DDD56: + ldrb r3, [r1, o_MusicPlayerTrack_flags] + orrs r3, r2 + strb r3, [r1, o_MusicPlayerTrack_flags] + bx lr + thumb_func_end clear_modM + + thumb_func_start ld_r3_tp_adr_i +ld_r3_tp_adr_i_unchecked: + ldr r2, [r1, o_MusicPlayerTrack_cmdPtr] + adds r3, r2, 1 + str r3, [r1, o_MusicPlayerTrack_cmdPtr] + ldrb r3, [r2] + bx lr + thumb_func_end ld_r3_tp_adr_i + + thumb_func_start ply_lfos +ply_lfos: + mov r12, lr + bl ld_r3_tp_adr_i_unchecked + strb r3, [r1, o_MusicPlayerTrack_lfoSpeed] + cmp r3, 0 + bne _081DDD7C + bl clear_modM +_081DDD7C: + bx r12 + thumb_func_end ply_lfos + + thumb_func_start ply_mod +ply_mod: + mov r12, lr + bl ld_r3_tp_adr_i_unchecked + strb r3, [r1, o_MusicPlayerTrack_mod] + cmp r3, 0 + bne _081DDD90 + bl clear_modM +_081DDD90: + bx r12 + thumb_func_end ply_mod + + .align 2, 0 @ Don't pad with nop. + + .bss +gUnknown_03001300: + .space 0x40 + .size gUnknown_03001300, .-gUnknown_03001300 + + .global gMPlayTrack_BGM +gMPlayTrack_BGM: + .space 0x320 + .size gMPlayTrack_BGM, .-gMPlayTrack_BGM + + .global gMPlayTrack_SE1 +gMPlayTrack_SE1: + .space 0xF0 + .size gMPlayTrack_SE1, .-gMPlayTrack_SE1 + + .global gMPlayTrack_SE2 +gMPlayTrack_SE2: + .space 0x2D0 + .size gMPlayTrack_SE2, .-gMPlayTrack_SE2 + + .global gMPlayTrack_SE3 +gMPlayTrack_SE3: + .space 0x50 + .size gMPlayTrack_SE3, .-gMPlayTrack_SE3 |