update apu sweep units

This commit is contained in:
retro-wertz 2018-12-09 20:49:46 +08:00
parent 972ec09e92
commit 9788d9745a
1 changed files with 32 additions and 48 deletions

View File

@ -67,6 +67,7 @@ static int32 RectDutyCount[2];
static uint8 sweepon[2];
/*static*/ int32 curfreq[2];
static uint8 SweepCount[2];
static uint8 SweepReload[2];
static uint16 nreg=0;
@ -207,21 +208,14 @@ void LogDPCM(int romaddress, int dpcmsize){
static void SQReload(int x, uint8 V)
{
if(EnabledChannels&(1<<x))
{
if(x)
DoSQ2();
else
DoSQ1();
lengthcount[x]=lengthtable[(V>>3)&0x1f];
}
sweepon[x]=PSG[(x<<2)|1]&0x80;
curfreq[x]=PSG[(x<<2)|0x2]|((V&7)<<8);
SweepCount[x]=((PSG[(x<<2)|0x1]>>4)&7)+1;
/* use the low 8 bits data from pulse period
* instead of from the sweep period */
/* https://forums.nesdev.com/viewtopic.php?t=219&p=1431 */
curfreq[x]=(curfreq[x] & 0xff)|((V&7)<<8);
RectDutyCount[x]=7;
EnvUnits[x].reloaddec=1;
//reloadfreq[x]=1;
}
static DECLFW(Write_PSG)
@ -237,7 +231,9 @@ static DECLFW(Write_PSG)
V = (V&0x3F)|((V&0x80)>>1)|((V&0x40)<<1);
break;
case 0x1:
DoSQ1();
sweepon[0]=V&0x80;
SweepReload[0]=1;
break;
case 0x2:
DoSQ1();
@ -245,6 +241,7 @@ static DECLFW(Write_PSG)
curfreq[0]|=V;
break;
case 0x3:
DoSQ1();
SQReload(0,V);
break;
case 0x4:
@ -255,7 +252,9 @@ static DECLFW(Write_PSG)
V = (V&0x3F)|((V&0x80)>>1)|((V&0x40)<<1);
break;
case 0x5:
DoSQ2();
sweepon[1]=V&0x80;
SweepReload[1]=1;
break;
case 0x6:
DoSQ2();
@ -263,6 +262,7 @@ static DECLFW(Write_PSG)
curfreq[1]|=V;
break;
case 0x7:
DoSQ2();
SQReload(1,V);
break;
case 0xa:
@ -421,44 +421,28 @@ static void FrameSoundStuff(int V)
/* Frequency Sweep Code Here */
/* xxxx 0000 */
/* xxxx = hz. 120/(x+1)*/
if(sweepon[P])
/* http://wiki.nesdev.com/w/index.php/APU_Sweep */
/* https://forums.nesdev.com/viewtopic.php?t=219&p=1431 */
if (SweepCount[P] > 0) SweepCount[P]--;
if (SweepCount[P] <= 0)
{
int32 mod=0;
int sweepShift = (PSG[(P << 2) + 0x1] & 7);
if (sweepon[P] && sweepShift && curfreq[P] >= 8)
{
int32 mod = (curfreq[P] >> sweepShift);
if (PSG[(P << 2) + 0x1] & 0x8)
curfreq[P] -= (mod + (P ^ 1));
else if ((mod + curfreq[P]) < 0x800)
curfreq[P] += mod;
}
if(SweepCount[P]>0) SweepCount[P]--;
if(SweepCount[P]<=0)
{
SweepCount[P]=((PSG[(P<<2)+0x1]>>4)&7)+1; //+1;
if(PSG[(P<<2)+0x1]&0x8)
{
mod-=(P^1)+((curfreq[P])>>(PSG[(P<<2)+0x1]&7));
if(curfreq[P] && (PSG[(P<<2)+0x1]&7)/* && sweepon[P]&0x80*/)
{
curfreq[P]+=mod;
SweepCount[P] = (((PSG[(P << 2) + 0x1] >> 4) & 7) + 1);
}
}
else
if (SweepReload[P])
{
mod=curfreq[P]>>(PSG[(P<<2)+0x1]&7);
if((mod+curfreq[P])&0x800)
{
sweepon[P]=0;
// curfreq[P]=0; // fixes R.C.Pro Am II title music
}
else
{
if(curfreq[P] && (PSG[(P<<2)+0x1]&7)/* && sweepon[P]&0x80*/)
{
curfreq[P]+=mod;
}
}
}
}
}
else /* Sweeping is disabled: */
{
//curfreq[P]&=0xFF00;
//curfreq[P]|=PSG[(P<<2)|0x2]; //|((PSG[(P<<2)|3]&7)<<8);
SweepCount[P] = (((PSG[(P << 2) + 0x1] >> 4) & 7) + 1);
SweepReload[P] = 0;
}
}
}