| 395 | } |
| 396 | |
| 397 | static void FrameSoundStuff(int V) |
| 398 | { |
| 399 | int P; |
| 400 | |
| 401 | DoSQ1(); |
| 402 | DoSQ2(); |
| 403 | DoNoise(); |
| 404 | DoTriangle(); |
| 405 | |
| 406 | if(!(V&1)) /* Envelope decay, linear counter, length counter, freq sweep */ |
| 407 | { |
| 408 | if(!(PSG[8]&0x80)) |
| 409 | if(lengthcount[2]>0) |
| 410 | lengthcount[2]--; |
| 411 | |
| 412 | if(!(PSG[0xC]&0x20)) /* Make sure loop flag is not set. */ |
| 413 | if(lengthcount[3]>0) |
| 414 | lengthcount[3]--; |
| 415 | |
| 416 | for(P=0;P<2;P++) |
| 417 | { |
| 418 | if(!(PSG[P<<2]&0x20)) /* Make sure loop flag is not set. */ |
| 419 | if(lengthcount[P]>0) |
| 420 | lengthcount[P]--; |
| 421 | |
| 422 | /* Frequency Sweep Code Here */ |
| 423 | /* xxxx 0000 */ |
| 424 | /* xxxx = hz. 120/(x+1)*/ |
| 425 | /* http://wiki.nesdev.com/w/index.php/APU_Sweep */ |
| 426 | /* https://forums.nesdev.com/viewtopic.php?t=219&p=1431 */ |
| 427 | if (SweepCount[P] > 0) SweepCount[P]--; |
| 428 | if (SweepCount[P] <= 0) |
| 429 | { |
| 430 | int sweepShift = (PSG[(P << 2) + 0x1] & 7); |
| 431 | if (sweepon[P] && sweepShift && curfreq[P] >= 8) |
| 432 | { |
| 433 | int32 mod = (curfreq[P] >> sweepShift); |
| 434 | if (PSG[(P << 2) + 0x1] & 0x8) |
| 435 | curfreq[P] -= (mod + (P ^ 1)); |
| 436 | else if ((mod + curfreq[P]) < 0x800) |
| 437 | curfreq[P] += mod; |
| 438 | } |
| 439 | |
| 440 | SweepCount[P] = (((PSG[(P << 2) + 0x1] >> 4) & 7) + 1); |
| 441 | } |
| 442 | |
| 443 | if (SweepReload[P]) |
| 444 | { |
| 445 | SweepCount[P] = (((PSG[(P << 2) + 0x1] >> 4) & 7) + 1); |
| 446 | SweepReload[P] = 0; |
| 447 | } |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | /* Now do envelope decay + linear counter. */ |
| 452 | |
| 453 | if(TriMode) // In load mode? |
| 454 | TriCount=PSG[0x8]&0x7F; |