# HG changeset patch # User Michael Pavone # Date 1490943450 25200 # Node ID 1b3fe6e03e7bd16818bf58cf33f6516c52c945ea # Parent 3cdc4e33a2c41582aa7cfd357bcabb2e87f92588 Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon diff -r 3cdc4e33a2c4 -r 1b3fe6e03e7b genesis.c --- a/genesis.c Wed Mar 29 22:31:37 2017 -0700 +++ b/genesis.c Thu Mar 30 23:57:30 2017 -0700 @@ -585,6 +585,7 @@ } else { gen->z80->reset = 1; } + ym_reset(gen->ym); } } } diff -r 3cdc4e33a2c4 -r 1b3fe6e03e7b ym2612.c --- a/ym2612.c Wed Mar 29 22:31:37 2017 -0700 +++ b/ym2612.c Thu Mar 30 23:57:30 2017 -0700 @@ -128,6 +128,41 @@ #define log2(x) (log(x)/log(2)) #endif + +#define TIMER_A_MAX 1023 +#define TIMER_B_MAX 255 + +void ym_reset(ym2612_context *context) +{ + memset(context->part1_regs, 0, sizeof(context->part1_regs)); + memset(context->part2_regs, 0, sizeof(context->part2_regs)); + memset(context->operators, 0, sizeof(context->operators)); + memset(context->channels, 0, sizeof(context->channels)); + memset(context->ch3_supp, 0, sizeof(context->ch3_supp)); + context->selected_reg = 0; + context->csm_keyon = 0; + context->ch3_mode = 0; + context->dac_enable = 0; + context->status = 0; + context->timer_a_load = 0; + context->timer_b_load = 0; + //TODO: Confirm these on hardware + context->timer_a = TIMER_A_MAX; + context->timer_b = TIMER_B_MAX; + + //TODO: Reset LFO state + + //some games seem to expect that the LR flags start out as 1 + for (int i = 0; i < NUM_CHANNELS; i++) { + context->channels[i].lr = 0xC0; + } + context->write_cycle = CYCLE_NEVER; + for (int i = 0; i < NUM_OPERATORS; i++) { + context->operators[i].envelope = MAX_ENVELOPE; + context->operators[i].env_phase = PHASE_RELEASE; + } +} + void ym_init(ym2612_context * context, uint32_t sample_rate, uint32_t master_clock, uint32_t clock_div, uint32_t sample_limit, uint32_t options, uint32_t lowpass_cutoff) { static uint8_t registered_finalize; @@ -145,14 +180,9 @@ context->lowpass_alpha = (int32_t)(((double)0x10000) * alpha); context->sample_limit = sample_limit*2; - context->write_cycle = CYCLE_NEVER; - for (int i = 0; i < NUM_OPERATORS; i++) { - context->operators[i].envelope = MAX_ENVELOPE; - context->operators[i].env_phase = PHASE_RELEASE; - } + //some games seem to expect that the LR flags start out as 1 for (int i = 0; i < NUM_CHANNELS; i++) { - context->channels[i].lr = 0xC0; if (options & YM_OPT_WAVE_LOG) { char fname[64]; sprintf(fname, "ym_channel_%d.wav", i); @@ -231,6 +261,7 @@ } } } + ym_reset(context); } void ym_free(ym2612_context *context) @@ -249,9 +280,6 @@ #define YM_VOLUME_DIVIDER 3 #define YM_MOD_SHIFT 1 -#define TIMER_A_MAX 1023 -#define TIMER_B_MAX 255 - #define CSM_MODE 0x80 #define SSG_ENABLE 8 diff -r 3cdc4e33a2c4 -r 1b3fe6e03e7b ym2612.h --- a/ym2612.h Wed Mar 29 22:31:37 2017 -0700 +++ b/ym2612.h Thu Mar 30 23:57:30 2017 -0700 @@ -131,6 +131,7 @@ }; void ym_init(ym2612_context * context, uint32_t sample_rate, uint32_t master_clock, uint32_t clock_div, uint32_t sample_limit, uint32_t options, uint32_t lowpass_cutoff); +void ym_reset(ym2612_context *context); void ym_free(ym2612_context *context); void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock); void ym_run(ym2612_context * context, uint32_t to_cycle);