diff --git a/src/emu/sound/fm.c b/src/emu/sound/fm.c index 284f000025e..45439141597 100644 --- a/src/emu/sound/fm.c +++ b/src/emu/sound/fm.c @@ -7,19 +7,21 @@ ** Copyright Jarek Burczynski (bujar at mame dot net) ** Copyright Tatsuyuki Satoh , MultiArcadeMachineEmulator development ** -** Version 1.4 (final beta) +** Version 1.4.2 (final beta) ** */ /* ** History: ** -** 2006-2008 Eke-Eke (Genesis Plus port), MAME backport by R. Belmont +** 2006-2008 Eke-Eke (Genesis Plus GX), MAME backport by R. Belmont. ** - implemented PG overflow, aka "detune bug" (Ariel, Comix Zone, Shaq Fu, Spiderman,...), credits to Nemesis ** - fixed SSG-EG support, credits to Nemesis and additional fixes from Alone Coder ** - modified EG rates and frequency, tested by Nemesis on real hardware -** - fixed EG attenuation level on KEY ON (Ecco 2 splash sound) -** - fixed LFO phase update for CH3 special mode (Warlock, Alladin), thanks to AamirM +** - implemented LFO phase update for CH3 special mode (Warlock birds, Alladin bug sound) +** - fixed Attack Rate update (Batman & Robin intro) +** - fixed attenuation level at the start of Substain (Gynoug explosions) +** - fixed EG decay->substain transition to handle special cases, like SL=0 and Decay rate is very slow (Mega Turrican tracks 03,09...) ** ** 06-23-2007 Zsolt Vasvari: ** - changed the timing not to require the use of floating point calculations @@ -701,7 +703,7 @@ typedef struct but LFO works with one more bit of a precision so we really need 4096 elements */ UINT32 fn_table[4096]; /* fnumber->increment counter */ - + UINT32 fn_max; /* maximal phase increment (used for phase overflow) */ /* LFO */ UINT32 lfo_cnt; @@ -726,8 +728,6 @@ static INT32 out_delta[4]; /* channel output NONE,LEFT,RIGHT or CENTER for YM260 static UINT32 LFO_AM; /* runtime LFO calculations helper */ static INT32 LFO_PM; /* runtime LFO calculations helper */ -static int fn_max; /* maximal phase increment (used for phase overflow) */ - /* log output level */ #define LOG_ERR 3 /* ERROR */ #define LOG_WAR 2 /* WARNING */ @@ -922,19 +922,19 @@ INLINE void FM_KEYON(UINT8 type, FM_CH *CH , int s ) { SLOT->key = 1; SLOT->phase = 0; /* restart Phase Generator */ + SLOT->ssgn = (SLOT->ssg & 0x04) >> 1; if ((type == TYPE_YM2612) || (type == TYPE_YM2608)) { if( (SLOT->ar + SLOT->ksr) < 32+62 ) { SLOT->state = EG_ATT; /* phase -> Attack */ - SLOT->volume = MAX_ATT_INDEX; /* fix Ecco 2 splash sound */ } else { /* directly switch to Decay */ - SLOT->state = EG_DEC; SLOT->volume = MIN_ATT_INDEX; + SLOT->state = EG_DEC; } } else @@ -1075,6 +1075,7 @@ INLINE void set_ar_ksr(UINT8 type, FM_CH *CH,FM_SLOT *SLOT,int v) SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; if ((type == TYPE_YM2612) || (type == TYPE_YM2608)) { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; SLOT->eg_sel_ar = eg_rate_select2612[SLOT->ar + SLOT->ksr ]; } else @@ -1168,12 +1169,9 @@ INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm) INLINE void advance_lfo(FM_OPN *OPN) { UINT8 pos; - UINT8 prev_pos; if (OPN->lfo_inc) /* LFO enabled ? */ { - prev_pos = OPN->lfo_cnt>>LFO_SH & 127; - OPN->lfo_cnt += OPN->lfo_inc; pos = (OPN->lfo_cnt >> LFO_SH) & 127; @@ -1181,7 +1179,6 @@ INLINE void advance_lfo(FM_OPN *OPN) /* update AM when LFO output changes */ - /*if (prev_pos != pos)*/ /* actually I can't optimize is this way without rewritting chan_calc() to use chip->lfo_am instead of global lfo_am */ { @@ -1195,7 +1192,6 @@ INLINE void advance_lfo(FM_OPN *OPN) } /* PM works with 4 times slower clock */ - prev_pos >>= 2; pos >>= 2; /* update PM when LFO output changes */ /*if (prev_pos != pos)*/ /* can't use global lfo_pm for this optimization, must be chip->lfo_pm instead*/ @@ -1222,6 +1218,9 @@ static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT) i = 4; /* four operators per channel */ do { + /* reset SSG-EG swap flag */ + swap_flag = 0; + switch(SLOT->state) { case EG_ATT: /* attack phase */ @@ -1240,24 +1239,48 @@ static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT) break; case EG_DEC: /* decay phase */ - if (SLOT->ssg&0x08) /* SSG EG type envelope selected */ + if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608)) { - if ( !(OPN->eg_cnt & ((1<eg_sh_d1r)-1) ) ) - { - SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)]; + if ( !(OPN->eg_cnt & ((1<eg_sh_d1r)-1) ) ) + { + if (SLOT->ssg&0x08) /* SSG EG type envelope selected */ + { + SLOT->volume += 6 * eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)]; + } + else + { + SLOT->volume += eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)]; + } + } - if ( SLOT->volume >= (INT32)(SLOT->sl) ) - SLOT->state = EG_SUS; + /* check transition even if no volume update: this fixes the case when SL = MIN_ATT_INDEX */ + if ( SLOT->volume >= (INT32)(SLOT->sl) ) + { + SLOT->volume = (INT32)(SLOT->sl); + SLOT->state = EG_SUS; } } else { - if ( !(OPN->eg_cnt & ((1<eg_sh_d1r)-1) ) ) + if (SLOT->ssg&0x08) /* SSG EG type envelope selected */ { - SLOT->volume += eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)]; + if ( !(OPN->eg_cnt & ((1<eg_sh_d1r)-1) ) ) + { + SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)]; - if ( SLOT->volume >= (INT32)(SLOT->sl) ) - SLOT->state = EG_SUS; + if ( SLOT->volume >= (INT32)(SLOT->sl) ) + SLOT->state = EG_SUS; + } + } + else + { + if ( !(OPN->eg_cnt & ((1<eg_sh_d1r)-1) ) ) + { + SLOT->volume += eg_inc[SLOT->eg_sel_d1r + ((OPN->eg_cnt>>SLOT->eg_sh_d1r)&7)]; + + if ( SLOT->volume >= (INT32)(SLOT->sl) ) + SLOT->state = EG_SUS; + } } } break; @@ -1267,11 +1290,22 @@ static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT) { if ( !(OPN->eg_cnt & ((1<eg_sh_d2r)-1) ) ) { - SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)]; - - if ( SLOT->volume >= 512 ) + + if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608)) { - SLOT->volume = MAX_ATT_INDEX; + SLOT->volume += 6 * eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)]; + } + else + { + SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d2r + ((OPN->eg_cnt>>SLOT->eg_sh_d2r)&7)]; + } + + if ( SLOT->volume >= ENV_QUIET ) + { + if ((OPN->type != TYPE_YM2612) && (OPN->type != TYPE_YM2608)) + { + SLOT->volume = MAX_ATT_INDEX; + } if (SLOT->ssg&0x01) /* bit 0 = hold */ { @@ -1287,13 +1321,28 @@ static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT) { /* same as KEY-ON operation */ - /* restart of the Phase Generator should be here, - only if AR is not maximum ??? */ + /* restart of the Phase Generator should be here */ SLOT->phase = 0; - /* phase -> Attack */ - SLOT->volume = 511; - SLOT->state = EG_ATT; + if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608)) + { + if ((SLOT->ar + SLOT->ksr) < 94 /*32+62*/) + { + SLOT->state = EG_ATT; /* phase -> Attack */ + } + else + { + /* Attack Rate is maximal: directly switch to Decay (or Substain) */ + SLOT->volume = MIN_ATT_INDEX; + SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC; + } + } + else + { + /* phase -> Attack */ + SLOT->volume = 511; + SLOT->state = EG_ATT; + } swap_flag = (SLOT->ssg&0x02); /* bit 1 = alternate */ } @@ -1319,7 +1368,15 @@ static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT) case EG_REL: /* release phase */ if ( !(OPN->eg_cnt & ((1<eg_sh_rr)-1) ) ) { - SLOT->volume += eg_inc[SLOT->eg_sel_rr + ((OPN->eg_cnt>>SLOT->eg_sh_rr)&7)]; + /* SSG-EG affects Release phase also (Nemesis) */ + if ((SLOT->ssg&0x08) && ((OPN->type = TYPE_YM2612) || (OPN->type = TYPE_YM2608))) + { + SLOT->volume += 6 * eg_inc[SLOT->eg_sel_rr + ((OPN->eg_cnt>>SLOT->eg_sh_rr)&7)]; + } + else + { + SLOT->volume += eg_inc[SLOT->eg_sel_rr + ((OPN->eg_cnt>>SLOT->eg_sh_rr)&7)]; + } if ( SLOT->volume >= MAX_ATT_INDEX ) { @@ -1331,15 +1388,18 @@ static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT) } - out = SLOT->tl + ((UINT32)SLOT->volume); - if ((SLOT->ssg&0x08) && (SLOT->ssgn&2) && (SLOT->state != EG_OFF)) /* negate output (changes come from alternate bit, init comes from attack bit) */ - out ^= 511; // was ((1<volume); + + /* negate output (changes come from alternate bit, init comes from attack bit) */ + if ((SLOT->ssg&0x08) && (SLOT->ssgn&2) && (SLOT->state > EG_REL)) + out ^= MAX_ATT_INDEX; /* we need to store the result here because we are going to change ssgn in next instruction */ - SLOT->vol_out = out; + SLOT->vol_out = out + SLOT->tl; + /* reverse SLOT inversion flag */ SLOT->ssgn ^= swap_flag; SLOT++; @@ -1375,7 +1435,7 @@ INLINE void update_phase_lfo_slot(FM_OPN *OPN, FM_SLOT *SLOT, INT32 pms, UINT32 fc = (OPN->fn_table[fn]>>(7-blk)) + SLOT->DT[kc]; /* detects frequency overflow (credits to Nemesis) */ - if (fc < 0) fc += fn_max; + if (fc < 0) fc += OPN->fn_max; /* update phase */ SLOT->phase += (fc * SLOT->mul) >> 1; @@ -1413,19 +1473,19 @@ INLINE void update_phase_lfo_channel(FM_OPN *OPN, FM_CH *CH) /* detects frequency overflow (credits to Nemesis) */ finc = fc + CH->SLOT[SLOT1].DT[kc]; - if (finc < 0) finc += fn_max; + if (finc < 0) finc += OPN->fn_max; CH->SLOT[SLOT1].phase += (finc*CH->SLOT[SLOT1].mul) >> 1; finc = fc + CH->SLOT[SLOT2].DT[kc]; - if (finc < 0) finc += fn_max; + if (finc < 0) finc += OPN->fn_max; CH->SLOT[SLOT2].phase += (finc*CH->SLOT[SLOT2].mul) >> 1; finc = fc + CH->SLOT[SLOT3].DT[kc]; - if (finc < 0) finc += fn_max; + if (finc < 0) finc += OPN->fn_max; CH->SLOT[SLOT3].phase += (finc*CH->SLOT[SLOT3].mul) >> 1; finc = fc + CH->SLOT[SLOT4].DT[kc]; - if (finc < 0) finc += fn_max; + if (finc < 0) finc += OPN->fn_max; CH->SLOT[SLOT4].phase += (finc*CH->SLOT[SLOT4].mul) >> 1; } else /* LFO phase modulation = zero */ @@ -1512,14 +1572,14 @@ INLINE void chan_calc(FM_OPN *OPN, FM_CH *CH, int chnum) } /* update phase increment and envelope generator */ -INLINE void refresh_fc_eg_slot(UINT8 type, FM_SLOT *SLOT , int fc , int kc ) +INLINE void refresh_fc_eg_slot(FM_OPN *OPN, FM_SLOT *SLOT , int fc , int kc ) { int ksr = kc >> SLOT->KSR; fc += SLOT->DT[kc]; /* detects frequency overflow (credits to Nemesis) */ - if (fc < 0) fc += fn_max; + if (fc < 0) fc += OPN->fn_max; /* (frequency) phase increment counter */ SLOT->Incr = (fc * SLOT->mul) >> 1; @@ -1532,7 +1592,7 @@ INLINE void refresh_fc_eg_slot(UINT8 type, FM_SLOT *SLOT , int fc , int kc ) if ((SLOT->ar + SLOT->ksr) < 32+62) { SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; - if ((type == TYPE_YM2612) || (type == TYPE_YM2608)) + if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608)) { SLOT->eg_sel_ar = eg_rate_select2612[SLOT->ar + SLOT->ksr ]; } @@ -1551,7 +1611,7 @@ INLINE void refresh_fc_eg_slot(UINT8 type, FM_SLOT *SLOT , int fc , int kc ) SLOT->eg_sh_d2r = eg_rate_shift [SLOT->d2r + SLOT->ksr]; SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr]; - if ((type == TYPE_YM2612) || (type == TYPE_YM2608)) + if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608)) { SLOT->eg_sel_d1r= eg_rate_select2612[SLOT->d1r + SLOT->ksr]; SLOT->eg_sel_d2r= eg_rate_select2612[SLOT->d2r + SLOT->ksr]; @@ -1568,15 +1628,15 @@ INLINE void refresh_fc_eg_slot(UINT8 type, FM_SLOT *SLOT , int fc , int kc ) /* update phase increment counters */ /* Changed from INLINE to static to work around gcc 4.2.1 codegen bug */ -static void refresh_fc_eg_chan(UINT8 type, FM_CH *CH ) +static void refresh_fc_eg_chan(FM_OPN *OPN, FM_CH *CH ) { if( CH->SLOT[SLOT1].Incr==-1){ int fc = CH->fc; int kc = CH->kcode; - refresh_fc_eg_slot(type, &CH->SLOT[SLOT1] , fc , kc ); - refresh_fc_eg_slot(type, &CH->SLOT[SLOT2] , fc , kc ); - refresh_fc_eg_slot(type, &CH->SLOT[SLOT3] , fc , kc ); - refresh_fc_eg_slot(type, &CH->SLOT[SLOT4] , fc , kc ); + refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT1] , fc , kc ); + refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT2] , fc , kc ); + refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT3] , fc , kc ); + refresh_fc_eg_slot(OPN, &CH->SLOT[SLOT4] , fc , kc ); } } @@ -1761,13 +1821,27 @@ static void FMCloseTable( void ) /* CSM Key Controll */ INLINE void CSMKeyControll(UINT8 type, FM_CH *CH) { - /* this is wrong, atm */ - - /* all key on */ - FM_KEYON(type, CH,SLOT1); - FM_KEYON(type, CH,SLOT2); - FM_KEYON(type, CH,SLOT3); - FM_KEYON(type, CH,SLOT4); + /* all key on then off (only for operators which were OFF!) */ + if (!CH->SLOT[SLOT1].key) + { + FM_KEYON(type, CH,SLOT1); + FM_KEYOFF(CH, SLOT1); + } + if (!CH->SLOT[SLOT2].key) + { + FM_KEYON(type, CH,SLOT2); + FM_KEYOFF(CH, SLOT2); + } + if (!CH->SLOT[SLOT3].key) + { + FM_KEYON(type, CH,SLOT3); + FM_KEYOFF(CH, SLOT3); + } + if (!CH->SLOT[SLOT4].key) + { + FM_KEYON(type, CH,SLOT4); + FM_KEYOFF(CH, SLOT4); + } } #ifdef __STATE_H__ @@ -1861,9 +1935,9 @@ static void OPNSetPres(FM_OPN *OPN, int pres, int timer_prescaler, int SSGpres) #endif } - /* maximal frequency, used for overflow, best setting with BLOCK=5 (notaz) */ - fn_max = ((UINT32)((double)OPN->fn_table[0x7ff*2] / OPN->ST.freqbase) >> 2); - + /* maximal frequency is required for Phase overflow calculation, register size is 17 bits (Nemesis) */ + OPN->fn_max = (UINT32)( (double)0x20000 * OPN->ST.freqbase * (1<<(FREQ_SH-10)) ); + /* LFO freq. table */ for(i = 0; i < 8; i++) { @@ -2204,19 +2278,19 @@ void ym2203_update_one(void *chip, FMSAMPLE *buffer, int length) /* refresh PG and EG */ - refresh_fc_eg_chan( OPN->type, cch[0] ); - refresh_fc_eg_chan( OPN->type, cch[1] ); + refresh_fc_eg_chan( OPN, cch[0] ); + refresh_fc_eg_chan( OPN, cch[1] ); if( (F2203->OPN.ST.mode & 0xc0) ) { /* 3SLOT MODE */ if( cch[2]->SLOT[SLOT1].Incr==-1) { - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode ); } - }else refresh_fc_eg_chan( OPN->type, cch[2] ); + }else refresh_fc_eg_chan( OPN, cch[2] ); /* YM2203 doesn't have LFO so we must keep these globals at 0 level */ @@ -3386,22 +3460,22 @@ void ym2608_update_one(void *chip, FMSAMPLE **buffer, int length) pcmsizeA = F2608->pcm_size; /* refresh PG and EG */ - refresh_fc_eg_chan( OPN->type, cch[0] ); - refresh_fc_eg_chan( OPN->type, cch[1] ); + refresh_fc_eg_chan( OPN, cch[0] ); + refresh_fc_eg_chan( OPN, cch[1] ); if( (OPN->ST.mode & 0xc0) ) { /* 3SLOT MODE */ if( cch[2]->SLOT[SLOT1].Incr==-1) { - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode ); } - }else refresh_fc_eg_chan( OPN->type, cch[2] ); - refresh_fc_eg_chan( OPN->type, cch[3] ); - refresh_fc_eg_chan( OPN->type, cch[4] ); - refresh_fc_eg_chan( OPN->type, cch[5] ); + }else refresh_fc_eg_chan( OPN, cch[2] ); + refresh_fc_eg_chan( OPN, cch[3] ); + refresh_fc_eg_chan( OPN, cch[4] ); + refresh_fc_eg_chan( OPN, cch[5] ); /* buffering */ @@ -3421,21 +3495,6 @@ void ym2608_update_one(void *chip, FMSAMPLE **buffer, int length) out_fm[4] = 0; out_fm[5] = 0; - /* advance envelope generator */ - OPN->eg_timer += OPN->eg_timer_add; - while (OPN->eg_timer >= OPN->eg_timer_overflow) - { - OPN->eg_timer -= OPN->eg_timer_overflow; - OPN->eg_cnt++; - - advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]); - advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]); - advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]); - advance_eg_channel(OPN, &cch[3]->SLOT[SLOT1]); - advance_eg_channel(OPN, &cch[4]->SLOT[SLOT1]); - advance_eg_channel(OPN, &cch[5]->SLOT[SLOT1]); - } - /* calculate FM */ chan_calc(OPN, cch[0], 0 ); chan_calc(OPN, cch[1], 1 ); @@ -3455,6 +3514,21 @@ void ym2608_update_one(void *chip, FMSAMPLE **buffer, int length) ADPCMA_calc_chan( F2608, &F2608->adpcm[j]); } + /* advance envelope generator */ + OPN->eg_timer += OPN->eg_timer_add; + while (OPN->eg_timer >= OPN->eg_timer_overflow) + { + OPN->eg_timer -= OPN->eg_timer_overflow; + OPN->eg_cnt++; + + advance_eg_channel(OPN, &cch[0]->SLOT[SLOT1]); + advance_eg_channel(OPN, &cch[1]->SLOT[SLOT1]); + advance_eg_channel(OPN, &cch[2]->SLOT[SLOT1]); + advance_eg_channel(OPN, &cch[3]->SLOT[SLOT1]); + advance_eg_channel(OPN, &cch[4]->SLOT[SLOT1]); + advance_eg_channel(OPN, &cch[5]->SLOT[SLOT1]); + } + /* buffering */ { int lt,rt; @@ -3940,20 +4014,20 @@ void ym2610_update_one(void *chip, FMSAMPLE **buffer, int length) #endif /* refresh PG and EG */ - refresh_fc_eg_chan( OPN->type, cch[0] ); + refresh_fc_eg_chan( OPN, cch[0] ); if( (OPN->ST.mode & 0xc0) ) { /* 3SLOT MODE */ if( cch[1]->SLOT[SLOT1].Incr==-1) { - refresh_fc_eg_slot(OPN->type, &cch[1]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] ); - refresh_fc_eg_slot(OPN->type, &cch[1]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] ); - refresh_fc_eg_slot(OPN->type, &cch[1]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] ); - refresh_fc_eg_slot(OPN->type, &cch[1]->SLOT[SLOT4] , cch[1]->fc , cch[1]->kcode ); + refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] ); + refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] ); + refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] ); + refresh_fc_eg_slot(OPN, &cch[1]->SLOT[SLOT4] , cch[1]->fc , cch[1]->kcode ); } - }else refresh_fc_eg_chan( OPN->type, cch[1] ); - refresh_fc_eg_chan( OPN->type, cch[2] ); - refresh_fc_eg_chan( OPN->type, cch[3] ); + }else refresh_fc_eg_chan( OPN, cch[1] ); + refresh_fc_eg_chan( OPN, cch[2] ); + refresh_fc_eg_chan( OPN, cch[3] ); /* buffering */ for(i=0; i < length ; i++) @@ -4069,22 +4143,22 @@ void ym2610b_update_one(void *chip, FMSAMPLE **buffer, int length) pcmsizeA = F2610->pcm_size; /* refresh PG and EG */ - refresh_fc_eg_chan( OPN->type, cch[0] ); - refresh_fc_eg_chan( OPN->type, cch[1] ); + refresh_fc_eg_chan( OPN, cch[0] ); + refresh_fc_eg_chan( OPN, cch[1] ); if( (OPN->ST.mode & 0xc0) ) { /* 3SLOT MODE */ if( cch[2]->SLOT[SLOT1].Incr==-1) { - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode ); } - }else refresh_fc_eg_chan( OPN->type, cch[2] ); - refresh_fc_eg_chan( OPN->type, cch[3] ); - refresh_fc_eg_chan( OPN->type, cch[4] ); - refresh_fc_eg_chan( OPN->type, cch[5] ); + }else refresh_fc_eg_chan( OPN, cch[2] ); + refresh_fc_eg_chan( OPN, cch[3] ); + refresh_fc_eg_chan( OPN, cch[4] ); + refresh_fc_eg_chan( OPN, cch[5] ); /* buffering */ for(i=0; i < length ; i++) @@ -4590,22 +4664,22 @@ void ym2612_update_one(void *chip, FMSAMPLE **buffer, int length) dacen = F2612->dacen; /* refresh PG and EG */ - refresh_fc_eg_chan( OPN->type, cch[0] ); - refresh_fc_eg_chan( OPN->type, cch[1] ); + refresh_fc_eg_chan( OPN, cch[0] ); + refresh_fc_eg_chan( OPN, cch[1] ); if( (OPN->ST.mode & 0xc0) ) { /* 3SLOT MODE */ if( cch[2]->SLOT[SLOT1].Incr==-1) { - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] ); - refresh_fc_eg_slot(OPN->type, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT1] , OPN->SL3.fc[1] , OPN->SL3.kcode[1] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT2] , OPN->SL3.fc[2] , OPN->SL3.kcode[2] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT3] , OPN->SL3.fc[0] , OPN->SL3.kcode[0] ); + refresh_fc_eg_slot(OPN, &cch[2]->SLOT[SLOT4] , cch[2]->fc , cch[2]->kcode ); } - }else refresh_fc_eg_chan( OPN->type, cch[2] ); - refresh_fc_eg_chan( OPN->type, cch[3] ); - refresh_fc_eg_chan( OPN->type, cch[4] ); - refresh_fc_eg_chan( OPN->type, cch[5] ); + }else refresh_fc_eg_chan( OPN, cch[2] ); + refresh_fc_eg_chan( OPN, cch[3] ); + refresh_fc_eg_chan( OPN, cch[4] ); + refresh_fc_eg_chan( OPN, cch[5] ); /* buffering */ for(i=0; i < length ; i++) @@ -4621,6 +4695,17 @@ void ym2612_update_one(void *chip, FMSAMPLE **buffer, int length) out_fm[4] = 0; out_fm[5] = 0; + /* calculate FM */ + chan_calc(OPN, cch[0], 0 ); + chan_calc(OPN, cch[1], 1 ); + chan_calc(OPN, cch[2], 2 ); + chan_calc(OPN, cch[3], 3 ); + chan_calc(OPN, cch[4], 4 ); + if( dacen ) + *cch[5]->connect4 += dacout; + else + chan_calc(OPN, cch[5], 5 ); + /* advance envelope generator */ OPN->eg_timer += OPN->eg_timer_add; while (OPN->eg_timer >= OPN->eg_timer_overflow) @@ -4636,17 +4721,6 @@ void ym2612_update_one(void *chip, FMSAMPLE **buffer, int length) advance_eg_channel(OPN, &cch[5]->SLOT[SLOT1]); } - /* calculate FM */ - chan_calc(OPN, cch[0], 0 ); - chan_calc(OPN, cch[1], 1 ); - chan_calc(OPN, cch[2], 2 ); - chan_calc(OPN, cch[3], 3 ); - chan_calc(OPN, cch[4], 4 ); - if( dacen ) - *cch[5]->connect4 += dacout; - else - chan_calc(OPN, cch[5], 5 ); - { int lt,rt;