NES: envelope and length counter effects
This commit is contained in:
parent
07f247af12
commit
9a1447e392
6 changed files with 100 additions and 8 deletions
|
|
@ -214,7 +214,7 @@ void DivPlatformNES::tick(bool sysTick) {
|
|||
rWrite(0x4000+i*4,(chan[i].outVol==0)?0:255);
|
||||
chan[i].freqChanged=true;
|
||||
} else {
|
||||
rWrite(0x4000+i*4,0x30|chan[i].outVol|((chan[i].duty&3)<<6));
|
||||
rWrite(0x4000+i*4,(chan[i].envMode<<4)|chan[i].outVol|((chan[i].duty&3)<<6));
|
||||
}
|
||||
}
|
||||
if (chan[i].std.arp.had) {
|
||||
|
|
@ -239,7 +239,7 @@ void DivPlatformNES::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (i!=2) {
|
||||
rWrite(0x4000+i*4,0x30|chan[i].outVol|((chan[i].duty&3)<<6));
|
||||
rWrite(0x4000+i*4,(chan[i].envMode<<4)|chan[i].outVol|((chan[i].duty&3)<<6));
|
||||
}
|
||||
if (i==3) { // noise
|
||||
chan[i].freqChanged=true;
|
||||
|
|
@ -289,11 +289,11 @@ void DivPlatformNES::tick(bool sysTick) {
|
|||
}
|
||||
if (i==3) { // noise
|
||||
rWrite(0x4002+i*4,(chan[i].duty<<7)|chan[i].freq);
|
||||
rWrite(0x4003+i*4,0xf0);
|
||||
rWrite(0x4003+i*4,(chan[i].len<<3));
|
||||
} else {
|
||||
rWrite(0x4002+i*4,chan[i].freq&0xff);
|
||||
if ((chan[i].prevFreq>>8)!=(chan[i].freq>>8) || i==2) {
|
||||
rWrite(0x4003+i*4,0xf8|(chan[i].freq>>8));
|
||||
rWrite(0x4003+i*4,(chan[i].len<<3)|(chan[i].freq>>8));
|
||||
}
|
||||
if (chan[i].freq!=65535 && chan[i].freq!=0) {
|
||||
chan[i].prevFreq=chan[i].freq;
|
||||
|
|
@ -419,7 +419,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
if (c.chan==2) {
|
||||
rWrite(0x4000+c.chan*4,0xff);
|
||||
} else if (!parent->song.brokenOutVol2) {
|
||||
rWrite(0x4000+c.chan*4,0x30|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
|
||||
rWrite(0x4000+c.chan*4,(chan[c.chan].envMode<<4)|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
|
|
@ -451,7 +451,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
if (c.chan==2) {
|
||||
rWrite(0x4000+c.chan*4,0xff);
|
||||
} else {
|
||||
rWrite(0x4000+c.chan*4,0x30|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
|
||||
rWrite(0x4000+c.chan*4,(chan[c.chan].envMode<<4)|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -491,7 +491,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
if (c.chan==3) { // noise
|
||||
chan[c.chan].freqChanged=true;
|
||||
} else if (c.chan<2) {
|
||||
rWrite(0x4000+c.chan*4,0x30|(chan[c.chan].active?chan[c.chan].outVol:0)|((chan[c.chan].duty&3)<<6));
|
||||
rWrite(0x4000+c.chan*4,(chan[c.chan].active?((chan[c.chan].envMode<<4)|chan[c.chan].outVol):0x30)|((chan[c.chan].duty&3)<<6));
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_NES_SWEEP:
|
||||
|
|
@ -507,6 +507,24 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
}
|
||||
rWrite(0x4001+(c.chan*4),chan[c.chan].sweep);
|
||||
break;
|
||||
case DIV_CMD_NES_ENV_MODE:
|
||||
chan[c.chan].envMode=c.value&3;
|
||||
if (c.chan==3) { // noise
|
||||
chan[c.chan].freqChanged=true;
|
||||
} else if (c.chan<2) {
|
||||
rWrite(0x4000+c.chan*4,(chan[c.chan].active?((chan[c.chan].envMode<<4)|chan[c.chan].outVol):0x30)|((chan[c.chan].duty&3)<<6));
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_NES_LENGTH:
|
||||
if (c.chan>=4) break;
|
||||
chan[c.chan].len=c.value&0x1f;
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].prevFreq=-1;
|
||||
break;
|
||||
case DIV_CMD_NES_COUNT_MODE:
|
||||
countMode=c.value;
|
||||
rWrite(0x4017,countMode?0x80:0);
|
||||
break;
|
||||
case DIV_CMD_NES_DMC:
|
||||
rWrite(0x4011,c.value&0x7f);
|
||||
break;
|
||||
|
|
@ -572,6 +590,7 @@ void DivPlatformNES::forceIns() {
|
|||
}
|
||||
rWrite(0x4001,chan[0].sweep);
|
||||
rWrite(0x4005,chan[1].sweep);
|
||||
rWrite(0x4017,countMode?0x80:0);
|
||||
}
|
||||
|
||||
void* DivPlatformNES::getChanState(int ch) {
|
||||
|
|
@ -615,6 +634,7 @@ void DivPlatformNES::reset() {
|
|||
dpcmBank=0;
|
||||
dpcmMode=false;
|
||||
goingToLoop=false;
|
||||
countMode=false;
|
||||
|
||||
if (useNP) {
|
||||
nes1_NP->Reset();
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
class DivPlatformNES: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, pitch2, prevFreq, note, ins;
|
||||
unsigned char duty, sweep;
|
||||
unsigned char duty, sweep, envMode, len;
|
||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, furnaceDac;
|
||||
signed char vol, outVol, wave;
|
||||
DivMacroInt std;
|
||||
|
|
@ -46,6 +46,8 @@ class DivPlatformNES: public DivDispatch {
|
|||
ins(-1),
|
||||
duty(0),
|
||||
sweep(8),
|
||||
envMode(3),
|
||||
len(0x1f),
|
||||
active(false),
|
||||
insChanged(true),
|
||||
freqChanged(false),
|
||||
|
|
@ -74,6 +76,7 @@ class DivPlatformNES: public DivDispatch {
|
|||
bool dacAntiClickOn;
|
||||
bool useNP;
|
||||
bool goingToLoop;
|
||||
bool countMode;
|
||||
struct NESAPU* nes;
|
||||
xgm::NES_APU* nes1_NP;
|
||||
xgm::NES_DMC* nes2_NP;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue