**\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
\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
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
#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
{\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
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
\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
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
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
{\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
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
/* 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
\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
{\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