1 /****************************************************************************
3 * ____ ___ ____ __ ______ ___ ____ ____/ / *
4 * / __ `__ \/ __ `/ |/ / __ `__ \/ __ \/ __ / *
5 * / / / / / / /_/ /> </ / / / / / /_/ / /_/ / *
6 * /_/ /_/ /_/\__,_/_/|_/_/ /_/ /_/\____/\__,_/ *
8 * Copyright (c) 2008, Mukunda Johnson (mukunda@maxmod.org) *
10 * Permission to use, copy, modify, and/or distribute this software for any *
11 * purpose with or without fee is hereby granted, provided that the above *
12 * copyright notice and this permission notice appear in all copies. *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF *
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR *
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES *
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN *
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
21 ****************************************************************************/
23 /******************************************************************************
27 ******************************************************************************/
29 #include "mp_defs.inc"
31 #include "mp_mas_structs.inc"
32 #include "mp_macros.inc"
35 #include "mp_mixer_gba.inc"
39 #include "mp_mixer_ds.inc"
42 /******************************************************************************
46 ******************************************************************************/
51 /******************************************************************************
54 * Function pointer to user event handler
55 ******************************************************************************/
59 /******************************************************************************
62 * Number of modules in soundbank
63 ******************************************************************************/
65 mmModuleCount: .space 4
67 /******************************************************************************
70 * Address of module bank
71 ******************************************************************************/
73 mmModuleBank: .space 4
75 /******************************************************************************
78 * Address of sample bank
79 ******************************************************************************/
81 mmSampleBank: .space 4
83 /******************************************************************************
86 * Bitmask to select which hardware/software channels can be used
87 ******************************************************************************/
91 /******************************************************************************
94 * Pointer to a user function to be called during the vblank irq
95 ******************************************************************************/
96 .global mm_vblank_function
97 mm_vblank_function: .space 4
99 /******************************************************************************
100 * mm_rds_pchannels, mm_rds_achannels
102 * Memory for module/active channels for NDS system
103 ******************************************************************************/
105 mm_rds_pchannels: .space MCH_SIZE*32
106 mm_rds_achannels: .space MCA_SIZE*32
109 /******************************************************************************
112 * Variable that will be 'true' if we are ready for playback
113 ******************************************************************************/
114 .global mmInitialized
115 mmInitialized: .space 1
120 /******************************************************************************
124 ******************************************************************************/
129 /******************************************************************************
132 * Functions to branch to a register
133 ******************************************************************************/
136 .section ".iwram", "ax", %progbits
140 .global mpp_call_r7i, mpp_call_r2i, mpp_call_r1i
143 //-----------------------------------------------------------------------------
145 //-----------------------------------------------------------------------------
148 //-----------------------------------------------------------------------------
150 //-----------------------------------------------------------------------------
153 //-----------------------------------------------------------------------------
155 //-----------------------------------------------------------------------------
159 //-----------------------------------------------------------------------------
163 //-----------------------------------------------------------------------------
165 .global mpp_call_r7, mpp_call_r1, mpp_call_r2, mpp_call_r3
168 @------------------------------------------------------------------------------
170 @------------------------------------------------------------------------------
173 @------------------------------------------------------------------------------
175 @------------------------------------------------------------------------------
178 @------------------------------------------------------------------------------
180 @------------------------------------------------------------------------------
183 @------------------------------------------------------------------------------
185 @------------------------------------------------------------------------------
187 /******************************************************************************
190 * Set function for handling playback events
191 ******************************************************************************/
192 .global mmSetEventHandler
201 /******************************************************************************
202 * mmLockChannels( mask )
204 * Lock audio channels to prevent the sequencer from using them.
205 ******************************************************************************/
206 .global mmLockChannels
210 ldr r1,=mm_ch_mask // clear bits
230 /******************************************************************************
231 * StopActiveChannel( index )
233 * Stop active channel
234 ******************************************************************************/
239 GET_MIXCH r1 // stop mixing channel
240 mov r2, #MIXER_CHN_SIZE //
249 str r2, [r1, #MIXER_CHN_SRC] //
256 str r2, [r1, #MIXER_CHN_SAMP] //
257 strh r2, [r1, #MIXER_CHN_CVOL] //
258 strh r2, [r1, #MIXER_CHN_VOL] //
262 ldr r1,=0x4000400 // stop hardware channel
267 ldr r1,=mm_achannels // disable achn
273 ldrb r4, [r1, #MCA_FLAGS] //
274 strb r2, [r1, #MCA_FLAGS] //
275 strb r2, [r1, #MCA_TYPE] //
283 ldr r1,=mm_pchannels // stop hooked pchannel
285 ldr r2,=mm_num_mch //
288 2: ldrb r3, [r1, #MCH_ALLOC] //
292 strb r3, [r1, #MCH_ALLOC] //
304 2: ldrb r3, [r1, #MCH_ALLOC] //
308 strb r3, [r1, #MCH_ALLOC] //
315 // hope it works out for effects...
321 /******************************************************************************
322 * mmUnlockChannels( mask )
324 * Unlock audio channels so they can be used by the sequencer.
325 ******************************************************************************/
326 .global mmUnlockChannels
331 ldr r1,=mm_mixing_mode // can NOT unlock channels in mode b
346 /******************************************************************************
350 ******************************************************************************/
355 //-----------------------------------------------------------------------------
357 //-----------------------------------------------------------------------------
362 /******************************************************************************
365 * Address of soundbank in memory/rom
366 ******************************************************************************/
368 mp_solution: .space 4
374 /******************************************************************************
378 ******************************************************************************/
385 mov r1, #MM_GBA_SYSTEM_SOUNDBANK
390 ldr r1, [r0,#MM_GBA_SYSTEM_ACTCH]
392 ldr r1, [r0,#MM_GBA_SYSTEM_MODCH]
394 ldr r1, [r0,#MM_GBA_SYSTEM_MCH_COUNT]
396 ldr r1, [r0,#MM_GBA_SYSTEM_ACH_COUNT]
399 bl mmMixerInit @ initialize software/hardware mixer
415 bl mmSetEffectsVolume //
428 /******************************************************************************
431 * Set function to be called during the vblank IRQ
432 ******************************************************************************/
433 .global mmSetVBlankHandler
437 ldr r1,=mm_vblank_function
441 /******************************************************************************
444 * Work routine, user _must_ call this every frame.
445 ******************************************************************************/
455 ldr r7,=mmUpdateEffects
459 @ sub layer has 60hz accuracy
464 @ update main layer and mix samples.
465 @ main layer is sample-accurate.
467 ldr r0,=mpp_channels @ copy channels
471 ldr r0,=mpp_nchannels @ copy #channels
475 ldr r0,=mpp_clayer @ layer=0 (main)
479 ldr r0,=mmLayerMain @mpp_layerA @ copy layer pointer
485 @ mixlen is divisible by 2
487 ldrb r1, [r0, #MPL_ISPLAYING] @ check if main layer is active
489 beq .mpf_no_mainlayer @ skip processing if disabled (and just mix samples)
493 ldr r0,=mpp_layerp @ get layer
496 mov r1, #MPL_TICKRATE @ get samples/tick
499 mov r1, #MPL_SAMPCOUNT @ get sample count
502 sub r5, r6 @ calc tickrate-counter
506 1: cmp r5, r4 @ > mixlen?
507 blt .mpf_mix_adv @ no, mix and process tick
508 b .mpf_mix @ yes, mix the rest of samples
512 mov r1, #MPL_SAMPCOUNT @ reset sample counter
515 sub r4, r5 @ subtract from #samples to mix
520 ldr r7,=mmMixerMix @ mix samples
525 ldr r7,=mppProcessTick
528 b .mpf_mix_advr @ process more samples
531 @ add samples remaining to SAMPCOUNT
532 @ and mix more samples
534 mov r1, #MPL_SAMPCOUNT
544 ret1 @ return to user
548 @ main layer isn't active,
563 //-----------------------------------------------------------------------------
565 //-----------------------------------------------------------------------------
569 /******************************************************************************
573 ******************************************************************************/
577 //-----------------------------------------------------------------------------
579 //-----------------------------------------------------------------------------
585 /******************************************************************************
588 * Function to disable interrupts via the status register
589 ******************************************************************************/
590 .global mmSuspendIRQ_t
602 str r1, previous_irq_state
606 /******************************************************************************
609 * Function to enable interrupts via the status register
610 ******************************************************************************/
611 .global mmRestoreIRQ_t
620 ldr r1, previous_irq_state
632 /******************************************************************************
635 * Returns true if the system is ready for playback
636 ******************************************************************************/
637 .global mmIsInitialized
640 ldr r0,=mmInitialized
644 /******************************************************************************
648 ******************************************************************************/
660 ldr r0,=0x400 // set volumes
661 bl mmSetModuleVolume //
663 bl mmSetJingleVolume //
665 bl mmSetEffectsVolume //
667 ldr r0,=mmInitialized // set initialized flag
671 ldr r0,=0xFFFF // select all hardware channels
672 bl mmUnlockChannels //
674 ldr r0,=mm_achannels // setup channel addresses
675 ldr r1,=mm_rds_achannels //
677 ldr r1,=mm_rds_pchannels //
679 mov r1, #32 // 32 channels
691 bl mmMixerInit // setup mixer
693 ldr r0,=mmEventForwarder // forward events
696 ldr r0,=mmInitialized // set initialized flag
704 /******************************************************************************
705 * mmInstall( channel )
707 * Install ARM7 system
708 ******************************************************************************/
714 ldr r1,=mmInitialized // not initialized until we get soundbank data
718 bl mmSetupComms // setup communication
722 /******************************************************************************
723 * mmEventForwarder( msg, param )
725 * Forward event to arm9
726 ******************************************************************************/
739 /******************************************************************************
740 * mmGetSoundBank( n_songs, bank )
742 * Load sound bank address
743 ******************************************************************************/
744 .global mmGetSoundBank
747 ldr r2,=mmModuleCount // save data
748 stmia r2!, {r0,r1} //
750 lsl r0, #2 // also sample bank address
754 //------------------------------------------------
756 //------------------------------------------------
760 /******************************************************************************
764 ******************************************************************************/
771 ldr r0,=mmInitialized // catch not-initialized
776 bl mmMixerPre // <-- critical timing
778 ldr r0,=0x4000208 // enable irq
782 bl mmUpdateEffects // update sound effects
783 bl mmPulse // update module playback
784 bl mmMixerMix // update audio
787 bl mmSendUpdateToARM9
789 1: bl mmProcessComms // process communications
795 //-----------------------------------------------------------------------------
797 //-----------------------------------------------------------------------------
799 //-----------------------------------------------------------------------------
801 //-----------------------------------------------------------------------------