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