mirror of
https://github.com/holub/mame
synced 2025-05-29 17:13:05 +03:00
YM2608/2612: applied latest fixes/discoveries [Eke-Eke, Nemesis].
This commit is contained in:
parent
db51d2ca3c
commit
eb91a91308
@ -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,6 +1239,29 @@ static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT)
|
||||
break;
|
||||
|
||||
case EG_DEC: /* decay phase */
|
||||
if ((OPN->type == TYPE_YM2612) || (OPN->type == TYPE_YM2608))
|
||||
{
|
||||
if ( !(OPN->eg_cnt & ((1<<SLOT->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)];
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 (SLOT->ssg&0x08) /* SSG EG type envelope selected */
|
||||
{
|
||||
if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_d1r)-1) ) )
|
||||
@ -1260,6 +1282,7 @@ static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT)
|
||||
SLOT->state = EG_SUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EG_SUS: /* sustain phase */
|
||||
@ -1267,11 +1290,22 @@ static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT)
|
||||
{
|
||||
if ( !(OPN->eg_cnt & ((1<<SLOT->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 += 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;
|
||||
|
||||
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 */
|
||||
}
|
||||
@ -1318,8 +1367,16 @@ static void advance_eg_channel(FM_OPN *OPN, FM_SLOT *SLOT)
|
||||
|
||||
case EG_REL: /* release phase */
|
||||
if ( !(OPN->eg_cnt & ((1<<SLOT->eg_sh_rr)-1) ) )
|
||||
{
|
||||
/* 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<<ENV_BITS)-1); /* 1023 */
|
||||
out = ((UINT32)SLOT->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 */
|
||||
/* 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,8 +1935,8 @@ 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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user