comparison ym2612.c @ 1931:374a5ae694e8 mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 18 Apr 2020 11:42:53 -0700
parents 00fb99805445
children c3c62dbf1ceb
comparison
equal deleted inserted replaced
1843:13abdc98379e 1931:374a5ae694e8
19 #else 19 #else
20 #define dfprintf 20 #define dfprintf
21 #define dfopen(var, fname, mode) 21 #define dfopen(var, fname, mode)
22 #endif 22 #endif
23 23
24 #define BUSY_CYCLES_ADDRESS 17 24 #define BUSY_CYCLES 32
25 #define BUSY_CYCLES_DATA_LOW 83
26 #define BUSY_CYCLES_DATA_HIGH 47
27 #define OP_UPDATE_PERIOD 144 25 #define OP_UPDATE_PERIOD 144
28 26
29 #define BIT_TIMERA_ENABLE 0x1 27 #define BIT_TIMERA_ENABLE 0x1
30 #define BIT_TIMERB_ENABLE 0x2 28 #define BIT_TIMERB_ENABLE 0x2
31 #define BIT_TIMERA_OVEREN 0x4 29 #define BIT_TIMERA_OVEREN 0x4
118 } 116 }
119 117
120 void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock) 118 void ym_adjust_master_clock(ym2612_context * context, uint32_t master_clock)
121 { 119 {
122 render_audio_adjust_clock(context->audio, master_clock, context->clock_inc * NUM_OPERATORS); 120 render_audio_adjust_clock(context->audio, master_clock, context->clock_inc * NUM_OPERATORS);
121 }
122
123 void ym_adjust_cycles(ym2612_context *context, uint32_t deduction)
124 {
125 context->current_cycle -= deduction;
126 if (context->write_cycle != CYCLE_NEVER && context->write_cycle >= deduction) {
127 context->write_cycle -= deduction;
128 } else {
129 context->write_cycle = CYCLE_NEVER;
130 }
131 if (context->busy_start != CYCLE_NEVER && context->busy_start >= deduction) {
132 context->busy_start -= deduction;
133 } else {
134 context->busy_start = CYCLE_NEVER;
135 }
136 if (context->last_status_cycle != CYCLE_NEVER && context->last_status_cycle >= deduction) {
137 context->last_status_cycle -= deduction;
138 } else {
139 context->last_status = 0;
140 context->last_status_cycle = CYCLE_NEVER;
141 }
123 } 142 }
124 143
125 #ifdef __ANDROID__ 144 #ifdef __ANDROID__
126 #define log2(x) (log(x)/log(2)) 145 #define log2(x) (log(x)/log(2))
127 #endif 146 #endif
171 { 190 {
172 static uint8_t registered_finalize; 191 static uint8_t registered_finalize;
173 dfopen(debug_file, "ym_debug.txt", "w"); 192 dfopen(debug_file, "ym_debug.txt", "w");
174 memset(context, 0, sizeof(*context)); 193 memset(context, 0, sizeof(*context));
175 context->clock_inc = clock_div * 6; 194 context->clock_inc = clock_div * 6;
195 context->busy_cycles = BUSY_CYCLES * context->clock_inc;
176 context->audio = render_audio_source(master_clock, context->clock_inc * NUM_OPERATORS, 2); 196 context->audio = render_audio_source(master_clock, context->clock_inc * NUM_OPERATORS, 2);
197 //TODO: pick a randomish high initial value and lower it over time
198 context->invalid_status_decay = 225000 * context->clock_inc;
199 context->status_address_mask = (options & YM_OPT_3834) ? 0 : 3;
177 200
178 //some games seem to expect that the LR flags start out as 1 201 //some games seem to expect that the LR flags start out as 1
179 for (int i = 0; i < NUM_CHANNELS; i++) { 202 for (int i = 0; i < NUM_CHANNELS; i++) {
180 if (options & YM_OPT_WAVE_LOG) { 203 if (options & YM_OPT_WAVE_LOG) {
181 char fname[64]; 204 char fname[64];
336 keyoff(context->operators + op); 359 keyoff(context->operators + op);
337 } 360 }
338 } 361 }
339 } 362 }
340 363
364 void ym_run_timers(ym2612_context *context)
365 {
366 if (context->timer_control & BIT_TIMERA_ENABLE) {
367 if (context->timer_a != TIMER_A_MAX) {
368 context->timer_a++;
369 if (context->csm_keyon) {
370 csm_keyoff(context);
371 }
372 } else {
373 if (context->timer_control & BIT_TIMERA_LOAD) {
374 context->timer_control &= ~BIT_TIMERA_LOAD;
375 } else if (context->timer_control & BIT_TIMERA_OVEREN) {
376 context->status |= BIT_STATUS_TIMERA;
377 }
378 context->timer_a = context->timer_a_load;
379 if (!context->csm_keyon && context->ch3_mode == CSM_MODE) {
380 context->csm_keyon = 0xF0;
381 uint8_t changes = 0xF0 ^ context->channels[2].keyon;;
382 for (uint8_t op = 2*4, bit = 0; op < 3*4; op++, bit++)
383 {
384 if (changes & keyon_bits[bit]) {
385 keyon(context->operators + op, context->channels + 2);
386 }
387 }
388 }
389 }
390 }
391 if (!context->sub_timer_b) {
392 if (context->timer_control & BIT_TIMERB_ENABLE) {
393 if (context->timer_b != TIMER_B_MAX) {
394 context->timer_b++;
395 } else {
396 if (context->timer_control & BIT_TIMERB_LOAD) {
397 context->timer_control &= ~BIT_TIMERB_LOAD;
398 } else if (context->timer_control & BIT_TIMERB_OVEREN) {
399 context->status |= BIT_STATUS_TIMERB;
400 }
401 context->timer_b = context->timer_b_load;
402 }
403 }
404 }
405 context->sub_timer_b += 0x10;
406 //Update LFO
407 if (context->lfo_enable) {
408 if (context->lfo_counter) {
409 context->lfo_counter--;
410 } else {
411 context->lfo_counter = lfo_timer_values[context->lfo_freq];
412 context->lfo_am_step += 2;
413 context->lfo_am_step &= 0xFE;
414 uint8_t old_pm_step = context->lfo_pm_step;
415 context->lfo_pm_step = context->lfo_am_step / 8;
416 if (context->lfo_pm_step != old_pm_step) {
417 for (int chan = 0; chan < NUM_CHANNELS; chan++)
418 {
419 if (context->channels[chan].pms) {
420 for (int op = chan * 4; op < (chan + 1) * 4; op++)
421 {
422 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
423 }
424 }
425 }
426 }
427 }
428 }
429 }
430
431 void ym_run_envelope(ym2612_context *context, ym_channel *channel, ym_operator *operator)
432 {
433 uint32_t env_cyc = context->env_counter;
434 uint8_t rate;
435 if (operator->env_phase == PHASE_DECAY && operator->envelope >= operator->sustain_level) {
436 //operator->envelope = operator->sustain_level;
437 operator->env_phase = PHASE_SUSTAIN;
438 }
439 rate = operator->rates[operator->env_phase];
440 if (rate) {
441 uint8_t ks = channel->keycode >> operator->key_scaling;;
442 rate = rate*2 + ks;
443 if (rate > 63) {
444 rate = 63;
445 }
446 }
447 uint32_t cycle_shift = rate < 0x30 ? ((0x2F - rate) >> 2) : 0;
448 if (!(env_cyc & ((1 << cycle_shift) - 1))) {
449 uint32_t update_cycle = env_cyc >> cycle_shift & 0x7;
450 uint16_t envelope_inc = rate_table[rate * 8 + update_cycle];
451 if (operator->env_phase == PHASE_ATTACK) {
452 //this can probably be optimized to a single shift rather than a multiply + shift
453 uint16_t old_env = operator->envelope;
454 operator->envelope += ((~operator->envelope * envelope_inc) >> 4) & 0xFFFFFFFC;
455 if (operator->envelope > old_env) {
456 //Handle overflow
457 operator->envelope = 0;
458 }
459 if (!operator->envelope) {
460 operator->env_phase = PHASE_DECAY;
461 }
462 } else {
463 if (operator->ssg) {
464 if (operator->envelope < SSG_CENTER) {
465 envelope_inc *= 4;
466 } else {
467 envelope_inc = 0;
468 }
469 }
470 //envelope value is 10-bits, but it will be used as a 4.8 value
471 operator->envelope += envelope_inc << 2;
472 //clamp to max attenuation value
473 if (
474 operator->envelope > MAX_ENVELOPE
475 || (operator->env_phase == PHASE_RELEASE && operator->envelope >= SSG_CENTER)
476 ) {
477 operator->envelope = MAX_ENVELOPE;
478 }
479 }
480 }
481 }
482
483 void ym_run_phase(ym2612_context *context, uint32_t channel, uint32_t op)
484 {
485 if (channel != 5 || !context->dac_enable) {
486 //printf("updating operator %d of channel %d\n", op, channel);
487 ym_operator * operator = context->operators + op;
488 ym_channel * chan = context->channels + channel;
489 uint16_t phase = operator->phase_counter >> 10 & 0x3FF;
490 operator->phase_counter += operator->phase_inc;//ym_calc_phase_inc(context, operator, op);
491 int16_t mod = 0;
492 if (op & 3) {
493 if (operator->mod_src[0]) {
494 mod = *operator->mod_src[0];
495 if (operator->mod_src[1]) {
496 mod += *operator->mod_src[1];
497 }
498 mod >>= YM_MOD_SHIFT;
499 }
500 } else {
501 if (chan->feedback) {
502 mod = (chan->op1_old + operator->output) >> (10-chan->feedback);
503 }
504 }
505 uint16_t env = operator->envelope;
506 if (operator->ssg) {
507 if (env >= SSG_CENTER) {
508 if (operator->ssg & SSG_ALTERNATE) {
509 if (operator->env_phase != PHASE_RELEASE && (
510 !(operator->ssg & SSG_HOLD) || ((operator->ssg ^ operator->inverted) & SSG_INVERT) == 0
511 )) {
512 operator->inverted ^= SSG_INVERT;
513 }
514 } else if (!(operator->ssg & SSG_HOLD)) {
515 phase = operator->phase_counter = 0;
516 }
517 if (
518 (operator->env_phase == PHASE_DECAY || operator->env_phase == PHASE_SUSTAIN)
519 && !(operator->ssg & SSG_HOLD)
520 ) {
521 start_envelope(operator, chan);
522 env = operator->envelope;
523 }
524 }
525 if (operator->inverted) {
526 env = (SSG_CENTER - env) & MAX_ENVELOPE;
527 }
528 }
529 env += operator->total_level;
530 if (operator->am) {
531 uint16_t base_am = (context->lfo_am_step & 0x80 ? context->lfo_am_step : ~context->lfo_am_step) & 0x7E;
532 if (ams_shift[chan->ams] >= 0) {
533 env += (base_am >> ams_shift[chan->ams]) & MAX_ENVELOPE;
534 } else {
535 env += base_am << (-ams_shift[chan->ams]);
536 }
537 }
538 if (env > MAX_ENVELOPE) {
539 env = MAX_ENVELOPE;
540 }
541 if (first_key_on) {
542 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]);
543 }
544 //if ((channel != 0 && channel != 4) || chan->algorithm != 5) {
545 phase += mod;
546 //}
547
548 int16_t output = pow_table[sine_table[phase & 0x1FF] + env];
549 if (phase & 0x200) {
550 output = -output;
551 }
552 if (op % 4 == 0) {
553 chan->op1_old = operator->output;
554 } else if (op % 4 == 2) {
555 chan->op2_old = operator->output;
556 }
557 operator->output = output;
558 //Update the channel output if we've updated all operators
559 if (op % 4 == 3) {
560 if (chan->algorithm < 4) {
561 chan->output = operator->output;
562 } else if(chan->algorithm == 4) {
563 chan->output = operator->output + context->operators[channel * 4 + 2].output;
564 } else {
565 output = 0;
566 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) {
567 output += context->operators[op].output;
568 }
569 chan->output = output;
570 }
571 if (first_key_on) {
572 int16_t value = context->channels[channel].output & 0x3FE0;
573 if (value & 0x2000) {
574 value |= 0xC000;
575 }
576 }
577 }
578 //puts("operator update done");
579 }
580 }
581
582 void ym_output_sample(ym2612_context *context)
583 {
584 int16_t left = 0, right = 0;
585 for (int i = 0; i < NUM_CHANNELS; i++) {
586 int16_t value = context->channels[i].output;
587 if (value > 0x1FE0) {
588 value = 0x1FE0;
589 } else if (value < -0x1FF0) {
590 value = -0x1FF0;
591 } else {
592 value &= 0x3FE0;
593 if (value & 0x2000) {
594 value |= 0xC000;
595 }
596 }
597 if (value >= 0) {
598 value += context->zero_offset;
599 } else {
600 value -= context->zero_offset;
601 }
602 if (context->channels[i].logfile) {
603 fwrite(&value, sizeof(value), 1, context->channels[i].logfile);
604 }
605 if (context->channels[i].lr & 0x80) {
606 left += (value * context->volume_mult) / context->volume_div;
607 } else if (context->zero_offset) {
608 if (value >= 0) {
609 left += (context->zero_offset * context->volume_mult) / context->volume_div;
610 } else {
611 left -= (context->zero_offset * context->volume_mult) / context->volume_div;
612 }
613 }
614 if (context->channels[i].lr & 0x40) {
615 right += (value * context->volume_mult) / context->volume_div;
616 } else if (context->zero_offset) {
617 if (value >= 0) {
618 right += (context->zero_offset * context->volume_mult) / context->volume_div;
619 } else {
620 right -= (context->zero_offset * context->volume_mult) / context->volume_div;
621 }
622 }
623 }
624 render_put_stereo_sample(context->audio, left, right);
625 }
626
341 void ym_run(ym2612_context * context, uint32_t to_cycle) 627 void ym_run(ym2612_context * context, uint32_t to_cycle)
342 { 628 {
629 if (context->current_cycle >= to_cycle) {
630 return;
631 }
343 //printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle); 632 //printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle);
344 //TODO: Fix channel update order OR remap channels in register write 633 //TODO: Fix channel update order OR remap channels in register write
345 for (; context->current_cycle < to_cycle; context->current_cycle += context->clock_inc) { 634 for (; context->current_cycle < to_cycle; context->current_cycle += context->clock_inc) {
346 //Update timers at beginning of 144 cycle period 635 //Update timers at beginning of 144 cycle period
347 if (!context->current_op) { 636 if (!context->current_op) {
348 if (context->timer_control & BIT_TIMERA_ENABLE) { 637 ym_run_timers(context);
349 if (context->timer_a != TIMER_A_MAX) {
350 context->timer_a++;
351 if (context->csm_keyon) {
352 csm_keyoff(context);
353 }
354 } else {
355 if (context->timer_control & BIT_TIMERA_LOAD) {
356 context->timer_control &= ~BIT_TIMERA_LOAD;
357 } else if (context->timer_control & BIT_TIMERA_OVEREN) {
358 context->status |= BIT_STATUS_TIMERA;
359 }
360 context->timer_a = context->timer_a_load;
361 if (!context->csm_keyon && context->ch3_mode == CSM_MODE) {
362 context->csm_keyon = 0xF0;
363 uint8_t changes = 0xF0 ^ context->channels[2].keyon;;
364 for (uint8_t op = 2*4, bit = 0; op < 3*4; op++, bit++)
365 {
366 if (changes & keyon_bits[bit]) {
367 keyon(context->operators + op, context->channels + 2);
368 }
369 }
370 }
371 }
372 }
373 if (!context->sub_timer_b) {
374 if (context->timer_control & BIT_TIMERB_ENABLE) {
375 if (context->timer_b != TIMER_B_MAX) {
376 context->timer_b++;
377 } else {
378 if (context->timer_control & BIT_TIMERB_LOAD) {
379 context->timer_control &= ~BIT_TIMERB_LOAD;
380 } else if (context->timer_control & BIT_TIMERB_OVEREN) {
381 context->status |= BIT_STATUS_TIMERB;
382 }
383 context->timer_b = context->timer_b_load;
384 }
385 }
386 }
387 context->sub_timer_b += 0x10;
388 //Update LFO
389 if (context->lfo_enable) {
390 if (context->lfo_counter) {
391 context->lfo_counter--;
392 } else {
393 context->lfo_counter = lfo_timer_values[context->lfo_freq];
394 context->lfo_am_step += 2;
395 context->lfo_am_step &= 0xFE;
396 context->lfo_pm_step = context->lfo_am_step / 8;
397 }
398 }
399 } 638 }
400 //Update Envelope Generator 639 //Update Envelope Generator
401 if (!(context->current_op % 3)) { 640 if (!(context->current_op % 3)) {
402 uint32_t env_cyc = context->env_counter;
403 uint32_t op = context->current_env_op; 641 uint32_t op = context->current_env_op;
404 ym_operator * operator = context->operators + op; 642 ym_operator * operator = context->operators + op;
405 ym_channel * channel = context->channels + op/4; 643 ym_channel * channel = context->channels + op/4;
406 uint8_t rate; 644 ym_run_envelope(context, channel, operator);
407 if (operator->env_phase == PHASE_DECAY && operator->envelope >= operator->sustain_level) {
408 //operator->envelope = operator->sustain_level;
409 operator->env_phase = PHASE_SUSTAIN;
410 }
411 rate = operator->rates[operator->env_phase];
412 if (rate) {
413 uint8_t ks = channel->keycode >> operator->key_scaling;;
414 rate = rate*2 + ks;
415 if (rate > 63) {
416 rate = 63;
417 }
418 }
419 uint32_t cycle_shift = rate < 0x30 ? ((0x2F - rate) >> 2) : 0;
420 if (first_key_on) {
421 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));
422 }
423 if (!(env_cyc & ((1 << cycle_shift) - 1))) {
424 uint32_t update_cycle = env_cyc >> cycle_shift & 0x7;
425 uint16_t envelope_inc = rate_table[rate * 8 + update_cycle];
426 if (operator->env_phase == PHASE_ATTACK) {
427 //this can probably be optimized to a single shift rather than a multiply + shift
428 if (first_key_on) {
429 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);
430 }
431 uint16_t old_env = operator->envelope;
432 operator->envelope += ((~operator->envelope * envelope_inc) >> 4) & 0xFFFFFFFC;
433 if (operator->envelope > old_env) {
434 //Handle overflow
435 operator->envelope = 0;
436 }
437 if (!operator->envelope) {
438 operator->env_phase = PHASE_DECAY;
439 }
440 } else {
441 if (first_key_on) {
442 dfprintf(debug_file, "Changing op %d envelope %d by %d in %s phase\n", op, operator->envelope, envelope_inc,
443 operator->env_phase == PHASE_SUSTAIN ? "sustain" : (operator->env_phase == PHASE_DECAY ? "decay": "release"));
444 }
445 if (operator->ssg) {
446 if (operator->envelope < SSG_CENTER) {
447 envelope_inc *= 4;
448 } else {
449 envelope_inc = 0;
450 }
451 }
452 //envelope value is 10-bits, but it will be used as a 4.8 value
453 operator->envelope += envelope_inc << 2;
454 //clamp to max attenuation value
455 if (
456 operator->envelope > MAX_ENVELOPE
457 || (operator->env_phase == PHASE_RELEASE && operator->envelope >= SSG_CENTER)
458 ) {
459 operator->envelope = MAX_ENVELOPE;
460 }
461 }
462 }
463 context->current_env_op++; 645 context->current_env_op++;
464 if (context->current_env_op == NUM_OPERATORS) { 646 if (context->current_env_op == NUM_OPERATORS) {
465 context->current_env_op = 0; 647 context->current_env_op = 0;
466 context->env_counter++; 648 context->env_counter++;
467 } 649 }
468 } 650 }
469 651
470 //Update Phase Generator 652 //Update Phase Generator
471 uint32_t channel = context->current_op / 4; 653 ym_run_phase(context, context->current_op / 4, context->current_op);
472 if (channel != 5 || !context->dac_enable) {
473 uint32_t op = context->current_op;
474 //printf("updating operator %d of channel %d\n", op, channel);
475 ym_operator * operator = context->operators + op;
476 ym_channel * chan = context->channels + channel;
477 uint16_t phase = operator->phase_counter >> 10 & 0x3FF;
478 operator->phase_counter += ym_calc_phase_inc(context, operator, context->current_op);
479 int16_t mod = 0;
480 if (op & 3) {
481 if (operator->mod_src[0]) {
482 mod = *operator->mod_src[0];
483 if (operator->mod_src[1]) {
484 mod += *operator->mod_src[1];
485 }
486 mod >>= YM_MOD_SHIFT;
487 }
488 } else {
489 if (chan->feedback) {
490 mod = (chan->op1_old + operator->output) >> (10-chan->feedback);
491 }
492 }
493 uint16_t env = operator->envelope;
494 if (operator->ssg) {
495 if (env >= SSG_CENTER) {
496 if (operator->ssg & SSG_ALTERNATE) {
497 if (operator->env_phase != PHASE_RELEASE && (
498 !(operator->ssg & SSG_HOLD) || ((operator->ssg ^ operator->inverted) & SSG_INVERT) == 0
499 )) {
500 operator->inverted ^= SSG_INVERT;
501 }
502 } else if (!(operator->ssg & SSG_HOLD)) {
503 phase = operator->phase_counter = 0;
504 }
505 if (
506 (operator->env_phase == PHASE_DECAY || operator->env_phase == PHASE_SUSTAIN)
507 && !(operator->ssg & SSG_HOLD)
508 ) {
509 start_envelope(operator, chan);
510 env = operator->envelope;
511 }
512 }
513 if (operator->inverted) {
514 env = (SSG_CENTER - env) & MAX_ENVELOPE;
515 }
516 }
517 env += operator->total_level;
518 if (operator->am) {
519 uint16_t base_am = (context->lfo_am_step & 0x80 ? context->lfo_am_step : ~context->lfo_am_step) & 0x7E;
520 if (ams_shift[chan->ams] >= 0) {
521 env += (base_am >> ams_shift[chan->ams]) & MAX_ENVELOPE;
522 } else {
523 env += base_am << (-ams_shift[chan->ams]);
524 }
525 }
526 if (env > MAX_ENVELOPE) {
527 env = MAX_ENVELOPE;
528 }
529 if (first_key_on) {
530 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]);
531 }
532 //if ((channel != 0 && channel != 4) || chan->algorithm != 5) {
533 phase += mod;
534 //}
535
536 int16_t output = pow_table[sine_table[phase & 0x1FF] + env];
537 if (phase & 0x200) {
538 output = -output;
539 }
540 if (op % 4 == 0) {
541 chan->op1_old = operator->output;
542 } else if (op % 4 == 2) {
543 chan->op2_old = operator->output;
544 }
545 operator->output = output;
546 //Update the channel output if we've updated all operators
547 if (op % 4 == 3) {
548 if (chan->algorithm < 4) {
549 chan->output = operator->output;
550 } else if(chan->algorithm == 4) {
551 chan->output = operator->output + context->operators[channel * 4 + 2].output;
552 } else {
553 output = 0;
554 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) {
555 output += context->operators[op].output;
556 }
557 chan->output = output;
558 }
559 if (first_key_on) {
560 int16_t value = context->channels[channel].output & 0x3FE0;
561 if (value & 0x2000) {
562 value |= 0xC000;
563 }
564 dfprintf(debug_file, "channel %d output: %d\n", channel, (value * context->volume_mult) / context->volume_div);
565 }
566 }
567 //puts("operator update done");
568 }
569 context->current_op++; 654 context->current_op++;
570 if (context->current_op == NUM_OPERATORS) { 655 if (context->current_op == NUM_OPERATORS) {
571 context->current_op = 0; 656 context->current_op = 0;
572 657 ym_output_sample(context);
573 int16_t left = 0, right = 0;
574 for (int i = 0; i < NUM_CHANNELS; i++) {
575 int16_t value = context->channels[i].output;
576 if (value > 0x1FE0) {
577 value = 0x1FE0;
578 } else if (value < -0x1FF0) {
579 value = -0x1FF0;
580 } else {
581 value &= 0x3FE0;
582 if (value & 0x2000) {
583 value |= 0xC000;
584 }
585 }
586 if (value >= 0) {
587 value += context->zero_offset;
588 } else {
589 value -= context->zero_offset;
590 }
591 if (context->channels[i].logfile) {
592 fwrite(&value, sizeof(value), 1, context->channels[i].logfile);
593 }
594 if (context->channels[i].lr & 0x80) {
595 left += (value * context->volume_mult) / context->volume_div;
596 } else if (context->zero_offset) {
597 if (value >= 0) {
598 left += (context->zero_offset * context->volume_mult) / context->volume_div;
599 } else {
600 left -= (context->zero_offset * context->volume_mult) / context->volume_div;
601 }
602 }
603 if (context->channels[i].lr & 0x40) {
604 right += (value * context->volume_mult) / context->volume_div;
605 } else if (context->zero_offset) {
606 if (value >= 0) {
607 right += (context->zero_offset * context->volume_mult) / context->volume_div;
608 } else {
609 right -= (context->zero_offset * context->volume_mult) / context->volume_div;
610 }
611 }
612 }
613 render_put_stereo_sample(context->audio, left, right);
614 } 658 }
615 659
616 }
617 if (context->current_cycle >= context->write_cycle + (context->busy_cycles * context->clock_inc / 6)) {
618 context->status &= 0x7F;
619 context->write_cycle = CYCLE_NEVER;
620 } 660 }
621 //printf("Done running YM2612 at cycle %d\n", context->current_cycle, to_cycle); 661 //printf("Done running YM2612 at cycle %d\n", context->current_cycle, to_cycle);
622 } 662 }
623 663
624 void ym_address_write_part1(ym2612_context * context, uint8_t address) 664 void ym_address_write_part1(ym2612_context * context, uint8_t address)
625 { 665 {
626 //printf("address_write_part1: %X\n", address); 666 //printf("address_write_part1: %X\n", address);
627 context->selected_reg = address; 667 context->selected_reg = address;
628 context->selected_part = 0; 668 context->selected_part = 0;
629 context->write_cycle = context->current_cycle;
630 context->busy_cycles = BUSY_CYCLES_ADDRESS;
631 context->status |= 0x80;
632 } 669 }
633 670
634 void ym_address_write_part2(ym2612_context * context, uint8_t address) 671 void ym_address_write_part2(ym2612_context * context, uint8_t address)
635 { 672 {
636 //printf("address_write_part2: %X\n", address); 673 //printf("address_write_part2: %X\n", address);
637 context->selected_reg = address; 674 context->selected_reg = address;
638 context->selected_part = 1; 675 context->selected_part = 1;
639 context->write_cycle = context->current_cycle;
640 context->busy_cycles = BUSY_CYCLES_ADDRESS;
641 context->status |= 0x80;
642 } 676 }
643 677
644 static uint8_t fnum_to_keycode[] = { 678 static uint8_t fnum_to_keycode[] = {
645 //F11 = 0 679 //F11 = 0
646 0,0,0,0,0,0,0,1, 680 0,0,0,0,0,0,0,1,
743 } 777 }
744 //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); 778 //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);
745 return inc; 779 return inc;
746 } 780 }
747 781
782 void ym_vgm_log(ym2612_context *context, uint32_t master_clock, vgm_writer *vgm)
783 {
784 vgm_ym2612_init(vgm, 6 * master_clock / context->clock_inc);
785 context->vgm = vgm;
786 for (uint8_t reg = YM_PART1_START; reg < YM_REG_END; reg++) {
787 if ((reg >= REG_DETUNE_MULT && (reg & 3) == 3) || (reg >= 0x2D && reg < REG_DETUNE_MULT) || reg == 0x23 || reg == 0x29) {
788 //skip invalid registers
789 continue;
790 }
791 vgm_ym2612_part1_write(context->vgm, context->current_cycle, reg, context->part1_regs[reg - YM_PART1_START]);
792 }
793
794 for (uint8_t reg = YM_PART2_START; reg < YM_REG_END; reg++) {
795 if ((reg & 3) == 3 || (reg >= REG_FNUM_LOW_CH3 && reg < REG_ALG_FEEDBACK)) {
796 //skip invalid registers
797 continue;
798 }
799 vgm_ym2612_part2_write(context->vgm, context->current_cycle, reg, context->part2_regs[reg - YM_PART2_START]);
800 }
801 }
802
748 void ym_data_write(ym2612_context * context, uint8_t value) 803 void ym_data_write(ym2612_context * context, uint8_t value)
749 { 804 {
805 context->write_cycle = context->current_cycle;
806 context->busy_start = context->current_cycle + context->clock_inc;
807
750 if (context->selected_reg >= YM_REG_END) { 808 if (context->selected_reg >= YM_REG_END) {
751 return; 809 return;
752 } 810 }
753 if (context->selected_part) { 811 if (context->selected_part) {
754 if (context->selected_reg < YM_PART2_START) { 812 if (context->selected_reg < YM_PART2_START) {
755 return; 813 return;
814 }
815 if (context->vgm) {
816 vgm_ym2612_part2_write(context->vgm, context->current_cycle, context->selected_reg, value);
756 } 817 }
757 context->part2_regs[context->selected_reg - YM_PART2_START] = value; 818 context->part2_regs[context->selected_reg - YM_PART2_START] = value;
758 } else { 819 } else {
759 if (context->selected_reg < YM_PART1_START) { 820 if (context->selected_reg < YM_PART1_START) {
760 return; 821 return;
822 }
823 if (context->vgm) {
824 vgm_ym2612_part1_write(context->vgm, context->current_cycle, context->selected_reg, value);
761 } 825 }
762 context->part1_regs[context->selected_reg - YM_PART1_START] = value; 826 context->part1_regs[context->selected_reg - YM_PART1_START] = value;
763 } 827 }
764 dfprintf(debug_file, "write of %X to reg %X in part %d\n", value, context->selected_reg, context->selected_part+1); 828 dfprintf(debug_file, "write of %X to reg %X in part %d\n", value, context->selected_reg, context->selected_part+1);
765 if (context->selected_reg < 0x30) { 829 if (context->selected_reg < 0x30) {
771 /*if ((value & 0x8) && !context->lfo_enable) { 835 /*if ((value & 0x8) && !context->lfo_enable) {
772 printf("LFO Enabled, Freq: %d\n", value & 0x7); 836 printf("LFO Enabled, Freq: %d\n", value & 0x7);
773 }*/ 837 }*/
774 context->lfo_enable = value & 0x8; 838 context->lfo_enable = value & 0x8;
775 if (!context->lfo_enable) { 839 if (!context->lfo_enable) {
840 uint8_t old_pm_step = context->lfo_pm_step;
776 context->lfo_am_step = context->lfo_pm_step = 0; 841 context->lfo_am_step = context->lfo_pm_step = 0;
842 if (old_pm_step) {
843 for (int chan = 0; chan < NUM_CHANNELS; chan++)
844 {
845 if (context->channels[chan].pms) {
846 for (int op = chan * 4; op < (chan + 1) * 4; op++)
847 {
848 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
849 }
850 }
851 }
852 }
777 } 853 }
778 context->lfo_freq = value & 0x7; 854 context->lfo_freq = value & 0x7;
779 855
780 break; 856 break;
781 case REG_TIMERA_HIGH: 857 case REG_TIMERA_HIGH:
807 context->status &= ~BIT_STATUS_TIMERB; 883 context->status &= ~BIT_STATUS_TIMERB;
808 } 884 }
809 if (context->ch3_mode == CSM_MODE && (value & 0xC0) != CSM_MODE && context->csm_keyon) { 885 if (context->ch3_mode == CSM_MODE && (value & 0xC0) != CSM_MODE && context->csm_keyon) {
810 csm_keyoff(context); 886 csm_keyoff(context);
811 } 887 }
888 uint8_t old_mode = context->ch3_mode;
812 context->ch3_mode = value & 0xC0; 889 context->ch3_mode = value & 0xC0;
890 if (context->ch3_mode != old_mode) {
891 for (int op = 2 * 4; op < 3*4; op++)
892 {
893 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
894 }
895 }
813 break; 896 break;
814 } 897 }
815 case REG_KEY_ONOFF: { 898 case REG_KEY_ONOFF: {
816 uint8_t channel = value & 0x7; 899 uint8_t channel = value & 0x7;
817 if (channel != 3 && channel != 7) { 900 if (channel != 3 && channel != 7) {
859 switch (context->selected_reg & 0xF0) 942 switch (context->selected_reg & 0xF0)
860 { 943 {
861 case REG_DETUNE_MULT: 944 case REG_DETUNE_MULT:
862 operator->detune = value >> 4 & 0x7; 945 operator->detune = value >> 4 & 0x7;
863 operator->multiple = value & 0xF; 946 operator->multiple = value & 0xF;
947 operator->phase_inc = ym_calc_phase_inc(context, operator, op);
864 break; 948 break;
865 case REG_TOTAL_LEVEL: 949 case REG_TOTAL_LEVEL:
866 operator->total_level = (value & 0x7F) << 5; 950 operator->total_level = (value & 0x7F) << 5;
867 break; 951 break;
868 case REG_ATTACK_KS: 952 case REG_ATTACK_KS:
905 { 989 {
906 case REG_FNUM_LOW: 990 case REG_FNUM_LOW:
907 context->channels[channel].block = context->channels[channel].block_fnum_latch >> 3 & 0x7; 991 context->channels[channel].block = context->channels[channel].block_fnum_latch >> 3 & 0x7;
908 context->channels[channel].fnum = (context->channels[channel].block_fnum_latch & 0x7) << 8 | value; 992 context->channels[channel].fnum = (context->channels[channel].block_fnum_latch & 0x7) << 8 | value;
909 context->channels[channel].keycode = context->channels[channel].block << 2 | fnum_to_keycode[context->channels[channel].fnum >> 7]; 993 context->channels[channel].keycode = context->channels[channel].block << 2 | fnum_to_keycode[context->channels[channel].fnum >> 7];
994 for (int op = channel * 4; op < (channel + 1) * 4; op++)
995 {
996 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
997 }
910 break; 998 break;
911 case REG_BLOCK_FNUM_H:{ 999 case REG_BLOCK_FNUM_H:{
912 context->channels[channel].block_fnum_latch = value; 1000 context->channels[channel].block_fnum_latch = value;
913 break; 1001 break;
914 } 1002 }
915 case REG_FNUM_LOW_CH3: 1003 case REG_FNUM_LOW_CH3:
916 if (channel < 3) { 1004 if (channel < 3) {
917 context->ch3_supp[channel].block = context->ch3_supp[channel].block_fnum_latch >> 3 & 0x7; 1005 context->ch3_supp[channel].block = context->ch3_supp[channel].block_fnum_latch >> 3 & 0x7;
918 context->ch3_supp[channel].fnum = (context->ch3_supp[channel].block_fnum_latch & 0x7) << 8 | value; 1006 context->ch3_supp[channel].fnum = (context->ch3_supp[channel].block_fnum_latch & 0x7) << 8 | value;
919 context->ch3_supp[channel].keycode = context->ch3_supp[channel].block << 2 | fnum_to_keycode[context->ch3_supp[channel].fnum >> 7]; 1007 context->ch3_supp[channel].keycode = context->ch3_supp[channel].block << 2 | fnum_to_keycode[context->ch3_supp[channel].fnum >> 7];
1008 if (context->ch3_mode) {
1009 int op = 2 * 4 + (channel < 2 ? (channel ^ 1) : channel);
1010 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
1011 }
920 } 1012 }
921 break; 1013 break;
922 case REG_BLOCK_FN_CH3: 1014 case REG_BLOCK_FN_CH3:
923 if (channel < 3) { 1015 if (channel < 3) {
924 context->ch3_supp[channel].block_fnum_latch = value; 1016 context->ch3_supp[channel].block_fnum_latch = value;
1040 break; 1132 break;
1041 } 1133 }
1042 context->channels[channel].feedback = value >> 3 & 0x7; 1134 context->channels[channel].feedback = value >> 3 & 0x7;
1043 //printf("Algorithm %d, feedback %d for channel %d\n", value & 0x7, value >> 3 & 0x7, channel); 1135 //printf("Algorithm %d, feedback %d for channel %d\n", value & 0x7, value >> 3 & 0x7, channel);
1044 break; 1136 break;
1045 case REG_LR_AMS_PMS: 1137 case REG_LR_AMS_PMS: {
1138 uint8_t old_pms = context->channels[channel].pms;
1046 context->channels[channel].pms = (value & 0x7) * 32; 1139 context->channels[channel].pms = (value & 0x7) * 32;
1047 context->channels[channel].ams = value >> 4 & 0x3; 1140 context->channels[channel].ams = value >> 4 & 0x3;
1048 context->channels[channel].lr = value & 0xC0; 1141 context->channels[channel].lr = value & 0xC0;
1142 if (old_pms != context->channels[channel].pms) {
1143 for (int op = channel * 4; op < (channel + 1) * 4; op++)
1144 {
1145 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op);
1146 }
1147 }
1049 //printf("Write of %X to LR_AMS_PMS reg for channel %d\n", value, channel); 1148 //printf("Write of %X to LR_AMS_PMS reg for channel %d\n", value, channel);
1050 break; 1149 break;
1051 } 1150 }
1052 } 1151 }
1053 } 1152 }
1054 1153 }
1055 context->write_cycle = context->current_cycle; 1154 }
1056 context->busy_cycles = context->selected_reg < 0xA0 ? BUSY_CYCLES_DATA_LOW : BUSY_CYCLES_DATA_HIGH; 1155
1057 context->status |= 0x80; 1156 uint8_t ym_read_status(ym2612_context * context, uint32_t cycle, uint32_t port)
1058 } 1157 {
1059 1158 uint8_t status;
1060 uint8_t ym_read_status(ym2612_context * context) 1159 port &= context->status_address_mask;
1061 { 1160 if (port) {
1062 return context->status; 1161 if (context->last_status_cycle != CYCLE_NEVER && cycle - context->last_status_cycle > context->invalid_status_decay) {
1162 context->last_status = 0;
1163 }
1164 status = context->last_status;
1165 } else {
1166 status = context->status;
1167 if (cycle >= context->busy_start && cycle < context->busy_start + context->busy_cycles) {
1168 status |= 0x80;
1169 }
1170 context->last_status = status;
1171 context->last_status_cycle = cycle;
1172 }
1173 return status;
1174
1063 } 1175 }
1064 1176
1065 void ym_print_channel_info(ym2612_context *context, int channel) 1177 void ym_print_channel_info(ym2612_context *context, int channel)
1066 { 1178 {
1067 ym_channel *chan = context->channels + channel; 1179 ym_channel *chan = context->channels + channel;
1169 save_int8(buf, context->status); 1281 save_int8(buf, context->status);
1170 save_int8(buf, context->selected_reg); 1282 save_int8(buf, context->selected_reg);
1171 save_int8(buf, context->selected_part); 1283 save_int8(buf, context->selected_part);
1172 save_int32(buf, context->current_cycle); 1284 save_int32(buf, context->current_cycle);
1173 save_int32(buf, context->write_cycle); 1285 save_int32(buf, context->write_cycle);
1174 save_int32(buf, context->busy_cycles); 1286 save_int32(buf, context->busy_start);
1287 save_int32(buf, context->last_status_cycle);
1288 save_int32(buf, context->invalid_status_decay);
1289 save_int8(buf, context->last_status);
1175 } 1290 }
1176 1291
1177 void ym_deserialize(deserialize_buffer *buf, void *vcontext) 1292 void ym_deserialize(deserialize_buffer *buf, void *vcontext)
1178 { 1293 {
1179 ym2612_context *context = vcontext; 1294 ym2612_context *context = vcontext;
1244 context->status = load_int8(buf); 1359 context->status = load_int8(buf);
1245 context->selected_reg = load_int8(buf); 1360 context->selected_reg = load_int8(buf);
1246 context->selected_part = load_int8(buf); 1361 context->selected_part = load_int8(buf);
1247 context->current_cycle = load_int32(buf); 1362 context->current_cycle = load_int32(buf);
1248 context->write_cycle = load_int32(buf); 1363 context->write_cycle = load_int32(buf);
1249 context->busy_cycles = load_int32(buf); 1364 context->busy_start = load_int32(buf);
1250 } 1365 if (buf->size > buf->cur_pos) {
1366 context->last_status_cycle = load_int32(buf);
1367 context->invalid_status_decay = load_int32(buf);
1368 context->last_status = load_int8(buf);
1369 } else {
1370 context->last_status = context->status;
1371 context->last_status_cycle = context->write_cycle;
1372 }
1373 }