diff --git a/CMakeLists.txt b/CMakeLists.txt index a5e91fb00..2051eb8d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -455,6 +455,8 @@ src/engine/platform/sound/c64_fp/WaveformCalculator.cpp src/engine/platform/sound/c64_fp/WaveformGenerator.cpp src/engine/platform/sound/c64_fp/resample/SincResampler.cpp +src/engine/platform/sound/c64_d/dsid.c + src/engine/platform/sound/tia/AudioChannel.cpp src/engine/platform/sound/tia/Audio.cpp diff --git a/src/engine/dispatchContainer.cpp b/src/engine/dispatchContainer.cpp index c30d7f231..3ff58e30e 100644 --- a/src/engine/dispatchContainer.cpp +++ b/src/engine/dispatchContainer.cpp @@ -273,12 +273,12 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do break; case DIV_SYSTEM_C64_6581: dispatch=new DivPlatformC64; - ((DivPlatformC64*)dispatch)->setFP(eng->getConfInt("c64Core",1)==1); + ((DivPlatformC64*)dispatch)->setCore(eng->getConfInt("c64Core",0)); ((DivPlatformC64*)dispatch)->setChipModel(true); break; case DIV_SYSTEM_C64_8580: dispatch=new DivPlatformC64; - ((DivPlatformC64*)dispatch)->setFP(eng->getConfInt("c64Core",1)==1); + ((DivPlatformC64*)dispatch)->setCore(eng->getConfInt("c64Core",0)); ((DivPlatformC64*)dispatch)->setChipModel(false); break; case DIV_SYSTEM_YM2151: diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 6d03ba2f4..469890bca 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -65,19 +65,29 @@ const char** DivPlatformC64::getRegisterSheet() { } void DivPlatformC64::acquire(short** buf, size_t len) { - int dcOff=isFP?0:sid.get_dc(0); + int dcOff=(sidCore)?0:sid.get_dc(0); for (size_t i=0; i=4) { + writeOscBuf=0; + oscBuf[0]->data[oscBuf[0]->needle++]=sid_d->lastOut[0]; + oscBuf[1]->data[oscBuf[1]->needle++]=sid_d->lastOut[1]; + oscBuf[2]->data[oscBuf[2]->needle++]=sid_d->lastOut[2]; + } + } else if (sidCore==1) { sid_fp.clock(4,&buf[0][i]); if (++writeOscBuf>=4) { writeOscBuf=0; @@ -452,7 +462,14 @@ int DivPlatformC64::dispatch(DivCommand c) { void DivPlatformC64::muteChannel(int ch, bool mute) { isMuted[ch]=mute; - if (isFP) { + if (sidCore==2) { + dSID_setMuteMask( + sid_d, + (isMuted[0]?1:0)| + (isMuted[1]?2:0)| + (isMuted[2]?4:0) + ); + } else if (sidCore==1) { sid_fp.mute(ch,mute); } else { sid.set_is_muted(ch,mute); @@ -514,7 +531,7 @@ bool DivPlatformC64::getWantPreNote() { } float DivPlatformC64::getPostAmp() { - return isFP?3.0f:1.0f; + return (sidCore==1)?3.0f:1.0f; } void DivPlatformC64::reset() { @@ -524,7 +541,9 @@ void DivPlatformC64::reset() { chan[i].std.setEngine(parent); } - if (isFP) { + if (sidCore==2) { + dSID_init(sid_d,chipClock,rate,sidIs6581?6581:8580,1); + } else if (sidCore==1) { sid_fp.reset(); sid_fp.clockSilent(16000); } else { @@ -555,22 +574,27 @@ void DivPlatformC64::poke(std::vector& wlist) { void DivPlatformC64::setChipModel(bool is6581) { if (is6581) { - if (isFP) { + if (sidCore==2) { + // do nothing + } else if (sidCore==1) { sid_fp.setChipModel(reSIDfp::MOS6581); } else { sid.set_chip_model(MOS6581); } } else { - if (isFP) { + if (sidCore==2) { + // do nothing + } else if (sidCore==1) { sid_fp.setChipModel(reSIDfp::MOS8580); } else { sid.set_chip_model(MOS8580); } } + sidIs6581=is6581; } -void DivPlatformC64::setFP(bool fp) { - isFP=fp; +void DivPlatformC64::setCore(unsigned char which) { + sidCore=which; } void DivPlatformC64::setFlags(const DivConfig& flags) { @@ -591,9 +615,9 @@ void DivPlatformC64::setFlags(const DivConfig& flags) { for (int i=0; i<3; i++) { oscBuf[i]->rate=rate/16; } - if (isFP) { + if (sidCore>0) { rate/=4; - sid_fp.setSamplingParameters(chipClock,reSIDfp::DECIMATE,rate,0); + if (sidCore==1) sid_fp.setSamplingParameters(chipClock,reSIDfp::DECIMATE,rate,0); } keyPriority=flags.getBool("keyPriority",true); testAD=((flags.getInt("testAttack",0)&15)<<4)|(flags.getInt("testDecay",0)&15); @@ -609,6 +633,13 @@ int DivPlatformC64::init(DivEngine* p, int channels, int sugRate, const DivConfi isMuted[i]=false; oscBuf[i]=new DivDispatchOscBuffer; } + + if (sidCore==2) { + sid_d=new struct SID_chip; + } else { + sid_d=NULL; + } + setFlags(flags); reset(); @@ -620,6 +651,7 @@ void DivPlatformC64::quit() { for (int i=0; i<3; i++) { delete oscBuf[i]; } + if (sid_d!=NULL) delete sid_d; } DivPlatformC64::~DivPlatformC64() { diff --git a/src/engine/platform/c64.h b/src/engine/platform/c64.h index b9b30b6ec..77c236760 100644 --- a/src/engine/platform/c64.h +++ b/src/engine/platform/c64.h @@ -24,6 +24,7 @@ #include #include "sound/c64/sid.h" #include "sound/c64_fp/SID.h" +#include "sound/c64_d/dsid.h" class DivPlatformC64: public DivDispatch { struct Channel: public SharedChannel { @@ -64,15 +65,16 @@ class DivPlatformC64: public DivDispatch { unsigned char filtControl, filtRes, vol; unsigned char writeOscBuf; + unsigned char sidCore; int filtCut, resetTime; - bool isFP; - bool keyPriority; + bool keyPriority, sidIs6581; unsigned char chanOrder[3]; unsigned char testAD, testSR; SID sid; reSIDfp::SID sid_fp; + struct SID_chip* sid_d; unsigned char regPool[32]; friend void putDispatchChip(void*,int); @@ -105,7 +107,7 @@ class DivPlatformC64: public DivDispatch { const char** getRegisterSheet(); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); void setChipModel(bool is6581); - void setFP(bool fp); + void setCore(unsigned char which); void quit(); ~DivPlatformC64(); }; diff --git a/src/engine/platform/sound/c64_d/dsid.c b/src/engine/platform/sound/c64_d/dsid.c index 884d8669c..72bf6596a 100644 --- a/src/engine/platform/sound/c64_d/dsid.c +++ b/src/engine/platform/sound/c64_d/dsid.c @@ -3,11 +3,30 @@ #include #include // memset, memcpy -// defle internals -void waveforms_add_sample(uint8_t id, int16_t left, int16_t right); +#define SID_OUT_SCALE (0x10000 * 3 * 16) -struct SID_chip sid; -static char init_wf = 1; +// CONTROL +#define GAT 0x01 +#define SYN 0x02 +#define RNG 0x04 +#define TST 0x08 +#define TRI 0x10 +#define SAW 0x20 +#define PUL 0x40 +#define NOI 0x80 + +#define _HZ 0x10 +#define DECSUS 0x40 +#define ATK 0x80 + +// filter mode (high) +#define LP 0x10 +#define BP 0x20 +#define HP 0x40 +#define OFF3 0x80 + +#define waveforms_add_sample(_id,_s) \ + sid->lastOut[_id]=(_s); const int Aexp[256] = { 1, 30, 30, 30, 30, 30, 30, 16, 16, 16, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, @@ -22,7 +41,7 @@ const int Aexp[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; double cmbWF(int chn, int *wfa, int index, int differ6581, struct SID_globals *g) { - if (differ6581 && sid.g.model == 6581) + if (differ6581 && g->model == 6581) index &= 0x7FF; return wfa[index]; @@ -42,60 +61,53 @@ void cCmbWF(int *wfa, double bitmul, double bstr, double trh) { } } -void dSID_init(double samplingRate, int model) { +void dSID_init(struct SID_chip* sid, double clockRate, double samplingRate, int model, unsigned char init_wf) { if (model == 6581) { - sid.g.model = 6581; + sid->g.model = 6581; } else { - sid.g.model = 8580; + sid->g.model = 8580; } - // SID area - for (int i = 0xD400; i <= 0xD7FF; i++) - sid.M[i] = 0; - // IO area - for (int i = 0xDE00; i <= 0xDFFF; i++) - sid.M[i] = 0; - - memset(sid.SIDct, 0, sizeof(sid.SIDct)); + memset(sid->M,0,MemLen); + memset(sid->SIDct, 0, sizeof(sid->SIDct)); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - sid.SIDct[i].ch[j].Ast = _HZ; - sid.SIDct[i].ch[j].nLFSR = 0x7FFFF8; - sid.SIDct[i].ch[j].prevwfout = 0; + sid->SIDct[i].ch[j].Ast = _HZ; + sid->SIDct[i].ch[j].nLFSR = 0x7FFFF8; + sid->SIDct[i].ch[j].prevwfout = 0; } - sid.SIDct[i].ch[0].FSW = 1; - sid.SIDct[i].ch[1].FSW = 2; - sid.SIDct[i].ch[2].FSW = 4; + sid->SIDct[i].ch[0].FSW = 1; + sid->SIDct[i].ch[1].FSW = 2; + sid->SIDct[i].ch[2].FSW = 4; } - sid.g.ctfr = -2.0 * 3.14 * (12500.0 / 256.0) / samplingRate, - sid.g.ctf_ratio_6581 = -2.0 * 3.14 * (20000.0 / 256.0) / samplingRate; - sid.g.ckr = (double) SID_CLK / samplingRate; + sid->g.ctfr = -2.0 * 3.14 * (12500.0 / 256.0) / samplingRate, + sid->g.ctf_ratio_6581 = -2.0 * 3.14 * (20000.0 / 256.0) / samplingRate; + sid->g.ckr = clockRate / samplingRate; const double bAprd[16] = {9, 32 * 1, 63 * 1, 95 * 1, 149 * 1, 220 * 1, 267 * 1, 313 * 1, 392 * 1, 977 * 1, 1954 * 1, 3126 * 1, 3907 * 1, 11720 * 1, 19532 * 1, 31251 * 1}; const int bAstp[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; - memcpy(&sid.g.Aprd, &bAprd, sizeof(bAprd)); - memcpy(&sid.g.Astp, &bAstp, sizeof(bAstp)); + memcpy(&sid->g.Aprd, &bAprd, sizeof(bAprd)); + memcpy(&sid->g.Astp, &bAstp, sizeof(bAstp)); if (init_wf) { - cCmbWF(sid.g.trsaw, 0.8, 2.4, 0.64); - cCmbWF(sid.g.pusaw, 1.4, 1.9, 0.68); - cCmbWF(sid.g.Pulsetrsaw, 0.8, 2.5, 0.64); - init_wf = 0; + cCmbWF(sid->g.trsaw, 0.8, 2.4, 0.64); + cCmbWF(sid->g.pusaw, 1.4, 1.9, 0.68); + cCmbWF(sid->g.Pulsetrsaw, 0.8, 2.5, 0.64); } - double prd0 = sid.g.ckr > 9 ? sid.g.ckr : 9; - sid.g.Aprd[0] = prd0; - sid.g.Astp[0] = ceil(prd0 / 9); + double prd0 = sid->g.ckr > 9 ? sid->g.ckr : 9; + sid->g.Aprd[0] = prd0; + sid->g.Astp[0] = ceil(prd0 / 9); } -double dSID_render() { +double dSID_render(struct SID_chip* sid) { double flin = 0, output = 0; double wfout = 0; - for (int chn = 0; chn < SID_CHA; chn++) { - struct SIDVOICE *voic = &((struct SIDMEM *) (sid.M))->v[chn]; - double pgt = (sid.SIDct->ch[chn].Ast & GAT); + for (int chn = 0; chn < 3; chn++) { + struct SIDVOICE *voic = &((struct SIDMEM *) (sid->M))->v[chn]; + double pgt = (sid->SIDct->ch[chn].Ast & GAT); uint8_t ctrl = voic->control; uint8_t wf = ctrl & 0xF0; uint8_t test = ctrl & TST; @@ -103,78 +115,78 @@ double dSID_render() { double tmp = 0; if (pgt != (ctrl & GAT)) { if (pgt) { - sid.SIDct->ch[chn].Ast &= 0xFF - (GAT | ATK | DECSUS); + sid->SIDct->ch[chn].Ast &= 0xFF - (GAT | ATK | DECSUS); } else { - sid.SIDct->ch[chn].Ast = (GAT | ATK | DECSUS); - if ((SR & 0xF) > (sid.SIDct->ch[chn].pSR & 0xF)) + sid->SIDct->ch[chn].Ast = (GAT | ATK | DECSUS); + if ((SR & 0xF) > (sid->SIDct->ch[chn].pSR & 0xF)) tmp = 1; } } - sid.SIDct->ch[chn].pSR = SR; - sid.SIDct->ch[chn].rcnt += sid.g.ckr; - if (sid.SIDct->ch[chn].rcnt >= 0x8000) - sid.SIDct->ch[chn].rcnt -= 0x8000; + sid->SIDct->ch[chn].pSR = SR; + sid->SIDct->ch[chn].rcnt += sid->g.ckr; + if (sid->SIDct->ch[chn].rcnt >= 0x8000) + sid->SIDct->ch[chn].rcnt -= 0x8000; static double step; double prd; - if (sid.SIDct->ch[chn].Ast & ATK) { + if (sid->SIDct->ch[chn].Ast & ATK) { step = voic->attack; - prd = sid.g.Aprd[(int) step]; - } else if (sid.SIDct->ch[chn].Ast & DECSUS) { + prd = sid->g.Aprd[(int) step]; + } else if (sid->SIDct->ch[chn].Ast & DECSUS) { step = voic->decay; - prd = sid.g.Aprd[(int) step]; + prd = sid->g.Aprd[(int) step]; } else { step = SR & 0xF; - prd = sid.g.Aprd[(int) step]; + prd = sid->g.Aprd[(int) step]; } - step = sid.g.Astp[(int) step]; - if (sid.SIDct->ch[chn].rcnt >= prd && sid.SIDct->ch[chn].rcnt < prd + sid.g.ckr && + step = sid->g.Astp[(int) step]; + if (sid->SIDct->ch[chn].rcnt >= prd && sid->SIDct->ch[chn].rcnt < prd + sid->g.ckr && tmp == 0) { - sid.SIDct->ch[chn].rcnt -= prd; - if ((sid.SIDct->ch[chn].Ast & ATK) || - ++sid.SIDct->ch[chn].expcnt == Aexp[(int) sid.SIDct->ch[chn].envcnt]) { - if (!(sid.SIDct->ch[chn].Ast & _HZ)) { - if (sid.SIDct->ch[chn].Ast & ATK) { - sid.SIDct->ch[chn].envcnt += step; - if (sid.SIDct->ch[chn].envcnt >= 0xFF) { - sid.SIDct->ch[chn].envcnt = 0xFF; - sid.SIDct->ch[chn].Ast &= 0xFF - ATK; + sid->SIDct->ch[chn].rcnt -= prd; + if ((sid->SIDct->ch[chn].Ast & ATK) || + ++sid->SIDct->ch[chn].expcnt == Aexp[(int) sid->SIDct->ch[chn].envcnt]) { + if (!(sid->SIDct->ch[chn].Ast & _HZ)) { + if (sid->SIDct->ch[chn].Ast & ATK) { + sid->SIDct->ch[chn].envcnt += step; + if (sid->SIDct->ch[chn].envcnt >= 0xFF) { + sid->SIDct->ch[chn].envcnt = 0xFF; + sid->SIDct->ch[chn].Ast &= 0xFF - ATK; } - } else if (!(sid.SIDct->ch[chn].Ast & DECSUS) || - sid.SIDct->ch[chn].envcnt > (SR >> 4) + (SR & 0xF0)) { - sid.SIDct->ch[chn].envcnt -= step; - if (sid.SIDct->ch[chn].envcnt <= 0 && - sid.SIDct->ch[chn].envcnt + step != 0) { - sid.SIDct->ch[chn].envcnt = 0; - sid.SIDct->ch[chn].Ast |= _HZ; + } else if (!(sid->SIDct->ch[chn].Ast & DECSUS) || + sid->SIDct->ch[chn].envcnt > (SR >> 4) + (SR & 0xF0)) { + sid->SIDct->ch[chn].envcnt -= step; + if (sid->SIDct->ch[chn].envcnt <= 0 && + sid->SIDct->ch[chn].envcnt + step != 0) { + sid->SIDct->ch[chn].envcnt = 0; + sid->SIDct->ch[chn].Ast |= _HZ; } } } - sid.SIDct->ch[chn].expcnt = 0; + sid->SIDct->ch[chn].expcnt = 0; } else { } } - sid.SIDct->ch[chn].envcnt = (int) sid.SIDct->ch[chn].envcnt & 0xFF; - double aAdd = (voic->freq_low + voic->freq_high * 256) * sid.g.ckr; - if (test || ((ctrl & SYN) && sid.SIDct->sMSBrise)) { - sid.SIDct->ch[chn].pacc = 0; + sid->SIDct->ch[chn].envcnt = (int) sid->SIDct->ch[chn].envcnt & 0xFF; + double aAdd = (voic->freq_low + voic->freq_high * 256) * sid->g.ckr; + if (test || ((ctrl & SYN) && sid->SIDct->sMSBrise)) { + sid->SIDct->ch[chn].pacc = 0; } else { - sid.SIDct->ch[chn].pacc += aAdd; - if (sid.SIDct->ch[chn].pacc > 0xFFFFFF) - sid.SIDct->ch[chn].pacc -= 0x1000000; + sid->SIDct->ch[chn].pacc += aAdd; + if (sid->SIDct->ch[chn].pacc > 0xFFFFFF) + sid->SIDct->ch[chn].pacc -= 0x1000000; } - double MSB = (int) sid.SIDct->ch[chn].pacc & 0x800000; - sid.SIDct->sMSBrise = (MSB > ((int) sid.SIDct->ch[chn].pracc & 0x800000)) ? 1 : 0; + double MSB = (int) sid->SIDct->ch[chn].pacc & 0x800000; + sid->SIDct->sMSBrise = (MSB > ((int) sid->SIDct->ch[chn].pracc & 0x800000)) ? 1 : 0; if (wf & NOI) { - tmp = sid.SIDct->ch[chn].nLFSR; - if ((((int) sid.SIDct->ch[chn].pacc & 0x100000) != - ((int) sid.SIDct->ch[chn].pracc & 0x100000)) || + tmp = sid->SIDct->ch[chn].nLFSR; + if ((((int) sid->SIDct->ch[chn].pacc & 0x100000) != + ((int) sid->SIDct->ch[chn].pracc & 0x100000)) || aAdd >= 0x100000) { step = ((int) tmp & 0x400000) ^ (((int) tmp & 0x20000) << 5); tmp = (((int) tmp << 1) + (step > 0 || test)) & 0x7FFFFF; - sid.SIDct->ch[chn].nLFSR = tmp; + sid->SIDct->ch[chn].nLFSR = tmp; } wfout = (wf & 0x70) ? 0 : (((int) tmp & 0x100000) >> 5) + (((int) tmp & 0x40000) >> 4) + @@ -189,7 +201,7 @@ double dSID_render() { tmp = (int) tmp ^ 0xFFFF; if (pw > tmp) pw = tmp; - tmp = (int) sid.SIDct->ch[chn].pacc >> 8; + tmp = (int) sid->SIDct->ch[chn].pacc >> 8; if (wf == PUL) { int lel = ((int) aAdd >> 16); if (lel > 0) { @@ -220,23 +232,23 @@ double dSID_render() { if (wf & TRI) { if (wf & SAW) { wfout = - (wfout) ? cmbWF(chn, sid.g.Pulsetrsaw, (int) tmp >> 4, 1, &sid.g) : 0; + (wfout) ? cmbWF(chn, sid->g.Pulsetrsaw, (int) tmp >> 4, 1, &sid->g) : 0; } else { - tmp = (int) sid.SIDct->ch[chn].pacc ^ (ctrl & RNG ? sid.SIDct->sMSB : 0); + tmp = (int) sid->SIDct->ch[chn].pacc ^ (ctrl & RNG ? sid->SIDct->sMSB : 0); wfout = (wfout) - ? cmbWF(chn, sid.g.pusaw, + ? cmbWF(chn, sid->g.pusaw, ((int) tmp ^ ((int) tmp & 0x800000 ? 0xFFFFFF : 0)) >> 11, - 0, &sid.g) + 0, &sid->g) : 0; } } else if (wf & SAW) - wfout = (wfout) ? cmbWF(chn, sid.g.pusaw, (int) tmp >> 4, 1, &sid.g) : 0; + wfout = (wfout) ? cmbWF(chn, sid->g.pusaw, (int) tmp >> 4, 1, &sid->g) : 0; } } else if (wf & SAW) { - wfout = (int) sid.SIDct->ch[chn].pacc >> 8; + wfout = (int) sid->SIDct->ch[chn].pacc >> 8; if (wf & TRI) - wfout = cmbWF(chn, sid.g.trsaw, (int) wfout >> 4, 1, &sid.g); + wfout = cmbWF(chn, sid->g.trsaw, (int) wfout >> 4, 1, &sid->g); else { step = aAdd / 0x1200000; wfout += wfout * step; @@ -244,103 +256,107 @@ double dSID_render() { wfout = 0xFFFF - (wfout - 0x10000) / step; } } else if (wf & TRI) { - tmp = (int) sid.SIDct->ch[chn].pacc ^ (ctrl & RNG ? sid.SIDct->sMSB : 0); + tmp = (int) sid->SIDct->ch[chn].pacc ^ (ctrl & RNG ? sid->SIDct->sMSB : 0); wfout = ((int) tmp ^ ((int) tmp & 0x800000 ? 0xFFFFFF : 0)) >> 7; } if (wf) - sid.SIDct->ch[chn].prevwfout = wfout; + sid->SIDct->ch[chn].prevwfout = wfout; else { - wfout = sid.SIDct->ch[chn].prevwfout; + wfout = sid->SIDct->ch[chn].prevwfout; } - sid.SIDct->ch[chn].pracc = sid.SIDct->ch[chn].pacc; - sid.SIDct->sMSB = MSB; + sid->SIDct->ch[chn].pracc = sid->SIDct->ch[chn].pacc; + sid->SIDct->sMSB = MSB; // double preflin = flin; - if ((sid.mute_mask & (1 << chn))) { - if (sid.M[0x17] & sid.SIDct->ch[chn].FSW) { - double chnout = (wfout - 0x8000) * (sid.SIDct->ch[chn].envcnt / 256); + if ((sid->mute_mask & (1 << chn))) { + if (sid->M[0x17] & sid->SIDct->ch[chn].FSW) { + double chnout = (wfout - 0x8000) * (sid->SIDct->ch[chn].envcnt / 256); flin += chnout; - // defle fake filter for solo waveform ahead + // fake filter for solo waveform ahead // mostly copypasted from below double fakeflin = chnout; double fakeflout = 0; - static double fakeplp[SID_CHA] = {0}; - static double fakepbp[SID_CHA] = {0}; - double ctf = ((double) (sid.M[0x15] & 7)) / 8 + sid.M[0x16] + 0.2; + static double fakeplp[3] = {0}; + static double fakepbp[3] = {0}; + double ctf = ((double) (sid->M[0x15] & 7)) / 8 + sid->M[0x16] + 0.2; double reso; - if (sid.g.model == 8580) { - ctf = 1 - exp(ctf * sid.g.ctfr); - reso = pow(2, ((double) (4 - (double) (sid.M[0x17] >> 4)) / 8)); + if (sid->g.model == 8580) { + ctf = 1 - exp(ctf * sid->g.ctfr); + reso = pow(2, ((double) (4 - (double) (sid->M[0x17] >> 4)) / 8)); } else { if (ctf < 24) ctf = 0.035; else - ctf = 1 - 1.263 * exp(ctf * sid.g.ctf_ratio_6581); - reso = (sid.M[0x17] > 0x5F) ? 8.0 / (double) (sid.M[0x17] >> 4) : 1.41; + ctf = 1 - 1.263 * exp(ctf * sid->g.ctf_ratio_6581); + reso = (sid->M[0x17] > 0x5F) ? 8.0 / (double) (sid->M[0x17] >> 4) : 1.41; } double tmp = fakeflin + fakepbp[chn] * reso + fakeplp[chn]; - if (sid.M[0x18] & HP) + if (sid->M[0x18] & HP) fakeflout -= tmp; tmp = fakepbp[chn] - tmp * ctf; fakepbp[chn] = tmp; - if (sid.M[0x18] & BP) + if (sid->M[0x18] & BP) fakeflout -= tmp; tmp = fakeplp[chn] + tmp * ctf; fakeplp[chn] = tmp; - if (sid.M[0x18] & LP) + if (sid->M[0x18] & LP) fakeflout += tmp; - double defle_wf_out = (fakeflout / SID_OUT_SCALE) * (sid.M[0x18] & 0xF) * 65535; - waveforms_add_sample(1 + chn, defle_wf_out, defle_wf_out); - } else if ((chn % SID_CHA) != 2 || !(sid.M[0x18] & OFF3)) { - double chnout = (wfout - 0x8000) * (sid.SIDct->ch[chn].envcnt / 256); + double wf_out = (fakeflout / SID_OUT_SCALE) * (sid->M[0x18] & 0xF) * 65535; + waveforms_add_sample(1 + chn, wf_out); + } else if ((chn % 3) != 2 || !(sid->M[0x18] & OFF3)) { + double chnout = (wfout - 0x8000) * (sid->SIDct->ch[chn].envcnt / 256); output += chnout; - double defle_wf_out = (chnout / SID_OUT_SCALE) * (sid.M[0x18] & 0xF) * 65535; - waveforms_add_sample(1 + chn, defle_wf_out, defle_wf_out); + double wf_out = (chnout / SID_OUT_SCALE) * (sid->M[0x18] & 0xF) * 65535; + waveforms_add_sample(1 + chn, wf_out); } } else { - waveforms_add_sample(1 + chn, 0, 0); + waveforms_add_sample(1 + chn, 0); } } int M1 = 0; if (M1 & 3) - sid.M[0x1B] = (int) wfout >> 8; - sid.M[0x1C] = sid.SIDct->ch[2].envcnt; + sid->M[0x1B] = (int) wfout >> 8; + sid->M[0x1C] = sid->SIDct->ch[2].envcnt; - double ctf = ((double) (sid.M[0x15] & 7)) / 8 + sid.M[0x16] + 0.2; + double ctf = ((double) (sid->M[0x15] & 7)) / 8 + sid->M[0x16] + 0.2; double reso; - if (sid.g.model == 8580) { - ctf = 1 - exp(ctf * sid.g.ctfr); - reso = pow(2, ((double) (4 - (double) (sid.M[0x17] >> 4)) / 8)); + if (sid->g.model == 8580) { + ctf = 1 - exp(ctf * sid->g.ctfr); + reso = pow(2, ((double) (4 - (double) (sid->M[0x17] >> 4)) / 8)); } else { if (ctf < 24) ctf = 0.035; else - ctf = 1 - 1.263 * exp(ctf * sid.g.ctf_ratio_6581); - reso = (sid.M[0x17] > 0x5F) ? 8.0 / (double) (sid.M[0x17] >> 4) : 1.41; + ctf = 1 - 1.263 * exp(ctf * sid->g.ctf_ratio_6581); + reso = (sid->M[0x17] > 0x5F) ? 8.0 / (double) (sid->M[0x17] >> 4) : 1.41; } - double tmp = flin + sid.SIDct->pbp * reso + sid.SIDct->plp; - if (sid.M[0x18] & HP) + double tmp = flin + sid->SIDct->pbp * reso + sid->SIDct->plp; + if (sid->M[0x18] & HP) output -= tmp; - tmp = sid.SIDct->pbp - tmp * ctf; - sid.SIDct->pbp = tmp; - if (sid.M[0x18] & BP) + tmp = sid->SIDct->pbp - tmp * ctf; + sid->SIDct->pbp = tmp; + if (sid->M[0x18] & BP) output -= tmp; - tmp = sid.SIDct->plp + tmp * ctf; - sid.SIDct->plp = tmp; - if (sid.M[0x18] & LP) + tmp = sid->SIDct->plp + tmp * ctf; + sid->SIDct->plp = tmp; + if (sid->M[0x18] & LP) output += tmp; - return (output / SID_OUT_SCALE) * (sid.M[0x18] & 0xF); + return (output / SID_OUT_SCALE) * (sid->M[0x18] & 0xF); } -void dSID_setMuteMask(int mute_mask) { - sid.mute_mask = mute_mask; +void dSID_setMuteMask(struct SID_chip* sid, int mute_mask) { + sid->mute_mask = mute_mask; } -float dSID_getVolume(int channel) { - if ((sid.M[0x18] & 0xF) == 0) +float dSID_getVolume(struct SID_chip* sid, int channel) { + if ((sid->M[0x18] & 0xF) == 0) return 0; - return sid.SIDct[0].ch[channel].envcnt / 256.0f; + return sid->SIDct[0].ch[channel].envcnt / 256.0f; +} + +void dSID_write(struct SID_chip* sid, unsigned char addr, unsigned char val) { + sid->M[addr&0x1f]=val; } diff --git a/src/engine/platform/sound/c64_d/dsid.h b/src/engine/platform/sound/c64_d/dsid.h index 31d524f18..59b83eb32 100644 --- a/src/engine/platform/sound/c64_d/dsid.h +++ b/src/engine/platform/sound/c64_d/dsid.h @@ -1,36 +1,12 @@ -#pragma once +#ifndef DSID_H +#define DSID_H + +#ifdef __cplusplus +extern "C" { +#endif #include -#define SID_CLK 985248 -#define SID_CHA 3 -#define SID_OUT_SCALE (0x10000 * SID_CHA * 16) - -// TODO: prefix SID_ - -// CONTROL -#define GAT 0x01 -#define SYN 0x02 -#define RNG 0x04 -#define TST 0x08 -#define TRI 0x10 -#define SAW 0x20 -#define PUL 0x40 -#define NOI 0x80 - -#define _HZ 0x10 -#define DECSUS 0x40 -#define ATK 0x80 - -// TODO: change -// filter mode (high) -#define LP 0x10 -#define BP 0x20 -#define HP 0x40 -#define OFF3 0x80 - -extern const int Aexp[256]; - struct SID_ctx_chan { double rcnt; double envcnt; @@ -67,7 +43,7 @@ struct SIDVOICE { }; struct SIDMEM { - struct SIDVOICE v[SID_CHA]; + struct SIDVOICE v[3]; uint8_t UNUSED : 4; uint8_t cutoff_low : 4; uint8_t cutoff_high; @@ -101,12 +77,19 @@ struct SID_chip { struct SID_globals g; struct SID_ctx SIDct[3]; uint8_t M[MemLen]; + int16_t lastOut[3]; int mute_mask; }; -extern struct SID_chip sid; +double dSID_render(struct SID_chip* sid); +void dSID_init(struct SID_chip* sid, double clockRate, double samplingRate, int model, unsigned char init_wf); +float dSID_getVolume(struct SID_chip* sid, int channel); +void dSID_setMuteMask(struct SID_chip* sid, int mute_mask); -double dSID_render(); -void dSID_init(double samplingRate, int model); -float dSID_getVolume(int channel); -void dSID_setMuteMask(int mute_mask); +void dSID_write(struct SID_chip* sid, unsigned char addr, unsigned char val); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/gui/debug.cpp b/src/gui/debug.cpp index 49d568b3c..60806bde1 100644 --- a/src/gui/debug.cpp +++ b/src/gui/debug.cpp @@ -356,7 +356,6 @@ void putDispatchChip(void* data, int type) { ImGui::Text("- filtCut: %d",ch->filtCut); ImGui::Text("- resetTime: %d",ch->resetTime); COMMON_CHIP_DEBUG_BOOL; - ImGui::TextColored(ch->isFP?colorOn:colorOff,">> IsFP"); break; } case DIV_SYSTEM_ARCADE: diff --git a/src/gui/gui.h b/src/gui/gui.h index a8befff29..b3bd9539c 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1544,7 +1544,7 @@ class FurnaceGUI { snCore(0), nesCore(0), fdsCore(0), - c64Core(1), + c64Core(0), pokeyCore(1), opnCore(1), pcSpeakerOutMethod(0), diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 882bc8075..f67e8e406 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -116,7 +116,8 @@ const char* nesCores[]={ const char* c64Cores[]={ "reSID", - "reSIDfp" + "reSIDfp", + "dSID" }; const char* pokeyCores[]={ @@ -1254,7 +1255,7 @@ void FurnaceGUI::drawSettings() { ImGui::Text("SID core"); ImGui::SameLine(); - ImGui::Combo("##C64Core",&settings.c64Core,c64Cores,2); + ImGui::Combo("##C64Core",&settings.c64Core,c64Cores,3); ImGui::Text("POKEY core"); ImGui::SameLine(); @@ -2645,7 +2646,7 @@ void FurnaceGUI::syncSettings() { settings.snCore=e->getConfInt("snCore",0); settings.nesCore=e->getConfInt("nesCore",0); settings.fdsCore=e->getConfInt("fdsCore",0); - settings.c64Core=e->getConfInt("c64Core",1); + settings.c64Core=e->getConfInt("c64Core",0); settings.pokeyCore=e->getConfInt("pokeyCore",1); settings.opnCore=e->getConfInt("opnCore",1); settings.pcSpeakerOutMethod=e->getConfInt("pcSpeakerOutMethod",0); @@ -2791,7 +2792,7 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.snCore,0,1); clampSetting(settings.nesCore,0,1); clampSetting(settings.fdsCore,0,1); - clampSetting(settings.c64Core,0,1); + clampSetting(settings.c64Core,0,2); clampSetting(settings.pokeyCore,0,1); clampSetting(settings.opnCore,0,1); clampSetting(settings.pcSpeakerOutMethod,0,4); @@ -2971,7 +2972,7 @@ void FurnaceGUI::commitSettings() { settings.snCore!=e->getConfInt("snCore",0) || settings.nesCore!=e->getConfInt("nesCore",0) || settings.fdsCore!=e->getConfInt("fdsCore",0) || - settings.c64Core!=e->getConfInt("c64Core",1) || + settings.c64Core!=e->getConfInt("c64Core",0) || settings.pokeyCore!=e->getConfInt("pokeyCore",1) || settings.opnCore!=e->getConfInt("opnCore",1) );