comparison ym2612.c @ 2053:3414a4423de1 segacd

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 15 Jan 2022 13:15:21 -0800
parents 1e7a63f0ccf4
children cfd53c94fffb
comparison
equal deleted inserted replaced
1692:5dacaef602a7 2053:3414a4423de1
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include "ym2612.h" 10 #include "ym2612.h"
11 #include "render.h" 11 #include "render.h"
12 #include "wave.h" 12 #include "wave.h"
13 #include "blastem.h" 13 #include "blastem.h"
14 #include "event_log.h"
14 15
15 //#define DO_DEBUG_PRINT 16 //#define DO_DEBUG_PRINT
16 #ifdef DO_DEBUG_PRINT 17 #ifdef DO_DEBUG_PRINT
17 #define dfprintf fprintf 18 #define dfprintf fprintf
18 #define dfopen(var, fname, mode) var=fopen(fname, mode) 19 #define dfopen(var, fname, mode) var=fopen(fname, mode)
19 #else 20 #else
20 #define dfprintf 21 #define dfprintf
21 #define dfopen(var, fname, mode) 22 #define dfopen(var, fname, mode)
22 #endif 23 #endif
23 24
24 #define BUSY_CYCLES_ADDRESS 17 25 #define BUSY_CYCLES 32
25 #define BUSY_CYCLES_DATA_LOW 83
26 #define BUSY_CYCLES_DATA_HIGH 47
27 #define OP_UPDATE_PERIOD 144 26 #define OP_UPDATE_PERIOD 144
28 27
29 #define BIT_TIMERA_ENABLE 0x1 28 #define BIT_TIMERA_ENABLE 0x1
30 #define BIT_TIMERB_ENABLE 0x2 29 #define BIT_TIMERB_ENABLE 0x2
31 #define BIT_TIMERA_OVEREN 0x4 30 #define BIT_TIMERA_OVEREN 0x4
118 } 117 }
119 118
120 void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock) 119 void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock)
121 { 120 {
122 render_audio_adjust_clock(context->audio, master_clock, context->clock_inc * NUM_OPERATORS); 121 render_audio_adjust_clock(context->audio, master_clock, context->clock_inc * NUM_OPERATORS);
122 }
123
124 void ym_adjust_cycles(ym2612_context *context, uint32_t deduction)
125 {
126 context->current_cycle -= deduction;
127 if (context->write_cycle != CYCLE_NEVER && context->write_cycle >= deduction) {
128 context->write_cycle -= deduction;
129 } else {
130 context->write_cycle = CYCLE_NEVER;
131 }
132 if (context->busy_start != CYCLE_NEVER && context->busy_start >= deduction) {
133 context->busy_start -= deduction;
134 } else {
135 context->busy_start = CYCLE_NEVER;
136 }
137 if (context->last_status_cycle != CYCLE_NEVER && context->last_status_cycle >= deduction) {
138 context->last_status_cycle -= deduction;
139 } else {
140 context->last_status = 0;
141 context->last_status_cycle = CYCLE_NEVER;
142 }
123 } 143 }
124 144
125 #ifdef __ANDROID__ 145 #ifdef __ANDROID__
126 #define log2(x) (log(x)/log(2)) 146 #define log2(x) (log(x)/log(2))
127 #endif 147 #endif
157 177
158 //some games seem to expect that the LR flags start out as 1 178 //some games seem to expect that the LR flags start out as 1
159 for (int i = 0; i < NUM_CHANNELS; i++) { 179 for (int i = 0; i < NUM_CHANNELS; i++) {
160 context->channels[i].lr = 0xC0; 180 context->channels[i].lr = 0xC0;
161 context->channels[i].logfile = savedlogs[i]; 181 context->channels[i].logfile = savedlogs[i];
182 if (i < 3) {
183 context->part1_regs[REG_LR_AMS_PMS - YM_PART1_START + i] = 0xC0;
184 } else {
185 context->part2_regs[REG_LR_AMS_PMS - YM_PART2_START + i - 3] = 0xC0;
186 }
162 } 187 }
163 context->write_cycle = CYCLE_NEVER; 188 context->write_cycle = CYCLE_NEVER;
164 for (int i = 0; i < NUM_OPERATORS; i++) { 189 for (int i = 0; i < NUM_OPERATORS; i++) {
165 context->operators[i].envelope = MAX_ENVELOPE; 190 context->operators[i].envelope = MAX_ENVELOPE;
166 context->operators[i].env_phase = PHASE_RELEASE; 191 context->operators[i].env_phase = PHASE_RELEASE;
171 { 196 {
172 static uint8_t registered_finalize; 197 static uint8_t registered_finalize;
173 dfopen(debug_file, "ym_debug.txt", "w"); 198 dfopen(debug_file, "ym_debug.txt", "w");
174 memset(context, 0, sizeof(*context)); 199 memset(context, 0, sizeof(*context));
175 context->clock_inc = clock_div * 6; 200 context->clock_inc = clock_div * 6;
201 context->busy_cycles = BUSY_CYCLES * context->clock_inc;
176 context->audio = render_audio_source(master_clock, context->clock_inc * NUM_OPERATORS, 2); 202 context->audio = render_audio_source(master_clock, context->clock_inc * NUM_OPERATORS, 2);
203 //TODO: pick a randomish high initial value and lower it over time
204 context->invalid_status_decay = 225000 * context->clock_inc;
205 context->status_address_mask = (options & YM_OPT_3834) ? 0 : 3;
177 206
178 //some games seem to expect that the LR flags start out as 1 207 //some games seem to expect that the LR flags start out as 1
179 for (int i = 0; i < NUM_CHANNELS; i++) { 208 for (int i = 0; i < NUM_CHANNELS; i++) {
180 if (options & YM_OPT_WAVE_LOG) { 209 if (options & YM_OPT_WAVE_LOG) {
181 char fname[64]; 210 char fname[64];
254 } 283 }
255 } 284 }
256 } 285 }
257 } 286 }
258 ym_reset(context); 287 ym_reset(context);
288 ym_enable_zero_offset(context, 1);
259 } 289 }
260 290
261 void ym_free(ym2612_context *context) 291 void ym_free(ym2612_context *context)
262 { 292 {
263 render_free_source(context->audio); 293 render_free_source(context->audio);
265 ym_finalize_log(); 295 ym_finalize_log();
266 } 296 }
267 free(context); 297 free(context);
268 } 298 }
269 299
270 #define YM_VOLUME_MULTIPLIER 2 300 void ym_enable_zero_offset(ym2612_context *context, uint8_t enabled)
271 #define YM_VOLUME_DIVIDER 3 301 {
302 if (enabled) {
303 context->zero_offset = 0x70;
304 context->volume_mult = 79;
305 context->volume_div = 120;
306 } else {
307 context->zero_offset = 0;
308 context->volume_mult = 2;
309 context->volume_div = 3;
310 }
311 }
272 #define YM_MOD_SHIFT 1 312 #define YM_MOD_SHIFT 1
273 313
274 #define CSM_MODE 0x80 314 #define CSM_MODE 0x80
275 315
276 #define SSG_ENABLE 8 316 #define SSG_ENABLE 8
325 keyoff(context->operators + op); 365 keyoff(context->operators + op);
326 } 366 }
327 } 367 }
328 } 368 }
329 369
370 void ym_run_timers(ym2612_context *context)
371 {
372 if (context->timer_control & BIT_TIMERA_ENABLE) {
373 if (context->timer_a != TIMER_A_MAX) {
374 context->timer_a++;
375 if (context->csm_keyon) {
376 csm_keyoff(context);
377 }
378 } else {
379 if (context->timer_control & BIT_TIMERA_LOAD) {
380 context->timer_control &= ~BIT_TIMERA_LOAD;
381 } else if (context->timer_control & BIT_TIMERA_OVEREN) {
382 context->status |= BIT_STATUS_TIMERA;
383 }
384 context->timer_a = context->timer_a_load;
385 if (!context->csm_keyon && context->ch3_mode == CSM_MODE) {
386 context->csm_keyon = 0xF0;
387 uint8_t changes = 0xF0 ^ context->channels[2].keyon;;
388 for (uint8_t op = 2*4, bit = 0; op < 3*4; op++, bit++)
389 {
390 if (changes & keyon_bits[bit]) {
391 keyon(context->operators + op, context->channels + 2);
392 }
393 }
394 }
395 }
396 }
397 if (!context->sub_timer_b) {
398 if (context->timer_control & BIT_TIMERB_ENABLE) {
399 if (context->timer_b != TIMER_B_MAX) {
400 context->timer_b++;
401 } else {
402 if (context->timer_control & BIT_TIMERB_LOAD) {
403 context->timer_control &= ~BIT_TIMERB_LOAD;
404 } else if (context->timer_control & BIT_TIMERB_OVEREN) {
405 context->status |= BIT_STATUS_TIMERB;
406 }
407 context->timer_b = context->timer_b_load;
408 }
409 }
410 } else if (context->timer_control & BIT_TIMERB_LOAD) {
411 context->timer_control &= ~BIT_TIMERB_LOAD;
412 context->timer_b = context->timer_b_load;
413 }
414 context->sub_timer_b += 0x10;
415 //Update LFO
416 if (context->lfo_enable) {
417 if (context->lfo_counter) {
418 context->lfo_counter--;
419 } else {
420 context->lfo_counter = lfo_timer_values[context->lfo_freq];
421 context->lfo_am_step += 2;
422 context->lfo_am_step &= 0xFE;
423 uint8_t old_pm_step = context->lfo_pm_step;
424 context->lfo_pm_step = context->lfo_am_step / 8;
425 if (context->lfo_pm_step != old_pm_step) {
426 for (int chan = 0; chan < NUM_CHANNELS; chan++)
427 {
428 if (context->channels[chan].pms) {
429 for (int op = chan * 4; op < (chan + 1) * 4; op++)
430 {
431 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
432 }
433 }
434 }
435 }
436 }
437 }
438 }
439
440 void ym_run_envelope(ym2612_context *context, ym_channel *channel, ym_operator *operator)
441 {
442 uint32_t env_cyc = context->env_counter;
443 uint8_t rate;
444 if (operator->env_phase == PHASE_DECAY && operator->envelope >= operator->sustain_level) {
445 //operator->envelope = operator->sustain_level;
446 operator->env_phase = PHASE_SUSTAIN;
447 }
448 rate = operator->rates[operator->env_phase];
449 if (rate) {
450 uint8_t ks = channel->keycode >> operator->key_scaling;;
451 rate = rate*2 + ks;
452 if (rate > 63) {
453 rate = 63;
454 }
455 }
456 uint32_t cycle_shift = rate < 0x30 ? ((0x2F - rate) >> 2) : 0;
457 if (!(env_cyc & ((1 << cycle_shift) - 1))) {
458 uint32_t update_cycle = env_cyc >> cycle_shift & 0x7;
459 uint16_t envelope_inc = rate_table[rate * 8 + update_cycle];
460 if (operator->env_phase == PHASE_ATTACK) {
461 //this can probably be optimized to a single shift rather than a multiply + shift
462 uint16_t old_env = operator->envelope;
463 operator->envelope += ((~operator->envelope * envelope_inc) >> 4) & 0xFFFFFFFC;
464 if (operator->envelope > old_env) {
465 //Handle overflow
466 operator->envelope = 0;
467 }
468 if (!operator->envelope) {
469 operator->env_phase = PHASE_DECAY;
470 }
471 } else {
472 if (operator->ssg) {
473 if (operator->envelope < SSG_CENTER) {
474 envelope_inc *= 4;
475 } else {
476 envelope_inc = 0;
477 }
478 }
479 //envelope value is 10-bits, but it will be used as a 4.8 value
480 operator->envelope += envelope_inc << 2;
481 //clamp to max attenuation value
482 if (
483 operator->envelope > MAX_ENVELOPE
484 || (operator->env_phase == PHASE_RELEASE && operator->envelope >= SSG_CENTER)
485 ) {
486 operator->envelope = MAX_ENVELOPE;
487 }
488 }
489 }
490 }
491
492 void ym_run_phase(ym2612_context *context, uint32_t channel, uint32_t op)
493 {
494 if (channel != 5 || !context->dac_enable) {
495 //printf("updating operator %d of channel %d\n", op, channel);
496 ym_operator * operator = context->operators + op;
497 ym_channel * chan = context->channels + channel;
498 uint16_t phase = operator->phase_counter >> 10 & 0x3FF;
499 operator->phase_counter += operator->phase_inc;//ym_calc_phase_inc(context, operator, op);
500 int16_t mod = 0;
501 if (op & 3) {
502 if (operator->mod_src[0]) {
503 mod = *operator->mod_src[0];
504 if (operator->mod_src[1]) {
505 mod += *operator->mod_src[1];
506 }
507 mod >>= YM_MOD_SHIFT;
508 }
509 } else {
510 if (chan->feedback) {
511 mod = (chan->op1_old + operator->output) >> (10-chan->feedback);
512 }
513 }
514 uint16_t env = operator->envelope;
515 if (operator->ssg) {
516 if (env >= SSG_CENTER) {
517 if (operator->ssg & SSG_ALTERNATE) {
518 if (operator->env_phase != PHASE_RELEASE && (
519 !(operator->ssg & SSG_HOLD) || ((operator->ssg ^ operator->inverted) & SSG_INVERT) == 0
520 )) {
521 operator->inverted ^= SSG_INVERT;
522 }
523 } else if (!(operator->ssg & SSG_HOLD)) {
524 phase = operator->phase_counter = 0;
525 }
526 if (
527 (operator->env_phase == PHASE_DECAY || operator->env_phase == PHASE_SUSTAIN)
528 && !(operator->ssg & SSG_HOLD)
529 ) {
530 start_envelope(operator, chan);
531 env = operator->envelope;
532 }
533 }
534 if (operator->inverted) {
535 env = (SSG_CENTER - env) & MAX_ENVELOPE;
536 }
537 }
538 env += operator->total_level;
539 if (operator->am) {
540 uint16_t base_am = (context->lfo_am_step & 0x80 ? context->lfo_am_step : ~context->lfo_am_step) & 0x7E;
541 if (ams_shift[chan->ams] >= 0) {
542 env += (base_am >> ams_shift[chan->ams]) & MAX_ENVELOPE;
543 } else {
544 env += base_am << (-ams_shift[chan->ams]);
545 }
546 }
547 if (env > MAX_ENVELOPE) {
548 env = MAX_ENVELOPE;
549 }
550 if (first_key_on) {
551 dfprintf(debug_file, "op %d, base phase: %d, mod: %d, sine: %d, out: %d\n", op, phase, mod, sine_table[(phase+mod) & 0x1FF], pow_table[sine_table[phase & 0x1FF] + env]);
552 }
553 //if ((channel != 0 && channel != 4) || chan->algorithm != 5) {
554 phase += mod;
555 //}
556
557 int16_t output = pow_table[sine_table[phase & 0x1FF] + env];
558 if (phase & 0x200) {
559 output = -output;
560 }
561 if (op % 4 == 0) {
562 chan->op1_old = operator->output;
563 } else if (op % 4 == 2) {
564 chan->op2_old = operator->output;
565 }
566 operator->output = output;
567 //Update the channel output if we've updated all operators
568 if (op % 4 == 3) {
569 if (chan->algorithm < 4) {
570 chan->output = operator->output;
571 } else if(chan->algorithm == 4) {
572 chan->output = operator->output + context->operators[channel * 4 + 2].output;
573 } else {
574 output = 0;
575 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) {
576 output += context->operators[op].output;
577 }
578 chan->output = output;
579 }
580 if (first_key_on) {
581 int16_t value = context->channels[channel].output & 0x3FE0;
582 if (value & 0x2000) {
583 value |= 0xC000;
584 }
585 }
586 }
587 //puts("operator update done");
588 }
589 }
590
591 void ym_output_sample(ym2612_context *context)
592 {
593 int16_t left = 0, right = 0;
594 for (int i = 0; i < NUM_CHANNELS; i++) {
595 int16_t value = context->channels[i].output;
596 if (value > 0x1FE0) {
597 value = 0x1FE0;
598 } else if (value < -0x1FF0) {
599 value = -0x1FF0;
600 } else {
601 value &= 0x3FE0;
602 if (value & 0x2000) {
603 value |= 0xC000;
604 }
605 }
606 if (value >= 0) {
607 value += context->zero_offset;
608 } else {
609 value -= context->zero_offset;
610 }
611 if (context->channels[i].logfile) {
612 fwrite(&value, sizeof(value), 1, context->channels[i].logfile);
613 }
614 if (context->channels[i].lr & 0x80) {
615 left += (value * context->volume_mult) / context->volume_div;
616 } else if (context->zero_offset) {
617 if (value >= 0) {
618 left += (context->zero_offset * context->volume_mult) / context->volume_div;
619 } else {
620 left -= (context->zero_offset * context->volume_mult) / context->volume_div;
621 }
622 }
623 if (context->channels[i].lr & 0x40) {
624 right += (value * context->volume_mult) / context->volume_div;
625 } else if (context->zero_offset) {
626 if (value >= 0) {
627 right += (context->zero_offset * context->volume_mult) / context->volume_div;
628 } else {
629 right -= (context->zero_offset * context->volume_mult) / context->volume_div;
630 }
631 }
632 }
633 render_put_stereo_sample(context->audio, left, right);
634 }
635
330 void ym_run(ym2612_context * context, uint32_t to_cycle) 636 void ym_run(ym2612_context * context, uint32_t to_cycle)
331 { 637 {
638 if (context->current_cycle >= to_cycle) {
639 return;
640 }
332 //printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle); 641 //printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle);
333 //TODO: Fix channel update order OR remap channels in register write 642 //TODO: Fix channel update order OR remap channels in register write
334 for (; context->current_cycle < to_cycle; context->current_cycle += context->clock_inc) { 643 for (; context->current_cycle < to_cycle; context->current_cycle += context->clock_inc) {
335 //Update timers at beginning of 144 cycle period 644 //Update timers at beginning of 144 cycle period
336 if (!context->current_op) { 645 if (!context->current_op) {
337 if (context->timer_control & BIT_TIMERA_ENABLE) { 646 ym_run_timers(context);
338 if (context->timer_a != TIMER_A_MAX) {
339 context->timer_a++;
340 if (context->csm_keyon) {
341 csm_keyoff(context);
342 }
343 } else {
344 if (context->timer_control & BIT_TIMERA_LOAD) {
345 context->timer_control &= ~BIT_TIMERA_LOAD;
346 } else if (context->timer_control & BIT_TIMERA_OVEREN) {
347 context->status |= BIT_STATUS_TIMERA;
348 }
349 context->timer_a = context->timer_a_load;
350 if (!context->csm_keyon && context->ch3_mode == CSM_MODE) {
351 context->csm_keyon = 0xF0;
352 uint8_t changes = 0xF0 ^ context->channels[2].keyon;;
353 for (uint8_t op = 2*4, bit = 0; op < 3*4; op++, bit++)
354 {
355 if (changes & keyon_bits[bit]) {
356 keyon(context->operators + op, context->channels + 2);
357 }
358 }
359 }
360 }
361 }
362 if (!context->sub_timer_b) {
363 if (context->timer_control & BIT_TIMERB_ENABLE) {
364 if (context->timer_b != TIMER_B_MAX) {
365 context->timer_b++;
366 } else {
367 if (context->timer_control & BIT_TIMERB_LOAD) {
368 context->timer_control &= ~BIT_TIMERB_LOAD;
369 } else if (context->timer_control & BIT_TIMERB_OVEREN) {
370 context->status |= BIT_STATUS_TIMERB;
371 }
372 context->timer_b = context->timer_b_load;
373 }
374 }
375 }
376 context->sub_timer_b += 0x10;
377 //Update LFO
378 if (context->lfo_enable) {
379 if (context->lfo_counter) {
380 context->lfo_counter--;
381 } else {
382 context->lfo_counter = lfo_timer_values[context->lfo_freq];
383 context->lfo_am_step += 2;
384 context->lfo_am_step &= 0xFE;
385 context->lfo_pm_step = context->lfo_am_step / 8;
386 }
387 }
388 } 647 }
389 //Update Envelope Generator 648 //Update Envelope Generator
390 if (!(context->current_op % 3)) { 649 if (!(context->current_op % 3)) {
391 uint32_t env_cyc = context->env_counter;
392 uint32_t op = context->current_env_op; 650 uint32_t op = context->current_env_op;
393 ym_operator * operator = context->operators + op; 651 ym_operator * operator = context->operators + op;
394 ym_channel * channel = context->channels + op/4; 652 ym_channel * channel = context->channels + op/4;
395 uint8_t rate; 653 ym_run_envelope(context, channel, operator);
396 if (operator->env_phase == PHASE_DECAY && operator->envelope >= operator->sustain_level) {
397 //operator->envelope = operator->sustain_level;
398 operator->env_phase = PHASE_SUSTAIN;
399 }
400 rate = operator->rates[operator->env_phase];
401 if (rate) {
402 uint8_t ks = channel->keycode >> operator->key_scaling;;
403 rate = rate*2 + ks;
404 if (rate > 63) {
405 rate = 63;
406 }
407 }
408 uint32_t cycle_shift = rate < 0x30 ? ((0x2F - rate) >> 2) : 0;
409 if (first_key_on) {
410 dfprintf(debug_file, "Operator: %d, env rate: %d (2*%d+%d), env_cyc: %d, cycle_shift: %d, env_cyc & ((1 << cycle_shift) - 1): %d\n", op, rate, operator->rates[operator->env_phase], channel->keycode >> operator->key_scaling,env_cyc, cycle_shift, env_cyc & ((1 << cycle_shift) - 1));
411 }
412 if (!(env_cyc & ((1 << cycle_shift) - 1))) {
413 uint32_t update_cycle = env_cyc >> cycle_shift & 0x7;
414 uint16_t envelope_inc = rate_table[rate * 8 + update_cycle];
415 if (operator->env_phase == PHASE_ATTACK) {
416 //this can probably be optimized to a single shift rather than a multiply + shift
417 if (first_key_on) {
418 dfprintf(debug_file, "Changing op %d envelope %d by %d(%d * %d) in attack phase\n", op, operator->envelope, (~operator->envelope * envelope_inc) >> 4, ~operator->envelope, envelope_inc);
419 }
420 uint16_t old_env = operator->envelope;
421 operator->envelope += ((~operator->envelope * envelope_inc) >> 4) & 0xFFFFFFFC;
422 if (operator->envelope > old_env) {
423 //Handle overflow
424 operator->envelope = 0;
425 }
426 if (!operator->envelope) {
427 operator->env_phase = PHASE_DECAY;
428 }
429 } else {
430 if (first_key_on) {
431 dfprintf(debug_file, "Changing op %d envelope %d by %d in %s phase\n", op, operator->envelope, envelope_inc,
432 operator->env_phase == PHASE_SUSTAIN ? "sustain" : (operator->env_phase == PHASE_DECAY ? "decay": "release"));
433 }
434 if (operator->ssg) {
435 if (operator->envelope < SSG_CENTER) {
436 envelope_inc *= 4;
437 } else {
438 envelope_inc = 0;
439 }
440 }
441 //envelope value is 10-bits, but it will be used as a 4.8 value
442 operator->envelope += envelope_inc << 2;
443 //clamp to max attenuation value
444 if (
445 operator->envelope > MAX_ENVELOPE
446 || (operator->env_phase == PHASE_RELEASE && operator->envelope >= SSG_CENTER)
447 ) {
448 operator->envelope = MAX_ENVELOPE;
449 }
450 }
451 }
452 context->current_env_op++; 654 context->current_env_op++;
453 if (context->current_env_op == NUM_OPERATORS) { 655 if (context->current_env_op == NUM_OPERATORS) {
454 context->current_env_op = 0; 656 context->current_env_op = 0;
455 context->env_counter++; 657 context->env_counter++;
456 } 658 }
457 } 659 }
458 660
459 //Update Phase Generator 661 //Update Phase Generator
460 uint32_t channel = context->current_op / 4; 662 ym_run_phase(context, context->current_op / 4, context->current_op);
461 if (channel != 5 || !context->dac_enable) {
462 uint32_t op = context->current_op;
463 //printf("updating operator %d of channel %d\n", op, channel);
464 ym_operator * operator = context->operators + op;
465 ym_channel * chan = context->channels + channel;
466 uint16_t phase = operator->phase_counter >> 10 & 0x3FF;
467 operator->phase_counter += ym_calc_phase_inc(context, operator, context->current_op);
468 int16_t mod = 0;
469 if (op & 3) {
470 if (operator->mod_src[0]) {
471 mod = *operator->mod_src[0];
472 if (operator->mod_src[1]) {
473 mod += *
474 operator->mod_src[1];
475 }
476 mod >>= YM_MOD_SHIFT;
477 }
478 } else {
479 if (chan->feedback) {
480 mod = (chan->op1_old + operator->output) >> (10-chan->feedback);
481 }
482 }
483 uint16_t env = operator->envelope;
484 if (operator->ssg) {
485 if (env >= SSG_CENTER) {
486 if (operator->ssg & SSG_ALTERNATE) {
487 if (operator->env_phase != PHASE_RELEASE && (
488 !(operator->ssg & SSG_HOLD) || ((operator->ssg ^ operator->inverted) & SSG_INVERT) == 0
489 )) {
490 operator->inverted ^= SSG_INVERT;
491 }
492 } else if (!(operator->ssg & SSG_HOLD)) {
493 phase = operator->phase_counter = 0;
494 }
495 if (
496 (operator->env_phase == PHASE_DECAY || operator->env_phase == PHASE_SUSTAIN)
497 && !(operator->ssg & SSG_HOLD)
498 ) {
499 start_envelope(operator, chan);
500 env = operator->envelope;
501 }
502 }
503 if (operator->inverted) {
504 env = (SSG_CENTER - env) & MAX_ENVELOPE;
505 }
506 }
507 env += operator->total_level;
508 if (operator->am) {
509 uint16_t base_am = (context->lfo_am_step & 0x80 ? context->lfo_am_step : ~context->lfo_am_step) & 0x7E;
510 if (ams_shift[chan->ams] >= 0) {
511 env += base_am >> ams_shift[chan->ams];
512 } else {
513 env += base_am << (-ams_shift[chan->ams]);
514 }
515 }
516 if (env > MAX_ENVELOPE) {
517 env = MAX_ENVELOPE;
518 }
519 if (first_key_on) {
520 dfprintf(debug_file, "op %d, base phase: %d, mod: %d, sine: %d, out: %d\n", op, phase, mod, sine_table[(phase+mod) & 0x1FF], pow_table[sine_table[phase & 0x1FF] + env]);
521 }
522 //if ((channel != 0 && channel != 4) || chan->algorithm != 5) {
523 phase += mod;
524 //}
525
526 int16_t output = pow_table[sine_table[phase & 0x1FF] + env];
527 if (phase & 0x200) {
528 output = -output;
529 }
530 if (op % 4 == 0) {
531 chan->op1_old = operator->output;
532 }
533 operator->output = output;
534 //Update the channel output if we've updated all operators
535 if (op % 4 == 3) {
536 if (chan->algorithm < 4) {
537 chan->output = operator->output;
538 } else if(chan->algorithm == 4) {
539 chan->output = operator->output + context->operators[channel * 4 + 2].output;
540 } else {
541 output = 0;
542 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) {
543 output += context->operators[op].output;
544 }
545 chan->output = output;
546 }
547 if (first_key_on) {
548 int16_t value = context->channels[channel].output & 0x3FE0;
549 if (value & 0x2000) {
550 value |= 0xC000;
551 }
552 dfprintf(debug_file, "channel %d output: %d\n", channel, (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER);
553 }
554 }
555 //puts("operator update done");
556 }
557 context->current_op++; 663 context->current_op++;
558 if (context->current_op == NUM_OPERATORS) { 664 if (context->current_op == NUM_OPERATORS) {
559 context->current_op = 0; 665 context->current_op = 0;
560 666 ym_output_sample(context);
561 int16_t left = 0, right = 0;
562 for (int i = 0; i < NUM_CHANNELS; i++) {
563 int16_t value = context->channels[i].output;
564 if (value > 0x1FE0) {
565 value = 0x1FE0;
566 } else if (value < -0x1FF0) {
567 value = -0x1FF0;
568 } else {
569 value &= 0x3FE0;
570 if (value & 0x2000) {
571 value |= 0xC000;
572 }
573 }
574 if (context->channels[i].logfile) {
575 fwrite(&value, sizeof(value), 1, context->channels[i].logfile);
576 }
577 if (context->channels[i].lr & 0x80) {
578 left += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER;
579 }
580 if (context->channels[i].lr & 0x40) {
581 right += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER;
582 }
583 }
584 render_put_stereo_sample(context->audio, left, right);
585 } 667 }
586 668
587 }
588 if (context->current_cycle >= context->write_cycle + (context->busy_cycles * context->clock_inc / 6)) {
589 context->status &= 0x7F;
590 context->write_cycle = CYCLE_NEVER;
591 } 669 }
592 //printf("Done running YM2612 at cycle %d\n", context->current_cycle, to_cycle); 670 //printf("Done running YM2612 at cycle %d\n", context->current_cycle, to_cycle);
593 } 671 }
594 672
595 void ym_address_write_part1(ym2612_context * context, uint8_t address) 673 void ym_address_write_part1(ym2612_context * context, uint8_t address)
596 { 674 {
597 //printf("address_write_part1: %X\n", address); 675 //printf("address_write_part1: %X\n", address);
598 context->selected_reg = address; 676 context->selected_reg = address;
599 context->selected_part = 0; 677 context->selected_part = 0;
600 context->write_cycle = context->current_cycle;
601 context->busy_cycles = BUSY_CYCLES_ADDRESS;
602 context->status |= 0x80;
603 } 678 }
604 679
605 void ym_address_write_part2(ym2612_context * context, uint8_t address) 680 void ym_address_write_part2(ym2612_context * context, uint8_t address)
606 { 681 {
607 //printf("address_write_part2: %X\n", address); 682 //printf("address_write_part2: %X\n", address);
608 context->selected_reg = address; 683 context->selected_reg = address;
609 context->selected_part = 1; 684 context->selected_part = 1;
610 context->write_cycle = context->current_cycle;
611 context->busy_cycles = BUSY_CYCLES_ADDRESS;
612 context->status |= 0x80;
613 } 685 }
614 686
615 static uint8_t fnum_to_keycode[] = { 687 static uint8_t fnum_to_keycode[] = {
616 //F11 = 0 688 //F11 = 0
617 0,0,0,0,0,0,0,1, 689 0,0,0,0,0,0,0,1,
669 index ^= 1; 741 index ^= 1;
670 } 742 }
671 inc = context->ch3_supp[index].fnum; 743 inc = context->ch3_supp[index].fnum;
672 if (channel->pms) { 744 if (channel->pms) {
673 inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step]; 745 inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step];
746 inc &= 0xFFF;
674 } 747 }
675 if (!context->ch3_supp[index].block) { 748 if (!context->ch3_supp[index].block) {
676 inc >>= 1; 749 inc >>= 1;
677 } else { 750 } else {
678 inc <<= (context->ch3_supp[index].block-1); 751 inc <<= (context->ch3_supp[index].block-1);
681 detune = detune_table[context->ch3_supp[index].keycode][operator->detune & 0x3]; 754 detune = detune_table[context->ch3_supp[index].keycode][operator->detune & 0x3];
682 } else { 755 } else {
683 inc = channel->fnum; 756 inc = channel->fnum;
684 if (channel->pms) { 757 if (channel->pms) {
685 inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step]; 758 inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step];
759 inc &= 0xFFF;
686 } 760 }
687 if (!channel->block) { 761 if (!channel->block) {
688 inc >>= 1; 762 inc >>= 1;
689 } else { 763 } else {
690 inc <<= (channel->block-1); 764 inc <<= (channel->block-1);
712 } 786 }
713 //printf("phase_inc for operator %d: %d, block: %d, fnum: %d, detune: %d, multiple: %d\n", op, inc, channel->block, channel->fnum, detune, operator->multiple); 787 //printf("phase_inc for operator %d: %d, block: %d, fnum: %d, detune: %d, multiple: %d\n", op, inc, channel->block, channel->fnum, detune, operator->multiple);
714 return inc; 788 return inc;
715 } 789 }
716 790
791 void ym_vgm_log(ym2612_context *context, uint32_t master_clock, vgm_writer *vgm)
792 {
793 vgm_ym2612_init(vgm, 6 * master_clock / context->clock_inc);
794 context->vgm = vgm;
795 for (uint8_t reg = YM_PART1_START; reg < YM_REG_END; reg++) {
796 if ((reg >= REG_DETUNE_MULT && (reg & 3) == 3) || (reg >= 0x2D && reg < REG_DETUNE_MULT) || reg == 0x23 || reg == 0x29) {
797 //skip invalid registers
798 continue;
799 }
800 vgm_ym2612_part1_write(context->vgm, context->current_cycle, reg, context->part1_regs[reg - YM_PART1_START]);
801 }
802
803 for (uint8_t reg = YM_PART2_START; reg < YM_REG_END; reg++) {
804 if ((reg & 3) == 3 || (reg >= REG_FNUM_LOW_CH3 && reg < REG_ALG_FEEDBACK)) {
805 //skip invalid registers
806 continue;
807 }
808 vgm_ym2612_part2_write(context->vgm, context->current_cycle, reg, context->part2_regs[reg - YM_PART2_START]);
809 }
810 }
811
717 void ym_data_write(ym2612_context * context, uint8_t value) 812 void ym_data_write(ym2612_context * context, uint8_t value)
718 { 813 {
814 context->write_cycle = context->current_cycle;
815 context->busy_start = context->current_cycle + context->clock_inc;
816
719 if (context->selected_reg >= YM_REG_END) { 817 if (context->selected_reg >= YM_REG_END) {
720 return; 818 return;
721 } 819 }
722 if (context->selected_part) { 820 if (context->selected_part) {
723 if (context->selected_reg < YM_PART2_START) { 821 if (context->selected_reg < YM_PART2_START) {
724 return; 822 return;
823 }
824 if (context->vgm) {
825 vgm_ym2612_part2_write(context->vgm, context->current_cycle, context->selected_reg, value);
725 } 826 }
726 context->part2_regs[context->selected_reg - YM_PART2_START] = value; 827 context->part2_regs[context->selected_reg - YM_PART2_START] = value;
727 } else { 828 } else {
728 if (context->selected_reg < YM_PART1_START) { 829 if (context->selected_reg < YM_PART1_START) {
729 return; 830 return;
730 } 831 }
832 if (context->vgm) {
833 vgm_ym2612_part1_write(context->vgm, context->current_cycle, context->selected_reg, value);
834 }
731 context->part1_regs[context->selected_reg - YM_PART1_START] = value; 835 context->part1_regs[context->selected_reg - YM_PART1_START] = value;
732 } 836 }
837 uint8_t buffer[3] = {context->selected_part, context->selected_reg, value};
838 event_log(EVENT_YM_REG, context->current_cycle, sizeof(buffer), buffer);
733 dfprintf(debug_file, "write of %X to reg %X in part %d\n", value, context->selected_reg, context->selected_part+1); 839 dfprintf(debug_file, "write of %X to reg %X in part %d\n", value, context->selected_reg, context->selected_part+1);
734 if (context->selected_reg < 0x30) { 840 if (context->selected_reg < 0x30) {
735 //Shared regs 841 //Shared regs
736 switch (context->selected_reg) 842 switch (context->selected_reg)
737 { 843 {
740 /*if ((value & 0x8) && !context->lfo_enable) { 846 /*if ((value & 0x8) && !context->lfo_enable) {
741 printf("LFO Enabled, Freq: %d\n", value & 0x7); 847 printf("LFO Enabled, Freq: %d\n", value & 0x7);
742 }*/ 848 }*/
743 context->lfo_enable = value & 0x8; 849 context->lfo_enable = value & 0x8;
744 if (!context->lfo_enable) { 850 if (!context->lfo_enable) {
851 uint8_t old_pm_step = context->lfo_pm_step;
745 context->lfo_am_step = context->lfo_pm_step = 0; 852 context->lfo_am_step = context->lfo_pm_step = 0;
853 if (old_pm_step) {
854 for (int chan = 0; chan < NUM_CHANNELS; chan++)
855 {
856 if (context->channels[chan].pms) {
857 for (int op = chan * 4; op < (chan + 1) * 4; op++)
858 {
859 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
860 }
861 }
862 }
863 }
746 } 864 }
747 context->lfo_freq = value & 0x7; 865 context->lfo_freq = value & 0x7;
748 866
749 break; 867 break;
750 case REG_TIMERA_HIGH: 868 case REG_TIMERA_HIGH:
776 context->status &= ~BIT_STATUS_TIMERB; 894 context->status &= ~BIT_STATUS_TIMERB;
777 } 895 }
778 if (context->ch3_mode == CSM_MODE && (value & 0xC0) != CSM_MODE && context->csm_keyon) { 896 if (context->ch3_mode == CSM_MODE && (value & 0xC0) != CSM_MODE && context->csm_keyon) {
779 csm_keyoff(context); 897 csm_keyoff(context);
780 } 898 }
899 uint8_t old_mode = context->ch3_mode;
781 context->ch3_mode = value & 0xC0; 900 context->ch3_mode = value & 0xC0;
901 if (context->ch3_mode != old_mode) {
902 for (int op = 2 * 4; op < 3*4; op++)
903 {
904 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
905 }
906 }
782 break; 907 break;
783 } 908 }
784 case REG_KEY_ONOFF: { 909 case REG_KEY_ONOFF: {
785 uint8_t channel = value & 0x7; 910 uint8_t channel = value & 0x7;
786 if (channel != 3 && channel != 7) { 911 if (channel != 3 && channel != 7) {
828 switch (context->selected_reg & 0xF0) 953 switch (context->selected_reg & 0xF0)
829 { 954 {
830 case REG_DETUNE_MULT: 955 case REG_DETUNE_MULT:
831 operator->detune = value >> 4 & 0x7; 956 operator->detune = value >> 4 & 0x7;
832 operator->multiple = value & 0xF; 957 operator->multiple = value & 0xF;
958 operator->phase_inc = ym_calc_phase_inc(context, operator, op);
833 break; 959 break;
834 case REG_TOTAL_LEVEL: 960 case REG_TOTAL_LEVEL:
835 operator->total_level = (value & 0x7F) << 5; 961 operator->total_level = (value & 0x7F) << 5;
836 break; 962 break;
837 case REG_ATTACK_KS: 963 case REG_ATTACK_KS:
838 operator->key_scaling = 3 - (value >> 6); 964 operator->key_scaling = 3 - (value >> 6);
839 operator->rates[PHASE_ATTACK] = value & 0x1F; 965 operator->rates[PHASE_ATTACK] = value & 0x1F;
840 break; 966 break;
841 case REG_DECAY_AM: 967 case REG_DECAY_AM:
842 //TODO: AM flag for LFO
843 operator->am = value & 0x80; 968 operator->am = value & 0x80;
844 operator->rates[PHASE_DECAY] = value & 0x1F; 969 operator->rates[PHASE_DECAY] = value & 0x1F;
845 break; 970 break;
846 case REG_SUSTAIN_RATE: 971 case REG_SUSTAIN_RATE:
847 operator->rates[PHASE_SUSTAIN] = value & 0x1F; 972 operator->rates[PHASE_SUSTAIN] = value & 0x1F;
875 { 1000 {
876 case REG_FNUM_LOW: 1001 case REG_FNUM_LOW:
877 context->channels[channel].block = context->channels[channel].block_fnum_latch >> 3 & 0x7; 1002 context->channels[channel].block = context->channels[channel].block_fnum_latch >> 3 & 0x7;
878 context->channels[channel].fnum = (context->channels[channel].block_fnum_latch & 0x7) << 8 | value; 1003 context->channels[channel].fnum = (context->channels[channel].block_fnum_latch & 0x7) << 8 | value;
879 context->channels[channel].keycode = context->channels[channel].block << 2 | fnum_to_keycode[context->channels[channel].fnum >> 7]; 1004 context->channels[channel].keycode = context->channels[channel].block << 2 | fnum_to_keycode[context->channels[channel].fnum >> 7];
1005 for (int op = channel * 4; op < (channel + 1) * 4; op++)
1006 {
1007 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
1008 }
880 break; 1009 break;
881 case REG_BLOCK_FNUM_H:{ 1010 case REG_BLOCK_FNUM_H:{
882 context->channels[channel].block_fnum_latch = value; 1011 context->channels[channel].block_fnum_latch = value;
883 break; 1012 break;
884 } 1013 }
885 case REG_FNUM_LOW_CH3: 1014 case REG_FNUM_LOW_CH3:
886 if (channel < 3) { 1015 if (channel < 3) {
887 context->ch3_supp[channel].block = context->ch3_supp[channel].block_fnum_latch >> 3 & 0x7; 1016 context->ch3_supp[channel].block = context->ch3_supp[channel].block_fnum_latch >> 3 & 0x7;
888 context->ch3_supp[channel].fnum = (context->ch3_supp[channel].block_fnum_latch & 0x7) << 8 | value; 1017 context->ch3_supp[channel].fnum = (context->ch3_supp[channel].block_fnum_latch & 0x7) << 8 | value;
889 context->ch3_supp[channel].keycode = context->ch3_supp[channel].block << 2 | fnum_to_keycode[context->ch3_supp[channel].fnum >> 7]; 1018 context->ch3_supp[channel].keycode = context->ch3_supp[channel].block << 2 | fnum_to_keycode[context->ch3_supp[channel].fnum >> 7];
1019 if (context->ch3_mode) {
1020 int op = 2 * 4 + (channel < 2 ? (channel ^ 1) : channel);
1021 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
1022 }
890 } 1023 }
891 break; 1024 break;
892 case REG_BLOCK_FN_CH3: 1025 case REG_BLOCK_FN_CH3:
893 if (channel < 3) { 1026 if (channel < 3) {
894 context->ch3_supp[channel].block_fnum_latch = value; 1027 context->ch3_supp[channel].block_fnum_latch = value;
898 context->channels[channel].algorithm = value & 0x7; 1031 context->channels[channel].algorithm = value & 0x7;
899 switch (context->channels[channel].algorithm) 1032 switch (context->channels[channel].algorithm)
900 { 1033 {
901 case 0: 1034 case 0:
902 //operator 3 modulated by operator 2 1035 //operator 3 modulated by operator 2
1036 //this uses a special op2 result reg on HW, but that reg will have the most recent
1037 //result from op2 when op3 starts executing
903 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output; 1038 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output;
904 context->operators[channel*4+1].mod_src[1] = NULL; 1039 context->operators[channel*4+1].mod_src[1] = NULL;
905 1040
906 //operator 2 modulated by operator 1 1041 //operator 2 modulated by operator 1
907 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; 1042 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
910 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output; 1045 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output;
911 context->operators[channel*4+3].mod_src[1] = NULL; 1046 context->operators[channel*4+3].mod_src[1] = NULL;
912 break; 1047 break;
913 case 1: 1048 case 1:
914 //operator 3 modulated by operator 1+2 1049 //operator 3 modulated by operator 1+2
915 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+0].output; 1050 //op1 starts executing before this, but due to pipeline length the most current result is
1051 //not available and instead the previous result is used
1052 context->operators[channel*4+1].mod_src[0] = &context->channels[channel].op1_old;
1053 //this uses a special op2 result reg on HW, but that reg will have the most recent
1054 //result from op2 when op3 starts executing
916 context->operators[channel*4+1].mod_src[1] = &context->operators[channel*4+2].output; 1055 context->operators[channel*4+1].mod_src[1] = &context->operators[channel*4+2].output;
917 1056
918 //operator 2 unmodulated 1057 //operator 2 unmodulated
919 context->operators[channel*4+2].mod_src[0] = NULL; 1058 context->operators[channel*4+2].mod_src[0] = NULL;
920 1059
922 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output; 1061 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output;
923 context->operators[channel*4+3].mod_src[1] = NULL; 1062 context->operators[channel*4+3].mod_src[1] = NULL;
924 break; 1063 break;
925 case 2: 1064 case 2:
926 //operator 3 modulated by operator 2 1065 //operator 3 modulated by operator 2
1066 //this uses a special op2 result reg on HW, but that reg will have the most recent
1067 //result from op2 when op3 starts executing
927 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output; 1068 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output;
928 context->operators[channel*4+1].mod_src[1] = NULL; 1069 context->operators[channel*4+1].mod_src[1] = NULL;
929 1070
930 //operator 2 unmodulated 1071 //operator 2 unmodulated
931 context->operators[channel*4+2].mod_src[0] = NULL; 1072 context->operators[channel*4+2].mod_src[0] = NULL;
932 1073
933 //operator 4 modulated by operator 1+3 1074 //operator 4 modulated by operator 1+3
1075 //this uses a special op1 result reg on HW, but that reg will have the most recent
1076 //result from op1 when op4 starts executing
934 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output; 1077 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output;
935 context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output; 1078 context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output;
936 break; 1079 break;
937 case 3: 1080 case 3:
938 //operator 3 unmodulated 1081 //operator 3 unmodulated
941 1084
942 //operator 2 modulated by operator 1 1085 //operator 2 modulated by operator 1
943 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; 1086 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
944 1087
945 //operator 4 modulated by operator 2+3 1088 //operator 4 modulated by operator 2+3
946 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+2].output; 1089 //op2 starts executing before this, but due to pipeline length the most current result is
1090 //not available and instead the previous result is used
1091 context->operators[channel*4+3].mod_src[0] = &context->channels[channel].op2_old;
947 context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output; 1092 context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output;
948 break; 1093 break;
949 case 4: 1094 case 4:
950 //operator 3 unmodulated 1095 //operator 3 unmodulated
951 context->operators[channel*4+1].mod_src[0] = NULL; 1096 context->operators[channel*4+1].mod_src[0] = NULL;
958 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output; 1103 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output;
959 context->operators[channel*4+3].mod_src[1] = NULL; 1104 context->operators[channel*4+3].mod_src[1] = NULL;
960 break; 1105 break;
961 case 5: 1106 case 5:
962 //operator 3 modulated by operator 1 1107 //operator 3 modulated by operator 1
963 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+0].output; 1108 //op1 starts executing before this, but due to pipeline length the most current result is
1109 //not available and instead the previous result is used
1110 context->operators[channel*4+1].mod_src[0] = &context->channels[channel].op1_old;
964 context->operators[channel*4+1].mod_src[1] = NULL; 1111 context->operators[channel*4+1].mod_src[1] = NULL;
965 1112
966 //operator 2 modulated by operator 1 1113 //operator 2 modulated by operator 1
967 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; 1114 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output;
968 1115
969 //operator 4 modulated by operator 1 1116 //operator 4 modulated by operator 1
1117 //this uses a special op1 result reg on HW, but that reg will have the most recent
1118 //result from op1 when op4 starts executing
970 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output; 1119 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output;
971 context->operators[channel*4+3].mod_src[1] = NULL; 1120 context->operators[channel*4+3].mod_src[1] = NULL;
972 break; 1121 break;
973 case 6: 1122 case 6:
974 //operator 3 unmodulated 1123 //operator 3 unmodulated
994 break; 1143 break;
995 } 1144 }
996 context->channels[channel].feedback = value >> 3 & 0x7; 1145 context->channels[channel].feedback = value >> 3 & 0x7;
997 //printf("Algorithm %d, feedback %d for channel %d\n", value & 0x7, value >> 3 & 0x7, channel); 1146 //printf("Algorithm %d, feedback %d for channel %d\n", value & 0x7, value >> 3 & 0x7, channel);
998 break; 1147 break;
999 case REG_LR_AMS_PMS: 1148 case REG_LR_AMS_PMS: {
1149 uint8_t old_pms = context->channels[channel].pms;
1000 context->channels[channel].pms = (value & 0x7) * 32; 1150 context->channels[channel].pms = (value & 0x7) * 32;
1001 context->channels[channel].ams = value >> 4 & 0x3; 1151 context->channels[channel].ams = value >> 4 & 0x3;
1002 context->channels[channel].lr = value & 0xC0; 1152 context->channels[channel].lr = value & 0xC0;
1153 if (old_pms != context->channels[channel].pms) {
1154 for (int op = channel * 4; op < (channel + 1) * 4; op++)
1155 {
1156 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
1157 }
1158 }
1003 //printf("Write of %X to LR_AMS_PMS reg for channel %d\n", value, channel); 1159 //printf("Write of %X to LR_AMS_PMS reg for channel %d\n", value, channel);
1004 break; 1160 break;
1005 } 1161 }
1006 } 1162 }
1007 } 1163 }
1008 1164 }
1009 context->write_cycle = context->current_cycle; 1165 }
1010 context->busy_cycles = context->selected_reg < 0xA0 ? BUSY_CYCLES_DATA_LOW : BUSY_CYCLES_DATA_HIGH; 1166
1011 context->status |= 0x80; 1167 uint8_t ym_read_status(ym2612_context * context, uint32_t cycle, uint32_t port)
1012 } 1168 {
1013 1169 uint8_t status;
1014 uint8_t ym_read_status(ym2612_context * context) 1170 port &= context->status_address_mask;
1015 { 1171 if (port) {
1016 return context->status; 1172 if (context->last_status_cycle != CYCLE_NEVER && cycle - context->last_status_cycle > context->invalid_status_decay) {
1173 context->last_status = 0;
1174 }
1175 status = context->last_status;
1176 } else {
1177 status = context->status;
1178 if (cycle >= context->busy_start && cycle < context->busy_start + context->busy_cycles) {
1179 status |= 0x80;
1180 }
1181 context->last_status = status;
1182 context->last_status_cycle = cycle;
1183 }
1184 return status;
1185
1017 } 1186 }
1018 1187
1019 void ym_print_channel_info(ym2612_context *context, int channel) 1188 void ym_print_channel_info(ym2612_context *context, int channel)
1020 { 1189 {
1021 ym_channel *chan = context->channels + channel; 1190 ym_channel *chan = context->channels + channel;
1123 save_int8(buf, context->status); 1292 save_int8(buf, context->status);
1124 save_int8(buf, context->selected_reg); 1293 save_int8(buf, context->selected_reg);
1125 save_int8(buf, context->selected_part); 1294 save_int8(buf, context->selected_part);
1126 save_int32(buf, context->current_cycle); 1295 save_int32(buf, context->current_cycle);
1127 save_int32(buf, context->write_cycle); 1296 save_int32(buf, context->write_cycle);
1128 save_int32(buf, context->busy_cycles); 1297 save_int32(buf, context->busy_start);
1298 save_int32(buf, context->last_status_cycle);
1299 save_int32(buf, context->invalid_status_decay);
1300 save_int8(buf, context->last_status);
1129 } 1301 }
1130 1302
1131 void ym_deserialize(deserialize_buffer *buf, void *vcontext) 1303 void ym_deserialize(deserialize_buffer *buf, void *vcontext)
1132 { 1304 {
1133 ym2612_context *context = vcontext; 1305 ym2612_context *context = vcontext;
1198 context->status = load_int8(buf); 1370 context->status = load_int8(buf);
1199 context->selected_reg = load_int8(buf); 1371 context->selected_reg = load_int8(buf);
1200 context->selected_part = load_int8(buf); 1372 context->selected_part = load_int8(buf);
1201 context->current_cycle = load_int32(buf); 1373 context->current_cycle = load_int32(buf);
1202 context->write_cycle = load_int32(buf); 1374 context->write_cycle = load_int32(buf);
1203 context->busy_cycles = load_int32(buf); 1375 context->busy_start = load_int32(buf);
1204 } 1376 if (buf->size > buf->cur_pos) {
1377 context->last_status_cycle = load_int32(buf);
1378 context->invalid_status_decay = load_int32(buf);
1379 context->last_status = load_int8(buf);
1380 } else {
1381 context->last_status = context->status;
1382 context->last_status_cycle = context->write_cycle;
1383 }
1384 }