diff --git a/papers/doc/7-systems/nes.md b/papers/doc/7-systems/nes.md index 3de0e307..8ce5d808 100644 --- a/papers/doc/7-systems/nes.md +++ b/papers/doc/7-systems/nes.md @@ -2,10 +2,13 @@ the console from Nintendo that plays Super Mario Bros. and helped revive the agonizing video game market in the US during mid-80s. -also known as Famicom. It is a five-channel PSG: first two channels play pulse wave with three different duty cycles, third is a fixed-volume triangle channel, fourth is a noise channel (can work in both pseudo-random and periodic modes) and fifth is a (D)PCM sample channel +also known as Famicom. It is a five-channel PSG: first two channels play pulse wave with three different duty cycles, third is a fixed-volume triangle channel, fourth is a noise channel (can work in both pseudo-random and periodic modes) and fifth is a (D)PCM sample channel # effects +- `11xx`: write to delta modulation counter. + - this may be used to attenuate the triangle and noise channels. + - will not work if a sample is playing. - `12xx`: set duty cycle or noise mode of channel. - may be 0-3 for the pulse channels and 0-1 for the noise channel. - `13xy`: setup sweep up. @@ -15,4 +18,4 @@ also known as Famicom. It is a five-channel PSG: first two channels play pulse w - `14xy`: setup sweep down. - `x` is the time. - `y` is the shift. - - set to 0 to disable it. + - set to 0 to disable it. \ No newline at end of file diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index d86f1b20..a12ccbfe 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -86,6 +86,7 @@ enum DivDispatchCmds { DIV_CMD_PCE_LFO_SPEED, // (speed) DIV_CMD_NES_SWEEP, // (direction, value) + DIV_CMD_NES_DMC, // (value) DIV_CMD_C64_CUTOFF, // (value) DIV_CMD_C64_RESONANCE, // (value) diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index b61abde0..f7a29066 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -59,6 +59,9 @@ const char** DivPlatformNES::getRegisterSheet() { const char* DivPlatformNES::getEffectName(unsigned char effect) { switch (effect) { + case 0x11: + return "Write to delta modulation counter (0 to 7F)"; + break; case 0x12: return "12xx: Set duty cycle/noise mode (pulse: 0 to 3; noise: 0 or 1)"; break; @@ -420,6 +423,9 @@ int DivPlatformNES::dispatch(DivCommand c) { } rWrite(0x4001+(c.chan*4),chan[c.chan].sweep); break; + case DIV_CMD_NES_DMC: + rWrite(0x4011,c.value&0x7f); + break; case DIV_CMD_SAMPLE_BANK: sampleBank=c.value; if (sampleBank>(parent->song.sample.size()/12)) { diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 5fd03116..29899f0d 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -88,6 +88,7 @@ const char* cmdName[]={ "PCE_LFO_SPEED", "NES_SWEEP", + "NES_DMC", "C64_CUTOFF", "C64_RESONANCE", @@ -317,6 +318,9 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe case DIV_SYSTEM_NES: case DIV_SYSTEM_MMC5: switch (effect) { + case 0x11: // DMC write + dispatchCmd(DivCommand(DIV_CMD_NES_DMC,ch,effectVal)); + break; case 0x12: // duty or noise mode dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); break;