# HG changeset patch # User Michael Pavone # Date 1553749494 25200 # Node ID ce6881d64eef5429757e40f1e13bf3e6d2a137ce # Parent a218c253fcb38f39d57eac06aac07ac7edd6dbd4 Operator results should be delayed by one sample when used as a modulator in some cases based on relative execution time and pipeline length diff -r a218c253fcb3 -r ce6881d64eef ym2612.c --- a/ym2612.c Tue Mar 26 23:55:41 2019 -0700 +++ b/ym2612.c Wed Mar 27 22:04:54 2019 -0700 @@ -481,8 +481,7 @@ if (operator->mod_src[0]) { mod = *operator->mod_src[0]; if (operator->mod_src[1]) { - mod += * - operator->mod_src[1]; + mod += *operator->mod_src[1]; } mod >>= YM_MOD_SHIFT; } @@ -540,6 +539,8 @@ } if (op % 4 == 0) { chan->op1_old = operator->output; + } else if (op % 4 == 2) { + chan->op2_old = operator->output; } operator->output = output; //Update the channel output if we've updated all operators @@ -712,6 +713,7 @@ inc = channel->fnum; if (channel->pms) { inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step]; + inc &= 0xFFF; } if (!channel->block) { inc >>= 1; @@ -928,6 +930,8 @@ { case 0: //operator 3 modulated by operator 2 + //this uses a special op2 result reg on HW, but that reg will have the most recent + //result from op2 when op3 starts executing context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output; context->operators[channel*4+1].mod_src[1] = NULL; @@ -940,7 +944,11 @@ break; case 1: //operator 3 modulated by operator 1+2 - context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+0].output; + //op1 starts executing before this, but due to pipeline length the most current result is + //not available and instead the previous result is used + context->operators[channel*4+1].mod_src[0] = &context->channels[channel].op1_old; + //this uses a special op2 result reg on HW, but that reg will have the most recent + //result from op2 when op3 starts executing context->operators[channel*4+1].mod_src[1] = &context->operators[channel*4+2].output; //operator 2 unmodulated @@ -952,6 +960,8 @@ break; case 2: //operator 3 modulated by operator 2 + //this uses a special op2 result reg on HW, but that reg will have the most recent + //result from op2 when op3 starts executing context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output; context->operators[channel*4+1].mod_src[1] = NULL; @@ -959,6 +969,8 @@ context->operators[channel*4+2].mod_src[0] = NULL; //operator 4 modulated by operator 1+3 + //this uses a special op1 result reg on HW, but that reg will have the most recent + //result from op1 when op4 starts executing context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output; context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output; break; @@ -971,7 +983,9 @@ context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; //operator 4 modulated by operator 2+3 - context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+2].output; + //op2 starts executing before this, but due to pipeline length the most current result is + //not available and instead the previous result is used + context->operators[channel*4+3].mod_src[0] = &context->channels[channel].op2_old; context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output; break; case 4: @@ -988,13 +1002,17 @@ break; case 5: //operator 3 modulated by operator 1 - context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+0].output; + //op1 starts executing before this, but due to pipeline length the most current result is + //not available and instead the previous result is used + context->operators[channel*4+1].mod_src[0] = &context->channels[channel].op1_old; context->operators[channel*4+1].mod_src[1] = NULL; //operator 2 modulated by operator 1 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; //operator 4 modulated by operator 1 + //this uses a special op1 result reg on HW, but that reg will have the most recent + //result from op1 when op4 starts executing context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output; context->operators[channel*4+3].mod_src[1] = NULL; break; diff -r a218c253fcb3 -r ce6881d64eef ym2612.h --- a/ym2612.h Tue Mar 26 23:55:41 2019 -0700 +++ b/ym2612.h Wed Mar 27 22:04:54 2019 -0700 @@ -39,6 +39,7 @@ uint16_t fnum; int16_t output; int16_t op1_old; + int16_t op2_old; uint8_t block_fnum_latch; uint8_t block; uint8_t keycode;