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 | |
73 | 3: @ 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 | |
80 | 4: @ 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 | |
92 | 2: @ 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 |
99 | 1: @ 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 |
107 | 10: @ 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 |
130 | 0: @ 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 | |
150 | 0: |
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 | |
205 | 0: |
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 | |
217 | 1: |
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 | |
228 | 2: |
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 | |
246 | 0: |
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 | |
257 | 1: |
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 | |
267 | 2: |
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 | |
286 | 0: |
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 | |
299 | 1: |
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 | |
309 | 2: |
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 | |
326 | 0: |
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 | |
339 | 1: |
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 | |
350 | 2: |
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 | |
366 | 0: |
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 | |
377 | 1: |
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 | |
388 | 2: |
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 | |
405 | 0: |
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 | |
416 | 1: @ 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 | |
426 | 2: |
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 | |
443 | 0: |
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 | |
453 | 1: @ 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 | |
463 | 2: |
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 | |
478 | 0: |
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 | |
490 | 1: @ 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 | |
499 | 2: |
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 | |
524 | 0: |
525 | .endm |
526 | |
527 | |
528 | /* |
529 | .global update_eg_phase @ FM_SLOT *SLOT, UINT32 eg_cnt |
530 | |
531 | update_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 | |
546 | advance_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 |
555 | upd_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 |
572 | upd_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 |
589 | upd_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 |
606 | upd_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 |
623 | upd_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 |
640 | upd_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 |
657 | upd_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 |
674 | upd_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 |
691 | upd_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 | |
714 | chan_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 | |
731 | crl_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 |
746 | crl_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 |
756 | eg_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 | |
774 | eg_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 | |
804 | crl_algo0: |
805 | upd_algo0_m |
806 | b crl_algo_done |
807 | .pool |
808 | |
809 | crl_algo1: |
810 | upd_algo1_m |
811 | b crl_algo_done |
812 | .pool |
813 | |
814 | crl_algo2: |
815 | upd_algo2_m |
816 | b crl_algo_done |
817 | .pool |
818 | |
819 | crl_algo3: |
820 | upd_algo3_m |
821 | b crl_algo_done |
822 | .pool |
823 | |
824 | crl_algo4: |
825 | upd_algo4_m |
826 | b crl_algo_done |
827 | .pool |
828 | |
829 | crl_algo5: |
830 | upd_algo5_m |
831 | b crl_algo_done |
832 | .pool |
833 | |
834 | crl_algo6: |
835 | upd_algo6_m |
836 | b crl_algo_done |
837 | .pool |
838 | |
839 | crl_algo7: |
840 | upd_algo7_m |
cc68a136 |
841 | |
842 | |
843 | crl_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 | |
863 | ctl_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 | |
869 | ctl_sample_mono: |
870 | ldr r1, [r11] |
871 | add r1, r0, r1 |
872 | str r1, [r11], #4 |
873 | |
874 | crl_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 | |
897 | crl_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 |