Merge branch 'master' of https://github.com/tildearrow/furnace into getSampleMemOffset

This commit is contained in:
cam900 2025-08-27 21:18:29 +09:00
commit e9b6b441e3
466 changed files with 378861 additions and 345914 deletions

View file

@ -995,7 +995,7 @@ size_t DivPlatformAmiga::getSampleMemUsage(int index) {
bool DivPlatformAmiga::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -1006,8 +1006,8 @@ const DivMemoryComposition* DivPlatformAmiga::getMemCompo(int index) {
void DivPlatformAmiga::renderSamples(int sysID) {
memset(sampleMem,0,2097152);
memset(sampleOff,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOff,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Chip Memory";
@ -1082,3 +1082,14 @@ void DivPlatformAmiga::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformAmiga::DivPlatformAmiga() {
sampleOff=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformAmiga::~DivPlatformAmiga() {
delete[] sampleOff;
delete[] sampleLoaded;
}

View file

@ -109,8 +109,8 @@ class DivPlatformAmiga: public DivDispatch {
unsigned char volTable[64][64];
unsigned int sampleOff[256];
bool sampleLoaded[256];
unsigned int* sampleOff;
bool* sampleLoaded;
unsigned short regPool[256];
@ -171,6 +171,8 @@ class DivPlatformAmiga: public DivDispatch {
const DivMemoryComposition* getMemCompo(int index);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformAmiga();
~DivPlatformAmiga();
};
#endif

View file

@ -602,7 +602,7 @@ size_t DivPlatformC140::getSampleMemUsage(int index) {
bool DivPlatformC140::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -613,8 +613,8 @@ const DivMemoryComposition* DivPlatformC140::getMemCompo(int index) {
void DivPlatformC140::renderSamples(int sysID) {
memset(sampleMem,0,is219?524288:16777216);
memset(sampleOff,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOff,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample ROM";
@ -801,3 +801,14 @@ void DivPlatformC140::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformC140::DivPlatformC140() {
sampleOff=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformC140::~DivPlatformC140() {
delete[] sampleOff;
delete[] sampleLoaded;
}

View file

@ -55,8 +55,8 @@ class DivPlatformC140: public DivDispatch {
Channel chan[24];
DivDispatchOscBuffer* oscBuf[24];
bool isMuted[24];
unsigned int sampleOff[256];
bool sampleLoaded[256];
unsigned int* sampleOff;
bool* sampleLoaded;
bool is219;
int totalChans;
unsigned char groupBank[4];
@ -117,7 +117,8 @@ class DivPlatformC140: public DivDispatch {
void setFlags(const DivConfig& flags);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
private:
DivPlatformC140();
~DivPlatformC140();
};
#endif

View file

@ -748,7 +748,7 @@ void DivPlatformES5506::tick(bool sysTick) {
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
if (amigaPitch && parent->song.linearPitch!=2) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch*16,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,2,chan[i].pitch2*16,16*COLOR_NTSC,chan[i].pcm.freqOffs);
chan[i].freq=524288*(COLOR_NTSC/chan[i].freq)/(chipClock/32.0);
chan[i].freq=PITCH_OFFSET*(COLOR_NTSC/chan[i].freq)/(chipClock/16.0);
chan[i].freq=CLAMP(chan[i].freq,0,0x1ffff);
} else {
chan[i].freq=CLAMP(parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,chan[i].pcm.freqOffs),0,0x1ffff);
@ -1439,7 +1439,7 @@ size_t DivPlatformES5506::getSampleMemOffset(int index) {
bool DivPlatformES5506::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -1450,8 +1450,8 @@ const DivMemoryComposition* DivPlatformES5506::getMemCompo(int index) {
void DivPlatformES5506::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity());
memset(sampleOffES5506,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOffES5506,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample Memory";
@ -1524,3 +1524,17 @@ void DivPlatformES5506::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformES5506::DivPlatformES5506():
DivDispatch(),
es550x_intf(),
es5506(*this) {
sampleOffES5506=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformES5506::~DivPlatformES5506() {
delete[] sampleOffES5506;
delete[] sampleLoaded;
}

View file

@ -232,8 +232,8 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
bool isMuted[32];
signed short* sampleMem; // ES5506 uses 16 bit data bus for samples
size_t sampleMemLen;
unsigned int sampleOffES5506[256];
bool sampleLoaded[256];
unsigned int* sampleOffES5506;
bool* sampleLoaded;
struct QueuedHostIntf {
unsigned char state;
unsigned char step;
@ -324,10 +324,8 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
virtual const char** getRegisterSheet() override;
virtual int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags) override;
virtual void quit() override;
DivPlatformES5506():
DivDispatch(),
es550x_intf(),
es5506(*this) {}
DivPlatformES5506();
~DivPlatformES5506();
};
#endif

View file

@ -197,6 +197,7 @@ class DivPlatformOPN: public DivPlatformFMBase {
extSys(isExtSys),
fbAllOps(false),
useCombo(0) {}
virtual ~DivPlatformOPN() {}
public:
void setCombo(unsigned char combo) {
useCombo=combo;

View file

@ -79,8 +79,10 @@ class DivPlatformFMBase: public DivDispatch {
unsigned int addr;
unsigned short val;
bool addrOrVal;
QueuedWrite(): addr(0), val(0), addrOrVal(false) {}
QueuedWrite(unsigned int a, unsigned char v): addr(a), val(v), addrOrVal(false) {}
bool urgent;
QueuedWrite(): addr(0), val(0), addrOrVal(false), urgent(false) {}
QueuedWrite(unsigned int a, unsigned char v): addr(a), val(v), addrOrVal(false), urgent(false) {}
QueuedWrite(unsigned int a, unsigned char v, bool u): addr(a), val(v), addrOrVal(false), urgent(u) {}
};
FixedQueue<QueuedWrite,2048> writes;
@ -108,14 +110,7 @@ class DivPlatformFMBase: public DivDispatch {
// only used by OPN2 for DAC writes
inline void urgentWrite(unsigned short a, unsigned char v) {
if (!skipRegisterWrites && !flushFirst) {
if (!writes.empty()) {
// check for hard reset
if (writes.front().addr==0xf0) {
// replace hard reset with DAC write
writes.pop_front();
}
}
writes.push_front(QueuedWrite(a,v));
writes.push_front(QueuedWrite(a,v,true));
if (dumpWrites) {
addWrite(a,v);
}
@ -152,6 +147,7 @@ class DivPlatformFMBase: public DivDispatch {
lastBusy(0),
delay(0),
flushFirst(false) {}
virtual ~DivPlatformFMBase() {}
};
#endif

View file

@ -478,7 +478,7 @@ size_t DivPlatformGA20::getSampleMemUsage(int index) {
bool DivPlatformGA20::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -489,8 +489,8 @@ const DivMemoryComposition* DivPlatformGA20::getMemCompo(int index) {
void DivPlatformGA20::renderSamples(int sysID) {
memset(sampleMem,0x00,getSampleMemCapacity());
memset(sampleOffGA20,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOffGA20,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample ROM";
@ -558,3 +558,17 @@ void DivPlatformGA20::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformGA20::DivPlatformGA20():
DivDispatch(),
iremga20_intf(),
ga20(*this) {
sampleOffGA20=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformGA20::~DivPlatformGA20() {
delete[] sampleOffGA20;
delete[] sampleLoaded;
}

View file

@ -55,8 +55,8 @@ class DivPlatformGA20: public DivDispatch, public iremga20_intf {
val(v) {}
};
FixedQueue<QueuedWrite,256> writes;
unsigned int sampleOffGA20[256];
bool sampleLoaded[256];
unsigned int* sampleOffGA20;
bool* sampleLoaded;
int oldOut;
@ -104,10 +104,8 @@ class DivPlatformGA20: public DivDispatch, public iremga20_intf {
virtual void renderSamples(int chipID) override;
virtual int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags) override;
virtual void quit() override;
DivPlatformGA20():
DivDispatch(),
iremga20_intf(),
ga20(*this) {}
DivPlatformGA20();
~DivPlatformGA20();
};
#endif

View file

@ -448,7 +448,7 @@ size_t DivPlatformGBADMA::getSampleMemUsage(int index) {
bool DivPlatformGBADMA::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -463,6 +463,8 @@ const DivMemoryComposition* DivPlatformGBADMA::getMemCompo(int index) {
void DivPlatformGBADMA::renderSamples(int sysID) {
size_t maxPos=getSampleMemCapacity();
memset(sampleMem,0,maxPos);
memset(sampleOff,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
romMemCompo.entries.clear();
romMemCompo.capacity=maxPos;
@ -533,3 +535,14 @@ void DivPlatformGBADMA::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformGBADMA::DivPlatformGBADMA() {
sampleOff=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformGBADMA::~DivPlatformGBADMA() {
delete[] sampleOff;
delete[] sampleLoaded;
}

View file

@ -54,8 +54,8 @@ class DivPlatformGBADMA: public DivDispatch {
Channel chan[2];
DivDispatchOscBuffer* oscBuf[2];
bool isMuted[2];
unsigned int sampleOff[256];
bool sampleLoaded[256];
unsigned int* sampleOff;
bool* sampleLoaded;
int outDepth;
signed char* sampleMem;
@ -93,6 +93,8 @@ class DivPlatformGBADMA: public DivDispatch {
void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformGBADMA();
~DivPlatformGBADMA();
private:
void updateWave(int ch);

View file

@ -674,7 +674,7 @@ size_t DivPlatformGBAMinMod::getSampleMemUsage(int index) {
bool DivPlatformGBAMinMod::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -690,6 +690,8 @@ const DivMemoryComposition* DivPlatformGBAMinMod::getMemCompo(int index) {
void DivPlatformGBAMinMod::renderSamples(int sysID) {
size_t maxPos=getSampleMemCapacity();
memset(sampleMem,0,maxPos);
memset(sampleOff,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
romMemCompo.entries.clear();
romMemCompo.capacity=maxPos;
@ -788,3 +790,14 @@ void DivPlatformGBAMinMod::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformGBAMinMod::DivPlatformGBAMinMod() {
sampleOff=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformGBAMinMod::~DivPlatformGBAMinMod() {
delete[] sampleOff;
delete[] sampleLoaded;
}

View file

@ -54,8 +54,8 @@ class DivPlatformGBAMinMod: public DivDispatch {
Channel chan[16];
DivDispatchOscBuffer* oscBuf[16];
bool isMuted[16];
unsigned int sampleOff[256];
bool sampleLoaded[256];
unsigned int* sampleOff;
bool* sampleLoaded;
int volScale;
unsigned char chanMax;
@ -121,6 +121,8 @@ class DivPlatformGBAMinMod: public DivDispatch {
void setFlags(const DivConfig& flags);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformGBAMinMod();
~DivPlatformGBAMinMod();
float maxCPU;
private:

View file

@ -150,17 +150,34 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
os[0]=0; os[1]=0;
for (int i=0; i<6; i++) {
if (delay<=0 && !writes.empty()) {
if (!writes.empty()) {
QueuedWrite& w=writes.front();
if (w.addr==0xfffffffe) {
delay=w.val*3;
writes.pop_front();
} else if (w.addrOrVal) {
//logV("%.3x=%.2x",w.addr,w.val);
OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
regPool[w.addr&0x1ff]=w.val;
writes.pop_front();
if (delay<=0 || w.urgent) {
if (w.addr==0xfffffffe) {
delay=w.val*3;
writes.pop_front();
} else if (w.addrOrVal) {
//logV("%.3x=%.2x",w.addr,w.val);
OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
regPool[w.addr&0x1ff]=w.val;
writes.pop_front();
if (dacWrite>=0) {
if (!canWriteDAC) {
canWriteDAC=true;
} else {
urgentWrite(0x2a,dacWrite);
dacWrite=-1;
canWriteDAC=writes.empty();
}
}
} else {
if (fm.write_busy==0) {
OPN2_Write(&fm,0x0+((w.addr>>8)<<1),w.addr);
w.addrOrVal=true;
}
}
} else {
if (dacWrite>=0) {
if (!canWriteDAC) {
canWriteDAC=true;
@ -170,11 +187,6 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
canWriteDAC=writes.empty();
}
}
} else {
if (fm.write_busy==0) {
OPN2_Write(&fm,0x0+((w.addr>>8)<<1),w.addr);
w.addrOrVal=true;
}
}
} else {
canWriteDAC=true;
@ -244,24 +256,36 @@ void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) {
if (delay>0) delay--;
os[0]=0; os[1]=0;
if (delay<=0 && !writes.empty()) {
if (!writes.empty()) {
QueuedWrite& w=writes.front();
if (w.addr==0xfffffffe) {
delay=w.val;
} else {
fm_ymfm->write(0x0+((w.addr>>8)<<1),w.addr);
fm_ymfm->write(0x1+((w.addr>>8)<<1),w.val);
regPool[w.addr&0x1ff]=w.val;
}
writes.pop_front();
if (dacWrite>=0) {
if (!canWriteDAC) {
canWriteDAC=true;
if (delay<=0 || w.urgent) {
if (w.addr==0xfffffffe) {
delay=w.val;
} else {
urgentWrite(0x2a,dacWrite);
dacWrite=-1;
canWriteDAC=writes.empty();
fm_ymfm->write(0x0+((w.addr>>8)<<1),w.addr);
fm_ymfm->write(0x1+((w.addr>>8)<<1),w.val);
regPool[w.addr&0x1ff]=w.val;
}
writes.pop_front();
if (dacWrite>=0) {
if (!canWriteDAC) {
canWriteDAC=true;
} else {
urgentWrite(0x2a,dacWrite);
dacWrite=-1;
canWriteDAC=writes.empty();
}
}
} else {
if (dacWrite>=0) {
if (!canWriteDAC) {
canWriteDAC=true;
} else {
urgentWrite(0x2a,dacWrite);
dacWrite=-1;
canWriteDAC=writes.empty();
}
}
}
} else {
@ -402,55 +426,89 @@ void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) {
if (delay>0) delay--;
if (delay<=0 && !writes.empty()) {
if (!writes.empty()) {
QueuedWrite& w=writes.front();
if (w.addr==0xfffffffe) {
delay=w.val;
writes.pop_front();
} else if (w.addrOrVal) {
//logV("%.3x=%.2x",w.addr,w.val);
//OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
was_reg_write=true;
if (delay<=0 || w.urgent) {
if (w.addr==0xfffffffe) {
delay=w.val;
writes.pop_front();
} else if (w.addrOrVal) {
//logV("%.3x=%.2x",w.addr,w.val);
//OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
was_reg_write=true;
fm_276.input.address=w.addr<0x100?0:2;
fm_276.input.data=w.addr&0xff;
fm_276.input.wr=1;
FMOPN2_Clock(&fm_276,0);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub(h);
fm_276.input.wr=0;
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub(h);
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
dacShifter=(dacShifter<<1)|fm_276.o_so;
if (o_lro!=fm_276.o_lro) {
if (o_lro)
sample_l=dacShifter;
else
sample_r=dacShifter;
}
o_lro=fm_276.o_lro;
}
o_bco=fm_276.o_bco;
}
for (int c=0; c<17; c++) {
fm_276.input.address=w.addr<0x100?0:2;
fm_276.input.data=w.addr&0xff;
fm_276.input.wr=1;
FMOPN2_Clock(&fm_276,0);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub(h);
fm_276.input.wr=0;
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub(h);
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
dacShifter=(dacShifter<<1)|fm_276.o_so;
if (o_lro!=fm_276.o_lro) {
if (o_lro)
sample_l=dacShifter;
else
sample_r=dacShifter;
}
o_lro=fm_276.o_lro;
}
o_bco=fm_276.o_bco;
}
for (int c=0; c<17; c++) {
FMOPN2_Clock(&fm_276,0);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub(h);
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub(h);
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
dacShifter=(dacShifter<<1)|fm_276.o_so;
if (o_lro!=fm_276.o_lro) {
if (o_lro)
sample_l=dacShifter;
else
sample_r=dacShifter;
}
o_lro=fm_276.o_lro;
}
o_bco=fm_276.o_bco;
}
}
fm_276.input.address=w.addr<0x100?1:3;
fm_276.input.data=w.val;
fm_276.input.wr=1;
FMOPN2_Clock(&fm_276,0);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
fm_276.input.wr=0;
acquire276OscSub(h);
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
@ -472,74 +530,54 @@ void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) {
}
o_bco=fm_276.o_bco;
}
}
fm_276.input.address=w.addr<0x100?1:3;
fm_276.input.data=w.val;
fm_276.input.wr=1;
FMOPN2_Clock(&fm_276,0);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
fm_276.input.wr=0;
for (int c=0; c<83; c++) {
FMOPN2_Clock(&fm_276,0);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub(h);
acquire276OscSub(h);
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub(h);
acquire276OscSub(h);
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
dacShifter=(dacShifter<<1)|fm_276.o_so;
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
dacShifter=(dacShifter<<1)|fm_276.o_so;
if (o_lro!=fm_276.o_lro) {
if (o_lro)
sample_l=dacShifter;
else
sample_r=dacShifter;
}
o_lro=fm_276.o_lro;
}
o_bco=fm_276.o_bco;
}
for (int c=0; c<83; c++) {
FMOPN2_Clock(&fm_276,0);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub(h);
FMOPN2_Clock(&fm_276,1);
sum_l+=fm_276.out_l;
sum_r+=fm_276.out_r;
acquire276OscSub(h);
if (chipType==2) {
if (!o_bco && fm_276.o_bco) {
dacShifter=(dacShifter<<1)|fm_276.o_so;
if (o_lro!=fm_276.o_lro) {
if (o_lro) {
sample_l=dacShifter;
} else {
sample_r=dacShifter;
if (o_lro!=fm_276.o_lro) {
if (o_lro) {
sample_l=dacShifter;
} else {
sample_r=dacShifter;
}
}
o_lro=fm_276.o_lro;
}
o_lro=fm_276.o_lro;
o_bco=fm_276.o_bco;
}
o_bco=fm_276.o_bco;
}
regPool[w.addr&0x1ff]=w.val;
writes.pop_front();
if (dacWrite>=0) {
if (!canWriteDAC) {
canWriteDAC=true;
} else {
urgentWrite(0x2a,dacWrite);
dacWrite=-1;
canWriteDAC=writes.empty();
}
}
} else {
w.addrOrVal=true;
}
regPool[w.addr&0x1ff]=w.val;
writes.pop_front();
} else {
if (dacWrite>=0) {
if (!canWriteDAC) {
canWriteDAC=true;
@ -549,8 +587,6 @@ void DivPlatformGenesis::acquire_nuked276(short** buf, size_t len) {
canWriteDAC=writes.empty();
}
}
} else {
w.addrOrVal=true;
}
} else {
canWriteDAC=true;

View file

@ -555,7 +555,7 @@ size_t DivPlatformK007232::getSampleMemUsage(int index) {
bool DivPlatformK007232::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -566,8 +566,8 @@ const DivMemoryComposition* DivPlatformK007232::getMemCompo(int index) {
void DivPlatformK007232::renderSamples(int sysID) {
memset(sampleMem,0xc0,getSampleMemCapacity());
memset(sampleOffK007232,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOffK007232,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample ROM";
@ -636,3 +636,17 @@ void DivPlatformK007232::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformK007232::DivPlatformK007232():
DivDispatch(),
k007232_intf(),
k007232(*this) {
sampleOffK007232=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformK007232::~DivPlatformK007232() {
delete[] sampleOffK007232;
delete[] sampleLoaded;
}

View file

@ -63,8 +63,8 @@ class DivPlatformK007232: public DivDispatch, public k007232_intf {
val(v) {}
};
FixedQueue<QueuedWrite,256> writes;
unsigned int sampleOffK007232[256];
bool sampleLoaded[256];
unsigned int* sampleOffK007232;
bool* sampleLoaded;
int delay;
unsigned char lastLoop, lastVolume, oscDivider;
@ -110,10 +110,8 @@ class DivPlatformK007232: public DivDispatch, public k007232_intf {
void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformK007232():
DivDispatch(),
k007232_intf(),
k007232(*this) {}
DivPlatformK007232();
~DivPlatformK007232();
};
#endif

View file

@ -160,7 +160,7 @@ void DivPlatformK053260::tick(bool sysTick) {
unsigned int start=0;
unsigned int length=0;
if (sample>=0 && sample<parent->song.sampleLen) {
start=sampleOffK053260[sample];
start=sampleOff[sample];
length=(s->depth==DIV_SAMPLE_DEPTH_ADPCM_K)?s->lengthK:s->length8;
if (chan[i].reverse) {
start+=length;
@ -474,7 +474,7 @@ size_t DivPlatformK053260::getSampleMemOffset(int index) {
bool DivPlatformK053260::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -485,8 +485,8 @@ const DivMemoryComposition* DivPlatformK053260::getMemCompo(int index) {
void DivPlatformK053260::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity());
memset(sampleOffK053260,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOff,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample ROM";
@ -495,7 +495,7 @@ void DivPlatformK053260::renderSamples(int sysID) {
for (int i=0; i<parent->song.sampleLen; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffK053260[i]=0;
sampleOff[i]=0;
continue;
}
@ -505,7 +505,7 @@ void DivPlatformK053260::renderSamples(int sysID) {
length=MIN(65535,s->getEndPosition(DIV_SAMPLE_DEPTH_ADPCM_K));
actualLength=MIN((int)(getSampleMemCapacity()-memPos-getSampleMemOffset()),length);
if (actualLength>0) {
sampleOffK053260[i]=memPos-getSampleMemOffset();
sampleOff[i]=memPos-getSampleMemOffset();
memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE,"Sample",i,memPos,memPos+actualLength+getSampleMemOffset()));
for (int j=0; j<actualLength; j++) {
sampleMem[memPos++]=s->dataK[j];
@ -516,7 +516,7 @@ void DivPlatformK053260::renderSamples(int sysID) {
length=MIN(65535,s->getEndPosition(DIV_SAMPLE_DEPTH_8BIT));
actualLength=MIN((int)(getSampleMemCapacity()-memPos-getSampleMemOffset()),length);
if (actualLength>0) {
sampleOffK053260[i]=memPos-getSampleMemOffset();
sampleOff[i]=memPos-getSampleMemOffset();
memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE,"Sample",i,memPos,memPos+actualLength+getSampleMemOffset()));
for (int j=0; j<actualLength; j++) {
sampleMem[memPos++]=s->data8[j];
@ -559,3 +559,17 @@ void DivPlatformK053260::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformK053260::DivPlatformK053260():
DivDispatch(),
k053260_intf(),
k053260(*this) {
sampleOff=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformK053260::~DivPlatformK053260() {
delete[] sampleOff;
delete[] sampleLoaded;
}

View file

@ -46,8 +46,8 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf {
bool isMuted[4];
int chipType;
unsigned char curChan;
unsigned int sampleOffK053260[256];
bool sampleLoaded[256];
unsigned int* sampleOff;
bool* sampleLoaded;
unsigned char* sampleMem;
size_t sampleMemLen;
@ -90,10 +90,8 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf {
virtual void renderSamples(int chipID) override;
virtual int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags) override;
virtual void quit() override;
DivPlatformK053260():
DivDispatch(),
k053260_intf(),
k053260(*this) {}
DivPlatformK053260();
~DivPlatformK053260();
private:
void chWrite(unsigned char ch, unsigned int addr, unsigned char val);
};

View file

@ -385,7 +385,7 @@ size_t DivPlatformMSM6295::getSampleMemUsage(int index) {
bool DivPlatformMSM6295::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -395,12 +395,12 @@ const DivMemoryComposition* DivPlatformMSM6295::getMemCompo(int index) {
}
void DivPlatformMSM6295::renderSamples(int sysID) {
unsigned int sampleOffVOX[256];
unsigned int* sampleOffVOX=new unsigned int[32768];
memset(adpcmMem,0,16777216);
memset(sampleOffVOX,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
for (int i=0; i<256; i++) {
memset(sampleOffVOX,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
for (int i=0; i<32768; i++) {
bankedPhrase[i].bank=0;
bankedPhrase[i].phrase=0;
}
@ -412,10 +412,18 @@ void DivPlatformMSM6295::renderSamples(int sysID) {
// sample data
size_t memPos=128*8;
int sampleCount=parent->song.sampleLen;
if (isBanked) {
if (sampleCount>8191) {
// mark the rest as unavailable
for (int i=8191; i<sampleCount; i++) {
sampleLoaded[i]=false;
}
sampleCount=8191;
}
int bankInd=0;
int phraseInd=0;
for (int i=0; i<parent->song.sampleLen; i++) {
for (int i=0; i<sampleCount; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
sampleOffVOX[i]=0;
@ -455,7 +463,7 @@ void DivPlatformMSM6295::renderSamples(int sysID) {
adpcmMemLen=memPos+256;
// phrase book
for (int i=0; i<parent->song.sampleLen; i++) {
for (int i=0; i<sampleCount; i++) {
int endPos=sampleOffVOX[i]+bankedPhrase[i].length;
for (int b=0; b<4; b++) {
unsigned int bankedAddr=((unsigned int)bankedPhrase[i].bank<<16)+(b<<8)+(bankedPhrase[i].phrase*8);
@ -468,8 +476,13 @@ void DivPlatformMSM6295::renderSamples(int sysID) {
}
}
} else {
int sampleCount=parent->song.sampleLen;
if (sampleCount>127) sampleCount=127;
if (sampleCount>127) {
// mark the rest as unavailable
for (int i=127; i<sampleCount; i++) {
sampleLoaded[i]=false;
}
sampleCount=127;
}
for (int i=0; i<sampleCount; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
@ -510,6 +523,8 @@ void DivPlatformMSM6295::renderSamples(int sysID) {
memCompo.capacity=getSampleMemCapacity(0);
memCompo.used=adpcmMemLen;
delete[] sampleOffVOX;
}
void DivPlatformMSM6295::setFlags(const DivConfig& flags) {
@ -600,5 +615,16 @@ void DivPlatformMSM6295::quit() {
delete[] adpcmMem;
}
DivPlatformMSM6295::~DivPlatformMSM6295() {
// initialization of important arrays
DivPlatformMSM6295::DivPlatformMSM6295():
DivDispatch(),
vgsound_emu_mem_intf(),
msm(*this) {
bankedPhrase=new BankedPhrase[32768];
sampleLoaded=new bool[32768];
}
DivPlatformMSM6295::~DivPlatformMSM6295() {
delete[] bankedPhrase;
delete[] sampleLoaded;
}

View file

@ -52,7 +52,7 @@ class DivPlatformMSM6295: public DivDispatch, public vgsound_emu_mem_intf {
unsigned char* adpcmMem;
size_t adpcmMemLen;
bool sampleLoaded[256];
bool* sampleLoaded;
unsigned char sampleBank;
int delay, updateOsc;
@ -68,7 +68,7 @@ class DivPlatformMSM6295: public DivDispatch, public vgsound_emu_mem_intf {
bank(0),
phrase(0),
length(0) {}
} bankedPhrase[256];
}* bankedPhrase;
DivMemoryComposition memCompo;
@ -106,10 +106,7 @@ class DivPlatformMSM6295: public DivDispatch, public vgsound_emu_mem_intf {
virtual int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags) override;
virtual void quit() override;
DivPlatformMSM6295():
DivDispatch(),
vgsound_emu_mem_intf(),
msm(*this) {}
DivPlatformMSM6295();
~DivPlatformMSM6295();
};
#endif

View file

@ -531,7 +531,7 @@ size_t DivPlatformNDS::getSampleMemUsage(int index) {
bool DivPlatformNDS::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -542,8 +542,8 @@ const DivMemoryComposition* DivPlatformNDS::getMemCompo(int index) {
void DivPlatformNDS::renderSamples(int sysID) {
memset(sampleMem,0,16777216);
memset(sampleOff,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOff,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Main Memory";
@ -629,3 +629,17 @@ void DivPlatformNDS::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformNDS::DivPlatformNDS():
DivDispatch(),
nds_sound_intf(),
nds(*this) {
sampleOff=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformNDS::~DivPlatformNDS() {
delete[] sampleOff;
delete[] sampleLoaded;
}

View file

@ -50,8 +50,8 @@ class DivPlatformNDS: public DivDispatch, public nds_sound_intf {
bool isDSi;
int globalVolume;
int lastOut[2];
unsigned int sampleOff[256];
bool sampleLoaded[256];
unsigned int* sampleOff;
bool* sampleLoaded;
struct QueuedWrite {
unsigned short addr;
unsigned char size;
@ -104,10 +104,8 @@ class DivPlatformNDS: public DivDispatch, public nds_sound_intf {
virtual void setFlags(const DivConfig& flags) override;
virtual int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags) override;
virtual void quit() override;
DivPlatformNDS():
DivDispatch(),
nds_sound_intf(),
nds(*this) {}
DivPlatformNDS();
~DivPlatformNDS();
private:
void writeOutVol(int ch);
};

View file

@ -352,9 +352,6 @@ void DivPlatformNES::tick(bool sysTick) {
}
if (chan[i].sweepChanged) {
chan[i].sweepChanged=false;
if (i==0) {
// rWrite(16+i*5,chan[i].sweep);
}
}
if (i<3) if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
@ -637,6 +634,13 @@ int DivPlatformNES::dispatch(DivCommand c) {
} else if (!parent->song.brokenOutVol2) {
rWrite(0x4000+c.chan*4,(chan[c.chan].envMode<<4)|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
}
if (resetSweep && c.chan<2) {
if (chan[c.chan].sweep!=0x08 && !chan[c.chan].sweepChanged) {
chan[c.chan].sweep=0x08;
chan[c.chan].prevFreq=-1;
rWrite(0x4001+(c.chan*4),chan[c.chan].sweep);
}
}
break;
case DIV_CMD_NOTE_OFF:
if (c.chan==4) {
@ -724,6 +728,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
}
}
rWrite(0x4001+(c.chan*4),chan[c.chan].sweep);
chan[c.chan].sweepChanged=true;
break;
case DIV_CMD_NES_ENV_MODE:
chan[c.chan].envMode=c.value&3;
@ -989,6 +994,7 @@ void DivPlatformNES::setFlags(const DivConfig& flags) {
}
dpcmModeDefault=flags.getBool("dpcmMode",true);
resetSweep=flags.getBool("resetSweep",false);
}
void DivPlatformNES::notifyInsDeletion(void* ins) {
@ -1033,7 +1039,7 @@ size_t DivPlatformNES::getSampleMemUsage(int index) {
bool DivPlatformNES::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -1044,7 +1050,8 @@ const DivMemoryComposition* DivPlatformNES::getMemCompo(int index) {
void DivPlatformNES::renderSamples(int sysID) {
memset(dpcmMem,0,getSampleMemCapacity(0));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOffDPCM,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="DPCM";
@ -1150,5 +1157,13 @@ void DivPlatformNES::quit() {
}
}
DivPlatformNES::~DivPlatformNES() {
// initialization of important arrays
DivPlatformNES::DivPlatformNES() {
sampleOffDPCM=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformNES::~DivPlatformNES() {
delete[] sampleOffDPCM;
delete[] sampleLoaded;
}

View file

@ -57,7 +57,7 @@ class DivPlatformNES: public DivDispatch {
int dacSample;
unsigned char* dpcmMem;
size_t dpcmMemLen;
bool sampleLoaded[256];
bool* sampleLoaded;
unsigned char dpcmBank;
unsigned char sampleBank;
unsigned char writeOscBuf;
@ -68,6 +68,7 @@ class DivPlatformNES: public DivDispatch {
signed char lastDPCMFreq;
bool dpcmMode;
bool dpcmModeDefault;
bool resetSweep;
bool dacAntiClickOn;
bool useNP;
bool goingToLoop;
@ -79,7 +80,7 @@ class DivPlatformNES: public DivDispatch {
xgm::I5E01_APU* e1_NP;
xgm::I5E01_DMC* e2_NP;
unsigned char regPool[128];
unsigned int sampleOffDPCM[256];
unsigned int* sampleOffDPCM;
DivMemoryComposition memCompo;
friend void putDispatchChip(void*,int);
@ -123,6 +124,7 @@ class DivPlatformNES: public DivDispatch {
void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformNES();
~DivPlatformNES();
};

View file

@ -37,6 +37,9 @@
#define PCM_CHECK(ch) ((chipType==4) && (ch>=pcmChanOffs))
#define PCM_REG(ch) (ch-pcmChanOffs)
// check if PCM in RAM (and size is <= 2MB) - 4MB uses whole sample area
#define PCM_IN_RAM (ramSize<=0x200000)
// N = invalid
#define N 255
@ -1338,7 +1341,7 @@ void DivPlatformOPL::tick(bool sysTick) {
unsigned char slot=slots[j][i];
if (slot==255) continue;
unsigned short baseAddr=slotMap[slot];
if (baseAddr>0x100) {
if (baseAddr>=0x100) {
weWillWriteRRLater[(baseAddr&0xff)|32]=true;
} else {
weWillWriteRRLater[(baseAddr&0xff)]=true;
@ -1464,38 +1467,43 @@ void DivPlatformOPL::tick(bool sysTick) {
chan[i].freqL=(chan[i].freq>>chan[i].freqH)&0x3ff;
chan[i].freqH=8^chan[i].freqH;
ctrl|=(chan[i].active?0x80:0)|(chan[i].damp?0x40:0)|(chan[i].lfoReset?0x20:0)|(chan[i].ch?0x10:0)|(isMuted[i]?8:(chan[i].pan&0xf));
unsigned int waveNum=chan[i].sample;
if (ramSize<=0x200000) {
waveNum=CLAMP(waveNum,0,0x7f)|0x180;
}
if (chan[i].keyOn) {
immWrite(PCM_ADDR_KEY_DAMP_LFORST_CH_PAN+PCM_REG(i),ctrl&~0x80); // force keyoff first
immWrite(PCM_ADDR_WAVE_H_FN_L+PCM_REG(i),((chan[i].freqL&0x7f)<<1)|((waveNum>>8)&1));
immWrite(PCM_ADDR_WAVE_L+PCM_REG(i),waveNum&0xff);
immWrite(PCM_ADDR_LFO_VIB+PCM_REG(i),(chan[i].lfo<<3)|(chan[i].vib));
immWrite(PCM_ADDR_AR_D1R+PCM_REG(i),(chan[i].ar<<4)|(chan[i].d1r));
immWrite(PCM_ADDR_DL_D2R+PCM_REG(i),(chan[i].dl<<4)|(chan[i].d2r));
immWrite(PCM_ADDR_RC_RR+PCM_REG(i),(chan[i].rc<<4)|(chan[i].rr));
immWrite(PCM_ADDR_AM+PCM_REG(i),chan[i].am);
if (!chan[i].std.vol.had) {
chan[i].outVol=chan[i].vol;
immWrite(PCM_ADDR_TL+(PCM_REG(i)),((0x7f-chan[i].outVol)<<1)|(chan[i].levelDirect?1:0));
int waveNum=chan[i].sample;
if (waveNum>=0) {
if (PCM_IN_RAM) {
waveNum=CLAMP(waveNum,0,0x7f)|0x180;
}
chan[i].writeCtrl=true;
chan[i].keyOn=false;
}
if (chan[i].keyOff) {
chan[i].writeCtrl=true;
chan[i].keyOff=false;
}
if (chan[i].freqChanged) {
immWrite(PCM_ADDR_WAVE_H_FN_L+PCM_REG(i),((chan[i].freqL&0x7f)<<1)|((waveNum>>8)&1));
immWrite(PCM_ADDR_FN_H_PR_OCT+PCM_REG(i),((chan[i].freqH&0xf)<<4)|(chan[i].pseudoReverb?0x08:0x00)|((chan[i].freqL>>7)&0x7));
chan[i].freqChanged=false;
}
if (chan[i].writeCtrl) {
immWrite(PCM_ADDR_KEY_DAMP_LFORST_CH_PAN+PCM_REG(i),ctrl);
chan[i].writeCtrl=false;
if (chan[i].keyOn) {
immWrite(PCM_ADDR_KEY_DAMP_LFORST_CH_PAN+PCM_REG(i),ctrl&~0x80); // force keyoff first
immWrite(PCM_ADDR_WAVE_H_FN_L+PCM_REG(i),((chan[i].freqL&0x7f)<<1)|((waveNum>>8)&1));
immWrite(PCM_ADDR_WAVE_L+PCM_REG(i),waveNum&0xff);
immWrite(PCM_ADDR_LFO_VIB+PCM_REG(i),(chan[i].lfo<<3)|(chan[i].vib));
immWrite(PCM_ADDR_AR_D1R+PCM_REG(i),(chan[i].ar<<4)|(chan[i].d1r));
immWrite(PCM_ADDR_DL_D2R+PCM_REG(i),(chan[i].dl<<4)|(chan[i].d2r));
immWrite(PCM_ADDR_RC_RR+PCM_REG(i),(chan[i].rc<<4)|(chan[i].rr));
immWrite(PCM_ADDR_AM+PCM_REG(i),chan[i].am);
if (!chan[i].std.vol.had) {
chan[i].outVol=chan[i].vol;
immWrite(PCM_ADDR_TL+(PCM_REG(i)),((0x7f-chan[i].outVol)<<1)|(chan[i].levelDirect?1:0));
}
chan[i].writeCtrl=true;
chan[i].keyOn=false;
}
if (chan[i].keyOff) {
chan[i].writeCtrl=true;
chan[i].keyOff=false;
}
if (chan[i].freqChanged) {
immWrite(PCM_ADDR_WAVE_H_FN_L+PCM_REG(i),((chan[i].freqL&0x7f)<<1)|((waveNum>>8)&1));
immWrite(PCM_ADDR_FN_H_PR_OCT+PCM_REG(i),((chan[i].freqH&0xf)<<4)|(chan[i].pseudoReverb?0x08:0x00)|((chan[i].freqL>>7)&0x7));
chan[i].freqChanged=false;
}
if (chan[i].writeCtrl) {
immWrite(PCM_ADDR_KEY_DAMP_LFORST_CH_PAN+PCM_REG(i),ctrl);
chan[i].writeCtrl=false;
}
} else {
// cut if we don't have a sample
immWrite(PCM_ADDR_KEY_DAMP_LFORST_CH_PAN+PCM_REG(i),ctrl&~0x80);
}
}
} else {
@ -2936,7 +2944,7 @@ void DivPlatformOPL::reset() {
if (chipType==4) {
immWrite(0x105,3);
// Reset wavetable header
immWrite(0x202,(ramSize<=0x200000)?0x10:0x00);
immWrite(0x202,PCM_IN_RAM?0x10:0x00);
// initialize mixer volume
fmMixL=7;
fmMixR=7;
@ -3204,7 +3212,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
pcm.setClockFrequency(chipClock);
rate=chipClock/768;
chipRateBase=chipClock/684;
immWrite(0x202,(ramSize<=0x200000)?0x10:0x00);
immWrite(0x202,PCM_IN_RAM?0x10:0x00);
break;
case 759:
rate=48000;
@ -3227,7 +3235,7 @@ const void* DivPlatformOPL::getSampleMem(int index) {
size_t DivPlatformOPL::getSampleMemCapacity(int index) {
return (index==0 && pcmChanOffs>=0)?
((ramSize<=0x200000)?0x200000+ramSize:ramSize):
(PCM_IN_RAM?0x200000+ramSize:ramSize):
((index==0 && adpcmChan>=0)?262144:0);
}
@ -3242,7 +3250,7 @@ size_t DivPlatformOPL::getSampleMemOffset(int index) {
bool DivPlatformOPL::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -3260,18 +3268,24 @@ void DivPlatformOPL::renderSamples(int sysID) {
if (pcmChanOffs>=0 && pcmMem!=NULL) {
memset(pcmMem,0,4194304);
}
memset(sampleOffPCM,0,256*sizeof(unsigned int));
memset(sampleOffB,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOffPCM,0,32768*sizeof(unsigned int));
memset(sampleOffB,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample Memory";
if (pcmChanOffs>=0) { // OPL4 PCM
size_t memPos=((ramSize<=0x200000)?0x200600:0x1800);
const int maxSample=(ramSize<=0x200000)?127:511;
size_t memPos=(PCM_IN_RAM?0x200600:0x1800);
const int maxSample=PCM_IN_RAM?128:512;
int sampleCount=parent->song.sampleLen;
if (sampleCount>maxSample) sampleCount=maxSample;
if (sampleCount>maxSample) {
// mark the rest as unavailable
for (int i=maxSample; i<sampleCount; i++) {
sampleLoaded[i]=false;
}
sampleCount=maxSample;
}
for (int i=0; i<sampleCount; i++) {
DivSample* s=parent->song.sample[i];
if (!s->renderOn[0][sysID]) {
@ -3334,7 +3348,7 @@ void DivPlatformOPL::renderSamples(int sysID) {
// instrument table
for (int i=0; i<sampleCount; i++) {
DivSample* s=parent->song.sample[i];
unsigned int insAddr=(i*12)+((ramSize<=0x200000)?0x200000:0);
unsigned int insAddr=(i*12)+(PCM_IN_RAM?0x200000:0);
unsigned char bitDepth;
int endPos=CLAMP(s->isLoopable()?s->loopEnd:(s->samples+1),1,0x10000);
int loop=s->isLoopable()?CLAMP(s->loopStart,0,endPos-2):(endPos-2);
@ -3365,12 +3379,12 @@ void DivPlatformOPL::renderSamples(int sysID) {
pcmMem[6+insAddr]=(~(endPos-1))&0xff;
// on MultiPCM this consists of instrument params, but on OPL4 this is not used
pcmMem[7+insAddr]=0; // LFO, VIB
pcmMem[8+insAddr]=(0xf << 4) | (0xf << 0); // AR, D1R
pcmMem[8+insAddr]=(0xf<<4)|(0xf<<0); // AR, D1R
pcmMem[9+insAddr]=0; // DL, D2R
pcmMem[10+insAddr]=(0xf << 4) | (0xf << 0); // RC, RR
pcmMem[10+insAddr]=(0xf<<4)|(0xf<<0); // RC, RR
pcmMem[11+insAddr]=0; // AM
}
if (ramSize<=0x200000) {
if (PCM_IN_RAM) {
memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_RESERVED,"ROM data",0,0,0x200000));
}
@ -3502,5 +3516,17 @@ void DivPlatformOPL::quit() {
}
}
DivPlatformOPL::~DivPlatformOPL() {
// initialization of important arrays
DivPlatformOPL::DivPlatformOPL():
pcmMemory(0x400000),
pcm(pcmMemory) {
sampleOffPCM=new unsigned int[32768];
sampleOffB=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformOPL::~DivPlatformOPL() {
delete[] sampleOffPCM;
delete[] sampleOffB;
delete[] sampleLoaded;
}

View file

@ -123,9 +123,9 @@ class DivPlatformOPL: public DivDispatch {
size_t pcmMemLen;
DivOPLAInterface iface;
DivYMF278MemoryInterface pcmMemory;
unsigned int sampleOffB[256];
unsigned int sampleOffPCM[256];
bool sampleLoaded[256];
unsigned int* sampleOffB;
unsigned int* sampleOffPCM;
bool* sampleLoaded;
ymfm::adpcm_b_engine* adpcmB;
const unsigned char** slotsNonDrums;
@ -224,9 +224,7 @@ class DivPlatformOPL: public DivDispatch {
void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformOPL():
pcmMemory(0x400000),
pcm(pcmMemory) {}
DivPlatformOPL();
~DivPlatformOPL();
};
#endif

View file

@ -202,81 +202,109 @@ void DivPlatformOPLL::tick(bool sysTick) {
}
}
if (chan[i].state.opllPreset==0) {
if (chan[i].std.alg.had) { // SUS
chan[i].state.alg=chan[i].std.alg.val;
if (chan[i].std.alg.had) { // SUS
chan[i].state.alg=chan[i].std.alg.val;
if (chan[i].state.opllPreset==0) {
chan[i].freqChanged=true;
}
if (chan[i].std.fb.had) {
chan[i].state.fb=chan[i].std.fb.val;
}
if (chan[i].std.fb.had) {
chan[i].state.fb=chan[i].std.fb.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x03,(chan[i].state.op[1].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
}
if (chan[i].std.fms.had) {
chan[i].state.fms=chan[i].std.fms.val;
}
if (chan[i].std.fms.had) {
chan[i].state.fms=chan[i].std.fms.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x03,(chan[i].state.op[1].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
}
if (chan[i].std.ams.had) {
chan[i].state.ams=chan[i].std.ams.val;
}
if (chan[i].std.ams.had) {
chan[i].state.ams=chan[i].std.ams.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x03,(chan[i].state.op[1].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
}
}
for (int j=0; j<2; j++) {
DivInstrumentFM::Operator& op=chan[i].state.op[j];
DivMacroInt::IntOp& m=chan[i].std.op[j];
for (int j=0; j<2; j++) {
DivInstrumentFM::Operator& op=chan[i].state.op[j];
DivMacroInt::IntOp& m=chan[i].std.op[j];
if (m.am.had) {
op.am=m.am.val;
if (m.am.had) {
op.am=m.am.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult));
}
if (m.ar.had) {
op.ar=m.ar.val;
}
if (m.ar.had) {
op.ar=m.ar.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x04+j,(op.ar<<4)|(op.dr));
}
if (m.dr.had) {
op.dr=m.dr.val;
}
if (m.dr.had) {
op.dr=m.dr.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x04+j,(op.ar<<4)|(op.dr));
}
if (m.mult.had) {
op.mult=m.mult.val;
}
if (m.mult.had) {
op.mult=m.mult.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult));
}
if (m.rr.had) {
op.rr=m.rr.val;
}
if (m.rr.had) {
op.rr=m.rr.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x06+j,(op.sl<<4)|(op.rr));
}
if (m.sl.had) {
op.sl=m.sl.val;
}
if (m.sl.had) {
op.sl=m.sl.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x06+j,(op.sl<<4)|(op.rr));
}
if (m.tl.had) {
op.tl=m.tl.val&((j==1)?15:63);
if (j==1) {
if (i<9) {
rWrite(0x30+i,((15-VOL_SCALE_LOG_BROKEN(chan[i].outVol,15-chan[i].state.op[1].tl,15))&15)|(chan[i].state.opllPreset<<4));
}
} else {
}
if (m.tl.had) {
op.tl=m.tl.val&((j==1)?15:63);
if (j==1) {
if (i<9) {
rWrite(0x30+i,((15-VOL_SCALE_LOG_BROKEN(chan[i].outVol,15-chan[i].state.op[1].tl,15))&15)|(chan[i].state.opllPreset<<4));
}
} else {
if (chan[i].state.opllPreset==0) {
rWrite(0x02,(chan[i].state.op[0].ksl<<6)|(op.tl&63));
}
}
}
if (m.egt.had) {
op.ssgEnv=(m.egt.val&1)?8:0;
if (m.egt.had) {
op.ssgEnv=(m.egt.val&1)?8:0;
if (chan[i].state.opllPreset==0) {
rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult));
}
if (m.ksl.had) {
op.ksl=m.ksl.val;
}
if (m.ksl.had) {
op.ksl=m.ksl.val;
if (chan[i].state.opllPreset==0) {
if (j==1) {
rWrite(0x02,(chan[i].state.op[0].ksl<<6)|(chan[i].state.op[0].tl&63));
} else {
rWrite(0x03,(chan[i].state.op[1].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb);
}
}
if (m.ksr.had) {
op.ksr=m.ksr.val;
}
if (m.ksr.had) {
op.ksr=m.ksr.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult));
}
if (m.vib.had) {
op.vib=m.vib.val;
}
if (m.vib.had) {
op.vib=m.vib.val;
if (chan[i].state.opllPreset==0) {
rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult));
}
}
@ -390,6 +418,7 @@ int DivPlatformOPLL::toFreq(int freq, int fixedBlock) {
block=freq/OPLL_C_NUM;
if (block>0) block=bsr(block);
}
if (block>7) block=7;
freq>>=block;
if (freq>0x1ff) freq=0x1ff;
return (block<<9)|freq;

View file

@ -307,39 +307,44 @@ void DivPlatformQSound::tick(bool sysTick) {
}
}
}
uint16_t qsound_bank = 0;
uint16_t qsound_addr = 0;
uint16_t qsound_loop = 0;
uint16_t qsound_end = 0;
uint16_t qsoundBank=0;
uint16_t qsoundAddr=0;
uint16_t qsoundLoop=0;
uint16_t qsoundEnd=0;
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[i].sample);
if (i<16) {
qsound_bank = 0x8000 | (offPCM[chan[i].sample] >> 16);
qsound_addr = offPCM[chan[i].sample] & 0xffff;
qsoundBank=0x8000|(offPCM[chan[i].sample]>>16);
qsoundAddr=offPCM[chan[i].sample]&0xffff;
} else {
qsound_bank = 0x8000 | (offBS[chan[i].sample] >> 16);
qsound_addr = offBS[chan[i].sample] & 0xffff;
qsoundBank=0x8000|(offBS[chan[i].sample]>>16);
qsoundAddr=offBS[chan[i].sample]&0xffff;
}
int loopStart=s->loopStart;
int length = s->loopEnd;
if (length > 65536 - 16) {
length = 65536 - 16;
}
if (!s->isLoopable()) {
if (i<16) {
qsound_end = offPCM[chan[i].sample] + length + 15;
} else {
qsound_end = offBS[chan[i].sample] + (length>>1) + 15;
int length=s->loopEnd;
if (i<16) {
if (length>65536-16) {
length=65536-16;
}
qsound_loop = 15;
} else {
if (i<16) {
qsound_end = offPCM[chan[i].sample] + length;
} else {
qsound_end = offBS[chan[i].sample] + (length>>1);
// ADPCM address is byte aligned
length>>=1;
if (length>65535) {
length=65535;
}
qsound_loop = length - loopStart;
}
if (i<16) {
if (!s->isLoopable()) {
qsoundEnd=offPCM[chan[i].sample]+length+15;
qsoundLoop=15;
} else {
qsoundEnd=offPCM[chan[i].sample]+length;
qsoundLoop=length-loopStart;
}
} else {
// ADPCM can't loop
qsoundEnd=offBS[chan[i].sample]+length;
}
}
if (NEW_ARP_STRAT) {
@ -406,19 +411,19 @@ void DivPlatformQSound::tick(bool sysTick) {
}
if (i<16) {
rWrite(q1_reg_map[Q1V_BANK][i], qsound_bank);
rWrite(q1_reg_map[Q1V_END][i], qsound_end);
rWrite(q1_reg_map[Q1V_LOOP][i], qsound_loop);
rWrite(q1_reg_map[Q1V_START][i], qsound_addr+chan[i].audPos);
rWrite(q1_reg_map[Q1V_BANK][i], qsoundBank);
rWrite(q1_reg_map[Q1V_END][i], qsoundEnd);
rWrite(q1_reg_map[Q1V_LOOP][i], qsoundLoop);
rWrite(q1_reg_map[Q1V_START][i], qsoundAddr+chan[i].audPos);
rWrite(q1_reg_map[Q1V_PHASE][i], 0x8000);
} else {
rWrite(Q1A_KEYON+(i-16),0);
rWrite(q1a_bank_map[i-16], qsound_bank);
rWrite(q1a_end_map[i-16], qsound_end);
rWrite(q1a_start_map[i-16], qsound_addr+chan[i].audPos);
rWrite(q1a_bank_map[i-16], qsoundBank);
rWrite(q1a_end_map[i-16], qsoundEnd);
rWrite(q1a_start_map[i-16], qsoundAddr+chan[i].audPos);
rWrite(Q1A_KEYON+(i-16),1);
}
//logV("ch %d bank=%04x, addr=%04x, end=%04x, loop=%04x!",i,qsound_bank,qsound_addr,qsound_end,qsound_loop);
//logV("ch %d bank=%04x, addr=%04x, end=%04x, loop=%04x!",i,qsoundBank,qsoundAddr,qsoundEnd,qsoundLoop);
// Write sample address. Enable volume
if (!chan[i].std.vol.had) {
if (chan[i].isNewQSound) {
@ -747,7 +752,7 @@ size_t DivPlatformQSound::getSampleMemUsage(int index) {
bool DivPlatformQSound::isSampleLoaded(int index, int sample) {
if (index<0 || index>1) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
if (index==1) return sampleLoadedBS[sample];
return sampleLoaded[sample];
}
@ -763,8 +768,10 @@ const DivMemoryComposition* DivPlatformQSound::getMemCompo(int index) {
void DivPlatformQSound::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity());
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleLoadedBS,0,256*sizeof(bool));
memset(offPCM,0,32768*sizeof(unsigned int));
memset(offBS,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memset(sampleLoadedBS,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample ROM";
@ -839,7 +846,7 @@ void DivPlatformQSound::renderSamples(int sysID) {
}
offBS[i]=memPos;
memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_SAMPLE_ALT1,"ADPCM",i,memPos,memPos+length));
memPos+=length+16;
memPos+=length;
}
sampleMemLenBS=memPos+256;
@ -880,3 +887,18 @@ void DivPlatformQSound::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformQSound::DivPlatformQSound() {
offPCM=new unsigned int[32768];
offBS=new unsigned int[32768];
sampleLoaded=new bool[32768];
sampleLoadedBS=new bool[32768];
}
DivPlatformQSound::~DivPlatformQSound() {
delete[] offPCM;
delete[] offBS;
delete[] sampleLoaded;
delete[] sampleLoadedBS;
}

View file

@ -53,13 +53,13 @@ class DivPlatformQSound: public DivDispatch {
size_t sampleMemLen;
size_t sampleMemLenBS;
size_t sampleMemUsage;
bool sampleLoaded[256];
bool sampleLoadedBS[256];
bool* sampleLoaded;
bool* sampleLoadedBS;
struct qsound_chip chip;
unsigned short regPool[512];
unsigned int offPCM[256];
unsigned int offBS[256];
unsigned int* offPCM;
unsigned int* offBS;
DivMemoryComposition memCompo;
@ -98,6 +98,8 @@ class DivPlatformQSound: public DivDispatch {
void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformQSound();
~DivPlatformQSound();
};
#endif

View file

@ -420,7 +420,7 @@ size_t DivPlatformRF5C68::getSampleMemUsage(int index) {
bool DivPlatformRF5C68::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -431,8 +431,8 @@ const DivMemoryComposition* DivPlatformRF5C68::getMemCompo(int index) {
void DivPlatformRF5C68::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity());
memset(sampleOffRFC,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOffRFC,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample Memory";
@ -497,3 +497,14 @@ void DivPlatformRF5C68::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformRF5C68::DivPlatformRF5C68() {
sampleOffRFC=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformRF5C68::~DivPlatformRF5C68() {
delete[] sampleOffRFC;
delete[] sampleLoaded;
}

View file

@ -44,8 +44,8 @@ class DivPlatformRF5C68: public DivDispatch {
bool isMuted[8];
int chipType;
unsigned char curChan;
unsigned int sampleOffRFC[256];
bool sampleLoaded[256];
unsigned int* sampleOffRFC;
bool* sampleLoaded;
unsigned char* sampleMem;
size_t sampleMemLen;
@ -85,6 +85,8 @@ class DivPlatformRF5C68: public DivDispatch {
void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformRF5C68();
~DivPlatformRF5C68();
private:
void chWrite(unsigned char ch, unsigned int addr, unsigned char val);
};

View file

@ -470,7 +470,7 @@ size_t DivPlatformSegaPCM::getSampleMemUsage(int index) {
bool DivPlatformSegaPCM::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -509,9 +509,9 @@ void DivPlatformSegaPCM::renderSamples(int sysID) {
size_t memPos=0;
memset(sampleMem,0,2097152);
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOffSegaPCM,0,256*sizeof(unsigned int));
memset(sampleEndSegaPCM,0,256);
memset(sampleLoaded,0,32768*sizeof(bool));
memset(sampleOffSegaPCM,0,32768*sizeof(unsigned int));
memset(sampleEndSegaPCM,0,32768);
memCompo=DivMemoryComposition();
memCompo.name="Sample ROM";
@ -595,5 +595,15 @@ void DivPlatformSegaPCM::quit() {
delete sampleMem;
}
DivPlatformSegaPCM::~DivPlatformSegaPCM() {
// initialization of important arrays
DivPlatformSegaPCM::DivPlatformSegaPCM() {
sampleOffSegaPCM=new unsigned int[32768];
sampleEndSegaPCM=new unsigned char[32768];
sampleLoaded=new bool[32768];
}
DivPlatformSegaPCM::~DivPlatformSegaPCM() {
delete[] sampleOffSegaPCM;
delete[] sampleEndSegaPCM;
delete[] sampleLoaded;
}

View file

@ -78,9 +78,9 @@ class DivPlatformSegaPCM: public DivDispatch {
short oldWrites[256];
short pendingWrites[256];
unsigned int sampleOffSegaPCM[256];
unsigned char sampleEndSegaPCM[256];
bool sampleLoaded[256];
unsigned int* sampleOffSegaPCM;
unsigned char* sampleEndSegaPCM;
bool* sampleLoaded;
DivMemoryComposition memCompo;
@ -116,6 +116,7 @@ class DivPlatformSegaPCM: public DivDispatch {
const DivMemoryComposition* getMemCompo(int index);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformSegaPCM();
~DivPlatformSegaPCM();
};
#endif

View file

@ -966,7 +966,7 @@ size_t DivPlatformSNES::getSampleMemUsage(int index) {
bool DivPlatformSNES::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -977,8 +977,8 @@ const DivMemoryComposition* DivPlatformSNES::getMemCompo(int index) {
void DivPlatformSNES::renderSamples(int sysID) {
memset(copyOfSampleMem,0,65536);
memset(sampleOff,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOff,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="SPC/DSP Memory";
@ -1077,3 +1077,14 @@ void DivPlatformSNES::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformSNES::DivPlatformSNES() {
sampleOff=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformSNES::~DivPlatformSNES() {
delete[] sampleOff;
delete[] sampleLoaded;
}

View file

@ -93,8 +93,8 @@ class DivPlatformSNES: public DivDispatch {
signed char sampleMem[65536];
signed char copyOfSampleMem[65536];
size_t sampleMemLen;
unsigned int sampleOff[256];
bool sampleLoaded[256];
unsigned int* sampleOff;
bool* sampleLoaded;
DivMemoryComposition memCompo;
unsigned char regPool[0x80];
SPC_DSP dsp;
@ -132,6 +132,8 @@ class DivPlatformSNES: public DivDispatch {
void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformSNES();
~DivPlatformSNES();
private:
void updateWave(int ch);
void writeOutVol(int ch);

View file

@ -72,11 +72,19 @@ void sm8521_noise_tick(struct sm8521_noise_t *noise, const int cycle)
noise->base.counter += cycle;
while (noise->base.counter >= (noise->base.t + 1))
{
// https://github.com/tildearrow/furnace/issues/2567
// unknown algorithm, but don't use rand()
//
// some research suggests VIC-like noise, although
// that remains to be confirmed
noise->oldLFSR = noise->lfsr & 1;
noise->lfsr = ( noise->lfsr>>1|(((noise->lfsr) ^ (noise->lfsr >> 5) ^ (noise->lfsr >> 8) ^ (noise->lfsr >> 13) ) & 1)<<31);
noise->base.counter -= (noise->base.t + 1);
if (noise->oldLFSR^(noise->lfsr&1)) {
noise->out ^= 1;
}
}
noise->base.out = (((noise->lfsr & 0x1) ? 7 : -8) * noise->base.level) >> 1; // scale out to 8bit
noise->base.out = ((noise->out ? 7 : -8) * noise->base.level) >> 1; // scale out to 8bit
}
void sm8521_sound_tick(struct sm8521_t *sm8521, const int cycle)
@ -130,6 +138,8 @@ void sm8521_reset(struct sm8521_t *sm8521)
sm8521->noise.base.out = 0;
sm8521->noise.base.counter = 0;
sm8521->noise.lfsr = 0x89abcdef;
sm8521->noise.oldLFSR = 1;
sm8521->noise.out = 0;
sm8521->out = 0;
sm8521->sgda = 0;
sm8521->sgc = 0;

View file

@ -65,7 +65,8 @@ struct sm8521_wave_t
struct sm8521_noise_t
{
struct sm8521_sg_t base;
unsigned int lfsr; // LFSR
unsigned int lfsr, oldLFSR; // LFSR
unsigned char out;
};
struct sm8521_t

View file

@ -145,8 +145,8 @@ static const int noise_periods [3] = { 0x100, 0x200, 0x400 };
void T6W28_Noise::reset()
{
period = &noise_periods [0];
shifter = 0x4000;
tap = 13;
shifter = 0xfffe;
tap = 12;
period_extra = 0;
T6W28_Osc::reset();
}
@ -201,9 +201,13 @@ void T6W28_Noise::run( sms_time_t time, sms_time_t end_time )
do
{
int changed = (l_shifter + 1) & 2; // set if prev and next bits differ
l_shifter = (((l_shifter << 14) ^ (l_shifter << tap)) & 0x4000) | (l_shifter >> 1);
if ( changed )
int prev_l_shifter=l_shifter;
if (tap==16) {
l_shifter = ((l_shifter >> 14) & 1) | (l_shifter << 1);
} else {
l_shifter = ((((l_shifter >> 15)&1) ^ ((l_shifter >> 12)&1)) & 1) | (l_shifter << 1);
}
if ( (prev_l_shifter^l_shifter)&1 )
{
delta_left = -delta_left;
blip_add_delta( output_left, time, delta_left );
@ -370,8 +374,8 @@ void T6W28_Apu::write_data_right( sms_time_t time, int data )
noise.period = &noise.period_extra;
int const tap_disabled = 16;
noise.tap = (data & 0x04) ? 13 : tap_disabled;
noise.shifter = 0x4000;
noise.tap = (data & 0x04) ? 12 : tap_disabled;
noise.shifter = 0xfffe;
}
}

View file

@ -4,8 +4,8 @@
// Chip revisions
// 0: V 0.3.0
// 1: V 47.0.0 (9-bit volume, phase reset on mute)
// 2: V 47.0.2 (Pulse Width XOR on Saw and Triangle)
// 1: V 47.0.2 (9-bit volume, phase reset on mute)
// 2: V 48.0.1 (Pulse Width XOR on Saw and Triangle)
#include "vera_psg.h"

View file

@ -51,6 +51,8 @@ void VSU::Power(void)
SweepControl = 0;
SweepModCounter = 0;
SweepModClockDivider = 1;
ModState = 0;
ModLock = 0;
for(int ch = 0; ch < 6; ch++)
{
@ -62,7 +64,9 @@ void VSU::Power(void)
RAMAddress[ch] = 0;
EffFreq[ch] = 0;
Envelope[ch] = 0;
EnvelopeReload[ch] = 0;
EnvelopeValue[ch] = 0;
EnvelopeModMask[ch] = 0;
WavePos[ch] = 0;
FreqCounter[ch] = 1;
IntervalCounter[ch] = 0;
@ -100,6 +104,8 @@ void VSU::Write(int timestamp, unsigned int A, unsigned char V)
Update(timestamp);
ModLock = 0;
//printf("VSU Write: %d, %08x %02x\n", timestamp, A, V);
if(A < 0x280)
@ -133,7 +139,6 @@ void VSU::Write(int timestamp, unsigned int A, unsigned char V)
if(V & 0x80)
{
EffFreq[ch] = Frequency[ch];
if(ch == 5)
FreqCounter[ch] = 10 * (2048 - EffFreq[ch]);
else
@ -146,15 +151,20 @@ void VSU::Write(int timestamp, unsigned int A, unsigned char V)
SweepModCounter = (SweepControl >> 4) & 7;
SweepModClockDivider = (SweepControl & 0x80) ? 8 : 1;
ModWavePos = 0;
ModState = 0;
}
WavePos[ch] = 0;
if(ch == 5) // Not sure if this is correct.
if(ch == 5) { // Not sure if this is correct.
lfsr = 1;
}
//if(!(IntlControl[ch] & 0x80))
// Envelope[ch] = (EnvControl[ch] >> 4) & 0xF;
EnvelopeModMask[ch] = 0;
if(!(EnvControl[ch] & 0x200) && (
(EnvelopeValue[ch] == 0 && !(EnvControl[ch] & 0x0008)) ||
(EnvelopeValue[ch] == 0xF && (EnvControl[ch] & 0x0008))))
EnvelopeModMask[ch] = 1;
EffectsClockDivider[ch] = 4800;
IntervalClockDivider[ch] = 4;
@ -167,21 +177,27 @@ void VSU::Write(int timestamp, unsigned int A, unsigned char V)
break;
case 0x2: Frequency[ch] &= 0xFF00;
Frequency[ch] |= V << 0;
EffFreq[ch] &= 0xFF00;
Frequency[ch] |= V << 0;
EffFreq[ch] &= 0xFF00;
EffFreq[ch] |= V << 0;
ModLock = 1;
break;
case 0x3: Frequency[ch] &= 0x00FF;
Frequency[ch] |= (V & 0x7) << 8;
EffFreq[ch] &= 0x00FF;
Frequency[ch] |= (V & 0x7) << 8;
EffFreq[ch] &= 0x00FF;
EffFreq[ch] |= (V & 0x7) << 8;
ModLock = 2;
break;
case 0x4: EnvControl[ch] &= 0xFF00;
EnvControl[ch] |= V << 0;
Envelope[ch] = (V >> 4) & 0xF;
EnvelopeReload[ch] = (V >> 4) & 0xF;
EnvelopeValue[ch] = (V >> 4) & 0xF;
if(EnvelopeModMask[ch] == 1)
EnvelopeModMask[ch] = 2;
break;
case 0x5: EnvControl[ch] &= 0x00FF;
@ -194,6 +210,12 @@ void VSU::Write(int timestamp, unsigned int A, unsigned char V)
}
else
EnvControl[ch] |= (V & 0x03) << 8;
if(EnvelopeModMask[ch] == 0 && !(EnvControl[ch] & 0x200) && (
(EnvelopeValue[ch] == 0 && !(EnvControl[ch] & 0x0008)) ||
(EnvelopeValue[ch] == 0xF && (EnvControl[ch] & 0x0008))))
EnvelopeModMask[ch] = 1;
break;
case 0x6: RAMAddress[ch] = V & 0xF;
@ -228,14 +250,14 @@ inline void VSU::CalcCurrentOutput(int ch, int &left, int &right)
else
WD = WaveData[RAMAddress[ch]][WavePos[ch]]; // - 0x20;
}
l_ol = Envelope[ch] * LeftLevel[ch];
l_ol = EnvelopeValue[ch] * LeftLevel[ch];
if(l_ol)
{
l_ol >>= 3;
l_ol += 1;
}
r_ol = Envelope[ch] * RightLevel[ch];
r_ol = EnvelopeValue[ch] * RightLevel[ch];
if(r_ol)
{
r_ol >>= 3;
@ -260,11 +282,11 @@ void VSU::Update(int timestamp)
CalcCurrentOutput(ch, left, right);
if (left!=last_output[ch][0]) {
blip_add_delta(bb[0],running_timestamp,left - last_output[ch][0]);
last_output[ch][0] = left;
last_output[ch][0] = left;
}
if (right!=last_output[ch][1]) {
blip_add_delta(bb[1],running_timestamp,right - last_output[ch][1]);
last_output[ch][1] = right;
last_output[ch][1] = right;
}
oscBuf[ch]->putSample(running_timestamp,(left+right)*8);
@ -355,23 +377,27 @@ void VSU::Update(int timestamp)
{
EnvelopeClockDivider[ch] += 4;
int new_envelope = EnvelopeValue[ch];
if(EnvelopeValue[ch] < 0xF && (EnvControl[ch] & 0x0008))
new_envelope++;
else if(EnvelopeValue[ch] > 0 && !(EnvControl[ch] & 0x0008))
new_envelope--;
else if((EnvControl[ch] & 0x200) && EnvelopeModMask[ch] != 2)
{
new_envelope = EnvelopeReload[ch];
EnvelopeModMask[ch] = 0;
}
else if(EnvelopeModMask[ch] == 0)
EnvelopeModMask[ch] = 1;
if(EnvControl[ch] & 0x0100) // Enveloping enabled?
{
EnvelopeCounter[ch]--;
if(!EnvelopeCounter[ch])
{
EnvelopeCounter[ch] = (EnvControl[ch] & 0x7) + 1;
if(EnvControl[ch] & 0x0008) // Grow
{
if(Envelope[ch] < 0xF || (EnvControl[ch] & 0x200))
Envelope[ch] = (Envelope[ch] + 1) & 0xF;
}
else // Decay
{
if(Envelope[ch] > 0 || (EnvControl[ch] & 0x200))
Envelope[ch] = (Envelope[ch] - 1) & 0xF;
}
EnvelopeCounter[ch] = (EnvControl[ch] & 0x7) + 1;
if(EnvelopeModMask[ch] == 0)
EnvelopeValue[ch] = new_envelope;
}
}
@ -380,6 +406,19 @@ void VSU::Update(int timestamp)
if(ch == 4)
{
// Calculate sweep early
int delta = EffFreq[ch] >> (SweepControl & 0x7);
int NewSweepFreq = EffFreq[ch] + ((SweepControl & 0x8) ? delta : -delta);
if(!(EnvControl[ch] & 0x1000))
{
if(NewSweepFreq < 0)
NewSweepFreq = 0;
else if(NewSweepFreq > 0x7FF)
IntlControl[ch] &= ~0x80;
}
SweepModClockDivider--;
while(SweepModClockDivider <= 0)
{
@ -394,33 +433,30 @@ void VSU::Update(int timestamp)
{
SweepModCounter = (SweepControl >> 4) & 0x7;
if(EnvControl[ch] & 0x1000) // Modulation
if(EnvControl[ch] & 0x1000) // Modulation
{
if(ModWavePos < 32 || (EnvControl[ch] & 0x2000))
{
ModWavePos &= 0x1F;
if(ModState == 0 || (EnvControl[ch] & 0x2000))
EffFreq[ch] = (Frequency[ch] + (signed char)ModData[ModWavePos]) & 0x7FF;
if(ModState == 1)
ModState = 2;
EffFreq[ch] = (Frequency[ch] + (signed char)ModData[ModWavePos]) & 0x7FF;
ModWavePos++;
}
// Hardware bug: writing to S5FQ* locks the relevant byte when modulating
if(ModLock == 1)
EffFreq[ch] = (EffFreq[ch] & 0x700) | (Frequency[ch] & 0xFF);
else if(ModLock == 2)
EffFreq[ch] = (EffFreq[ch] & 0xFF) | (Frequency[ch] & 0x700);
}
else // Sweep
else if(ModState < 2) // Sweep
{
int delta = EffFreq[ch] >> (SweepControl & 0x7);
int NewFreq = EffFreq[ch] + ((SweepControl & 0x8) ? delta : -delta);
EffFreq[ch] = NewSweepFreq;
}
//printf("Sweep(%d): Old: %d, New: %d\n", ch, EffFreq[ch], NewFreq);
if(NewFreq < 0)
EffFreq[ch] = 0;
else if(NewFreq > 0x7FF)
if(++ModWavePos >= 32)
{
//EffFreq[ch] = 0x7FF;
IntlControl[ch] &= ~0x80;
if(ModState == 0)
ModState = 1;
ModWavePos = 0;
}
else
EffFreq[ch] = NewFreq;
}
}
}
} // end while(SweepModClockDivider <= 0)
@ -433,11 +469,11 @@ void VSU::Update(int timestamp)
CalcCurrentOutput(ch, left, right);
if (left!=last_output[ch][0]) {
blip_add_delta(bb[0],running_timestamp,left - last_output[ch][0]);
last_output[ch][0] = left;
last_output[ch][0] = left;
}
if (right!=last_output[ch][1]) {
blip_add_delta(bb[1],running_timestamp,right - last_output[ch][1]);
last_output[ch][1] = right;
last_output[ch][1] = right;
}
oscBuf[ch]->putSample(running_timestamp,(left+right)*8);
}

View file

@ -74,7 +74,8 @@ class VSU
//
//
int EffFreq[6];
int Envelope[6];
int EnvelopeValue[6];
int EnvelopeReload[6];
int WavePos[6];
int ModWavePos;
@ -91,6 +92,12 @@ class VSU
int EnvelopeClockDivider[6];
int SweepModClockDivider;
public:
int EnvelopeModMask[6];
int ModState;
int ModLock;
private:
int NoiseLatcherClockDivider;
unsigned int NoiseLatcher;

View file

@ -1,6 +1,7 @@
#ifndef YMF278_HH
#define YMF278_HH
#include <stdint.h>
#include <vector>
#include <string>
#include <algorithm>

View file

@ -338,11 +338,13 @@ void pcm_channel::output(output_data &output) const
// fetch current sample and add
int16_t sample = fetch_sample();
int32_t outl = (lvol * sample) >> 15;
int32_t outr = (rvol * sample) >> 15;
uint32_t outnum = m_regs.ch_output_channel(m_choffs) * 2;
output.data[outnum + 0] += (lvol * sample) >> 15;
output.data[outnum + 1] += (rvol * sample) >> 15;
m_output[outnum + 0] = output.data[outnum + 0];
m_output[outnum + 1] = output.data[outnum + 1];
output.data[outnum + 0] += outl;
output.data[outnum + 1] += outr;
m_output[outnum + 0] = outl;
m_output[outnum + 1] = outr;
}

View file

@ -690,7 +690,7 @@ size_t DivPlatformSoundUnit::getSampleMemUsage(int index) {
bool DivPlatformSoundUnit::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -701,8 +701,8 @@ const DivMemoryComposition* DivPlatformSoundUnit::getMemCompo(int index) {
void DivPlatformSoundUnit::renderSamples(int sysID) {
memset(sampleMem,0,sampleMemSize?65536:8192);
memset(sampleOffSU,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOffSU,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample RAM";
@ -770,5 +770,13 @@ void DivPlatformSoundUnit::quit() {
delete[] sampleMem;
}
DivPlatformSoundUnit::~DivPlatformSoundUnit() {
// initialization of important arrays
DivPlatformSoundUnit::DivPlatformSoundUnit() {
sampleOffSU=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformSoundUnit::~DivPlatformSoundUnit() {
delete[] sampleOffSU;
delete[] sampleLoaded;
}

View file

@ -94,8 +94,8 @@ class DivPlatformSoundUnit: public DivDispatch {
unsigned char ilCtrl, ilSize, fil1;
unsigned char initIlCtrl, initIlSize, initFil1;
signed char echoVol, initEchoVol;
unsigned int sampleOffSU[256];
bool sampleLoaded[256];
unsigned int* sampleOffSU;
bool* sampleLoaded;
int cycles, curChan, delay, sysIDCache;
short tempL;
@ -140,6 +140,7 @@ class DivPlatformSoundUnit: public DivDispatch {
void renderSamples(int chipID);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformSoundUnit();
~DivPlatformSoundUnit();
};

View file

@ -513,7 +513,7 @@ size_t DivPlatformSupervision::getSampleMemUsage(int index) {
bool DivPlatformSupervision::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -524,7 +524,7 @@ const DivMemoryComposition* DivPlatformSupervision::getMemCompo(int index) {
void DivPlatformSupervision::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity(0));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample Memory";
@ -603,5 +603,15 @@ void DivPlatformSupervision::quit() {
}
}
DivPlatformSupervision::~DivPlatformSupervision() {
// initialization of important arrays
DivPlatformSupervision::DivPlatformSupervision() {
sampleOff=new unsigned int[32768];
sampleLen=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformSupervision::~DivPlatformSupervision() {
delete[] sampleOff;
delete[] sampleLen;
delete[] sampleLoaded;
}

View file

@ -56,9 +56,9 @@ class DivPlatformSupervision: public DivDispatch {
int tempR[32];
int coreQuality;
unsigned char regPool[64];
unsigned int sampleOff[256];
unsigned int sampleLen[256];
bool sampleLoaded[256];
unsigned int* sampleOff;
unsigned int* sampleLen;
bool* sampleLoaded;
DivMemoryComposition memCompo;
unsigned char* sampleMem;
size_t sampleMemLen;
@ -98,6 +98,7 @@ class DivPlatformSupervision: public DivDispatch {
bool getDCOffRequired();
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformSupervision();
~DivPlatformSupervision();
};

View file

@ -19,6 +19,8 @@
#include "vb.h"
#include "../engine.h"
#include "IconsFontAwesome4.h"
#include "furIcons.h"
#include <math.h>
//#define rWrite(a,v) pendingWrites[a]=v;
@ -252,6 +254,27 @@ void DivPlatformVB::tick(bool sysTick) {
}
}
}
for (int i=0; i<6; i++) {
if ((chan[i].envHigh&3)==0) {
chan[i].hasEnvWarning=0;
} else {
switch (vb->EnvelopeModMask[i]) {
case 0: // envelope OK
chan[i].hasEnvWarning=0;
break;
case 1: // envelope has finished
chan[i].hasEnvWarning=21;
break;
case 2: // can't envelope
chan[i].hasEnvWarning=22;
break;
}
}
}
/*if (vb->ModLock) {
chan[4].hasEnvWarning=4;
}*/
}
int DivPlatformVB::dispatch(DivCommand c) {
@ -477,6 +500,16 @@ unsigned short DivPlatformVB::getPan(int ch) {
return ((chan[ch].pan&0xf0)<<4)|(chan[ch].pan&15);
}
DivChannelModeHints DivPlatformVB::getModeHints(int ch) {
DivChannelModeHints ret;
//if (ch>4) return ret;
ret.count=1;
ret.hint[0]=ICON_FA_EXCLAMATION_TRIANGLE;
ret.type[0]=chan[ch].hasEnvWarning;
return ret;
}
DivDispatchOscBuffer* DivPlatformVB::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -30,6 +30,7 @@ class DivPlatformVB: public DivDispatch {
int antiClickPeriodCount, antiClickWavePos;
unsigned char pan, envLow, envHigh;
bool noise, deferredWaveUpdate, intWritten;
unsigned char hasEnvWarning;
signed short wave;
DivWaveSynth ws;
Channel():
@ -42,6 +43,7 @@ class DivPlatformVB: public DivDispatch {
noise(false),
deferredWaveUpdate(false),
intWritten(false),
hasEnvWarning(0),
wave(-1) {}
};
Channel chan[6];
@ -78,6 +80,7 @@ class DivPlatformVB: public DivDispatch {
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
unsigned short getPan(int chan);
DivChannelModeHints getModeHints(int chan);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();

View file

@ -284,13 +284,13 @@ void DivPlatformVIC20::muteChannel(int ch, bool mute) {
void DivPlatformVIC20::forceIns() {
for (int i=0; i<4; i++) {
chan[i].insChanged=true;
// I give up!
if (chan[i].onOff) {
if (chan[i].onOff && chan[i].active) {
chan[i].freqChanged=true;
} else {
chan[i].freqChanged=false;
chan[i].keyOff=true;
chan[i].keyOn=false;
chan[i].waveWriteCycle=-1;
}
writeOutVol(i);
}

View file

@ -418,6 +418,9 @@ int DivPlatformVRC6::dispatch(DivCommand c) {
case DIV_CMD_STD_NOISE_MODE:
if ((c.chan!=2) && (!chan[c.chan].pcm)) { // pulse
chan[c.chan].duty=c.value;
if (!isMuted[c.chan]) { // pulse
chWrite(c.chan,0,(chan[c.chan].outVol&0xf)|((chan[c.chan].duty&7)<<4));
}
}
break;
case DIV_CMD_SAMPLE_MODE:

View file

@ -1001,7 +1001,7 @@ size_t DivPlatformX1_010::getSampleMemUsage(int index) {
bool DivPlatformX1_010::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -1012,8 +1012,8 @@ const DivMemoryComposition* DivPlatformX1_010::getMemCompo(int index) {
void DivPlatformX1_010::renderSamples(int sysID) {
memset(sampleMem,0,16777216);
memset(sampleOffX1,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOffX1,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample ROM";
@ -1081,5 +1081,16 @@ void DivPlatformX1_010::quit() {
delete[] sampleMem;
}
DivPlatformX1_010::~DivPlatformX1_010() {
// initialization of important arrays
DivPlatformX1_010::DivPlatformX1_010():
DivDispatch(),
vgsound_emu_mem_intf(),
x1_010(*this) {
sampleOffX1=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformX1_010::~DivPlatformX1_010() {
delete[] sampleOffX1;
delete[] sampleLoaded;
}

View file

@ -117,8 +117,8 @@ class DivPlatformX1_010: public DivDispatch, public vgsound_emu_mem_intf {
bool isBanked=false;
unsigned int bankSlot[8];
unsigned int sampleOffX1[256];
bool sampleLoaded[256];
unsigned int* sampleOffX1;
bool* sampleLoaded;
DivMemoryComposition memCompo;
@ -159,10 +159,7 @@ class DivPlatformX1_010: public DivDispatch, public vgsound_emu_mem_intf {
const char** getRegisterSheet();
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformX1_010():
DivDispatch(),
vgsound_emu_mem_intf(),
x1_010(*this) {}
DivPlatformX1_010();
~DivPlatformX1_010();
};

View file

@ -531,6 +531,16 @@ void DivPlatformYM2608::acquire_lle(short** buf, size_t len) {
signed char subCycle=0;
unsigned char subSubCycle=0;
// AY -> OPN
ay->runDAC();
ay->runTFX(rate);
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
for (int i=0; i<6; i++) {
fmOut[i]=0;
}
@ -1991,7 +2001,7 @@ size_t DivPlatformYM2608::getSampleMemUsage(int index) {
bool DivPlatformYM2608::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -2002,8 +2012,8 @@ const DivMemoryComposition* DivPlatformYM2608::getMemCompo(int index) {
void DivPlatformYM2608::renderSamples(int sysID) {
memset(adpcmBMem,0,getSampleMemCapacity(0));
memset(sampleOffB,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOffB,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="ADPCM";
@ -2148,5 +2158,16 @@ void DivPlatformYM2608::quit() {
delete[] adpcmBMem;
}
DivPlatformYM2608::~DivPlatformYM2608() {
// initialization of important arrays
DivPlatformYM2608::DivPlatformYM2608():
DivPlatformOPN(2, 6, 9, 15, 16, 9440540.0, 72, 32, false, 16),
prescale(0x2d),
isCSM(0) {
sampleOffB=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformYM2608::~DivPlatformYM2608() {
delete[] sampleOffB;
delete[] sampleLoaded;
}

View file

@ -67,8 +67,8 @@ class DivPlatformYM2608: public DivPlatformOPN {
unsigned char* adpcmBMem;
size_t adpcmBMemLen;
DivYM2608Interface iface;
unsigned int sampleOffB[256];
bool sampleLoaded[256];
unsigned int* sampleOffB;
bool* sampleLoaded;
DivPlatformAY8910* ay;
unsigned char sampleBank;
@ -124,10 +124,7 @@ class DivPlatformYM2608: public DivPlatformOPN {
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void setCSM(bool isCSM);
void quit();
DivPlatformYM2608():
DivPlatformOPN(2, 6, 9, 15, 16, 9440540.0, 72, 32, false, 16),
prescale(0x2d),
isCSM(0) {}
DivPlatformYM2608();
~DivPlatformYM2608();
};
#endif

View file

@ -465,6 +465,16 @@ void DivPlatformYM2610::acquire_lle(short** buf, size_t len) {
signed char subCycle=0;
unsigned char subSubCycle=0;
// AY -> OPN
ay->runDAC();
ay->runTFX(rate);
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
for (int i=0; i<6; i++) {
fmOut[i]=0;
}

View file

@ -533,6 +533,16 @@ void DivPlatformYM2610B::acquire_lle(short** buf, size_t len) {
signed char subCycle=0;
unsigned char subSubCycle=0;
// AY -> OPN
ay->runDAC();
ay->runTFX(rate);
ay->flushWrites();
for (DivRegWrite& i: ay->getRegisterWrites()) {
if (i.addr>15) continue;
immWrite(i.addr&15,i.val);
}
ay->getRegisterWrites().clear();
for (int i=0; i<6; i++) {
fmOut[i]=0;
}

View file

@ -75,14 +75,14 @@ class DivPlatformYM2610Base: public DivPlatformOPN {
size_t adpcmBMemLen;
DivYM2610Interface iface;
unsigned int sampleOffA[256];
unsigned int sampleOffB[256];
unsigned int* sampleOffA;
unsigned int* sampleOffB;
unsigned char sampleBank;
bool extMode, noExtMacros;
bool sampleLoaded[2][256];
bool* sampleLoaded[2];
unsigned char writeADPCMAOff, writeADPCMAOn;
int globalADPCMAVolume;
@ -214,7 +214,7 @@ class DivPlatformYM2610Base: public DivPlatformOPN {
bool isSampleLoaded(int index, int sample) {
if (index<0 || index>1) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[index][sample];
}
@ -226,9 +226,10 @@ class DivPlatformYM2610Base: public DivPlatformOPN {
void renderSamples(int sysID) {
memset(adpcmAMem,0,getSampleMemCapacity(0));
memset(sampleOffA,0,256*sizeof(unsigned int));
memset(sampleOffB,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*2*sizeof(bool));
memset(sampleOffA,0,32768*sizeof(unsigned int));
memset(sampleOffB,0,32768*sizeof(unsigned int));
memset(sampleLoaded[0],0,32768*sizeof(bool));
memset(sampleLoaded[1],0,32768*sizeof(bool));
memCompoA=DivMemoryComposition();
memCompoA.name="ADPCM-A";
@ -365,7 +366,18 @@ class DivPlatformYM2610Base: public DivPlatformOPN {
}
DivPlatformYM2610Base(int ext, int psg, int adpcmA, int adpcmB, int chanCount):
DivPlatformOPN(ext,psg,adpcmA,adpcmB,chanCount,9440540.0, 72, 32, false, 16) {}
DivPlatformOPN(ext,psg,adpcmA,adpcmB,chanCount,9440540.0, 72, 32, false, 16) {
sampleOffA=new unsigned int[32768];
sampleOffB=new unsigned int[32768];
sampleLoaded[0]=new bool[32768];
sampleLoaded[1]=new bool[32768];
}
~DivPlatformYM2610Base() {
delete[] sampleOffA;
delete[] sampleOffB;
delete[] sampleLoaded[0];
delete[] sampleLoaded[1];
}
};
#endif

View file

@ -449,7 +449,7 @@ size_t DivPlatformYMZ280B::getSampleMemUsage(int index) {
bool DivPlatformYMZ280B::isSampleLoaded(int index, int sample) {
if (index!=0) return false;
if (sample<0 || sample>255) return false;
if (sample<0 || sample>32767) return false;
return sampleLoaded[sample];
}
@ -460,8 +460,8 @@ const DivMemoryComposition* DivPlatformYMZ280B::getMemCompo(int index) {
void DivPlatformYMZ280B::renderSamples(int sysID) {
memset(sampleMem,0,getSampleMemCapacity());
memset(sampleOff,0,256*sizeof(unsigned int));
memset(sampleLoaded,0,256*sizeof(bool));
memset(sampleOff,0,32768*sizeof(unsigned int));
memset(sampleLoaded,0,32768*sizeof(bool));
memCompo=DivMemoryComposition();
memCompo.name="Sample ROM";
@ -570,3 +570,14 @@ void DivPlatformYMZ280B::quit() {
delete oscBuf[i];
}
}
// initialization of important arrays
DivPlatformYMZ280B::DivPlatformYMZ280B() {
sampleOff=new unsigned int[32768];
sampleLoaded=new bool[32768];
}
DivPlatformYMZ280B::~DivPlatformYMZ280B() {
delete[] sampleOff;
delete[] sampleLoaded;
}

View file

@ -44,8 +44,8 @@ class DivPlatformYMZ280B: public DivDispatch {
DivDispatchOscBuffer* oscBuf[8];
bool isMuted[8];
int chipType;
unsigned int sampleOff[256];
bool sampleLoaded[256];
unsigned int* sampleOff;
bool* sampleLoaded;
unsigned char* sampleMem;
size_t sampleMemLen;
@ -86,6 +86,8 @@ class DivPlatformYMZ280B: public DivDispatch {
void setFlags(const DivConfig& flags);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
DivPlatformYMZ280B();
~DivPlatformYMZ280B();
private:
void writeOutVol(int ch);
};