fixed YM2612 registers on reset, fixed max Frequency increment value (Nemesis)

This commit is contained in:
ekeeke31 2008-09-12 16:22:49 +00:00
parent fbbd1d6057
commit 4c374d034a
3 changed files with 32 additions and 33 deletions

View File

@ -4,8 +4,10 @@ Genesis Plus for Gamecube
CURRENT: CURRENT:
--------- ---------
[Genesis] [Genesis]
- YM2612(MAME): improved Enveloppe Generator accuracy: fix tracks #3 and #9 in Mega Turrican - YM2612(MAME): improved Enveloppe Generator accuracy, fix tracks #3 and #9 in Mega Turrican
- YM2612(MAME): fixed SSG-EG emulation bug: fix Level 1 music in Alisia Dragoon - YM2612(MAME): fixed a bug in SSG-EG emulation code, fix Level 1 music in Alisia Dragoon
- YM2612(MAME): improved Detune overflow accuracy, fix high-frequency sound effects & musics in many games
- YM2612(MAME): fixed registers 0x20-0x26 Reset state, fix intro music in B.O.B
[NGC/Wii] [NGC/Wii]
- improved menu scrolling using Wiimote D-PAD - improved menu scrolling using Wiimote D-PAD

View File

@ -583,11 +583,10 @@ void render_shutdown(void)
void remap_buffer(int line, int width) void remap_buffer(int line, int width)
{ {
/* get line offset from framebuffer */ /* get line offset from framebuffer */
int offset = vdp_pal ? bitmap.viewport.y : (bitmap.viewport.y*11/8); // NTSC is 243 lines int vline = (line + bitmap.viewport.y) % lines_per_frame;
int vline = (line + offset) % lines_per_frame;
/* illegal video mode (screen rolls up) */ /* illegal video mode (screen rolls up) */
if (!vdp_pal && (reg[1] & 8)) vline = (vline + frame_cnt)%240; if ((reg[1] & 8) && !vdp_pal) vline = (vline + frame_cnt)%240;
/* double resolution mode */ /* double resolution mode */
if (config.render && interlaced) vline = (vline * 2) + odd_frame; if (config.render && interlaced) vline = (vline * 2) + odd_frame;

View File

@ -12,18 +12,18 @@
/* /*
** History: ** History:
** **
** 2006-2008 Eke-Eke (Gamecube/Wii genesis plus port): ** 2006-2008 Eke-Eke (gamecube&wii port of Genesis Plus):
** - fixed internal FM timer emulation ** - fixed internal FM timer emulation
** - removed unused multichip support and YMxxx support ** - removed unused multichip support and YMxxx support
** - fixed CH3 CSM mode (credits to Nemesis) ** - fixed CH3 CSM mode (which games actually use this ?), credits to Nemesis
** - implemented PG overflow, aka "detune bug" (Ariel, Comix Zone, Shaq Fu, Spiderman,...), credits to Nemesis ** - implemented Detune overflow (Ariel, Comix Zone, Shaq Fu, Spiderman & many others), credits to Nemesis
** - fixed SSG-EG support, credits to Nemesis ** - fixed SSG-EG support (Asterix, Bubba'n Six & many others), thanks to Nemesis for his tests
** - modified EG rates, tested by Nemesis on real hardware ** - modified EG rates, tested by Nemesis on real hardware
** - fixed EG attenuation level on KEY ON (Ecco 2 splash sound) ** - fixed EG attenuation level on KEY ON (Ecco 2 splash sound)
** - fixed LFO phase update for CH3 special mode (Warlock, Alladin), thanks to AamirM ** - implemented LFO phase update for CH3 special mode (Warlock birds, Alladin bug sound)
** - fixed Attack rate refresh (fix Batman&Robin introduction)$ ** - fixed Attack Rate update (Batman & Robin intro)
** - fixed attenuation level at the start of Substain (Gynoug ?) ** - fixed attenuation level at the start of Substain (Gynoug explosions)
** - fixed EG updates in some specific cases (AR maximal and/or Susbstain Level minimal) ** - fixed EG updates when AR is maximal and/or SL minimal (Mega Turrican tracks 03,09...)
** **
** 03-08-2003 Jarek Burczynski: ** 03-08-2003 Jarek Burczynski:
** - fixed YM2608 initial values (after the reset) ** - fixed YM2608 initial values (after the reset)
@ -931,6 +931,7 @@ INLINE void advance_eg_channel(FM_SLOT *SLOT)
SLOT->volume += (~SLOT->volume * (eg_inc[SLOT->eg_sel_ar + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_ar)&7)]))>>4; SLOT->volume += (~SLOT->volume * (eg_inc[SLOT->eg_sel_ar + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_ar)&7)]))>>4;
if (SLOT->volume <= MIN_ATT_INDEX) if (SLOT->volume <= MIN_ATT_INDEX)
{ {
/* switch to Release or Substain Phase (Eke-Eke) */
SLOT->volume = MIN_ATT_INDEX; SLOT->volume = MIN_ATT_INDEX;
SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC; SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC;
} }
@ -942,8 +943,8 @@ INLINE void advance_eg_channel(FM_SLOT *SLOT)
{ {
if ( !(ym2612.OPN.eg_cnt & ((1<<SLOT->eg_sh_d1r)-1) ) ) if ( !(ym2612.OPN.eg_cnt & ((1<<SLOT->eg_sh_d1r)-1) ) )
{ {
//SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d1r + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_d1r)&7)]; /* Nemesis */
SLOT->volume += 6 * eg_inc[SLOT->eg_sel_d1r + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_d1r)&7)]; /* from Nemesis */ SLOT->volume += 6 * eg_inc[SLOT->eg_sel_d1r + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_d1r)&7)];
if ( SLOT->volume >= (INT32)(SLOT->sl) ) if ( SLOT->volume >= (INT32)(SLOT->sl) )
{ {
@ -972,8 +973,8 @@ INLINE void advance_eg_channel(FM_SLOT *SLOT)
{ {
if ( !(ym2612.OPN.eg_cnt & ((1<<SLOT->eg_sh_d2r)-1) ) ) if ( !(ym2612.OPN.eg_cnt & ((1<<SLOT->eg_sh_d2r)-1) ) )
{ {
//SLOT->volume += 4 * eg_inc[SLOT->eg_sel_d2r + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_d2r)&7)]; /* Nemesis */
SLOT->volume += 6 * eg_inc[SLOT->eg_sel_d2r + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_d2r)&7)]; /* from Nemesis */ SLOT->volume += 6 * eg_inc[SLOT->eg_sel_d2r + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_d2r)&7)];
if ( SLOT->volume >= MAX_ATT_INDEX) if ( SLOT->volume >= MAX_ATT_INDEX)
{ {
@ -1003,7 +1004,7 @@ INLINE void advance_eg_channel(FM_SLOT *SLOT)
} }
else else
{ {
/* Attack Rate is maximal: directly switch to Decay */ /* Attack Rate is maximal: directly switch to Decay (or Substain) */
SLOT->volume = MIN_ATT_INDEX; SLOT->volume = MIN_ATT_INDEX;
SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC; SLOT->state = (SLOT->sl == MIN_ATT_INDEX) ? EG_SUS : EG_DEC;
} }
@ -1033,7 +1034,8 @@ INLINE void advance_eg_channel(FM_SLOT *SLOT)
if ( !(ym2612.OPN.eg_cnt & ((1<<SLOT->eg_sh_rr)-1) ) ) if ( !(ym2612.OPN.eg_cnt & ((1<<SLOT->eg_sh_rr)-1) ) )
{ {
if (SLOT->ssg&0x08) if (SLOT->ssg&0x08)
SLOT->volume += 6 * eg_inc[SLOT->eg_sel_rr + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_rr)&7)]; /* from Nemesis */ /* SSG-EG affects Release Phase also (Nemesis) */
SLOT->volume += 6 * eg_inc[SLOT->eg_sel_rr + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_rr)&7)];
else else
SLOT->volume += eg_inc[SLOT->eg_sel_rr + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_rr)&7)]; SLOT->volume += eg_inc[SLOT->eg_sel_rr + ((ym2612.OPN.eg_cnt>>SLOT->eg_sh_rr)&7)];
@ -1401,29 +1403,29 @@ static int init_tables(void)
} }
/* CSM Key Controll (correct implementation, credits to Nemesis) */ /* CSM Key Controll */
INLINE void CSMKeyControll(FM_CH *CH) INLINE void CSMKeyControll(FM_CH *CH)
{ {
/* all key on/off */ /* all key ON/OFF (only for operator which have been OFF)*/
if (CH->SLOT[SLOT1].state == EG_REL) if (!CH->SLOT[SLOT1].key)
{ {
FM_KEYON(CH,SLOT1); FM_KEYON(CH,SLOT1);
FM_KEYOFF(CH,SLOT1); FM_KEYOFF(CH,SLOT1);
} }
if (CH->SLOT[SLOT2].state == EG_REL) if (!CH->SLOT[SLOT2].key)
{ {
FM_KEYON(CH,SLOT2); FM_KEYON(CH,SLOT2);
FM_KEYOFF(CH,SLOT2); FM_KEYOFF(CH,SLOT2);
} }
if (CH->SLOT[SLOT3].state == EG_REL) if (!CH->SLOT[SLOT3].key)
{ {
FM_KEYON(CH,SLOT3); FM_KEYON(CH,SLOT3);
FM_KEYOFF(CH,SLOT3); FM_KEYOFF(CH,SLOT3);
} }
if (CH->SLOT[SLOT4].state == EG_REL) if (!CH->SLOT[SLOT4].key)
{ {
FM_KEYON(CH,SLOT4); FM_KEYON(CH,SLOT4);
FM_KEYOFF(CH,SLOT4); FM_KEYOFF(CH,SLOT4);
@ -1480,8 +1482,6 @@ static void OPNSetPres(int pres)
/* timer increment in usecs (timers are incremented after each updated samples) */ /* timer increment in usecs (timers are incremented after each updated samples) */
ym2612.OPN.ST.TimerBase = (int) (ym2612.OPN.ST.freqbase * 4096.0); ym2612.OPN.ST.TimerBase = (int) (ym2612.OPN.ST.freqbase * 4096.0);
/* make time tables */ /* make time tables */
init_timetables(dt_tab); init_timetables(dt_tab);
@ -1495,8 +1495,8 @@ static void OPNSetPres(int pres)
ym2612.OPN.fn_table[i] = (UINT32)( (double)i * 32 * ym2612.OPN.ST.freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ ym2612.OPN.fn_table[i] = (UINT32)( (double)i * 32 * ym2612.OPN.ST.freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */
} }
/* maximal frequency, used for overflow, best setting with BLOCK=5 (notaz) */ /* maximal frequency, used for overflow, internal register is 17-bits (Nemesis) */
fn_max = ((UINT32)((double)ym2612.OPN.fn_table[0x7ff*2] / ym2612.OPN.ST.freqbase) >> 2); fn_max = (UINT32)( (double)0x1ffff * ym2612.OPN.ST.freqbase * (1<<(FREQ_SH-10)) );
/* LFO freq. table */ /* LFO freq. table */
for(i = 0; i < 8; i++) for(i = 0; i < 8; i++)
@ -1508,7 +1508,6 @@ static void OPNSetPres(int pres)
} }
/* write a OPN mode register 0x20-0x2f */ /* write a OPN mode register 0x20-0x2f */
static void OPNWriteMode(int r, int v) static void OPNWriteMode(int r, int v)
{ {
@ -1799,10 +1798,9 @@ void YM2612UpdateOne(int **buffer, int length)
chan_calc(&ym2612.CH[2]); chan_calc(&ym2612.CH[2]);
chan_calc(&ym2612.CH[3]); chan_calc(&ym2612.CH[3]);
chan_calc(&ym2612.CH[4]); chan_calc(&ym2612.CH[4]);
/* DAC Mode */
if (ym2612.dacen) if (ym2612.dacen)
{ {
/* DAC Mode */
*(ym2612.CH[5].connect4) += ym2612.dacout; *(ym2612.CH[5].connect4) += ym2612.dacout;
} }
else chan_calc(&ym2612.CH[5]); else chan_calc(&ym2612.CH[5]);
@ -1893,7 +1891,7 @@ int YM2612ResetChip(void)
OPNWriteReg(i ,0); OPNWriteReg(i ,0);
OPNWriteReg(i|0x100,0); OPNWriteReg(i|0x100,0);
} }
for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteReg(i,0); for(i = 0x26 ; i >= 0x20 ; i-- ) OPNWriteMode(i,0);
/* DAC mode clear */ /* DAC mode clear */
ym2612.dacen = 0; ym2612.dacen = 0;