diff --git a/HISTORY.txt b/HISTORY.txt
index 7d9516b..d1b1a64 100644
--- a/HISTORY.txt
+++ b/HISTORY.txt
@@ -113,6 +113,11 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
* fixed 68k cycles delay on invalid VRAM writes (fixes "Microcosm" intro loop)
* optimized tile caching
+[Core/Sound]
+---------------
+* rewrote optimized & more accurate PSG core from scratch
+* removed PSG boost noise feature & added optional high-quality PSG resampling
+
[Gamecube/Wii]
---------------
* added configurable BIOS & Lock-on ROM files
diff --git a/builds/genesis_plus_gx_libretro.dll b/builds/genesis_plus_gx_libretro.dll
index bdd0016..1f9d29f 100644
Binary files a/builds/genesis_plus_gx_libretro.dll and b/builds/genesis_plus_gx_libretro.dll differ
diff --git a/builds/genplus_cube.dol b/builds/genplus_cube.dol
index 1856fc6..b56b9b1 100644
Binary files a/builds/genplus_cube.dol and b/builds/genplus_cube.dol differ
diff --git a/builds/genplus_wii.dol b/builds/genplus_wii.dol
index a8f55b1..51f5bab 100644
Binary files a/builds/genplus_wii.dol and b/builds/genplus_wii.dol differ
diff --git a/core/io_ctrl.c b/core/io_ctrl.c
index 97a8964..44797fc 100644
--- a/core/io_ctrl.c
+++ b/core/io_ctrl.c
@@ -570,7 +570,7 @@ void io_gg_write(unsigned int offset, unsigned int data)
case 6: /* PSG Stereo output control */
io_reg[6] = data;
- SN76489_Config(Z80.cycles, config.psg_preamp, config.psgBoostNoise, data);
+ psg_config(Z80.cycles, config.psg_preamp, data);
return;
default: /* Read-only */
diff --git a/core/mem68k.c b/core/mem68k.c
index 75c633f..cb60ed7 100644
--- a/core/mem68k.c
+++ b/core/mem68k.c
@@ -1218,7 +1218,7 @@ void vdp_write_byte(unsigned int address, unsigned int data)
{
if (address & 1)
{
- SN76489_Write(m68k.cycles, data);
+ psg_write(m68k.cycles, data);
return;
}
m68k_unused_8_w(address, data);
@@ -1264,7 +1264,7 @@ void vdp_write_word(unsigned int address, unsigned int data)
case 0x10: /* PSG */
case 0x14:
{
- SN76489_Write(m68k.cycles, data & 0xFF);
+ psg_write(m68k.cycles, data & 0xFF);
return;
}
diff --git a/core/membnk.c b/core/membnk.c
index 64f16d8..50ffd52 100644
--- a/core/membnk.c
+++ b/core/membnk.c
@@ -2,8 +2,8 @@
* Genesis Plus
* Z80 bank access to 68k bus
*
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
- * Copyright (C) 2007-2011 Eke-Eke (Genesis Plus GX)
+ * Copyright (C) 1998-2003 Charles Mac Donald (original code)
+ * Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -294,7 +294,7 @@ void zbank_write_vdp(unsigned int address, unsigned int data)
{
if (address & 1)
{
- SN76489_Write(Z80.cycles, data);
+ psg_write(Z80.cycles, data);
return;
}
zbank_unused_w(address, data);
diff --git a/core/membnk.h b/core/membnk.h
index b4b242e..dd34631 100644
--- a/core/membnk.h
+++ b/core/membnk.h
@@ -2,8 +2,8 @@
* Genesis Plus
* Z80 bank access to 68k bus
*
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
- * Copyright (C) 2007-2012 Eke-Eke (Genesis Plus GX)
+ * Copyright (C) 1998-2003 Charles Mac Donald (original code)
+ * Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
diff --git a/core/memz80.c b/core/memz80.c
index 0692ce3..b3a6ef1 100644
--- a/core/memz80.c
+++ b/core/memz80.c
@@ -231,7 +231,7 @@ void z80_md_port_w(unsigned int port, unsigned char data)
case 0x40:
case 0x41:
{
- SN76489_Write(Z80.cycles, data);
+ psg_write(Z80.cycles, data);
return;
}
@@ -345,7 +345,7 @@ void z80_gg_port_w(unsigned int port, unsigned char data)
case 0x40:
case 0x41:
{
- SN76489_Write(Z80.cycles, data);
+ psg_write(Z80.cycles, data);
return;
}
@@ -450,7 +450,7 @@ void z80_ms_port_w(unsigned int port, unsigned char data)
case 0x40:
case 0x41:
{
- SN76489_Write(Z80.cycles, data);
+ psg_write(Z80.cycles, data);
return;
}
@@ -493,7 +493,7 @@ void z80_ms_port_w(unsigned int port, unsigned char data)
1 0 : disable both PSG & FM output
1 1 : enable both PSG and FM output
*/
- SN76489_Config(Z80.cycles, config.psg_preamp, config.psgBoostNoise, ((data + 1) & 0x02) ? 0x00 : 0xFF);
+ psg_config(Z80.cycles, config.psg_preamp, ((data + 1) & 0x02) ? 0x00 : 0xFF);
fm_write(Z80.cycles, 0x02, data);
io_reg[6] = data;
return;
@@ -611,7 +611,7 @@ void z80_m3_port_w(unsigned int port, unsigned char data)
case 0x40:
case 0x41:
{
- SN76489_Write(Z80.cycles, data);
+ psg_write(Z80.cycles, data);
return;
}
@@ -699,7 +699,7 @@ void z80_sg_port_w(unsigned int port, unsigned char data)
case 0x40:
case 0x41:
{
- SN76489_Write(Z80.cycles, data);
+ psg_write(Z80.cycles, data);
/* Z80 !WAIT input is tied to SN76489AN chip READY pin (held low for 32 clocks after each write access) */
Z80.cycles += (32 * 15);
diff --git a/core/shared.h b/core/shared.h
index f463aa8..959f289 100644
--- a/core/shared.h
+++ b/core/shared.h
@@ -22,7 +22,7 @@
#include "io_ctrl.h"
#include "input.h"
#include "sound.h"
-#include "sn76489.h"
+#include "psg.h"
#include "ym2413.h"
#include "ym2612.h"
#include "sram.h"
diff --git a/core/sound/psg.c b/core/sound/psg.c
new file mode 100644
index 0000000..44c03ec
--- /dev/null
+++ b/core/sound/psg.c
@@ -0,0 +1,591 @@
+/***************************************************************************************
+ * Genesis Plus
+ * PSG sound chip (SN76489A compatible)
+ *
+ * Support for discrete chip & integrated (ASIC) clones
+ *
+ * Noise implementation based on http://www.smspower.org/Development/SN76489#NoiseChannel
+ *
+ * Copyright (C) 2016 Eke-Eke (Genesis Plus GX)
+ *
+ * Redistribution and use of this code or any derivative works are permitted
+ * provided that the following conditions are met:
+ *
+ * - Redistributions may not be sold, nor may they be used in a commercial
+ * product or activity.
+ *
+ * - Redistributions that are modified from the original source must include the
+ * complete source code, including the source code for all components used by a
+ * binary built from the modified sources. However, as a special exception, the
+ * source code distributed need not include anything that is normally distributed
+ * (in either source or binary form) with the major components (compiler, kernel,
+ * and so on) of the operating system on which the executable runs, unless that
+ * component itself accompanies the executable.
+ *
+ * - Redistributions must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#include "shared.h"
+#include "blip_buf.h"
+
+/* internal clock = input clock : 16 = (master clock : 15) : 16 */
+#define PSG_MCYCLES_RATIO (15*16)
+
+/* maximal channel output (roughly adjusted to match VA4 MD1 PSG/FM balance with 1.5x amplification of PSG output) */
+#define PSG_MAX_VOLUME 2800
+
+static const uint8 noiseShiftWidth[2] = {14,15};
+
+static const uint8 noiseBitMask[2] = {0x6,0x9};
+
+static const uint8 noiseFeedback[10] = {0,1,1,0,1,0,0,1,1,0};
+
+static const uint16 chanVolume[16] = {
+ PSG_MAX_VOLUME, /* MAX */
+ PSG_MAX_VOLUME * 0.794328234, /* -2dB */
+ PSG_MAX_VOLUME * 0.630957344, /* -4dB */
+ PSG_MAX_VOLUME * 0.501187233, /* -6dB */
+ PSG_MAX_VOLUME * 0.398107170, /* -8dB */
+ PSG_MAX_VOLUME * 0.316227766, /* -10dB */
+ PSG_MAX_VOLUME * 0.251188643, /* -12dB */
+ PSG_MAX_VOLUME * 0.199526231, /* -14dB */
+ PSG_MAX_VOLUME * 0.158489319, /* -16dB */
+ PSG_MAX_VOLUME * 0.125892541, /* -18dB */
+ PSG_MAX_VOLUME * 0.1, /* -20dB */
+ PSG_MAX_VOLUME * 0.079432823, /* -22dB */
+ PSG_MAX_VOLUME * 0.063095734, /* -24dB */
+ PSG_MAX_VOLUME * 0.050118723, /* -26dB */
+ PSG_MAX_VOLUME * 0.039810717, /* -28dB */
+ 0 /* OFF */
+};
+
+static struct
+{
+ int clocks;
+ int latch;
+ int noiseShiftValue;
+ int noiseShiftWidth;
+ int noiseBitMask;
+ int regs[8];
+ int freqInc[4];
+ int freqCounter[4];
+ int polarity[4];
+ int chanDelta[4][2];
+ int chanOut[4][2];
+ int chanAmp[4][2];
+} psg;
+
+static void psg_update(unsigned int clocks);
+
+void psg_init(PSG_TYPE type)
+{
+ int i;
+
+ /* Initialize stereo amplification (default) */
+ for (i=0; i<4; i++)
+ {
+ psg.chanAmp[i][0] = 100;
+ psg.chanAmp[i][1] = 100;
+ }
+
+ /* Initialize Noise LSFR type */
+ psg.noiseShiftWidth = noiseShiftWidth[type];
+ psg.noiseBitMask = noiseBitMask[type];
+}
+
+void psg_reset()
+{
+ int i;
+
+ /* power-on state (verified on 315-5313A & 315-5660 integrated version only) */
+ for (i=0; i<4; i++)
+ {
+ psg.regs[i*2] = 0;
+ psg.regs[i*2+1] = 0;
+ psg.freqInc[i] = (i < 3) ? (1 * PSG_MCYCLES_RATIO) : (16 * PSG_MCYCLES_RATIO);
+ psg.freqCounter[i] = 0;
+ psg.polarity[i] = -1;
+ psg.chanDelta[i][0] = 0;
+ psg.chanDelta[i][1] = 0;
+ psg.chanOut[i][0] = 0;
+ psg.chanOut[i][1] = 0;
+ }
+
+ /* noise attenuation register is latched on power-on (verified on 315-5313A & 315-5660 integrated version only) */
+ psg.latch = 7;
+
+ /* reset noise shift register */
+ psg.noiseShiftValue = 1 << psg.noiseShiftWidth;
+
+ /* reset internal M-cycles clock counter */
+ psg.clocks = 0;
+}
+
+int psg_context_save(uint8 *state)
+{
+ int bufferptr = 0;
+
+ save_param(&psg.clocks,sizeof(psg.clocks));
+ save_param(&psg.latch,sizeof(psg.latch));
+ save_param(&psg.noiseShiftValue,sizeof(psg.noiseShiftValue));
+ save_param(psg.regs,sizeof(psg.regs));
+ save_param(psg.freqInc,sizeof(psg.freqInc));
+ save_param(psg.freqCounter,sizeof(psg.freqCounter));
+ save_param(psg.polarity,sizeof(psg.polarity));
+ save_param(psg.chanDelta,sizeof(psg.chanDelta));
+ save_param(psg.chanOut,sizeof(psg.chanOut));
+
+ return bufferptr;
+}
+
+int psg_context_load(uint8 *state)
+{
+ int chanOut[4][2], delta[2];
+ int i, bufferptr = 0;
+
+ /* get current tone channels output */
+ for (i=0; i<3; i++)
+ {
+ if (psg.polarity[i] > 0)
+ {
+ chanOut[i][0] = psg.chanOut[i][0];
+ chanOut[i][1] = psg.chanOut[i][1];
+ }
+ else
+ {
+ chanOut[i][0] = 0;
+ chanOut[i][1] = 0;
+ }
+ }
+
+ /* get current noise channel output */
+ if (psg.noiseShiftValue & 1)
+ {
+ chanOut[3][0] = psg.chanOut[3][0];
+ chanOut[3][1] = psg.chanOut[3][1];
+ }
+ else
+ {
+ chanOut[3][0] = 0;
+ chanOut[3][1] = 0;
+ }
+
+ load_param(&psg.clocks,sizeof(psg.clocks));
+ load_param(&psg.latch,sizeof(psg.latch));
+ load_param(&psg.noiseShiftValue,sizeof(psg.noiseShiftValue));
+ load_param(psg.regs,sizeof(psg.regs));
+ load_param(psg.freqInc,sizeof(psg.freqInc));
+ load_param(psg.freqCounter,sizeof(psg.freqCounter));
+ load_param(psg.polarity,sizeof(psg.polarity));
+ load_param(psg.chanDelta,sizeof(psg.chanDelta));
+ load_param(psg.chanOut,sizeof(psg.chanOut));
+
+ /* apply any pending channel volume variation */
+ for (i=0; i<4; i++)
+ {
+ psg.chanOut[i][0] += psg.chanDelta[i][0];
+ psg.chanOut[i][1] += psg.chanDelta[i][1];
+ psg.chanDelta[i][0] = 0;
+ psg.chanDelta[i][1] = 0;
+ }
+
+ /* calculate noise channel output variations */
+ if (psg.noiseShiftValue & 1)
+ {
+ /* channel output is high */
+ delta[0] = psg.chanOut[3][0] - chanOut[3][0];
+ delta[1] = psg.chanOut[3][0] - chanOut[3][1];
+ }
+ else
+ {
+ /* channel output is low */
+ delta[0] = -chanOut[3][0];
+ delta[1] = -chanOut[3][1];
+ }
+
+ /* add tone channels output variations */
+ for (i=0; i<3; i++)
+ {
+ if (psg.polarity[i] > 0)
+ {
+ /* channel output is high */
+ delta[0] += (psg.chanOut[i][0] - chanOut[i][0]);
+ delta[1] += (psg.chanOut[i][0] - chanOut[i][1]);
+ }
+ else
+ {
+ /* channel output is low */
+ delta[0] -= chanOut[i][0];
+ delta[1] -= chanOut[i][1];
+ }
+ }
+
+ /* update mixed channels output */
+ if (config.hq_psg)
+ {
+ blip_add_delta(snd.blips[0], psg.clocks, delta[0], delta[1]);
+ }
+ else
+ {
+ blip_add_delta_fast(snd.blips[0], psg.clocks, delta[0], delta[1]);
+ }
+
+ return bufferptr;
+}
+
+void psg_write(unsigned int clocks, unsigned int data)
+{
+ int index;
+
+ /* PSG chip synchronization */
+ if (clocks > psg.clocks)
+ {
+ /* run PSG chip until current timestamp */
+ psg_update(clocks);
+
+ /* update internal M-cycles clock counter */
+ psg.clocks += ((clocks - psg.clocks + PSG_MCYCLES_RATIO - 1) / PSG_MCYCLES_RATIO) * PSG_MCYCLES_RATIO;
+ }
+
+ if (data & 0x80)
+ {
+ /* latch register index (1xxx----) */
+ psg.latch = index = (data >> 4) & 0x07;
+ }
+ else
+ {
+ /* restore latched register index */
+ index= psg.latch;
+ }
+
+ switch (index)
+ {
+ case 0:
+ case 2:
+ case 4: /* Tone channels frequency */
+ {
+ /* recalculate frequency register value */
+ if (data & 0x80)
+ {
+ /* update 10-bit register LSB (1---xxxx) */
+ data = (psg.regs[index] & 0x3f0) | (data & 0x0f);
+ }
+ else
+ {
+ /* update 10-bit register MSB (0-xxxxxx) */
+ data = (psg.regs[index] & 0x00f) | ((data & 0x3f) << 4);
+ }
+
+ /* update channel M-cycle counter increment */
+ if (data)
+ {
+ psg.freqInc[index>>1] = data * PSG_MCYCLES_RATIO;
+ }
+ else
+ {
+ /* zero value behaves the same as a value of 1 (verified on integrated version only) */
+ psg.freqInc[index>>1] = PSG_MCYCLES_RATIO;
+ }
+
+ /* update noise channel counter increment if required */
+ if ((index == 4) && ((psg.regs[6] & 0x03) == 0x03))
+ {
+ psg.freqInc[3] = psg.freqInc[2];
+ }
+
+ break;
+ }
+
+ case 6: /* Noise control */
+ {
+ /* noise signal generator frequency (----?xxx) */
+ int noiseFreq = (data & 0x03);
+
+ if (noiseFreq == 0x03)
+ {
+ /* noise generator is controlled by tone channel #3 generator */
+ psg.freqInc[3] = psg.freqInc[2];
+ psg.freqCounter[3] = psg.freqCounter[2];
+ }
+ else
+ {
+ /* noise generator is running at separate frequency */
+ psg.freqInc[3] = (0x10 << noiseFreq) * PSG_MCYCLES_RATIO;
+ }
+
+ /* reset shift register value */
+ psg.noiseShiftValue = 1 << psg.noiseShiftWidth;;
+
+ break;
+ }
+
+ case 7: /* Noise channel attenuation */
+ {
+ /* convert 4-bit attenuation value (----xxxx) to 16-bit volume value */
+ data = chanVolume[data & 0x0f];
+
+ /* check noise shift register output */
+ if (psg.noiseShiftValue & 1)
+ {
+ /* channel output is high, volume variation will be applied at next internal cycle update */
+ psg.chanDelta[3][0] = ((data * psg.chanAmp[3][0]) / 100) - psg.chanOut[3][0];
+ psg.chanDelta[3][1] = ((data * psg.chanAmp[3][1]) / 100) - psg.chanOut[3][1];
+ }
+ else
+ {
+ /* channel output is low, volume variation will be applied at next transition */
+ psg.chanOut[3][0] = (data * psg.chanAmp[3][0]) / 100;
+ psg.chanOut[3][1] = (data * psg.chanAmp[3][1]) / 100;
+ }
+
+ break;
+ }
+
+ default: /* Tone channels attenuation */
+ {
+ /* channel number (0-2) */
+ int i = index >> 1;
+
+ /* convert 4-bit attenuation value (----xxxx) to 16-bit volume value */
+ data = chanVolume[data & 0x0f];
+
+ /* check tone generator polarity */
+ if (psg.polarity[i] > 0)
+ {
+ /* channel output is high, volume variation will be applied at next internal cycle update */
+ psg.chanDelta[i][0] = ((data * psg.chanAmp[i][0]) / 100) - psg.chanOut[i][0];
+ psg.chanDelta[i][1] = ((data * psg.chanAmp[i][1]) / 100) - psg.chanOut[i][1];
+ }
+ else
+ {
+ /* channel output is low, volume variation will be applied at next transition */
+ psg.chanOut[i][0] = (data * psg.chanAmp[i][0]) / 100;
+ psg.chanOut[i][1] = (data * psg.chanAmp[i][1]) / 100;
+ }
+
+ break;
+ }
+ }
+
+ /* save register value */
+ psg.regs[index] = data;
+}
+
+void psg_config(unsigned int clocks, unsigned int preamp, unsigned int panning)
+{
+ int i;
+
+ /* PSG chip synchronization */
+ if (clocks > psg.clocks)
+ {
+ /* run PSG chip until current timestamp */
+ psg_update(clocks);
+
+ /* update internal M-cycles clock counter */
+ psg.clocks += ((clocks - psg.clocks + PSG_MCYCLES_RATIO - 1) / PSG_MCYCLES_RATIO) * PSG_MCYCLES_RATIO;
+ }
+
+ for (i=0; i<4; i++)
+ {
+ /* channel internal volume */
+ int volume = psg.regs[i*2+1];
+
+ /* update channel stereo amplification */
+ psg.chanAmp[i][0] = preamp * ((panning >> (i + 4)) & 1);
+ psg.chanAmp[i][1] = preamp * ((panning >> (i + 0)) & 1);
+
+ /* tone channels */
+ if (i < 3)
+ {
+ /* check tone generator polarity */
+ if (psg.polarity[i] > 0)
+ {
+ /* channel output is high, volume variation will be applied at next internal cycle update */
+ psg.chanDelta[i][0] = ((volume * psg.chanAmp[i][0]) / 100) - psg.chanOut[i][0];
+ psg.chanDelta[i][1] = ((volume * psg.chanAmp[i][1]) / 100) - psg.chanOut[i][1];
+ }
+ else
+ {
+ /* channel output is low, volume variation will be applied at next transition*/
+ psg.chanOut[i][0] = (volume * psg.chanAmp[i][0]) / 100;
+ psg.chanOut[i][1] = (volume * psg.chanAmp[i][1]) / 100;
+ }
+ }
+
+ /* noise channel */
+ else
+ {
+ /* check noise shift register output */
+ if (psg.noiseShiftValue & 1)
+ {
+ /* channel output is high, volume variation will be applied at next internal cycle update */
+ psg.chanDelta[3][0] = ((volume * psg.chanAmp[3][0]) / 100) - psg.chanOut[3][0];
+ psg.chanDelta[3][1] = ((volume * psg.chanAmp[3][1]) / 100) - psg.chanOut[3][1];
+ }
+ else
+ {
+ /* channel output is low, volume variation will be applied at next transition */
+ psg.chanOut[3][0] = (volume * psg.chanAmp[3][0]) / 100;
+ psg.chanOut[3][1] = (volume * psg.chanAmp[3][1]) / 100;
+ }
+ }
+ }
+}
+
+void psg_end_frame(unsigned int clocks)
+{
+ int i;
+
+ if (clocks > psg.clocks)
+ {
+ /* run PSG chip until current timestamp */
+ psg_update(clocks);
+
+ /* update internal M-cycles clock counter */
+ psg.clocks += ((clocks - psg.clocks + PSG_MCYCLES_RATIO - 1) / PSG_MCYCLES_RATIO) * PSG_MCYCLES_RATIO;
+ }
+
+ /* adjust internal M-cycles clock counter for next frame */
+ psg.clocks -= clocks;
+
+ /* adjust channels time counters for next frame */
+ for (i=0; i<4; ++i)
+ {
+ psg.freqCounter[i] -= clocks;
+ }
+}
+
+static void psg_update(unsigned int clocks)
+{
+ int i, timestamp, polarity;
+
+ for (i=0; i<4; i++)
+ {
+ /* apply any pending channel volume variations */
+ if (psg.chanDelta[i][0] | psg.chanDelta[i][1])
+ {
+ /* update channel output */
+ if (config.hq_psg)
+ {
+ blip_add_delta(snd.blips[0], psg.clocks, psg.chanDelta[i][0], psg.chanDelta[i][1]);
+ }
+ else
+ {
+ blip_add_delta_fast(snd.blips[0], psg.clocks, psg.chanDelta[i][0], psg.chanDelta[i][1]);
+ }
+
+ /* update channel volume */
+ psg.chanOut[i][0] += psg.chanDelta[i][0];
+ psg.chanOut[i][1] += psg.chanDelta[i][1];
+
+ /* clear pending channel volume variations */
+ psg.chanDelta[i][0] = 0;
+ psg.chanDelta[i][1] = 0;
+ }
+
+ /* timestamp of next transition */
+ timestamp = psg.freqCounter[i];
+
+ /* current channel generator polarity */
+ polarity = psg.polarity[i];
+
+ /* Tone channels */
+ if (i < 3)
+ {
+ /* process all transitions occurring until current clock timestamp */
+ while (timestamp < clocks)
+ {
+ /* invert tone generator polarity */
+ polarity = -polarity;
+
+ /* update channel output */
+ if (config.hq_psg)
+ {
+ blip_add_delta(snd.blips[0], timestamp, polarity*psg.chanOut[i][0], polarity*psg.chanOut[i][1]);
+ }
+ else
+ {
+ blip_add_delta_fast(snd.blips[0], timestamp, polarity*psg.chanOut[i][0], polarity*psg.chanOut[i][1]);
+ }
+
+ /* timestamp of next transition */
+ timestamp += psg.freqInc[i];
+ }
+ }
+
+ /* Noise channel */
+ else
+ {
+ /* current noise shift register value */
+ int shiftValue = psg.noiseShiftValue;
+
+ /* process all transitions occurring until current clock timestamp */
+ while (timestamp < clocks)
+ {
+ /* invert noise generator polarity */
+ polarity = -polarity;
+
+ /* noise register is shifted on positive edge only */
+ if (polarity > 0)
+ {
+ /* current shift register output */
+ int shiftOutput = shiftValue & 0x01;
+
+ /* White noise (----1xxx) */
+ if (psg.regs[6] & 0x04)
+ {
+ /* shift and apply XOR feedback network */
+ shiftValue = (shiftValue >> 1) | (noiseFeedback[shiftValue & psg.noiseBitMask] << psg.noiseShiftWidth);
+ }
+
+ /* Periodic noise (----0xxx) */
+ else
+ {
+ /* shift and feedback current output */
+ shiftValue = (shiftValue >> 1) | (shiftOutput << psg.noiseShiftWidth);
+ }
+
+ /* shift register output variation */
+ shiftOutput = (shiftValue & 0x1) - shiftOutput;
+
+ /* update noise channel output */
+ if (config.hq_psg)
+ {
+ blip_add_delta(snd.blips[0], timestamp, shiftOutput*psg.chanOut[3][0], shiftOutput*psg.chanOut[3][1]);
+ }
+ else
+ {
+ blip_add_delta_fast(snd.blips[0], timestamp, shiftOutput*psg.chanOut[3][0], shiftOutput*psg.chanOut[3][1]);
+ }
+ }
+
+ /* timestamp of next transition */
+ timestamp += psg.freqInc[3];
+ }
+
+ /* save shift register value */
+ psg.noiseShiftValue = shiftValue;
+ }
+
+ /* save timestamp of next transition */
+ psg.freqCounter[i] = timestamp;
+
+ /* save channel generator polarity */
+ psg.polarity[i] = polarity;
+ }
+}
diff --git a/core/sound/psg.h b/core/sound/psg.h
new file mode 100644
index 0000000..46370d4
--- /dev/null
+++ b/core/sound/psg.h
@@ -0,0 +1,60 @@
+/***************************************************************************************
+ * Genesis Plus
+ * PSG sound chip (SN76489A compatible)
+ *
+ * Support for discrete chip & integrated (ASIC) clones
+ *
+ * Noise implementation based on http://www.smspower.org/Development/SN76489#NoiseChannel
+ *
+ * Copyright (C) 2016 Eke-Eke (Genesis Plus GX)
+ *
+ * Redistribution and use of this code or any derivative works are permitted
+ * provided that the following conditions are met:
+ *
+ * - Redistributions may not be sold, nor may they be used in a commercial
+ * product or activity.
+ *
+ * - Redistributions that are modified from the original source must include the
+ * complete source code, including the source code for all components used by a
+ * binary built from the modified sources. However, as a special exception, the
+ * source code distributed need not include anything that is normally distributed
+ * (in either source or binary form) with the major components (compiler, kernel,
+ * and so on) of the operating system on which the executable runs, unless that
+ * component itself accompanies the executable.
+ *
+ * - Redistributions must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************************/
+
+#ifndef _PSG_H_
+#define _PSG_H_
+
+typedef enum {
+ PSG_DISCRETE,
+ PSG_INTEGRATED
+} PSG_TYPE;
+
+/* Function prototypes */
+extern void psg_init(PSG_TYPE type);
+extern void psg_reset(void);
+extern int psg_context_save(uint8 *state);
+extern int psg_context_load(uint8 *state);
+extern void psg_write(unsigned int clocks, unsigned int data);
+extern void psg_config(unsigned int clocks, unsigned int preamp, unsigned int panning);
+extern void psg_end_frame(unsigned int clocks);
+
+#endif /* _PSG_H_ */
diff --git a/core/sound/sn76489.c b/core/sound/sn76489.c
deleted file mode 100644
index da0a1b6..0000000
--- a/core/sound/sn76489.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- SN76489 emulation
- by Maxim in 2001 and 2002
- converted from my original Delphi implementation
-
- I'm a C newbie so I'm sure there are loads of stupid things
- in here which I'll come back to some day and redo
-
- Includes:
- - Super-high quality tone channel "oversampling" by calculating fractional positions on transitions
- - Noise output pattern reverse engineered from actual SMS output
- - Volume levels taken from actual SMS output
-
- 07/08/04 Charles MacDonald
- Modified for use with SMS Plus:
- - Added support for multiple PSG chips.
- - Added reset/config/update routines.
- - Added context management routines.
- - Removed SN76489_GetValues().
- - Removed some unused variables.
-
- 25/04/07 Eke-Eke (Genesis Plus GX)
- - Removed stereo GG support (unused)
- - Made SN76489_Update outputs 16bits mono samples
- - Replaced volume table with VGM plugin's one
-
- 05/01/09 Eke-Eke (Genesis Plus GX)
- - Modified Cut-Off frequency (according to Steve Snake: http://www.smspower.org/forums/viewtopic.php?t=1746)
-
- 24/08/10 Eke-Eke (Genesis Plus GX)
- - Removed multichip support (unused)
- - Removed alternate volume table, panning & mute support (unused)
- - Removed configurable Feedback and Shift Register Width (always use Sega ones)
- - Added linear resampling using Blip Buffer (based on Blargg's implementation: http://www.smspower.org/forums/viewtopic.php?t=11376)
-
- 01/09/12 Eke-Eke (Genesis Plus GX)
- - Added generic Blip-Buffer support internally, using common Master Clock as timebase
- - Re-added stereo GG support
- - Re-added configurable Feedback and Shift Register Width
- - Rewrote core with various optimizations
-
- 04/11/16 Eke-Eke (Genesis Plus GX)
- - improved resampling quality (removes aliasing noise when using high frequency tones)
- - removed cut-off value (improves emulation accuracy of highest frequency tones)
- - modified channels output to 0/1 like real chip instead of -1/+1 (fixes PCM voices when cut-off value is removed)
-
-*/
-
-#include "shared.h"
-
-#define PSG_MCYCLES_RATIO (16 * 15)
-
-/* Initial state of shift register */
-#define NoiseInitialState 0x8000
-
-/* original Texas Instruments TMS SN76489AN (rev. A) used in SG-1000, SC-3000H & SF-7000 computers */
-#define FB_DISCRETE 0x0006
-#define SRW_DISCRETE 15
-
-/* SN76489AN clone integrated in Sega's VDP chips (315-5124, 315-5246, 315-5313, Game Gear) */
-#define FB_SEGAVDP 0x0009
-#define SRW_SEGAVDP 16
-
-typedef struct
-{
- /* Configuration */
- int PreAmp[4][2]; /* stereo channels pre-amplification ratio (%) */
- int NoiseFeedback;
- int SRWidth;
-
- /* PSG registers: */
- int Registers[8]; /* Tone, vol x4 */
- int LatchedRegister;
- int NoiseShiftRegister;
- int NoiseFreq; /* Noise channel signal generator frequency */
-
- /* Output calculation variables */
- int ToneFreqVals[4]; /* Frequency register values (counters) */
- int ToneFreqPos[4]; /* Frequency channel flip-flops */
- int Channel[4][2]; /* current amplitude of each (stereo) channel */
- int ChanOut[4][2]; /* current output value of each (stereo) channel */
-
- /* Internal M-clock counter */
- unsigned long clocks;
-
-} SN76489_Context;
-
-static const uint16 PSGVolumeValues[16] =
-{
- /* These values are taken from a real SMS2's output */
- /*{892,892,892,760,623,497,404,323,257,198,159,123,96,75,60,0}, */
- /* I can't remember why 892... :P some scaling I did at some point */
- /* these values are true volumes for 2dB drops at each step (multiply previous by 10^-0.1) */
- 1516,1205,957,760,603,479,381,303,240,191,152,120,96,76,60,0
-};
-
-static SN76489_Context SN76489;
-
-void SN76489_Init(int type)
-{
- int i;
-
- for (i=0; i<4; i++)
- {
- SN76489.PreAmp[i][0] = 100;
- SN76489.PreAmp[i][1] = 100;
- }
-
- if (type == SN_DISCRETE)
- {
- SN76489.NoiseFeedback = FB_DISCRETE;
- SN76489.SRWidth = SRW_DISCRETE;
- }
- else
- {
- SN76489.NoiseFeedback = FB_SEGAVDP;
- SN76489.SRWidth = SRW_SEGAVDP;
- }
-}
-
-void SN76489_Reset()
-{
- int i;
-
- for(i = 0; i <= 3; i++)
- {
- /* Initialise PSG state */
- SN76489.Registers[2*i] = 1; /* tone freq=1 */
- SN76489.Registers[2*i+1] = 0xf; /* vol=off */
-
- /* Set counters to 0 */
- SN76489.ToneFreqVals[i] = 0;
-
- /* Set flip-flops to 1 */
- SN76489.ToneFreqPos[i] = 1;
-
- /* Clear stereo channels amplitude */
- SN76489.Channel[i][0] = 0;
- SN76489.Channel[i][1] = 0;
-
- /* Clear stereo channel outputs in delta buffer */
- SN76489.ChanOut[i][0] = 0;
- SN76489.ChanOut[i][1] = 0;
- }
-
- /* Initialise latched register index */
- SN76489.LatchedRegister = 0;
-
- /* Initialise noise generator */
- SN76489.NoiseShiftRegister=NoiseInitialState;
- SN76489.NoiseFreq = 0x10;
-
- /* Reset internal M-cycle counter */
- SN76489.clocks = 0;
-}
-
-void *SN76489_GetContextPtr(void)
-{
- return (uint8 *)&SN76489;
-}
-
-int SN76489_GetContextSize(void)
-{
- return sizeof(SN76489_Context);
-}
-
-/* Updates tone amplitude in delta buffer. Call whenever amplitude might have changed. */
-INLINE void UpdateToneAmplitude(int i, int time)
-{
- /* left & right output */
- int delta_l = (SN76489.Channel[i][0] * SN76489.ToneFreqPos[i]) - SN76489.ChanOut[i][0];
- int delta_r = (SN76489.Channel[i][1] * SN76489.ToneFreqPos[i]) - SN76489.ChanOut[i][1];
- blip_add_delta(snd.blips[0], time, delta_l, delta_r);
- SN76489.ChanOut[i][0] += delta_l;
- SN76489.ChanOut[i][1] += delta_r;
-}
-
-/* Updates noise amplitude in delta buffer. Call whenever amplitude might have changed. */
-INLINE void UpdateNoiseAmplitude(int time)
-{
- /* left & right output */
- int delta_l = (SN76489.Channel[3][0] * ( SN76489.NoiseShiftRegister & 0x1 )) - SN76489.ChanOut[3][0];
- int delta_r = (SN76489.Channel[3][1] * ( SN76489.NoiseShiftRegister & 0x1 )) - SN76489.ChanOut[3][1];
- blip_add_delta(snd.blips[0], time, delta_l, delta_r);
- SN76489.ChanOut[3][0] += delta_l;
- SN76489.ChanOut[3][1] += delta_r;
-}
-
-/* Runs tone channel for clock_length clocks */
-static void RunTone(int i, int clocks)
-{
- int time;
-
- /* Update in case a register changed etc. */
- UpdateToneAmplitude(i, SN76489.clocks);
-
- /* Time of next transition */
- time = SN76489.ToneFreqVals[i];
-
- /* Process any transitions that occur within clocks we're running */
- while (time < clocks)
- {
- /* Flip the flip-flop */
- SN76489.ToneFreqPos[i] ^= 1;
- UpdateToneAmplitude(i, time);
-
- /* Advance to time of next transition */
- time += SN76489.Registers[i*2] * PSG_MCYCLES_RATIO;
- }
-
- /* Update channel tone counter */
- SN76489.ToneFreqVals[i] = time;
-}
-
-/* Runs noise channel for clock_length clocks */
-static void RunNoise(int clocks)
-{
- int time;
-
- /* Noise channel: match to tone2 if in slave mode */
- int NoiseFreq = SN76489.NoiseFreq;
- if (NoiseFreq == 0x80)
- {
- NoiseFreq = SN76489.Registers[2*2];
- SN76489.ToneFreqVals[3] = SN76489.ToneFreqVals[2];
- }
-
- /* Update in case a register changed etc. */
- UpdateNoiseAmplitude(SN76489.clocks);
-
- /* Time of next transition */
- time = SN76489.ToneFreqVals[3];
-
- /* Process any transitions that occur within clocks we're running */
- while (time < clocks)
- {
- /* Flip the flip-flop */
- SN76489.ToneFreqPos[3] ^= 1;
- if (SN76489.ToneFreqPos[3])
- {
- /* On the positive edge of the square wave (only once per cycle) */
- int Feedback = SN76489.NoiseShiftRegister;
- if ( SN76489.Registers[6] & 0x4 )
- {
- /* White noise */
- /* Calculate parity of fed-back bits for feedback */
- /* Do some optimised calculations for common (known) feedback values */
- /* If two bits fed back, I can do Feedback=(nsr & fb) && (nsr & fb ^ fb) */
- /* since that's (one or more bits set) && (not all bits set) */
- Feedback = ((Feedback & SN76489.NoiseFeedback) && ((Feedback & SN76489.NoiseFeedback) ^ SN76489.NoiseFeedback));
- }
- else /* Periodic noise */
- Feedback = Feedback & 1;
-
- SN76489.NoiseShiftRegister = (SN76489.NoiseShiftRegister >> 1) | (Feedback << (SN76489.SRWidth - 1));
- UpdateNoiseAmplitude(time);
- }
-
- /* Advance to time of next transition */
- time += NoiseFreq * PSG_MCYCLES_RATIO;
- }
-
- /* Update channel tone counter */
- SN76489.ToneFreqVals[3] = time;
-}
-
-static void SN76489_RunUntil(unsigned int clocks)
-{
- int i;
-
- /* Run noise first, since it might use current value of third tone frequency counter */
- RunNoise(clocks);
-
- /* Run tone channels */
- for (i=0; i<3; ++i)
- {
- RunTone(i, clocks);
- }
-}
-
-void SN76489_Config(unsigned int clocks, int preAmp, int boostNoise, int stereo)
-{
- int i;
-
- /* cycle-accurate Game Gear stereo */
- if (clocks > SN76489.clocks)
- {
- /* Run chip until current timestamp */
- SN76489_RunUntil(clocks);
-
- /* Update internal M-cycle counter */
- SN76489.clocks += ((clocks - SN76489.clocks + PSG_MCYCLES_RATIO - 1) / PSG_MCYCLES_RATIO) * PSG_MCYCLES_RATIO;
- }
-
- for (i=0; i<4; i++)
- {
- /* stereo channel pre-amplification */
- SN76489.PreAmp[i][0] = preAmp * ((stereo >> (i + 4)) & 1);
- SN76489.PreAmp[i][1] = preAmp * ((stereo >> (i + 0)) & 1);
-
- /* noise channel boost (applied to all channels) */
- SN76489.PreAmp[i][0] = SN76489.PreAmp[i][0] << boostNoise;
- SN76489.PreAmp[i][1] = SN76489.PreAmp[i][1] << boostNoise;
-
- /* update stereo channel amplitude */
- SN76489.Channel[i][0]= (PSGVolumeValues[SN76489.Registers[i*2 + 1]] * SN76489.PreAmp[i][0]) / 100;
- SN76489.Channel[i][1]= (PSGVolumeValues[SN76489.Registers[i*2 + 1]] * SN76489.PreAmp[i][1]) / 100;
- }
-}
-
-void SN76489_Update(unsigned int clocks)
-{
- int i;
-
- if (clocks > SN76489.clocks)
- {
- /* Run chip until current timestamp */
- SN76489_RunUntil(clocks);
-
- /* Update internal M-cycle counter */
- SN76489.clocks += ((clocks - SN76489.clocks + PSG_MCYCLES_RATIO - 1) / PSG_MCYCLES_RATIO) * PSG_MCYCLES_RATIO;
- }
-
- /* Adjust internal M-cycle counter for next frame */
- SN76489.clocks -= clocks;
-
- /* Adjust channel time counters for new frame */
- for (i=0; i<4; ++i)
- {
- SN76489.ToneFreqVals[i] -= clocks;
- }
-}
-
-void SN76489_Write(unsigned int clocks, unsigned int data)
-{
- unsigned int index;
-
- if (clocks > SN76489.clocks)
- {
- /* run chip until current timestamp */
- SN76489_RunUntil(clocks);
-
- /* update internal M-cycle counter */
- SN76489.clocks += ((clocks - SN76489.clocks + PSG_MCYCLES_RATIO - 1) / PSG_MCYCLES_RATIO) * PSG_MCYCLES_RATIO;
- }
-
- if (data & 0x80)
- {
- /* latch byte %1 cc t dddd */
- SN76489.LatchedRegister = index = (data >> 4) & 0x07;
- }
- else
- {
- /* restore latched register index */
- index = SN76489.LatchedRegister;
- }
-
- switch (index)
- {
- case 0:
- case 2:
- case 4: /* Tone Channels frequency */
- {
- if (data & 0x80)
- {
- /* Data byte %1 cc t dddd */
- SN76489.Registers[index] = (SN76489.Registers[index] & 0x3f0) | (data & 0xf);
- }
- else
- {
- /* Data byte %0 - dddddd */
- SN76489.Registers[index] = (SN76489.Registers[index] & 0x00f) | ((data & 0x3f) << 4);
- }
-
- /* zero frequency behaves the same as a value of 1 */
- if (SN76489.Registers[index] == 0)
- {
- SN76489.Registers[index] = 1;
- }
- break;
- }
-
- case 1:
- case 3:
- case 5: /* Tone Channels attenuation */
- {
- data &= 0x0f;
- SN76489.Registers[index] = data;
- data = PSGVolumeValues[data];
- index >>= 1;
- SN76489.Channel[index][0] = (data * SN76489.PreAmp[index][0]) / 100;
- SN76489.Channel[index][1] = (data * SN76489.PreAmp[index][1]) / 100;
- break;
- }
-
- case 6: /* Noise control */
- {
- SN76489.Registers[6] = data & 0x0f;
-
- /* reset shift register */
- SN76489.NoiseShiftRegister = NoiseInitialState;
-
- /* set noise signal generator frequency */
- SN76489.NoiseFreq = 0x10 << (data&0x3);
- break;
- }
-
- case 7: /* Noise attenuation */
- {
- data &= 0x0f;
- SN76489.Registers[7] = data;
- data = PSGVolumeValues[data];
- SN76489.Channel[3][0] = (data * SN76489.PreAmp[3][0]) / 100;
- SN76489.Channel[3][1] = (data * SN76489.PreAmp[3][1]) / 100;
- break;
- }
- }
-}
diff --git a/core/sound/sn76489.h b/core/sound/sn76489.h
deleted file mode 100644
index 157a9f5..0000000
--- a/core/sound/sn76489.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- SN76489 emulation
- by Maxim in 2001 and 2002
-*/
-
-#ifndef _SN76489_H_
-#define _SN76489_H_
-
-#include "blip_buf.h"
-
-#define SN_DISCRETE 0
-#define SN_INTEGRATED 1
-
-/* Function prototypes */
-extern void SN76489_Init(int type);
-extern void SN76489_Reset(void);
-extern void SN76489_Config(unsigned int clocks, int preAmp, int boostNoise, int stereo);
-extern void SN76489_Write(unsigned int clocks, unsigned int data);
-extern void SN76489_Update(unsigned int cycles);
-extern void *SN76489_GetContextPtr(void);
-extern int SN76489_GetContextSize(void);
-
-#endif /* _SN76489_H_ */
diff --git a/core/sound/sound.c b/core/sound/sound.c
index f1862ff..f99da18 100644
--- a/core/sound/sound.c
+++ b/core/sound/sound.c
@@ -86,7 +86,7 @@ void sound_init( void )
YM_Update = YM2612Update;
YM_Write = YM2612Write;
- /* chip is running a VCLK / 144 = MCLK / 7 / 144 */
+ /* chip is running at VCLK / 144 = MCLK / 7 / 144 */
fm_cycles_ratio = 144 * 7;
}
else
@@ -97,21 +97,20 @@ void sound_init( void )
YM_Update = YM2413Update;
YM_Write = YM2413Write;
- /* chip is running a ZCLK / 72 = MCLK / 15 / 72 */
+ /* chip is running at ZCLK / 72 = MCLK / 15 / 72 */
fm_cycles_ratio = 72 * 15;
}
/* Initialize PSG chip */
- SN76489_Init((system_hw == SYSTEM_SG) ? SN_DISCRETE : SN_INTEGRATED);
- SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff);
+ psg_init((system_hw == SYSTEM_SG) ? PSG_DISCRETE : PSG_INTEGRATED);
}
void sound_reset(void)
{
/* reset sound chips */
YM_Reset();
- SN76489_Reset();
- SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff);
+ psg_reset();
+ psg_config(0, config.psg_preamp, 0xff);
/* reset FM buffer ouput */
fm_last[0] = fm_last[1] = 0;
@@ -127,8 +126,10 @@ int sound_update(unsigned int cycles)
{
int prev_l, prev_r, preamp, time, l, r, *ptr;
- /* Run PSG & FM chips until end of frame */
- SN76489_Update(cycles);
+ /* Run PSG chip until end of frame */
+ psg_end_frame(cycles);
+
+ /* Run FM chip until end of frame */
fm_update(cycles);
/* FM output pre-amplification */
@@ -210,7 +211,7 @@ int sound_context_save(uint8 *state)
save_param(YM2413GetContextPtr(),YM2413GetContextSize());
}
- save_param(SN76489_GetContextPtr(),SN76489_GetContextSize());
+ bufferptr += psg_context_save(&state[bufferptr]);
save_param(&fm_cycles_start,sizeof(fm_cycles_start));
@@ -231,7 +232,7 @@ int sound_context_load(uint8 *state)
load_param(YM2413GetContextPtr(),YM2413GetContextSize());
}
- load_param(SN76489_GetContextPtr(),SN76489_GetContextSize());
+ bufferptr += psg_context_load(&state[bufferptr]);
load_param(&fm_cycles_start,sizeof(fm_cycles_start));
fm_cycles_count = fm_cycles_start;
diff --git a/core/state.c b/core/state.c
index f79fd3d..3bdab0b 100644
--- a/core/state.c
+++ b/core/state.c
@@ -2,7 +2,7 @@
* Genesis Plus
* Savestate support
*
- * Copyright (C) 2007-2014 Eke-Eke (Genesis Plus GX)
+ * Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -116,11 +116,11 @@ int state_load(unsigned char *state)
bufferptr += sound_context_load(&state[bufferptr]);
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
{
- SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff);
+ psg_config(0, config.psg_preamp, 0xff);
}
else
{
- SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, io_reg[6]);
+ psg_config(0, config.psg_preamp, io_reg[6]);
}
/* 68000 */
diff --git a/core/state.h b/core/state.h
index 6b480c0..1ac9322 100644
--- a/core/state.h
+++ b/core/state.h
@@ -2,7 +2,7 @@
* Genesis Plus
* Savestate support
*
- * Copyright (C) 2007-2014 Eke-Eke (Genesis Plus GX)
+ * Copyright (C) 2007-2016 Eke-Eke (Genesis Plus GX)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
diff --git a/gcw0/Makefile b/gcw0/Makefile
index b17ced2..2400056 100644
--- a/gcw0/Makefile
+++ b/gcw0/Makefile
@@ -71,7 +71,7 @@ OBJECTS += $(OBJDIR)/input.o \
$(OBJDIR)/graphic_board.o
OBJECTS += $(OBJDIR)/sound.o \
- $(OBJDIR)/sn76489.o \
+ $(OBJDIR)/psg.o \
$(OBJDIR)/ym2413.o \
$(OBJDIR)/ym2612.o
diff --git a/gcw0/config.c b/gcw0/config.c
index 564cfaf..16b7b15 100644
--- a/gcw0/config.c
+++ b/gcw0/config.c
@@ -42,7 +42,7 @@ void set_config_defaults(void)
config.psg_preamp = 150;
config.fm_preamp = 100;
config.hq_fm = 1;
- config.psgBoostNoise = 1;
+ config.hq_psg = 1;
config.filter = 1;
config.low_freq = 200;
config.high_freq = 8000;
diff --git a/gcw0/config.h b/gcw0/config.h
index 9b522e1..9cf5ed5 100644
--- a/gcw0/config.h
+++ b/gcw0/config.h
@@ -20,7 +20,7 @@ typedef struct
{
uint8 hq_fm;
uint8 filter;
- uint8 psgBoostNoise;
+ uint8 hq_psg;
uint8 dac_bits;
uint8 ym2413;
int16 psg_preamp;
diff --git a/gx/config.c b/gx/config.c
index 3d1c67f..f3da2c2 100644
--- a/gx/config.c
+++ b/gx/config.c
@@ -3,7 +3,7 @@
*
* Genesis Plus GX configuration file support
*
- * Copyright Eke-Eke (2007-2015)
+ * Copyright Eke-Eke (2007-2016)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -101,7 +101,7 @@ void config_default(void)
config.psg_preamp = 150;
config.fm_preamp = 100;
config.hq_fm = 1;
- config.psgBoostNoise = 1;
+ config.hq_psg = 1;
config.filter = 1;
config.lp_range = 0x9999; /* 0.6 in 16.16 fixed point */
config.low_freq = 880;
diff --git a/gx/config.h b/gx/config.h
index 3aad3db..9bc3097 100644
--- a/gx/config.h
+++ b/gx/config.h
@@ -3,7 +3,7 @@
*
* Genesis Plus GX configuration file support
*
- * Copyright Eke-Eke (2007-2015)
+ * Copyright Eke-Eke (2007-2016)
*
* Redistribution and use of this code or any derivative works are permitted
* provided that the following conditions are met:
@@ -51,7 +51,7 @@ typedef struct
char version[16];
uint8 hq_fm;
uint8 filter;
- uint8 psgBoostNoise;
+ uint8 hq_psg;
uint8 dac_bits;
uint8 ym2413;
uint8 mono;
diff --git a/gx/gui/menu.c b/gx/gui/menu.c
index 57f9d55..0aeafb8 100644
--- a/gx/gui/menu.c
+++ b/gx/gui/menu.c
@@ -341,19 +341,19 @@ static gui_item items_options[] =
/* Audio options */
static gui_item items_audio[] =
{
- {NULL,NULL,"Master System FM: AUTO", "Enable/disable YM2413 chip", 56,132,276,48},
- {NULL,NULL,"High-Quality FM: ON", "Adjust YM2612/YM2413 resampling quality", 56,132,276,48},
- {NULL,NULL,"FM Resolution: MAX", "Adjust YM2612 DAC precision", 56,132,276,48},
- {NULL,NULL,"FM Volume: 1.00", "Adjust YM2612/YM2413 output level", 56,132,276,48},
- {NULL,NULL,"PSG Volume: 2.50", "Adjust SN76489 output level", 56,132,276,48},
- {NULL,NULL,"PSG Noise Boost: OFF", "Boost SN76489 Noise Channel", 56,132,276,48},
- {NULL,NULL,"Audio Out: STEREO", "Select audio mixing output type", 56,132,276,48},
- {NULL,NULL,"Filtering: 3-BAND EQ", "Setup Audio filtering", 56,132,276,48},
- {NULL,NULL,"Low Gain: 1.00", "Adjust EQ Low Band Gain", 56,132,276,48},
- {NULL,NULL,"Mid Gain: 1.00", "Adjust EQ Mid Band Gain", 56,132,276,48},
- {NULL,NULL,"High Gain: 1.00", "Adjust EQ High Band Gain", 56,132,276,48},
- {NULL,NULL,"Low Freq: 200 Hz", "Adjust EQ Lowest Frequency", 56,132,276,48},
- {NULL,NULL,"High Freq: 20000 Hz", "Adjust EQ Highest Frequency", 56,132,276,48}
+ {NULL,NULL,"Master System FM: AUTO", "Enable/Disable YM2413 chip", 56,132,276,48},
+ {NULL,NULL,"High-Quality FM: ON", "Enable/Disable YM2612/YM2413 high-quality resampling", 56,132,276,48},
+ {NULL,NULL,"FM Resolution: MAX", "Adjust YM2612 DAC precision", 56,132,276,48},
+ {NULL,NULL,"FM Volume: 1.00", "Adjust YM2612/YM2413 audio balance", 56,132,276,48},
+ {NULL,NULL,"PSG Volume: 2.50", "Adjust SN76489 audio balance", 56,132,276,48},
+ {NULL,NULL,"High-Quality PSG: ON", "Enable/Disable SN76489 high-quality resampling", 56,132,276,48},
+ {NULL,NULL,"Audio Output: STEREO", "Select audio mixing output type", 56,132,276,48},
+ {NULL,NULL,"Filtering: 3-BAND EQ", "Select audio filtering type", 56,132,276,48},
+ {NULL,NULL,"Low Gain: 1.00", "Adjust EQ Low Band Gain", 56,132,276,48},
+ {NULL,NULL,"Mid Gain: 1.00", "Adjust EQ Mid Band Gain", 56,132,276,48},
+ {NULL,NULL,"High Gain: 1.00", "Adjust EQ High Band Gain", 56,132,276,48},
+ {NULL,NULL,"Low Freq: 200 Hz", "Adjust EQ Lowest Frequency", 56,132,276,48},
+ {NULL,NULL,"High Freq: 20000 Hz", "Adjust EQ Highest Frequency", 56,132,276,48}
};
/* System ROM paths */
@@ -381,10 +381,10 @@ static gui_item items_system[] =
{NULL,NULL,"VDP Mode: AUTO", "Select VDP mode", 56,132,276,48},
{NULL,NULL,"System Clock: AUTO", "Select system clock frequency", 56,132,276,48},
{NULL,NULL,"System Boot: BIOS&CART", "Select system booting method", 56,132,276,48},
- {NULL,NULL,"System Lockups: ON", "Enable/disable original system lock-ups", 56,132,276,48},
- {NULL,NULL,"68k Address Error: ON", "Enable/disable 68k address error exceptions", 56,132,276,48},
+ {NULL,NULL,"System Lockups: ON", "Enable/Disable original system lock-ups", 56,132,276,48},
+ {NULL,NULL,"68k Address Error: ON", "Enable/Disable 68k address error exceptions", 56,132,276,48},
{NULL,NULL,"Lock-on: OFF", "Select Lock-On cartridge type", 56,132,276,48},
- {NULL,NULL,"Cartridge Swap: OFF", "Enable/disable cartridge hot swap", 56,132,276,48},
+ {NULL,NULL,"Cartridge Swap: OFF", "Enable/Disable cartridge hot swap", 56,132,276,48},
{NULL,NULL,"BIOS & Lock-On ROM paths","Configure BIOS & Lock-On ROM paths", 56,132,276,48},
{NULL,NULL,"SVP Cycles: 1500", "Adjust SVP chip emulation speed", 56,132,276,48}
};
@@ -394,22 +394,22 @@ static gui_item items_video[] =
{
{NULL,NULL,"Display: PROGRESSIVE", "Select video mode", 56,132,276,48},
{NULL,NULL,"TV mode: 50/60HZ", "Select video refresh rate", 56,132,276,48},
- {NULL,NULL,"VSYNC: AUTO", "Enable/disable sync with video hardware", 56,132,276,48},
- {NULL,NULL,"Bilinear Filter: OFF", "Enable/disable GX hardware texture filtering", 56,132,276,48},
- {NULL,NULL,"Deflickering Filter: AUTO", "Enable/disable GX hardware framebuffer filtering", 56,132,276,48},
+ {NULL,NULL,"VSYNC: AUTO", "Enable/Disable sync with video hardware", 56,132,276,48},
+ {NULL,NULL,"Bilinear Filter: OFF", "Enable/Disable GX hardware texture filtering", 56,132,276,48},
+ {NULL,NULL,"Deflickering Filter: AUTO", "Enable/Disable GX hardware framebuffer filtering", 56,132,276,48},
#ifdef HW_RVL
- {NULL,NULL,"Trap Filter: ON", "Enable/disable VI hardware composite out filtering",56,132,276,48},
+ {NULL,NULL,"Trap Filter: ON", "Enable/Disable VI hardware composite out filtering",56,132,276,48},
{NULL,NULL,"Gamma Correction: 1.0", "Adjust VI hardware gamma correction", 56,132,276,48},
#endif
- {NULL,NULL,"LCD Ghosting Filter: OFF", "Enable/disable software LCD image persistence", 56,132,276,48},
- {NULL,NULL,"NTSC Filter: COMPOSITE", "Enable/disable software NTSC filtering", 56,132,276,48},
+ {NULL,NULL,"LCD Ghosting Filter: OFF", "Enable/Disable software LCD image persistence", 56,132,276,48},
+ {NULL,NULL,"NTSC Filter: COMPOSITE", "Enable/Disable software NTSC filtering", 56,132,276,48},
{NULL,NULL,"NTSC Sharpness: 0.0", "Adjust edge contrast enhancement/blurring", 56,132,276,48},
{NULL,NULL,"NTSC Resolution: 0.0", "Adjust image resolution", 56,132,276,48},
{NULL,NULL,"NTSC Artifacts: 0.0", "Adjust artifacts caused by color changes", 56,132,276,48},
{NULL,NULL,"NTSC Color Bleed: 0.0", "Adjust color resolution reduction", 56,132,276,48},
{NULL,NULL,"NTSC Color Fringing: 0.0", "Adjust artifacts caused by brightness changes", 56,132,276,48},
- {NULL,NULL,"Borders: OFF", "Enable/disable overscan emulation", 56,132,276,48},
- {NULL,NULL,"GG screen: ORIGINAL", "Enable/disable Game Gear extended screen", 56,132,276,48},
+ {NULL,NULL,"Borders: OFF", "Enable/Disable overscan emulation", 56,132,276,48},
+ {NULL,NULL,"GG screen: ORIGINAL", "Enable/Disable Game Gear extended screen", 56,132,276,48},
{NULL,NULL,"Aspect: ORIGINAL (4:3)", "Select display aspect ratio", 56,132,276,48},
{NULL,NULL,"Screen Position (+0,+0)", "Adjust display position", 56,132,276,48},
{NULL,NULL,"Screen Scaling (+0,+0)", "Adjust display scaling", 56,132,276,48}
@@ -418,19 +418,19 @@ static gui_item items_video[] =
/* Menu options */
static gui_item items_prefs[] =
{
- {NULL,NULL,"Auto ROM Load: OFF", "Enable/disable automatic ROM loading on startup", 56,132,276,48},
- {NULL,NULL,"Auto Cheats: OFF", "Enable/disable automatic cheats activation", 56,132,276,48},
- {NULL,NULL,"Auto Saves: OFF", "Enable/disable automatic saves", 56,132,276,48},
+ {NULL,NULL,"Auto ROM Load: OFF", "Enable/Disable automatic ROM loading on startup", 56,132,276,48},
+ {NULL,NULL,"Auto Cheats: OFF", "Enable/Disable automatic cheats activation", 56,132,276,48},
+ {NULL,NULL,"Auto Saves: OFF", "Enable/Disable automatic saves", 56,132,276,48},
{NULL,NULL,"ROM Load Device: SD", "Configure default device for ROM files", 56,132,276,48},
{NULL,NULL,"Saves Device: FAT", "Configure default device for Save files", 56,132,276,48},
{NULL,NULL,"SFX Volume: 100", "Adjust sound effects volume", 56,132,276,48},
{NULL,NULL,"BGM Volume: 100", "Adjust background music volume", 56,132,276,48},
- {NULL,NULL,"BG Overlay: ON", "Enable/disable background overlay", 56,132,276,48},
+ {NULL,NULL,"BG Overlay: ON", "Enable/Disable background overlay", 56,132,276,48},
{NULL,NULL,"Screen Width: 658", "Adjust menu screen width in pixels", 56,132,276,48},
- {NULL,NULL,"Show CD Leds: OFF", "Enable/disable CD leds display", 56,132,276,48},
- {NULL,NULL,"Show FPS: OFF", "Enable/disable FPS counter", 56,132,276,48},
+ {NULL,NULL,"Show CD Leds: OFF", "Enable/Disable CD leds display", 56,132,276,48},
+ {NULL,NULL,"Show FPS: OFF", "Enable/Disable FPS counter", 56,132,276,48},
#ifdef HW_RVL
- {NULL,NULL,"Wiimote Timeout: OFF","Enable/disable Wii remote automatic shutodwn", 56,132,276,48},
+ {NULL,NULL,"Wiimote Timeout: OFF","Enable/Disable Wii remote automatic shutodwn", 56,132,276,48},
{NULL,NULL,"Wiimote Calibration: AUTO","Calibrate Wii remote pointer", 56,132,276,48},
#endif
};
@@ -899,16 +899,15 @@ static void soundmenu ()
else if (config.ym2413 == 1) sprintf (items[0].text, "Master System FM: ON");
else sprintf (items[0].text, "Master System FM: AUTO");
- if (config.hq_fm) sprintf (items[1].text, "High-Quality FM: ON");
- else sprintf (items[1].text, "High-Quality FM: OFF");
+ sprintf (items[1].text, "High-Quality FM: %s", config.hq_fm ? "ON":"OFF");
if (config.dac_bits < 14) sprintf (items[2].text, "FM Resolution: %d bits", config.dac_bits);
else sprintf (items[2].text, "FM Resolution: MAX");
sprintf (items[3].text, "FM Volume: %1.2f", fm_volume);
sprintf (items[4].text, "PSG Volume: %1.2f", psg_volume);
- sprintf (items[5].text, "PSG Noise Boost: %s", config.psgBoostNoise ? "ON":"OFF");
- sprintf (items[6].text, "Audio Out: %s", config.mono ? "MONO":"STEREO");
+ sprintf (items[5].text, "High-Quality PSG: %s", config.hq_psg? "ON":"OFF");
+ sprintf (items[6].text, "Audio Output: %s", config.mono ? "MONO":"STEREO");
if (config.filter == 2)
{
@@ -971,8 +970,7 @@ static void soundmenu ()
case 1:
{
config.hq_fm ^= 1;
- if (config.hq_fm) sprintf (items[1].text, "High-Quality FM: ON");
- else sprintf (items[1].text, "High-Quality FM: OFF");
+ sprintf (items[1].text, "High-Quality FM: %s", config.hq_fm ? "ON":"OFF");
break;
}
@@ -1001,27 +999,19 @@ static void soundmenu ()
config.psg_preamp = (int)(psg_volume * 100.0 + 0.5);
if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
{
- SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff);
+ psg_config(0, config.psg_preamp, 0xff);
}
else
{
- SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, io_reg[6]);
+ psg_config(0, config.psg_preamp, io_reg[6]);
}
break;
}
case 5:
{
- config.psgBoostNoise ^= 1;
- sprintf (items[5].text, "PSG Noise Boost: %s", config.psgBoostNoise ? "ON":"OFF");
- if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
- {
- SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff);
- }
- else
- {
- SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, io_reg[6]);
- }
+ config.hq_psg ^= 1;
+ sprintf (items[5].text, "High-Quality PSG: %s", config.hq_psg ? "ON":"OFF");
break;
}
@@ -1745,8 +1735,8 @@ static void videomenu ()
else
sprintf (items[VI_OFFSET+1].text, "NTSC Filter: OFF");
- strcpy(items[VI_OFFSET+2+ntsc_offset].comment, "Enable/disable overscan emulation");
- strcpy(items[VI_OFFSET+3+ntsc_offset].comment, "Enable/disable Game Gear extended screen");
+ strcpy(items[VI_OFFSET+2+ntsc_offset].comment, "Enable/Disable overscan emulation");
+ strcpy(items[VI_OFFSET+3+ntsc_offset].comment, "Enable/Disable Game Gear extended screen");
strcpy(items[VI_OFFSET+4+ntsc_offset].comment, "Select display aspect ratio");
strcpy(items[VI_OFFSET+5+ntsc_offset].comment, "Adjust display position");
strcpy(items[VI_OFFSET+6+ntsc_offset].comment, "Adjust display scaling");
@@ -3645,15 +3635,15 @@ static void showcredits(void)
gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
FONT_writeCenter("Genesis Plus Core", 24, 0, 640, 480 - offset, (GXColor)LIGHT_BLUE);
- FONT_writeCenter("improved emulation code, fixes & extra features by Eke-Eke", 18, 0, 640, 516 - offset, (GXColor)WHITE);
+ FONT_writeCenter("improved emulation code & extra features by Eke-Eke", 18, 0, 640, 516 - offset, (GXColor)WHITE);
FONT_writeCenter("original 1.3 version by Charles MacDonald", 18, 0, 640, 534 - offset, (GXColor)WHITE);
FONT_writeCenter("original Z80 core by Juergen Buchmueller", 18, 0, 640, 552 - offset, (GXColor)WHITE);
FONT_writeCenter("original 68k core (Musashi) by Karl Stenerud", 18, 0, 640, 570 - offset, (GXColor)WHITE);
FONT_writeCenter("original YM2612/2413 cores by Jarek Burczynski, Tatsuyuki Satoh", 18, 0, 640, 588 - offset, (GXColor)WHITE);
- FONT_writeCenter("original SN76489 core by Maxim", 18, 0, 640, 606 - offset, (GXColor)WHITE);
- FONT_writeCenter("SVP core by Gravydas Ignotas (Notaz)", 18, 0, 640, 624 - offset, (GXColor)WHITE);
- FONT_writeCenter("Blip Buffer Library & NTSC Video Filter by Shay Green (Blargg)", 18, 0, 640, 642 - offset, (GXColor)WHITE);
- FONT_writeCenter("3-Band EQ implementation by Neil C", 18, 0, 640, 660 - offset, (GXColor)WHITE);
+ FONT_writeCenter("SVP core by Gravydas Ignotas (Notaz)", 18, 0, 640, 606 - offset, (GXColor)WHITE);
+ FONT_writeCenter("Blip Buffer Library & NTSC Video Filter by Shay Green (Blargg)", 18, 0, 640, 624 - offset, (GXColor)WHITE);
+ FONT_writeCenter("3-Band EQ implementation by Neil C", 18, 0, 640, 642 - offset, (GXColor)WHITE);
+ FONT_writeCenter("Ogg Vorbis 'Tremor' Library by Xiph.org Foundation", 18, 0, 640, 660 - offset, (GXColor)WHITE);
FONT_writeCenter("Special thanks to ...", 20, 0, 640, 700 - offset, (GXColor)LIGHT_GREEN);
FONT_writeCenter("Nemesis, Tasco Deluxe, Bart Trzynadlowski, Jorge Cwik, Haze,", 18, 0, 640, 736 - offset, (GXColor)WHITE);
@@ -3670,7 +3660,7 @@ static void showcredits(void)
FONT_writeCenter("libfat by Chism", 18, 0, 640, 978 - offset, (GXColor)WHITE);
FONT_writeCenter("wiiuse by Michael Laforest (Para)", 18, 0, 640, 996 - offset, (GXColor)WHITE);
FONT_writeCenter("asndlib & OGG player by Francisco Muņoz (Hermes)", 18, 0, 640, 1014 - offset, (GXColor)WHITE);
- FONT_writeCenter("zlib, libpng & libtremor by their respective authors", 18, 0, 640, 1032 - offset, (GXColor)WHITE);
+ FONT_writeCenter("zlib & libpng by their respective authors", 18, 0, 640, 1032 - offset, (GXColor)WHITE);
FONT_writeCenter("devkitPPC by Wintermute", 18, 0, 640, 1050 - offset, (GXColor)WHITE);
FONT_writeCenter("Special thanks to ...", 20, 0, 640, 1090 - offset, (GXColor)LIGHT_GREEN);
diff --git a/libretro/debian/copyright b/libretro/debian/copyright
index 450a60b..5656c57 100644
--- a/libretro/debian/copyright
+++ b/libretro/debian/copyright
@@ -13,7 +13,7 @@ Upstream Authors:
Files: *
Copyright: 1998, 1999, 2000, 2001, 2002, 2003 Charles MacDonald
Some portions copyright Nicola Salmoria and the MAME team. All rights reserved.
- 2007-2015 Eke-Eke. All rights reserved.
+ 2007-2016 Eke-Eke. All rights reserved.
License:
Unless otherwise explicitly stated, all code in Genesis Plus GX is released
under the following license:
@@ -77,7 +77,6 @@ License: LGPLv2.1
Files: core/sound/blip_buf.c
core/sound/blip_buf.h
Copyright: 2003-2009 Shay Green
- 2012-2013 EkeEke
License: LGPLv2.1
Files: core/sound/eq.c
@@ -90,13 +89,6 @@ License: Public domain
The author assumes NO RESPONSIBILITY for any problems caused by the use of
this software.
-Files: core/sound/sn76489.c
- core/sound/sn76489.h
-Copyright: 2001, 2002 Maxim
- 2004 Charles MacDonald
- 2007, 2009, 2010, 2012 Eke-Eke
-License: Genesis Plus GX license
-
Files: core/sound/ym2413.c
core/sound/ym2413.h
Copyright: 2002 Jarek Burczynski
diff --git a/libretro/libretro.c b/libretro/libretro.c
index c6df187..4171fd7 100644
--- a/libretro/libretro.c
+++ b/libretro/libretro.c
@@ -3,7 +3,7 @@
*
* Genesis Plus GX libretro port
*
- * Copyright Eke-Eke (2007-2015)
+ * Copyright Eke-Eke (2007-2016)
*
* Copyright Daniel De Matteis (2012-2016)
*
@@ -495,8 +495,8 @@ static void config_default(void)
/* sound options */
config.psg_preamp = 150;
config.fm_preamp = 100;
- config.hq_fm = 1; /* high-quality resampling */
- config.psgBoostNoise = 1;
+ config.hq_fm = 1; /* high-quality FM resampling (slower) */
+ config.hq_psg = 1; /* high-quality PSG resampling (slower) */
config.filter = 0; /* no filter */
config.lp_range = 0x9999; /* 0.6 in 16.16 fixed point */
config.low_freq = 880;
@@ -504,7 +504,7 @@ static void config_default(void)
config.lg = 1.0;
config.mg = 1.0;
config.hg = 1.0;
- config.dac_bits = 14; /* MAX DEPTH */
+ config.dac_bits = 14; /* MAX DEPTH */
config.ym2413 = 2; /* AUTO */
config.mono = 0; /* STEREO output */
diff --git a/libretro/msvc/msvc-2003-xbox1/msvc-2003-xbox1.vcproj b/libretro/msvc/msvc-2003-xbox1/msvc-2003-xbox1.vcproj
index 7a597ad..4563a92 100644
--- a/libretro/msvc/msvc-2003-xbox1/msvc-2003-xbox1.vcproj
+++ b/libretro/msvc/msvc-2003-xbox1/msvc-2003-xbox1.vcproj
@@ -394,7 +394,7 @@
RelativePath="..\..\..\core\sound\eq.c">
+ RelativePath="..\..\..\core\sound\psg.c">
diff --git a/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj b/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj
index c97d11e..41d892f 100644
--- a/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj
+++ b/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj
@@ -143,7 +143,7 @@
CompileAsC
-
+
diff --git a/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters b/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters
index ae6ed86..ef720ec 100644
--- a/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters
+++ b/libretro/msvc/msvc-2010-360/msvc-2010-360.vcxproj.filters
@@ -80,7 +80,7 @@
Source Files\sound
-
+
Source Files\sound
diff --git a/libretro/msvc/msvc-2010/msvc-2010.vcxproj b/libretro/msvc/msvc-2010/msvc-2010.vcxproj
index 11ed4df..f6972c0 100644
--- a/libretro/msvc/msvc-2010/msvc-2010.vcxproj
+++ b/libretro/msvc/msvc-2010/msvc-2010.vcxproj
@@ -49,7 +49,7 @@
-
+
diff --git a/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters b/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters
index 262e025..32ee69b 100644
--- a/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters
+++ b/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters
@@ -117,7 +117,7 @@
Source Files\sound
-
+
Source Files\sound
diff --git a/libretro/osd.h b/libretro/osd.h
index befd26d..4c02b68 100644
--- a/libretro/osd.h
+++ b/libretro/osd.h
@@ -3,7 +3,7 @@
*
* Genesis Plus GX libretro port
*
- * Copyright Eke-Eke (2007-2015)
+ * Copyright Eke-Eke (2007-2016)
*
* Copyright Daniel De Matteis (2012-2016)
*
@@ -84,7 +84,7 @@ struct
char version[16];
uint8 hq_fm;
uint8 filter;
- uint8 psgBoostNoise;
+ uint8 hq_psg;
uint8 dac_bits;
uint8 ym2413;
uint8 mono;
diff --git a/psp2/Makefile b/psp2/Makefile
index 36bb06a..6c6a743 100644
--- a/psp2/Makefile
+++ b/psp2/Makefile
@@ -69,7 +69,7 @@ OBJECTS += $(OBJDIR)/input.o \
$(OBJDIR)/graphic_board.o
OBJECTS += $(OBJDIR)/sound.o \
- $(OBJDIR)/sn76489.o \
+ $(OBJDIR)/psg.o \
$(OBJDIR)/ym2413.o \
$(OBJDIR)/ym2612.o
diff --git a/psp2/config.c b/psp2/config.c
index 93f2ae3..b8299e2 100644
--- a/psp2/config.c
+++ b/psp2/config.c
@@ -11,7 +11,7 @@ void set_config_defaults(void)
config.psg_preamp = 150;
config.fm_preamp = 100;
config.hq_fm = 0;
- config.psgBoostNoise = 1;
+ config.hq_psg = 0;
config.filter = 1;
config.low_freq = 200;
config.high_freq = 8000;
diff --git a/psp2/config.h b/psp2/config.h
index 30c2c5b..44aaddb 100644
--- a/psp2/config.h
+++ b/psp2/config.h
@@ -19,7 +19,7 @@ typedef struct
{
uint8 hq_fm;
uint8 filter;
- uint8 psgBoostNoise;
+ uint8 hq_psg;
uint8 dac_bits;
uint8 ym2413;
int16 psg_preamp;
diff --git a/sdl/Makefile.sdl1 b/sdl/Makefile.sdl1
index 7be4437..dc38ca7 100644
--- a/sdl/Makefile.sdl1
+++ b/sdl/Makefile.sdl1
@@ -67,7 +67,7 @@ OBJECTS += $(OBJDIR)/input.o \
$(OBJDIR)/graphic_board.o
OBJECTS += $(OBJDIR)/sound.o \
- $(OBJDIR)/sn76489.o \
+ $(OBJDIR)/psg.o \
$(OBJDIR)/ym2413.o \
$(OBJDIR)/ym2612.o
diff --git a/sdl/Makefile.sdl2 b/sdl/Makefile.sdl2
index 73b2ede..46b5895 100644
--- a/sdl/Makefile.sdl2
+++ b/sdl/Makefile.sdl2
@@ -67,7 +67,7 @@ OBJECTS += $(OBJDIR)/input.o \
$(OBJDIR)/graphic_board.o
OBJECTS += $(OBJDIR)/sound.o \
- $(OBJDIR)/sn76489.o \
+ $(OBJDIR)/psg.o \
$(OBJDIR)/ym2413.o \
$(OBJDIR)/ym2612.o
diff --git a/sdl/config.c b/sdl/config.c
index 99aa1e8..933e669 100644
--- a/sdl/config.c
+++ b/sdl/config.c
@@ -12,7 +12,7 @@ void set_config_defaults(void)
config.psg_preamp = 150;
config.fm_preamp = 100;
config.hq_fm = 1;
- config.psgBoostNoise = 1;
+ config.hq_psg = 1;
config.filter = 1;
config.low_freq = 200;
config.high_freq = 8000;
diff --git a/sdl/config.h b/sdl/config.h
index 3434204..78e7c84 100644
--- a/sdl/config.h
+++ b/sdl/config.h
@@ -15,7 +15,7 @@ typedef struct
{
uint8 hq_fm;
uint8 filter;
- uint8 psgBoostNoise;
+ uint8 hq_psg;
uint8 dac_bits;
uint8 ym2413;
int16 psg_preamp;