ES5506: Fix sample direction

This commit is contained in:
cam900 2025-06-02 16:38:15 +09:00
parent 7929cecb9d
commit ece9dd83c7
3 changed files with 47 additions and 23 deletions

View file

@ -340,9 +340,11 @@ void DivPlatformES5506::updateNoteChangesAsNeeded(int ch) {
void DivPlatformES5506::tick(bool sysTick) { void DivPlatformES5506::tick(bool sysTick) {
for (int i=0; i<=chanMax; i++) { for (int i=0; i<=chanMax; i++) {
if (chan[i].crDirValInit) {
chan[i].crDirVal=es5506.regs_r(i,0,false)&0x41;
chan[i].crDirValInit=false;
}
chan[i].std.next(); chan[i].std.next();
bool crChanged=false;
unsigned short crWriteVal=chan[i].cr;
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_ES5506); DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_ES5506);
signed int k1=chan[i].k1Prev,k2=chan[i].k2Prev; signed int k1=chan[i].k1Prev,k2=chan[i].k2Prev;
// volume/panning macros // volume/panning macros
@ -513,15 +515,17 @@ void DivPlatformES5506::tick(bool sysTick) {
if (chan[i].pcm.pause!=(bool)(chan[i].std.alg.val&1)) { if (chan[i].pcm.pause!=(bool)(chan[i].std.alg.val&1)) {
chan[i].pcm.pause=chan[i].std.alg.val&1; chan[i].pcm.pause=chan[i].std.alg.val&1;
if (!chan[i].keyOn) { if (!chan[i].keyOn) {
crWriteVal=(crWriteVal&~0x0002)|(chan[i].pcm.pause?0x0002:0x0000); chan[i].crWriteVal=(chan[i].crWriteVal&~0x41)|chan[i].crDirVal;
crChanged=true; chan[i].crWriteVal=(chan[i].crWriteVal&~0x0002)|(chan[i].pcm.pause?0x0002:0x0000);
chan[i].crChanged=true;
} }
} }
if (chan[i].pcm.direction!=(bool)(chan[i].std.alg.val&2)) { if (chan[i].pcm.direction!=(bool)(chan[i].std.alg.val&2)) {
chan[i].pcm.direction=chan[i].std.alg.val&2; chan[i].pcm.direction=chan[i].std.alg.val&2;
if (!chan[i].keyOn) { if (!chan[i].keyOn) {
crWriteVal=(crWriteVal&~0x0040)|(chan[i].pcm.direction?0x0040:0x0000); chan[i].crDirVal=(chan[i].crDirVal&~0x0040)|(chan[i].pcm.direction?0x0040:0x0000);
crChanged=true; chan[i].crWriteVal=(chan[i].crWriteVal&~0x41)|chan[i].crDirVal;
chan[i].crChanged=true;
} }
} }
} }
@ -555,8 +559,9 @@ void DivPlatformES5506::tick(bool sysTick) {
} }
} }
if (chan[i].volChanged.ca) { if (chan[i].volChanged.ca) {
crWriteVal=(crWriteVal&~0x1c00)|(chan[i].ca<<10); chan[i].crWriteVal=(chan[i].crWriteVal&~0x41)|chan[i].crDirVal;
crChanged=true; chan[i].crWriteVal=(chan[i].crWriteVal&~0x1c00)|(chan[i].ca<<10);
chan[i].crChanged=true;
} }
chan[i].volChanged.changed=0; chan[i].volChanged.changed=0;
} }
@ -665,8 +670,10 @@ void DivPlatformES5506::tick(bool sysTick) {
break; break;
} }
// Set loop mode & Bank // Set loop mode & Bank
crWriteVal=(crWriteVal&~0xe0fd)|loopFlag; chan[i].crDirVal=(chan[i].crDirVal&~0x0040)|(chan[i].pcm.direction?0x0040:0x0000);
crChanged=true; chan[i].crWriteVal=(chan[i].crWriteVal&~0x41)|chan[i].crDirVal;
chan[i].crWriteVal=(chan[i].crWriteVal&~0xe0fd)|loopFlag;
chan[i].crChanged=true;
} }
chan[i].pcmChanged.loopBank=0; chan[i].pcmChanged.loopBank=0;
} }
@ -675,8 +682,9 @@ void DivPlatformES5506::tick(bool sysTick) {
if (chan[i].filterChanged.changed) { if (chan[i].filterChanged.changed) {
if (!chan[i].keyOn) { if (!chan[i].keyOn) {
if (chan[i].filterChanged.mode) { if (chan[i].filterChanged.mode) {
crWriteVal=(crWriteVal&~0x0300)|(chan[i].filter.mode<<8); chan[i].crWriteVal=(chan[i].crWriteVal&~0x41)|chan[i].crDirVal;
crChanged=true; chan[i].crWriteVal=(chan[i].crWriteVal&~0x0300)|(chan[i].filter.mode<<8);
chan[i].crChanged=true;
} }
if (chan[i].filterChanged.k2) { if (chan[i].filterChanged.k2) {
if (chan[i].std.ex2.mode!=0) { // Relative if (chan[i].std.ex2.mode!=0) { // Relative
@ -810,8 +818,8 @@ void DivPlatformES5506::tick(bool sysTick) {
pageWrite(0x00|i,0x0a,((unsigned char)(chan[i].envelope.k1Ramp)<<8)|(chan[i].envelope.k1Slow?1:0)); pageWrite(0x00|i,0x0a,((unsigned char)(chan[i].envelope.k1Ramp)<<8)|(chan[i].envelope.k1Slow?1:0));
pageWrite(0x00|i,0x08,((unsigned char)(chan[i].envelope.k2Ramp)<<8)|(chan[i].envelope.k2Slow?1:0)); pageWrite(0x00|i,0x08,((unsigned char)(chan[i].envelope.k2Ramp)<<8)|(chan[i].envelope.k2Slow?1:0));
// initialize filter // initialize filter
crWriteVal=(crWriteVal&~0xc300)|((chan[i].pcm.bank<<14)|(chan[i].filter.mode<<8)); chan[i].crWriteVal=(chan[i].crWriteVal&~0xc300)|((chan[i].pcm.bank<<14)|(chan[i].filter.mode<<8));
crChanged=true; chan[i].crChanged=true;
if ((chan[i].std.ex2.mode!=0) && (chan[i].std.ex2.had)) { if ((chan[i].std.ex2.mode!=0) && (chan[i].std.ex2.had)) {
k2=CLAMP(chan[i].filter.k2+chan[i].k2Offs,0,65535); k2=CLAMP(chan[i].filter.k2+chan[i].k2Offs,0,65535);
} else { } else {
@ -851,14 +859,16 @@ void DivPlatformES5506::tick(bool sysTick) {
loopFlag|=0x0002; loopFlag|=0x0002;
} }
// Run sample // Run sample
crWriteVal=(crWriteVal&~0x3cff)|loopFlag; chan[i].crDirVal=(chan[i].crDirVal&~0x0040)|(chan[i].pcm.direction?0x0040:0x0000);
crChanged=true; chan[i].crWriteVal=(chan[i].crWriteVal&~0x41)|chan[i].crDirVal;
chan[i].crWriteVal=(chan[i].crWriteVal&~0x3cff)|loopFlag;
chan[i].crChanged=true;
pageWrite(0x00|i,0x06,(unsigned int)chan[i].envelope.ecount); // Clear ECOUNT pageWrite(0x00|i,0x06,(unsigned int)chan[i].envelope.ecount); // Clear ECOUNT
} }
} }
if (chan[i].keyOff) { if (chan[i].keyOff) {
crWriteVal=0x0303; chan[i].crWriteVal=0x0303;
crChanged=true; chan[i].crChanged=true;
crWrite(0x00|i,0x0303); // Wipeout CR crWrite(0x00|i,0x0303); // Wipeout CR
} else if (!chan[i].keyOn && chan[i].active) { } else if (!chan[i].keyOn && chan[i].active) {
pageWrite(0x00|i,0x01,chan[i].freq); pageWrite(0x00|i,0x01,chan[i].freq);
@ -877,8 +887,10 @@ void DivPlatformES5506::tick(bool sysTick) {
chan[i].k1Prev=k1; chan[i].k1Prev=k1;
} }
} }
if (crChanged) { if (chan[i].crChanged) {
crWrite(0x00|i,crWriteVal); crWrite(0x00|i,chan[i].crWriteVal);
chan[i].crChanged=false;
chan[i].crDirValInit=true;
} }
} }
} }
@ -1181,7 +1193,9 @@ int DivPlatformES5506::dispatch(DivCommand c) {
if (chan[c.chan].active) { if (chan[c.chan].active) {
if (chan[c.chan].pcm.pause!=(bool)(c.value&1)) { if (chan[c.chan].pcm.pause!=(bool)(c.value&1)) {
chan[c.chan].pcm.pause=c.value&1; chan[c.chan].pcm.pause=c.value&1;
crWriteMask(0x00|c.chan,chan[c.chan].pcm.pause?0x0002:0x0000,0x0002); chan[c.chan].crWriteVal=(chan[c.chan].crWriteVal&~0x41)|chan[c.chan].crDirVal;
chan[c.chan].crWriteVal=(chan[c.chan].crWriteVal&~0x0002)|(chan[c.chan].pcm.pause?0x0002:0x0000);
chan[c.chan].crChanged=true;
} }
} }
break; break;
@ -1237,7 +1251,9 @@ int DivPlatformES5506::dispatch(DivCommand c) {
case DIV_CMD_SAMPLE_DIR: { case DIV_CMD_SAMPLE_DIR: {
if (chan[c.chan].pcm.direction!=(bool)(c.value&1)) { if (chan[c.chan].pcm.direction!=(bool)(c.value&1)) {
chan[c.chan].pcm.direction=c.value&1; chan[c.chan].pcm.direction=c.value&1;
crWriteMask(0x00|c.chan,chan[c.chan].pcm.direction?0x0040:0x0000,0x0040); chan[c.chan].crDirVal=(chan[c.chan].crDirVal&~0x0040)|(chan[c.chan].pcm.direction?0x0040:0x0000);
chan[c.chan].crWriteVal=(chan[c.chan].crWriteVal&~0x41)|chan[c.chan].crDirVal;
chan[c.chan].crChanged=true;
} }
break; break;
} }

View file

@ -67,7 +67,8 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
int nextFreq, nextNote, currNote, wave; int nextFreq, nextNote, currNote, wave;
int volMacroMax, panMacroMax; int volMacroMax, panMacroMax;
bool useWave, isReverseLoop; bool useWave, isReverseLoop;
unsigned short cr; unsigned short cr, crWriteVal, crDirVal;
bool crChanged, crDirValInit;
struct NoteChanged { // Note changed flags struct NoteChanged { // Note changed flags
union { // pack flag bits in single byte union { // pack flag bits in single byte
@ -197,6 +198,9 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
useWave(false), useWave(false),
isReverseLoop(false), isReverseLoop(false),
cr(0), cr(0),
crWriteVal(0),
crChanged(false),
crDirValInit(true),
noteChanged(NoteChanged()), noteChanged(NoteChanged()),
volChanged(VolChanged()), volChanged(VolChanged()),
filterChanged(FilterChanged()), filterChanged(FilterChanged()),

View file

@ -884,6 +884,8 @@ void putDispatchChan(void* data, int chanNum, int type) {
ImGui::Text("- VolMacroMax: %d",ch->volMacroMax); ImGui::Text("- VolMacroMax: %d",ch->volMacroMax);
ImGui::Text("- PanMacroMax: %d",ch->panMacroMax); ImGui::Text("- PanMacroMax: %d",ch->panMacroMax);
ImGui::Text("- CR: %.4x",ch->cr); ImGui::Text("- CR: %.4x",ch->cr);
ImGui::Text("- CRWriteVal: %.4x",ch->crWriteVal);
ImGui::Text("- CRDirVal: %.4x",ch->crDirVal);
ImGui::Text("* PCM:"); ImGui::Text("* PCM:");
ImGui::Text(" * index: %d",ch->pcm.index); ImGui::Text(" * index: %d",ch->pcm.index);
ImGui::Text(" - next: %d",ch->pcm.next); ImGui::Text(" - next: %d",ch->pcm.next);
@ -949,6 +951,8 @@ void putDispatchChan(void* data, int chanNum, int type) {
ImGui::TextColored(ch->pcmChanged.position?colorOn:colorOff,">> PCMPositionChanged"); ImGui::TextColored(ch->pcmChanged.position?colorOn:colorOff,">> PCMPositionChanged");
ImGui::TextColored(ch->pcmChanged.loopBank?colorOn:colorOff,">> PCMLoopBankChanged"); ImGui::TextColored(ch->pcmChanged.loopBank?colorOn:colorOff,">> PCMLoopBankChanged");
ImGui::TextColored(ch->isReverseLoop?colorOn:colorOff,">> IsReverseLoop"); ImGui::TextColored(ch->isReverseLoop?colorOn:colorOff,">> IsReverseLoop");
ImGui::TextColored(ch->crChanged?colorOn:colorOff,">> CRChanged");
ImGui::TextColored(ch->crDirValInit?colorOn:colorOff,">> CRDirValInit");
ImGui::TextColored(ch->pcm.isNoteMap?colorOn:colorOff,">> PCMIsNoteMap"); ImGui::TextColored(ch->pcm.isNoteMap?colorOn:colorOff,">> PCMIsNoteMap");
ImGui::TextColored(ch->pcm.pause?colorOn:colorOff,">> PCMPause"); ImGui::TextColored(ch->pcm.pause?colorOn:colorOff,">> PCMPause");
ImGui::TextColored(ch->pcm.direction?colorOn:colorOff,">> PCMDirection"); ImGui::TextColored(ch->pcm.direction?colorOn:colorOff,">> PCMDirection");