mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-02 09:17:26 +00:00
AY/8930: implement sample offset
This commit is contained in:
parent
b8dd185463
commit
a88b63cf31
4 changed files with 48 additions and 12 deletions
|
@ -122,7 +122,7 @@ void DivPlatformAY8910::runDAC() {
|
||||||
int prevOut=chan[i].dac.out;
|
int prevOut=chan[i].dac.out;
|
||||||
while (chan[i].dac.period>dacRate && !end) {
|
while (chan[i].dac.period>dacRate && !end) {
|
||||||
DivSample* s=parent->getSample(chan[i].dac.sample);
|
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;
|
chan[i].dac.sample=-1;
|
||||||
immWrite(0x08+i,0);
|
immWrite(0x08+i,0);
|
||||||
end=true;
|
end=true;
|
||||||
|
@ -297,7 +297,11 @@ void DivPlatformAY8910::tick(bool sysTick) {
|
||||||
rWrite(0x08+i,0);
|
rWrite(0x08+i,0);
|
||||||
addWrite(0xffff0000+(i<<8),chan[i].dac.sample);
|
addWrite(0xffff0000+(i<<8),chan[i].dac.sample);
|
||||||
}
|
}
|
||||||
|
if (chan[i].dac.setPos) {
|
||||||
|
chan[i].dac.setPos=false;
|
||||||
|
} else {
|
||||||
chan[i].dac.pos=0;
|
chan[i].dac.pos=0;
|
||||||
|
}
|
||||||
chan[i].dac.period=0;
|
chan[i].dac.period=0;
|
||||||
chan[i].keyOn=true;
|
chan[i].keyOn=true;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +426,11 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
||||||
addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (chan[c.chan].dac.setPos) {
|
||||||
|
chan[c.chan].dac.setPos=false;
|
||||||
|
} else {
|
||||||
chan[c.chan].dac.pos=0;
|
chan[c.chan].dac.pos=0;
|
||||||
|
}
|
||||||
chan[c.chan].dac.period=0;
|
chan[c.chan].dac.period=0;
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||||
|
@ -448,7 +456,11 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
||||||
} else {
|
} else {
|
||||||
if (dumpWrites) addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
if (dumpWrites) addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
||||||
}
|
}
|
||||||
|
if (chan[c.chan].dac.setPos) {
|
||||||
|
chan[c.chan].dac.setPos=false;
|
||||||
|
} else {
|
||||||
chan[c.chan].dac.pos=0;
|
chan[c.chan].dac.pos=0;
|
||||||
|
}
|
||||||
chan[c.chan].dac.period=0;
|
chan[c.chan].dac.period=0;
|
||||||
chan[c.chan].dac.rate=parent->getSample(chan[c.chan].dac.sample)->rate*2048;
|
chan[c.chan].dac.rate=parent->getSample(chan[c.chan].dac.sample)->rate*2048;
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
|
@ -652,6 +664,11 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
||||||
sampleBank=parent->song.sample.size()/12;
|
sampleBank=parent->song.sample.size()/12;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case DIV_CMD_MACRO_OFF:
|
||||||
chan[c.chan].std.mask(c.value,true);
|
chan[c.chan].std.mask(c.value,true);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -57,7 +57,7 @@ class DivPlatformAY8910: public DivDispatch {
|
||||||
|
|
||||||
struct DAC {
|
struct DAC {
|
||||||
int sample, rate, period, pos, out;
|
int sample, rate, period, pos, out;
|
||||||
bool furnaceDAC;
|
bool furnaceDAC, setPos;
|
||||||
|
|
||||||
DAC():
|
DAC():
|
||||||
sample(-1),
|
sample(-1),
|
||||||
|
@ -65,7 +65,8 @@ class DivPlatformAY8910: public DivDispatch {
|
||||||
period(0),
|
period(0),
|
||||||
pos(0),
|
pos(0),
|
||||||
out(0),
|
out(0),
|
||||||
furnaceDAC(false) {}
|
furnaceDAC(false),
|
||||||
|
setPos(false) {}
|
||||||
} dac;
|
} dac;
|
||||||
|
|
||||||
unsigned char autoEnvNum, autoEnvDen;
|
unsigned char autoEnvNum, autoEnvDen;
|
||||||
|
|
|
@ -118,7 +118,7 @@ void DivPlatformAY8930::runDAC() {
|
||||||
int prevOut=chan[i].dac.out;
|
int prevOut=chan[i].dac.out;
|
||||||
while (chan[i].dac.period>rate && !end) {
|
while (chan[i].dac.period>rate && !end) {
|
||||||
DivSample* s=parent->getSample(chan[i].dac.sample);
|
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;
|
chan[i].dac.sample=-1;
|
||||||
immWrite(0x08+i,0);
|
immWrite(0x08+i,0);
|
||||||
end=true;
|
end=true;
|
||||||
|
@ -285,7 +285,11 @@ void DivPlatformAY8930::tick(bool sysTick) {
|
||||||
rWrite(0x08+i,0);
|
rWrite(0x08+i,0);
|
||||||
addWrite(0xffff0000+(i<<8),chan[i].dac.sample);
|
addWrite(0xffff0000+(i<<8),chan[i].dac.sample);
|
||||||
}
|
}
|
||||||
|
if (chan[i].dac.setPos) {
|
||||||
|
chan[i].dac.setPos=false;
|
||||||
|
} else {
|
||||||
chan[i].dac.pos=0;
|
chan[i].dac.pos=0;
|
||||||
|
}
|
||||||
chan[i].dac.period=0;
|
chan[i].dac.period=0;
|
||||||
chan[i].keyOn=true;
|
chan[i].keyOn=true;
|
||||||
}
|
}
|
||||||
|
@ -423,7 +427,11 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
||||||
addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (chan[c.chan].dac.setPos) {
|
||||||
|
chan[c.chan].dac.setPos=false;
|
||||||
|
} else {
|
||||||
chan[c.chan].dac.pos=0;
|
chan[c.chan].dac.pos=0;
|
||||||
|
}
|
||||||
chan[c.chan].dac.period=0;
|
chan[c.chan].dac.period=0;
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||||
|
@ -449,7 +457,11 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
||||||
} else {
|
} else {
|
||||||
if (dumpWrites) addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
if (dumpWrites) addWrite(0xffff0000+(c.chan<<8),chan[c.chan].dac.sample);
|
||||||
}
|
}
|
||||||
|
if (chan[c.chan].dac.setPos) {
|
||||||
|
chan[c.chan].dac.setPos=false;
|
||||||
|
} else {
|
||||||
chan[c.chan].dac.pos=0;
|
chan[c.chan].dac.pos=0;
|
||||||
|
}
|
||||||
chan[c.chan].dac.period=0;
|
chan[c.chan].dac.period=0;
|
||||||
chan[c.chan].dac.rate=parent->getSample(chan[c.chan].dac.sample)->rate*4096;
|
chan[c.chan].dac.rate=parent->getSample(chan[c.chan].dac.sample)->rate*4096;
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
|
@ -654,6 +666,11 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
||||||
sampleBank=parent->song.sample.size()/12;
|
sampleBank=parent->song.sample.size()/12;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case DIV_CMD_MACRO_OFF:
|
||||||
chan[c.chan].std.mask(c.value,true);
|
chan[c.chan].std.mask(c.value,true);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -65,7 +65,7 @@ class DivPlatformAY8930: public DivDispatch {
|
||||||
|
|
||||||
struct DAC {
|
struct DAC {
|
||||||
int sample, rate, period, pos, out;
|
int sample, rate, period, pos, out;
|
||||||
bool furnaceDAC;
|
bool furnaceDAC, setPos;
|
||||||
|
|
||||||
DAC():
|
DAC():
|
||||||
sample(-1),
|
sample(-1),
|
||||||
|
@ -73,7 +73,8 @@ class DivPlatformAY8930: public DivDispatch {
|
||||||
period(0),
|
period(0),
|
||||||
pos(0),
|
pos(0),
|
||||||
out(0),
|
out(0),
|
||||||
furnaceDAC(false) {}
|
furnaceDAC(false),
|
||||||
|
setPos(false) {}
|
||||||
} dac;
|
} dac;
|
||||||
|
|
||||||
unsigned char autoEnvNum, autoEnvDen, duty;
|
unsigned char autoEnvNum, autoEnvDen, duty;
|
||||||
|
|
Loading…
Reference in a new issue