speedup ymf278b_compute_envelope, and make note about reading fm regs

This commit is contained in:
Michaël Banaan Ananas 2011-08-13 22:54:57 +00:00
parent ce1bc07076
commit 450320469d

View File

@ -233,7 +233,7 @@ static UINT32 ymf278_compute_decay_env_vol_step(YMF278BSlot *slot, int val)
// rate override with damping/pseudo reverb // rate override with damping/pseudo reverb
if (slot->DAMP) if (slot->DAMP)
rate = 56; // datasheet says it's slightly curved though rate = 56; // approximate, datasheet says it's slightly curved though
else if (slot->preverb && slot->env_vol > ((6*8)<<23)) else if (slot->preverb && slot->env_vol > ((6*8)<<23))
{ {
// pseudo reverb starts at -18dB (6 in voltab) // pseudo reverb starts at -18dB (6 in voltab)
@ -266,7 +266,10 @@ static void ymf278b_compute_freq_step(YMF278BSlot *slot)
static void ymf278b_compute_envelope(YMF278BSlot *slot) static void ymf278b_compute_envelope(YMF278BSlot *slot)
{ {
if(slot->env_step == 0) switch (slot->env_step)
{
// Attack
case 0:
{ {
// Attack // Attack
int rate = ymf278b_compute_rate(slot, slot->AR); int rate = ymf278b_compute_rate(slot, slot->AR);
@ -279,70 +282,72 @@ static void ymf278b_compute_envelope(YMF278BSlot *slot)
LOG(("YMF278B: Attack skipped - ")); LOG(("YMF278B: Attack skipped - "));
slot->env_vol = 0; slot->env_vol = 0;
slot->env_step++; slot->env_step++;
// ..fall through ymf278b_compute_envelope(slot);
} }
else if (rate<4) else if (rate<4)
{ {
slot->env_vol_step = 0; slot->env_vol_step = 0;
return;
} }
else else
{ {
// NOTE: attack rate is linear here, but datasheet shows a smooth curve // NOTE: attack rate is linear here, but datasheet shows a smooth curve
LOG(("YMF278B: Attack, val = %d, rate = %d, delay = %g\n", slot->AR, rate, ymf278_compute_attack_rate(rate)*1000.0)); LOG(("YMF278B: Attack, val = %d, rate = %d, delay = %g\n", slot->AR, rate, ymf278_compute_attack_rate(rate)*1000.0));
slot->env_vol_step = ~((256U<<23) / ymf278_compute_attack_rate(rate)); slot->env_vol_step = ~((256U<<23) / ymf278_compute_attack_rate(rate));
return;
} }
break;
} }
if(slot->env_step == 1)
{
// Decay 1 // Decay 1
case 1:
if(slot->DL) if(slot->DL)
{ {
LOG(("YMF278B: Decay step 1, dl=%d, val = %d rate = %d, delay = %g, PRVB = %d, DAMP = %d\n", slot->DL, slot->D1R, ymf278b_compute_rate(slot, slot->D1R), ymf278_compute_decay_rate(ymf278b_compute_rate(slot, slot->D1R))*1000.0, slot->preverb, slot->DAMP)); LOG(("YMF278B: Decay step 1, dl=%d, val = %d rate = %d, delay = %g, PRVB = %d, DAMP = %d\n", slot->DL, slot->D1R, ymf278b_compute_rate(slot, slot->D1R), ymf278_compute_decay_rate(ymf278b_compute_rate(slot, slot->D1R))*1000.0, slot->preverb, slot->DAMP));
slot->env_vol_step = ymf278_compute_decay_env_vol_step(slot, slot->D1R); slot->env_vol_step = ymf278_compute_decay_env_vol_step(slot, slot->D1R);
slot->env_vol_lim = (slot->DL*8)<<23; slot->env_vol_lim = (slot->DL*8)<<23;
return;
} }
else else
slot->env_step++;
// ..fall through
}
if(slot->env_step == 2)
{ {
LOG(("YMF278B: Decay 1 skipped - "));
slot->env_step++;
ymf278b_compute_envelope(slot);
}
break;
// Decay 2 // Decay 2
case 2:
LOG(("YMF278B: Decay step 2, val = %d, rate = %d, delay = %g, , PRVB = %d, DAMP = %d, current vol = %d\n", slot->D2R, ymf278b_compute_rate(slot, slot->D2R), ymf278_compute_decay_rate(ymf278b_compute_rate(slot, slot->D2R))*1000.0, slot->preverb, slot->DAMP, slot->env_vol >> 23)); LOG(("YMF278B: Decay step 2, val = %d, rate = %d, delay = %g, , PRVB = %d, DAMP = %d, current vol = %d\n", slot->D2R, ymf278b_compute_rate(slot, slot->D2R), ymf278_compute_decay_rate(ymf278b_compute_rate(slot, slot->D2R))*1000.0, slot->preverb, slot->DAMP, slot->env_vol >> 23));
slot->env_vol_step = ymf278_compute_decay_env_vol_step(slot, slot->D2R); slot->env_vol_step = ymf278_compute_decay_env_vol_step(slot, slot->D2R);
slot->env_vol_lim = 256U<<23; slot->env_vol_lim = 256U<<23;
return; break;
}
if(slot->env_step == 3)
{
// Decay 2 reached -96dB // Decay 2 reached -96dB
case 3:
LOG(("YMF278B: Voice cleared because of decay 2\n")); LOG(("YMF278B: Voice cleared because of decay 2\n"));
slot->env_vol = 256U<<23; slot->env_vol = 256U<<23;
slot->env_vol_step = 0; slot->env_vol_step = 0;
slot->env_vol_lim = 0; slot->env_vol_lim = 0;
slot->active = 0; slot->active = 0;
return; break;
}
if(slot->env_step == 4)
{
// Release // Release
case 4:
LOG(("YMF278B: Release, val = %d, rate = %d, delay = %g, PRVB = %d, DAMP = %d\n", slot->RR, ymf278b_compute_rate(slot, slot->RR), ymf278_compute_decay_rate(ymf278b_compute_rate(slot, slot->RR))*1000.0, slot->preverb, slot->DAMP)); LOG(("YMF278B: Release, val = %d, rate = %d, delay = %g, PRVB = %d, DAMP = %d\n", slot->RR, ymf278b_compute_rate(slot, slot->RR), ymf278_compute_decay_rate(ymf278b_compute_rate(slot, slot->RR))*1000.0, slot->preverb, slot->DAMP));
slot->env_vol_step = ymf278_compute_decay_env_vol_step(slot, slot->RR); slot->env_vol_step = ymf278_compute_decay_env_vol_step(slot, slot->RR);
slot->env_vol_lim = 256U<<23; slot->env_vol_lim = 256U<<23;
return; break;
}
if(slot->env_step == 5)
{
// Release reached -96dB // Release reached -96dB
case 5:
LOG(("YMF278B: Release ends\n")); LOG(("YMF278B: Release ends\n"));
slot->env_vol = 256U<<23; slot->env_vol = 256U<<23;
slot->env_vol_step = 0; slot->env_vol_step = 0;
slot->env_vol_lim = 0; slot->env_vol_lim = 0;
slot->active = 0; slot->active = 0;
return; break;
default: break;
} }
} }
@ -857,7 +862,13 @@ READ8_DEVICE_HANDLER( ymf278b_r )
break; break;
} }
// PCM regs (FM regs can't be read) // FM regs can be read too (on contrary to what the datasheet says)
case 1:
case 3:
// but they're not implemented here yet
break;
// PCM regs
case 5: case 5:
// only accessible if NEW2 is set // only accessible if NEW2 is set
if (~chip->exp & 2) if (~chip->exp & 2)