AY/8930: implement tone and env period macros

This commit is contained in:
tildearrow 2024-07-05 16:18:08 -05:00
parent e495c8d990
commit 8f577fb669
5 changed files with 45 additions and 6 deletions

View file

@ -360,6 +360,15 @@ void DivPlatformAY8910::tick(bool sysTick) {
chan[i].freqChanged=true;
if (!chan[i].std.ex3.will) chan[i].autoEnvNum=1;
}
if (chan[i].std.ex4.had) {
chan[i].fixedFreq=chan[i].std.ex4.val;
chan[i].freqChanged=true;
}
if (chan[i].std.ex5.had) {
ayEnvPeriod=chan[i].std.ex5.val;
immWrite(0x0b,ayEnvPeriod);
immWrite(0x0c,ayEnvPeriod>>8);
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
if (chan[i].dac.furnaceDAC) {
@ -377,6 +386,7 @@ void DivPlatformAY8910::tick(bool sysTick) {
}
if (chan[i].freq<0) chan[i].freq=0;
if (chan[i].freq>4095) chan[i].freq=4095;
if (chan[i].fixedFreq>4095) chan[i].fixedFreq=4095;
if (chan[i].keyOn) {
//rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(ins->gb.soundLen&63)));
//rWrite(16+i*5+2,((chan[i].vol<<4))|(ins->gb.envLen&7)|((ins->gb.envDir&1)<<3));
@ -388,8 +398,13 @@ void DivPlatformAY8910::tick(bool sysTick) {
chan[i].curPSGMode.val=0;
rWrite(0x08+i,0);
}
rWrite((i)<<1,chan[i].freq&0xff);
rWrite(1+((i)<<1),chan[i].freq>>8);
if (chan[i].fixedFreq>0) {
rWrite((i)<<1,chan[i].fixedFreq&0xff);
rWrite(1+((i)<<1),chan[i].fixedFreq>>8);
} else {
rWrite((i)<<1,chan[i].freq&0xff);
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) {
@ -516,6 +531,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value;
}
chan[c.chan].fixedFreq=0;
chan[c.chan].active=true;
chan[c.chan].keyOn=true;
chan[c.chan].macroInit(ins);

View file

@ -74,6 +74,7 @@ class DivPlatformAY8910: public DivDispatch {
unsigned char autoEnvNum, autoEnvDen;
signed char konCycles;
unsigned short fixedFreq;
Channel():
SharedChannel<int>(15),
curPSGMode(PSGMode(0)),
@ -81,7 +82,8 @@ class DivPlatformAY8910: public DivDispatch {
dac(DAC()),
autoEnvNum(0),
autoEnvDen(0),
konCycles(0) {}
konCycles(0),
fixedFreq(0) {}
};
Channel chan[3];
bool isMuted[3];

View file

@ -323,6 +323,15 @@ void DivPlatformAY8930::tick(bool sysTick) {
ayNoiseOr=chan[i].std.fms.val;
immWrite(0x1a,ayNoiseOr);
}
if (chan[i].std.ex4.had) {
chan[i].fixedFreq=chan[i].std.ex4.val;
chan[i].freqChanged=true;
}
if (chan[i].std.ex5.had) {
chan[i].envelope.period=chan[i].std.ex5.val;
immWrite(regPeriodL[i],chan[i].envelope.period);
immWrite(regPeriodH[i],chan[i].envelope.period>>8);
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
if (chan[i].dac.furnaceDAC) {
@ -353,8 +362,13 @@ void DivPlatformAY8930::tick(bool sysTick) {
chan[i].curPSGMode.val=0;
rWrite(0x08+i,0);
}
rWrite((i)<<1,chan[i].freq&0xff);
rWrite(1+((i)<<1),chan[i].freq>>8);
if (chan[i].fixedFreq>0) {
rWrite((i)<<1,chan[i].fixedFreq&0xff);
rWrite(1+((i)<<1),chan[i].fixedFreq>>8);
} else {
rWrite((i)<<1,chan[i].freq&0xff);
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) {
@ -504,6 +518,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value;
}
chan[c.chan].fixedFreq=0;
chan[c.chan].active=true;
chan[c.chan].keyOn=true;
chan[c.chan].macroInit(ins);

View file

@ -79,6 +79,7 @@ class DivPlatformAY8930: public DivDispatch {
unsigned char autoEnvNum, autoEnvDen, duty, autoNoiseMode;
signed char konCycles, autoNoiseOff;
unsigned short fixedFreq;
Channel():
SharedChannel<int>(31),
envelope(Envelope()),
@ -90,7 +91,8 @@ class DivPlatformAY8930: public DivDispatch {
duty(4),
autoNoiseMode(0),
konCycles(0),
autoNoiseOff(0) {}
autoNoiseOff(0),
fixedFreq(0) {}
};
Channel chan[3];
bool isMuted[3];

View file

@ -7000,6 +7000,8 @@ void FurnaceGUI::drawInsEdit() {
macroList.push_back(FurnaceGUIMacroDesc(_("Envelope"),&ins->std.ex2Macro,0,4,64,uiColors[GUI_COLOR_MACRO_ENVELOPE],false,NULL,NULL,true,ayEnvBits));
macroList.push_back(FurnaceGUIMacroDesc(_("AutoEnv Num"),&ins->std.ex3Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("AutoEnv Den"),&ins->std.algMacro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Force Period"),&ins->std.ex4Macro,0,4095,160,uiColors[GUI_COLOR_MACRO_PITCH]));
macroList.push_back(FurnaceGUIMacroDesc(_("Env Period"),&ins->std.ex5Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
break;
case DIV_INS_AY8930:
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
@ -7014,6 +7016,8 @@ void FurnaceGUI::drawInsEdit() {
macroList.push_back(FurnaceGUIMacroDesc(_("Envelope"),&ins->std.ex2Macro,0,4,64,uiColors[GUI_COLOR_MACRO_ENVELOPE],false,NULL,NULL,true,ayEnvBits));
macroList.push_back(FurnaceGUIMacroDesc(_("AutoEnv Num"),&ins->std.ex3Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("AutoEnv Den"),&ins->std.algMacro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Force Period"),&ins->std.ex4Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_PITCH]));
macroList.push_back(FurnaceGUIMacroDesc(_("Env Period"),&ins->std.ex5Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise AND Mask"),&ins->std.fbMacro,0,8,96,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(_("Noise OR Mask"),&ins->std.fmsMacro,0,8,96,uiColors[GUI_COLOR_MACRO_NOISE],false,NULL,NULL,true));
break;