AtomicSSG AY core

This commit is contained in:
tildearrow 2024-04-29 15:21:58 -05:00
parent 8db06f359e
commit aa966a5466
7 changed files with 202 additions and 81 deletions

View file

@ -393,6 +393,11 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
break; break;
case DIV_SYSTEM_AY8910: case DIV_SYSTEM_AY8910:
dispatch=new DivPlatformAY8910; dispatch=new DivPlatformAY8910;
if (isRender) {
((DivPlatformAY8910*)dispatch)->setCore(eng->getConfInt("ayCoreRender",0)==1);
} else {
((DivPlatformAY8910*)dispatch)->setCore(eng->getConfInt("ayCore",0)==1);
}
break; break;
case DIV_SYSTEM_AY8930: case DIV_SYSTEM_AY8930:
dispatch=new DivPlatformAY8930; dispatch=new DivPlatformAY8930;

View file

@ -169,7 +169,7 @@ void DivPlatformAY8910::checkWrites() {
} }
} }
void DivPlatformAY8910::acquire(short** buf, size_t len) { void DivPlatformAY8910::acquire_mame(short** buf, size_t len) {
if (ayBufLen<len) { if (ayBufLen<len) {
ayBufLen=len; ayBufLen=len;
for (int i=0; i<3; i++) { for (int i=0; i<3; i++) {
@ -212,6 +212,42 @@ void DivPlatformAY8910::acquire(short** buf, size_t len) {
} }
} }
void DivPlatformAY8910::acquire_atomic(short** buf, size_t len) {
for (size_t i=0; i<len; i++) {
runDAC();
if (!writes.empty()) {
QueuedWrite w=writes.front();
SSG_Write(&ay_atomic,w.addr&0x0f,w.val);
regPool[w.addr&0x0f]=w.val;
writes.pop();
}
SSG_Clock(&ay_atomic,0);
SSG_Clock(&ay_atomic,1);
if (stereo) {
buf[0][i]=ay_atomic.o_analog[0]+ay_atomic.o_analog[1]+((ay_atomic.o_analog[2]*stereoSep)>>8);
buf[1][i]=((ay_atomic.o_analog[0]*stereoSep)>>8)+ay_atomic.o_analog[1]+ay_atomic.o_analog[2];
} else {
buf[0][i]=ay_atomic.o_analog[0]+ay_atomic.o_analog[1]+ay_atomic.o_analog[2];
buf[1][i]=buf[0][i];
}
oscBuf[0]->data[oscBuf[0]->needle++]=ay_atomic.o_analog[0];
oscBuf[1]->data[oscBuf[1]->needle++]=ay_atomic.o_analog[1];
oscBuf[2]->data[oscBuf[2]->needle++]=ay_atomic.o_analog[2];
}
}
void DivPlatformAY8910::acquire(short** buf, size_t len) {
if (selCore) {
acquire_atomic(buf,len);
} else {
acquire_mame(buf,len);
}
}
void DivPlatformAY8910::updateOutSel(bool immediate) { void DivPlatformAY8910::updateOutSel(bool immediate) {
if (immediate) { if (immediate) {
immWrite(0x07, immWrite(0x07,
@ -778,6 +814,12 @@ void DivPlatformAY8910::reset() {
addWrite(0xffffffff,0); addWrite(0xffffffff,0);
} }
SSG_Reset(&ay_atomic);
SSG_SetType(&ay_atomic,
(yamaha?0:1)|
(intellivision?2:0)
);
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
oldWrites[i]=-1; oldWrites[i]=-1;
pendingWrites[i]=-1; pendingWrites[i]=-1;
@ -830,6 +872,10 @@ void DivPlatformAY8910::setExtClockDiv(unsigned int eclk, unsigned char ediv) {
} }
} }
void DivPlatformAY8910::setCore(unsigned char core) {
selCore=core;
}
void DivPlatformAY8910::setFlags(const DivConfig& flags) { void DivPlatformAY8910::setFlags(const DivConfig& flags) {
if (extMode) { if (extMode) {
chipClock=extClock; chipClock=extClock;
@ -888,8 +934,13 @@ void DivPlatformAY8910::setFlags(const DivConfig& flags) {
break; break;
} }
CHECK_CUSTOM_CLOCK; CHECK_CUSTOM_CLOCK;
rate=chipClock/8; if (selCore) {
dacRate=rate; rate=chipClock/2;
dacRate=chipClock*2;
} else {
rate=chipClock/8;
dacRate=rate;
}
} }
for (int i=0; i<3; i++) { for (int i=0; i<3; i++) {
oscBuf[i]->rate=rate; oscBuf[i]->rate=rate;
@ -900,23 +951,27 @@ void DivPlatformAY8910::setFlags(const DivConfig& flags) {
case 1: case 1:
clockSel=flags.getBool("halfClock",false); clockSel=flags.getBool("halfClock",false);
ay=new ym2149_device(rate,clockSel); ay=new ym2149_device(rate,clockSel);
yamaha=true;
sunsoft=false; sunsoft=false;
intellivision=false; intellivision=false;
break; break;
case 2: case 2:
ay=new sunsoft_5b_sound_device(rate); ay=new sunsoft_5b_sound_device(rate);
yamaha=true;
sunsoft=true; sunsoft=true;
intellivision=false; intellivision=false;
clockSel=false; clockSel=false;
break; break;
case 3: case 3:
ay=new ay8914_device(rate); ay=new ay8914_device(rate);
yamaha=false;
sunsoft=false; sunsoft=false;
intellivision=true; intellivision=true;
clockSel=false; clockSel=false;
break; break;
default: default:
ay=new ay8910_device(rate); ay=new ay8910_device(rate);
yamaha=false;
sunsoft=false; sunsoft=false;
intellivision=false; intellivision=false;
clockSel=false; clockSel=false;

View file

@ -22,6 +22,9 @@
#include "../dispatch.h" #include "../dispatch.h"
#include "../../fixedQueue.h" #include "../../fixedQueue.h"
#include "sound/ay8910.h" #include "sound/ay8910.h"
extern "C" {
#include "sound/atomicssg/ssg.h"
}
class DivPlatformAY8910: public DivDispatch { class DivPlatformAY8910: public DivDispatch {
protected: protected:
@ -97,6 +100,9 @@ class DivPlatformAY8910: public DivDispatch {
unsigned char sampleBank; unsigned char sampleBank;
unsigned char stereoSep; unsigned char stereoSep;
unsigned char selCore;
ssg_t ay_atomic;
int delay; int delay;
@ -106,7 +112,7 @@ class DivPlatformAY8910: public DivDispatch {
unsigned char extDiv; unsigned char extDiv;
unsigned char dacRateDiv; unsigned char dacRateDiv;
bool stereo, sunsoft, intellivision, clockSel; bool stereo, sunsoft, intellivision, clockSel, yamaha;
bool ioPortA, ioPortB; bool ioPortA, ioPortB;
unsigned char portAVal, portBVal; unsigned char portAVal, portBVal;
@ -122,6 +128,9 @@ class DivPlatformAY8910: public DivDispatch {
void checkWrites(); void checkWrites();
void updateOutSel(bool immediate=false); void updateOutSel(bool immediate=false);
void acquire_mame(short** buf, size_t len);
void acquire_atomic(short** buf, size_t len);
friend void putDispatchChip(void*,int); friend void putDispatchChip(void*,int);
friend void putDispatchChan(void*,int,int); friend void putDispatchChan(void*,int,int);
@ -135,6 +144,7 @@ class DivPlatformAY8910: public DivDispatch {
int mapVelocity(int ch, float vel); int mapVelocity(int ch, float vel);
unsigned char* getRegisterPool(); unsigned char* getRegisterPool();
int getRegisterPoolSize(); int getRegisterPoolSize();
void setCore(unsigned char core);
void flushWrites(); void flushWrites();
void reset(); void reset();
void forceIns(); void forceIns();

View file

@ -34,76 +34,19 @@ void SSG_Clock(ssg_t* chip, int clk)
{ {
int read = !chip->ic && !chip->input.rd && !chip->input.cs; int read = !chip->ic && !chip->input.rd && !chip->input.cs;
chip->read0 = !chip->ic && !chip->input.rd && !chip->input.cs && !chip->input.a1 && !chip->input.a0; chip->read0 = !chip->ic && !chip->input.rd && !chip->input.cs;
int write = !chip->input.wr && !chip->input.cs; int write = !chip->input.wr && !chip->input.cs;
int writeaddr = chip->ic || (!chip->input.wr && !chip->input.cs && !chip->input.a0); int writeaddr = chip->ic || (!chip->input.wr && !chip->input.cs);
int writedata = !chip->ic && !chip->input.wr && !chip->input.cs && chip->input.a0; int writedata = !chip->ic && !chip->input.wr && !chip->input.cs;
int read1 = !chip->ic && !chip->input.rd && !chip->input.cs && !chip->input.a1 && chip->input.a0; int read1 = !chip->ic && !chip->input.rd && !chip->input.cs;
chip->read2 = !chip->ic && !chip->input.rd && !chip->input.cs && chip->input.a1 && !chip->input.a0; chip->ssg_write0 = writeaddr;
chip->read3 = !chip->ic && !chip->input.rd && !chip->input.cs && chip->input.a1 && chip->input.a0; chip->ssg_write1 = writedata || chip->ic;
chip->write2 = !chip->ic && !chip->input.wr && !chip->input.cs && chip->input.a1 && !chip->input.a0;
chip->write3 = !chip->ic && !chip->input.wr && !chip->input.cs && chip->input.a1 && chip->input.a0;
chip->ssg_write0 = writeaddr && !chip->input.a1;
chip->ssg_write1 = (writedata && !chip->input.a1) || chip->ic;
chip->ssg_read1 = read1; chip->ssg_read1 = read1;
chip->o_data_d = !read; chip->o_data_d = !read;
if (writeaddr)
chip->write0_trig0 = 1;
else if (chip->write0_l[0])
chip->write0_trig0 = 0;
if (chip->clk1)
{
chip->write0_trig1 = chip->write0_trig0;
chip->write0_l[1] = chip->write0_l[0];
}
if (chip->clk2)
{
chip->write0_l[0] = chip->write0_trig1;
chip->write0_l[2] = chip->write0_l[1];
}
chip->write0_en = chip->write0_l[0] && !chip->write0_l[2];
if (writedata)
chip->write1_trig0 = 1;
else if (chip->write1_l[0])
chip->write1_trig0 = 0;
if (chip->clk1)
{
chip->write1_trig1 = chip->write1_trig0;
chip->write1_l[1] = chip->write1_l[0];
}
if (chip->clk2)
{
chip->write1_l[0] = chip->write1_trig1;
chip->write1_l[2] = chip->write1_l[1];
}
chip->write1_en = chip->write1_l[0] && !chip->write1_l[2];
if (writeaddr)
chip->write2_trig0 = 1;
else if (chip->write2_l[0])
chip->write2_trig0 = 0;
if (chip->clk1)
{
chip->write2_trig1 = chip->write2_trig0;
chip->write2_l[1] = chip->write2_l[0];
}
if (chip->clk2)
{
chip->write2_l[0] = chip->write2_trig1;
chip->write2_l[2] = chip->write2_l[1];
}
chip->write2_en = chip->write2_l[0] && !chip->write2_l[2];
if (writedata)
chip->write3_trig0 = 1;
else if (chip->write3_l[0])
chip->write3_trig0 = 0;
if (write) if (write)
chip->data_l = (chip->input.data & 255) | (chip->input.a1 << 8); chip->data_l = (chip->input.data & 255);
if (chip->ic) if (chip->ic)
chip->data_bus2 |= 0x2f; chip->data_bus2 |= 0x2f;
@ -128,12 +71,12 @@ void SSG_Clock(ssg_t* chip, int clk)
if (chip->ic) if (chip->ic)
chip->ssg_ssg_addr = 0; chip->ssg_ssg_addr = 0;
else if (chip->ssg_write0) else if (chip->ssg_write0)
chip->ssg_ssg_addr = (chip->data_bus1 & 0xf0) == 0; chip->ssg_ssg_addr = 1;
if (chip->ic) if (chip->ic)
chip->ssg_address = 0; chip->ssg_address = 0;
else if (chip->ssg_write0 && (chip->data_bus1 & 0xe0) == 0) else if (chip->ssg_write0)
chip->ssg_address = chip->data_bus1 & 0x1f; chip->ssg_address = chip->input.a0 & 0x1f;
int ssg_access = chip->ssg_ssg_addr && (chip->ssg_write1 || chip->ssg_read1); int ssg_access = chip->ssg_ssg_addr && (chip->ssg_write1 || chip->ssg_read1);
@ -443,26 +386,99 @@ void SSG_Clock(ssg_t* chip, int clk)
int sign_b = ((chip->ssg_mode & 2) == 0 && (chip->ssg_sign[0] & 2) != 0) || ((chip->ssg_mode & 16) == 0 && chip->ssg_noise_bit); int sign_b = ((chip->ssg_mode & 2) == 0 && (chip->ssg_sign[0] & 2) != 0) || ((chip->ssg_mode & 16) == 0 && chip->ssg_noise_bit);
int sign_c = ((chip->ssg_mode & 4) == 0 && (chip->ssg_sign[0] & 4) != 0) || ((chip->ssg_mode & 32) == 0 && chip->ssg_noise_bit); int sign_c = ((chip->ssg_mode & 4) == 0 && (chip->ssg_sign[0] & 4) != 0) || ((chip->ssg_mode & 32) == 0 && chip->ssg_noise_bit);
static const float volume_lut[32] = { static const float volume_lut_ay[32] = {
0.0000,
0.0000,
0.0106,
0.0106,
0.0150,
0.0150,
0.0222,
0.0222,
0.0320,
0.0320,
0.0466,
0.0466,
0.0665,
0.0665,
0.1039,
0.1039,
0.1237,
0.1237,
0.1986,
0.1986,
0.2803,
0.2803,
0.3548,
0.3548,
0.4702,
0.4702,
0.6030,
0.6030,
0.7530,
0.7530,
0.9250,
0.9250
};
static const float volume_lut_ssg[32] = {
0.0000, 0.0000, 0.0049, 0.0075, 0.0105, 0.0131, 0.0156, 0.0183, 0.0000, 0.0000, 0.0049, 0.0075, 0.0105, 0.0131, 0.0156, 0.0183,
0.0228, 0.0276, 0.0321, 0.0367, 0.0448, 0.0535, 0.0626, 0.0713, 0.0228, 0.0276, 0.0321, 0.0367, 0.0448, 0.0535, 0.0626, 0.0713,
0.0884, 0.1057, 0.1225, 0.1392, 0.1691, 0.2013, 0.2348, 0.2670, 0.0884, 0.1057, 0.1225, 0.1392, 0.1691, 0.2013, 0.2348, 0.2670,
0.3307, 0.3951, 0.4573, 0.5196, 0.6316, 0.7528, 0.8787, 1.0000 0.3307, 0.3951, 0.4573, 0.5196, 0.6316, 0.7528, 0.8787, 1.0000
}; };
if (chip->type & 1) {
chip->o_analog[0] = volume_lut[sign_a ? 0 : vol_a]; chip->o_analog[0] = volume_lut_ay[sign_a ? 0 : vol_a] * 11806;
chip->o_analog[1] = volume_lut[sign_b ? 0 : vol_b]; chip->o_analog[1] = volume_lut_ay[sign_b ? 0 : vol_b] * 11806;
chip->o_analog[2] = volume_lut[sign_c ? 0 : vol_c]; chip->o_analog[2] = volume_lut_ay[sign_c ? 0 : vol_c] * 11806;
} else {
chip->o_analog[0] = volume_lut_ssg[sign_a ? 0 : vol_a] * 10922;
chip->o_analog[1] = volume_lut_ssg[sign_b ? 0 : vol_b] * 10922;
chip->o_analog[2] = volume_lut_ssg[sign_c ? 0 : vol_c] * 10922;
}
} }
{ {
chip->read_bus = 0; // FIXME chip->read_bus = 0; // FIXME
if (chip->ssg_read1 if (chip->ssg_read1)
|| chip->read3
)
chip->read_bus = chip->data_bus1 & 255; chip->read_bus = chip->data_bus1 & 255;
chip->o_data = chip->read_bus; chip->o_data = chip->read_bus;
} }
if (clk)
chip->input.cs=1;
}
void SSG_Reset(ssg_t* chip) {
memset(chip,0,sizeof(ssg_t));
chip->input.test=1;
chip->input.ic=1;
SSG_Clock(chip,0);
SSG_Clock(chip,1);
chip->input.ic=0;
SSG_Clock(chip,0);
SSG_Clock(chip,1);
chip->input.ic=1;
SSG_Clock(chip,0);
SSG_Clock(chip,1);
chip->input.cs=1;
}
void SSG_Write(ssg_t* chip, unsigned char addr, unsigned char val) {
chip->input.cs=0;
chip->input.rd=1;
chip->input.wr=0;
chip->input.a0=addr;
chip->input.data=val;
}
void SSG_SetType(ssg_t* chip, int type) {
chip->type=type;
} }

View file

@ -25,7 +25,6 @@ typedef struct {
int wr; // neg int wr; // neg
int rd; // neg int rd; // neg
int a0; int a0;
int a1;
int data; int data;
int test; // set to 1 int test; // set to 1
int gpio_a; int gpio_a;
@ -36,6 +35,12 @@ ssg_input_t;
typedef struct { typedef struct {
ssg_input_t input; ssg_input_t input;
// bitfield
// bit 0: AY-3-8910 (16-step envelope)
// bit 1: AY-3-8914 (different register map and envelope volume)
// bit 2: AY8930 (TODO)
int type;
int ic; int ic;
int ic_latch1[2]; int ic_latch1[2];
@ -143,11 +148,14 @@ typedef struct {
int o_gpio_b; int o_gpio_b;
int o_gpio_b_d; int o_gpio_b_d;
float o_analog[3]; int o_analog[3];
int o_data; int o_data;
int o_data_d; int o_data_d;
} }
ssg_t; ssg_t;
void SSG_SetType(ssg_t* chip, int type);
void SSG_Reset(ssg_t* chip);
void SSG_Clock(ssg_t* chip, int clk); void SSG_Clock(ssg_t* chip, int clk);
void SSG_Write(ssg_t* chip, unsigned char addr, unsigned char val);

View file

@ -1667,6 +1667,7 @@ class FurnaceGUI {
int opl3Core; int opl3Core;
int esfmCore; int esfmCore;
int opllCore; int opllCore;
int ayCore;
int bubsysQuality; int bubsysQuality;
int dsidQuality; int dsidQuality;
int gbQuality; int gbQuality;
@ -1692,6 +1693,7 @@ class FurnaceGUI {
int opl3CoreRender; int opl3CoreRender;
int esfmCoreRender; int esfmCoreRender;
int opllCoreRender; int opllCoreRender;
int ayCoreRender;
int bubsysQualityRender; int bubsysQualityRender;
int dsidQualityRender; int dsidQualityRender;
int gbQualityRender; int gbQualityRender;
@ -1911,6 +1913,7 @@ class FurnaceGUI {
opl3Core(0), opl3Core(0),
esfmCore(0), esfmCore(0),
opllCore(0), opllCore(0),
ayCore(0),
bubsysQuality(3), bubsysQuality(3),
dsidQuality(3), dsidQuality(3),
gbQuality(3), gbQuality(3),
@ -1936,6 +1939,7 @@ class FurnaceGUI {
opl3CoreRender(0), opl3CoreRender(0),
esfmCoreRender(0), esfmCoreRender(0),
opllCoreRender(0), opllCoreRender(0),
ayCoreRender(0),
bubsysQualityRender(3), bubsysQualityRender(3),
dsidQualityRender(3), dsidQualityRender(3),
gbQualityRender(3), gbQualityRender(3),

View file

@ -180,6 +180,11 @@ const char* opllCores[]={
"emu2413" "emu2413"
}; };
const char* ayCores[]={
"MAME",
"AtomicSSG"
};
const char* coreQualities[]={ const char* coreQualities[]={
"Lower", "Lower",
"Low", "Low",
@ -1781,6 +1786,17 @@ void FurnaceGUI::drawSettings() {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::Combo("##OPLLCoreRender",&settings.opllCoreRender,opllCores,2)) settingsChanged=true; if (ImGui::Combo("##OPLLCoreRender",&settings.opllCoreRender,opllCores,2)) settingsChanged=true;
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text("AY-3-8910/SSG");
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::Combo("##AYCore",&settings.ayCore,ayCores,2)) settingsChanged=true;
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::Combo("##AYCoreRender",&settings.ayCoreRender,ayCores,2)) settingsChanged=true;
ImGui::EndTable(); ImGui::EndTable();
} }
@ -4376,6 +4392,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
settings.opl3Core=conf.getInt("opl3Core",0); settings.opl3Core=conf.getInt("opl3Core",0);
settings.esfmCore=conf.getInt("esfmCore",0); settings.esfmCore=conf.getInt("esfmCore",0);
settings.opllCore=conf.getInt("opllCore",0); settings.opllCore=conf.getInt("opllCore",0);
settings.ayCore=conf.getInt("ayCore",0);
settings.bubsysQuality=conf.getInt("bubsysQuality",3); settings.bubsysQuality=conf.getInt("bubsysQuality",3);
settings.dsidQuality=conf.getInt("dsidQuality",3); settings.dsidQuality=conf.getInt("dsidQuality",3);
@ -4403,6 +4420,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
settings.opl3CoreRender=conf.getInt("opl3CoreRender",0); settings.opl3CoreRender=conf.getInt("opl3CoreRender",0);
settings.esfmCoreRender=conf.getInt("esfmCoreRender",0); settings.esfmCoreRender=conf.getInt("esfmCoreRender",0);
settings.opllCoreRender=conf.getInt("opllCoreRender",0); settings.opllCoreRender=conf.getInt("opllCoreRender",0);
settings.ayCoreRender=conf.getInt("ayCoreRender",0);
settings.bubsysQualityRender=conf.getInt("bubsysQualityRender",3); settings.bubsysQualityRender=conf.getInt("bubsysQualityRender",3);
settings.dsidQualityRender=conf.getInt("dsidQualityRender",3); settings.dsidQualityRender=conf.getInt("dsidQualityRender",3);
@ -4447,6 +4465,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
clampSetting(settings.opl3Core,0,2); clampSetting(settings.opl3Core,0,2);
clampSetting(settings.esfmCore,0,1); clampSetting(settings.esfmCore,0,1);
clampSetting(settings.opllCore,0,1); clampSetting(settings.opllCore,0,1);
clampSetting(settings.ayCore,0,1);
clampSetting(settings.bubsysQuality,0,5); clampSetting(settings.bubsysQuality,0,5);
clampSetting(settings.dsidQuality,0,5); clampSetting(settings.dsidQuality,0,5);
clampSetting(settings.gbQuality,0,5); clampSetting(settings.gbQuality,0,5);
@ -4472,6 +4491,7 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
clampSetting(settings.opl3CoreRender,0,2); clampSetting(settings.opl3CoreRender,0,2);
clampSetting(settings.esfmCoreRender,0,1); clampSetting(settings.esfmCoreRender,0,1);
clampSetting(settings.opllCoreRender,0,1); clampSetting(settings.opllCoreRender,0,1);
clampSetting(settings.ayCoreRender,0,1);
clampSetting(settings.bubsysQualityRender,0,5); clampSetting(settings.bubsysQualityRender,0,5);
clampSetting(settings.dsidQualityRender,0,5); clampSetting(settings.dsidQualityRender,0,5);
clampSetting(settings.gbQualityRender,0,5); clampSetting(settings.gbQualityRender,0,5);
@ -4931,6 +4951,7 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
conf.set("opl3Core",settings.opl3Core); conf.set("opl3Core",settings.opl3Core);
conf.set("esfmCore",settings.esfmCore); conf.set("esfmCore",settings.esfmCore);
conf.set("opllCore",settings.opllCore); conf.set("opllCore",settings.opllCore);
conf.set("ayCore",settings.ayCore);
conf.set("bubsysQuality",settings.bubsysQuality); conf.set("bubsysQuality",settings.bubsysQuality);
conf.set("dsidQuality",settings.dsidQuality); conf.set("dsidQuality",settings.dsidQuality);
@ -4958,6 +4979,7 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) {
conf.set("opl3CoreRender",settings.opl3CoreRender); conf.set("opl3CoreRender",settings.opl3CoreRender);
conf.set("esfmCoreRender",settings.esfmCoreRender); conf.set("esfmCoreRender",settings.esfmCoreRender);
conf.set("opllCoreRender",settings.opllCoreRender); conf.set("opllCoreRender",settings.opllCoreRender);
conf.set("ayCoreRender",settings.ayCoreRender);
conf.set("bubsysQualityRender",settings.bubsysQualityRender); conf.set("bubsysQualityRender",settings.bubsysQualityRender);
conf.set("dsidQualityRender",settings.dsidQualityRender); conf.set("dsidQualityRender",settings.dsidQualityRender);
@ -5018,6 +5040,7 @@ void FurnaceGUI::commitSettings() {
settings.opl3Core!=e->getConfInt("opl3Core",0) || settings.opl3Core!=e->getConfInt("opl3Core",0) ||
settings.esfmCore!=e->getConfInt("esfmCore",0) || settings.esfmCore!=e->getConfInt("esfmCore",0) ||
settings.opllCore!=e->getConfInt("opllCore",0) || settings.opllCore!=e->getConfInt("opllCore",0) ||
settings.ayCore!=e->getConfInt("ayCore",0) ||
settings.bubsysQuality!=e->getConfInt("bubsysQuality",3) || settings.bubsysQuality!=e->getConfInt("bubsysQuality",3) ||
settings.dsidQuality!=e->getConfInt("dsidQuality",3) || settings.dsidQuality!=e->getConfInt("dsidQuality",3) ||
settings.gbQuality!=e->getConfInt("gbQuality",3) || settings.gbQuality!=e->getConfInt("gbQuality",3) ||