From 54687cde58d72ed965d2de5121a7fcabfbbb88d0 Mon Sep 17 00:00:00 2001 From: EkeEke Date: Mon, 15 Oct 2012 10:40:39 +0200 Subject: [PATCH] .fixed broken PSG noise frequency .improved accuracy Game Gear PSG stereo (cycle-accurate) --- source/io_ctrl.c | 2 +- source/sound/sn76489.c | 58 +++++++++++++++++++++++++----------------- source/sound/sn76489.h | 2 +- source/sound/sound.c | 2 +- source/state.c | 4 +-- 5 files changed, 39 insertions(+), 29 deletions(-) diff --git a/source/io_ctrl.c b/source/io_ctrl.c index a8642a5..2b4f924 100644 --- a/source/io_ctrl.c +++ b/source/io_ctrl.c @@ -547,7 +547,7 @@ void io_gg_write(unsigned int offset, unsigned int data) case 6: /* PSG Stereo output control */ io_reg[6] = data; - SN76489_Config(config.psg_preamp, config.psgBoostNoise, data); + SN76489_Config(Z80.cycles, config.psg_preamp, config.psgBoostNoise, data); return; default: /* Read-only */ diff --git a/source/sound/sn76489.c b/source/sound/sn76489.c index b507ac6..bcba8cb 100644 --- a/source/sound/sn76489.c +++ b/source/sound/sn76489.c @@ -157,29 +157,6 @@ void SN76489_Reset() SN76489.clocks = 0; } -void SN76489_Config(int preAmp, int boostNoise, int stereo) -{ - int i; - - for (i=0; i<4; i++) - { - /* stereo channel pre-amplification */ - SN76489.PreAmp[i][0] = preAmp * ((stereo >> (i*2)) & 1); - SN76489.PreAmp[i][1] = preAmp * ((stereo >> (i*2 + 1)) & 1); - - /* noise channel boost */ - if (i == 3) - { - SN76489.PreAmp[3][0] = SN76489.PreAmp[3][0] << boostNoise; - SN76489.PreAmp[3][1] = SN76489.PreAmp[3][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_GetContextPtr(void) { return (uint8 *)&SN76489; @@ -331,6 +308,39 @@ static void SN76489_RunUntil(unsigned int 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*2)) & 1); + SN76489.PreAmp[i][1] = preAmp * ((stereo >> (i*2 + 1)) & 1); + + /* noise channel boost */ + if (i == 3) + { + SN76489.PreAmp[3][0] = SN76489.PreAmp[3][0] << boostNoise; + SN76489.PreAmp[3][1] = SN76489.PreAmp[3][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; @@ -424,7 +434,7 @@ void SN76489_Write(unsigned int clocks, unsigned int data) SN76489.NoiseShiftRegister = NoiseInitialState; /* set noise signal generator frequency */ - SN76489.NoiseFreq = (0x10 << (data&0x3)) * PSG_MCYCLES_RATIO; + SN76489.NoiseFreq = 0x10 << (data&0x3); break; } diff --git a/source/sound/sn76489.h b/source/sound/sn76489.h index 3c59611..19d4a86 100644 --- a/source/sound/sn76489.h +++ b/source/sound/sn76489.h @@ -14,7 +14,7 @@ /* Function prototypes */ extern void SN76489_Init(blip_t* left, blip_t* right, int type); extern void SN76489_Reset(void); -extern void SN76489_Config(int preAmp, int boostNoise, int stereo); +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); diff --git a/source/sound/sound.c b/source/sound/sound.c index d36d349..868c2cf 100644 --- a/source/sound/sound.c +++ b/source/sound/sound.c @@ -102,7 +102,7 @@ void sound_init( void ) } /* Initialize PSG chip */ - SN76489_Config(config.psg_preamp, config.psgBoostNoise, 0xff); + SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff); } void sound_reset(void) diff --git a/source/state.c b/source/state.c index 7ee3fb9..e5b75f6 100644 --- a/source/state.c +++ b/source/state.c @@ -117,12 +117,12 @@ int state_load(unsigned char *state) if ((system_hw & SYSTEM_PBC) == SYSTEM_MD) { SN76489_Init(snd.blips[0][0], snd.blips[0][1], SN_INTEGRATED); - SN76489_Config(config.psg_preamp, config.psgBoostNoise, 0xff); + SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, 0xff); } else { SN76489_Init(snd.blips[0][0], snd.blips[0][1], (system_hw < SYSTEM_MARKIII) ? SN_DISCRETE : SN_INTEGRATED); - SN76489_Config(config.psg_preamp, config.psgBoostNoise, io_reg[6]); + SN76489_Config(0, config.psg_preamp, config.psgBoostNoise, io_reg[6]); } /* 68000 */