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