ym2612 ARM, bug fixing and small optimizations
authorkub <derkub@gmail.com>
Thu, 2 Apr 2020 18:33:56 +0000 (20:33 +0200)
committerkub <derkub@gmail.com>
Thu, 2 Apr 2020 18:33:56 +0000 (20:33 +0200)
pico/sound/ym2612_arm.S

index e3ec370..59abb74 100644 (file)
@@ -15,6 +15,9 @@
 
 #include "../arm_features.h"
 
+@ very simple adaption YM2612 output rate to sample rate (~1M cycles @44100)
+//#define INTERPOL
+
 .equiv SLOT1, 0
 .equiv SLOT2, 2
 .equiv SLOT3, 1
 @ r5=slot, r1=eg_cnt, trashes: r0,r2,r3
 @ writes output to routp, but only if vol_out changes
 .macro update_eg_phase_slot slot
+#if defined(INTERPOL)
     ldrh    r0, [r5,#0x34]       @ vol_out
+#endif
     ldrb    r2, [r5,#0x17]       @ state
     add     r3, r5, #0x1c
+#if defined(INTERPOL)
     strh    r0, [r5,#0x36]       @ vol_ipol
+#endif
     tst     r2, r2
     beq     0f                   @ EG_OFF
 
     bne     0f                   @ no volume change
 
     mov     r3, r1, lsr r0
+    ldrb    r0, [r5,#0x30]       @ ssg
     and     r3, r3, #7
     add     r3, r3, r3, lsl #1
     mov     r3, r2, lsr r3
     and     r3, r3, #7           @ eg_inc_val shift, may be 0
-    ldrb    r0, [r5,#0x30]       @ ssg
     ldrb    r2, [r5,#0x17]       @ state
 
     tst     r0, #0x08            @ ssg enabled?
     b       11f
 
 9:  @ SSG-EG mode
-    cmp     r2, #4               @ EG_ATT
     ldrh    r0, [r5,#0x1a]       @ volume, unsigned (0-1023)
+    cmp     r2, #4               @ EG_ATT
     beq     4f
 
     cmp     r0, #0x200           @ if ( volume < 0x200 )
     strgeb  r3, [r5,#0x17]       @ state
 
 10: @ finish
-    strh    r0, [r5,#0x1a]       @ volume
     ldrb    r2, [r5,#0x30]       @ ssg
     ldrb    r3, [r5,#0x17]       @ state
+    strh    r0, [r5,#0x1a]       @ volume
     cmp     r2, #0x0c            @ if ( ssg&0x04 && state > EG_REL )
     cmpge   r3, #EG_REL+1
     rsbge   r0, r0, #0x200       @ volume = (0x200-volume) & MAX_ATT
 .macro update_ssg_eg
     ldrh    r0, [r5,#0x30]                @ ssg+ssgn
     ldrb    r2, [r5,#0x17]                @ state
-    and     r3, r0, #0x08
-    cmp     r3, #0x08                     @ ssg enabled &&
     ldrh    r3, [r5,#0x1a]                @ volume
-    cmpge   r2, #EG_REL+1                 @   state > EG_REL &&
+    tst     r0, #0x08                     @ ssg enabled &&
+    beq     9f
+    cmp     r2, #EG_REL+1                 @   state > EG_REL &&
     cmpge   r3, #0x200                    @   volume >= 0x200?
     blt     9f
 
     orrne   r0, r0, #0x400                @ ssgn = 4
     strneh  r0, [r5,#0x30]
 
-    eor     r0, r0, #0x4                  @ if ( !(ssg&0x04 )
+    eor     r0, r0, #0x4                  @ if ( !(ssg&0x04) )
     tst     r0, #0x4
     cmpne   r2, #EG_ATT                   @ if ( state != EG_ATT )
     movne   r3, #0x400
@@ -747,7 +754,7 @@ eg_done:
     beq     crl_loop
 
     @ output interpolation
-#if 0
+#if 0 // too expensive on slow platforms
     @ basic interpolator, interpolate in middle region, else use closer value
     mov     r3, r8, lsr #EG_SH      @ eg_timer, [0..3<<EG_SH) after loop
     cmp     r3, #(EG_TIMER_OVERFLOW>>EG_SH)/2
@@ -780,7 +787,7 @@ eg_done:
     mov     r7, r7, lsl #16
     orr     r7, r7, r0
     ror     r7, r7, #16
-#elif 0
+#elif defined(INTERPOL)
     @ super-basic... just take value closest to sample point
     mov     r3, r8, lsr #EG_SH-1    @ eg_timer, [0..3<<EG_SH) after loop
     cmp     r3, #(EG_TIMER_OVERFLOW>>EG_SH)