sh2 drc: updates from mame for ym2612 sound
authorkub <derkub@gmail.com>
Sat, 21 Dec 2019 21:54:40 +0000 (22:54 +0100)
committerkub <derkub@gmail.com>
Sat, 21 Dec 2019 21:54:40 +0000 (22:54 +0100)
pico/sound/ym2612.c
pico/sound/ym2612_arm.S
platform/gp2x/emu.c

index 0867f55..5640852 100644 (file)
@@ -5,6 +5,8 @@
 **\r
 ** SSG-EG was also removed, because it's rarely used, Sega2.doc even does not\r
 ** document it ("proprietary") and tells to write 0 to SSG-EG control register.\r
+**\r
+** updated with fixes from mame 0.216 (file version 1.5.1) (kub)\r
 */\r
 \r
 /*\r
@@ -148,7 +150,7 @@ void memset32(int *dest, int c, int count);
 \r
 #define FREQ_SH                        16  /* 16.16 fixed point (frequency calculations) */\r
 #define EG_SH                  16  /* 16.16 fixed point (envelope generator timing) */\r
-#define LFO_SH                 25  /*  7.25 fixed point (LFO calculations)       */\r
+#define LFO_SH                 24  /*  8.24 fixed point (LFO calculations)       */\r
 #define TIMER_SH               16  /* 16.16 fixed point (timers calculations)    */\r
 \r
 #define ENV_BITS               10\r
@@ -287,8 +289,8 @@ O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),
 O(18),O(18),O(18),O(18),O(18),O(18),O(18),O(18),\r
 \r
 /* rates 00-11 */\r
-O( 0),O( 1),O( 2),O( 3),\r
-O( 0),O( 1),O( 2),O( 3),\r
+O(18),O(18),O( 0),O( 0),\r
+O( 0),O( 0),O( 2),O( 2),\r
 O( 0),O( 1),O( 2),O( 3),\r
 O( 0),O( 1),O( 2),O( 3),\r
 O( 0),O( 1),O( 2),O( 3),\r
@@ -328,10 +330,10 @@ O(16),O(16),O(16),O(16),O(16),O(16),O(16),O(16)
 #define O(a) (a*1)\r
 static const UINT8 eg_rate_shift[32+64+32]={   /* Envelope Generator counter shifts (32 + 64 rates + 32 RKS) */\r
 /* 32 infinite time rates */\r
-O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),\r
-O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),\r
-O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),\r
-O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0),\r
+O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),\r
+O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),\r
+O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),\r
+O(11),O(11),O(11),O(11),O(11),O(11),O(11),O(11),\r
 \r
 /* rates 00-11 */\r
 O(11),O(11),O(11),O(11),\r
@@ -560,7 +562,13 @@ INLINE void FM_KEYON(int c , int s )
        {\r
                SLOT->key = 1;\r
                SLOT->phase = 0;                /* restart Phase Generator */\r
-               SLOT->state = EG_ATT;   /* phase -> Attack */\r
+               if (SLOT->ar + SLOT->ksr < 32+62) {\r
+                       SLOT->state = (SLOT->volume > MIN_ATT_INDEX) ? EG_ATT :\r
+                               ((SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC);\r
+               } else {\r
+                       SLOT->volume = MIN_ATT_INDEX;\r
+                       SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC;\r
+               }\r
                ym2612.slot_mask |= (1<<s) << (c*4);\r
        }\r
 }\r
@@ -616,7 +624,7 @@ INLINE void set_ar_ksr(FM_CH *CH, FM_SLOT *SLOT, int v)
                else\r
                {\r
                        eg_sh_ar  = 0;\r
-                       eg_sel_ar = 17;\r
+                       eg_sel_ar = 18;\r
                }\r
 \r
                SLOT->eg_pack_ar = eg_inc_pack[eg_sel_ar] | (eg_sh_ar<<24);\r
@@ -656,6 +664,9 @@ INLINE void set_sl_rr(FM_SLOT *SLOT, int v)
 \r
        SLOT->sl = sl_table[ v>>4 ];\r
 \r
+       if (SLOT->state == EG_DEC && (SLOT->volume >= (INT32)(SLOT->sl)))\r
+               SLOT->state = EG_SUS;\r
+\r
        SLOT->rr  = 34 + ((v&0x0f)<<2);\r
 \r
        eg_sh_rr  = eg_rate_shift [SLOT->rr  + SLOT->ksr];\r
