Page 1 of 1
APU sweep unit
Posted: Tue Apr 15, 2014 11:13 am
by Anes
I tought my sweep unit was ok, but after testing "Excitebike" in a real NES when the bike "jumps" a platform and use sweep unit my emulator is not correctly emulating it.
The code im using to emulate the sweep is this:
Code: Select all
void ClockSweep(PSWEEP PSweep, PPROGTIMER pTimer, int add)
{
u16 result;
if (PSweep->negate)
result = pTimer->reload_value - (pTimer->reload_value >> PSweep->shift) + add;
else
result = pTimer->reload_value + (pTimer->reload_value >> PSweep->shift) + add;
if (PSweep->divider == 0)
{
PSweep->dac = 1;
if ((pTimer->reload_value < 8) || (result > 0x7FF && !PSweep->negate))
PSweep->dac = 0;
else
if (PSweep->enable && PSweep->shift)
{
pTimer->reload_value = result;
}
PSweep->divider = PSweep->period ;
}
else if (PSweep->divider)
PSweep->divider--;
if (PSweep->write)
{
PSweep->divider = PSweep->period ;
PSweep->write = 0;
}
}
It always confused me Sweep Unit.
Any help??
Re: APU sweep unit
Posted: Tue Apr 15, 2014 11:33 am
by Quietust
I can only assume that your problem is that it doesn't sound quite right - assuming that the "add" parameter is to handle the difference between the two sweep units (i.e. where one uses two's complement negation while the other uses one's complement negation), you should only be including that when subtracting, NOT when adding.
If that isn't the problem, then you need to provide more information.
Re: APU sweep unit
Posted: Tue Apr 15, 2014 11:37 am
by Grapeshot
You should be doing
Code: Select all
result = pTimer->reload_value + (pTimer->reload_value >> PSweep->shift);
when the negate flag is off. Also I'm not sure if you're silencing it correctly.
Re: APU sweep unit
Posted: Tue Apr 15, 2014 11:55 am
by Anes
Grapeshot wrote:You should be doing
Code: Select all
result = pTimer->reload_value + (pTimer->reload_value >> PSweep->shift);
when the negate flag is off. Also I'm not sure if you're silencing it correctly.
But if we take into account:
Code: Select all
if (PSweep->negate)
result = pTimer->reload_value - (pTimer->reload_value >> PSweep->shift) - add;
else
result = pTimer->reload_value + (pTimer->reload_value >> PSweep->shift) + add;
the "else" is doing just what you say.
Then talking about silencing the routine that process sound output in my emu for a square channel is:
Code: Select all
if (Apu.Square.Len.counter && Apu.Square.Sweep.dac && Apu.Square.Duty.dac)
if (Apu.Square.Env.env_disable)
out += Apu.Square.Env.env_volume;
else
out += Apu.Square.Env.out;
isn't that correct?
Re: APU sweep unit
Posted: Tue Apr 15, 2014 2:05 pm
by cpow
Anes wrote:Grapeshot wrote:
result = pTimer->reload_value + (pTimer->reload_value >> PSweep->shift);
if (PSweep->negate)
result = pTimer->reload_value - (pTimer->reload_value >> PSweep->shift) - add;
else
result = pTimer->reload_value + (pTimer->reload_value >> PSweep->shift)
+ add;
the "else" is doing just what you say.
Is it?
Anes wrote:
Then talking about silencing the routine that process sound output in my emu for a square channel is:
Code: Select all
if (Apu.Square.Len.counter && Apu.Square.Sweep.dac && Apu.Square.Duty.dac)
if (Apu.Square.Env.env_disable)
out += Apu.Square.Env.env_volume;
else
out += Apu.Square.Env.out;
isn't that correct?
I don't think so...the DAC value isn't an "input" to whether or not the channel is silenced, if I recall.
Re: APU sweep unit
Posted: Tue Apr 15, 2014 3:28 pm
by Anes
cpow wrote:I don't think so...the DAC value isn't an "input" to whether or not the channel is silenced, if I recall.
So how does it do to silence the channel?