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.
11 .equiv SLOT_STRUCT_SIZE, 0x30
13 .equiv TL_TAB_LEN, 0x1A00
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) */
25 .equiv ENV_QUIET, (2*13*256/8)/2
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
41 ldr r2, [r5,#0x20] @ eg_pack_ar (1ci)
46 bne 5f @ do smth for tl problem (set on init?)
48 ldrh r0, [r5,#0x1a] @ volume, unsigned (0-1023)
50 add r3, r3, r3, lsl #1
52 and r3, r3, #7 @ shift for eg_inc calculation
55 add r0, r0, r2, asr #5
56 cmp r0, #0 @ if (volume <= MIN_ATT_INDEX)
58 strleb r3, [r5,#0x17] @ state
63 ldr r2, [r5,#0x24] @ eg_pack_d1r (1ci)
68 bne 5f @ do smth for tl problem (set on init?)
70 ldrh r0, [r5,#0x1a] @ volume
72 add r3, r3, r3, lsl #1
74 and r3, r3, #7 @ shift for eg_inc calculation
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 )
81 strgeb r3, [r5,#0x17] @ state
85 ldr r2, [r5,#0x28] @ eg_pack_d2r (1ci)
90 bne 5f @ do smth for tl problem (set on init?)
92 ldrh r0, [r5,#0x1a] @ volume
94 add r3, r3, r3, lsl #1
96 and r3, r3, #7 @ shift for eg_inc calculation
99 add r0, r0, r3, asr #1
101 sub r2, r2, #1 @ r2 = MAX_ATT_INDEX
102 cmp r0, r2 @ if ( volume >= MAX_ATT_INDEX )
107 ldr r2, [r5,#0x2c] @ eg_pack_rr (1ci)
112 bne 5f @ do smth for tl problem (set on init?)
114 ldrh r0, [r5,#0x1a] @ volume
116 add r3, r3, r3, lsl #1
118 and r3, r3, #7 @ shift for eg_inc calculation
121 add r0, r0, r3, asr #1
123 sub r2, r2, #1 @ r2 = MAX_ATT_INDEX
124 cmp r0, r2 @ if ( volume >= MAX_ATT_INDEX )
127 strgeb r3, [r5,#0x17] @ state
130 ldrh r3, [r5,#0x18] @ tl
131 strh r0, [r5,#0x1a] @ volume
135 orr r6, r0, r6, lsl #16
136 .elseif \slot == SLOT2
140 orr r6, r0, r6, lsr #16
141 .elseif \slot == SLOT3
144 orr r7, r0, r7, lsl #16
145 .elseif \slot == SLOT4
149 orr r7, r0, r7, lsr #16
156 @ r12=lfo_ampm[31:16], r1=lfo_cnt_old, r2=lfo_cnt, r3=scratch
158 mov r2, r2, lsr #LFO_SH
159 cmp r2, r1, lsr #LFO_SH
164 bic r12,r12, #0xff000000 @ lfo_ampm &= 0xff
165 orr r12,r12, r3, lsl #1+24
168 cmp r2, r1, lsr #LFO_SH+2
169 bicne r12,r12, #0xff0000
170 orrne r12,r12, r2, lsl #16
176 @ result goes to r1, trashes r2
177 .macro make_eg_out slot
179 tstne r12, #(1<<(\slot+8))
183 .elseif \slot == SLOT2
185 .elseif \slot == SLOT3
188 .elseif \slot == SLOT4
194 addne r1, r1, r12, lsr r2
200 eorne \r, \r, #0xff @ if (sin & 0x100) sin = 0xff - (sin&0xff);
203 orr \r, \r, r1, lsl #8
205 ldrh \r, [r3, \r] @ 2ci if ne
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
220 ldr r0, [lr, #0x38] @ mem (signed)
222 add r0, r2, r0, lsr #1
234 add r0, r0, r2, lsr #16
235 lookup_tl r0 @ r0=output smp
243 ldr r2, [lr, #0x14] @ 1ci
245 add r2, r5, r2, lsr #16
246 lookup_tl r2 @ r2=mem
249 str r2, [lr, #0x38] @ mem
261 ldr r0, [lr, #0x38] @ mem (signed)
263 add r0, r2, r0, lsr #1
274 add r0, r0, r2, lsr #16
275 lookup_tl r0 @ r0=output smp
283 ldr r2, [lr, #0x14] @ 1ci
285 lookup_tl r2 @ r2=mem
288 add r2, r2, r10, asr #16
301 ldr r0, [lr, #0x38] @ mem (signed)
303 add r0, r2, r0, lsr #1
307 add r0, r0, r10, asr #16
316 add r0, r0, r2, lsr #16
317 lookup_tl r0 @ r0=output smp
326 mov r2, r2, lsr #16 @ 1ci
327 lookup_tl r2 @ r2=mem
330 str r2, [lr, #0x38] @ mem
339 ldr r2, [lr, #0x38] @ mem (for future)
342 ldr r0, [lr, #0x18] @ 1ci
356 add r0, r0, r2, lsr #16
357 lookup_tl r0 @ r0=output smp
367 add r2, r5, r2, lsr #16
368 lookup_tl r2 @ r2=mem
371 str r2, [lr, #0x38] @ mem
383 mov r0, r0, lsr #16 @ 1ci
394 add r0, r0, r2, lsr #16
395 lookup_tl r0 @ r0=output smp
404 add r2, r5, r2, lsr #16
406 add r0, r0, r2 @ add to smp
420 ldr r0, [lr, #0x38] @ mem (signed)
422 add r0, r2, r0, lsr #1
423 lookup_tl r0 @ r0=output smp
432 add r2, r5, r2, lsr #16
434 add r0, r0, r2 @ add to smp
442 add r2, r5, r2, lsr #16
444 add r0, r0, r2 @ add to smp
448 str r1, [lr, #0x38] @ mem
460 mov r0, r0, lsr #16 @ 1ci
461 lookup_tl r0 @ r0=output smp
469 mov r2, r2, lsr #16 @ 1ci
471 add r0, r0, r2 @ add to smp
479 add r2, r5, r2, lsr #16
481 add r0, r0, r2 @ add to smp
495 mov r0, r0, lsr #16 @ 1ci
496 lookup_tl r0 @ r0=output smp
499 add r0, r0, r10, asr #16
506 mov r2, r2, lsr #16 @ 1ci
508 add r0, r0, r2 @ add to smp
515 mov r2, r2, lsr #16 @ 1ci
517 add r0, r0, r2 @ add to smp
527 movcs r10, r10, lsl #16 @ ct->op1_out <<= 16; // op1_out0 = op1_out1; op1_out1 = 0;
529 ands r2, r12, #0xf000
531 movne r2, r2, lsr #12
532 addne r0, r10, r10, lsl #16
533 movne r0, r0, asr #16
538 add r0, r0, r2, lsr #16
540 mov r10,r10,lsl #16 @ ct->op1_out <<= 16;
542 orr r10,r10, r0, lsr #16
549 .global update_eg_phase @ FM_SLOT *SLOT, UINT32 eg_cnt
554 ldrh r3, [r5,#0x18] @ tl
555 ldrh r6, [r5,#0x1a] @ volume
557 update_eg_phase_slot SLOT1
564 .global advance_lfo @ int lfo_ampm, UINT32 lfo_cnt_old, UINT32 lfo_cnt
574 .global upd_algo0 @ chan_rend_context *c
576 stmfd sp!, {r4-r10,lr}
587 ldmfd sp!, {r4-r10,pc}
591 .global upd_algo1 @ chan_rend_context *c
593 stmfd sp!, {r4-r10,lr}
604 ldmfd sp!, {r4-r10,pc}
608 .global upd_algo2 @ chan_rend_context *c
610 stmfd sp!, {r4-r10,lr}
621 ldmfd sp!, {r4-r10,pc}
625 .global upd_algo3 @ chan_rend_context *c
627 stmfd sp!, {r4-r10,lr}
638 ldmfd sp!, {r4-r10,pc}
642 .global upd_algo4 @ chan_rend_context *c
644 stmfd sp!, {r4-r10,lr}
655 ldmfd sp!, {r4-r10,pc}
659 .global upd_algo5 @ chan_rend_context *c
661 stmfd sp!, {r4-r10,lr}
672 ldmfd sp!, {r4-r10,pc}
676 .global upd_algo6 @ chan_rend_context *c
678 stmfd sp!, {r4-r10,lr}
689 ldmfd sp!, {r4-r10,pc}
693 .global upd_algo7 @ chan_rend_context *c
695 stmfd sp!, {r4-r10,lr}
706 ldmfd sp!, {r4-r10,pc}
710 .global upd_slot1 @ chan_rend_context *c
712 stmfd sp!, {r4-r10,lr}
724 ldmfd sp!, {r4-r10,pc}
729 @ lr=context, r12=pack (stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16])
730 @ r0-r2=scratch, r3=sin_tab/scratch, r4=(length<<8)|unused[4],was_update,algo[3], r5=tl_tab/slot,
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
735 stmfd sp!, {r4-r11,lr}
737 mov r4, r2, lsl #8 @ no more 24 bits here
742 orr r4, r4, r0 @ (length<<8)|algo
744 ldmia r0, {r8,r9} @ eg_timer, eg_timer_add
745 ldr r10, [lr, #0x54] @ op1_out
746 ldmia lr, {r6,r7} @ load volumes
756 @ r12=lfo_ampm[31:16], r1=lfo_cnt_old, r2=lfo_cnt
765 cmp r8, #EG_TIMER_OVERFLOW
768 ldmia r0, {r1,r5} @ eg_cnt, CH
770 sub r8, r8, #EG_TIMER_OVERFLOW
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
782 cmp r8, #EG_TIMER_OVERFLOW
783 subcs r5, r5, #SLOT_STRUCT_SIZE*3
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
805 ldr pc, [pc, r0, lsl #2]
861 orr r4, r4, #8 @ have_output
880 add r11,r11, r1, lsl #2
912 str r8, [lr, #0x44] @ eg_timer
913 str r12, [lr, #0x4c] @ pack (for lfo_ampm)
914 str r4, [lr, #0x50] @ was_update
915 str r10, [lr, #0x54] @ op1_out
916 ldmfd sp!, {r4-r11,pc}