From 2cdf32300b86d291345924938d1b782a5634ec8f Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Thu, 5 Oct 2017 14:43:20 +0800 Subject: [PATCH] Add core option Swap Duty Cycles --- src/drivers/libretro/libretro.c | 13 +++++++++++++ src/fceu.h | 9 ++++++++- src/sound.c | 24 +++++++++++++++++------- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 9d7d624..cbf695a 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -84,6 +84,7 @@ static int soundo = 1; unsigned sndsamplerate = 48000; unsigned sndquality = 0; unsigned sndvolume = 150; +unsigned swapDuty = 0; static volatile int nofocus = 0; @@ -600,6 +601,7 @@ void retro_set_environment(retro_environment_t cb) { "fceumm_region", "Region Override; Auto|NTSC|PAL|Dendy" }, { "fceumm_sndquality", "Sound Quality; Low|High|Very High" }, { "fceumm_sndvolume", "Sound Volume; 150|160|170|180|190|200|210|220|230|240|250|0|10|20|30|40|50|60|70|80|90|100|110|120|130|140" }, + { "fceumm_swapduty", "Swap Duty Cyles; disabled|enabled" }, { "fceumm_zapper_mode", "Zapper Mode; absolute|relative" }, { "fceumm_show_crosshair", "Show Crosshair; enabled|disabled" }, { NULL, NULL }, @@ -1071,6 +1073,17 @@ static void check_variables(bool startup) retro_get_system_av_info(&av_info); environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &av_info); } + + var.key = "fceumm_swapduty"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + bool newval = (!strcmp(var.value, "enabled")); + if (newval != swapDuty) + { + swapDuty = newval; + } + } } static int mzx = 0, mzy = 0, mzb = 0; diff --git a/src/fceu.h b/src/fceu.h index a943591..1d69e0d 100644 --- a/src/fceu.h +++ b/src/fceu.h @@ -5,16 +5,23 @@ extern int fceuindbg; +/* Overclocking-related */ extern unsigned overclock_state; extern unsigned overclocked; extern unsigned skip_7bit_overclocking; extern unsigned DMC_7bit; - extern unsigned normal_scanlines; extern unsigned extrascanlines; extern unsigned vblankscanlines; + +/* Region selection */ extern unsigned dendy; +/* Audio mods*/ +extern unsigned swapDuty; /* Swap bits 6 & 7 of $4000/$4004 to mimic bug + * found on some famiclones/Dendy models. + */ + void ResetGameLoaded(void); #define DECLFR(x) uint8 FP_FASTAPASS(1) x(uint32 A) diff --git a/src/sound.c b/src/sound.c index b1cdf77..f4e9f60 100644 --- a/src/sound.c +++ b/src/sound.c @@ -195,9 +195,12 @@ static DECLFW(Write_PSG) { // FCEU_printf("APU1 %04x:%04x\n",A,V); A &= 0x1F; switch (A) { - case 0x0: DoSQ1(); + case 0x0: + DoSQ1(); EnvUnits[0].Mode = (V & 0x30) >> 4; EnvUnits[0].Speed = (V & 0xF); + if (swapDuty) + V = (V & 0x3F) | ((V & 0x80) >> 1) | ((V & 0x40) << 1); break; case 0x1: sweepon[0] = V & 0x80; @@ -214,30 +217,36 @@ static DECLFW(Write_PSG) { DoSQ2(); EnvUnits[1].Mode = (V & 0x30) >> 4; EnvUnits[1].Speed = (V & 0xF); + if (swapDuty) + V = (V & 0x3F) | ((V & 0x80) >> 1) | ((V & 0x40) << 1); break; case 0x5: sweepon[1] = V & 0x80; break; - case 0x6: DoSQ2(); + case 0x6: + DoSQ2(); curfreq[1] &= 0xFF00; curfreq[1] |= V; break; case 0x7: SQReload(1, V); break; - case 0xa: DoTriangle(); + case 0xa: + DoTriangle(); break; case 0xb: DoTriangle(); if (EnabledChannels & 0x4) lengthcount[2] = lengthtable[(V >> 3) & 0x1f]; - TriMode = 1; // Load mode + TriMode = 1; /* Load mode */ break; - case 0xC: DoNoise(); + case 0xC: + DoNoise(); EnvUnits[2].Mode = (V & 0x30) >> 4; EnvUnits[2].Speed = (V & 0xF); break; - case 0xE: DoNoise(); + case 0xE: + DoNoise(); break; case 0xF: DoNoise(); @@ -245,7 +254,8 @@ static DECLFW(Write_PSG) { lengthcount[3] = lengthtable[(V >> 3) & 0x1f]; EnvUnits[2].reloaddec = 1; break; - case 0x10: DoPCM(); + case 0x10: + DoPCM(); LoadDMCPeriod(V & 0xF); if (SIRQStat & 0x80) {