@@ -715,12 +726,12 @@ INLINE int advance_lfo(int lfo_ampm, UINT32 lfo_cnt_old, UINT32 lfo_cnt)
        if (prev_pos != pos)\r
        {\r
                lfo_ampm &= 0xff;\r
-               /* triangle */\r
+               /* triangle (inverted) */\r
                /* AM: 0 to 126 step +2, 126 to 0 step -2 */\r
                if (pos<64)\r
-                       lfo_ampm |= ((pos&63) * 2) << 8;           /* 0 - 126 */\r
+                       lfo_ampm |= ((pos^63) * 2) << 8;           /* 0 - 126 */\r
                else\r
-                       lfo_ampm |= (126 - (pos&63)*2) << 8;\r
+                       lfo_ampm |= ((pos&63) * 2) << 8;\r
        }\r
        else\r
        {\r
@@ -759,7 +770,7 @@ INLINE void update_eg_phase(UINT16 *vol_out, FM_SLOT *SLOT, UINT32 eg_cnt)
                if ( volume <= MIN_ATT_INDEX )\r
                {\r
                        volume = MIN_ATT_INDEX;\r
-                       SLOT->state = EG_DEC;\r
+                       SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS: EG_DEC;\r
                }\r
                break;\r
 \r
@@ -1124,22 +1135,29 @@ static int chan_render(int *buffer, int length, int c, UINT32 flags) // flags: s
                {\r
                        UINT8  blk;\r
                        UINT32 fn;\r
-                       int kc,fc;\r
+                       int kc,fc,fdt;\r
 \r
-                       blk = block_fnum >> 11;\r
                        block_fnum = block_fnum*2 + lfo_fn_table_index_offset;\r
-\r
+                       blk = (block_fnum&0x7000) >> 12;\r
                        fn  = block_fnum & 0xfff;\r
 \r
                        /* keyscale code */\r
-                       kc = (blk<<2) | opn_fktable[fn >> 8];\r
+                       kc = (blk<<2) | opn_fktable[(fn >> 7) & 0xf];\r
                        /* phase increment counter */\r
-                       fc = fn_table[fn]>>(7-blk);\r
-\r
-                       crct.incr1 = ((fc+crct.CH->SLOT[SLOT1].DT[kc])*crct.CH->SLOT[SLOT1].mul) >> 1;\r
-                       crct.incr2 = ((fc+crct.CH->SLOT[SLOT2].DT[kc])*crct.CH->SLOT[SLOT2].mul) >> 1;\r
-                       crct.incr3 = ((fc+crct.CH->SLOT[SLOT3].DT[kc])*crct.CH->SLOT[SLOT3].mul) >> 1;\r
-                       crct.incr4 = ((fc+crct.CH->SLOT[SLOT4].DT[kc])*crct.CH->SLOT[SLOT4].mul) >> 1;\r
+                       fc = (fn_table[fn]>>(7-blk));\r
+\r
+                       fdt = fc + crct.CH->SLOT[SLOT1].DT[kc];\r
+                       if (fdt < 0) fdt += fn_table[0x7ff*2] >> 2;\r
+                       crct.incr1 = (fdt*crct.CH->SLOT[SLOT1].mul) >> 1;\r
+                       fdt = fc + crct.CH->SLOT[SLOT2].DT[kc];\r
+                       if (fdt < 0) fdt += fn_table[0x7ff*2] >> 2;\r
+                       crct.incr2 = (fdt*crct.CH->SLOT[SLOT2].mul) >> 1;\r
+                       fdt = fc + crct.CH->SLOT[SLOT3].DT[kc];\r
+                       if (fdt < 0) fdt += fn_table[0x7ff*2] >> 2;\r
+                       crct.incr3 = (fdt*crct.CH->SLOT[SLOT3].mul) >> 1;\r
+                       fdt = fc + crct.CH->SLOT[SLOT4].DT[kc];\r
+                       if (fdt < 0) fdt += fn_table[0x7ff*2] >> 2;\r
+                       crct.incr4 = (fdt*crct.CH->SLOT[SLOT4].mul) >> 1;\r
                }\r
                else    /* LFO phase modulation  = zero */\r
                {\r
@@ -1201,7 +1219,7 @@ INLINE void refresh_fc_eg_slot(FM_SLOT *SLOT, int fc, int kc)
                else\r
                {\r
                        eg_sh  = 0;\r
-                       eg_sel = 17;\r
+                       eg_sel = 18;\r
                }\r
 \r
                SLOT->eg_pack_ar = eg_inc_pack[eg_sel] | (eg_sh<<24);\r
@@ -1256,7 +1274,7 @@ static void init_timetables(const UINT8 *dttable)
        /* DeTune table */\r
        for (d = 0;d <= 3;d++){\r
                for (i = 0;i <= 31;i++){\r
-                       rate = ((double)dttable[d*32 + i]) * SIN_LEN  * ym2612.OPN.ST.freqbase  * (1<<FREQ_SH) / ((double)(1<<20));\r
+                       rate = ((double)dttable[d*32 + i]) * ym2612.OPN.ST.freqbase  * (1<<(FREQ_SH-10));\r
                        ym2612.OPN.ST.dt_tab[d][i]   = (INT32) rate;\r
                        ym2612.OPN.ST.dt_tab[d+4][i] = -ym2612.OPN.ST.dt_tab[d][i];\r
                }\r
@@ -1661,6 +1679,9 @@ void YM2612ResetChip_(void)
 \r
        ym2612.OPN.eg_timer = 0;\r
        ym2612.OPN.eg_cnt   = 0;\r
+       ym2612.OPN.lfo_inc = 0;\r
+       ym2612.OPN.lfo_cnt = 0;\r
+       g_lfo_ampm = 126 << 8;\r
        ym2612.OPN.ST.status = 0;\r
 \r
        reset_channels( &ym2612.CH[0] );\r
@@ -1720,6 +1741,7 @@ int YM2612Write_(unsigned int a, unsigned int v)
                                {\r
                                        ym2612.OPN.lfo_inc = 0;\r
                                        ym2612.OPN.lfo_cnt = 0;\r
+                                       g_lfo_ampm = 126 << 8;\r
                                }\r
                                break;\r
 #if 0 // handled elsewhere\r
index 7d4c609..9b80792 100644 (file)
@@ -30,7 +30,7 @@
 
 .equiv EG_SH,                    16             @ 16.16 fixed point (envelope generator timing)
 .equiv EG_TIMER_OVERFLOW, (3*(1<<EG_SH)) @ envelope generator timer overflows every 3 samples (on real chip)
-.equiv LFO_SH,            25  /*  7.25 fixed point (LFO calculations)       */
+.equiv LFO_SH,            24  /*  8.24 fixed point (LFO calculations)       */
 
 .equiv ENV_QUIET,                (2*13*256/8)
 
     mov     r2, r2, lsl r3
     add     r0, r0, r2, asr #4
     cmp     r0, #0               @ if (volume <= MIN_ATT_INDEX)
-    movle   r3, #EG_DEC
-    strleb  r3, [r5,#0x17]       @ state
-    movle   r0, #0
+    bgt     10f
+    ldr     r2, [r5,#0x1c]
+    mov     r0, #0
+    cmp     r2, #0
+    movne   r3, #EG_DEC
+    moveq   r3, #EG_SUS
+    strb    r3, [r5,#0x17]       @ state
     b       10f
 
 2:  @ EG_SUS
     beq     0f
     and     r3, r2, #0x3f
     cmp     r2, #0x40
-    rsbge   r3, r3, #0x3f
+    eorlt   r3, r3, #0x3f
     bic     r12,r12, #0xff000000          @ lfo_ampm &= 0xff
     orr     r12,r12, r3, lsl #1+24
 
index 4ad90b8..1deb84d 100644 (file)
@@ -55,7 +55,7 @@ void pemu_prep_defconfig(void)
        gp2x_soc_t soc;\r
 \r
        defaultConfig.CPUclock = default_cpu_clock;\r
-       defaultConfig.renderer32x = RT_8BIT_FAST;\r
+       defaultConfig.renderer32x = RT_8BIT_ACC;\r
        defaultConfig.analog_deadzone = 50;\r
 \r
        soc = soc_detect();\r