full ym2612 save/load for 940
[picodrive.git] / Pico / sound / ym2612.s
CommitLineData
cc68a136 1@ this is a rewrite of MAME's ym2612 code, in particular this is only the main sample-generatin loop.
2@ it does not seem to give much performance increase (if any at all), so don't use it if it causes trouble.
3@ - notaz, 2006
4
85f8e929 5@ vim:filetype=armasm
6
cc68a136 7.equiv SLOT1, 0
8.equiv SLOT2, 2
9.equiv SLOT3, 1
10.equiv SLOT4, 3
11.equiv SLOT_STRUCT_SIZE, 0x30
12
13.equiv TL_TAB_LEN, 0x1A00
14
15.equiv EG_ATT, 4
16.equiv EG_DEC, 3
17.equiv EG_SUS, 2
18.equiv EG_REL, 1
19.equiv EG_OFF, 0
20
21.equiv EG_SH, 16 @ 16.16 fixed point (envelope generator timing)
22.equiv EG_TIMER_OVERFLOW, (3*(1<<EG_SH)) @ envelope generator timer overflows every 3 samples (on real chip)
23.equiv LFO_SH, 25 /* 7.25 fixed point (LFO calculations) */
24
25.equiv ENV_QUIET, (2*13*256/8)/2
26
27
28@ r5=slot, r1=eg_cnt, trashes: r0,r2,r3
29@ writes output to routp, but only if vol_out changes
30.macro update_eg_phase_slot slot
31 ldrb r2, [r5,#0x17] @ state
32 mov r3, #1 @ 1ci
33 cmp r2, #1
34 blt 5f @ EG_OFF
35 beq 3f @ EG_REL
36 cmp r2, #3
37 blt 2f @ EG_SUS
38 beq 1f @ EG_DEC
39
400: @ EG_ATT
41 ldr r2, [r5,#0x20] @ eg_pack_ar (1ci)
42 mov r0, r2, lsr #24
43 mov r3, r3, lsl r0
44 sub r3, r3, #1
45 tst r1, r3
46 bne 5f @ do smth for tl problem (set on init?)
47 mov r3, r1, lsr r0
48 ldrh r0, [r5,#0x1a] @ volume, unsigned (0-1023)
49 and r3, r3, #7
50 add r3, r3, r3, lsl #1
51 mov r3, r2, lsr r3
52 and r3, r3, #7 @ shift for eg_inc calculation
53 mvn r2, r0
54 mov r2, r2, lsl r3
55 add r0, r0, r2, asr #5
56 cmp r0, #0 @ if (volume <= MIN_ATT_INDEX)
57 movle r3, #EG_DEC
58 strleb r3, [r5,#0x17] @ state
59 movle r0, #0
60 b 4f
61
621: @ EG_DEC
63 ldr r2, [r5,#0x24] @ eg_pack_d1r (1ci)
64 mov r0, r2, lsr #24
65 mov r3, r3, lsl r0
66 sub r3, r3, #1
67 tst r1, r3
68 bne 5f @ do smth for tl problem (set on init?)
69 mov r3, r1, lsr r0
70 ldrh r0, [r5,#0x1a] @ volume
71 and r3, r3, #7
72 add r3, r3, r3, lsl #1
73 mov r3, r2, lsr r3
74 and r3, r3, #7 @ shift for eg_inc calculation
75 mov r2, #1
76 mov r3, r2, lsl r3
77 ldr r2, [r5,#0x1c] @ sl (can be 16bit?)
78 add r0, r0, r3, asr #1
79 cmp r0, r2 @ if ( volume >= (INT32) SLOT->sl )
80 movge r3, #EG_SUS
81 strgeb r3, [r5,#0x17] @ state
82 b 4f
83
842: @ EG_SUS
85 ldr r2, [r5,#0x28] @ eg_pack_d2r (1ci)
86 mov r0, r2, lsr #24
87 mov r3, r3, lsl r0
88 sub r3, r3, #1
89 tst r1, r3
90 bne 5f @ do smth for tl problem (set on init?)
91 mov r3, r1, lsr r0
92 ldrh r0, [r5,#0x1a] @ volume
93 and r3, r3, #7
94 add r3, r3, r3, lsl #1
95 mov r3, r2, lsr r3
96 and r3, r3, #7 @ shift for eg_inc calculation
97 mov r2, #1
98 mov r3, r2, lsl r3
99 add r0, r0, r3, asr #1
100 mov r2, #1024
101 sub r2, r2, #1 @ r2 = MAX_ATT_INDEX
102 cmp r0, r2 @ if ( volume >= MAX_ATT_INDEX )
103 movge r0, r2
104 b 4f
105
1063: @ EG_REL
107 ldr r2, [r5,#0x2c] @ eg_pack_rr (1ci)
108 mov r0, r2, lsr #24
109 mov r3, r3, lsl r0
110 sub r3, r3, #1
111 tst r1, r3
112 bne 5f @ do smth for tl problem (set on init?)
113 mov r3, r1, lsr r0
114 ldrh r0, [r5,#0x1a] @ volume
115 and r3, r3, #7
116 add r3, r3, r3, lsl #1
117 mov r3, r2, lsr r3
118 and r3, r3, #7 @ shift for eg_inc calculation
119 mov r2, #1
120 mov r3, r2, lsl r3
121 add r0, r0, r3, asr #1
122 mov r2, #1024
123 sub r2, r2, #1 @ r2 = MAX_ATT_INDEX
124 cmp r0, r2 @ if ( volume >= MAX_ATT_INDEX )
125 movge r0, r2
126 movge r3, #EG_OFF
127 strgeb r3, [r5,#0x17] @ state
128
1294:
130 ldrh r3, [r5,#0x18] @ tl
131 strh r0, [r5,#0x1a] @ volume
132.if \slot == SLOT1
133 mov r6, r6, lsr #16
134 add r0, r0, r3
135 orr r6, r0, r6, lsl #16
136.elseif \slot == SLOT2
137 mov r6, r6, lsl #16
138 add r0, r0, r3
139 mov r0, r0, lsl #16
140 orr r6, r0, r6, lsr #16
141.elseif \slot == SLOT3
142 mov r7, r7, lsr #16
143 add r0, r0, r3
144 orr r7, r0, r7, lsl #16
145.elseif \slot == SLOT4
146 mov r7, r7, lsl #16
147 add r0, r0, r3
148 mov r0, r0, lsl #16
149 orr r7, r0, r7, lsr #16
150.endif
151
1525:
153.endm
154
155
156@ r12=lfo_ampm[31:16], r1=lfo_cnt_old, r2=lfo_cnt, r3=scratch
157.macro advance_lfo_m
158 mov r2, r2, lsr #LFO_SH
159 cmp r2, r1, lsr #LFO_SH
160 beq 0f
161 and r3, r2, #0x3f
162 cmp r2, #0x40
163 rsbge r3, r3, #0x3f
164 bic r12,r12, #0xff000000 @ lfo_ampm &= 0xff
165 orr r12,r12, r3, lsl #1+24
166
167 mov r2, r2, lsr #2
168 cmp r2, r1, lsr #LFO_SH+2
169 bicne r12,r12, #0xff0000
170 orrne r12,r12, r2, lsl #16
171
1720:
173.endm
174
175
176@ result goes to r1, trashes r2
177.macro make_eg_out slot
178 tst r12, #8
179 tstne r12, #(1<<(\slot+8))
180.if \slot == SLOT1
181 mov r1, r6, lsl #16
182 mov r1, r1, lsr #17
183.elseif \slot == SLOT2
184 mov r1, r6, lsr #17
185.elseif \slot == SLOT3
186 mov r1, r7, lsl #16
187 mov r1, r1, lsr #17
188.elseif \slot == SLOT4
189 mov r1, r7, lsr #17
190.endif
191 andne r2, r12, #0xc0
192 movne r2, r2, lsr #6
193 addne r2, r2, #24
194 addne r1, r1, r12, lsr r2
195.endm
196
197
198.macro lookup_tl r
199 tst \r, #0x100
200 eorne \r, \r, #0xff @ if (sin & 0x100) sin = 0xff - (sin&0xff);
201 tst \r, #0x200
202 and \r, \r, #0xff
203 orr \r, \r, r1, lsl #8
204 mov \r, \r, lsl #1
205 ldrh \r, [r3, \r] @ 2ci if ne
206 rsbne \r, \r, #0
207.endm
208
209
210@ lr=context, r12=pack (stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16])
211@ r0-r2=scratch, r3=sin_tab, r5=scratch, r6-r7=vol_out[4], r10=op1_out
212.macro upd_algo0_m
213
214 @ SLOT3
215 make_eg_out SLOT3
216 cmp r1, #ENV_QUIET
217 movcs r0, #0
218 bcs 0f
219 ldr r2, [lr, #0x18]
220 ldr r0, [lr, #0x38] @ mem (signed)
221 mov r2, r2, lsr #16
222 add r0, r2, r0, lsr #1
223 lookup_tl r0 @ r0=c2
224
2250:
226
227 @ SLOT4
228 make_eg_out SLOT4
229 cmp r1, #ENV_QUIET
230 movcs r0, #0
231 bcs 1f
232 ldr r2, [lr, #0x1c]
233 mov r0, r0, lsr #1
234 add r0, r0, r2, lsr #16
235 lookup_tl r0 @ r0=output smp
236
2371:
238 @ SLOT2
239 make_eg_out SLOT2
240 cmp r1, #ENV_QUIET
241 movcs r2, #0
242 bcs 2f
243 ldr r2, [lr, #0x14] @ 1ci
244 mov r5, r10, lsr #17
245 add r2, r5, r2, lsr #16
246 lookup_tl r2 @ r2=mem
247
2482:
249 str r2, [lr, #0x38] @ mem
250.endm
251
252
253.macro upd_algo1_m
254
255 @ SLOT3
256 make_eg_out SLOT3
257 cmp r1, #ENV_QUIET
258 movcs r0, #0
259 bcs 0f
260 ldr r2, [lr, #0x18]
261 ldr r0, [lr, #0x38] @ mem (signed)
262 mov r2, r2, lsr #16
263 add r0, r2, r0, lsr #1
264 lookup_tl r0 @ r0=c2
265
2660:
267 @ SLOT4
268 make_eg_out SLOT4
269 cmp r1, #ENV_QUIET
270 movcs r0, #0
271 bcs 1f
272 ldr r2, [lr, #0x1c]
273 mov r0, r0, lsr #1
274 add r0, r0, r2, lsr #16
275 lookup_tl r0 @ r0=output smp
276
2771:
278 @ SLOT2
279 make_eg_out SLOT2
280 cmp r1, #ENV_QUIET
281 movcs r2, #0
282 bcs 2f
283 ldr r2, [lr, #0x14] @ 1ci
284 mov r2, r2, lsr #16
285 lookup_tl r2 @ r2=mem
286
2872:
288 add r2, r2, r10, asr #16
289 str r2, [lr, #0x38]
290.endm
291
292
293.macro upd_algo2_m
294
295 @ SLOT3
296 make_eg_out SLOT3
297 cmp r1, #ENV_QUIET
298 movcs r0, #0
299 bcs 0f
300 ldr r2, [lr, #0x18]
301 ldr r0, [lr, #0x38] @ mem (signed)
302 mov r2, r2, lsr #16
303 add r0, r2, r0, lsr #1
304 lookup_tl r0 @ r0=c2
305
3060:
307 add r0, r0, r10, asr #16
308
309 @ SLOT4
310 make_eg_out SLOT4
311 cmp r1, #ENV_QUIET
312 movcs r0, #0
313 bcs 1f
314 ldr r2, [lr, #0x1c]
315 mov r0, r0, lsr #1
316 add r0, r0, r2, lsr #16
317 lookup_tl r0 @ r0=output smp
318
3191:
320 @ SLOT2
321 make_eg_out SLOT2
322 cmp r1, #ENV_QUIET
323 movcs r2, #0
324 bcs 2f
325 ldr r2, [lr, #0x14]
326 mov r2, r2, lsr #16 @ 1ci
327 lookup_tl r2 @ r2=mem
328
3292:
330 str r2, [lr, #0x38] @ mem
331.endm
332
333
334.macro upd_algo3_m
335
336 @ SLOT3
337 make_eg_out SLOT3
338 cmp r1, #ENV_QUIET
339 ldr r2, [lr, #0x38] @ mem (for future)
340 movcs r0, r2
341 bcs 0f
342 ldr r0, [lr, #0x18] @ 1ci
343 mov r0, r0, lsr #16
344 lookup_tl r0 @ r0=c2
345
3460:
347 add r0, r0, r2
348
349 @ SLOT4
350 make_eg_out SLOT4
351 cmp r1, #ENV_QUIET
352 movcs r0, #0
353 bcs 1f
354 ldr r2, [lr, #0x1c]
355 mov r0, r0, lsr #1
356 add r0, r0, r2, lsr #16
357 lookup_tl r0 @ r0=output smp
358
3591:
360 @ SLOT2
361 make_eg_out SLOT2
362 cmp r1, #ENV_QUIET
363 movcs r2, #0
364 bcs 2f
365 ldr r2, [lr, #0x14]
366 mov r5, r10, lsr #17
367 add r2, r5, r2, lsr #16
368 lookup_tl r2 @ r2=mem
369
3702:
371 str r2, [lr, #0x38] @ mem
372.endm
373
374
375.macro upd_algo4_m
376
377 @ SLOT3
378 make_eg_out SLOT3
379 cmp r1, #ENV_QUIET
380 movcs r0, #0
381 bcs 0f
382 ldr r0, [lr, #0x18]
383 mov r0, r0, lsr #16 @ 1ci
384 lookup_tl r0 @ r0=c2
385
3860:
387 @ SLOT4
388 make_eg_out SLOT4
389 cmp r1, #ENV_QUIET
390 movcs r0, #0
391 bcs 1f
392 ldr r2, [lr, #0x1c]
393 mov r0, r0, lsr #1
394 add r0, r0, r2, lsr #16
395 lookup_tl r0 @ r0=output smp
396
3971:
398 @ SLOT2
399 make_eg_out SLOT2
400 cmp r1, #ENV_QUIET
401 bcs 2f
402 ldr r2, [lr, #0x14]
403 mov r5, r10, lsr #17
404 add r2, r5, r2, lsr #16
405 lookup_tl r2
406 add r0, r0, r2 @ add to smp
407
4082:
409.endm
410
411
412.macro upd_algo5_m
413
414 @ SLOT3
415 make_eg_out SLOT3
416 cmp r1, #ENV_QUIET
417 movcs r0, #0
418 bcs 0f
419 ldr r2, [lr, #0x18]
420 ldr r0, [lr, #0x38] @ mem (signed)
421 mov r2, r2, lsr #16
422 add r0, r2, r0, lsr #1
423 lookup_tl r0 @ r0=output smp
424
4250:
426 @ SLOT4
427 make_eg_out SLOT4
428 cmp r1, #ENV_QUIET
429 bcs 1f
430 ldr r2, [lr, #0x1c]
431 mov r5, r10, lsr #17
432 add r2, r5, r2, lsr #16
433 lookup_tl r2
434 add r0, r0, r2 @ add to smp
435
4361: @ SLOT2
437 make_eg_out SLOT2
438 cmp r1, #ENV_QUIET
439 bcs 2f
440 ldr r2, [lr, #0x14]
441 mov r5, r10, lsr #17
442 add r2, r5, r2, lsr #16
443 lookup_tl r2
444 add r0, r0, r2 @ add to smp
445
4462:
447 mov r1, r10, asr #16
448 str r1, [lr, #0x38] @ mem
449.endm
450
451
452.macro upd_algo6_m
453
454 @ SLOT3
455 make_eg_out SLOT3
456 cmp r1, #ENV_QUIET
457 movcs r0, #0
458 bcs 0f
459 ldr r0, [lr, #0x18]
460 mov r0, r0, lsr #16 @ 1ci
461 lookup_tl r0 @ r0=output smp
462
4630:
464 @ SLOT4
465 make_eg_out SLOT4
466 cmp r1, #ENV_QUIET
467 bcs 1f
468 ldr r2, [lr, #0x1c]
469 mov r2, r2, lsr #16 @ 1ci
470 lookup_tl r2
471 add r0, r0, r2 @ add to smp
472
4731: @ SLOT2
474 make_eg_out SLOT2
475 cmp r1, #ENV_QUIET
476 bcs 2f
477 ldr r2, [lr, #0x14]
478 mov r5, r10, lsr #17
479 add r2, r5, r2, lsr #16
480 lookup_tl r2
481 add r0, r0, r2 @ add to smp
482
4832:
484.endm
485
486
487.macro upd_algo7_m
488
489 @ SLOT3
490 make_eg_out SLOT3
491 cmp r1, #ENV_QUIET
492 movcs r0, #0
493 bcs 0f
494 ldr r0, [lr, #0x18]
495 mov r0, r0, lsr #16 @ 1ci
496 lookup_tl r0 @ r0=output smp
497
4980:
499 add r0, r0, r10, asr #16
500
501 @ SLOT4
502 make_eg_out SLOT4
503 cmp r1, #ENV_QUIET
504 bcs 1f
505 ldr r2, [lr, #0x1c]
506 mov r2, r2, lsr #16 @ 1ci
507 lookup_tl r2
508 add r0, r0, r2 @ add to smp
509
5101: @ SLOT2
511 make_eg_out SLOT2
512 cmp r1, #ENV_QUIET
513 bcs 2f
514 ldr r2, [lr, #0x14]
515 mov r2, r2, lsr #16 @ 1ci
516 lookup_tl r2
517 add r0, r0, r2 @ add to smp
518
5192:
520.endm
521
522
523.macro upd_slot1_m
524
525 make_eg_out SLOT1
526 cmp r1, #ENV_QUIET
527 movcs r10, r10, lsl #16 @ ct->op1_out <<= 16; // op1_out0 = op1_out1; op1_out1 = 0;
528 bcs 0f
529 ands r2, r12, #0xf000
530 moveq r0, #0
531 movne r2, r2, lsr #12
532 addne r0, r10, r10, lsl #16
533 movne r0, r0, asr #16
534 movne r0, r0, lsl r2
535
536 ldr r2, [lr, #0x10]
537 mov r0, r0, lsr #16
538 add r0, r0, r2, lsr #16
539 lookup_tl r0
540 mov r10,r10,lsl #16 @ ct->op1_out <<= 16;
541 mov r0, r0, lsl #16
542 orr r10,r10, r0, lsr #16
543
5440:
545.endm
546
547
548/*
549.global update_eg_phase @ FM_SLOT *SLOT, UINT32 eg_cnt
550
551update_eg_phase:
552 stmfd sp!, {r5,r6}
553 mov r5, r0 @ slot
554 ldrh r3, [r5,#0x18] @ tl
555 ldrh r6, [r5,#0x1a] @ volume
556 add r6, r6, r3
557 update_eg_phase_slot SLOT1
558 mov r0, r6
559 ldmfd sp!, {r5,r6}
560 bx lr
561.pool
562
563
564.global advance_lfo @ int lfo_ampm, UINT32 lfo_cnt_old, UINT32 lfo_cnt
565
566advance_lfo:
567 mov r12, r0, lsl #16
568 advance_lfo_m
569 mov r0, r12, lsr #16
570 bx lr
571.pool
572
573
574.global upd_algo0 @ chan_rend_context *c
575upd_algo0:
576 stmfd sp!, {r4-r10,lr}
577 mov lr, r0
578
579 ldr r3, =ym_sin_tab
580 ldr r5, =ym_tl_tab
581 ldmia lr, {r6-r7}
582 ldr r10, [lr, #0x54]
583 ldr r12, [lr, #0x4c]
584
585 upd_algo0_m
586
587 ldmfd sp!, {r4-r10,pc}
588.pool
589
590
591.global upd_algo1 @ chan_rend_context *c
592upd_algo1:
593 stmfd sp!, {r4-r10,lr}
594 mov lr, r0
595
596 ldr r3, =ym_sin_tab
597 ldr r5, =ym_tl_tab
598 ldmia lr, {r6-r7}
599 ldr r10, [lr, #0x54]
600 ldr r12, [lr, #0x4c]
601
602 upd_algo1_m
603
604 ldmfd sp!, {r4-r10,pc}
605.pool
606
607
608.global upd_algo2 @ chan_rend_context *c
609upd_algo2:
610 stmfd sp!, {r4-r10,lr}
611 mov lr, r0
612
613 ldr r3, =ym_sin_tab
614 ldr r5, =ym_tl_tab
615 ldmia lr, {r6-r7}
616 ldr r10, [lr, #0x54]
617 ldr r12, [lr, #0x4c]
618
619 upd_algo2_m
620
621 ldmfd sp!, {r4-r10,pc}
622.pool
623
624
625.global upd_algo3 @ chan_rend_context *c
626upd_algo3:
627 stmfd sp!, {r4-r10,lr}
628 mov lr, r0
629
630 ldr r3, =ym_sin_tab
631 ldr r5, =ym_tl_tab
632 ldmia lr, {r6-r7}
633 ldr r10, [lr, #0x54]
634 ldr r12, [lr, #0x4c]
635
636 upd_algo3_m
637
638 ldmfd sp!, {r4-r10,pc}
639.pool
640
641
642.global upd_algo4 @ chan_rend_context *c
643upd_algo4:
644 stmfd sp!, {r4-r10,lr}
645 mov lr, r0
646
647 ldr r3, =ym_sin_tab
648 ldr r5, =ym_tl_tab
649 ldmia lr, {r6-r7}
650 ldr r10, [lr, #0x54]
651 ldr r12, [lr, #0x4c]
652
653 upd_algo4_m
654
655 ldmfd sp!, {r4-r10,pc}
656.pool
657
658
659.global upd_algo5 @ chan_rend_context *c
660upd_algo5:
661 stmfd sp!, {r4-r10,lr}
662 mov lr, r0
663
664 ldr r3, =ym_sin_tab
665 ldr r5, =ym_tl_tab
666 ldmia lr, {r6-r7}
667 ldr r10, [lr, #0x54]
668 ldr r12, [lr, #0x4c]
669
670 upd_algo5_m
671
672 ldmfd sp!, {r4-r10,pc}
673.pool
674
675
676.global upd_algo6 @ chan_rend_context *c
677upd_algo6:
678 stmfd sp!, {r4-r10,lr}
679 mov lr, r0
680
681 ldr r3, =ym_sin_tab
682 ldr r5, =ym_tl_tab
683 ldmia lr, {r6-r7}
684 ldr r10, [lr, #0x54]
685 ldr r12, [lr, #0x4c]
686
687 upd_algo6_m
688
689 ldmfd sp!, {r4-r10,pc}
690.pool
691
692
693.global upd_algo7 @ chan_rend_context *c
694upd_algo7:
695 stmfd sp!, {r4-r10,lr}
696 mov lr, r0
697
698 ldr r3, =ym_sin_tab
699 ldr r5, =ym_tl_tab
700 ldmia lr, {r6-r7}
701 ldr r10, [lr, #0x54]
702 ldr r12, [lr, #0x4c]
703
704 upd_algo7_m
705
706 ldmfd sp!, {r4-r10,pc}
707.pool
708
709
710.global upd_slot1 @ chan_rend_context *c
711upd_slot1:
712 stmfd sp!, {r4-r10,lr}
713 mov lr, r0
714
715 ldr r3, =ym_sin_tab
716 ldr r5, =ym_tl_tab
717 ldmia lr, {r6-r7}
718 ldr r10, [lr, #0x54]
719 ldr r12, [lr, #0x4c]
720
721 upd_slot1_m
722 str r10, [lr, #0x38]
723
724 ldmfd sp!, {r4-r10,pc}
725.pool
726*/
727
728
729@ lr=context, r12=pack (stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16])
85f8e929 730@ r0-r2=scratch, r3=sin_tab/scratch, r4=(length<<8)|unused[4],was_update,algo[3], r5=tl_tab/slot,
cc68a136 731@ r6-r7=vol_out[4], r8=eg_timer, r9=eg_timer_add[31:16], r10=op1_out, r11=buffer
732.global chan_render_loop @ chan_rend_context *ct, int *buffer, int length
733
734chan_render_loop:
735 stmfd sp!, {r4-r11,lr}
736 mov lr, r0
737 mov r4, r2, lsl #8 @ no more 24 bits here
738 ldr r12, [lr, #0x4c]
739 ldr r0, [lr, #0x50]
740 mov r11, r1
741 and r0, r0, #7
742 orr r4, r4, r0 @ (length<<8)|algo
743 add r0, lr, #0x44
744 ldmia r0, {r8,r9} @ eg_timer, eg_timer_add
745 ldr r10, [lr, #0x54] @ op1_out
746 ldmia lr, {r6,r7} @ load volumes
747
748 tst r12, #8 @ lfo?
749 beq crl_loop
750
751crl_loop_lfo:
752 add r0, lr, #0x30
753 ldmia r0, {r1,r2}
754 add r2, r2, r1
755 str r2, [lr, #0x30]
756 @ r12=lfo_ampm[31:16], r1=lfo_cnt_old, r2=lfo_cnt
757 advance_lfo_m
758
759crl_loop:
760 subs r4, r4, #0x100
761 bmi crl_loop_end
762
763 @ -- EG --
764 add r8, r8, r9
765 cmp r8, #EG_TIMER_OVERFLOW
766 bcc eg_done
767 add r0, lr, #0x3c
768 ldmia r0, {r1,r5} @ eg_cnt, CH
769eg_loop:
770 sub r8, r8, #EG_TIMER_OVERFLOW
771 add r1, r1, #1
772 @ SLOT1 (0)
773 @ r5=slot, r1=eg_cnt, trashes: r0,r2,r3
774 update_eg_phase_slot SLOT1
775 add r5, r5, #SLOT_STRUCT_SIZE*2 @ SLOT2 (2)
776 update_eg_phase_slot SLOT2
777 sub r5, r5, #SLOT_STRUCT_SIZE @ SLOT3 (1)
778 update_eg_phase_slot SLOT3
779 add r5, r5, #SLOT_STRUCT_SIZE*2 @ SLOT4 (3)
780 update_eg_phase_slot SLOT4
781
782 cmp r8, #EG_TIMER_OVERFLOW
783 subcs r5, r5, #SLOT_STRUCT_SIZE*3
784 bcs eg_loop
785 str r1, [lr, #0x3c]
786
787eg_done:
788
789 @ -- disabled? --
790 and r0, r12, #0xC
791 cmp r0, #0xC
792 beq crl_loop_lfo
793 cmp r0, #0x4
794 beq crl_loop
795
796 @ -- SLOT1 --
797 ldr r3, =ym_tl_tab
798
799 @ lr=context, r12=pack (stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16])
800 @ r0-r2=scratch, r3=tl_tab, r5=scratch, r6-r7=vol_out[4], r10=op1_out
801 upd_slot1_m
802
803 @ -- SLOT2+ --
804 and r0, r4, #7
805 ldr pc, [pc, r0, lsl #2]
806 nop
807 .word crl_algo0
808 .word crl_algo1
809 .word crl_algo2
810 .word crl_algo3
811 .word crl_algo4
812 .word crl_algo5
813 .word crl_algo6
814 .word crl_algo7
815 .pool
816
817crl_algo0:
818 upd_algo0_m
819 b crl_algo_done
820 .pool
821
822crl_algo1:
823 upd_algo1_m
824 b crl_algo_done
825 .pool
826
827crl_algo2:
828 upd_algo2_m
829 b crl_algo_done
830 .pool
831
832crl_algo3:
833 upd_algo3_m
834 b crl_algo_done
835 .pool
836
837crl_algo4:
838 upd_algo4_m
839 b crl_algo_done
840 .pool
841
842crl_algo5:
843 upd_algo5_m
844 b crl_algo_done
845 .pool
846
847crl_algo6:
848 upd_algo6_m
849 b crl_algo_done
850 .pool
851
852crl_algo7:
853 upd_algo7_m
854 .pool
855
856
857crl_algo_done:
858 @ -- WRITE SAMPLE --
859 tst r0, r0
860 beq ctl_sample_skip
85f8e929 861 orr r4, r4, #8 @ have_output
cc68a136 862 tst r12, #1
863 beq ctl_sample_mono
864
865 tst r12, #0x20 @ L
866 ldrne r1, [r11]
867 addeq r11, r11, #4
868 addne r1, r0, r1
869 strne r1, [r11], #4
870 tst r12, #0x10 @ R
871 ldrne r1, [r11]
872 addeq r11, r11, #4
873 addne r1, r0, r1
874 strne r1, [r11], #4
875 b crl_do_phase
876
877ctl_sample_skip:
878 and r1, r12, #1
879 add r1, r1, #1
880 add r11,r11, r1, lsl #2
881 b crl_do_phase
882
883ctl_sample_mono:
884 ldr r1, [r11]
885 add r1, r0, r1
886 str r1, [r11], #4
887
888crl_do_phase:
889 @ -- PHASE UPDATE --
890 add r5, lr, #0x10
891 ldmia r5, {r0-r1}
892 add r5, lr, #0x20
893 ldmia r5, {r2-r3}
894 add r5, lr, #0x10
895 add r0, r0, r2
896 add r1, r1, r3
897 stmia r5!,{r0-r1}
898 ldmia r5, {r0-r1}
899 add r5, lr, #0x28
900 ldmia r5, {r2-r3}
901 add r5, lr, #0x18
902 add r0, r0, r2
903 add r1, r1, r3
904 stmia r5, {r0-r1}
905
906 tst r12, #8
907 bne crl_loop_lfo
908 b crl_loop
909
910
911crl_loop_end:
912 str r8, [lr, #0x44] @ eg_timer
913 str r12, [lr, #0x4c] @ pack (for lfo_ampm)
85f8e929 914 str r4, [lr, #0x50] @ was_update
cc68a136 915 str r10, [lr, #0x54] @ op1_out
916 ldmfd sp!, {r4-r11,pc}
917
918.pool
919