sound fixes for Ferrari GP

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@247 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-09-14 17:52:42 +00:00
parent e849512f15
commit 5f8c85be2a
4 changed files with 39 additions and 19 deletions

View file

@ -117,7 +117,7 @@ PICO_INTERNAL void sound_reset(void)
// to be called after changing sound rate or chips // to be called after changing sound rate or chips
void sound_rerate(int preserve_state) void sound_rerate(int preserve_state)
{ {
unsigned int state[28]; void *state = NULL;
int target_fps = Pico.m.pal ? 50 : 60; int target_fps = Pico.m.pal ? 50 : 60;
// not all rates are supported in MCD mode due to mp3 decoder limitations // not all rates are supported in MCD mode due to mp3 decoder limitations
@ -127,12 +127,16 @@ void sound_rerate(int preserve_state)
} }
if (preserve_state) { if (preserve_state) {
state = malloc(0x200);
if (state == NULL) return;
memcpy(state, YM2612GetRegs(), 0x200);
if ((PicoMCD & 1) && Pico_mcd->m.audio_track) if ((PicoMCD & 1) && Pico_mcd->m.audio_track)
Pico_mcd->m.audio_offset = mp3_get_offset(); Pico_mcd->m.audio_offset = mp3_get_offset();
} }
YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PsndRate); YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PsndRate);
if (preserve_state) { if (preserve_state) {
// feed it back it's own registers, just like after loading state // feed it back it's own registers, just like after loading state
memcpy(YM2612GetRegs(), state, 0x200);
YM2612PicoStateLoad(); YM2612PicoStateLoad();
if ((PicoMCD & 1) && Pico_mcd->m.audio_track) if ((PicoMCD & 1) && Pico_mcd->m.audio_track)
mp3_start_play(Pico_mcd->TOC.Tracks[Pico_mcd->m.audio_track].F, Pico_mcd->m.audio_offset); mp3_start_play(Pico_mcd->TOC.Tracks[Pico_mcd->m.audio_track].F, Pico_mcd->m.audio_offset);
@ -142,6 +146,9 @@ void sound_rerate(int preserve_state)
SN76496_init(Pico.m.pal ? OSC_PAL/15 : OSC_NTSC/15, PsndRate); SN76496_init(Pico.m.pal ? OSC_PAL/15 : OSC_NTSC/15, PsndRate);
if (preserve_state) memcpy(sn76496_regs, state, 28*4); // restore old state if (preserve_state) memcpy(sn76496_regs, state, 28*4); // restore old state
if (state)
free(state);
// calculate PsndLen // calculate PsndLen
PsndLen=PsndRate / target_fps; PsndLen=PsndRate / target_fps;
PsndLen_exc_add=((PsndRate - PsndLen*target_fps)<<16) / target_fps; PsndLen_exc_add=((PsndRate - PsndLen*target_fps)<<16) / target_fps;

View file

@ -1637,8 +1637,7 @@ void YM2612Init_(int clock, int rate)
ym2612_dacen = &ym2612.dacen; ym2612_dacen = &ym2612.dacen;
ym2612_dacout = &ym2612.dacout; ym2612_dacout = &ym2612.dacout;
/* clear everything but the regs */ memset(&ym2612, 0, sizeof(ym2612));
memset(ym2612.CH, 0, sizeof(ym2612)-sizeof(ym2612.REGS)-4);
init_tables(); init_tables();
ym2612.OPN.ST.clock = clock; ym2612.OPN.ST.clock = clock;
@ -1654,8 +1653,11 @@ void YM2612ResetChip_(void)
{ {
int i; int i;
memset(ym2612.REGS, 0, sizeof(ym2612.REGS));
OPNSetPres( 6*24 ); OPNSetPres( 6*24 );
set_timers( 0x30 ); /* mode 0 , timer reset */ set_timers( 0x30 ); /* mode 0 , timer reset */
ym2612.REGS[0x27] = 0x30;
ym2612.OPN.eg_timer = 0; ym2612.OPN.eg_timer = 0;
ym2612.OPN.eg_cnt = 0; ym2612.OPN.eg_cnt = 0;
@ -1666,6 +1668,8 @@ void YM2612ResetChip_(void)
{ {
OPNWriteReg(i ,0xc0); OPNWriteReg(i ,0xc0);
OPNWriteReg(i|0x100,0xc0); OPNWriteReg(i|0x100,0xc0);
ym2612.REGS[i ] = 0xc0;
ym2612.REGS[i|0x100] = 0xc0;
} }
for(i = 0xb2 ; i >= 0x30 ; i-- ) for(i = 0xb2 ; i >= 0x30 ; i-- )
{ {
@ -1675,6 +1679,7 @@ void YM2612ResetChip_(void)
for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(i,0); for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(i,0);
/* DAC mode clear */ /* DAC mode clear */
ym2612.dacen = 0; ym2612.dacen = 0;
ym2612.addr_A1 = 0;
} }
@ -1852,7 +1857,7 @@ int YM2612PicoTick_(int n)
void YM2612PicoStateLoad_(void) void YM2612PicoStateLoad_(void)
{ {
#ifndef EXTERNAL_YM2612 #ifndef EXTERNAL_YM2612
int i, old_A1 = ym2612.addr_A1; int i, real_A1 = ym2612.addr_A1;
reset_channels( &ym2612.CH[0], 6 ); reset_channels( &ym2612.CH[0], 6 );
@ -1861,12 +1866,13 @@ void YM2612PicoStateLoad_(void)
YM2612Write_(0, i); YM2612Write_(0, i);
YM2612Write_(1, ym2612.REGS[i]); YM2612Write_(1, ym2612.REGS[i]);
} }
for(i = 0; i < 0x100; i++) { for(i = 0; i < 0x100; i++) {
YM2612Write_(2, i); YM2612Write_(2, i);
YM2612Write_(3, ym2612.REGS[i|0x100]); YM2612Write_(3, ym2612.REGS[i|0x100]);
} }
ym2612.addr_A1 = old_A1; ym2612.addr_A1 = real_A1;
#else #else
reset_channels( &ym2612.CH[0], 6 ); reset_channels( &ym2612.CH[0], 6 );
#endif #endif

View file

@ -18,6 +18,7 @@
#include "../common/arm_utils.h" #include "../common/arm_utils.h"
#include "../common/menu.h" #include "../common/menu.h"
#include "../../Pico/PicoInt.h" #include "../../Pico/PicoInt.h"
#include "../../Pico/sound/ym2612.h"
#include "../../Pico/sound/mix.h" #include "../../Pico/sound/mix.h"
/* we will need some gp2x internals here */ /* we will need some gp2x internals here */
@ -51,10 +52,9 @@ static FILE *loaded_mp3 = 0;
/* these will be managed locally on our side */ /* these will be managed locally on our side */
extern int *ym2612_dacen; extern int *ym2612_dacen;
extern INT32 *ym2612_dacout; extern INT32 *ym2612_dacout;
extern void *ym2612_regs;
static UINT8 *REGS = 0; /* we will also keep local copy of regs for savestates and such */ static UINT8 *REGS = 0; /* we will also keep local copy of regs for savestates and such */
static INT32 addr_A1; /* address line A1 */ static INT32 *addr_A1; /* address line A1 */
static int dacen; static int dacen;
static INT32 dacout; static INT32 dacout;
static UINT8 ST_address; /* address register */ static UINT8 ST_address; /* address register */
@ -113,19 +113,19 @@ int YM2612Write_940(unsigned int a, unsigned int v)
switch( a ) { switch( a ) {
case 0: /* address port 0 */ case 0: /* address port 0 */
if (!addr_A1 && ST_address == v) if (!*addr_A1 && ST_address == v)
return 0; /* address already selected, don't send this command to 940 */ return 0; /* address already selected, don't send this command to 940 */
ST_address = v; ST_address = v;
/* don't send DAC or timer related address changes to 940 */ /* don't send DAC or timer related address changes to 940 */
if (!addr_A1 && (v & 0xf0) == 0x20 && if (!*addr_A1 && (v & 0xf0) == 0x20 &&
(v == 0x24 || v == 0x25 || v == 0x26 || v == 0x2a)) (v == 0x24 || v == 0x25 || v == 0x26 || v == 0x2a))
return 0; return 0;
addr_A1 = 0; *addr_A1 = 0;
upd = 0; upd = 0;
break; break;
case 1: /* data port 0 */ case 1: /* data port 0 */
if (addr_A1 != 0) { if (*addr_A1 != 0) {
return 0; /* verified on real YM2608 */ return 0; /* verified on real YM2608 */
} }
@ -184,15 +184,15 @@ int YM2612Write_940(unsigned int a, unsigned int v)
break; break;
case 2: /* address port 1 */ case 2: /* address port 1 */
if (addr_A1 && ST_address == v) if (*addr_A1 && ST_address == v)
return 0; return 0;
ST_address = v; ST_address = v;
addr_A1 = 1; *addr_A1 = 1;
upd = 0; upd = 0;
break; break;
case 3: /* data port 1 */ case 3: /* data port 1 */
if (addr_A1 != 1) { if (*addr_A1 != 1) {
return 0; /* verified on real YM2608 */ return 0; /* verified on real YM2608 */
} }
@ -313,7 +313,7 @@ static void add_job_940(int job)
void YM2612PicoStateLoad_940(void) void YM2612PicoStateLoad_940(void)
{ {
int i, old_A1 = addr_A1; int i, old_A1 = *addr_A1;
/* make sure JOB940_PICOSTATELOAD gets done before next JOB940_YM2612UPDATEONE */ /* make sure JOB940_PICOSTATELOAD gets done before next JOB940_YM2612UPDATEONE */
add_job_940(JOB940_PICOSTATELOAD); add_job_940(JOB940_PICOSTATELOAD);
@ -331,7 +331,7 @@ void YM2612PicoStateLoad_940(void)
YM2612Write_940(3, REGS[i|0x100]); YM2612Write_940(3, REGS[i|0x100]);
} }
addr_A1 = old_A1; *addr_A1 = old_A1;
} }
@ -345,6 +345,8 @@ static void internal_reset(void)
ST_TB = 0; ST_TB = 0;
ST_TBC = 0; ST_TBC = 0;
dacen = 0; dacen = 0;
dacout = 0;
ST_address= 0;
} }
@ -439,7 +441,11 @@ void YM2612Init_940(int baseclock, int rate)
memset(shared_data, 0, sizeof(*shared_data)); memset(shared_data, 0, sizeof(*shared_data));
memset(shared_ctl, 0, sizeof(*shared_ctl)); memset(shared_ctl, 0, sizeof(*shared_ctl));
/* cause local ym2612 to init REGS */
YM2612Init_(baseclock, rate);
REGS = YM2612GetRegs(); REGS = YM2612GetRegs();
addr_A1 = (INT32 *) (REGS + 0x200);
ym2612_dacen = &dacen; ym2612_dacen = &dacen;
ym2612_dacout = &dacout; ym2612_dacout = &dacout;

View file

@ -233,6 +233,7 @@ Changelog
* Fixed hang of NBA Jam (ingame saves do not work though). * Fixed hang of NBA Jam (ingame saves do not work though).
* Adjusted timing for "accurate timing" mode and added preliminary VDP FIFO * Adjusted timing for "accurate timing" mode and added preliminary VDP FIFO
emulation. Fixes Double Dragon 2, tearing in Chaos Engine and some other games. emulation. Fixes Double Dragon 2, tearing in Chaos Engine and some other games.
* Fixed a few games not having sound at startup.
1.33 1.33
* Updated Cyclone core to 0.0088. * Updated Cyclone core to 0.0088.