curved tunnel
[gbajam21] / libs / maxmod / mm_mas.S
1 /****************************************************************************
2  *                                                          __              *
3  *                ____ ___  ____ __  ______ ___  ____  ____/ /              *
4  *               / __ `__ \/ __ `/ |/ / __ `__ \/ __ \/ __  /               *
5  *              / / / / / / /_/ />  </ / / / / / /_/ / /_/ /                *
6  *             /_/ /_/ /_/\__,_/_/|_/_/ /_/ /_/\____/\__,_/                 *
7  *                                                                          *
8  *                            Module Processing                             *
9  *                                                                          *
10  *         Copyright (c) 2008, Mukunda Johnson (mukunda@maxmod.org)         *
11  *                                                                          *
12  * Permission to use, copy, modify, and/or distribute this software for any *
13  * purpose with or without fee is hereby granted, provided that the above   *
14  * copyright notice and this permission notice appear in all copies.        *
15  *                                                                          *
16  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
17  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         *
18  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  *
19  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   *
20  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    *
21  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  *
22  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           *
23  ****************************************************************************/
24
25 #include "mp_format_mas.inc"
26 #include "mp_mas_structs.inc"
27 #include "mp_defs.inc"
28 #include "mp_macros.inc"
29
30 //-----------------------------------------------------------------------------
31 #ifdef SYS_GBA
32 //-----------------------------------------------------------------------------
33
34 #include "mp_mixer_gba.inc"
35 #include "swi_gba.inc"
36
37 //-----------------------------------------------------------------------------
38 #endif
39 //-----------------------------------------------------------------------------
40
41 //-----------------------------------------------------------------------------
42 #ifdef SYS_NDS
43 //-----------------------------------------------------------------------------
44 #include "mp_mixer_ds.inc"
45 #include "swi_nds.inc"
46 //-----------------------------------------------------------------------------
47 #endif
48 //-----------------------------------------------------------------------------
49
50
51 .equ    S3M_FREQ_DIVIDER        ,57268224       // (s3m,xm,it)
52 .equ    MOD_FREQ_DIVIDER_PAL    ,56750314       // (mod)
53 .equ    MOD_FREQ_DIVIDER_NTSC   ,57272724       // (---)
54
55
56
57 /******************************************************************************
58  *
59  * Memory
60  *
61  ******************************************************************************/
62
63
64
65         .BSS
66         .ALIGN 2
67
68 /******************************************************************************
69  * mmLayerMain
70  *
71  * Layer data for module playback.
72  ******************************************************************************/
73                                                         .global mmLayerMain
74 mmLayerMain:            .space MPL_SIZE
75
76 /******************************************************************************
77  * mmLayerSub
78  *
79  * Layer data for jingle playback.
80  ******************************************************************************/
81                                                         .global mmLayerSub
82 mmLayerSub:             .space MPL_SIZE
83
84 /******************************************************************************
85  * mpp_vars
86  *
87  * Holds intermediate data during the module processing.
88  ******************************************************************************/
89                                                         .global mpp_vars
90 mpp_vars:               .space MPV_SIZE
91
92         .ALIGN 2
93
94 /******************************************************************************
95  * mpp_layerp
96  *
97  * Pointer to layer data during processing.
98  ******************************************************************************/
99                                                         .global mpp_layerp
100 mpp_layerp:             .space 4
101
102 /******************************************************************************
103  * mpp_channels
104  *
105  * Pointer to channel array during processing
106  ******************************************************************************/
107                                                         .global mpp_channels
108 mpp_channels:           .space 4
109
110 /******************************************************************************
111  * mpp_resolution
112  *
113  * Speed divider for DS timing.
114  ******************************************************************************/
115  
116 mpp_resolution:         .space 4
117
118 /******************************************************************************
119  * mm_mastertempo
120  *
121  * Master tempo scaler.
122  ******************************************************************************/
123  
124 mm_mastertempo:         .space 4
125
126 /******************************************************************************
127  * mm_masterpitch
128  * 
129  * Master pitch scaler.
130  ******************************************************************************/
131  
132 mm_masterpitch:         .space 4
133
134 /******************************************************************************
135  * mpp_nchannels
136  *
137  * Number of channels in layer
138  ******************************************************************************/
139                                                         .global mpp_nchannels
140 mpp_nchannels:          .space 1
141
142 /******************************************************************************
143  * mpp_clayer
144  *
145  * Layer selection, 0 = main, 1 = sub
146  ******************************************************************************/
147                                                         .global mpp_clayer
148 mpp_clayer:             .space 1
149
150 /******************************************************************************
151  * mm_achannels, mm_pchannels, mm_num_mch, mm_num_ach, mm_schannels
152  *
153  * Channel data/sizes, don't move these around--see mmInit first
154  ******************************************************************************/
155                                                         .ALIGN 2
156                                                         
157 .global mm_achannels, mm_pchannels, mm_num_mch, mm_num_ach, mm_schannels
158                                                 
159 mm_achannels:           .space 4
160 mm_pchannels:           .space 4
161 mm_num_mch:             .space 4
162 mm_num_ach:             .space 4
163 mm_schannels:           .space MP_SCHANNELS*MCH_SIZE
164
165
166
167 /******************************************************************************
168  * 
169  * Macros
170  *
171  ******************************************************************************/
172
173
174 /******************************************************************************
175  * mpp_InstrumentPointer
176  *
177  * Calculate instrument address.
178  * Requires r8 = layer
179  * Returns in r0
180  * Trashes r1, r2
181  ******************************************************************************/
182 .macro mpp_InstrumentPointer
183         mov     r1, r8  
184         ldr     r2,[r1,#MPL_SONGADR]    
185         ldr     r1,[r1,#MPL_INSTTABLE]  
186         lsl     r0, #2                  
187         ldr     r0,[r1,r0]              
188         add     r0, r2
189 .endm
190
191 /******************************************************************************
192  * mpp_SamplePointer
193  *
194  * Calculate sample address.
195  * Requires r8 = layer
196  * Returns in r0
197  * Trashes r1, r2
198  ******************************************************************************/
199 .macro mpp_SamplePointer        
200         mov     r1, r8          
201         ldr     r2,[r1,#MPL_SONGADR]    
202         ldr     r1,[r1,#MPL_SAMPTABLE]  
203         lsl     r0, #2                  
204         ldr     r0,[r1,r0]              
205         add     r0, r2
206 .endm
207
208
209
210 /******************************************************************************
211  *
212  * Program
213  *
214  ******************************************************************************/
215
216
217
218         .TEXT
219         .ALIGN 2
220
221 /******************************************************************************
222  * mpp_resetchannels(...)
223  *
224  * Reset channel data, and any active channels linked to the layer.
225  * Requires r5 = layer, r6 = channels, r7 = #channels
226  ******************************************************************************/
227                                                         .thumb_func
228 mpp_resetchannels:
229
230         push    {r4-r6}
231
232         mov     r0, r6                                  // clear channel data to 0
233         mov     r1, #MCH_SIZE/4                         //
234         mul     r1, r7                                  //
235         mov     r2, #0                                  //
236 1:      stmia   r0!, {r2}                               //
237         sub     r1, #1                                  //
238         bne     1b                                      //
239         
240         mov     r0, r6                                  // reset channel indexes
241         sub     r0, #MCH_SIZE-MCH_ALLOC                 //
242         mov     r1, #MCH_SIZE                           //
243         mul     r1, r7                                  //
244         mov     r2, #255                                //
245 1:      strb    r2, [r0, r1]                            //
246         sub     r1, #MCH_SIZE                           //
247         bne     1b                                      //
248
249         GET_MIXCH r4                                    // reset active channels linked to this layer
250         ldr     r6,=mpp_clayer                          //
251         ldrb    r6, [r6]                                //
252
253 #ifdef SYS_GBA                                          // disabled status differs between systems
254         ldr     r5,=1<<31                               //
255 #endif                                                  //
256 #ifdef SYS_NDS                                          //
257         mov     r5, #0                                  //
258 #endif                                                  //
259
260         ldr     r0,=mm_achannels                        // r0 = achannels
261         ldr     r0, [r0]                                //
262         ldr     r1,=mm_num_ach                          // r1 = #achannels
263         ldr     r1, [r1]                                //
264         mov     r2, #0                                  // r2 = 0 (for clearing)
265         
266 .mpic_loop3:
267         ldrb    r3, [r0, #MCA_FLAGS]                    // test if layer matches
268         lsr     r3, #6                                  //
269         cmp     r3, r6                                  //
270         bne     .mpic_l3_skip                           //
271
272         mov     r3, #MCA_SIZE-4                         // clear achannel data to zero
273 .mpic_loop4:                                            //
274         str     r2, [r0, r3]                            //
275         sub     r3, r3, #4                              //
276         bpl     .mpic_loop4                             //
277
278         str     r5, [r4]                                // disable mixer channel
279         
280 .mpic_l3_skip:
281         
282         add     r0, #MCA_SIZE                           // increment stuff and loop
283         add     r4, #MIXER_CHN_SIZE                     //
284                                                         //
285         sub     r1, #1                                  //
286         bne     .mpic_loop3                             //
287         
288         pop     {r4-r6}
289         bx      lr
290
291 #ifdef SYS_NDS
292
293 /******************************************************************************
294  * mm_reset_channels()
295  *
296  * Reset all channels.
297  ******************************************************************************/
298                                                 .global mm_reset_channels
299                                                 .thumb_func
300 mm_reset_channels:
301
302         push    {lr}
303         
304         ldr     r0,=mm_achannels                // clear active channel data
305         ldr     r0, [r0]                        //
306         mov     r1, #0                          //
307         ldr     r2,=MCA_SIZE*32/4               //
308                                                 //
309 1:      stmia   r0!, {r1}                       //
310         sub     r2, #1                          //
311         bne     1b                              //
312         
313         ldr     r0,=mm_pchannels                // reset channel allocation
314         ldr     r0, [r0]                        //
315         mov     r1, #255                        //
316         mov     r2, #32                         //
317                                                 //
318 1:      strb    r1, [r0, #MCH_ALLOC]            //
319         add     r0, #MCH_SIZE                   //
320         sub     r2, #1                          //
321         bne     1b                              //
322         
323         ldr     r0,=mm_schannels                // reset channel allocation
324         mov     r2, #4                          //
325                                                 //
326 1:      strb    r1, [r0, #MCH_ALLOC]            //
327         add     r0, #MCH_SIZE                   //
328         sub     r2, #1                          //
329         bne     1b                              //
330         
331         bl      mmResetEffects
332         
333         pop     {r3}
334         bx      r3
335         
336 #endif
337
338 /******************************************************************************
339  * mpp_suspend()
340  *
341  * Suspend main module and associated channels.
342  ******************************************************************************/
343                                                 .thumb_func
344 mpp_suspend:
345
346         push    {r4,lr}
347         ldr     r0,=mm_achannels
348         ldr     r0, [r0]
349         GET_MIXCH r1
350         ldr     r2,=mm_num_ach
351         ldr     r2, [r2]
352         mov     r4, #0
353 .mpps_loop:
354         ldrb    r3, [r0, #MCA_FLAGS]
355         lsr     r3, #6
356         bne     .mpps_next
357 #ifdef SYS_GBA 
358         str     r4, [r1, #MIXER_CHN_FREQ]
359 #else
360         strh    r4, [r1, #MIXER_CHN_FREQ]
361         strh    r4, [r1, #MIXER_CHN_VOL]
362 #endif
363
364 .mpps_next:
365         add     r0, #MCA_SIZE
366         add     r1, #MIXER_CHN_SIZE
367         sub     r2, #1
368         bne     .mpps_loop
369         
370         pop     {r4, pc}
371
372 /******************************************************************************
373  *
374  * NDS System
375  *
376  ******************************************************************************/
377
378 //-----------------------------------------------------------------------------
379 #ifdef SYS_NDS
380 //-----------------------------------------------------------------------------
381
382 /******************************************************************************
383  * mmStart( module_ID, mode )
384  *
385  * Start module playback.
386  *
387  * module_ID : Index of module.
388  * mode : Playback mode.
389  ******************************************************************************/
390                                                         .global mmStart
391                                                         .thumb_func
392 mmStart:
393         
394         mov     r2, #0
395 .mpps_backdoor:
396         lsl     r0, #2
397         ldr     r3,=mmModuleBank
398         ldr     r3, [r3]
399         ldr     r0, [r3, r0]
400         
401         cmp     r0, #0
402         beq     1f
403         add     r0, #8
404         b       mmPlayModule
405 1:      bx      lr
406
407 /******************************************************************************
408  * mmJingle( module_ID )
409  *
410  * Play module as jingle.
411  *
412  * module_ID : Index of module
413  ******************************************************************************/
414                                                         .global mmJingle
415                                                         .thumb_func
416 mmJingle:
417         
418         mov     r2, #1
419         mov     r1, #MPP_PLAY_ONCE
420         b       .mpps_backdoor
421         
422 //-----------------------------------------------------------------------------
423 #endif
424 //-----------------------------------------------------------------------------
425
426 /******************************************************************************
427  *
428  * GBA System
429  *
430  ******************************************************************************/
431  
432 //-----------------------------------------------------------------------------
433 #ifdef SYS_GBA
434 //-----------------------------------------------------------------------------
435
436 /******************************************************************************
437  * mmStart( module_ID, mode )
438  *
439  * Start module playback
440  *
441  * module_ID : id of module
442  * mode : mode of playback
443  ******************************************************************************/
444                                                         .global mmStart
445                                                         .thumb_func
446 mmStart:
447
448         mov     r2, #0
449 .mpps_backdoor:
450         push    {r2}
451         ldr     r2,=mp_solution         @ resolve song address
452         ldr     r2, [r2]
453         ldrh    r3, [r2, #0]
454         lsl     r3, #2
455         add     r3, #12
456         add     r3, r2
457         lsl     r0, #2
458         add     r0, r3
459         ldr     r0, [r0]
460         add     r0, r2
461         
462         pop     {r2}
463         
464         add     r0, #8
465
466         b       mmPlayModule
467 1:      bx      lr
468
469 /******************************************************************************
470  * mmJingle( module_ID )
471  *
472  * Start jingle playback
473  *
474  * module_ID : index of module
475  ******************************************************************************/
476                                                         .global mmJingle
477                                                         .thumb_func
478 mmJingle:
479
480         mov     r2, #1
481         mov     r1, #MPP_PLAY_ONCE
482         b       .mpps_backdoor
483
484 //-----------------------------------------------------------------------------
485 #endif
486 //-----------------------------------------------------------------------------
487
488 /******************************************************************************
489  * mmPlayModule( address, mode, layer )
490  *
491  * Start playing module.
492  ******************************************************************************/
493                                                         .global mmPlayModule
494                                                         .thumb_func
495 mmPlayModule:
496         
497         push    {lr}
498         push    {r4-r7}
499         
500         ldr     r3,=mpp_clayer
501         strb    r2, [r3]
502         
503         cmp     r2, #0
504         bne     1f
505         ldr     r5,=mmLayerMain
506         @ldr    r6,=mpp_pchannels
507         ldr     r6,=mm_pchannels
508         ldr     r6,[r6]
509         @mov    r7, #MP_MCHANNELS
510         ldr     r7,=mm_num_mch
511         ldr     r7,[r7]
512         b       2f
513 1:      ldr     r5,=mmLayerSub
514         ldr     r6,=mm_schannels
515         mov     r7, #MP_SCHANNELS
516 2:
517 //      push    {r2}
518         
519         mov     r2, #MPL_MODE
520         strb    r1, [r5, r2]
521
522         mov     r4, r0
523         str     r4, [r5, #MPL_SONGADR]
524         
525         bl      mpp_resetchannels
526         
527         ldrb    r3, [r4, #C_MAS_INSTN]
528         ldrb    r2, [r4, #C_MAS_SAMPN]
529         lsl     r3, #2
530         lsl     r2, #2
531         
532         mov     r0, r4
533         add     r0, #255
534         add     r0, #C_MAS_TABLES-255
535         
536         str     r0, [r5, #MPL_INSTTABLE]        @ setup instrument table
537         add     r0, r3
538         str     r0, [r5, #MPL_SAMPTABLE]        @ setup sample table
539         add     r0, r2
540         str     r0, [r5, #MPL_PATTTABLE]        @ setup pattern table
541
542         mov     r0, #0          @ set pattern to 0
543         
544         @ldr    r1,=mpp_setposition
545         @bl     mpp_call_r1
546         bl      mpp_setposition
547         
548         ldrb    r0, [r4, #C_MAS_TEMPO]  @ load initial tempo
549         
550         bl      mpp_setbpm
551         
552         ldrb    r0, [r4, #C_MAS_GV]     @ load initial global volume
553         
554
555         strb    r0, [r5, #MPL_GV]
556
557         ldrb    r0, [r4, #C_MAS_FLAGS]  @ read song flags
558         strb    r0, [r5, #MPL_FLAGS]    @ save
559         
560         lsl     r0, #32-2
561         lsr     r0, #32-2+1
562         strb    r0, [r5, #MPL_OLDEFFECTS]
563
564         ldrb    r0, [r4, #C_MAS_SPEED]  @ speed
565         strb    r0, [r5, #MPL_SPEED]            @ and set
566         
567         mov     r0, #1                          // mpp_playing=true
568         strb    r0, [r5, #MPL_ISPLAYING]
569         
570         mov     r1, #MPL_VALID                  // set valid flag
571         strb    r0, [r5, r1]                    //
572
573         bl      mpp_resetvars
574         
575         @ setup channel volumes
576         mov     r0, r6
577         add     r0, #MCH_CVOLUME
578         mov     r3, r7
579         add     r4, #C_MAS_CHANVOL
580 .cvol_setup:
581         ldrb    r1, [r4]
582         strb    r1, [r0]
583         add     r0, #MCH_SIZE
584         add     r4, #1
585         sub     r3, #1
586         bne     .cvol_setup
587         
588         add     r4, #32
589         sub     r4, r7
590         
591         mov     r0, r6
592         add     r0, #MCH_PANNING
593         mov     r3, r7
594 .cpan_setup:
595         ldrb    r1, [r4]
596         strb    r1, [r0]
597         add     r0, #MCH_SIZE
598         add     r4, #1
599         sub     r3, #1
600         bne     .cpan_setup
601
602 //      pop     {r2}            @ <-- FIX.2 WHY WAS THIS PRESERVED
603         
604         pop     {r4-r7}
605         pop     {r0}            @ return
606         
607         bx      r0              @
608 .pool
609
610 /******************************************************************************
611  * mmPause()
612  *
613  * Pause module playback.
614  ******************************************************************************/
615                                                         .global mmPause
616                                                         .thumb_func
617 mmPause:
618         
619         push    {lr}
620         push    {r5}
621         
622         ldr     r5,=mmLayerMain
623         
624         mov     r0, #MPL_VALID
625         ldrb    r0, [r5, r0]
626         cmp     r0, #0
627         beq     1f
628         
629         mov     r0, #0
630         strb    r0, [r5, #MPL_ISPLAYING]
631         
632         bl      mpp_suspend
633         
634 1:      pop     {r5}
635         ret0
636
637 /******************************************************************************
638  * mmResume()
639  *
640  * Resume module playback.
641  ******************************************************************************/
642                                                         .global mmResume
643                                                         .thumb_func
644 mmResume:
645
646         ldr     r1,=mmLayerMain
647         mov     r0, #MPL_VALID
648         ldrb    r0, [r1, r0]
649         cmp     r0, #0
650         beq     1f
651         
652         mov     r0, #1
653         strb    r0, [r1, #MPL_ISPLAYING]
654 1:      bx      lr
655
656 /******************************************************************************
657  * mmActive()
658  *
659  * Returns true if module is playing.
660  ******************************************************************************/
661                                                         .global mmActive
662                                                         .thumb_func
663 mmActive:
664
665         ldr     r0,=mmLayerMain
666         ldrb    r0, [r0, #MPL_ISPLAYING]
667         bx      lr
668
669 /******************************************************************************
670  * mmActiveSub()
671  *
672  * Returns true if a jingle is playing.
673  ******************************************************************************/
674                                                         .global mmActiveSub
675                                                         .thumb_func
676 mmActiveSub:
677         
678         ldr     r0,=mmLayerSub
679         ldrb    r0, [r0, #MPL_ISPLAYING]
680         bx      lr
681
682 /******************************************************************************
683  * mmSetModuleVolume( volume )
684  *
685  * Set master module volume.
686  *
687  * volume : 0->1024
688  ******************************************************************************/
689                                                         .global mmSetModuleVolume
690                                                         .thumb_func
691 mmSetModuleVolume:
692
693 @ clamp volume 0->1024
694         lsr     r1, r0, #10
695         beq     1f
696         mov     r0, #1
697         lsl     r0, #10
698
699 @ set volume
700 1:      ldr     r1,=mmLayerMain
701         mov     r2, #MPL_VOLUME
702         strh    r0, [r1, r2]
703         bx      lr
704
705 /******************************************************************************
706  * mmSetJingleVolume( volume )
707  *
708  * Set master jingle volume.
709  *
710  * volume : 0->1024
711  ******************************************************************************/
712                                                         .global mmSetJingleVolume
713                                                         .thumb_func
714 mmSetJingleVolume:
715
716 @ clamp volume 0->1024
717         lsr     r1, r0, #10
718         beq     1f
719         mov     r0, #1
720         lsl     r0, #10
721
722 @ set volume
723 1:      ldr     r1,=mmLayerSub @mpp_layerB
724         mov     r2, #MPL_VOLUME
725         strh    r0, [r1, r2]
726         bx      lr
727
728 /******************************************************************************
729  * mppStop() [[internal function]]
730  *
731  * Stop module playback.
732  ******************************************************************************/
733                                                         .thumb_func
734 mppStop:
735
736         push    {lr}
737
738         ldr     r0,=mpp_clayer
739         ldrb    r0, [r0]
740         
741         cmp     r0, #0
742         beq     1f
743         ldr     r5,=mmLayerSub
744         ldr     r6,=mm_schannels
745         mov     r7, #MP_SCHANNELS
746         b       2f
747 1:      ldr     r5,=mmLayerMain
748         @ldr    r6,=mpp_pchannels
749         ldr     r6,=mm_pchannels
750         ldr     r6,[r6]
751         @mov    r7, #MP_MCHANNELS
752         ldr     r7,=mm_num_mch
753         ldr     r7,[r7]
754 2:
755         
756         mov     r0, #0
757         strb    r0, [r5, #MPL_ISPLAYING]
758         
759         mov     r1, #MPL_VALID
760         strb    r0, [r5, r1]
761         
762         bl      mpp_resetchannels
763         pop     {r0}
764         bx      r0
765
766 /******************************************************************************
767  * mmGetPosition()
768  *
769  * Get playback position
770  ******************************************************************************/
771                                                         .global mmGetPosition
772                                                         .thumb_func
773 mmGetPosition:
774         
775         ldr     r1,=mmLayerMain
776         ldrb    r0, [r1, #MPL_POSITION]
777         bx      lr
778         
779 /******************************************************************************
780  * mmPosition( position )
781  *
782  * Set playback position
783  ******************************************************************************/
784                                                         .global mmPosition
785                                                         .thumb_func
786 mmPosition:
787         
788         push    {r4-r7,lr}
789         ldr     r5,=mmLayerMain
790         ldr     r6,=mm_pchannels
791         ldr     r6,[r6]
792         ldr     r7,=mm_num_mch
793         ldr     r7, [r7]
794         
795         push    {r0}
796 //      bl      mpp_resetchannels
797         
798         pop     {r0}
799         bl      mpp_setposition
800
801         pop     {r4-r7}
802         pop     {r3}
803         bx      r3
804         
805 /******************************************************************************
806  * mmSetModuleTempo( tempo )
807  *
808  * Set master tempo
809  *
810  * tempo : x.10 fixed point tempo, 0.5->2.0
811  ******************************************************************************/
812                                                         .global mmSetModuleTempo
813                                                         .thumb_func
814 mmSetModuleTempo:
815         
816         push    {r5,lr}
817         
818         mov     r1, #1                          // clamp value: 512->2048
819         lsl     r1, #11                         //
820         cmp     r0, r1                          //
821         ble     1f                              //
822         mov     r0, r1                          //
823 1:      mov     r1, #1                          //
824         lsl     r1, #9                          //
825         cmp     r0, r1                          //
826         bge     1f                              //
827         mov     r0, r1                          //
828 1:
829         
830         ldr     r1,=mm_mastertempo
831         str     r0, [r1]
832         
833         ldr     r5,=mmLayerMain
834         ldr     r0,=mpp_clayer
835         mov     r1, #0
836         strb    r1, [r0]
837         
838         ldrb    r0, [r5, #MPL_BPM]
839         cmp     r0, #0
840         beq     1f
841         bl      mpp_setbpm
842         
843 1:      pop     {r5}
844         pop     {r3}
845         bx      r3
846         
847 /******************************************************************************
848  * mmSetModulePitch( pitch )
849  *
850  * Set master pitch
851  *
852  * pitch : x.10 fixed point value, range = 0.5->2.0
853  ******************************************************************************/
854                                                         .global mmSetModulePitch
855                                                         .thumb_func
856 mmSetModulePitch:
857         push    {r5,lr}
858         
859         mov     r1, #1                          // clamp value: 512->2048
860         lsl     r1, #11                         //
861         cmp     r0, r1                          //
862         ble     1f                              //
863         mov     r0, r1                          //
864 1:      mov     r1, #1                          //
865         lsl     r1, #9                          //
866         cmp     r0, r1                          //
867         bge     1f                              //
868         mov     r0, r1                          //
869 1:
870         
871         ldr     r1,=mm_masterpitch
872         str     r0, [r1]
873         
874 1:      pop     {r5}
875         pop     {r3}
876         bx      r3
877         
878 .pool
879
880 //-----------------------------------------------------------------------------
881 #ifdef SYS_NDS7
882 //-----------------------------------------------------------------------------
883
884 /******************************************************************************
885  * mmSetResolution( divider )
886  *
887  * Set update resolution
888  ******************************************************************************/
889                                                         .global mmSetResolution
890                                                         .thumb_func
891 mmSetResolution:
892
893         push    {r5, lr}
894         
895         ldr     r1,=mpp_resolution
896         str     r0, [r1]
897         
898         ldr     r5,=mmLayerMain
899         
900         ldr     r0,=mpp_clayer
901         mov     r1, #0
902         strb    r1, [r0]
903         
904         ldrb    r0, [r5, #MPL_BPM]
905         cmp     r0, #0
906         beq     1f
907         bl      mpp_setbpm
908 1:      ldr     r5,=mmLayerSub
909
910         ldr     r0,=mpp_clayer
911         mov     r1, #1
912         strb    r1, [r0]
913         
914         ldrb    r0, [r5, #MPL_BPM]
915         cmp     r0, #0
916         beq     1f
917         bl      mpp_setbpm
918 1:      pop     {r5}
919         pop     {r3}
920         bx      r3
921
922 #endif
923
924 /******************************************************************************
925  * mmStop()
926  *
927  * Stop module playback.
928  ******************************************************************************/
929                                                         .global mmStop
930                                                         .thumb_func
931 mmStop:
932
933         push    {r4-r7,lr}
934         ldr     r1,=mpp_clayer
935         mov     r0, #0
936         strb    r0, [r1]
937         bl      mppStop
938         pop     {r4-r7}
939         ret3
940
941 /******************************************************************************
942  * mpp_resetvars()
943  *
944  * Reset pattern variables
945  * Input r5 = layer
946  ******************************************************************************/
947                                                         .thumb_func
948 mpp_resetvars:
949
950         mov     r0, #255
951         strb    r0, [r5, #MPL_PATTJUMP]
952         mov     r0, #0
953         strb    r0, [r5, #MPL_PATTJUMP_ROW]
954         bx      lr
955
956 /******************************************************************************
957  * mpp_setbpm( bpm )
958  *
959  * Set BPM. bpm = 32..255
960  * Input r5 = layer
961  ******************************************************************************/
962                                                         .thumb_func
963 mpp_setbpm:
964         
965         strb    r0, [r5, #MPL_BPM]
966         
967 #ifdef SYS_GBA
968
969         ldr     r1,=mpp_clayer
970         ldrb    r1, [r1]
971         cmp     r1, #0
972         bne     1f
973         
974         ldr     r1,=mm_mastertempo      // multiply by master tempo
975         ldr     r1, [r1]                //
976         mul     r1, r0                  //
977         lsr     r1, #10                 //
978         
979         ldr     r0,=mm_bpmdv            @ samples per tick ~= mixfreq / (bpm/2.5) ~= mixfreq*2.5/bpm
980         ldr     r0,[r0]
981         
982         swi     SWI_DIVIDE              @ SWI 07h, divide r1/r0
983         lsr     r0, #1                  @ multiple of two
984         lsl     r0, #1                  @ ---------------
985         mov     r1, #MPL_TICKRATE
986         strh    r0, [r5, r1]            @ 
987         mov     r1, #MPL_SAMPCOUNT
988 //      mov     r0, #0
989 //      strh    r0, [r5, r1]
990         bx      lr                      @ return
991         
992 1:      @ SUB LAYER, time using vsync (rate = bpm/2.5 / 59.7)
993         
994         lsl     r0, #15
995         mov     r1, #149
996         swi     SWI_DIVIDE
997         mov     r1, #MPL_TICKRATE
998         strh    r0, [r5, r1]
999         bx      lr
1000         
1001 #endif
1002
1003 #ifdef SYS_NDS
1004
1005 @ vsync = ~59.8261 HZ (says GBATEK)
1006 @ divider = hz * 2.5 * 64
1007
1008         ldr     r1,=mpp_clayer
1009         ldrb    r1, [r1]
1010         cmp     r1, #0
1011         bne     1f
1012         ldr     r1,=mm_mastertempo      // multiply by master tempo
1013         ldr     r1, [r1]                //
1014         mul     r0, r1                  //
1015 //      lsr     r1, #10                 //
1016
1017         lsl     r0, #16+6-10
1018         b       2f
1019 1:
1020         lsl     r0, #16+6
1021 2:
1022         @ using 60hz vsync for timing
1023 //      lsl     r0, #16+6
1024         ldr     r1,=mpp_resolution
1025         ldr     r1, [r1]
1026         swi     SWI_DIVIDE
1027         lsr     r0, #1
1028         mov     r1, #MPL_TICKRATE
1029         strh    r0, [r5, r1]
1030         bx      lr
1031         
1032 #endif
1033
1034 .pool
1035
1036 /******************************************************************************
1037  * mpp_setposition( position )
1038  *
1039  * Set sequence position.
1040  * Input r5 = layer
1041  ******************************************************************************/
1042                                                         .thumb_func
1043 mpp_setposition:
1044         
1045         push    {lr}
1046         
1047 mpp_setpositionA:
1048         
1049         strb    r0, [r5, #MPL_POSITION]
1050         
1051         ldr     r1, [r5, #MPL_SONGADR]
1052         mov     r3, r1
1053         add     r1, #C_MAS_ORDER        @ get sequence entry
1054         ldrb    r1, [r1, r0]            @
1055         
1056         cmp     r1, #254
1057         bne     .mpsp_skippatt
1058         add     r0, #1
1059         b       mpp_setpositionA
1060 .mpsp_skippatt:
1061         
1062         cmp     r1, #255
1063         bne     .mpsp_endsong
1064         
1065         @ END OF SONG!!! WOOPHEE!!!!
1066         
1067
1068         mov     r0, #MPL_MODE @mpp_playmode
1069         ldrb    r0, [r5, r0]
1070         
1071         cmp     r0, #MPP_PLAY_ONCE
1072         bge     1f
1073 @       @ its looping:
1074         b       3f
1075
1076 1:      @ its playing once:
1077
1078         bl      mppStop
1079         mov     r0, #MPCB_SONGFINISHED
1080         ldr     r2,=mmCallback
1081         ldr     r2,[r2]
1082         cmp     r2, #0
1083         beq     3f
1084         ldr     r1,=mpp_clayer
1085         ldrb    r1, [r1]
1086         bl      mpp_call_r2
1087         
1088 3:      
1089         
1090         ldrb    r0, [r5, #MPL_ISPLAYING]
1091         cmp     r0, #0
1092         bne     1f
1093
1094         pop     {pc}
1095
1096 1:      
1097         ldr     r0, [r5, #MPL_SONGADR]  @ set position to 'restart'
1098         ldrb    r0, [r0, #C_MAS_REP]
1099         b       mpp_setpositionA
1100 .mpsp_endsong:
1101         
1102         mov     r0, r1
1103         
1104         ldr     r1, [r5, #MPL_PATTTABLE]
1105         lsl     r0, #2
1106         
1107         @ r1 = pattern address( in table )
1108         
1109         ldr     r1, [r1, r0]
1110         add     r1, r3          @ add song address
1111         
1112         @ r1 = pattern address
1113         
1114         ldrb    r2, [r1]                @ set pattern size
1115         strb    r2, [r5, #MPL_NROWS]    @
1116         
1117         mov     r2, #0                  @ reset tick/row
1118         strh    r2, [r5, #MPL_TICK]
1119         strb    r2, [r5, #MPL_FPATTDELAY]
1120         strb    r2, [r5, #MPL_PATTDELAY]
1121
1122         mov     r0, #MPL_PATTREAD
1123         add     r1, #1
1124         str     r1, [r5, r0]            @ store pattern data address
1125
1126         mov     r0, #MPL_PLOOP_ADR              @ reset pattern loop
1127         str     r1, [r5, r0]
1128         mov     r0, #0
1129         strb    r0, [r5, #MPL_PLOOP_ROW]
1130         strb    r0, [r5, #MPL_PLOOP_TIMES]
1131         
1132         pop     {pc}
1133
1134 //-----------------------------------------------------------------------------
1135 #ifdef SYS_NDS
1136 //-----------------------------------------------------------------------------
1137
1138 /******************************************************************************
1139  * mppUpdateLayer( layer )
1140  *
1141  * Update module layer
1142  ******************************************************************************/
1143                                                         .thumb_func
1144 mppUpdateLayer:
1145
1146         push    {lr}
1147         ldr     r1,=mpp_layerp
1148         str     r0, [r1]
1149         mov     r1, #MPL_TICKRATE
1150         ldrh    r1, [r0, r1]    
1151         mov     r2, #MPL_TICKFRAC
1152         ldrh    r3, [r0, r2]
1153         lsl     r1, #1
1154         add     r3, r1
1155         strh    r3, [r0, r2]
1156         lsr     r3, #16
1157         beq     1f
1158 2:      push    {r3}
1159         
1160         bl      mppProcessTick
1161         pop     {r3}
1162         sub     r3, #1
1163         bne     2b
1164 1:      pop     {pc}
1165
1166 /******************************************************************************
1167  * mmPulse()
1168  *
1169  * NDS Work Routine
1170  ******************************************************************************/
1171                                                 .global mmPulse
1172                                                 .thumb_func
1173 mmPulse:
1174                 
1175         push    {lr}
1176         
1177         ldr     r0,=mpp_channels                // update main layer
1178         ldr     r1,=mm_pchannels                //
1179         ldr     r1,[r1]                         //
1180         str     r1, [r0]                        //
1181         ldr     r0,=mpp_nchannels               //
1182         ldr     r1,=mm_num_mch                  //
1183         ldr     r1,[r1]                         //
1184         strb    r1, [r0]                        //
1185         ldr     r0,=mpp_clayer                  //
1186         mov     r1, #0                          //
1187         strb    r1, [r0]                        //
1188                                                 //
1189         ldr     r0,=mmLayerMain                 //
1190         bl      mppUpdateLayer                  //
1191
1192         ldr     r0,=mpp_channels                // update sub layer
1193         ldr     r1,=mm_schannels                //
1194         str     r1, [r0]                        //
1195         ldr     r0,=mpp_nchannels               //
1196         mov     r1, #MP_SCHANNELS               //
1197         strb    r1, [r0]                        //
1198         ldr     r0,=mpp_clayer                  //
1199         mov     r1, #1                          //
1200         strb    r1, [r0]                        //
1201                                                 //
1202         ldr     r0,=mmLayerSub                  //
1203         bl      mppUpdateLayer                  //
1204         
1205         pop     {pc}
1206         
1207 //-----------------------------------------------------------------------------
1208 #endif
1209 //-----------------------------------------------------------------------------
1210
1211 //-----------------------------------------------------------------------------
1212 #ifdef SYS_GBA
1213 //-----------------------------------------------------------------------------
1214
1215 /******************************************************************************
1216  * mppUpdateSub()
1217  *
1218  * Update sub-module/jingle, this is bad for some reason...
1219  ******************************************************************************/
1220                                                 .global mppUpdateSub
1221                                                 .thumb_func
1222 mppUpdateSub:
1223         
1224         ldr     r0,=mmLayerSub
1225         ldrb    r0, [r0, #MPL_ISPLAYING]
1226         cmp     r0, #0
1227         bne     .mppus_update
1228         bx      lr
1229 .mppus_update:
1230         
1231         ldr     r0,=mpp_channels
1232         ldr     r1,=mm_schannels
1233         str     r1, [r0]
1234         ldr     r0,=mpp_nchannels
1235         mov     r1, #MP_SCHANNELS
1236         strb    r1, [r0]
1237         ldr     r0,=mpp_clayer
1238         mov     r1, #1
1239         strb    r1, [r0]
1240         
1241         push    {lr}
1242         ldr     r0,=mmLayerSub
1243         ldr     r1,=mpp_layerp
1244         str     r0, [r1]
1245         
1246         mov     r1, #MPL_TICKRATE
1247         ldrh    r1, [r0, r1]
1248         mov     r2, #MPL_TICKFRAC
1249         ldrh    r3, [r0, r2]
1250         lsl     r1, #1
1251         add     r3, r1
1252         strh    r3, [r0, r2]
1253         lsr     r3, #16
1254         beq     1f
1255 2:      push    {r3}
1256         ldr     r1,=mppProcessTick
1257         bl      mpp_call_r1
1258         pop     {r3}
1259         sub     r3, #1
1260         bgt     2b
1261 1:      pop     {pc}
1262         
1263 //-----------------------------------------------------------------------------
1264 #endif
1265 //-----------------------------------------------------------------------------
1266
1267 .pool
1268
1269 //-----------------------------------------------------------------------------
1270 // IWRAM CODE
1271 //-----------------------------------------------------------------------------
1272 #ifdef USE_IWRAM
1273         .SECTION ".iwram", "ax", %progbits
1274         .ALIGN 2
1275 #endif
1276 //-----------------------------------------------------------------------------
1277
1278 /******************************************************************************
1279  * mppProcessTick()
1280  *
1281  * Process module tick.
1282  ******************************************************************************/
1283 .global mppProcessTick                          @@@@@@@@@@@@@@@@@@
1284 .thumb_func                                     @@@@     @@@     @@
1285                                                 @@@  @@  @@@@@@  @@
1286 mppProcessTick:                                 @@      @@@ @    @@
1287                                                 @@  @@@@@@@    @@@
1288                                                 @@@@@@@@@@@@@@@@@
1289
1290         add     r0,pc,#0                        // switch to ARM to preserve regs
1291         bx      r0                              //
1292 .arm                                            //
1293         stmfd   sp!, {lr}                       //
1294         stmfd   sp!, {r4-r10}                   //
1295         
1296         add     r0,pc,#1                        // switch back to THUMB
1297         bx      r0
1298 .thumb
1299
1300         ldr     r0,=mpp_layerp                  // test if module is playing
1301         ldr     r0, [r0]                        //
1302         mov     r8, r0                          //
1303         ldrb    r1, [r0, #MPL_ISPLAYING]        //
1304         cmp     r1, #0                          //
1305         bne     1f                              //
1306         ldr     r1,=.mppt_exit                  //
1307         mov     pc,r1                           //
1308 1:
1309
1310 @---------------------------------------------------
1311 @ read pattern data
1312 @---------------------------------------------------
1313
1314         ldrb    r1, [r0, #MPL_PATTDELAY]
1315         cmp     r1, #0
1316         bne     .mpp_pt_skippatternread
1317         ldrb    r0, [r0, #MPL_TICK]
1318         cmp     r0, #0
1319         bne     .mpp_pt_skippatternread
1320         
1321         PROF_START
1322         fjump2 mmReadPattern
1323         //bl    mpp_ReadPattern
1324         PROF_END 4
1325
1326 @-----------------------------------------      
1327 .mpp_pt_skippatternread:
1328         
1329         mov     r0, r8
1330         mov     r4, #MPL_MCH_UPDATE
1331         ldr     r4, [r0, r4]
1332         
1333 @---------------------------------------------------
1334 @ loop through module channels
1335 @---------------------------------------------------
1336         
1337         ldr     r7,=mpp_channels
1338         ldr     r7, [r7]
1339         mov     r0, #0
1340         mov     r10, r0 @ use r10 as channel counter
1341         mov     r0, r8
1342         ldrb    r0, [r0, #MPL_TICK]
1343         cmp     r0, #0
1344         bne     pchannel_loop_other
1345         
1346 @---------------------------------------------------
1347 pchannel_loop_first:
1348 @---------------------------------------------------    
1349         lsr     r4, #1
1350         bcc     pchannel_empty
1351         fjump2  mmUpdateChannel_T0
1352 pchannel_empty:
1353         mov     r0, #1
1354         add     r10, r0
1355         add     r7, #MCH_SIZE
1356         cmp     r4, #0
1357         bne     pchannel_loop_first
1358         b       pchannel_loop_finished
1359         
1360 @---------------------------------------------------
1361 pchannel_loop_other:
1362 @---------------------------------------------------
1363         lsr     r4, #1
1364         bcc     pchannel_empty2
1365         #ifdef FOO_UC
1366         bl      mpp_Update_Channel
1367         #else
1368         fjump2  mmUpdateChannel_TN
1369         #endif
1370         
1371 pchannel_empty2:
1372         mov     r0, #1
1373         add     r10, r0
1374         add     r7, #MCH_SIZE
1375         cmp     r4, #0
1376         bne     pchannel_loop_other
1377         
1378 pchannel_loop_finished:
1379         
1380 @---------------------------------------------------
1381 @ loop through active channels
1382 @---------------------------------------------------
1383         PROF_START
1384         ldr     r6,=mm_achannels
1385         ldr     r6, [r6]
1386         @ldr    r6,=mpp_achannels
1387         mov     r4, #0
1388         
1389 @---------------------------------------------------    
1390 .mpp_pt_achn_loop:
1391 @---------------------------------------------------
1392
1393         ldrb    r0, [r6, #MCA_TYPE]
1394         cmp     r0, #ACHN_DISABLED
1395         beq     .mpp_pt_achn_disabled
1396         ldr     r0,=mpp_clayer
1397         ldrb    r0, [r0]
1398         ldrb    r1, [r6, #MCA_FLAGS]
1399         lsr     r1, #6
1400         cmp     r1, r0
1401         bne     .mpp_pt_achn_next
1402         
1403         ldr     r1,=mpp_vars
1404         ldrb    r0, [r6, #MCA_VOLUME]
1405         strb    r0, [r1, #MPV_AFVOL]
1406         mov     r0, #0
1407         strh    r0, [r1, #MPV_PANPLUS]
1408         
1409         ldr     r5, [r6, #MCA_PERIOD]
1410         
1411         bl      mpp_Update_ACHN
1412         
1413         b       .mpp_pt_achn_next
1414         
1415 @---------------------------------------------------    
1416 .mpp_pt_achn_disabled:
1417 @       mov     r0, r4
1418 @       bl      mp_Mixer_StopChannel
1419         
1420 @---------------------------------------------------
1421 .mpp_pt_achn_next:
1422 @---------------------------------------------------
1423
1424         ldrb    r0, [r6, #MCA_FLAGS]
1425         mov     r1, #MCAF_UPDATED
1426         bic     r0, r1
1427         strb    r0, [r6, #MCA_FLAGS]
1428         add     r6, #MCA_SIZE
1429         add     r4, #1
1430         ldr     r0,=mm_num_ach
1431         ldr     r0,[r0]
1432         
1433         cmp     r4, r0
1434 @       cmp     r4, #MP_NCHANNELS
1435         bne     .mpp_pt_achn_loop
1436 @---------------------------------------------------
1437         PROF_END 6
1438         
1439         
1440         
1441         ldr     r1,=mppProcessTick_incframe
1442         mov     pc,r1
1443
1444 .pool
1445
1446 //-----------------------------------------------------------------------------
1447 // TEXT Code
1448 //-----------------------------------------------------------------------------
1449         .TEXT
1450         .THUMB
1451         .ALIGN 2
1452 //-----------------------------------------------------------------------------
1453
1454 /******************************************************************************
1455  * mppProcessTick_incframe [[internal]]
1456  ******************************************************************************/
1457                                                 .thumb_func
1458 mppProcessTick_incframe:
1459
1460 @---------------------------------------------------
1461 @ update tick/row/position
1462 @---------------------------------------------------
1463         
1464         mov     r5, r8                          @ get tick#
1465         ldrb    r1, [r5, #MPL_TICK]             @ ..
1466         add     r1, #1                          @ increment
1467         
1468         ldrb    r2, [r5, #MPL_SPEED]            @ compare with speed
1469         cmp     r1, r2                          @ ..
1470         blt     .mppt_continuerow               @ if less than, continue this row
1471         
1472         ldrb    r2, [r5, #MPL_FPATTDELAY]
1473         cmp     r2, #0
1474         beq     .mppt_nofpd
1475         sub     r2, #1
1476         strb    r2, [r5, #MPL_FPATTDELAY]
1477         b       .mppt_continuerow
1478 .mppt_nofpd:
1479         
1480         mov     r1, #0                          @  .. otherwise clear tick count
1481         b       .mppt_nextrow                   @  and advance to next row
1482         
1483 .mppt_continuerow:                              @ continue current row:
1484         strb    r1, [r5, #MPL_TICK]             @ save tick#
1485         b       .mppt_exit                      @ exit
1486         
1487 .mppt_nextrow:                                          @ advance row
1488         
1489         ldrb    r2, [r5, #MPL_PATTDELAY]
1490         cmp     r2, #0
1491         beq     .mppt_nopd
1492         sub     r2, #1
1493         strb    r2, [r5, #MPL_PATTDELAY]
1494         beq     .mppt_nopd
1495         b       .mppt_continuerow
1496 .mppt_nopd:
1497         
1498         strb    r1, [r5, #MPL_TICK]                     @ save tick# (0)
1499         ldrb    r1, [r5, #MPL_PATTJUMP]
1500         cmp     r1, #255
1501         beq     .mppt_no_pj
1502         
1503         mov     r2, #255
1504         strb    r2, [r5, #MPL_PATTJUMP]
1505         mov     r0, r1
1506         bl      mpp_setposition
1507         
1508         ldrb    r1, [r5, #MPL_PATTJUMP_ROW]
1509         cmp     r1, #0
1510         beq     .mppt_pj_no_offset
1511         mov     r2, #0
1512         strb    r2, [r5, #MPL_PATTJUMP_ROW]
1513         bl      mpph_FastForward
1514 .mppt_pj_no_offset:
1515         
1516         b       .mppt_exit
1517         
1518 .mppt_no_pj:
1519         
1520         mov     r3, #MPL_PLOOP_JUMP
1521         ldrb    r1, [r5, r3]
1522         cmp     r1, #0
1523         beq     .mppt_no_ploop
1524         mov     r1, #0
1525         strb    r1, [r5, r3]
1526         ldrb    r1, [r5, #MPL_PLOOP_ROW]
1527         strb    r1, [r5, #MPL_ROW]
1528         mov     r3, #MPL_PLOOP_ADR
1529         ldr     r1, [r5, r3]
1530
1531         mov     r3, #MPL_PATTREAD
1532         str     r1, [r5, r3]
1533         b       .mppt_exit
1534 .mppt_no_ploop:
1535         ldrb    r1, [r5, #MPL_ROW]                      @ ..
1536         add     r1, #1                                  @ increment
1537         ldrb    r2, [r5, #MPL_NROWS]                    @ 
1538         add     r2, #1
1539         cmp     r1, r2                                  @ check with #rows for pattern
1540         bne     .mppt_continuepattern                   @ if !=, then continue playing this pattern
1541         
1542 .mppt_nextposition:                                     @ advance position
1543         
1544         ldrb    r0, [r5, #MPL_POSITION]                 @ increment position
1545         add     r0, #1
1546         
1547         bl      mpp_setposition
1548         b       .mppt_exit
1549         
1550 .mppt_continuepattern:
1551         
1552         strb    r1, [r5, #MPL_ROW]                      @ save row count
1553         
1554 .thumb_func
1555 .mppt_exit:
1556         
1557         @ switch to arm
1558         ldr     r0,=.mppt_exita
1559         bx      r0
1560 .arm
1561 .align 2
1562 .mppt_exita:
1563
1564         ldmfd   sp!, {r4-r10}
1565         ldmfd   sp!, {r0}
1566         bx      r0
1567 .thumb
1568
1569 .pool
1570
1571 //-----------------------------------------------------------------------------
1572 // IWRAM CODE
1573 //-----------------------------------------------------------------------------
1574 #ifdef USE_IWRAM
1575         .SECTION ".iwram", "ax", %progbits
1576         .ALIGN 2
1577 #endif
1578 //-----------------------------------------------------------------------------
1579
1580 /******************************************************************************
1581  * mpp_Channel_NewNote()
1582  *
1583  * Process new note.
1584  * Input r7 = pchannel address
1585  ******************************************************************************/
1586                                                 .global mpp_Channel_NewNote
1587                                                 .thumb_func
1588 mpp_Channel_NewNote:
1589         
1590         @ r7 = pchannel address
1591         push    {r4,lr}
1592
1593         ldrb    r0, [r7, #MCH_INST]             @ get instrument#
1594         sub     r0, #1
1595         bcc     .mppt_skipnna
1596
1597         bl      mpp_Channel_GetACHN
1598         cmp     r6, #0
1599         beq     .mppt_alloc_channel     
1600         
1601         ldrb    r0, [r7, #MCH_INST]             @ get instrument#
1602         sub     r0, #1
1603         
1604         mpp_InstrumentPointer
1605         
1606         ldrb    r1, [r7, #MCH_BFLAGS]           @ fetch NNA
1607         lsr     r1, #6
1608         
1609         beq     .mppt_NNA_CUT                   @ skip if zero
1610         
1611         ldrb    r1, [r0, #C_MASI_DCT]           @ otherwise check duplicate check type
1612         lsl     r1, #32-2
1613         lsr     r1, #32-2
1614         lsl     r1, #1                          @ jump to mppt_DCT_TABLE[dct]
1615         add     r1, pc
1616         mov     pc, r1
1617
1618 .mppt_DCT_TABLE:
1619 b       .mppt_DCNA
1620 b       .mppt_DCT_NOTE
1621 b       .mppt_DCT_SAMP
1622 b       .mppt_DCT_INST
1623 .mppt_DCT_NOTE:                                 @ DCT note ---------------------
1624         ldrb    r1, [r7, #MCH_PNOTE]            @ get pattern note
1625         lsl     r1, #1                          @ translate to real note
1626         add     r1, #C_MASI_MAP                 @ with note/sample map
1627         ldrb    r1, [r0, r1]                    @ r1 = real note
1628         ldrb    r2, [r7, #MCH_NOTE]             @ compare with last note
1629         cmp     r1, r2                          @
1630         beq     .mppt_DCA                       @ equal? perform DCA
1631         b       .mppt_DCNA                      @ otherwise skip
1632         
1633 .mppt_DCT_SAMP:                                 @ DCT sample -------------------
1634         
1635         // **WARNING: code not functional with new instrument table
1636         ldrb    r1, [r7, #MCH_PNOTE]            @ get pattern note
1637         lsl     r1, #1                          @ translate to sample#
1638         add     r1, #C_MASI_MAP+1               @ with note/sample map
1639         ldrb    r1, [r0, r1]                    @ r1 = sample#
1640         ldrb    r2, [r6, #MCA_SAMPLE]           @ compare with achn's sample
1641         cmp     r1, r2                          @
1642         beq     .mppt_DCA                       @ equal? perform DCA
1643         b       .mppt_DCNA                      @ otherwise skip
1644         
1645 .mppt_DCT_INST:                                 @ DCT instrument ---------------
1646         ldrb    r1, [r7, #MCH_INST]             @ load instrument
1647         ldrb    r2, [r6, #MCA_INST]             @ compare with active inst
1648         cmp     r1, r2                          @
1649         bne     .mppt_DCNA                      @ not equal? skip DCA
1650         
1651 .mppt_DCA:                                      @ DUPLICATE CHECK ACTION -------
1652         ldrb    r1, [r0, #C_MASI_DCA]           @ read type
1653         cmp     r1, #IT_DCA_CUT                 @ cut?
1654         beq     .mppt_NNA_CUT                   @   branch
1655         cmp     r1, #IT_DCA_OFF                 @ note-off?
1656         beq     .mppt_NNA_OFF                   @   branch
1657         b       .mppt_NNA_FADE                  @ note-fade otherwise
1658         
1659 .mppt_DCNA:
1660         
1661         ldrb    r1, [r7, #MCH_BFLAGS]
1662         lsr     r1, #6                          @ get NNA
1663         lsl     r1, #1                          @ and jump to
1664         add     r1, pc                          @ NNA_TABLE[NNA]
1665         mov     pc, r1
1666 .mppt_NNA_TABLE:
1667 b       .mppt_NNA_CUT
1668 b       .mppt_NNA_CONTINUE
1669 b       .mppt_NNA_OFF
1670 b       .mppt_NNA_FADE
1671         
1672 @---------------------------------------------------------------------------------
1673 .mppt_NNA_CUT:
1674 @---------------------------------------------------------------------------------
1675         
1676         #ifdef SYS_NDS                          // nds supports volume ramping
1677         
1678         ldrb    r1, [r6, #MCA_TYPE]
1679         cmp     r1, #0
1680         BEQ     .mppt_samechannel
1681         mov     r1, #ACHN_BACKGROUND
1682         strb    r1, [r6, #MCA_TYPE]
1683         mov     r1, #0
1684         strb    r1, [r6, #MCA_VOLUME]
1685         b       .mppt_NNA_FINISHED
1686         
1687         #else
1688         b       .mppt_samechannel
1689         #endif
1690         
1691 @---------------------------------------------------------------------------------
1692 .mppt_NNA_CONTINUE:
1693 @---------------------------------------------------------------------------------
1694         
1695         mov     r1, #ACHN_BACKGROUND    @ use different channel
1696         strb    r1, [r6, #MCA_TYPE]     @ set active channel to "background"
1697         b       .mppt_NNA_FINISHED      @ finished
1698
1699 @---------------------------------------------------------------------------------
1700 .mppt_NNA_OFF:
1701 @---------------------------------------------------------------------------------
1702
1703         ldrb    r1, [r6, #MCA_FLAGS]    @ clear KEYON in flags byte
1704         mov     r2, #MCAF_KEYON
1705         bic     r1, r2
1706
1707         strb    r1, [r6, #MCA_FLAGS]
1708         mov     r1, #ACHN_BACKGROUND    @ set type to "background"
1709         strb    r1, [r6, #MCA_TYPE]
1710         b       .mppt_NNA_FINISHED      @ finished
1711
1712 @---------------------------------------------------------------------------------
1713 .mppt_NNA_FADE:
1714 @---------------------------------------------------------------------------------
1715
1716         ldrb    r1, [r6, #MCA_FLAGS]    @ set NOTE FADE in flags byte
1717         mov     r2, #MCAF_FADE
1718         orr     r1, r2
1719         strb    r1, [r6, #MCA_FLAGS]
1720         mov     r1, #ACHN_BACKGROUND    @ set type to "background"
1721         strb    r1, [r6, #MCA_TYPE]     @
1722         
1723 .mppt_NNA_FINISHED:
1724         
1725 .mppt_alloc_channel:
1726
1727         mov     r4, r6
1728
1729         ldr     r1,=mmAllocChannel
1730         jump1                           @ find new active channel
1731         strb    r0, [r7, #MCH_ALLOC]    @ save number
1732         
1733         #ifdef SYS_NDS
1734         
1735         cmp     r4, #0
1736         beq     .mppt_samechannel
1737
1738         mov     r1, #MCA_SIZE           @ copy data from previous channel
1739         mul     r0, r1                  @ (for volume ramping wierdness)
1740         ldr     r1,=mm_achannels        @
1741         ldr     r1,[r1]                 @
1742         add     r0, r1                  @
1743                                         @
1744         mov     r2, #MCA_SIZE/4
1745 1:      ldmia   r4!, {r1}
1746         stmia   r0!, {r1}
1747         sub     r2, #1
1748         bne     1b
1749         
1750 /*      ldr     r1, [r4, #MCA_FADE]     @
1751         str     r1, [r0, #MCA_FADE]     @
1752         ldr     r1, [r4, #MCA_ENVC_PAN] @
1753         str     r1, [r0, #MCA_ENVC_PAN] @
1754         ldr     r1, [r4, #MCA_AVIB_DEP] @
1755         str     r1, [r0, #MCA_AVIB_DEP] @
1756         ldrb    r1, [r4, #MCA_FLAGS]    @
1757         strb    r1, [r0, #MCA_FLAGS]    @
1758         ldrb    r1, [r4, #MCA_VOLUME]
1759         strb    r1, [r0, #MCA_VOLUME]
1760         ldrb    r1, [r4, #MCA_PANNING]
1761         strb    r1, [r0, #MCA_PANNING]
1762         ldrb    r1, [r4, #MCA_SAMPLE]
1763         strb    r1, [r0, #MCA_SAMPLE]
1764         ldrb    r1, [r4, #MCA_INST]
1765         strb    r1, [r0, #MCA_INST]*/
1766         
1767         #endif
1768         
1769 .mppt_samechannel:
1770         
1771 .mppt_skipnna:
1772         pop     {r4}
1773         pop     {r3}
1774         bx      r3
1775         
1776 .pool
1777
1778 .align 2
1779 .thumb_func
1780 @------------------------------------------------------------------------------------------------------
1781 mpp_Channel_GetACHN:
1782 @------------------------------------------------------------------------------------------------------
1783         
1784         @ gets the active channel pointer
1785         @ and stores in r6
1786         @ gives 0 if N/A
1787         
1788         ldrb    r0, [r7, #MCH_ALLOC]
1789         cmp     r0, #255
1790         bge     1f
1791         ldr     r6,=mm_achannels
1792         ldr     r6,[r6]
1793         mov     r1, #MCA_SIZE
1794         mul     r0, r1
1795         add     r6, r0
1796         bx      lr
1797         
1798 1:      mov     r6, #0
1799         bx      lr
1800 .pool
1801
1802 .align 2
1803 .thumb_func
1804 @----------------------------------------------------------------------------------------------------
1805 mpp_Update_ACHN:
1806 @----------------------------------------------------------------------------------------------------
1807                 
1808 @ r5 = affected period
1809 @ r6 = achannel address
1810
1811         push    {lr}                    @ enter subroutine
1812         
1813 @ check updated flag & exit if already updated
1814         
1815         ldrb    r0, [r6, #MCA_FLAGS]
1816         mov     r1, #MCAF_UPDATED
1817         tst     r0, r1
1818         beq     .mpp_achn_update
1819         pop     {pc}
1820
1821 @--------------------------------------------
1822
1823         .global mpp_Update_ACHN_notest
1824         .thumb_func
1825 @----------------------------------------------------------------------------------------------------
1826 mpp_Update_ACHN_notest:
1827 @----------------------------------------------------------------------------------------------------
1828         push    {lr}
1829         
1830 .mpp_achn_update:
1831         
1832 @------------------------------------------------------------------------
1833 @ Envelope Processing
1834 @------------------------------------------------------------------------
1835         
1836         ldrb    r0, [r6, #MCA_INST]
1837         sub     r0, #1
1838         bCS     1f
1839         b       .mppt_achn_noinst
1840 1:      mpp_InstrumentPointer
1841
1842 @ get envelope flags
1843         
1844         mov     r1, r0
1845         ldrb    r2, [r1, #C_MASI_ENVFLAGS]
1846         add     r1, #C_MASI_ENVELOPES
1847         
1848         lsr     r2, #1                          @ shift out volume envelope bit
1849         bcc     .mppt_no_volenv
1850
1851         ldrb    r3, [r6, #MCA_FLAGS]
1852         lsr     r3, #6
1853         
1854         bcs     .mppt_achn_ve_enabled
1855         ldrb    r0, [r1]
1856         add     r1, r0
1857         b       .mppt_no_volenv
1858 .mppt_achn_ve_enabled:
1859         
1860         push    {r1, r2}
1861         
1862         ldrh    r0, [r6, #MCA_ENVC_VOL]
1863         mov     r2, r1
1864         ldrb    r1, [r6, #MCA_ENVN_VOL]
1865         bl      mpph_ProcessEnvelope
1866         strb    r1, [r6, #MCA_ENVN_VOL]
1867         strh    r0, [r6, #MCA_ENVC_VOL]
1868         mov     r1, r3
1869         
1870         cmp     r2, #1
1871         bne     .mpph_volenv_notend
1872         ldrb    r0, [r6, #MCA_FLAGS]
1873         
1874         mov     r3, r8                          @ stupid xm doesn't fade out at envelope end
1875         ldrb    r3, [r3, #MPL_FLAGS]
1876         lsr     r3, #C_FLAGS_XS
1877         
1878         mov     r3, #MCAF_ENVEND
1879         bcs     1f
1880         mov     r3, #MCAF_ENVEND+MCAF_FADE
1881 1:
1882         orr     r0, r3
1883         strb    r0, [r6, #MCA_FLAGS]
1884 .mpph_volenv_notend:
1885
1886         cmp     r2, #1
1887         blt     .mpph_volenv_normal
1888         
1889         @ check keyon and turn on fade...
1890         ldrb    r0, [r6, #MCA_FLAGS]
1891         mov     r2, #MCAF_KEYON
1892         tst     r0, r2
1893         bne     .mpph_volenv_normal
1894 .mpph_volenv_notefade:
1895         mov     r2, #MCAF_FADE
1896         orr     r0, r2
1897         strb    r0, [r6, #MCA_FLAGS]
1898         
1899 .mpph_volenv_normal:
1900         
1901         ldr     r0,=mpp_vars
1902         ldrb    r2, [r0, #MPV_AFVOL]
1903         mul     r2, r1
1904         lsr     r2, #6+6
1905         strb    r2, [r0, #MPV_AFVOL]
1906         pop     {r1, r2}
1907         ldrb    r0, [r1]
1908         add     r1, r0
1909         b       .mppt_has_volenv
1910 .mppt_no_volenv:
1911         
1912         ldrb    r0, [r6, #MCA_FLAGS]
1913         mov     r3, #MCAF_ENVEND
1914         orr     r0, r3
1915         mov     r3, #MCAF_KEYON
1916         tst     r0, r3
1917         bne     .mppt_has_volenv
1918         mov     r3, #MCAF_FADE
1919         orr     r0, r3
1920         strb    r0, [r6, #MCA_FLAGS]
1921         
1922         mov     r0, r8          @ check XM MODE and cut note
1923         ldrb    r0, [r0, #MPL_FLAGS]
1924         lsr     r0, #C_FLAGS_XS
1925         bcc     .mppt_has_volenv
1926         mov     r0, #0
1927         strh    r0, [r6, #MCA_FADE]
1928 .mppt_has_volenv:
1929         
1930         lsr     r2, #1
1931         bcc     .mppt_no_panenv
1932         push    {r1, r2}
1933         ldrh    r0, [r6, #MCA_ENVC_PAN]
1934         mov     r2, r1
1935         ldrb    r1, [r6, #MCA_ENVN_PAN]
1936         bl      mpph_ProcessEnvelope
1937         strb    r1, [r6, #MCA_ENVN_PAN]
1938         strh    r0, [r6, #MCA_ENVC_PAN]
1939         mov     r1, r3
1940
1941         ldr     r0,=mpp_vars
1942         mov     r3, #MPV_PANPLUS
1943         ldrsh   r2, [r0,r3]
1944         lsr     r1, #4
1945         sub     r1, #128
1946         add     r2, r1
1947         strh    r2, [r0,r3]
1948         pop     {r1, r2}
1949 .mppt_no_panenv:
1950         
1951         lsr     r2, #1
1952         bcc     .mppt_no_pitchenv
1953         ldrb    r0, [r1, #C_MASIE_FILTER]
1954         cmp     r0, #0
1955         bne     .mppt_no_pitchenv
1956         push    {r1, r2}
1957         ldrh    r0, [r6, #MCA_ENVC_PIC]
1958         mov     r2, r1
1959         ldrb    r1, [r6, #MCA_ENVN_PIC]
1960         bl      mpph_ProcessEnvelope
1961         strb    r1, [r6, #MCA_ENVN_PIC]
1962         strh    r0, [r6, #MCA_ENVC_PIC]
1963         mov     r1, r3
1964         lsr     r1, #3
1965         sub     r1, #255
1966         mov     r0, r5
1967         sub     r1, #1
1968         bmi     .mppt_pitchenv_minus
1969 #ifdef USE_IWRAM
1970         ldr     r2,=mpph_LinearPitchSlide_Up
1971         jump2
1972 #else
1973         bl      mpph_LinearPitchSlide_Up
1974 #endif
1975         b       .mppt_pitchenv_plus
1976 .mppt_pitchenv_minus:
1977         neg     r1, r1
1978 #ifdef USE_IWRAM
1979         ldr     r2,=mpph_LinearPitchSlide_Down
1980         jump2
1981 #else
1982         bl      mpph_LinearPitchSlide_Down
1983 #endif
1984 .mppt_pitchenv_plus:
1985         mov     r5, r0
1986         pop     {r1, r2}
1987 .mppt_no_pitchenv:
1988         
1989         ldrb    r0, [r6, #MCA_FLAGS]
1990         mov     r1, #MCAF_FADE
1991         tst     r0, r1
1992         beq     .mppt_achn_nofade
1993         ldrb    r0, [r6, #MCA_INST]
1994         sub     r0, #1
1995         
1996         mpp_InstrumentPointer
1997         ldrb    r0, [r0, #C_MASI_FADE]
1998
1999         ldrh    r1, [r6, #MCA_FADE]
2000
2001         sub     r1, r0
2002         bcs     .mppt_achn_fadeout_clip
2003         mov     r1, #0
2004 .mppt_achn_fadeout_clip:
2005         strh    r1, [r6, #MCA_FADE]
2006
2007 .mppt_achn_nofade:
2008         
2009 .mppt_achn_keyon:
2010         
2011
2012 @----------------------------------------------------------------------------------
2013 @ *** PROCESS AUTO VIBRATO
2014 @----------------------------------------------------------------------------------
2015         
2016         ldrb    r0, [r6, #MCA_SAMPLE]
2017         sub     r0, #1
2018         bcc     .mppt_achn_nostart      @ no sample!!
2019         
2020         @bl     mpp_SamplePointer
2021         mpp_SamplePointer
2022         ldrh    r1, [r0, #C_MASS_VIR]   @ get av-rate
2023         cmp     r1, #0                  @ 0?
2024         beq     .mppt_av_disabled       @  if 0 then its disabled
2025         ldrh    r2, [r6, #MCA_AVIB_DEP] @ get depth counter
2026         add     r2, r1                  @ add rate
2027         lsr     r1, r2, #15             @ check for 15-bit overflow
2028         beq     .mppt_av_depclip        @ ..
2029         
2030         ldr     r2,=32768               @ and clamp to 32768
2031 .mppt_av_depclip:                       
2032         strh    r2, [r6, #MCA_AVIB_DEP] @ save depth counter
2033         ldrb    r1, [r0, #C_MASS_VID]   @ get av-depth
2034         mul     r1, r2                  @ multiply
2035
2036         ldrb    r3, [r6, #MCA_AVIB_POS] @ get table position
2037         ldrb    r2, [r0, #C_MASS_VIS]   @ get av-speed
2038         add     r3, r2                  @ add to position
2039         lsl     r3, #32-8               @ wrap position to 0->255
2040         lsr     r3, #32-8               @ ..
2041         strb    r3, [r6, #MCA_AVIB_POS]         @ save position
2042         ldr     r2,=mpp_TABLE_FineSineData      @ get table pointer
2043         ldrsb   r2, [r2, r3]                    @ load table value at position
2044         mul     r2, r1                          @ multiply with depth
2045         asr     r2, #23                         @ shift value
2046         bmi     .mppt_av_minus                  @ and perform slide...
2047 .mppt_av_plus:                                  @ --slide up
2048         mov     r1, r2                          @ r1 = slide value
2049         mov     r0, r5                          @ r0 = frequency
2050 #ifdef USE_IWRAM
2051         fjump2  mpph_PitchSlide_Up
2052 #else
2053         bl      mpph_PitchSlide_Up              @ pitch slide
2054 #endif
2055         b       .mppt_av_finished               @
2056 .mppt_av_minus:                                 @ --slide down
2057         neg     r1, r2                          @ r1 = slide value
2058         mov     r0, r5                          @ r0 = frequency
2059 #ifdef USE_IWRAM
2060         ldr     r2,=mpph_PitchSlide_Down
2061         jump2
2062 #else
2063         bl      mpph_PitchSlide_Down            @ pitch slide
2064 #endif
2065
2066 .mppt_av_finished:
2067         mov     r5, r0                          @ affect frequency
2068 .mppt_av_disabled:
2069         
2070 @---------------------------------------------------------------------------------
2071         
2072 .mppt_achn_noinst:
2073         
2074         push    {r4}
2075         mov     r0, #MIXER_CHN_SIZE
2076         mul     r4, r0
2077         @ldr    r0,=mp_channels
2078 @       ldr     r0,=mm_mixchannels
2079 @       ldr     r0,[r0]
2080         GET_MIXCH r0
2081         add     r4, r0
2082         
2083         @ *** UPDATE MIXING INFORMATION
2084         
2085         ldrb    r0, [r6, #MCA_FLAGS]            @ read flags
2086         mov     r1, #MCAF_START                 @ test start bit
2087         tst     r0, r1                          @ ..
2088         beq     .mppt_achn_nostart              @
2089 .mppt_achn_start:                               @ START NOTE
2090         bic     r0, r1                          @ clear bit
2091         strb    r0, [r6, #MCA_FLAGS]            @ save flags
2092         ldrb    r0, [r6, #MCA_SAMPLE]           @ get sample #
2093
2094         sub     r0, #1                          @ ..
2095         bcc     .mppt_achn_nostart              @ quit if invalid
2096         @bl     mpp_SamplePointer               @ get sample address
2097         mpp_SamplePointer
2098         
2099         ldrh    r3, [r0, #C_MASS_MSLID]
2100         
2101         add     r1,r3,#1                        @ msl id == 0xFFFF?
2102         lsr     r1, #17
2103         
2104         bcc     .mppt_achn_msl_sample 
2105
2106 .mppt_achn_direct_sample:                       @ then sample follows
2107         
2108         add     r0, #12
2109         
2110 //------------------------------------------------
2111 #ifdef SYS_GBA
2112 //      ldr     r1, [r0,#C_SAMPLE_LEN]  @ setup mixer (GBA)
2113 //      lsl     r1, #MP_SAMPFRAC
2114 //      str     r1, [r4,#MIXER_CHN_LEN]
2115 //      ldr     r1, [r0,#C_SAMPLE_LOOP]
2116 //      str     r1, [r4,#MIXER_CHN_LOOP]
2117         add     r0, #C_SAMPLE_DATA
2118         str     r0, [r4,#MIXER_CHN_SRC]
2119         
2120 #else
2121 //-------------------------------------------
2122
2123         ldr     r1,=0x2000000
2124         sub     r0, r1
2125         str     r0, [r4, #MIXER_CHN_SAMP]
2126         ldrb    r1, [r4, #MIXER_CHN_CNT]
2127         mov     r0, #MIXER_CF_START
2128         orr     r1, r0
2129         strb    r1, [r4, #MIXER_CHN_CNT]
2130         
2131 #endif
2132 //-------------------
2133         
2134         b       .mppt_achn_gotsample
2135 .mppt_achn_msl_sample:                          @ otherwise get from solution
2136
2137         #ifdef SYS_GBA
2138
2139         ldr     r2,=mp_solution
2140         ldr     r2, [r2]
2141         mov     r1, r2
2142         add     r1, #12
2143         lsl     r3, #2
2144         ldr     r1, [r1, r3]
2145         add     r1, #8
2146         add     r0, r1, r2
2147         
2148         @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NOTICE, USE LDM HERE
2149         
2150 //      ldr     r1, [r0,#C_SAMPLE_LEN]  @ setup mixer (GBA)
2151 //      lsl     r1, #MP_SAMPFRAC
2152 //      str     r1, [r4,#MIXER_CHN_LEN]
2153 //      ldr     r1, [r0,#C_SAMPLE_LOOP]
2154 //      str     r1, [r4,#MIXER_CHN_LOOP]
2155         add     r0, #C_SAMPLE_DATA
2156         str     r0, [r4,#MIXER_CHN_SRC]
2157
2158         #endif
2159
2160         #ifdef SYS_NDS
2161                         
2162         ldr     r2,=mmSampleBank        @ get samplebank pointer
2163         ldr     r2, [r2]
2164         lsl     r3, #2          @ add msl_id *4
2165         ldr     r1, [r2, r3]
2166         
2167         lsl     r1, #8          @ mask out counter value
2168         lsr     r1, #8
2169         add     r1, #8
2170
2171         str     r1, [r4,#MIXER_CHN_SAMP]
2172         ldrb    r1, [r4,#MIXER_CHN_CNT]         // read control         **CNT was cleared, no need to read it
2173         mov     r0, #MIXER_CF_START             // set start bit
2174         orr     r1, r0
2175         strb    r1, [r4,#MIXER_CHN_CNT]         // save control
2176
2177         #endif
2178         
2179 .mppt_achn_gotsample:
2180         ldr     r1,=mpp_vars
2181         ldrb    r1, [r1, #MPV_SAMPOFF]
2182 #ifdef SYS_GBA
2183         lsl     r1, #MP_SAMPFRAC+8
2184         str     r1, [r4, #MIXER_CHN_READ]
2185 #else
2186         str     r1, [r4, #MIXER_CHN_READ]
2187 #endif
2188         
2189 .mppt_achn_nostart:
2190         @ set pitch
2191         
2192         ldrb    r0, [r6, #MCA_SAMPLE]           @ get sample#
2193         sub     r0, #1                          @ ..
2194         bcc     .mppt_achn_setvolumeA
2195         @bl     mpp_SamplePointer               @ quit if invalid
2196         mpp_SamplePointer
2197         push    {r0}
2198         
2199         mov     r1, r8
2200         ldrb    r1, [r1, #MPL_FLAGS]
2201         lsr     r1, #C_FLAGS_SS
2202         bcc     .mppt_achn_amigafreqs
2203 .mppt_achn_linearfreqs:
2204         
2205         ldrh    r0, [r0, #C_MASS_FREQ]          @ get C5SPEED
2206         LSL     R0, #2
2207         lsr     r1, r5, #8                      @ do some stuff...
2208         mul     r1, r0                          @ ... period * freq?
2209         
2210         lsr     r1, #8
2211         
2212         ldr     r0,=mpp_clayer
2213         ldrb    r0, [r0]
2214         cmp     r0, #0
2215         bne     1f
2216         ldr     r0,=mm_masterpitch
2217         ldr     r0, [r0]
2218         mul     r1, r0
2219         lsr     r1, #10
2220 1:
2221
2222         #ifdef SYS_GBA
2223         
2224         
2225 //      ldr     r0,=mm_freqscalar
2226 //      ldr     r0, [r0]
2227         ldr     r0,=(4096*65536)/15768
2228         mul     r0, r1
2229         lsr     r0, #16
2230         str     r0, [r4, #MIXER_CHN_FREQ]
2231         
2232         #else
2233
2234         ldr     r0,=MIXER_SCALE
2235         mul     r0, r1
2236         lsr     r0, #16+1
2237         strh    r0, [r4, #MIXER_CHN_FREQ]
2238         
2239         //strh  r1, [r4, #MIXER_CHN_FREQ]
2240         #endif
2241         
2242         b       .mppt_achn_setvolume
2243         
2244 .mppt_achn_amigafreqs:
2245         ldr     r0,=MOD_FREQ_DIVIDER_PAL
2246         movs    r1, r5
2247         
2248         beq     .mppt_achn_setvolume            @ 0 is a bad period
2249         swi     SWI_DIVIDE
2250         
2251         ldr     r1,=mpp_clayer
2252         ldrb    r1, [r1]
2253         cmp     r1, #0
2254         bne     1f
2255         ldr     r1,=mm_masterpitch
2256         ldr     r1, [r1]
2257         mul     r0, r1
2258         lsr     r0, #10
2259 1:
2260
2261         #ifdef SYS_GBA
2262
2263 //      ldr     r1,=mm_freqscalar
2264 //      ldr     r1,[r1]
2265         ldr     r1,=(4096*65536)/15768
2266         mul     r0, r1
2267         lsr     r0, #16
2268
2269         str     r0, [r4, #MIXER_CHN_FREQ]
2270         #else
2271 //      mov     r1, r0
2272 //      ldr     r0,=16756991                    @ calculate ds mixer timing
2273 //      swi     SWI_DIVIDE
2274 //      neg     r0,r0
2275         //lsr   r0, #5
2276         ldr     r1,=MIXER_SCALE
2277         mul     r0, r1
2278         lsr     r0, #16+1
2279         strh    r0, [r4, #MIXER_CHN_FREQ]
2280         #endif
2281
2282 @----------------------------------------------------------------------------------------------------
2283 .mppt_achn_setvolume:
2284 @----------------------------------------------------------------------------------------------------
2285         
2286         @ set volume
2287         
2288         pop     {r0}
2289                                                 @ <-- stepped oct 28, 3:27pm 
2290         ldrb    r3, [r0, #C_MASS_GV]            @ SV, 6-bit
2291         ldrb    r0, [r6, #MCA_INST]
2292         sub     r0, #1
2293         bcs     1f
2294         
2295 .thumb_func
2296 .mppt_achn_setvolumeA:  
2297         mov     r1, #0
2298         b       .mppt_achn_badinstrument
2299 1:      
2300         mpp_InstrumentPointer
2301         ldrb    r0, [r0, #C_MASI_GVOL]  @ IV, 7-bit
2302         mul     r3, r0
2303         
2304         ldr     r1,=mpp_vars
2305         ldrb    r0, [r1, #MPV_AFVOL]    @ ((CV*VOL)/32*VEV/64) 7-bit
2306         
2307         mul     r3, r0
2308         
2309         mov     r1, r8                  @ get global vollume
2310         ldrb    r0, [r1, #MPL_FLAGS]
2311         lsr     r0, #4
2312         ldrb    r0, [r1, #MPL_GV]       @ ..                 7-bit
2313         
2314         bcc     1f
2315         lsl     r0, #1                  @ xm mode global volume is only 0->64, shift to 0->128
2316         
2317 1:      mul     r3, r0                  @ multiply
2318         
2319         lsr     r3, #10
2320         
2321         ldrh    r0, [r6, #MCA_FADE]
2322         
2323         
2324         mul     r3, r0
2325         
2326         lsr     r3, r3, #10
2327         
2328         mov     r0, r8
2329         mov     r1, #MPL_VOLUME
2330         ldrh    r0, [r0, r1]
2331         mul     r3, r0
2332         
2333 //------------------------------------------------
2334 #ifdef SYS_NDS
2335         lsr     r1, r3, #19-3-5 ///#19-3        (new 16-bit levels!)
2336         ldr     r3,=65535  //2047
2337         cmp     r1, r3                          @ clip values over 255
2338         blt     1f
2339         mov     r1, r3
2340 1:
2341 .mppt_achn_badinstrument:
2342 //      lsr     r3, r1, #3              (new 16-bit levels!)
2343         lsr     r3, r1, #8              
2344         strb    r3, [r6, #MCA_FVOL]
2345
2346 #else
2347
2348         lsr     r1, r3, #19
2349         cmp     r1, #255                        @ clip values over 255
2350         blt     1f
2351         mov     r1, #255
2352 1:
2353 .mppt_achn_badinstrument:
2354         strb    r1, [r6, #MCA_FVOL]
2355
2356 #endif
2357
2358         cmp     r1, #0
2359         bne     .mppt_achn_audible
2360         
2361         #ifdef SYS_NDS                  // nds has volume ramping!
2362         
2363         ldrb    r3, [r6, #MCA_TYPE]
2364         cmp     r3, #ACHN_BACKGROUND
2365         bne     1f
2366         ldrb    r3, [r6, #MCA_VOLUME]
2367         cmp     r3, #0
2368         bne     1f
2369         ldrh    r3, [r4, #MIXER_CHN_CVOL]
2370         cmp     r3, #0
2371         beq     .mppt_achn_not_audible
2372         #endif
2373         
2374 1:      ldrb    r3, [r6, #MCA_FLAGS]
2375         mov     r2, #MCAF_ENVEND
2376         tst     r3, r2
2377         beq     .mppt_achn_audible
2378         mov     r2, #MCAF_KEYON
2379         tst     r3, r2
2380         bne     .mppt_achn_audible
2381         
2382 //      #ifdef SYS_NDS
2383 //      ldrh    r3, [r4, #MIXER_CHN_CVOL]       // nds has volume ramping!!
2384 //      cmp     r3, #0
2385 //      bne     .mppt_achn_audible
2386 //      #endif
2387
2388 .mppt_achn_not_audible:
2389         @ STOP CHANNEL
2390
2391 #ifdef SYS_GBA
2392         ldr     r0,=1<<31
2393         str     r0,[r4,#MIXER_CHN_SRC]  @ stop mixer channel
2394 #else
2395         mov     r0,#0
2396         str     r0,[r4,#MIXER_CHN_SAMP] @ stop mixer channel
2397 #endif
2398
2399         ldrb    r3, [r6, #MCA_TYPE]
2400         cmp     r3, #ACHN_FOREGROUND
2401         bne     .mpp_achn_noparent
2402         ldrb    r1, [r6, #MCA_PARENT]
2403         mov     r3, #MCH_SIZE
2404         mul     r1, r3
2405         ldr     r0,=mpp_channels
2406         ldr     r0, [r0]
2407         add     r0, r1
2408         mov     r1, #255
2409         strb    r1, [r0, #MCH_ALLOC]
2410 .mpp_achn_noparent:
2411         
2412         mov     r1, #ACHN_DISABLED
2413         strb    r1, [r6, #MCA_TYPE]
2414         b       .mpp_achn_updated
2415 .mppt_achn_audible:
2416         
2417 #ifdef SYS_NDS
2418         
2419         strh    r1, [r4, #MIXER_CHN_VOL]
2420         
2421 #else
2422         
2423         strb    r1, [r4, #MIXER_CHN_VOL]
2424         
2425 #endif
2426         
2427 #ifdef SYS_GBA                                          // check if mixer channel has ended
2428
2429         ldr     r0, [r4, #MIXER_CHN_SRC]
2430         asr     r0, #31
2431         beq     1f
2432
2433 #else
2434
2435         ldr     r0, [r4, #MIXER_CHN_SAMP]
2436         lsl     r0, #8
2437         bne     1f
2438         
2439 #endif
2440
2441         ldrb    r3, [r6, #MCA_TYPE]
2442         cmp     r3, #ACHN_FOREGROUND
2443         bne     2f
2444
2445         ldrb    r1, [r6, #MCA_PARENT]                   // stop channel if channel ended
2446         mov     r3, #MCH_SIZE
2447         mul     r1, r3
2448         ldr     r0,=mpp_channels
2449         ldr     r0, [r0]
2450         add     r0, r1
2451         mov     r1, #255
2452         strb    r1, [r0, #MCH_ALLOC]
2453 2:
2454
2455 #ifdef SYS_GBA
2456         ldr     r0,=1<<31
2457         str     r0,[r4,#MIXER_CHN_SRC]  @ stop mixer channel
2458 #else
2459         mov     r0,#0
2460         str     r0,[r4,#MIXER_CHN_SAMP] @ stop mixer channel
2461 #endif
2462
2463         mov     r1, #ACHN_DISABLED
2464         strb    r1, [r6, #MCA_TYPE]
2465         b       .mpp_achn_updated
2466
2467         @ set panning
2468 1:      ldr     r1,=mpp_vars
2469         mov     r3, #MPV_PANPLUS
2470         ldrsh   r0, [r1,r3]
2471         ldrb    r1, [r6, #MCA_PANNING]
2472         
2473         add     r1, r0
2474
2475         cmp     r1, #0
2476         bge     .mpp_achn_clippan1
2477         mov     r1, #0
2478 .mpp_achn_clippan1:
2479         cmp     r1, #255
2480         ble     .mpp_achn_clippan2
2481         mov     r1, #255
2482 .mpp_achn_clippan2:
2483
2484         #ifdef SYS_NDS
2485         lsr     r1, #1
2486         ldrb    r0, [r4, #MIXER_CHN_CNT]
2487         lsr     r0, #7
2488         lsl     r0, #7
2489         orr     r0, r1
2490         strb    r0, [r4, #MIXER_CHN_CNT]
2491         #endif
2492         
2493         #ifdef SYS_GBA
2494         strb    r1, [r4, #MIXER_CHN_PAN]
2495         #endif
2496         
2497         
2498 .mpp_achn_updated:
2499         pop     {r4}
2500         pop     {r0}
2501         bx      r0
2502         //pop   {pc}                            @ exit
2503 .pool
2504
2505 .align 2
2506 .thumb_func
2507 @-------------------------------------------------------------------------
2508 mpph_ProcessEnvelope:                   @ params={count,node,address}
2509 @-------------------------------------------------------------------------
2510
2511 @ processes the envelope at <address>
2512 @ returns:
2513 @ r0=count
2514 @ r1=node
2515 @ r2=exit_code
2516 @ r3=value*64
2517         
2518         push    {r4,r5}
2519
2520 @ get node and base
2521         lsl     r4, r1, #2
2522         add     r4, #C_MASIE_NODES
2523         add     r4, r2
2524         
2525         ldrh    r3, [r4, #2]
2526         lsl     r3, #32-7
2527         lsr     r3, #32-7-6
2528
2529 @ check for zero count
2530         
2531         cmp     r0, #0
2532         bne     .mpph_pe_between
2533 .mpph_pe_new:
2534
2535 @ process envelope loop
2536         
2537         ldrb    r5, [r2, #C_MASIE_LEND]
2538         cmp     r1, r5
2539         bne     1f
2540         ldrb    r1, [r2, #C_MASIE_LSTART]
2541         mov     r2, #2
2542         b       .mpph_pe_exit
2543
2544 @ process envelope sustain loop
2545
2546 1:      ldrb    r5, [r6, #MCA_FLAGS]
2547         lsr     r5, #1  @ locked
2548         bcc     1f
2549         ldrb    r5, [r2, #C_MASIE_SEND]
2550         cmp     r1, r5
2551         bne     1f
2552         ldrb    r1, [r2, #C_MASIE_SSTART]
2553         mov     r2, #0
2554         b       .mpph_pe_exit
2555
2556 @ check for end
2557
2558 1:      ldrb    r5, [r2, #C_MASIE_NODEC]
2559         sub     r5, #1
2560         cmp     r1, r5
2561         bne     .mpph_count
2562         mov     r2, #2
2563         b       .mpph_pe_exit
2564
2565 .mpph_pe_between:
2566
2567 @                            delta * count 
2568 @ formula : y = base*2^6 + -----------------
2569 @                                 2^3
2570         mov     r5, #0
2571         ldrsh   r5, [r4,r5]
2572         mul     r5, r0
2573         asr     r5, #3
2574         add     r3, r5
2575         
2576 .mpph_count:
2577
2578 @ increment count and check if == read count
2579
2580         add     r0, #1
2581         ldrh    r5, [r4, #2]
2582         lsr     r5, #7
2583         cmp     r0, r5
2584         bne     .mpph_pe_exit
2585
2586 @ increment node and reset counter
2587
2588         mov     r0, #0
2589         add     r1, #1
2590
2591 .mpph_pe_exit:
2592         
2593         pop     {r4,r5}
2594         bx      lr
2595 .pool
2596
2597 /*
2598 .align 2
2599 .thumb_func
2600 @--------------------------------------------------------------------------------------------
2601 mpp_Alloc_Channel:
2602 @--------------------------------------------------------------------------------------------
2603         
2604         @ find a channel to use
2605         @ returns invalid channel if none available
2606         push    {r4,r5}                         @ preserve reg(s)
2607         ldr     r5,=mm_ch_mask
2608         ldr     r5, [r5]
2609
2610         @ldr    r1,=mpp_achannels               @ load pointer
2611         ldr     r1,=mm_achannels
2612         ldr     r1,[r1]
2613         mov     r0, #0                          @ load counter
2614         mov     r2, #255                        @ r2 = MAXVOL+1 (highest)
2615         add     r2, #1
2616         mov     r3, #255                        @ r3 = 255 (none found)
2617         b       .mppac_start
2618
2619 .mppac_next:
2620         add     r1, #MCA_SIZE           @ change pointer
2621         add     r0, #1                  @ count
2622 .mppac_start:
2623         lsr     r5, #1
2624         bcs     .mppac_check
2625         bne     .mppac_next
2626 .mppac_end:
2627         mov     r0, r3                  @ if no disabled channels are found, use lowest volume channel
2628 .mppac_found:
2629
2630         pop     {r4,r5}
2631         bx      lr
2632         
2633 .mppac_check:
2634         ldrb    r4, [r1, #MCA_TYPE]     @ check active channel type
2635         cmp     r4, #ACHN_DISABLED      @ disabled?
2636         beq     .mppac_found            @ if so, use this channel
2637         cmp     r4, #ACHN_BACKGROUND    @ check if its a background channel
2638         bne     .mppac_next
2639         
2640         ldrb    r4, [r1, #MCA_FVOL]     @ compare volumes
2641         cmp     r4, r2                  @
2642         bge     .mppac_next
2643         mov     r3, r0                  @ save channel#
2644         mov     r2, r4                  @ and volume
2645         b       .mppac_next
2646 */
2647
2648 .pool
2649
2650 @........................................................................................
2651
2652 .thumb_func
2653 mpp_PatternPointer:
2654         mov     r1, r8
2655         ldr     r2,[r1,#MPL_SONGADR]
2656         ldr     r1,[r1,#MPL_PATTTABLE]
2657         lsl     r0, #2
2658         ldr     r0,[r1,r0]
2659         add     r0, r2
2660         bx      lr
2661 .pool
2662 #ifdef FOO_UC
2663 .align 2
2664 .thumb_func
2665 mpp_GetPeriod:
2666         @ r0 = note
2667         @ r2 = tuning
2668         @ CLOBBERS R1,R3
2669         @ RETURN
2670         @ r0 = IT/S3M PERIOD
2671
2672         mov     r1, r8
2673         ldrb    r1, [r1, #MPL_FLAGS]
2674         lsr     r1, #C_FLAGS_SS
2675         bcs     .mpp_gp_linear
2676 .mpp_gp_amiga:
2677         
2678         mov     r3, r0
2679         ldr     r0,=note_table_mod
2680         ldrb    r1, [r0, r3]
2681         sub     r0, #3*10
2682         lsr     r3, #2
2683         ldrb    r0, [r0, r3]
2684         
2685         @ r0 = octave
2686         @ r1 = note
2687         lsl     r1, #1
2688         ldr     r3,=ST3_FREQTABLE
2689         ldrh    r1, [r3, r1]
2690         
2691         ldr     r3,=133808
2692         mul     r1, r3
2693         lsr     r1, r0
2694         
2695         lsr     r0, r1, #3
2696         mov     r1, r2
2697         
2698         swi     SWI_DIVIDE
2699         lsl     r0, #3
2700         
2701         bx      lr
2702
2703 .mpp_gp_linear:
2704         ldr     r1,=IT_PitchTable
2705         lsl     r0, #2
2706         ldr     r0, [r1, r0]
2707         
2708         bx      lr
2709
2710 #endif
2711
2712 @=============================================================================
2713 @                                EFFECT MEMORY
2714 @=============================================================================
2715
2716 .text
2717
2718 mpp_effect_memmap_xm:
2719 .byte   0,0,0,0,2,3,4,0,0,5,0,6,7,0,0,8,9,10,11,0,0,0,0,12,0,0,0,0,0,0,13
2720 @       /,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q, R, S,T,U,V,W, X,Y,Z,0,1,2,3
2721
2722 .equ    MPP_XM_VFX_MEM_VS,      12  @ $ud
2723 .equ    MPP_XM_VFX_MEM_FVS,     13  @ $ud
2724 .equ    MPP_XM_VFX_MEM_GLIS,    14  @ $0x
2725 .equ    MPP_XM_VFX_MEM_PANSL,   7   @ $lr
2726
2727 mpp_effect_memmap_it:
2728 .byte   0,0,0,0,2,3,3,0,0,4,5,2,2,0,6,7,8,9,10,11,12,0,0,13,0,14,0
2729 @       /,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R, S, T, U,V,W, X,Y, Z
2730 mpp_veffect_memmap_it:
2731
2732 .equ    MPP_IT_VFX_MEM,         14
2733 .equ    MPP_GLIS_MEM,           0
2734 .equ    MPP_IT_PORTAMEM,        2
2735
2736
2737 @ 0 means custom behavior, or disabled
2738
2739 .align 2
2740 .thumb_func
2741 @-----------------------------------------------------------------------------
2742 mpp_Channel_ExchangeMemory:
2743 @-----------------------------------------------------------------------------
2744         
2745         @ r0 = effect#
2746         @ r1 = param
2747
2748 @ check flags for XM mode
2749         
2750         mov     r2, r8
2751         ldrb    r2, [r2, #MPL_FLAGS]
2752         lsr     r2, #C_FLAGS_XS
2753         bcs     1f
2754
2755 @ IT effects 
2756         
2757         ldr     r2,=mpp_effect_memmap_it
2758         b       2f
2759         
2760 1:
2761 @ XM effects
2762
2763         ldr     r2,=mpp_effect_memmap_xm
2764 2:      ldrb    r2, [r2, r0]
2765         sub     r2, #1
2766         bcc     3f
2767         
2768 @ if param=0 then load memory value, otherwise save param to memory
2769         
2770         add     r2, #MCH_MEMORY
2771         cmp     r1, #0
2772         bne     1f
2773         ldrb    r1, [r7, r2]
2774         strb    r1, [r7, #MCH_PARAM]
2775 1:      strb    r1, [r7, r2]
2776         
2777 3:      bx      lr
2778
2779 @----------------------------------------------------------
2780 mpp_Channel_ExchangeGxx:
2781 @----------------------------------------------------------
2782
2783         @ r1 = param
2784
2785
2786
2787 /******************************************************************************
2788  *
2789  * Volume Commands
2790  *
2791  ******************************************************************************/
2792
2793
2794
2795 /******************************************************************************
2796  * mpp_Process_VolumeCommand()
2797  *
2798  * Process volume command
2799  ******************************************************************************/
2800                                         .global mpp_Process_VolumeCommand
2801                                         .thumb_func
2802 mpp_Process_VolumeCommand:
2803         
2804         mov     r0, r8
2805         ldrb    r2, [r0, #MPL_TICK]
2806         ldr     r0, [r0, #MPL_SONGADR]
2807         ldrb    r0, [r0, #C_MAS_FLAGS]
2808         lsr     r0, #4
2809         ldrb    r0, [r7, #MCH_VOLCMD]
2810         bcc     .mppuv_it
2811         b       .mppuv_xm
2812 .mppuv_it:
2813
2814 @ determine which command to use 
2815
2816         cmp     r0, #64
2817         ble     .mppuv_setvol
2818         cmp     r0, #84
2819         ble     .mppuv_fvol
2820         cmp     r0, #104
2821         ble     .mppuv_volslide
2822         cmp     r0, #124
2823         ble     .mppuv_porta
2824         cmp     r0, #192
2825         ble     .mppuv_panning
2826         cmp     r0, #202
2827         ble     .mppuv_glissando
2828         cmp     r0, #212
2829         ble     .mppuv_vibrato
2830 .mppuv_exit1:
2831         bx      lr
2832
2833 .align 2
2834 @-----------------------------------------------------------------------------------
2835 .mppuv_setvol:                                  @ SET VOLUME
2836 @-----------------------------------------------------------------------------------
2837
2838 @ sets volume on tick0
2839
2840         cmp     r2, #0
2841         bne     .mppuv_setvol_exit
2842         strb    r0, [r7, #MCH_VOLUME]
2843 .mppuv_setvol_exit:
2844         bx      lr                              @ exit
2845
2846 .align 2
2847 @-----------------------------------------------------------------------------------
2848 .mppuv_fvol:                                    @ FINE VOLUME SLIDE UP/DOWN
2849 @-----------------------------------------------------------------------------------
2850
2851         cmp     r2, #0                          @ only slide on tick0
2852         bne     .mppuv_exit1                    @ ..
2853         ldrb    r1, [r7, #MCH_VOLUME]           @ load channel volume
2854         mov     r2, #MCH_MEMORY+MPP_IT_VFX_MEM
2855         cmp     r0, #75                         @ check slide direction
2856         bge     .mppuv_fvoldown                 @ jump to slide down if value is 75+ (75-84 is slide down)
2857 .mppuv_fvolup:                                  @ ------ slide up ----------
2858         sub     r0, #65                         @ 65->74 , 0->9
2859 .mppuv_volup:                                   @ ** entry for volume slide up
2860         bne     1f                              @ is value 0?
2861         ldrb    r0, [r7, r2]                    @  then fetch value from memory
2862 1:      strb    r0, [r7, r2]                    @ save value
2863 .mppuv_volupA:
2864         add     r1, r0                          @ add to volume
2865         cmp     r1, #64                         @ clamp to 0->64
2866         blt     .mppuv_fvol_exit                @ ..
2867         mov     r1, #64                         @ ..
2868         b       .mppuv_fvol_exit                @ ..
2869 .mppuv_fvoldown:                                @ ------ slide down --------
2870         sub     r0, #75                         @ 75->84 , 0->9
2871 .mppuv_voldown:                                 @ ** entry for volume slide down
2872         bne     1f                              @ is value 0?
2873         ldrb    r0, [r7, r2]                    @  then fetch value from memory
2874 1:      strb    r0, [r7, r2]                    @ save value
2875 .mppuv_voldownA:
2876         sub     r1, r0                          @ subtract from volume
2877         bcs     .mppuv_fvol_exit                @ check overflow and clamp
2878         mov     r1, #0                          @ ..
2879 .mppuv_fvol_exit:                               @ ..
2880         strb    r1, [r7, #MCH_VOLUME]           @ store volume
2881 .mppuv_exit2:
2882         bx      lr                              @ exit function
2883         
2884 .align 2
2885 @----------------------------------------------------------------------------------
2886 .mppuv_volslide:                                @ VOLUME SLIDE UP/DOWN
2887 @----------------------------------------------------------------------------------
2888
2889         cmp     r2, #0                          @ only slide on other ticks
2890         beq     .mppuv_exit1                    @ ..
2891         ldrb    r1, [r7, #MCH_VOLUME]           @ get volume
2892         cmp     r0, #95                         @ check slide direction
2893         bge     .mppuv_vs_down                  
2894 .mppuv_vs_up:                                   @ slide up...
2895         mov     r2, #MCH_MEMORY+MPP_IT_VFX_MEM
2896         sub     r0, #85                         @ 85->94 , 0->9
2897         b       .mppuv_volup                    @ branch to function (use fvol code)
2898
2899 .mppuv_vs_down:                                 @ slide down...
2900         mov     r2, #MCH_MEMORY+MPP_IT_VFX_MEM
2901         sub     r0, #95                         @ 95->104 , 0->9
2902         b       .mppuv_voldown                  @ branch to function (use fvol code)
2903
2904 .align 2
2905 @---------------------------------------------------------------------------------------
2906 .mppuv_porta:                                   @ PORTAMENTO UP/DOWN
2907 @---------------------------------------------------------------------------------------
2908
2909         cmp     r2, #0                          @ only slide on other ticks
2910         beq     .mppuv_exit2
2911         
2912         push    {lr}                            @ save return address
2913         mov     r1, r0                          @ get period value
2914         mov     r0, #MCH_PERIOD
2915         ldr     r0, [r7, r0]
2916         
2917         cmp     r1, #115                        @ check slide direction
2918         bge     .mppuv_porta_up
2919 .mppuv_porta_down:
2920         sub     r1, #105                        @ map value 0->9
2921         lsl     r1, #2                          @ volume command slides are
2922         bne     1f
2923         ldrb    r1, [r7, #MCH_MEMORY+MPP_IT_PORTAMEM]
2924 1:      strb    r1, [r7, #MCH_MEMORY+MPP_IT_PORTAMEM]
2925         bl      mpph_PitchSlide_Down            @ equal to normal slides *4
2926         b       .mppuv_porta_set
2927         
2928 .mppuv_porta_up:
2929         sub     r1, #115                        @ slide up...
2930         lsl     r1, #2
2931         bne     1f
2932         ldrb    r1, [r7, #MCH_MEMORY+MPP_IT_PORTAMEM]
2933 1:      strb    r1, [r7, #MCH_MEMORY+MPP_IT_PORTAMEM]
2934         bl      mpph_PitchSlide_Up
2935
2936 .mppuv_porta_set:
2937         mov     r2, #MCH_PERIOD                 @ store new period
2938         ldr     r1, [r7, r2]
2939         str     r0, [r7, r2]
2940         sub     r0, r1                          @ and edit temp period
2941         add     r5, r0
2942         
2943         pop     {r0}
2944         bx      r0
2945 //      pop     {pc}                            @ exit
2946
2947 .align 2
2948 @---------------------------------------------------------------------------------------
2949 .mppuv_panning:                                 @ SET PANNING
2950 @---------------------------------------------------------------------------------------
2951
2952         cmp     r2, #0                          @ only set on tick 0
2953         bne     .mppuv_exit1                    @ ..
2954         sub     r0, #128                        @ map to 0->64
2955         lsl     r0, #2
2956         cmp     r0, #255
2957         blt     .mppuv_p_store
2958         mov     r0, #255
2959 .mppuv_p_store:
2960         strb    r0, [r7, #MCH_PANNING]          @ save to active channel
2961 .mppuv_p_exit:
2962         bx      lr                              @ exit
2963
2964 .align 2
2965 @---------------------------------------------------------------------------------------
2966 .mppuv_glissando:                               @ GLISSANDO
2967 @---------------------------------------------------------------------------------------
2968
2969         cmp     r2, #0
2970         beq     .mppuv_p_exit
2971
2972         sub     r0, #193
2973         ldr     r1,=vcmd_glissando_table
2974         ldrb    r0, [r1, r0]
2975
2976         mov     r1, r8
2977         ldrb    r1, [r1, #MPL_FLAGS]
2978         lsr     r1, #C_FLAGS_GS
2979         bcs     2f
2980 @ single gxx
2981
2982         cmp     r0, #0
2983         beq     1f
2984         ldrb    r0, [r7, #MCH_MEMORY+MPP_GLIS_MEM]
2985 1:      strb    r0, [r7, #MCH_MEMORY+MPP_GLIS_MEM]
2986         b       .mppe_glis_ot
2987
2988 2: @ shared gxx
2989
2990         cmp     r0, #0
2991         beq     1f
2992         ldrb    r0, [r7, #MCH_MEMORY+MPP_IT_PORTAMEM]
2993 1:      strb    r0, [r7, #MCH_MEMORY+MPP_IT_PORTAMEM]
2994         strb    r0, [r7, #MCH_MEMORY+MPP_GLIS_MEM]
2995         
2996         b       .mppe_glis_ot
2997 .pool
2998
2999 vcmd_glissando_table:
3000 .byte   0,1,4,8,16,32,64,96,128,255
3001
3002 .align 2
3003 @---------------------------------------------------------------------------------------
3004 .mppuv_vibrato:                                 @ VIBRATO (SPEED)
3005 @---------------------------------------------------------------------------------------
3006         
3007         @ vibrato... sets speed
3008         cmp     r2, #0
3009         beq     .mppuv_vib_exit
3010         sub     r0, #203
3011         beq     1f
3012         lsl     r0, #2
3013         strb    r0, [r7, #MCH_VIBSPD]
3014 1:      b       mppe_DoVibrato
3015 .mppuv_vib_exit:
3016         bx      lr
3017
3018
3019
3020 /******************************************************************************
3021  *
3022  * XM Volume Commands
3023  *
3024  ******************************************************************************/
3025
3026
3027
3028 .align 2
3029 .thumb_func
3030 @---------------------------------------------------------------------------------------
3031 .mppuv_xm:
3032 @---------------------------------------------------------------------------------------
3033
3034 @ determine command type 
3035         
3036         cmp     r0, #0          @ 0 = none
3037         beq     .mppuv_exit4
3038         cmp     r0, #0x50
3039         ble     .mppuv_xm_setvol
3040         cmp     r0, #0x80
3041         blt     .mppuv_xm_volslide
3042         cmp     r0, #0xA0
3043         blt     .mppuv_xm_fvolslide
3044         cmp     r0, #0xC0
3045         blt     .mppuv_xm_vibrato
3046         cmp     r0, #0xD0
3047         blt     .mppuv_xm_panning
3048         cmp     r0, #0xF0
3049         blt     .mppuv_xm_panslide
3050         b       .mppuv_xm_toneporta
3051
3052 .align 2
3053 .thumb_func
3054 @----------------------------------------------------------------------------------------
3055 .mppuv_xm_setvol:                                       @ Set Volume
3056 @----------------------------------------------------------------------------------------
3057
3058         cmp     R2, #0
3059         bne     .mppuv_exit4
3060         sub     r0, #0x10
3061         strb    r0, [r7, #MCH_VOLUME]
3062 .mppuv_exit4:
3063         bx      lr
3064
3065 .align 2
3066 .thumb_func
3067 @----------------------------------------------------------------------------------------
3068 .mppuv_xm_volslide:                                     @ Volume Slide
3069 @----------------------------------------------------------------------------------------
3070
3071         cmp     r2, #0
3072         beq     .mppuv_exit2
3073         ldrb    r1, [r7, #MCH_VOLUME]
3074         mov     r3, #MCH_MEMORY+MPP_XM_VFX_MEM_VS
3075         ldrb    r2, [r7, r3]
3076         cmp     r0, #0x70
3077         bge     .mppuv_xm_volslide_up
3078         sub     r0, #0x60
3079 .mppuv_xm_volslide_dn_check:
3080         bne     1f
3081         mov     r0, r2
3082         lsl     r0, #32-4
3083         lsr     r0, #32-4
3084         b       2f
3085 1:      lsr     r2, #4
3086         lsl     r2, #4
3087         orr     r2, r0
3088         strb    r2, [r7, r3]    
3089 2:      b       .mppuv_voldownA
3090
3091 .mppuv_xm_volslide_up:
3092         sub     r0, #0x70
3093 .mppuv_xm_volslide_up_check:
3094         bne     1f
3095         mov     r0, r2
3096         lsr     r0, #4
3097         b       2f
3098 1:      lsl     r2, #32-4
3099         lsr     r2, #32-4
3100         lsl     r0, #4
3101         orr     r2, r0
3102         lsr     r0, #4
3103         strb    r2, [r7, r3]
3104 2:      b       .mppuv_volupA
3105
3106 .align 2
3107 .thumb_func
3108 @----------------------------------------------------------------------------------------
3109 .mppuv_xm_fvolslide:                                    @ Fine Volume Slide
3110 @----------------------------------------------------------------------------------------
3111
3112         cmp     r2, #0
3113         bne     .mppuv_exit4
3114         ldrb    r1, [r7, #MCH_VOLUME]
3115         mov     r3, #MCH_MEMORY+MPP_XM_VFX_MEM_FVS
3116         ldrb    r2, [r7, r3]
3117         cmp     r0, #0x90
3118         bge     .mppuv_xm_fvolslide_up
3119         sub     r0, #0x80
3120         b       .mppuv_xm_volslide_dn_check
3121 .mppuv_xm_fvolslide_up:
3122         sub     r0, #0x90
3123         b       .mppuv_xm_volslide_up_check
3124
3125 .align 2
3126 .thumb_func
3127 @----------------------------------------------------------------------------------------
3128 .mppuv_xm_vibrato:                                      @ Vibrato
3129 @----------------------------------------------------------------------------------------
3130         
3131         @ xm vibrato
3132         @ sets speed or depth
3133         
3134         cmp     r2, #0
3135         beq     .mppuv_xm_vibexit
3136         cmp     r0, #0xB0
3137         bge     .mppuv_xm_vibdepth
3138
3139 .mppuv_xm_vibspd:
3140         sub     r0, #0xA0
3141         lsl     r0, #2
3142         beq     1f
3143         strb    r0, [r7, #MCH_VIBSPD]
3144 1:      b       mppe_DoVibrato
3145         
3146 .mppuv_xm_vibdepth:
3147         sub     r0, #0xB0
3148         lsl     r0, #3
3149         beq     1f
3150         strb    r0, [r7, #MCH_VIBDEP]
3151 1:      b       mppe_DoVibrato
3152         
3153 .mppuv_xm_vibexit:
3154         bx      lr
3155
3156 .align 2
3157 .thumb_func
3158 @----------------------------------------------------------------------------------------
3159 .mppuv_xm_panning:                                      @ Panning
3160 @----------------------------------------------------------------------------------------
3161         
3162         cmp     r2, #0
3163         bne     .mppuv_exit3
3164         sub     r0, #0xC0
3165         lsl     r0, #4
3166         cmp     r0, #240
3167         beq     .mppuv_xm_panhack
3168         strb    r0, [r7, #MCH_PANNING]
3169         bx      lr
3170 .mppuv_xm_panhack:
3171         mov     r0, #255
3172         strb    r0, [r7, #MCH_PANNING]
3173 .mppuv_exit3:
3174         bx      lr
3175         
3176 .align 2
3177 .thumb_func
3178 @----------------------------------------------------------------------------------------
3179 .mppuv_xm_panslide:                                     @ Panning Slide
3180 @----------------------------------------------------------------------------------------
3181         
3182         cmp     r2, #0
3183         beq     .mppuv_exit3
3184         ldrb    r2, [r7, #MCH_PANNING]
3185         ldrb    r3, [r7, #MCH_MEMORY + MPP_XM_VFX_MEM_PANSL]
3186         cmp     r0, #0xE0
3187         bge     .mppuv_xm_panslide_right
3188         sub     r0, #0xD0
3189         bne     1f
3190         lsr     r0, r3, #4
3191         b       2f
3192 1:      lsl     r3, #32-4
3193         lsr     r3, #32-4
3194         lsl     r0, #4
3195         orr     r3, r0
3196         lsr     r0, #4
3197         strb    r3, [r7, #MCH_MEMORY + MPP_XM_VFX_MEM_PANSL]
3198
3199 2:      lsl     r0, #2
3200         sub     r2, r0
3201         bcs     .mppuv_xm_panslide_set
3202         mov     r2, #0
3203         b       .mppuv_xm_panslide_set
3204 .mppuv_xm_panslide_right:
3205         sub     r0, #0xE0
3206         bne     1f
3207         lsl     r0, r3, #32-4
3208         lsr     r0, #32-4
3209         b       2f
3210 1:      lsr     r3, #4
3211         lsl     r3, #4
3212         orr     r3, r0
3213         strb    r3, [r7, #MCH_MEMORY + MPP_XM_VFX_MEM_PANSL]
3214 2:      lsl     r0, #2
3215         add     r2, r0
3216         cmp     r2, #255
3217         blt     .mppuv_xm_panslide_set
3218         mov     r2, #255
3219 .mppuv_xm_panslide_set:
3220         strb    r2, [r7, #MCH_PANNING]
3221         bx      lr
3222
3223 .align 2
3224 .thumb_func
3225 @-------------------------------------------------------------------------------------
3226 .mppuv_xm_toneporta:                                    @ Glissando
3227 @-------------------------------------------------------------------------------------
3228
3229         @ glissando...
3230         @ on nonzero ticks, do a regular glissando slide at speed * 16
3231         cmp     r2, #0
3232         beq     1f
3233         
3234         sub     r0, #0xF0
3235         lsl     r0, #4
3236         beq     2f
3237         mov     r1, #MCH_MEMORY+MPP_XM_VFX_MEM_GLIS
3238         strb    r0, [r7, r1]
3239 2:      ldrb    r0, [r7, r1]
3240         mov     r1, r0
3241         
3242         b       .mppe_glis_backdoor
3243         
3244 1:      bx      lr
3245
3246
3247
3248 /******************************************************************************
3249  *
3250  * Module Effects
3251  *
3252  ******************************************************************************/
3253
3254
3255
3256 /******************************************************************************
3257  * mpp_ProcessEffect()
3258  *
3259  * Process pattern effect.
3260  ******************************************************************************/
3261                                                 .global mpp_Process_Effect
3262                                                 .thumb_func
3263 mpp_Process_Effect:
3264
3265         push    {lr}
3266         ldrb    r0, [r7, #MCH_EFFECT]   @ get effect#
3267         ldrb    r1, [r7, #MCH_PARAM]    @ r1 = param
3268         bl      mpp_Channel_ExchangeMemory
3269
3270         lsl     r0, #1
3271
3272         pop     {r2}
3273         mov     lr, r2
3274
3275         mov     r2, r8
3276         ldrb    r2, [r2, #MPL_TICK]     @ r2 = tick#
3277
3278         cmp     r2, #0                  @ Z flag = tick0 :)
3279         add     r0, pc
3280         mov     pc, r0
3281         
3282         b       mppe_todo
3283         b       mppe_SetSpeed
3284         b       mppe_PositionJump
3285         b       mppe_PatternBreak
3286         b       mppe_VolumeSlide
3287         b       mppe_Portamento
3288         b       mppe_Portamento
3289         b       mppe_Glissando
3290         b       mppe_Vibrato
3291         b       mppe_todo
3292         b       mppe_Arpeggio
3293         b       mppe_VibratoVolume
3294         b       mppe_PortaVolume
3295         b       mppe_ChannelVolume
3296         b       mppe_ChannelVolumeSlide
3297         b       mppe_SampleOffset
3298         b       mppe_todo
3299         b       mppe_Retrigger
3300         b       mppe_Tremolo            @ tremolo
3301         b       mppe_Extended
3302         b       mppe_SetTempo
3303         b       mppe_FineVibrato
3304         b       mppe_SetGlobalVolume
3305         b       mppe_GlobalVolumeSlide
3306         b       mppe_SetPanning
3307         b       mppe_Panbrello
3308         b       mppe_ZXX
3309         b       mppe_SetVolume
3310         b       mppe_KeyOff
3311         b       mppe_EnvelopePos
3312         b       mppe_OldTremor
3313 .pool
3314
3315 .align 2
3316 .thumb_func
3317 @---------------------------------------------------------------------------------
3318 mppe_SetSpeed:                          @ EFFECT Axy: SET SPEED
3319 @---------------------------------------------------------------------------------
3320
3321         bne     .mppe_ss_exit           @ dont set on nonzero ticks
3322         cmp     r1, #0
3323         beq     .mppe_ss_exit
3324         mov     r0, r8
3325         
3326         strb    r1, [r0, #MPL_SPEED]
3327 .mppe_ss_exit:
3328 .thumb_func
3329 mppe_todo:
3330         bx      lr                      @ exit
3331
3332 .align 2
3333 .thumb_func
3334 @---------------------------------------------------------------------------------
3335 mppe_PositionJump:                      @ EFFECT Bxy: SET POSITION
3336 @---------------------------------------------------------------------------------
3337
3338         bne     .mppe_pj_exit           @ skip nonzero ticks
3339         mov     r0, r8
3340         strb    r1, [r0, #MPL_PATTJUMP]
3341 .mppe_pj_exit:
3342         bx      lr                      @ exit
3343 .pool
3344
3345 .align 2
3346 .thumb_func
3347 @---------------------------------------------------------------------------------
3348 mppe_PatternBreak:                              @ EFFECT Cxy: PATTERN BREAK
3349 @---------------------------------------------------------------------------------
3350         bne     .mppe_pb_exit                   @ skip nonzero ticks
3351         mov     r0, r8                          @ get variables
3352         strb    r1, [r0, #MPL_PATTJUMP_ROW]     @ save param to row value
3353         ldrb    r1, [r0, #MPL_PATTJUMP]         @ check if pattjump=empty
3354         cmp     r1, #255                        @ 255=empty
3355         bne     .mppe_pb_exit                   @ ...
3356         ldrb    r1, [r0, #MPL_POSITION]         @ if empty, set pattjump=position+1
3357         add     r1, #1
3358         strb    r1, [r0, #MPL_PATTJUMP]
3359 .mppe_pb_exit:
3360         bx      lr                              @ finished
3361 .pool
3362
3363 .align 2
3364 .thumb_func
3365 @------------------------------------------------------------------------------------------
3366 mppe_VolumeSlide:                               @ EFFECT Dxy: VOLUME SLIDE
3367 @------------------------------------------------------------------------------------------
3368
3369         push    {lr}
3370         ldrb    r0, [r7, #MCH_VOLUME]           @ load volume
3371         
3372         bl      mpph_VolumeSlide64
3373         
3374         strb    r0, [r7, #MCH_VOLUME]           @ save volume
3375 .mppe_vs_zt:
3376         pop     {r0}
3377         bx      r0
3378 //      pop     {pc}                            @ exit
3379
3380 .align 2
3381 .thumb_func
3382 @----------------------------------------------------------------------------------
3383 mppe_Portamento:                                @ EFFECT Exy/Fxy: Portamento
3384 @----------------------------------------------------------------------------------
3385
3386         push    {lr}
3387         
3388 .mppe_pd_ot:
3389         mov     r3, #0
3390         mov     r0, r1
3391         lsr     r0, #4                          @ test for Ex param (Extra fine slide)
3392         cmp     r0, #0xE                        @ ..
3393 .mppe_pd_checkE:                                @ ..
3394         bne     .mppe_pd_checkF                 @ ..
3395         cmp     r2, #0                          @ Extra fine slide: only slide on tick0
3396         bne     .mppe_pd_exit                   @ ..
3397         lsl     r1, #32-4                       @ mask out slide value
3398         lsr     r1, #32-4                       @ ..
3399         mov     r3, #1
3400         b       .mppe_pd_otherslide             @ skip the *4 multiplication
3401 .mppe_pd_checkF:                                @ ------------------------------------
3402         cmp     r0, #0xF                        @ test for Fx param (Fine slide)
3403         bne     .mppe_pd_regslide               @ ..
3404         cmp     r2, #0                          @ Fine slide: only slide on tick0
3405         bne     .mppe_pd_exit                   @ ..
3406         lsl     r1, #32-4                       @ mask out slide value
3407         lsr     r1, #32-4                       @ ..
3408         b       .mppe_pd_otherslide
3409 .mppe_pd_regslide:
3410         cmp     r2, #0
3411         beq     .mppe_pd_exit
3412 .mppe_pd_otherslide:
3413         
3414         ldrb    r0, [r7, #MCH_EFFECT]           @ check slide direction
3415         mov     r2, #MCH_PERIOD
3416         cmp     r0, #5                          @ .. (5 = portamento down)
3417         ldr     r0, [r7, r2]                    @ get period
3418         
3419         bne     .mppe_pd_slideup                @ branch to function
3420 .mppe_pd_slidedown:                             @ -------SLIDE DOWN-------
3421         
3422         cmp     r3, #0
3423         bne     .mppe_pd_fineslidedown
3424         bl      mpph_PitchSlide_Down
3425         
3426         b       .mppe_pd_store                  @ store & exit
3427
3428 .mppe_pd_fineslidedown:
3429         bl      mpph_FinePitchSlide_Down
3430         b       .mppe_pd_store
3431         
3432 .mppe_pd_slideup:                               @ ---------SLIDE UP---------
3433         
3434         cmp     r3, #0
3435         bne     .mppe_pd_fineslideup
3436         bl      mpph_PitchSlide_Up
3437         b       .mppe_pd_store
3438 .mppe_pd_fineslideup:
3439         bl      mpph_FinePitchSlide_Up
3440
3441 .mppe_pd_store:
3442         mov     r2, #MCH_PERIOD
3443         ldr     r1, [r7, #MCH_PERIOD]
3444         str     r0, [r7, #MCH_PERIOD]
3445         sub     r0, r1
3446         add     r5, r0
3447 .mppe_pd_exit:
3448         pop     {r0}
3449         bx      r0                              @ exit
3450
3451 .align 2
3452 .thumb_func
3453 @---------------------------------------------------------------------------------
3454 mppe_Glissando:                                 @ EFFECT Gxy: Glissando
3455 @---------------------------------------------------------------------------------
3456
3457         bne     .mppe_glis_ot
3458         
3459         mov     r0, r8
3460         ldrb    r0, [r0, #MPL_FLAGS]
3461         lsr     r0, #C_FLAGS_GS
3462         bcc     2f
3463         @ gxx is shared, IT MODE ONLY!!
3464         cmp     r1, #0
3465         bne     3f
3466         ldrb    r1, [r7, #MCH_MEMORY+MPP_IT_PORTAMEM]
3467         strb    r1, [r7, #MCH_PARAM]
3468 3:      strb    r1, [r7, #MCH_MEMORY+MPP_IT_PORTAMEM]
3469         strb    r1, [r7, #MCH_MEMORY+MPP_GLIS_MEM]      @ for simplification later
3470         b       .mppe_glis_ot
3471         
3472 2:      @ gxx is separate
3473         cmp     r1, #0
3474         bne     3f
3475         
3476         ldrb    r1, [r7, #MCH_MEMORY+MPP_GLIS_MEM]
3477         strb    r1, [r7, #MCH_PARAM]
3478 3:      strb    r1, [r7, #MCH_MEMORY+MPP_GLIS_MEM]
3479
3480         bx      lr
3481 //      b       .mppe_glis_exit
3482 .mppe_glis_ot:
3483         
3484         push    {lr}                                    // save return address
3485
3486         ldrb    r1, [r7, #MCH_MEMORY+MPP_GLIS_MEM]
3487
3488 .mppe_glis_backdoor:
3489
3490         push    {r1}
3491         
3492         cmp     r6, #0                                  // exit if no active channel
3493         bne     1f                                      //
3494         pop     {r1,r3}                                 //
3495         bx      r3                                      //
3496 1:                                                      //
3497         
3498         ldrb    r0, [r6, #MCA_SAMPLE]                   // get target period
3499         sub     r0, #1                                  //
3500         mpp_SamplePointer                               //
3501         ldrh    r1, [r0, #C_MASS_FREQ]                  //
3502         LSL     R1, #2                                  //
3503         ldrb    r2, [r7, #MCH_NOTE]                     //
3504         ldr     r3,=mmGetPeriod                         //
3505         bl      mpp_call_r3                             //
3506         
3507         pop     {r1}                                    // r1 = parameter
3508         push    {r0}                                    // 
3509         
3510         mov     r3, r0                                  // r3 = target period
3511         mov     r2, #MCH_PERIOD                         // r0 = current period
3512         ldr     r0, [r7, r2]                            //
3513         mov     r2, r8                                  // test S flag
3514         ldrb    r2, [r2, #MPL_FLAGS]                    //
3515         lsr     r2, #C_FLAGS_SS                         //
3516         bCC     .mppe_glis_amiga
3517         cmp     r0, r3
3518         blt     .mppe_glis_slideup
3519         bgt     .mppe_glis_slidedown
3520 .mppe_glis_noslide:
3521         pop     {r0}
3522         pop     {r3}
3523         bx      r3
3524
3525 .mppe_glis_slideup:
3526         bl      mpph_PitchSlide_Up
3527         pop     {r1}
3528         
3529         cmp     r0, r1
3530         blt     .mppe_glis_store
3531         mov     r0, r1
3532         b       .mppe_glis_store
3533 .mppe_glis_slidedown:
3534         bl      mpph_PitchSlide_Down
3535         pop     {r1}
3536         cmp     r0, r1
3537         bgt     .mppe_glis_store
3538         mov     r0, r1
3539 .mppe_glis_store:
3540         
3541         mov     r2, #MCH_PERIOD
3542         ldr     r1, [r7, r2] @#MCA_PERIOD]
3543         str     r0, [r7, r2] @#MCA_PERIOD]
3544         sub     r0, r1
3545         add     r5, r0
3546         
3547 .mppe_glis_exit:
3548         pop     {r3}
3549         bx      r3
3550
3551
3552         //bx    lr
3553
3554 .mppe_glis_amiga:
3555
3556         cmp     r0, r3
3557         blt     .mppe_glis_amiga_up
3558         bgt     .mppe_glis_amiga_down
3559         pop     {r0}
3560         pop     {r3}
3561         bx      r3
3562
3563 .mppe_glis_amiga_down:
3564         bl      mpph_PitchSlide_Up
3565         pop     {r1}
3566         cmp     r0, r1
3567         bgt     .mppe_glis_store
3568         mov     r0, r1
3569         b       .mppe_glis_store
3570 .mppe_glis_amiga_up:
3571         bl      mpph_PitchSlide_Down
3572         pop     {r1}
3573         cmp     r0, r1
3574         blt     .mppe_glis_store
3575         mov     r0, r1
3576         b       .mppe_glis_store
3577
3578 .align 2
3579 .thumb_func
3580 @---------------------------------------------------------------------------------
3581 mppe_Vibrato:                                   @ EFFECT Hxy: Vibrato
3582 @---------------------------------------------------------------------------------
3583
3584         bne     .mppe_v_ot
3585         lsr     r0, r1, #4                      @ if (x != 0) {
3586         beq     .mppe_v_nospd                   @   speed = 4*x;
3587         lsl     r0, #2                          @   ..
3588         strb    r0, [r7, #MCH_VIBSPD]           @   ..
3589 .mppe_v_nospd:
3590         
3591         lsl     r0, r1, #32-4                   @ if (y != 0) {
3592         beq     .mppe_v_nodep                   @ ..
3593         lsr     r0, #32-6                       @   depth = y * 4;
3594         mov     r1, r8
3595         ldrb    r1, [r1, #MPL_OLDEFFECTS]       @   if(OldEffects)
3596         lsl     r0, r1                          @      depth <<= 1;
3597         strb    r0, [r7, #MCH_VIBDEP]           @
3598         b       mppe_DoVibrato
3599 .mppe_v_nodep:
3600         BX      LR
3601
3602 .align 2
3603 .thumb_func
3604 @-------------------------------------------------------
3605 mppe_DoVibrato:
3606 @-------------------------------------------------------
3607
3608 .mppe_v_ot:
3609         mov     r0, r8
3610         ldrb    r1, [r0, #MPL_TICK]
3611         ldrb    r0, [r0, #MPL_OLDEFFECTS]
3612         
3613         cmp     r0, #0
3614         beq     .mppe_dv_update
3615         cmp     r1, #0
3616         bne     .mppe_dv_update
3617         
3618         push    {lr}
3619         ldrb    r1, [r7, #MCH_VIBPOS]
3620         b       .mppe_dv_notupdate
3621 .mppe_dv_update:
3622         push    {lr}
3623         ldrb    r0, [r7, #MCH_VIBSPD]
3624         ldrb    r1, [r7, #MCH_VIBPOS]
3625         add     r1, r0
3626         lsl     r1, #32-8
3627         lsr     r1, #32-8
3628         strb    r1, [r7, #MCH_VIBPOS]
3629 .mppe_dv_notupdate:
3630         ldr     r2,=mpp_TABLE_FineSineData
3631         ldrsb   r1, [r2, r1]
3632         ldrb    r0, [r7, #MCH_VIBDEP]
3633         mul     r1, r0
3634         asr     r1, #8
3635         mov     r0, r5
3636         cmp     r1, #0
3637         blt     .mppe_dv_negative
3638         bl      mpph_PitchSlide_Up
3639         b       .mppe_dv_store
3640 .mppe_dv_negative:
3641         neg     r1, r1
3642         bl      mpph_PitchSlide_Down
3643 .mppe_dv_store:
3644         mov     r5, r0
3645         pop     {r0}
3646         bx      r0
3647 //      pop     {pc}            @ return THUMB
3648 .pool
3649
3650 .align 2
3651 .thumb_func
3652 @---------------------------------------------------------------------------------
3653 mppe_Tremor:                                    @ EFFECT Ixy: Tremor
3654 @---------------------------------------------------------------------------------
3655         bx      lr
3656
3657 .align 2
3658 .thumb_func
3659 @---------------------------------------------------------------------------------
3660 mppe_Arpeggio:                                  @ EFFECT Jxy: Arpeggio
3661 @---------------------------------------------------------------------------------
3662
3663         bne     .mppe_arp_ot
3664
3665         mov     r0, #0
3666         strb    r0, [r7, #MCH_FXMEM]
3667 .mppe_arp_ot:
3668         cmp     r6, #0
3669         beq     1f
3670         ldrb    r0, [r7, #MCH_FXMEM]
3671 //      ldrb    r3, [r6, #MCA_SAMPLE]   ?               ???     
3672         cmp     r0, #1
3673         bgt     .mppe_arp_2
3674         beq     .mppe_arp_1
3675 .mppe_arp_0:
3676         mov     r0, #1
3677         strb    r0, [r7, #MCH_FXMEM]
3678         @ do nothing! :)
3679 1:      bx      lr
3680         
3681 .mppe_arp_1:
3682         
3683         mov     r0, #2                  @ set next tick to '2'
3684         strb    r0, [r7, #MCH_FXMEM]    @ save...
3685         mov     r0, r5
3686         lsr     r1, #4                  @ mask out high nibble of param
3687 .mppe_arp_others:
3688         mov     r2, r5
3689         cmp     r1, #12                 @ see if its >= 12
3690         blt     .mppea1_12              @ ..
3691         add     r2, r5                  @  add period if so... (octave higher)
3692 .mppea1_12:                             @  ..
3693         lsl     r1, #4                  @ *16*hword
3694         
3695         mov     r0, r5
3696         push    {lr}
3697         bl      mpph_LinearPitchSlide_Up
3698
3699         mov     r5, r0
3700         pop     {r0}
3701         bx      r0
3702 //      pop     {pc}
3703         
3704 .mppe_arp_2:
3705         mov     r0, #0
3706         strb    r0, [r7, #MCH_FXMEM]
3707         mov     r0, r5
3708         lsl     r1, #32-4
3709         lsr     r1, #32-4
3710         b       .mppe_arp_others
3711
3712 .align 2
3713 .thumb_func
3714 @---------------------------------------------------------------------------------
3715 mppe_VibratoVolume:                     @ EFFECT Kxy: Vibrato+Volume Slide
3716 @---------------------------------------------------------------------------------
3717
3718         push    {lr}
3719         push    {r1,r2}
3720         bl      mppe_DoVibrato
3721         pop     {r1,r2}
3722         cmp     r2, #0
3723         bl      mppe_VolumeSlide
3724         pop     {r0}
3725         bx      r0
3726 //      pop     {pc}
3727
3728 .align 2
3729 .thumb_func
3730 @---------------------------------------------------------------------------------
3731 mppe_PortaVolume:                       @ EFFECT Lxy: Portamento+Volume Slide
3732 @---------------------------------------------------------------------------------
3733
3734         push    {lr}
3735         push    {r1,r2}
3736         ldrb    r1, [r7, #MCH_MEMORY+MPP_GLIS_MEM]
3737         bl      mppe_Glissando
3738         pop     {r1, r2}
3739         cmp     r2, #0
3740         bl      mppe_VolumeSlide
3741         pop     {r0}
3742         bx      r0
3743 //      pop     {pc}
3744
3745 .align 2
3746 .thumb_func
3747 @---------------------------------------------------------------------------------
3748 mppe_ChannelVolume:                             @ EFFECT Mxy: Set Channel Volume
3749 @---------------------------------------------------------------------------------
3750
3751         bne     .mppe_cv_exit                   @ quite simple...
3752         cmp     r1, #0x40
3753         bgt     .mppe_cv_exit                   @ ignore command if parameter is > 0x40
3754         strb    r1, [r7, #MCH_CVOLUME]
3755 .mppe_cv_exit:
3756         bx      lr
3757         
3758 .align 2
3759 .thumb_func
3760 @------------------------------------------------------------------------------------
3761 mppe_ChannelVolumeSlide:                        @ EFFECT Nxy: Channel Volume Slide
3762 @------------------------------------------------------------------------------------
3763
3764         push    {lr}
3765
3766         ldrb    r0, [r7, #MCH_CVOLUME]          @ load volume
3767         bl      mpph_VolumeSlide64
3768
3769         strb    r0, [r7, #MCH_CVOLUME]          @ save volume
3770         pop     {r0}
3771         bx      r0
3772 //      pop     {pc}                            @ exit
3773
3774 .align 2
3775 .thumb_func
3776 @----------------------------------------------------------------------------------
3777 mppe_SampleOffset:                              @ EFFECT Oxy Sample Offset
3778 @----------------------------------------------------------------------------------
3779
3780         bne     .mppe_so_exit                   @ skip on other ticks
3781
3782         ldr     r0,=mpp_vars
3783         strb    r1, [r0, #MPV_SAMPOFF]          @ set offset
3784 .mppe_so_exit:
3785         bx      lr
3786 .pool
3787
3788 .align 2
3789 .thumb_func
3790 @---------------------------------------------------------------------------------
3791 mppe_PanningSlide:                              @ EFFECT Pxy Panning Slide
3792 @---------------------------------------------------------------------------------
3793
3794         push    {lr}
3795
3796         mov     r0, #255
3797         push    {r0}
3798         ldrb    r0, [r7, #MCH_PANNING]          @ load panning
3799         
3800         bl      mpph_VolumeSlide
3801
3802         strb    r0, [r7, #MCH_PANNING]          @ save panning
3803         pop     {r0}
3804         bx      r0
3805 //      pop     {pc}                            @ exit
3806
3807 .align 2
3808 .thumb_func
3809 @---------------------------------------------------------------------------------
3810 mppe_Retrigger:                                 @ EFFECT Qxy Retrigger Note
3811 @---------------------------------------------------------------------------------
3812
3813         ldrb    r0, [r7, #MCH_FXMEM]
3814         cmp     r0, #0
3815         bne     .mppe_retrig_refillN
3816 .mppe_retrig_refill:
3817         lsl     r0, r1, #32-4
3818         lsr     r0, #32-4
3819         add     r0, #1
3820 .mppe_retrig_exitcount:
3821         strb    r0, [r7, #MCH_FXMEM]
3822         bx      lr
3823 .mppe_retrig_refillN:
3824         sub     r0, #1
3825         cmp     r0, #1
3826         bne     .mppe_retrig_exitcount
3827 .mppe_retrig_fire:
3828         
3829         ldrb    r2, [r7, #MCH_VOLUME]
3830         lsr     r0, r1, #4
3831         beq     .mppe_retrig_v_change0
3832         cmp     r0, #5
3833         ble     .mppe_retrig_v_change_sub
3834         cmp     r0, #6
3835         beq     .mppe_retrig_v_change_23
3836         cmp     r0, #7
3837         beq     .mppe_retrig_v_change_12
3838         cmp     r0, #8
3839         beq     .mppe_retrig_v_change0
3840         cmp     r0, #0xD
3841         ble     .mppe_retrig_v_change_add
3842         cmp     r0, #0xE
3843         beq     .mppe_retrig_v_change_32
3844         cmp     r0, #0xF
3845         beq     .mppe_retrig_v_change_21
3846 .mppe_retrig_v_change_21:
3847         lsl     r2, #1
3848         cmp     r2, #64
3849         blt     .mppe_retrig_finish
3850         mov     r2, #64
3851 .mppe_retrig_v_change0:
3852         b       .mppe_retrig_finish
3853 .mppe_retrig_v_change_sub:
3854         sub     r0, #1
3855         mov     r3, #1
3856         lsl     r3, r0
3857         sub     r2, r3
3858         bcs     .mppe_retrig_finish
3859         mov     r2, #0
3860         b       .mppe_retrig_finish
3861 .mppe_retrig_v_change_23:
3862         mov     r0, #171
3863         mul     r2, r0
3864         lsr     r2, #8
3865         b       .mppe_retrig_finish
3866 .mppe_retrig_v_change_12:
3867         lsr     r2, #1
3868         b       .mppe_retrig_finish
3869 .mppe_retrig_v_change_add:
3870         sub     r0, #9
3871         mov     r3, #1
3872         lsl     r3, r0
3873         add     r2, r3
3874         cmp     r2, #64
3875         blt     .mppe_retrig_finish
3876         mov     r2, #64
3877         b       .mppe_retrig_finish
3878 .mppe_retrig_v_change_32:
3879         mov     r0, #192
3880         mul     r2, r0
3881         lsr     r2, #7
3882 .mppe_retrig_finish:
3883         strb    r2, [r7, #MCH_VOLUME]
3884         cmp     r6, #0
3885         beq     .mppe_retrig_refill
3886         ldrb    r0, [r6, #MCA_FLAGS]
3887         mov     r2, #MCAF_START
3888         orr     r0, r2
3889         strb    r0, [r6, #MCA_FLAGS]
3890         b       .mppe_retrig_refill
3891
3892 .align 2
3893 .thumb_func
3894 @---------------------------------------------------------------------------------
3895 mppe_Tremolo:                                   @ EFFECT Rxy: Tremolo
3896 @---------------------------------------------------------------------------------
3897
3898 @ r1 = param
3899 @ Z = tick0
3900
3901         beq     .mppe_trem_zt                   @ skip this part on tick0
3902 .mppe_trem_ot:
3903         @ X = speed, Y = depth
3904         ldrb    r0, [r7, #MCH_FXMEM]            @ get sine position
3905         lsr     r3, r1, #4                      @ mask out SPEED
3906         lsl     r3, #2                          @ speed*4 to compensate for larger sine table
3907         add     r0, r3                          @ add to position
3908         strb    r0, [r7, #MCH_FXMEM]            @ save (value & 255)
3909 .mppe_trem_zt:
3910         ldrb    r0, [r7, #MCH_FXMEM]            @ get sine position
3911         ldr     r3,=mpp_TABLE_FineSineData      @ load sine table value
3912         ldrsb   r0, [r3, r0]
3913         lsl     r1, #32-4                       @ mask out DEPTH
3914         lsr     r1, #32-4
3915         mul     r0, r1                          @ SINE*DEPTH / 64
3916         asr     r0, #6
3917         mov     r1, r8
3918         ldrb    r1, [r1, #MPL_FLAGS]
3919         lsr     r1, #C_FLAGS_XS
3920         bcs     1f
3921         asr     r0, #1
3922 1:      ldr     r1,=mpp_vars                    @ set volume addition variable
3923         strb    r0, [r1, #MPV_VOLPLUS]
3924         bx      lr
3925 .pool
3926
3927 .align 2
3928 .thumb_func
3929 @---------------------------------------------------------------------------------
3930 mppe_Extended:                          @ EFFECT Sxy: Extended Effects
3931 @---------------------------------------------------------------------------------
3932         
3933         lsr     r0, r1, #4
3934         lsl     r0, #1
3935         cmp     r2, #0
3936         add     r0, pc
3937         mov     pc, r0
3938         
3939         @ branch table...
3940         b       mppex_XM_FVolSlideUp    @ S0x
3941         b       mppex_XM_FVolSlideDown  @ S1x
3942         b       mppex_OldRetrig         @ S2x
3943         b       mppex_VibForm           @ S3x
3944         b       mppex_TremForm          @ S4x
3945         b       mppex_PanbForm          @ S5x
3946         b       mppex_FPattDelay        @ S6x
3947         b       mppex_InstControl       @ S7x
3948         b       mppex_SetPanning        @ S8x
3949         b       mppex_SoundControl      @ S9x
3950         b       mppex_HighOffset        @ SAx
3951         b       mppex_PatternLoop       @ SBx
3952         b       mppex_NoteCut           @ SCx
3953         b       mppex_NoteDelay         @ SDx
3954         b       mppex_PatternDelay      @ SEy
3955         b       mppex_SongMessage       @ SFx
3956
3957 .mppe_ex_quit:
3958
3959 @-------------------------------------------
3960 .thumb_func
3961 mppex_Unused:
3962         bx      lr
3963
3964 @-------------------------------------------
3965
3966 .thumb_func
3967 mppex_XM_FVolSlideUp:
3968         bne     2f
3969         ldrb    r0, [r7, #MCH_VOLUME]
3970         lsl     r1, #32-4
3971         lsr     r1, #32-4
3972         add     r0, r1
3973         cmp     r0, #64
3974         blt     1f
3975         mov     r0, #64
3976 1:      strb    r0, [r7, #MCH_VOLUME]
3977 2:      bx      lr
3978
3979 .thumb_func
3980 mppex_XM_FVolSlideDown:
3981         bne     2f
3982         ldrb    r0, [r7, #MCH_VOLUME]
3983         lsl     r1, #32-4
3984         lsr     r1, #32-4
3985         sub     r0, r1
3986         bcs     1f
3987         mov     r0, #0
3988 1:      strb    r0, [r7, #MCH_VOLUME]
3989 2:      bx      lr
3990
3991 @-------------------------------------------
3992 .thumb_func
3993 mppex_OldRetrig:
3994         bne     1f
3995         lsl     r1, #32-4
3996         lsr     r1, #32-4
3997         strb    r1, [r7, #MCH_FXMEM]
3998         bx      lr
3999         
4000 1:      ldrb    r0, [r7, #MCH_FXMEM]
4001         sub     r0, #1
4002
4003         bne     1f
4004         
4005         lsl     r0, r1, #32-4
4006         lsr     r0, #32-4
4007         strb    r0, [r7, #MCH_FXMEM]
4008
4009         cmp     r6, #0
4010         beq     1f
4011         ldrb    r1, [r6, #MCA_FLAGS]
4012         mov     r2, #MCAF_START
4013         
4014         orr     r1, r2
4015         strb    r1, [r6, #MCA_FLAGS]
4016         
4017 1:      strb    r0, [r7, #MCH_FXMEM]
4018         bx      lr
4019
4020 @-------------------------------------------
4021 .thumb_func
4022 mppex_VibForm:
4023         bx      lr
4024
4025 @-------------------------------------------
4026 .thumb_func
4027 mppex_TremForm:
4028         bx      lr
4029
4030 @-------------------------------------------
4031 .thumb_func
4032 mppex_PanbForm:
4033         bx      lr
4034
4035 @-------------------------------------------
4036 .thumb_func
4037 mppex_FPattDelay:
4038         bne     .mppex_fpd_exit
4039         lsl     r1, #32-4
4040         lsr     r1, #32-4
4041         mov     r0, r8
4042         strb    r1, [r0, #MPL_FPATTDELAY]
4043 .mppex_fpd_exit:
4044         bx      lr
4045
4046 @-------------------------------------------
4047 .thumb_func
4048 mppex_InstControl:
4049         bne     .mppex_ic_exit
4050         lsl     r1, #32-4
4051         lsr     r1, #32-4
4052         cmp     r1, #2
4053         ble     .mppex_ic_pastnotes
4054         cmp     r1, #6
4055         ble     .mppex_ic_nna
4056         cmp     r1, #8
4057         ble     .mppex_ic_envelope
4058         bx      lr
4059 .mppex_ic_pastnotes:
4060         @ todo...
4061         bx      lr
4062 .mppex_ic_nna:
4063         @ overwrite NNA
4064         sub     r1, #3
4065         ldrb    r2, [r7, #MCH_BFLAGS]
4066         lsl     r2, #32-6
4067         lsr     r2, #32-6
4068         lsl     r1, #6
4069         orr     r2, r1
4070         strb    r2, [r7, #MCH_BFLAGS]
4071         bx      lr
4072 .mppex_ic_envelope:
4073         cmp     r6, #0
4074         beq     .mppex_ic_exit
4075         ldrb    r2, [r6, #MCA_FLAGS]
4076         mov     r0, #32
4077         bic     r2, r0
4078         sub     r1, #7
4079         lsl     r1, #5
4080         orr     r2, r1
4081         strb    r2, [r6, #MCA_FLAGS]
4082
4083 .mppex_ic_exit:
4084         bx      lr
4085
4086 @-------------------------------------------
4087 .thumb_func
4088 mppex_SetPanning:
4089         lsl     r1, #4
4090         strb    r1, [r7, #MCH_PANNING]
4091         bx      lr
4092
4093 @-------------------------------------------
4094 .thumb_func
4095 mppex_SoundControl:
4096         cmp     r1, #0x91
4097         beq     .mppex_sc_surround
4098         bx      lr
4099 .mppex_sc_surround:
4100         @ set surround
4101         bx      lr
4102
4103 @-------------------------------------------
4104 .thumb_func
4105 mppex_HighOffset:
4106         @ todo...
4107         bx      lr
4108
4109 @-------------------------------------------
4110 .thumb_func
4111 mppex_PatternLoop:
4112         bne     .mppex_pl_exit                          @ dont update on nonzero ticks
4113         mov     r2, r8
4114
4115         lsl     r1, #32-4                               @ mask low nibble of parameter
4116         lsr     r1, #32-4                               @ ...
4117         bne     .mppex_pl_not0                          @ is zero?
4118         
4119         ldrb    r1, [r2, #MPL_ROW]                      @   ...
4120         strb    r1, [r2, #MPL_PLOOP_ROW]                @    ...
4121         ldr     r1,=mpp_vars                            @    ....
4122         ldr     r1, [r1, #MPV_PATTREAD_P]               @   .. ...
4123         mov     r3, #MPL_PLOOP_ADR
4124         str     r1, [r2, r3]                            @  ...  ...
4125         bx      lr                                      @ ...    ...
4126 .mppex_pl_not0:                                         @ otherwise...
4127         ldrb    r0, [r2, #MPL_PLOOP_TIMES]              @   get pattern loop counter
4128         cmp     r0, #0                                  @   zero?
4129         bne     .mppex_pl_active                        @   if not then its already active
4130         strb    r1, [r2, #MPL_PLOOP_TIMES]              @     zero: save parameter to counter
4131         b       .mppex_pl_exit_enable                   @     exit & enable jump
4132 .mppex_pl_active:                                       @  nonzero:
4133         sub     r0, #1                                  @    decrement counter
4134         strb    r0, [r2, #MPL_PLOOP_TIMES]              @    save
4135         beq     .mppex_pl_exit                          @    enable jump if not 0
4136 .mppex_pl_exit_enable:
4137         mov     r0, #1                                  @    enable jump
4138         mov     r3, #MPL_PLOOP_JUMP
4139         strb    r0, [r2, r3]                            @    ..
4140 .mppex_pl_exit:                                         @    exit
4141         bx      lr                                      @    ....
4142 .pool
4143
4144 @-------------------------------------------
4145 .thumb_func
4146 mppex_NoteCut:
4147         lsl     r1, #32-4                       @ mask parameter
4148         lsr     r1, #32-4                       @ ..
4149         cmp     r1, r2                          @ compare with tick#
4150         bne     .mppex_nc_exit                  @ if equal:
4151         mov     r0, #0                          @   cut volume
4152         strb    r0, [r7, #MCH_VOLUME]           @   ..
4153 .mppex_nc_exit:                                 @ exit
4154         bx      lr                              @ ..
4155
4156 @-------------------------------------------
4157 .thumb_func
4158 mppex_NoteDelay:
4159         
4160         mov     r0, r8
4161         ldrb    r2, [r0, #MPL_TICK]
4162         lsl     r1, #32-4
4163         lsr     r1, #32-4
4164         cmp     r2, r1
4165         bge     1f
4166         ldr     r0,=mpp_vars
4167         strb    r1, [r0, #MPV_NOTEDELAY]
4168 1:      bx      lr
4169
4170 @-------------------------------------------
4171 .thumb_func
4172 mppex_PatternDelay:
4173         bne     .mppex_pd_quit                  @ update on tick0
4174         lsl     r1, #32-4                       @ mask parameter
4175         lsr     r1, #32-4                       @ ..
4176         mov     r0, r8
4177         ldrb    r2, [r0, #MPL_PATTDELAY]        @ get patterndelay
4178         cmp     r2, #0                          @ only update if it's 0
4179         bne     .mppex_pd_quit                  @ ..
4180         add     r1, #1                          @ set to param+1
4181         strb    r1, [r0, #MPL_PATTDELAY]        @ ..
4182 .mppex_pd_quit:                                 @ exit
4183         bx      lr                              @ ..
4184
4185 @-------------------------------------------
4186 .thumb_func
4187 mppex_SongMessage:
4188
4189         bne     .mppex_pd_quit                  @ update on tick0
4190         push    {lr}                            @ save return address
4191         lsl     r1, #32-4                       @ mask parameter
4192         lsr     r1, #32-4                       @ ..
4193         ldr     r2,=mmCallback
4194         ldr     r2, [r2]
4195         cmp     r2, #0
4196         beq     1f
4197         mov     r0, #MPCB_SONGMESSAGE
4198         
4199         bl      mpp_call_r2
4200         @jump2
4201 1:      //pop   {pc}
4202         pop     {r0}
4203         bx      r0
4204 .pool
4205
4206 .align 2
4207 .thumb_func
4208 @----------------------------------------------------------------------------------------
4209 mppe_SetTempo:                                  @ EFFECT Txy: Set Tempo / Tempo Slide
4210 @----------------------------------------------------------------------------------------
4211
4212         @ 0x  = slide down
4213         @ 1x  = slide up
4214         @ 2x+ = set
4215         
4216         // BUGGED???
4217         // not using setbpm for slides???
4218
4219         cmp     r1, #0x20
4220         bge     .mppe_st_set
4221         cmp     r2, #0
4222         beq     .mppe_st_exit
4223
4224         mov     r0, r8
4225         ldrb    r2, [r0, #MPL_BPM]
4226
4227         cmp     r1, #0x10
4228         bge     .mppe_st_slideup
4229 .mppe_st_slidedown:
4230         sub     r2, r1
4231         cmp     r2, #32
4232         bge     .mppe_st_save
4233         mov     r2, #32
4234 .mppe_st_save:
4235         mov     r0, r2
4236         b       .mppe_st_set2
4237 .mppe_st_slideup:
4238         
4239         lsl     r1, #32-4
4240         lsr     r1, #32-4
4241         
4242         add     r2, r1
4243         cmp     r2, #255
4244         blt     .mppe_st_save
4245         mov     r2, #255
4246         b       .mppe_st_save
4247 .mppe_st_set:
4248         cmp     r2, #0
4249         bne     .mppe_st_exit
4250         mov     r0, r1
4251 .mppe_st_set2:
4252         push    {r5,lr}
4253         mov     r5, r8
4254         ldr     r1,=mpp_setbpm
4255         bl      mpp_call_r1
4256         @jump1
4257         pop     {r5}
4258         pop     {r3}
4259         bx      r3
4260 .mppe_st_exit:
4261         bx      lr
4262 .pool
4263
4264 .align 2
4265 .thumb_func
4266 @----------------------------------------------------------------------------------------
4267 mppe_FineVibrato:                               @ EFFECT Uxy: Fine Vibrato
4268 @----------------------------------------------------------------------------------------
4269
4270         bne     .mppe_fv_ot
4271         lsr     r0, r1, #4
4272         beq     .mppe_fv_nospd
4273         lsl     r0, #2
4274         strb    r0, [r7, #MCH_VIBSPD]
4275 .mppe_fv_nospd:
4276         
4277         lsl     r0, r1, #32-4
4278         beq     .mppe_fv_nodep
4279 //      lsr     r0, #32                 heh...
4280         lsr     r0, #32-4
4281         mov     r1, r8
4282         ldrb    r1, [r1, #MPL_OLDEFFECTS]
4283         lsl     r0, r1
4284         strb    r0, [r7, #MCH_VIBDEP]
4285 .mppe_fv_nodep:
4286
4287 .mppe_fv_ot:
4288         b       mppe_DoVibrato
4289 .pool
4290
4291 .align 2
4292 .thumb_func
4293 @------------------------------------------------------------------------------------
4294 mppe_SetGlobalVolume:                   @ EFFECT Vxy: Set Global Volume
4295 @------------------------------------------------------------------------------------
4296
4297         bne     .mppe_sgv_exit          @ on tick0:
4298         mov     r0, r8
4299         ldrb    r2, [r0, #MPL_FLAGS]
4300         mov     r3, #(1<<(C_FLAGS_XS-1))+(1<<(C_FLAGS_LS-1))
4301         tst     r2, r3
4302         beq     1f
4303         mov     r2, #0x40
4304         b       2f
4305 1:      mov     r2, #0x80
4306 2:
4307         cmp     r1, r2
4308         blt     1f
4309         mov     r1, r2
4310 1:      strb    r1, [r0, #MPL_GV]       @ save param to global volume
4311 .mppe_sgv_exit:
4312         bx      lr
4313 .pool
4314
4315
4316 .align 2
4317 .thumb_func
4318 @----------------------------------------------------------------------------------
4319 mppe_GlobalVolumeSlide:                         @ EFFECT Wxy: Global Volume Slide
4320 @----------------------------------------------------------------------------------
4321
4322         push    {lr}
4323
4324 .mppe_gvs_ot:
4325         mov     r0, r8
4326         ldrb    r0, [r0, #MPL_FLAGS]
4327         lsr     r0, #C_FLAGS_XS
4328         bcs     1f
4329         
4330         mov     r0, #128
4331         b       2f
4332
4333 1:      mov     r0, #64
4334
4335 2:      push    {r0}
4336         mov     r0, r8
4337         ldrb    r0, [r0, #MPL_GV]               @ load global volume
4338         
4339         bl      mpph_VolumeSlide                @ slide..       
4340         
4341         mov     r1, r8
4342         strb    r0, [r1, #MPL_GV]               @ save global volume
4343         pop     {r0}
4344         bx      r0
4345 //      pop     {pc}                            @ exit
4346 .pool
4347
4348
4349 .align 2
4350 .thumb_func
4351 @---------------------------------------------------------------------------------------
4352 mppe_SetPanning:                                @ EFFECT Xxy: Set Panning
4353 @---------------------------------------------------------------------------------------
4354
4355         bne     .mppe_sp_exit                   @ on tick0:
4356         strb    r1, [r7, #MCH_PANNING]          @ set panning=param
4357 .mppe_sp_exit:
4358         bx      lr
4359 .pool
4360
4361 .align 2
4362 .thumb_func
4363 @---------------------------------------------------------------------------------------
4364 mppe_Panbrello:                                 @ EFFECT Yxy: Panbrello
4365 @---------------------------------------------------------------------------------------
4366
4367         @ todo
4368         bx      lr
4369
4370 .align 2
4371 .thumb_func
4372 @---------------------------------------------------------------------------------
4373 mppe_ZXX:                               @ EFFECT Zxy: Set Filter
4374 @---------------------------------------------------------------------------------
4375
4376 @       ZXX IS NOT SUPPORTED
4377         bx      lr                      @     exit
4378 .pool
4379
4380 @=======================================================================================
4381 @                                     OLD EFFECTS
4382 @=======================================================================================
4383
4384 .align 2
4385 .thumb_func
4386 @-----------------------------------------------------------------------------------
4387 mppe_SetVolume:                         @ EFFECT 0xx: Set Volume
4388 @-----------------------------------------------------------------------------------
4389
4390         bne     .mppe_sv_exit           @ on tick0:
4391         strb    r1, [r7, #MCH_VOLUME]   @ set volume=param
4392 .mppe_sv_exit:
4393         bx      lr
4394
4395 .align 2
4396 .thumb_func
4397 @-----------------------------------------------------------------------------------
4398 mppe_KeyOff:                            @ EFFECT 1xx: Key Off
4399 @-----------------------------------------------------------------------------------
4400         cmp     r1, r2                  @ if tick=param:
4401         bne     .mppe_ko_exit           @ 
4402         cmp     r6, #0
4403         beq     .mppe_ko_exit
4404         ldrb    r0, [r6, #MCA_FLAGS]    @   clear keyon from flags
4405         mov     r1, #MCAF_KEYON         @
4406         bic     r0, r1                  @
4407         strb    r0, [r6, #MCA_FLAGS]    @
4408 .mppe_ko_exit:
4409         bx      lr                      @ finished
4410 .pool
4411
4412 .align 2
4413 .thumb_func
4414 @-----------------------------------------------------------------------------------
4415 mppe_EnvelopePos:                       @ EFFECT 1xx: Envelope Position
4416 @-----------------------------------------------------------------------------------
4417         bne     .mppe_ep_ot             @ on tick0:
4418         cmp     r6, #0
4419         beq     .mppe_ep_ot
4420
4421         @ - NOT SUPPORTED ANYMORE -
4422
4423 @       strh    r1, [r6, #MCA_ENVP_VOL] @ set volume envelope position
4424 @       strh    r1, [r6, #MCA_ENVP_PAN] @ set panning envelope positin
4425                                         @ pitch envelope wasn't invented yet
4426 .mppe_ep_ot:
4427         bx      lr                      @ finished
4428
4429 .align 2
4430 .thumb_func
4431 @-----------------------------------------------------------------------------------
4432 mppe_OldTremor:                         @ EFFECT 3xy: Old Tremor
4433 @-----------------------------------------------------------------------------------
4434         
4435         bne     .mppe_ot_ot
4436         bx      lr
4437 .mppe_ot_ot:
4438         ldrb    r0, [r7, #MCH_FXMEM]
4439         cmp     r0, #0
4440         bne     .mppe_ot_old
4441 .mppe_ot_new:
4442         ldrb    r0, [r7, #MCH_BFLAGS+1]
4443         mov     r3, #0b110
4444         eor     r0, r3
4445         strb    r0, [r7, #MCH_BFLAGS+1]
4446         lsr     r0, #3
4447         bcc     .mppe_ot_low
4448         lsr     r1, #4
4449         add     r1, #1
4450         strb    r1, [r7, #MCH_FXMEM]
4451         b       .mppe_ot_apply
4452 .mppe_ot_low:
4453         lsl     r1, #32-4
4454         lsr     r1, #32-4
4455         add     r1, #1
4456         strb    r1, [r7, #MCH_FXMEM]
4457         b       .mppe_ot_apply
4458         
4459 .mppe_ot_old:
4460         sub     r0, #1
4461         strb    r0, [r7, #MCH_FXMEM]
4462
4463 .mppe_ot_apply:
4464         ldrb    r2, [r7, #MCH_BFLAGS+1]
4465         
4466         lsr     r2, #3
4467         bcs     .mppe_ot_cut
4468         mov     r1, #-64&255 
4469         ldr     r2,=mpp_vars
4470         strb    r1, [r2, #MPV_VOLPLUS]
4471 .mppe_ot_cut:
4472         bx      lr
4473
4474 @===============================================================================
4475 @                                    FUNCTIONS!!
4476 @===============================================================================
4477
4478 .align 2
4479 .thumb_func
4480 @--------------------------------------------------------------------------
4481 mpph_PitchSlide_Down:                           @ Linear/Amiga slide down
4482 @--------------------------------------------------------------------------
4483
4484         @ r0 = period
4485         @ r1 = slide value (/4)
4486         mov     r2, r8
4487         ldrb    r2, [r2, #MPL_FLAGS]
4488         lsr     r2, #C_FLAGS_SS
4489         bcc     .mpph_psd_amiga
4490         b       .mpph_psd
4491
4492 .thumb_func
4493 @--------------------------------------------------------------------------
4494 mpph_LinearPitchSlide_Down:                     @ Linear slide down
4495 @--------------------------------------------------------------------------
4496
4497         mov     r2, r8
4498         ldrb    r2, [r2, #MPL_FLAGS]
4499         lsr     r2, #C_FLAGS_SS
4500         bcc     .mpph_psu
4501 .mpph_psd:
4502         ldr     r2,=mpp_TABLE_LinearSlideDownTable
4503 .mpph_psd_fine:
4504         lsl     r1, #1
4505         ldrh    r1, [r2, r1]
4506         lsr     r0, #5
4507         mul     r0, r1
4508         lsr     r0, #16 -5
4509 .mpph_psd_clip:
4510         cmp     r0, #0
4511         bge     .mpph_psd_clipdone
4512         mov     r0, #0
4513 .mpph_psd_clipdone:
4514         bx      lr
4515 .mpph_psd_amiga:
4516         lsl     r1, #4
4517 .mpph_psd_amiga_fine:
4518         add     r0, r1
4519         lsr     r1, r0, #16+5
4520         beq     .mpph_psd_clipdone
4521         mov     r0, #1
4522         lsl     r0, #16+5
4523         b       .mpph_psd_clip
4524
4525 .align 2
4526 .thumb_func
4527 @--------------------------------------------------------------------------
4528 mpph_PitchSlide_Up:                     @ Linear/Amiga slide up
4529 @--------------------------------------------------------------------------
4530
4531         @ r0 = period
4532         @ r1 = slide value (/4)
4533
4534         mov     r2, r8
4535         ldrb    r2, [r2, #MPL_FLAGS]
4536         lsr     r2, #C_FLAGS_SS
4537         bcc     .mpph_psu_amiga
4538         b       .mpph_psu
4539 .thumb_func
4540 mpph_LinearPitchSlide_Up:               @ Linear slide up
4541         mov     r2, r8
4542         ldrb    r2, [r2, #MPL_FLAGS]
4543         lsr     r2, #C_FLAGS_SS
4544         bcc     .mpph_psd
4545 .mpph_psu:
4546         ldr     r2,=mpp_TABLE_LinearSlideUpTable
4547         mov     r3, r0
4548         cmp     r1, #192
4549         blt     .mpph_psu_notdouble
4550         add     r3, r3
4551 .mpph_psu_notdouble:
4552 .mpph_psu_fine:
4553         lsl     r1, #1
4554         ldrh    r1, [r2, r1]
4555         lsr     r0, #5
4556         mul     r0, r1
4557         lsr     r0, #16-5
4558         add     r0, r3
4559 .mpph_psu_clip:
4560         mov     r1, r0
4561         lsr     r1, #16+5
4562         beq     .mpph_psu_clipped
4563         mov     r0, #1
4564         lsl     r0, #16+5
4565 .mpph_psu_clipped:
4566         bx      lr
4567 .mpph_psu_amiga:
4568         lsl     r1, #4
4569 .mpph_psu_amiga_fine:
4570         sub     r0, r1
4571         bcs     .mpph_psu_clipped
4572         mov     r0, #0
4573         bx      lr
4574
4575 .align 2
4576 .thumb_func
4577 @---------------------------------------------------------------------------
4578 mpph_FinePitchSlide_Up:
4579 @---------------------------------------------------------------------------
4580
4581         @ r0 = period
4582         @ r1 = slide value (0-15)
4583         mov     r2, r8
4584         ldrb    r2, [r2, #MPL_FLAGS]
4585         lsr     r2, #C_FLAGS_SS
4586         bcc     .mpph_fpsu_amiga
4587         ldr     r2,=mpp_TABLE_FineLinearSlideUpTable
4588         mov     r3, r0
4589         b       .mpph_psu_fine
4590 .mpph_fpsu_amiga:
4591         lsl     r1, #2
4592         b       .mpph_psu_amiga_fine
4593
4594 .align 2
4595 .thumb_func
4596 @-----------------------------------------------------------------------------------
4597 mpph_FinePitchSlide_Down:
4598 @-----------------------------------------------------------------------------------
4599
4600         @ r0 = period
4601         @ r1 = slide value (0-15)
4602         
4603         mov     r2, r8
4604         ldrb    r2, [r2, #MPL_FLAGS]
4605         lsr     r2, #C_FLAGS_SS
4606         bcc     .mpph_fpsd_amiga
4607         ldr     r2,=mpp_TABLE_FineLinearSlideDownTable
4608         b       .mpph_psd_fine
4609 .mpph_fpsd_amiga:
4610         lsl     r1, #2
4611         b       .mpph_psd_amiga_fine
4612 .pool
4613
4614 @-----------------------------------------------------------------------------------
4615
4616 .text
4617 .align 2
4618 .thumb_func
4619 @-----------------------------------------------------------------------------------
4620 mpph_FastForward:
4621 @-----------------------------------------------------------------------------------
4622
4623         @ r1 = #rows to skip
4624         cmp     r1, #0
4625         bne     .mpph_ff
4626 .mpph_ff_exitf:
4627         bx      lr
4628 .mpph_ff:
4629         
4630         mov     r0, r8
4631         ldrb    r2, [r0, #MPL_NROWS]
4632         add     r2, #1
4633         cmp     r1, r2
4634         bge     .mpph_ff_exitf
4635         strb    r1, [r0, #MPL_ROW]
4636         push    {r7,lr}
4637         ldr     r7,=mmReadPattern //mpp_ReadPattern
4638 .mpph_ff_loop:
4639         push    {r1,r7}
4640         bl      mpp_call_r7
4641         pop     {r1,r7}
4642         sub     r1, #1
4643         bne     .mpph_ff_loop
4644
4645         pop     {r7}
4646         pop     {r0}
4647         bx      r0
4648 //      pop     {pc}
4649 .pool
4650
4651 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
4652 @          IWRAM CODE          @
4653 @                              @
4654 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
4655
4656 .align 2
4657 .thumb_func
4658 @-----------------------------------------------------------------------------
4659 mpph_VolumeSlide64:
4660 @-----------------------------------------------------------------------------
4661
4662         mov     r3, #64
4663         push    {r3}
4664
4665 .thumb_func
4666 @-----------------------------------------------------------------------------
4667 mpph_VolumeSlide:
4668 @-----------------------------------------------------------------------------
4669
4670         @ r0 = volume
4671         @ r1 = paramter
4672         @ r2 = tick#
4673         @ stack:1 = max volume
4674         
4675         mov     r3, r8
4676         ldrb    r3, [r3, #MPL_FLAGS]
4677         lsr     r3, #C_FLAGS_XS
4678         bcs     .mpph_vs_XM
4679         
4680         cmp     r1, #0x0F                       @  is value 15?
4681         bne     .mpph_vs_hack1                  @    then only slide on tick0
4682         b       .mpph_vs_fsub
4683 .mpph_vs_hack1:
4684         cmp     r1, #0xF0                       @  is value 15?
4685         bne     .mpph_vs_hack2                  @    then only slide on tick0
4686         cmp     r2, #0                          @    ..
4687         bne     .mpph_vs_exit                   @    ..
4688         b       .mpph_vs_fadd
4689 .mpph_vs_hack2:
4690
4691         mov     r3, r1                          @ test for Dx0
4692         lsl     r3, #32-4                       @ ..
4693         bne     .mpph_vs_next1                  @ ..
4694 .mpph_vs_add:                                   @ Dx0:                  (used for DxF too)
4695         cmp     r2, #0
4696         beq     .mpph_vs_exit
4697 .mpph_vs_fadd:
4698         lsr     r1, #4                          @  fix value
4699         add     r0, r1                          @  add to volume
4700         pop     {r1}
4701         cmp     r0, r1                          @  clip values past 64
4702         blt     .mpph_vs_exit2                  @  ..
4703         mov     r0, r1                          @  ..
4704         b       .mpph_vs_exit2                  @  ..
4705 .mpph_vs_next1:                                 @---------------------
4706         mov     r3, r1                          @ test for D0x
4707         lsr     r3, #4                          @ ..
4708         bne     .mpph_vs_next2                  @ ..
4709 .mpph_vs_sub:                                   @ D0x:
4710         cmp     r2, #0
4711         beq     .mpph_vs_exit
4712 .mpph_vs_fsub:
4713         lsl     r1, #32-4                       @  mask value
4714         lsr     r1, #32-4                       @  ..
4715         
4716         sub     r0, r1                          @  subtract from volume
4717         bcs     .mpph_vs_exit                   @  clip values under 0
4718         mov     r0, #0                          @  ..
4719         b       .mpph_vs_exit                   @  ..
4720 .mpph_vs_next2:                                 @---------------------
4721         cmp     r2, #0                          @ fine slides now... only slide on tick0
4722         bne     .mpph_vs_exit                   @ ..
4723         
4724         mov     r3, r1                          @ test for DxF
4725         lsl     r3, #32-4                       @ ..
4726         lsr     r3, #32-4
4727         cmp     r3, #0x0F                       @ ..
4728         beq     .mpph_vs_fadd                   @ branch
4729         
4730         mov     r3, r1                          @ test for DFx
4731         lsr     r3, #4                          @ ..
4732         cmp     r3, #0x0F                       @ ..
4733         beq     .mpph_vs_fsub                   @ branch
4734 .mpph_vs_exit:
4735
4736         pop     {r1}
4737
4738 .mpph_vs_exit2:
4739         bx      lr                              @ exit if all fail
4740         
4741 .mpph_vs_XM:
4742         cmp     r2, #0
4743         beq     .mpph_vs_exit
4744         
4745         lsr     r3, r1, #4
4746         lsl     r1, #32-4
4747         lsr     r1, #32-4
4748         sub     r3, r1
4749         add     r0, r3
4750         pop     {r1}
4751         cmp     r0, r1
4752         blt     .mpph_vsxm_testlow
4753         mov     r0, r1
4754 .mpph_vsxm_testlow:
4755         cmp     r0, #0
4756         bgt     .mpph_vs_exit2
4757         mov     r0, #0
4758         bx      lr
4759 .pool
4760
4761 @==========================================================================================
4762 @                                          TABLES
4763 @==========================================================================================
4764
4765 .TEXT
4766
4767 .align 2
4768 /******************************************************************************
4769  * ST3_FREQTABLE
4770  *
4771  * LUT for amiga periods.
4772  ******************************************************************************/
4773                                                 .global ST3_FREQTABLE
4774 ST3_FREQTABLE:
4775
4776 .hword  1712*8, 1616*8, 1524*8, 1440*8, 1356*8, 1280*8, 1208*8, 1140*8, 1076*8, 1016*8, 960*8, 907*8    @ MORE ACCURACY SCALARS
4777
4778 @middle octave is 4.
4779 @       
4780 @                        133808 * ( period(NOTE) >> octave )
4781 @       note_st3period = --------------------------------------------
4782 @                        middle_c_finetunevalue(INSTRUMENT)
4783 @
4784
4785 .align 2        
4786 @-------------------------------------------------------------------------------------------
4787 mpp_TABLE_LinearSlideUpTable:                   @ value = 2^(val/192), 16.16 fixed
4788 @-------------------------------------------------------------------------------------------
4789
4790 .hword  0,     237,   475,   714,   953   @ 0->4                @ ADD 1.0
4791 .hword  1194,  1435,  1677,  1920,  2164  @ 5->9
4792 .hword  2409,  2655,  2902,  3149,  3397  @ 10->14
4793 .hword  3647,  3897,  4148,  4400,  4653  @ 15->19
4794 .hword  4907,  5157,  5417,  5674,  5932  @ 20->24
4795 .hword  6190,  6449,  6710,  6971,  7233  @ 25->29
4796 .hword  7496,  7761,  8026,  8292,  8559  @ 30->34
4797 .hword  8027,  9096,  9366,  9636,  9908  @ 35->39
4798 .hword  10181, 10455, 10730, 11006, 11283 @ 40->44
4799 .hword  11560, 11839, 12119, 12400, 12682 @ 45->49
4800 .hword  12965, 13249, 13533, 13819, 14106 @ 50->54
4801 .hword  14394, 14684, 14974, 15265, 15557 @ 55->59
4802 .hword  15850, 16145, 16440, 16737, 17034 @ 60->64
4803 .hword  17333, 17633, 17933, 18235, 18538 @ 65->69
4804 .hword  18842, 19147, 19454, 19761, 20070 @ 70->74
4805 .hword  20379, 20690, 21002, 21315, 21629 @ 75->79
4806 .hword  21944, 22260, 22578, 22897, 23216 @ 80->84
4807 .hword  23537, 23860, 24183, 24507, 24833 @ 85->89
4808 .hword  25160, 25488, 25817, 26148, 26479 @ 90->94
4809 .hword  26812, 27146, 27481, 27818, 28155 @ 95->99
4810 .hword  28494, 28834, 29175, 29518, 29862 @ 100->104
4811 .hword  30207, 30553, 30900, 31248, 31599 @ 105->109
4812 .hword  31951, 32303, 32657, 33012, 33369 @ 110->114
4813 .hword  33726, 34085, 34446, 34807, 35170 @ 115->119
4814 .hword  35534, 35900, 36267, 36635, 37004 @ 120->124
4815 .hword  37375, 37747, 38121, 38496, 38872 @ 125->129
4816 .hword  39250, 39629, 40009, 40391, 40774 @ 130->134
4817 .hword  41158, 41544, 41932, 42320, 42710 @ 135->139
4818 .hword  43102, 43495, 43889, 44285, 44682 @ 140->144
4819 .hword  45081, 45481, 45882, 46285, 46690 @ 145->149
4820 .hword  47095, 47503, 47917, 48322, 48734 @ 150->154
4821 .hword  49147, 49562, 49978, 50396, 50815 @ 155->159
4822 .hword  51236, 51658, 52082, 52507, 52934 @ 160->164
4823 .hword  53363, 53793, 54224, 54658, 55092 @ 165->169
4824 .hword  55529, 55966, 56406, 56847, 57289 @ 170->174
4825 .hword  57734, 58179, 58627, 59076, 59527 @ 175->179
4826 .hword  59979, 60433, 60889, 61346, 61805 @ 180->184
4827 .hword  62265, 62727, 63191, 63657, 64124 @ 185->189
4828 .hword  64593, 65064, 0,     474,   950   @ 190->194            @ ADD 2.0 w/ 192+
4829 .hword  1427,  1906,  2387,  2870,  3355  @ 195->199
4830 .hword  3841,  4327,  4818,  5310,  5803  @ 200->204
4831 .hword  6298,  6795,  7294,  7794,  8296  @ 205->209
4832 .hword  8800,  9306,  9814,  10323, 10835 @ 210->214
4833 .hword  11348, 11863, 12380, 12899, 13419 @ 215->219
4834 .hword  13942, 14467, 14993, 15521, 16051 @ 220->224
4835 .hword  16583, 17117, 17653, 18191, 18731 @ 225->229
4836 .hword  19273, 19817, 20362, 20910, 21460 @ 230->234
4837 .hword  22011, 22565, 23121, 23678, 24238 @ 235->239
4838 .hword  24800, 25363, 25929, 25497, 27067 @ 240->244
4839 .hword  27639, 28213, 28789, 29367, 29947 @ 245->249
4840 .hword  30530, 31114, 31701, 32289, 32880 @ 250->254
4841 .hword  33473, 34068                      @ 255->256
4842
4843 .align 2
4844 @-------------------------------------------------------------------------------------
4845 mpp_TABLE_LinearSlideDownTable:                 @ value = 2^(-val/192), 16.16 fixed
4846 @-------------------------------------------------------------------------------------
4847
4848 .hword  65535, 65300, 65065, 64830, 64596, 64364, 64132, 63901 @ 0->7
4849 .hword  63670, 63441, 63212, 62984, 62757, 62531, 62306, 62081 @ 8->15
4850 .hword  61858, 61635, 61413, 61191, 60971, 60751, 60532, 60314 @ 16->23
4851 .hword  60097, 59880, 59664, 59449, 59235, 59022, 58809, 58597 @ 24->31
4852 .hword  58386, 58176, 57966, 57757, 57549, 57341, 57135, 56929 @ 32->39
4853 .hword  56724, 56519, 56316, 56113, 55911, 55709, 55508, 55308 @ 40->47
4854 .hword  55109, 54910, 54713, 54515, 54319, 54123, 53928, 53734 @ 48->55
4855 .hword  53540, 53347, 53155, 52963, 52773, 52582, 52393, 52204 @ 56->63
4856 .hword  52016, 51829, 51642, 51456, 51270, 51085, 50901, 50718 @ 64->71
4857 .hword  50535, 50353, 50172, 49991, 49811, 49631, 49452, 49274 @ 72->79
4858 .hword  49097, 48920, 48743, 48568, 48393, 48128, 48044, 47871 @ 80->87
4859 .hword  47699, 47527, 47356, 47185, 47015, 46846, 46677, 46509 @ 88->95
4860 .hword  46341, 46174, 46008, 45842, 45677, 45512, 45348, 45185 @ 96->103
4861 .hword  45022, 44859, 44698, 44537, 44376, 44216, 44057, 43898 @104->111
4862 .hword  43740, 43582, 43425, 43269, 43113, 42958, 42803, 42649 @112->119
4863 .hword  42495, 42342, 42189, 42037, 41886, 41735, 41584, 41434 @120->127
4864 .hword  41285, 41136, 40988, 40840, 40639, 40566, 40400, 40253 @128->135
4865 .hword  40110, 39965, 39821, 39678, 39535, 39392, 39250, 39109 @136->143
4866 .hword  38968, 38828, 38688, 38548, 38409, 38271, 38133, 37996 @144->151
4867 .hword  37859, 37722, 37586, 37451, 37316, 37181, 37047, 36914 @152->159
4868 .hword  36781, 36648, 36516, 36385, 36254, 36123, 35993, 35863 @160->167
4869 .hword  35734, 35605, 35477, 35349, 35221, 35095, 34968, 34842 @168->175
4870 .hword  34716, 34591, 34467, 34343, 34219, 34095, 33973, 33850 @176->183
4871 .hword  33728, 33607, 33486, 33365, 33245, 33125, 33005, 32887 @184->191
4872 .hword  32768, 32650, 32532, 32415, 32298, 32182, 32066, 31950 @192->199
4873 .hword  31835, 31720, 31606, 31492, 31379, 31266, 31153, 31041 @200->207
4874 .hword  30929, 30817, 30706, 30596, 30485, 30376, 30226, 30157 @208->215
4875 .hword  30048, 29940, 29832, 29725, 29618, 29511, 29405, 29299 @216->223
4876 .hword  29193, 29088, 28983, 28879, 28774, 28671, 28567, 28464 @224->231
4877 .hword  28362, 28260, 28158, 28056, 27955, 27855, 27754, 27654 @232->239
4878 .hword  27554, 27455, 27356, 27258, 27159, 27062, 26964, 26867 @240->247
4879 .hword  26770, 26674, 26577, 26482, 26386, 26291, 26196, 26102 @248->255
4880 .hword  26008                                                  @ 256
4881
4882 /******************************************************************************
4883  * IT_PitchTable
4884  *
4885  * LUT for linear periods.
4886  ******************************************************************************/
4887                                                 .global IT_PitchTable
4888                                                 .align 2
4889 IT_PitchTable:
4890
4891 .hword  2048, 0,   2170, 0,   2299, 0,   2435, 0,   2580, 0,   2734, 0 @ C-0
4892 .hword  2896, 0,   3069, 0,   3251, 0,   3444, 0,   3649, 0,   3866, 0 @>B-0
4893
4894 .hword  4096, 0,   4340, 0,   4598, 0,   4871, 0,   5161, 0,   5468, 0 @ C-1
4895 .hword  5793, 0,   6137, 0,   6502, 0,   6889, 0,   7298, 0,   7732, 0 @>B-1
4896
4897 .hword  8192, 0,   8679, 0,   9195, 0,   9742, 0,   10321, 0,  10935, 0 @ octave 2
4898 .hword  11585, 0,  12274, 0,  13004, 0,  13777, 0,  14596, 0,  15464, 0
4899
4900 .hword  16384, 0,  17358, 0,  18390, 0,  19484, 0,  20643, 0,  21870, 0 @ octave 3
4901 .hword  23170, 0,  24548, 0,  26008, 0,  27554, 0,  29193, 0,  30929, 0
4902
4903 .hword  32768, 0,  34716, 0,  36781, 0,  38968, 0,  41285, 0,  43740, 0 @ octave 4
4904 .hword  46341, 0,  49097, 0,  52016, 0,  55109, 0,  58386, 0,  61858, 0
4905
4906 .hword  0, 1,      3897, 1,   8026, 1,   12400, 1,  17034, 1,  21944, 1 @ octave 5
4907 .hword  27146, 1,  32657, 1,  38496, 1,  44682, 1,  51236, 1,  58179, 1
4908
4909 .hword  0, 2,      7794, 2,   16051, 2,  24800, 2,  34068, 2,  43888, 2 @ octave 6
4910 .hword  54292, 2,  65314, 2,  11456, 3,  23828, 3,  36936, 3,  50823, 3
4911
4912 .hword  0, 4,      15588, 4,  32103, 4,  49600, 4,  2601, 5,   22240, 5 @ octave 7
4913 .hword  43048, 5,  65092, 5,  22912, 6,  47656, 6,  8336, 7,   36110, 7
4914
4915 .hword  0, 8,      31176, 8,  64205, 8,  33663, 9,  5201, 10,  44481, 10 @ octave 8
4916 .hword  20559, 11, 64648, 11, 45823, 12, 29776, 13, 16671, 14, 6684, 15
4917
4918 .hword  0, 16,     62352, 16, 62875, 17, 1790,  19, 10403, 20, 23425, 21 @ octave 9
4919 .hword  41118, 22, 63761, 23, 26111, 25, 59552, 26, 33342, 28, 13368, 30
4920
4921 .align 2
4922 @-------------------------------------------------------------------------------------
4923 mpp_TABLE_FineLinearSlideUpTable:
4924 @-------------------------------------------------------------------------------------
4925
4926 .hword  0,      59,     118,    178,    237    @ 0->4           ADD 1x
4927 .hword  296,    356,    415,    475,    535    @ 5->9
4928 .hword  594,    654,    714,    773,    833    @ 10->14
4929 .hword  893                                    @ 15
4930
4931 .align 2
4932 @-------------------------------------------------------------------------------------
4933 mpp_TABLE_FineLinearSlideDownTable:
4934 @-------------------------------------------------------------------------------------
4935
4936 .hword  65535, 65477, 65418, 65359, 65300, 65241, 65182, 65359 @ 0->7
4937 .hword  65065, 65006, 64947, 64888, 64830, 64772, 64713, 64645 @ 8->15
4938
4939 @-------------------------------------------------------------------------------------
4940 mpp_TABLE_FineSineData:
4941 @-------------------------------------------------------------------------------------
4942
4943 .byte     0,  2,  3,  5,  6,  8,  9, 11, 12, 14, 16, 17, 19, 20, 22, 23
4944 .byte    24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44
4945 .byte    45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59
4946 .byte    59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64
4947 .byte    64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60
4948 .byte    59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46
4949 .byte    45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26
4950 .byte    24, 23, 22, 20, 19, 17, 16, 14, 12, 11,  9,  8,  6,  5,  3,  2
4951 .byte     0, -2, -3, -5, -6, -8, -9,-11,-12,-14,-16,-17,-19,-20,-22,-23
4952 .byte   -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44
4953 .byte   -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59
4954 .byte   -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64
4955 .byte   -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60
4956 .byte   -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46
4957 .byte   -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26
4958 .byte   -24,-23,-22,-20,-19,-17,-16,-14,-12,-11, -9, -8, -6, -5, -3, -2
4959
4960 .end