diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index cb1708d52..09beda172 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -122,7 +122,7 @@ void DivPlatformAY8910::runDAC() { int prevOut=chan[i].dac.out; while (chan[i].dac.period>dacRate && !end) { DivSample* s=parent->getSample(chan[i].dac.sample); - if (s->samples<=0) { + if (s->samples<=0 || chan[i].dac.pos<0 || chan[i].dac.pos>=(int)s->samples) { chan[i].dac.sample=-1; immWrite(0x08+i,0); end=true; @@ -297,7 +297,11 @@ void DivPlatformAY8910::tick(bool sysTick) { rWrite(0x08+i,0); addWrite(0xffff0000+(i<<8),chan[i].dac.sample); } - chan[i].dac.pos=0; + if (chan[i].dac.setPos) { + chan[i].dac.setPos=false; + } else { + chan[i].dac.pos=0; + } chan[i].dac.period=0; chan[i].keyOn=true; } @@ -422,7 +426,11 @@ int DivPlatformAY8910::dispatch(DivCommand c) { addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample); } } - chan[c.chan].dac.pos=0; + if (chan[c.chan].dac.setPos) { + chan[c.chan].dac.setPos=false; + } else { + chan[c.chan].dac.pos=0; + } chan[c.chan].dac.period=0; if (c.value!=DIV_NOTE_NULL) { chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); @@ -448,7 +456,11 @@ int DivPlatformAY8910::dispatch(DivCommand c) { } else { if (dumpWrites) addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample); } - chan[c.chan].dac.pos=0; + if (chan[c.chan].dac.setPos) { + chan[c.chan].dac.setPos=false; + } else { + chan[c.chan].dac.pos=0; + } chan[c.chan].dac.period=0; chan[c.chan].dac.rate=parent->getSample(chan[c.chan].dac.sample)->rate*2048; if (dumpWrites) { @@ -652,6 +664,11 @@ int DivPlatformAY8910::dispatch(DivCommand c) { sampleBank=parent->song.sample.size()/12; } break; + case DIV_CMD_SAMPLE_POS: + chan[c.chan].dac.pos=c.value; + chan[c.chan].dac.setPos=true; + if (dumpWrites) addWrite(0xffff0005,chan[c.chan].dac.pos); + break; case DIV_CMD_MACRO_OFF: chan[c.chan].std.mask(c.value,true); break; diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index fe0a6758a..a64efbd0f 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -57,7 +57,7 @@ class DivPlatformAY8910: public DivDispatch { struct DAC { int sample, rate, period, pos, out; - bool furnaceDAC; + bool furnaceDAC, setPos; DAC(): sample(-1), @@ -65,7 +65,8 @@ class DivPlatformAY8910: public DivDispatch { period(0), pos(0), out(0), - furnaceDAC(false) {} + furnaceDAC(false), + setPos(false) {} } dac; unsigned char autoEnvNum, autoEnvDen; diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 997e4cc32..5b319abe2 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -118,7 +118,7 @@ void DivPlatformAY8930::runDAC() { int prevOut=chan[i].dac.out; while (chan[i].dac.period>rate && !end) { DivSample* s=parent->getSample(chan[i].dac.sample); - if (s->samples<=0) { + if (s->samples<=0 || chan[i].dac.pos<0 || chan[i].dac.pos>=(int)s->samples) { chan[i].dac.sample=-1; immWrite(0x08+i,0); end=true; @@ -285,7 +285,11 @@ void DivPlatformAY8930::tick(bool sysTick) { rWrite(0x08+i,0); addWrite(0xffff0000+(i<<8),chan[i].dac.sample); } - chan[i].dac.pos=0; + if (chan[i].dac.setPos) { + chan[i].dac.setPos=false; + } else { + chan[i].dac.pos=0; + } chan[i].dac.period=0; chan[i].keyOn=true; } @@ -423,7 +427,11 @@ int DivPlatformAY8930::dispatch(DivCommand c) { addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample); } } - chan[c.chan].dac.pos=0; + if (chan[c.chan].dac.setPos) { + chan[c.chan].dac.setPos=false; + } else { + chan[c.chan].dac.pos=0; + } chan[c.chan].dac.period=0; if (c.value!=DIV_NOTE_NULL) { chan[c.chan].baseFreq=NOTE_PERIODIC(c.value); @@ -449,7 +457,11 @@ int DivPlatformAY8930::dispatch(DivCommand c) { } else { if (dumpWrites) addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample); } - chan[c.chan].dac.pos=0; + if (chan[c.chan].dac.setPos) { + chan[c.chan].dac.setPos=false; + } else { + chan[c.chan].dac.pos=0; + } chan[c.chan].dac.period=0; chan[c.chan].dac.rate=parent->getSample(chan[c.chan].dac.sample)->rate*4096; if (dumpWrites) { @@ -654,6 +666,11 @@ int DivPlatformAY8930::dispatch(DivCommand c) { sampleBank=parent->song.sample.size()/12; } break; + case DIV_CMD_SAMPLE_POS: + chan[c.chan].dac.pos=c.value; + chan[c.chan].dac.setPos=true; + if (dumpWrites) addWrite(0xffff0005,chan[c.chan].dac.pos); + break; case DIV_CMD_MACRO_OFF: chan[c.chan].std.mask(c.value,true); break; diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index b43ec0fcd..457601848 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -65,7 +65,7 @@ class DivPlatformAY8930: public DivDispatch { struct DAC { int sample, rate, period, pos, out; - bool furnaceDAC; + bool furnaceDAC, setPos; DAC(): sample(-1), @@ -73,7 +73,8 @@ class DivPlatformAY8930: public DivDispatch { period(0), pos(0), out(0), - furnaceDAC(false) {} + furnaceDAC(false), + setPos(false) {} } dac; unsigned char autoEnvNum, autoEnvDen, duty;