parent
04240ffa46
commit
75ce5f4e2a
|
@ -33,3 +33,8 @@ the chip's powerful sound comes from the envelope...
|
|||
- `24xx`: set envelope period high byte.
|
||||
- `25xx`: slide envelope period up.
|
||||
- `26xx`: slide envelope period down.
|
||||
- `29xy`: enable auto-envelope mode.
|
||||
- in this mode the envelope period is set to the channel's notes, multiplied by a fraction.
|
||||
- `x` is the numerator.
|
||||
- `y` is the denominator.
|
||||
- if `x` or `y` are 0 this will disable auto-envelope mode.
|
|
@ -38,4 +38,9 @@ while emulation of this chip is mostly complete, the additional noise setup regi
|
|||
- `25xx`: slide envelope period up.
|
||||
- `26xx`: slide envelope period down.
|
||||
- `27xx`: set noise AND mask.
|
||||
- `28xx`: set noise OR mask.
|
||||
- `28xx`: set noise OR mask.
|
||||
- `29xy`: enable auto-envelope mode.
|
||||
- in this mode the envelope period is set to the channel's notes, multiplied by a fraction.
|
||||
- `x` is the numerator.
|
||||
- `y` is the denominator.
|
||||
- if `x` or `y` are 0 this will disable auto-envelope mode.
|
|
@ -29,7 +29,7 @@ its soundchip is a 3-in-1: FM, YM2149 (AY-3-8910 clone) and ADPCM in a single pa
|
|||
- `00`: square
|
||||
- `01`: noise
|
||||
- `02`: square and noise
|
||||
- `03`: envelope
|
||||
- `03`: nothing (apparently)
|
||||
- `04`: envelope and square
|
||||
- `05`: envelope and noise
|
||||
- `06`: envelope and square and noise
|
||||
|
@ -52,3 +52,8 @@ its soundchip is a 3-in-1: FM, YM2149 (AY-3-8910 clone) and ADPCM in a single pa
|
|||
- `24xx`: set envelope period high byte.
|
||||
- `25xx`: slide envelope period up.
|
||||
- `26xx`: slide envelope period down.
|
||||
- `29xy`: enable SSG auto-envelope mode.
|
||||
- in this mode the envelope period is set to the channel's notes, multiplied by a fraction.
|
||||
- `x` is the numerator.
|
||||
- `y` is the denominator.
|
||||
- if `x` or `y` are 0 this will disable auto-envelope mode.
|
|
@ -68,6 +68,7 @@ enum DivDispatchCmds {
|
|||
DIV_CMD_AY_ENVELOPE_SLIDE,
|
||||
DIV_CMD_AY_NOISE_MASK_AND,
|
||||
DIV_CMD_AY_NOISE_MASK_OR,
|
||||
DIV_CMD_AY_AUTO_ENVELOPE,
|
||||
|
||||
DIV_CMD_SAA_ENVELOPE,
|
||||
|
||||
|
|
|
@ -82,6 +82,11 @@ void DivPlatformAY8910::tick() {
|
|||
rWrite(1+((i)<<1),chan[i].freq>>8);
|
||||
if (chan[i].keyOn) chan[i].keyOn=false;
|
||||
if (chan[i].keyOff) chan[i].keyOff=false;
|
||||
if (chan[i].freqChanged && chan[i].autoEnvNum>0 && chan[i].autoEnvDen>0) {
|
||||
ayEnvPeriod=(chan[i].freq*chan[i].autoEnvDen/chan[i].autoEnvNum)>>4;
|
||||
immWrite(0x0b,ayEnvPeriod);
|
||||
immWrite(0x0c,ayEnvPeriod>>8);
|
||||
}
|
||||
chan[i].freqChanged=false;
|
||||
}
|
||||
}
|
||||
|
@ -241,6 +246,11 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
|||
case DIV_CMD_AY_ENVELOPE_SLIDE:
|
||||
ayEnvSlide=c.value;
|
||||
break;
|
||||
case DIV_CMD_AY_AUTO_ENVELOPE:
|
||||
chan[c.chan].autoEnvNum=c.value>>4;
|
||||
chan[c.chan].autoEnvDen=c.value&15;
|
||||
chan[c.chan].freqChanged=true;
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
break;
|
||||
|
|
|
@ -10,13 +10,13 @@ class DivPlatformAY8910: public DivDispatch {
|
|||
struct Channel {
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch;
|
||||
unsigned char ins, note, psgMode;
|
||||
unsigned char ins, note, psgMode, autoEnvNum, autoEnvDen;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
|
||||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
DivMacroInt std;
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), ins(-1), note(0), psgMode(1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15), pan(3) {}
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), ins(-1), note(0), psgMode(1), autoEnvNum(0), autoEnvDen(0), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15), pan(3) {}
|
||||
};
|
||||
Channel chan[3];
|
||||
bool isMuted[3];
|
||||
|
|
|
@ -108,6 +108,11 @@ void DivPlatformAY8930::tick() {
|
|||
rWrite(1+((i)<<1),chan[i].freq>>8);
|
||||
if (chan[i].keyOn) chan[i].keyOn=false;
|
||||
if (chan[i].keyOff) chan[i].keyOff=false;
|
||||
if (chan[i].freqChanged && chan[i].autoEnvNum>0 && chan[i].autoEnvDen>0) {
|
||||
ayEnvPeriod[i]=(chan[i].freq*chan[i].autoEnvDen/chan[i].autoEnvNum)>>4;
|
||||
immWrite(regPeriodL[i],ayEnvPeriod[i]);
|
||||
immWrite(regPeriodH[i],ayEnvPeriod[i]>>8);
|
||||
}
|
||||
chan[i].freqChanged=false;
|
||||
}
|
||||
|
||||
|
@ -281,6 +286,11 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
|||
ayNoiseOr=c.value;
|
||||
immWrite(0x1a,ayNoiseOr);
|
||||
break;
|
||||
case DIV_CMD_AY_AUTO_ENVELOPE:
|
||||
chan[c.chan].autoEnvNum=c.value>>4;
|
||||
chan[c.chan].autoEnvDen=c.value&15;
|
||||
chan[c.chan].freqChanged=true;
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
break;
|
||||
|
|
|
@ -10,13 +10,13 @@ class DivPlatformAY8930: public DivDispatch {
|
|||
struct Channel {
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch;
|
||||
unsigned char ins, note, psgMode, duty;
|
||||
unsigned char ins, note, psgMode, autoEnvNum, autoEnvDen, duty;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
|
||||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
DivMacroInt std;
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), ins(-1), note(0), psgMode(1), duty(4), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(31), pan(3) {}
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), ins(-1), note(0), psgMode(1), autoEnvNum(0), autoEnvDen(0), duty(4), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(31), pan(3) {}
|
||||
};
|
||||
Channel chan[3];
|
||||
bool isMuted[3];
|
||||
|
|
|
@ -92,6 +92,11 @@ void DivPlatformYM2610::tick() {
|
|||
rWrite(1+((i-4)<<1),chan[i].freq>>8);
|
||||
if (chan[i].keyOn) chan[i].keyOn=false;
|
||||
if (chan[i].keyOff) chan[i].keyOff=false;
|
||||
if (chan[i].freqChanged && chan[i].autoEnvNum>0 && chan[i].autoEnvDen>0) {
|
||||
ayEnvPeriod=(chan[i].freq*chan[i].autoEnvDen/chan[i].autoEnvNum)>>4;
|
||||
immWrite(0x0b,ayEnvPeriod);
|
||||
immWrite(0x0c,ayEnvPeriod>>8);
|
||||
}
|
||||
chan[i].freqChanged=false;
|
||||
}
|
||||
}
|
||||
|
@ -503,6 +508,12 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
|||
if (c.chan<4 || c.chan>6) break;
|
||||
ayEnvSlide=c.value;
|
||||
break;
|
||||
case DIV_CMD_AY_AUTO_ENVELOPE:
|
||||
if (c.chan<4 || c.chan>6) break;
|
||||
chan[c.chan].autoEnvNum=c.value>>4;
|
||||
chan[c.chan].autoEnvDen=c.value&15;
|
||||
chan[c.chan].freqChanged=true;
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
break;
|
||||
|
|
|
@ -19,13 +19,13 @@ class DivPlatformYM2610: public DivDispatch {
|
|||
struct Channel {
|
||||
unsigned char freqH, freqL;
|
||||
int freq, baseFreq, pitch;
|
||||
unsigned char ins, note, psgMode;
|
||||
unsigned char ins, note, psgMode, autoEnvNum, autoEnvDen;
|
||||
signed char konCycles;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
|
||||
int vol, outVol;
|
||||
unsigned char pan;
|
||||
DivMacroInt std;
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), ins(-1), note(0), psgMode(1), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15), pan(3) {}
|
||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), ins(-1), note(0), psgMode(1), autoEnvNum(0), autoEnvDen(0), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15), pan(3) {}
|
||||
};
|
||||
Channel chan[13];
|
||||
bool isMuted[13];
|
||||
|
|
|
@ -80,6 +80,7 @@ const char* cmdName[DIV_CMD_MAX]={
|
|||
"AY_ENVELOPE_SLIDE",
|
||||
"AY_NOISE_MASK_AND",
|
||||
"AY_NOISE_MASK_OR",
|
||||
"AY_AUTO_ENVELOPE",
|
||||
|
||||
"SAA_ENVELOPE",
|
||||
|
||||
|
@ -286,6 +287,11 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
|||
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,effectVal));
|
||||
}
|
||||
break;
|
||||
case 0x29: // auto-envelope
|
||||
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_AY_AUTO_ENVELOPE,ch,effectVal));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -369,6 +375,9 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
|||
case 0x28: // noise or mask
|
||||
dispatchCmd(DivCommand(DIV_CMD_AY_NOISE_MASK_OR,ch,effectVal));
|
||||
break;
|
||||
case 0x29: // auto-envelope
|
||||
dispatchCmd(DivCommand(DIV_CMD_AY_AUTO_ENVELOPE,ch,effectVal));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_SAA1099:
|
||||
|
|
Loading…
Reference in a new issue