Mercurial > repos > blastem
comparison ym2612.c @ 1308:1b3fe6e03e7b
Reset YM2612 whenver the Z80 is reset. Fixes issue with stuck notes in Fantastic Dizzy and Kid Chameleon
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 30 Mar 2017 23:57:30 -0700 |
parents | babff81e4cfd |
children | 4d16c09210fd |
comparison
equal
deleted
inserted
replaced
1307:3cdc4e33a2c4 | 1308:1b3fe6e03e7b |
---|---|
126 | 126 |
127 #ifdef __ANDROID__ | 127 #ifdef __ANDROID__ |
128 #define log2(x) (log(x)/log(2)) | 128 #define log2(x) (log(x)/log(2)) |
129 #endif | 129 #endif |
130 | 130 |
131 | |
132 #define TIMER_A_MAX 1023 | |
133 #define TIMER_B_MAX 255 | |
134 | |
135 void ym_reset(ym2612_context *context) | |
136 { | |
137 memset(context->part1_regs, 0, sizeof(context->part1_regs)); | |
138 memset(context->part2_regs, 0, sizeof(context->part2_regs)); | |
139 memset(context->operators, 0, sizeof(context->operators)); | |
140 memset(context->channels, 0, sizeof(context->channels)); | |
141 memset(context->ch3_supp, 0, sizeof(context->ch3_supp)); | |
142 context->selected_reg = 0; | |
143 context->csm_keyon = 0; | |
144 context->ch3_mode = 0; | |
145 context->dac_enable = 0; | |
146 context->status = 0; | |
147 context->timer_a_load = 0; | |
148 context->timer_b_load = 0; | |
149 //TODO: Confirm these on hardware | |
150 context->timer_a = TIMER_A_MAX; | |
151 context->timer_b = TIMER_B_MAX; | |
152 | |
153 //TODO: Reset LFO state | |
154 | |
155 //some games seem to expect that the LR flags start out as 1 | |
156 for (int i = 0; i < NUM_CHANNELS; i++) { | |
157 context->channels[i].lr = 0xC0; | |
158 } | |
159 context->write_cycle = CYCLE_NEVER; | |
160 for (int i = 0; i < NUM_OPERATORS; i++) { | |
161 context->operators[i].envelope = MAX_ENVELOPE; | |
162 context->operators[i].env_phase = PHASE_RELEASE; | |
163 } | |
164 } | |
165 | |
131 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) | 166 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) |
132 { | 167 { |
133 static uint8_t registered_finalize; | 168 static uint8_t registered_finalize; |
134 dfopen(debug_file, "ym_debug.txt", "w"); | 169 dfopen(debug_file, "ym_debug.txt", "w"); |
135 memset(context, 0, sizeof(*context)); | 170 memset(context, 0, sizeof(*context)); |
143 double dt = 1.0 / ((double)master_clock / (double)(context->clock_inc * NUM_OPERATORS)); | 178 double dt = 1.0 / ((double)master_clock / (double)(context->clock_inc * NUM_OPERATORS)); |
144 double alpha = dt / (dt + rc); | 179 double alpha = dt / (dt + rc); |
145 context->lowpass_alpha = (int32_t)(((double)0x10000) * alpha); | 180 context->lowpass_alpha = (int32_t)(((double)0x10000) * alpha); |
146 | 181 |
147 context->sample_limit = sample_limit*2; | 182 context->sample_limit = sample_limit*2; |
148 context->write_cycle = CYCLE_NEVER; | 183 |
149 for (int i = 0; i < NUM_OPERATORS; i++) { | |
150 context->operators[i].envelope = MAX_ENVELOPE; | |
151 context->operators[i].env_phase = PHASE_RELEASE; | |
152 } | |
153 //some games seem to expect that the LR flags start out as 1 | 184 //some games seem to expect that the LR flags start out as 1 |
154 for (int i = 0; i < NUM_CHANNELS; i++) { | 185 for (int i = 0; i < NUM_CHANNELS; i++) { |
155 context->channels[i].lr = 0xC0; | |
156 if (options & YM_OPT_WAVE_LOG) { | 186 if (options & YM_OPT_WAVE_LOG) { |
157 char fname[64]; | 187 char fname[64]; |
158 sprintf(fname, "ym_channel_%d.wav", i); | 188 sprintf(fname, "ym_channel_%d.wav", i); |
159 FILE * f = context->channels[i].logfile = fopen(fname, "wb"); | 189 FILE * f = context->channels[i].logfile = fopen(fname, "wb"); |
160 if (!f) { | 190 if (!f) { |
229 lfo_pm_table[freq * 256 + pms * 32 + step] = value; | 259 lfo_pm_table[freq * 256 + pms * 32 + step] = value; |
230 } | 260 } |
231 } | 261 } |
232 } | 262 } |
233 } | 263 } |
264 ym_reset(context); | |
234 } | 265 } |
235 | 266 |
236 void ym_free(ym2612_context *context) | 267 void ym_free(ym2612_context *context) |
237 { | 268 { |
238 if (context == log_context) { | 269 if (context == log_context) { |
246 } | 277 } |
247 | 278 |
248 #define YM_VOLUME_MULTIPLIER 2 | 279 #define YM_VOLUME_MULTIPLIER 2 |
249 #define YM_VOLUME_DIVIDER 3 | 280 #define YM_VOLUME_DIVIDER 3 |
250 #define YM_MOD_SHIFT 1 | 281 #define YM_MOD_SHIFT 1 |
251 | |
252 #define TIMER_A_MAX 1023 | |
253 #define TIMER_B_MAX 255 | |
254 | 282 |
255 #define CSM_MODE 0x80 | 283 #define CSM_MODE 0x80 |
256 | 284 |
257 #define SSG_ENABLE 8 | 285 #define SSG_ENABLE 8 |
258 #define SSG_INVERT 4 | 286 #define SSG_INVERT 4 |