[~]fixed ym2612 context restore

[~]small fixes to SSG-EG emulation (should be finally fine !)
This commit is contained in:
ekeeke31 2009-02-28 17:49:31 +00:00
parent 914b8d22f2
commit 99e00b8fe3
10 changed files with 66 additions and 48 deletions

View File

@ -6,15 +6,16 @@ Genesis Plus GX 1.3.2 (??/??/????) (Eke-Eke)
------
* modified SN76489 cut-off frequency
* removed old Gens YM2612 core support
* improved MAME YM2612 core accuracy: SSG-EG mode, CSM mode (based on Nemesis real hardware's last tests)
* fixed YM2612 context restore
* modified sound update engine to fix synchronization issues (see below)
* various code cleanup
* removed now outdated Gens YM2612 core
* improved MAME YM2612 accuracy (SSG-EG, CSM mode and more !), based upon Nemesis last tests on real hardware
* improved FM context restore when loading savesates
* modified sound update functions to be compatible with the new advanced synchronization techniques
* various code cleanup & optimization
[Gamecube/Wii]
* improved sound/video synchronization in 60Hz modes
* greatly improved audio/video synchronization
* fixed video skipping issues in 60Hz modes
* fixed some statibilty issues
* rewrote Font & GUI engines (now powered by GX hardware)
* new Interface design !

View File

@ -68,14 +68,10 @@ void legal ()
DrawTexture(&texture, (640-texture.width)/2, ypos, texture.width, texture.height);
ypos += texture.height + 2 * fheight;
#ifdef HW_RVL
SetScreen ();
sleep(1);
#endif
//WriteCentre (ypos, "Press A to continue");
SetScreen ();
//WaitButtonA ();
sleep (3);
sleep (2);
ClearScreen((GXColor)BLACK);
@ -86,7 +82,7 @@ void legal ()
OpenPNGFromMemory(&texture, Background_intro_c1);
DrawTexture(&texture, (640-texture.width)/2, (480-texture.height)/2, texture.width, texture.height);
SetScreen ();
sleep (2);
sleep (1);
ClearScreen((GXColor)WHITE);
texture.data = 0;
@ -96,7 +92,7 @@ void legal ()
OpenPNGFromMemory(&texture, Background_intro_c2);
DrawTexture(&texture, (640-texture.width)/2, (480-texture.height)/2, texture.width, texture.height);
SetScreen ();
sleep (2);
sleep (1);
ClearScreen((GXColor)BLACK);
texture.data = 0;
@ -106,6 +102,6 @@ void legal ()
OpenPNGFromMemory(&texture, Background_intro_c3);
DrawTexture(&texture, (640-texture.width)/2, (480-texture.height)/2, texture.width, texture.height);
SetScreen ();
sleep (3);
sleep (2);
}

View File

@ -306,8 +306,12 @@ void soundmenu ()
if (config.hq_fm>2) config.hq_fm = 0;
if (genromsize)
{
unsigned char *temp = malloc(YM2612GetContextSize());
if (!temp) break;
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
audio_init(48000);
fm_restore();
YM2612Restore(temp);
free(temp);
}
break;
@ -364,9 +368,12 @@ void miscmenu ()
/* reinitialize timings */
system_init ();
unsigned char *temp = malloc(YM2612GetContextSize());
if (temp) memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
audio_init(48000);
fm_restore();
YM2612Restore(temp);
if (temp) free(temp);
/* reinitialize HVC tables */
vctab = (vdp_pal) ? ((reg[1] & 8) ? vc_pal_240 : vc_pal_224) : vc_ntsc_224;
hctab = (reg[12] & 1) ? cycle2hc40 : cycle2hc32;

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -21,7 +21,7 @@
#include "state.h"
#include "sound.h"
#include "sn76489.h"
#include "fm.h"
#include "ym2612.h"
#include "loadrom.h"
#include "cart_hw.h"
#include "eeprom.h"

View File

