Use raw pitch in envelope column

This commit is contained in:
Kamil Patecki 2025-08-11 23:44:06 +02:00
parent ccd0d676c2
commit f2e2d4e0b4
3 changed files with 29 additions and 6 deletions

View file

@ -674,11 +674,25 @@ void DivPlatformAY8910::tick(bool sysTick) {
ayEnvPeriod=chan[3].std.ex5.val<<8;
}
else if ((chan[3].freqChanged && chan[3].active) || chan[3].keyOn) {
chan[3].freq=parent->calcFreq(chan[3].baseFreq,chan[3].pitch,chan[3].fixedArp?chan[3].baseNoteOverride:chan[3].arpOff,chan[3].fixedArp,true,0,chan[3].pitch2,chipClock*16,CHIP_DIVIDER);
if (chan[3].freq<0) chan[3].freq=0;
if (chan[3].freq>65535*256) chan[3].freq=65535*256;
ayEnvPeriod=chan[3].freq;
chan[3].freqChanged=false;
if (envRawMode) {
// Compute base without pitch2, then apply pitch2 directly to the raw envelope period
int baseFreq=parent->calcFreq(chan[3].baseFreq,chan[3].pitch,chan[3].fixedArp?chan[3].baseNoteOverride:chan[3].arpOff,chan[3].fixedArp,true,0,0,chipClock*16,CHIP_DIVIDER);
if (baseFreq<0) baseFreq=0;
if (baseFreq>65535*256) baseFreq=65535*256;
// Apply pitch2 later as raw offset in the same fixed-point scale (8 fractional bits)
long adjusted=(long)baseFreq + ((long)chan[3].pitch2<<8);
if (adjusted<0) adjusted=0;
if (adjusted>(long)65535*256) adjusted=(long)65535*256;
chan[3].freq=(int)adjusted;
ayEnvPeriod=chan[3].freq;
chan[3].freqChanged=false;
} else {
chan[3].freq=parent->calcFreq(chan[3].baseFreq,chan[3].pitch,chan[3].fixedArp?chan[3].baseNoteOverride:chan[3].arpOff,chan[3].fixedArp,true,0,chan[3].pitch2,chipClock*16,CHIP_DIVIDER);
if (chan[3].freq<0) chan[3].freq=0;
if (chan[3].freq>65535*256) chan[3].freq=65535*256;
ayEnvPeriod=chan[3].freq;
chan[3].freqChanged=false;
}
}
if (chan[3].keyOn) chan[3].keyOn=false;
if (chan[3].keyOff) chan[3].keyOff=false;
@ -1317,6 +1331,7 @@ void DivPlatformAY8910::setFlags(const DivConfig& flags) {
stereo=flags.getBool("stereo",false);
stereoSep=flags.getInt("stereoSep",0)&255;
extendedSsg=false;
envRawMode=flags.getBool("envRawMode",false);
switch (flags.getInt("panLaw",0)) {
case 1:
centerVol=sqrtf((stereoSep+256)/512.f)*256.f;

View file

@ -141,6 +141,10 @@ class DivPlatformAY8910: public DivDispatch {
unsigned char dacRateDiv;
bool stereo, sunsoft, intellivision, clockSel, yamaha;
// When true, the AY "envelope column" uses raw register values instead of
// converting linear pitch/note values into envelope frequency. Intended for
// embedded AY inside chips like YM2203.
bool envRawMode;
bool ioPortA, ioPortB;
unsigned char portAVal, portBVal;
@ -202,6 +206,7 @@ class DivPlatformAY8910: public DivDispatch {
extMode(useExtMode),
extClock(eclk),
extDiv(ediv),
dacRateDiv(ddiv) {}
dacRateDiv(ddiv),
envRawMode(false) {}
};
#endif

View file

@ -1472,6 +1472,9 @@ void DivPlatformYM2203::setFlags(const DivConfig& flags) {
ayFlags.set("stereo",stereo);
ayFlags.set("stereoSep",stereoSep);
ayFlags.set("panLaw",flags.getInt("panLaw",0));
// AY inside YM2203 should treat envelope column values as raw register values
// rather than linear pitch-derived values.
ayFlags.set("envRawMode",true);
if (useCombo==2) {
rate=chipClock/(fmDivBase*2);
} else {