Update apu sweep unit
- http://wiki.nesdev.com/w/index.php/APU_Sweep - APU sweep test roms: https://forums.nesdev.com/viewtopic.php?t=219&p=1403 - Fixes R.C. Pro AM II intro music
This commit is contained in:
56
src/sound.c
56
src/sound.c
@@ -70,6 +70,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;
|
||||
|
||||
@@ -183,13 +184,9 @@ static void SQReload(int x, uint8 V) {
|
||||
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;
|
||||
|
||||
curfreq[x] = curfreq[x] & 0xff | ((V & 7) << 8);
|
||||
RectDutyCount[x] = 7;
|
||||
EnvUnits[x].reloaddec = 1;
|
||||
/* reloadfreq[x]=1; */
|
||||
}
|
||||
|
||||
static DECLFW(Write_PSG) {
|
||||
@@ -204,7 +201,9 @@ static DECLFW(Write_PSG) {
|
||||
V = (V & 0x3F) | ((V & 0x80) >> 1) | ((V & 0x40) << 1);
|
||||
break;
|
||||
case 0x1:
|
||||
sweepon[0] = V & 0x80;
|
||||
DoSQ1();
|
||||
sweepReload[0] = 1;
|
||||
sweepon[0] = (V & 0x80);
|
||||
break;
|
||||
case 0x2:
|
||||
DoSQ1();
|
||||
@@ -222,7 +221,9 @@ static DECLFW(Write_PSG) {
|
||||
V = (V & 0x3F) | ((V & 0x80) >> 1) | ((V & 0x40) << 1);
|
||||
break;
|
||||
case 0x5:
|
||||
sweepon[1] = V & 0x80;
|
||||
DoSQ2();
|
||||
sweepReload[1] = 1;
|
||||
sweepon[1] = (V & 0x80);
|
||||
break;
|
||||
case 0x6:
|
||||
DoSQ2();
|
||||
@@ -371,34 +372,25 @@ static void FASTAPASS(1) FrameSoundStuff(int V) {
|
||||
/* Frequency Sweep Code Here */
|
||||
/* xxxx 0000 */
|
||||
/* xxxx = hz. 120/(x+1)*/
|
||||
if (sweepon[P]) {
|
||||
int32 mod = 0;
|
||||
|
||||
if (SweepCount[P] > 0) SweepCount[P]--;
|
||||
if (SweepCount[P] <= 0) {
|
||||
SweepCount[P] = ((PSG[(P << 2) + 0x1] >> 4) & 7) + 1; /* +1; */
|
||||
/* http://wiki.nesdev.com/w/index.php/APU_Sweep */
|
||||
if (SweepCount[P] > 0) SweepCount[P]--;
|
||||
if (SweepCount[P] <= 0) {
|
||||
uint32 sweepShift = (PSG[(P << 2) + 0x1] & 7);
|
||||
if (sweepon[P] && sweepShift && curfreq[P] >= 8) {
|
||||
int32 mod = (curfreq[P] >> sweepShift);
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
mod = curfreq[P] >> (PSG[(P << 2) + 0x1] & 7);
|
||||
if ((mod + curfreq[P]) & 0x800) {
|
||||
sweepon[P] = 0;
|
||||
curfreq[P] = 0;
|
||||
} else {
|
||||
if (curfreq[P] && (PSG[(P << 2) + 0x1] & 7) /* && sweepon[P]&0x80*/) {
|
||||
curfreq[P] += mod;
|
||||
}
|
||||
}
|
||||
curfreq[P] -= (mod + (P ^ 1));
|
||||
} else if ((mod + curfreq[P]) < 0x800) {
|
||||
curfreq[P] += mod;
|
||||
}
|
||||
}
|
||||
} else {/* Sweeping is disabled: */
|
||||
#if 0
|
||||
curfreq[P]&=0xFF00;
|
||||
curfreq[P]|=PSG[(P<<2)|0x2]; /* |((PSG[(P<<2)|3]&7)<<8); */
|
||||
#endif
|
||||
|
||||
SweepCount[P] = (((PSG[(P << 2) + 0x1] >> 4) & 7) + 1);
|
||||
}
|
||||
|
||||
if (sweepReload[P]) {
|
||||
SweepCount[P] = (((PSG[(P << 2) + 0x1] >> 4) & 7) + 1);
|
||||
sweepReload[P] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user