@ -102,19 +102,6 @@ void sound_update(int fm_len, int psg_len)
snd.psg.lastStage = 0;
}
/* YM2612 control */
/* restore FM context */
void fm_restore(void)
{
unsigned char *temp = malloc(YM2612GetContextSize());
if (!temp) return;
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
YM2612ResetChip();
memcpy(YM2612GetContextPtr(), temp, YM2612GetContextSize());
free(temp);
}
/* write FM chip */
void fm_write(unsigned int cpu, unsigned int address, unsigned int data)
{

View File

@ -27,7 +27,6 @@
/* Function prototypes */
extern void sound_init(int rate);
extern void sound_update(int fm_len, int psg_len);
extern void fm_restore(void);
extern void fm_write(unsigned int cpu, unsigned int address, unsigned int data);
extern unsigned int fm_read(unsigned int cpu, unsigned int address);
extern void psg_write(unsigned int cpu, unsigned int data);

View File

@ -17,15 +17,16 @@
**
** - removed multichip support (unused)
** - added YM2612 Context external access functions
** - implemented correct LFO phase update in CH3 special mode (Warlock birds, Alladin bug sound)
** - added LFO phase update in CH3 special mode (Warlock birds, Alladin bug sound)
** - fixed internal timers emulation
** - fixed Attack Rate update on register write (Batman & Robin intro)
** - fixed EG behavior on KEY ON when Attack Rate is maximal
** - fixed EG behavior on decay->substain transition when SL=0 (Mega Turrican tracks 03,09...)
** - added Attack Rate immediate update on register write (Batman & Robin intro)
** - fixed EG behavior when Attack Rate is maximal
** - fixed EG behavior when SL=0 (Mega Turrican tracks 03,09...) or/and Key ON occurs at minimal attenuation
** - added EG output immediate update on register writes
** - fixed YM2612 initial values (after the reset)
** - implemented correct Detune overflow (Ariel, Comix Zone, Shaq Fu, Spiderman & many others)
** - implemented correct CSM mode support
** - implemented correct SSG-EG support (Asterix, Beavis&Butthead, Bubba'n Six & many others)
** - implemented Detune overflow (Ariel, Comix Zone, Shaq Fu, Spiderman & many others)
** - implemented correct CSM mode emulation
** - implemented correct SSG-EG emulation (Asterix, Beavis&Butthead, Bubba'n Six & many others)
** - adjusted some EG rates
** - modified address/data port behavior
**
@ -668,7 +669,7 @@ INLINE void FM_KEYOFF(FM_CH *CH , int s )
{
/* convert EG attenuation level */
if (SLOT->ssgn ^ (SLOT->ssg&0x04))
SLOT->volume = ((UINT32)SLOT->volume ^ 0x1FF) + 1;
SLOT->volume = (0x200 - SLOT->volume);
/* force EG attenuation level */
if (SLOT->volume >= 0x200)
@ -733,7 +734,7 @@ INLINE void FM_KEYOFF_CSM(FM_CH *CH , int s )
{
/* convert EG attenuation level */
if (SLOT->ssgn ^ (SLOT->ssg&0x04))
SLOT->volume = ((UINT32)SLOT->volume ^ 0x1FF) + 1;
SLOT->volume = (0x200 - SLOT->volume);
/* force EG attenuation level */
if (SLOT->volume >= 0x200)
@ -946,6 +947,10 @@ INLINE void set_sr(FM_SLOT *SLOT,int v)
INLINE void set_sl_rr(FM_SLOT *SLOT,int v)
{
SLOT->sl = sl_table[ v>>4 ];
/* check EG state changes */
if ((SLOT->state == EG_DEC) && (SLOT->volume >= (INT32)(SLOT->sl)))
SLOT->state = EG_SUS;
SLOT->rr = 34 + ((v&0x0f)<<2);
@ -1179,12 +1184,12 @@ INLINE void update_ssg_eg_channel(FM_SLOT *SLOT)
{
if (SLOT->ssg & 0x01) /* bit 0 = hold SSG-EG */
{
/* force inversion flag */
/* set inversion flag */
if (SLOT->ssg & 0x02)
SLOT->ssgn = 4;
/* force attenuation level */
if (!(SLOT->ssgn ^ (SLOT->ssg & 0x04)))
/* force attenuation level during decay phases */
if ((SLOT->state != EG_ATT) && !(SLOT->ssgn ^ (SLOT->ssg & 0x04)))
SLOT->volume = MAX_ATT_INDEX;
}
else /* loop SSG-EG */
@ -1947,10 +1952,10 @@ void YM2612UpdateOne(int **buffer, int length)
update_ssg_eg_channel(&ym2612.CH[5].SLOT[SLOT1]);
/* advance envelope generator */
ym2612.OPN.eg_timer ++;
if (ym2612.OPN.eg_timer == 3)
ym2612.OPN.eg_timer += ym2612.OPN.eg_timer_add;
while (ym2612.OPN.eg_timer >= ym2612.OPN.eg_timer_overflow)
{
ym2612.OPN.eg_timer = 0;
ym2612.OPN.eg_timer -= ym2612.OPN.eg_timer_overflow;
ym2612.OPN.eg_cnt++;
advance_eg_channel(&ym2612.CH[0].SLOT[SLOT1]);
@ -2135,3 +2140,18 @@ unsigned int YM2612GetContextSize(void)
{
return sizeof(YM2612);
}
void YM2612Restore(unsigned char *buffer)
{
/* save current timings */
int clock = ym2612.OPN.ST.clock;
int rate = ym2612.OPN.ST.rate;
/* restore internal state */
memcpy(&ym2612, buffer, sizeof(YM2612));
/* restore current timings */
ym2612.OPN.ST.clock = clock;
ym2612.OPN.ST.rate = rate;
OPNSetPres(6*24);
}

View File

@ -26,5 +26,6 @@ extern void YM2612Write(unsigned int a, unsigned int v);
extern unsigned int YM2612Read(void);
extern unsigned char *YM2612GetContextPtr(void);
extern unsigned int YM2612GetContextSize(void);
extern void YM2612Restore(unsigned char *buffer);
#endif /* _H_FM_FM_ */

View File

@ -79,7 +79,14 @@ void state_load(unsigned char *buffer)
vdp_restore(temp_reg);
// FM
load_param(YM2612GetContextPtr(),YM2612GetContextSize());
unsigned char *temp = malloc (YM2612GetContextSize());
if (temp)
{
load_param(temp,YM2612GetContextSize());
YM2612Restore(temp);
free(temp);
}
else bufferptr+=YM2612GetContextSize();
// PSG
load_param(SN76489_GetContextPtr (0),SN76489_GetContextSize ());