mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-25 02:31:49 +01:00
small fix to SSG-EG emulation
This commit is contained in:
parent
a857fb3990
commit
914b8d22f2
@ -563,7 +563,7 @@ typedef struct
|
|||||||
UINT8 fn_h; /* freq3 latch */
|
UINT8 fn_h; /* freq3 latch */
|
||||||
UINT8 kcode[3]; /* key code */
|
UINT8 kcode[3]; /* key code */
|
||||||
UINT32 block_fnum[3]; /* current fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */
|
UINT32 block_fnum[3]; /* current fnum value for this slot (can be different betweeen slots of one channel in 3slot mode) */
|
||||||
UINT8 key_csm; /* 1: KEY ON event occured in CSM mode */
|
UINT8 key_csm; /* CSM mode Key-ON flag */
|
||||||
|
|
||||||
} FM_3SLOT;
|
} FM_3SLOT;
|
||||||
|
|
||||||
@ -622,7 +622,7 @@ INLINE void FM_KEYON(FM_CH *CH , int s )
|
|||||||
{
|
{
|
||||||
FM_SLOT *SLOT = &CH->SLOT[s];
|
FM_SLOT *SLOT = &CH->SLOT[s];
|
||||||
|
|
||||||
if( !SLOT->key && !ym2612.OPN.SL3.key_csm)
|
if (!SLOT->key && !ym2612.OPN.SL3.key_csm)
|
||||||
{
|
{
|
||||||
/* restart Phase Generator */
|
/* restart Phase Generator */
|
||||||
SLOT->phase = 0;
|
SLOT->phase = 0;
|
||||||
@ -657,17 +657,27 @@ INLINE void FM_KEYOFF(FM_CH *CH , int s )
|
|||||||
{
|
{
|
||||||
FM_SLOT *SLOT = &CH->SLOT[s];
|
FM_SLOT *SLOT = &CH->SLOT[s];
|
||||||
|
|
||||||
if( SLOT->key && !ym2612.OPN.SL3.key_csm)
|
if (SLOT->key && !ym2612.OPN.SL3.key_csm)
|
||||||
{
|
{
|
||||||
if (SLOT->state>EG_REL)
|
if (SLOT->state>EG_REL)
|
||||||
{
|
{
|
||||||
SLOT->state = EG_REL; /* phase -> Release */
|
SLOT->state = EG_REL; /* phase -> Release */
|
||||||
|
|
||||||
/* SSG-EG */
|
/* SSG-EG specific update */
|
||||||
if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04)))
|
if (SLOT->ssg&0x08)
|
||||||
{
|
{
|
||||||
/* recalculate proper volume */
|
/* convert EG attenuation level */
|
||||||
SLOT->volume = ((UINT32)SLOT->volume ^ 0x1FF) + 1; /* Invert Attenuation */
|
if (SLOT->ssgn ^ (SLOT->ssg&0x04))
|
||||||
|
SLOT->volume = ((UINT32)SLOT->volume ^ 0x1FF) + 1;
|
||||||
|
|
||||||
|
/* force EG attenuation level */
|
||||||
|
if (SLOT->volume >= 0x200)
|
||||||
|
{
|
||||||
|
SLOT->volume = MAX_ATT_INDEX;
|
||||||
|
SLOT->state = EG_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* recalculate EG output */
|
||||||
SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
|
SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -680,7 +690,7 @@ INLINE void FM_KEYON_CSM(FM_CH *CH , int s )
|
|||||||
{
|
{
|
||||||
FM_SLOT *SLOT = &CH->SLOT[s];
|
FM_SLOT *SLOT = &CH->SLOT[s];
|
||||||
|
|
||||||
if( !SLOT->key && !ym2612.OPN.SL3.key_csm)
|
if (!SLOT->key && !ym2612.OPN.SL3.key_csm)
|
||||||
{
|
{
|
||||||
/* restart Phase Generator */
|
/* restart Phase Generator */
|
||||||
SLOT->phase = 0;
|
SLOT->phase = 0;
|
||||||
@ -712,17 +722,27 @@ INLINE void FM_KEYON_CSM(FM_CH *CH , int s )
|
|||||||
INLINE void FM_KEYOFF_CSM(FM_CH *CH , int s )
|
INLINE void FM_KEYOFF_CSM(FM_CH *CH , int s )
|
||||||
{
|
{
|
||||||
FM_SLOT *SLOT = &CH->SLOT[s];
|
FM_SLOT *SLOT = &CH->SLOT[s];
|
||||||
if( !SLOT->key )
|
if (!SLOT->key)
|
||||||
{
|
{
|
||||||
if (SLOT->state>EG_REL)
|
if (SLOT->state>EG_REL)
|
||||||
{
|
{
|
||||||
SLOT->state = EG_REL; /* phase -> Release */
|
SLOT->state = EG_REL; /* phase -> Release */
|
||||||
|
|
||||||
/* SSG-EG */
|
/* SSG-EG specific update */
|
||||||
if ((SLOT->ssg&0x08) && (SLOT->ssgn ^ (SLOT->ssg&0x04)))
|
if (SLOT->ssg&0x08)
|
||||||
{
|
{
|
||||||
/* recalculate proper volume */
|
/* convert EG attenuation level */
|
||||||
SLOT->volume = ((UINT32)SLOT->volume ^ 0x1FF) + 1; /* Invert Attenuation */
|
if (SLOT->ssgn ^ (SLOT->ssg&0x04))
|
||||||
|
SLOT->volume = ((UINT32)SLOT->volume ^ 0x1FF) + 1;
|
||||||
|
|
||||||
|
/* force EG attenuation level */
|
||||||
|
if (SLOT->volume >= 0x200)
|
||||||
|
{
|
||||||
|
SLOT->volume = MAX_ATT_INDEX;
|
||||||
|
SLOT->state = EG_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* recalculate EG output */
|
||||||
SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
|
SLOT->vol_out = (UINT32)SLOT->volume + SLOT->tl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1153,14 +1173,14 @@ INLINE void update_ssg_eg_channel(FM_SLOT *SLOT)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* detect SSG-EG transition */
|
/* detect SSG-EG transition */
|
||||||
/* this is not required during release phase as the attenuation is set to MAX and output invert flag is not used */
|
/* this is not required during release phase as the attenuation has been forced to MAX and output invert flag is not used */
|
||||||
/* if an Attack Phase is programmed, inversion can occur on each sample */
|
/* if an Attack Phase is programmed, inversion can occur on each sample */
|
||||||
if ((SLOT->ssg & 0x08) && (SLOT->volume >= 0x200) && (SLOT->state > EG_REL))
|
if ((SLOT->ssg & 0x08) && (SLOT->volume >= 0x200) && (SLOT->state > EG_REL))
|
||||||
{
|
{
|
||||||
if (SLOT->ssg & 0x01) /* bit 0 = hold SSG-EG */
|
if (SLOT->ssg & 0x01) /* bit 0 = hold SSG-EG */
|
||||||
{
|
{
|
||||||
/* set inversion flag */
|
/* force inversion flag */
|
||||||
if ((SLOT->ssg & 0x02) && !SLOT->ssgn)
|
if (SLOT->ssg & 0x02)
|
||||||
SLOT->ssgn = 4;
|
SLOT->ssgn = 4;
|
||||||
|
|
||||||
/* force attenuation level */
|
/* force attenuation level */
|
||||||
@ -1170,8 +1190,10 @@ INLINE void update_ssg_eg_channel(FM_SLOT *SLOT)
|
|||||||
else /* loop SSG-EG */
|
else /* loop SSG-EG */
|
||||||
{
|
{
|
||||||
/* toggle output inversion flag or reset Phase Generator */
|
/* toggle output inversion flag or reset Phase Generator */
|
||||||
if (SLOT->ssg & 0x02) SLOT->ssgn ^= 4;
|
if (SLOT->ssg & 0x02)
|
||||||
else SLOT->phase = 0;
|
SLOT->ssgn ^= 4;
|
||||||
|
else
|
||||||
|
SLOT->phase = 0;
|
||||||
|
|
||||||
/* same as Key ON */
|
/* same as Key ON */
|
||||||
if (SLOT->state != EG_ATT)
|
if (SLOT->state != EG_ATT)
|
||||||
|
Loading…
Reference in New Issue
Block a user