Mercurial > repos > blastem
comparison ym2612.c @ 1808:ce6881d64eef
Operator results should be delayed by one sample when used as a modulator in some cases based on relative execution time and pipeline length
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 27 Mar 2019 22:04:54 -0700 |
parents | a851d36e24bb |
children | 43a6cee4fd00 |
comparison
equal
deleted
inserted
replaced
1807:a218c253fcb3 | 1808:ce6881d64eef |
---|---|
479 int16_t mod = 0; | 479 int16_t mod = 0; |
480 if (op & 3) { | 480 if (op & 3) { |
481 if (operator->mod_src[0]) { | 481 if (operator->mod_src[0]) { |
482 mod = *operator->mod_src[0]; | 482 mod = *operator->mod_src[0]; |
483 if (operator->mod_src[1]) { | 483 if (operator->mod_src[1]) { |
484 mod += * | 484 mod += *operator->mod_src[1]; |
485 operator->mod_src[1]; | |
486 } | 485 } |
487 mod >>= YM_MOD_SHIFT; | 486 mod >>= YM_MOD_SHIFT; |
488 } | 487 } |
489 } else { | 488 } else { |
490 if (chan->feedback) { | 489 if (chan->feedback) { |
538 if (phase & 0x200) { | 537 if (phase & 0x200) { |
539 output = -output; | 538 output = -output; |
540 } | 539 } |
541 if (op % 4 == 0) { | 540 if (op % 4 == 0) { |
542 chan->op1_old = operator->output; | 541 chan->op1_old = operator->output; |
542 } else if (op % 4 == 2) { | |
543 chan->op2_old = operator->output; | |
543 } | 544 } |
544 operator->output = output; | 545 operator->output = output; |
545 //Update the channel output if we've updated all operators | 546 //Update the channel output if we've updated all operators |
546 if (op % 4 == 3) { | 547 if (op % 4 == 3) { |
547 if (chan->algorithm < 4) { | 548 if (chan->algorithm < 4) { |
710 detune = detune_table[context->ch3_supp[index].keycode][operator->detune & 0x3]; | 711 detune = detune_table[context->ch3_supp[index].keycode][operator->detune & 0x3]; |
711 } else { | 712 } else { |
712 inc = channel->fnum; | 713 inc = channel->fnum; |
713 if (channel->pms) { | 714 if (channel->pms) { |
714 inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step]; | 715 inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step]; |
716 inc &= 0xFFF; | |
715 } | 717 } |
716 if (!channel->block) { | 718 if (!channel->block) { |
717 inc >>= 1; | 719 inc >>= 1; |
718 } else { | 720 } else { |
719 inc <<= (channel->block-1); | 721 inc <<= (channel->block-1); |
926 context->channels[channel].algorithm = value & 0x7; | 928 context->channels[channel].algorithm = value & 0x7; |
927 switch (context->channels[channel].algorithm) | 929 switch (context->channels[channel].algorithm) |
928 { | 930 { |
929 case 0: | 931 case 0: |
930 //operator 3 modulated by operator 2 | 932 //operator 3 modulated by operator 2 |
933 //this uses a special op2 result reg on HW, but that reg will have the most recent | |
934 //result from op2 when op3 starts executing | |
931 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output; | 935 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output; |
932 context->operators[channel*4+1].mod_src[1] = NULL; | 936 context->operators[channel*4+1].mod_src[1] = NULL; |
933 | 937 |
934 //operator 2 modulated by operator 1 | 938 //operator 2 modulated by operator 1 |
935 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; | 939 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; |
938 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output; | 942 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output; |
939 context->operators[channel*4+3].mod_src[1] = NULL; | 943 context->operators[channel*4+3].mod_src[1] = NULL; |
940 break; | 944 break; |
941 case 1: | 945 case 1: |
942 //operator 3 modulated by operator 1+2 | 946 //operator 3 modulated by operator 1+2 |
943 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+0].output; | 947 //op1 starts executing before this, but due to pipeline length the most current result is |
948 //not available and instead the previous result is used | |
949 context->operators[channel*4+1].mod_src[0] = &context->channels[channel].op1_old; | |
950 //this uses a special op2 result reg on HW, but that reg will have the most recent | |
951 //result from op2 when op3 starts executing | |
944 context->operators[channel*4+1].mod_src[1] = &context->operators[channel*4+2].output; | 952 context->operators[channel*4+1].mod_src[1] = &context->operators[channel*4+2].output; |
945 | 953 |
946 //operator 2 unmodulated | 954 //operator 2 unmodulated |
947 context->operators[channel*4+2].mod_src[0] = NULL; | 955 context->operators[channel*4+2].mod_src[0] = NULL; |
948 | 956 |
950 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output; | 958 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output; |
951 context->operators[channel*4+3].mod_src[1] = NULL; | 959 context->operators[channel*4+3].mod_src[1] = NULL; |
952 break; | 960 break; |
953 case 2: | 961 case 2: |
954 //operator 3 modulated by operator 2 | 962 //operator 3 modulated by operator 2 |
963 //this uses a special op2 result reg on HW, but that reg will have the most recent | |
964 //result from op2 when op3 starts executing | |
955 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output; | 965 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+2].output; |
956 context->operators[channel*4+1].mod_src[1] = NULL; | 966 context->operators[channel*4+1].mod_src[1] = NULL; |
957 | 967 |
958 //operator 2 unmodulated | 968 //operator 2 unmodulated |
959 context->operators[channel*4+2].mod_src[0] = NULL; | 969 context->operators[channel*4+2].mod_src[0] = NULL; |
960 | 970 |
961 //operator 4 modulated by operator 1+3 | 971 //operator 4 modulated by operator 1+3 |
972 //this uses a special op1 result reg on HW, but that reg will have the most recent | |
973 //result from op1 when op4 starts executing | |
962 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output; | 974 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output; |
963 context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output; | 975 context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output; |
964 break; | 976 break; |
965 case 3: | 977 case 3: |
966 //operator 3 unmodulated | 978 //operator 3 unmodulated |
969 | 981 |
970 //operator 2 modulated by operator 1 | 982 //operator 2 modulated by operator 1 |
971 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; | 983 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; |
972 | 984 |
973 //operator 4 modulated by operator 2+3 | 985 //operator 4 modulated by operator 2+3 |
974 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+2].output; | 986 //op2 starts executing before this, but due to pipeline length the most current result is |
987 //not available and instead the previous result is used | |
988 context->operators[channel*4+3].mod_src[0] = &context->channels[channel].op2_old; | |
975 context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output; | 989 context->operators[channel*4+3].mod_src[1] = &context->operators[channel*4+1].output; |
976 break; | 990 break; |
977 case 4: | 991 case 4: |
978 //operator 3 unmodulated | 992 //operator 3 unmodulated |
979 context->operators[channel*4+1].mod_src[0] = NULL; | 993 context->operators[channel*4+1].mod_src[0] = NULL; |
986 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output; | 1000 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+1].output; |
987 context->operators[channel*4+3].mod_src[1] = NULL; | 1001 context->operators[channel*4+3].mod_src[1] = NULL; |
988 break; | 1002 break; |
989 case 5: | 1003 case 5: |
990 //operator 3 modulated by operator 1 | 1004 //operator 3 modulated by operator 1 |
991 context->operators[channel*4+1].mod_src[0] = &context->operators[channel*4+0].output; | 1005 //op1 starts executing before this, but due to pipeline length the most current result is |
1006 //not available and instead the previous result is used | |
1007 context->operators[channel*4+1].mod_src[0] = &context->channels[channel].op1_old; | |
992 context->operators[channel*4+1].mod_src[1] = NULL; | 1008 context->operators[channel*4+1].mod_src[1] = NULL; |
993 | 1009 |
994 //operator 2 modulated by operator 1 | 1010 //operator 2 modulated by operator 1 |
995 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; | 1011 context->operators[channel*4+2].mod_src[0] = &context->operators[channel*4+0].output; |
996 | 1012 |
997 //operator 4 modulated by operator 1 | 1013 //operator 4 modulated by operator 1 |
1014 //this uses a special op1 result reg on HW, but that reg will have the most recent | |
1015 //result from op1 when op4 starts executing | |
998 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output; | 1016 context->operators[channel*4+3].mod_src[0] = &context->operators[channel*4+0].output; |
999 context->operators[channel*4+3].mod_src[1] = NULL; | 1017 context->operators[channel*4+3].mod_src[1] = NULL; |
1000 break; | 1018 break; |
1001 case 6: | 1019 case 6: |
1002 //operator 3 unmodulated | 1020 //operator 3 unmodulated |