diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 12171b162..68e25740a 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -362,6 +362,29 @@ void DivPlatformAY8930::tick(bool sysTick) { immWrite(regPeriodL[i],chan[i].envelope.period); immWrite(regPeriodH[i],chan[i].envelope.period>>8); } + if (chan[i].freqChanged && chan[i].autoNoiseMode) { + int noiseFreq=chan[i].freq; + switch (chan[i].autoNoiseMode) { + case 1: // noise + noiseFreq+=chan[i].autoNoiseOff; + if (noiseFreq<0) noiseFreq=0; + if (noiseFreq>255) noiseFreq=255; + rWrite(0x06,noiseFreq); + break; + case 2: { // noise + OR mask + if (noiseFreq<0) noiseFreq=0; + int noiseDiv=(noiseFreq>>8)+1; + noiseFreq/=noiseDiv; + ayNoiseOr=noiseDiv; + immWrite(0x1a,ayNoiseOr); + noiseFreq+=chan[i].autoNoiseOff; + if (noiseFreq<0) noiseFreq=0; + if (noiseFreq>255) noiseFreq=255; + rWrite(0x06,noiseFreq); + break; + } + } + } chan[i].freqChanged=false; } @@ -632,6 +655,12 @@ int DivPlatformAY8930::dispatch(DivCommand c) { chan[c.chan].autoEnvDen=c.value&15; chan[c.chan].freqChanged=true; break; + case DIV_CMD_AY_AUTO_PWM: + chan[c.chan].autoNoiseMode=c.value>>4; + chan[c.chan].autoNoiseOff=c.value&15; + if (chan[c.chan].autoNoiseOff>=8) chan[c.chan].autoNoiseOff-=16; + chan[c.chan].freqChanged=true; + break; case DIV_CMD_AY_IO_WRITE: if (c.value==255) { immWrite(0x1f,c.value2); diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index 457601848..e9f3cf21e 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -77,8 +77,8 @@ class DivPlatformAY8930: public DivDispatch { setPos(false) {} } dac; - unsigned char autoEnvNum, autoEnvDen, duty; - signed char konCycles; + unsigned char autoEnvNum, autoEnvDen, duty, autoNoiseMode; + signed char konCycles, autoNoiseOff; Channel(): SharedChannel(31), envelope(Envelope()), @@ -88,7 +88,9 @@ class DivPlatformAY8930: public DivDispatch { autoEnvNum(0), autoEnvDen(0), duty(4), - konCycles(0) {} + autoNoiseMode(0), + konCycles(0), + autoNoiseOff(0) {} }; Channel chan[3]; bool isMuted[3]; diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index dd05313ba..45e0bb52a 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -452,6 +452,7 @@ void DivEngine::registerSystems() { [](unsigned char, unsigned char val) -> int { return 0x10+(val&15); }}}, {0x27, {DIV_CMD_AY_NOISE_MASK_AND, "27xx: Set noise AND mask"}}, {0x28, {DIV_CMD_AY_NOISE_MASK_OR, "28xx: Set noise OR mask"}}, + {0x2c, {DIV_CMD_AY_AUTO_PWM, "2Cxy: Automatic noise frequency (x: mode (0: disable, 1: freq, 2: freq + OR mask); y: offset"}}, {0x2d, {DIV_CMD_AY_IO_WRITE, "2Dxx: NOT TO BE EMPLOYED BY THE COMPOSER", constVal<255>, effectVal}}, };