summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2017-03-30 23:57:30 -0700
committerMichael Pavone <pavone@retrodev.com>2017-03-30 23:57:30 -0700
commit09ea7cd96aa384f0ab952c511920b7b741318854 (patch)
tree367d28d4b19309562f40f099eebeb07a4a70ee64
parent2c86fe734c79199cbf32ea6d575c72e5f92d2111 (diff)
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
-rw-r--r--genesis.c1
-rw-r--r--ym2612.c46
-rw-r--r--ym2612.h1
3 files changed, 39 insertions, 9 deletions
diff --git a/genesis.c b/genesis.c
index 8f1197b..e267852 100644
--- a/genesis.c
+++ b/genesis.c
@@ -585,6 +585,7 @@ static m68k_context * io_write(uint32_t location, m68k_context * context, uint8_
} else {
gen->z80->reset = 1;
}
+ ym_reset(gen->ym);
}
}
}
diff --git a/ym2612.c b/ym2612.c
index e5016ac..634d1e5 100644
--- a/ym2612.c
+++ b/ym2612.c
@@ -128,6 +128,41 @@ void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock)
#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 @@ void ym_init(ym2612_context * context, uint32_t sample_rate, uint32_t master_clo
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 @@ void ym_init(ym2612_context * context, uint32_t sample_rate, uint32_t master_clo
}
}
}
+ ym_reset(context);
}
void ym_free(ym2612_context *context)
@@ -249,9 +280,6 @@ void ym_free(ym2612_context *context)
#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 --git a/ym2612.h b/ym2612.h
index 71a00fd..124e3e1 100644
--- a/ym2612.h
+++ b/ym2612.h
@@ -131,6 +131,7 @@ enum {
};
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);