Mercurial > repos > blastem
comparison ym2612.c @ 1842:49f65d240299 mame_interp
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 14 Apr 2019 23:38:02 -0700 |
parents | ce6881d64eef |
children | 43a6cee4fd00 |
comparison
equal
deleted
inserted
replaced
1787:0c6d07f91346 | 1842:49f65d240299 |
---|---|
254 } | 254 } |
255 } | 255 } |
256 } | 256 } |
257 } | 257 } |
258 ym_reset(context); | 258 ym_reset(context); |
259 ym_enable_zero_offset(context, 1); | |
259 } | 260 } |
260 | 261 |
261 void ym_free(ym2612_context *context) | 262 void ym_free(ym2612_context *context) |
262 { | 263 { |
263 render_free_source(context->audio); | 264 render_free_source(context->audio); |
265 ym_finalize_log(); | 266 ym_finalize_log(); |
266 } | 267 } |
267 free(context); | 268 free(context); |
268 } | 269 } |
269 | 270 |
270 #define YM_VOLUME_MULTIPLIER 2 | 271 void ym_enable_zero_offset(ym2612_context *context, uint8_t enabled) |
271 #define YM_VOLUME_DIVIDER 3 | 272 { |
273 if (enabled) { | |
274 context->zero_offset = 0x70; | |
275 context->volume_mult = 79; | |
276 context->volume_div = 120; | |
277 } else { | |
278 context->zero_offset = 0; | |
279 context->volume_mult = 2; | |
280 context->volume_div = 3; | |
281 } | |
282 } | |
272 #define YM_MOD_SHIFT 1 | 283 #define YM_MOD_SHIFT 1 |
273 | 284 |
274 #define CSM_MODE 0x80 | 285 #define CSM_MODE 0x80 |
275 | 286 |
276 #define SSG_ENABLE 8 | 287 #define SSG_ENABLE 8 |
468 int16_t mod = 0; | 479 int16_t mod = 0; |
469 if (op & 3) { | 480 if (op & 3) { |
470 if (operator->mod_src[0]) { | 481 if (operator->mod_src[0]) { |
471 mod = *operator->mod_src[0]; | 482 mod = *operator->mod_src[0]; |
472 if (operator->mod_src[1]) { | 483 if (operator->mod_src[1]) { |
473 mod += * | 484 mod += *operator->mod_src[1]; |
474 operator->mod_src[1]; | |
475 } | 485 } |
476 mod >>= YM_MOD_SHIFT; | 486 mod >>= YM_MOD_SHIFT; |
477 } | 487 } |
478 } else { | 488 } else { |
479 if (chan->feedback) { | 489 if (chan->feedback) { |
506 } | 516 } |
507 env += operator->total_level; | 517 env += operator->total_level; |
508 if (operator->am) { | 518 if (operator->am) { |
509 uint16_t base_am = (context->lfo_am_step & 0x80 ? context->lfo_am_step : ~context->lfo_am_step) & 0x7E; | 519 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) { | 520 if (ams_shift[chan->ams] >= 0) { |
511 env += base_am >> ams_shift[chan->ams]; | 521 env += (base_am >> ams_shift[chan->ams]) & MAX_ENVELOPE; |
512 } else { | 522 } else { |
513 env += base_am << (-ams_shift[chan->ams]); | 523 env += base_am << (-ams_shift[chan->ams]); |
514 } | 524 } |
515 } | 525 } |
516 if (env > MAX_ENVELOPE) { | 526 if (env > MAX_ENVELOPE) { |
527 if (phase & 0x200) { | 537 if (phase & 0x200) { |
528 output = -output; | 538 output = -output; |
529 } | 539 } |
530 if (op % 4 == 0) { | 540 if (op % 4 == 0) { |
531 chan->op1_old = operator->output; | 541 chan->op1_old = operator->output; |
542 } else if (op % 4 == 2) { | |
543 chan->op2_old = operator->output; | |
532 } | 544 } |
533 operator->output = output; | 545 operator->output = output; |
534 //Update the channel output if we've updated all operators | 546 //Update the channel output if we've updated all operators |
535 if (op % 4 == 3) { | 547 if (op % 4 == 3) { |
536 if (chan->algorithm < 4) { | 548 if (chan->algorithm < 4) { |
547 if (first_key_on) { | 559 if (first_key_on) { |
548 int16_t value = context->channels[channel].output & 0x3FE0; | 560 int16_t value = context->channels[channel].output & 0x3FE0; |
549 if (value & 0x2000) { | 561 if (value & 0x2000) { |
550 value |= 0xC000; | 562 value |= 0xC000; |
551 } | 563 } |
552 dfprintf(debug_file, "channel %d output: %d\n", channel, (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER); | 564 dfprintf(debug_file, "channel %d output: %d\n", channel, (value * context->volume_mult) / context->volume_div); |
553 } | 565 } |
554 } | 566 } |
555 //puts("operator update done"); | 567 //puts("operator update done"); |
556 } | 568 } |
557 context->current_op++; | 569 context->current_op++; |
569 value &= 0x3FE0; | 581 value &= 0x3FE0; |
570 if (value & 0x2000) { | 582 if (value & 0x2000) { |
571 value |= 0xC000; | 583 value |= 0xC000; |
572 } | 584 } |
573 } | 585 } |
586 if (value >= 0) { | |
587 value += context->zero_offset; | |
588 } else { | |
589 value -= context->zero_offset; | |
590 } | |
574 if (context->channels[i].logfile) { | 591 if (context->channels[i].logfile) { |
575 fwrite(&value, sizeof(value), 1, context->channels[i].logfile); | 592 fwrite(&value, sizeof(value), 1, context->channels[i].logfile); |
576 } | 593 } |
577 if (context->channels[i].lr & 0x80) { | 594 if (context->channels[i].lr & 0x80) { |
578 left += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER; | 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 } | |
579 } | 602 } |
580 if (context->channels[i].lr & 0x40) { | 603 if (context->channels[i].lr & 0x40) { |
581 right += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER; | 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 } | |
582 } | 611 } |
583 } | 612 } |
584 render_put_stereo_sample(context->audio, left, right); | 613 render_put_stereo_sample(context->audio, left, right); |
585 } | 614 } |
586 | 615 |
669 index ^= 1; | 698 index ^= 1; |
670 } | 699 } |
671 inc = context->ch3_supp[index].fnum; | 700 inc = context->ch3_supp[index].fnum; |
672 if (channel->pms) { | 701 if (channel->pms) { |
673 inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step]; | 702 inc = inc * 2 + lfo_pm_table[(inc & 0x7F0) * 16 + channel->pms + context->lfo_pm_step]; |
703 inc &= 0xFFF; | |
674 } | 704 } |
675 if (!context->ch3_supp[index].block) { | 705 if (!context->ch3_supp[index].block) { |
676 inc >>= 1; | 706 inc >>= 1; |
677 } else { | 707 } else { |
678 inc <<= (context->ch3_supp[index].block-1); | 708 inc <<= (context->ch3_supp[index].block-1); |
681 detune = detune_table[context->ch3_supp[index].keycode][operator->detune & 0x3]; | 711 detune = detune_table[context->ch3_supp[index].keycode][operator->detune & 0x3]; |
682 } else { | 712 } else { |
683 inc = channel->fnum; | 713 inc = channel->fnum; |
684 if (channel->pms) { | 714 if (channel->pms) { |
685 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; | |
686 } | 717 } |
687 if (!channel->block) { | 718 if (!channel->block) { |
688 inc >>= 1; | 719 inc >>= 1; |
689 } else { | 720 } else { |
690 inc <<= (channel->block-1); | 721 inc <<= (channel->block-1); |
837 case REG_ATTACK_KS: | 868 case REG_ATTACK_KS: |
838 operator->key_scaling = 3 - (value >> 6); | 869 operator->key_scaling = 3 - (value >> 6); |
839 operator->rates[PHASE_ATTACK] = value & 0x1F; | 870 operator->rates[PHASE_ATTACK] = value & 0x1F; |
840 break; | 871 break; |
841 case REG_DECAY_AM: | 872 case REG_DECAY_AM: |
842 //TODO: AM flag for LFO | |
843 operator->am = value & 0x80; | 873 operator->am = value & 0x80; |
844 operator->rates[PHASE_DECAY] = value & 0x1F; | 874 operator->rates[PHASE_DECAY] = value & 0x1F; |
845 break; | 875 break; |
846 case REG_SUSTAIN_RATE: | 876 case REG_SUSTAIN_RATE: |
847 operator->rates[PHASE_SUSTAIN] = value & 0x1F; | 877 operator->rates[PHASE_SUSTAIN] = value & 0x1F; |
898 context->channels[channel].algorithm = value & 0x7; | 928 context->channels[channel].algorithm = value & 0x7; |
899 switch (context->channels[channel].algorithm) | 929 switch (context->channels[channel].algorithm) |
900 { | 930 { |
901 case 0: | 931 case 0: |
902 //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 | |
903 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; |
904 context->operators[channel*4+1].mod_src[1] = NULL; | 936 context->operators[channel*4+1].mod_src[1] = NULL; |
905 | 937 |
906 //operator 2 modulated by operator 1 | 938 //operator 2 modulated by operator 1 |
907 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; |
910 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; |
911 context->operators[channel*4+3].mod_src[1] = NULL; | 943 context->operators[channel*4+3].mod_src[1] = NULL; |
912 break; | 944 break; |
913 case 1: | 945 case 1: |
914 //operator 3 modulated by operator 1+2 | 946 //operator 3 modulated by operator 1+2 |
915 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 | |
916 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; |
917 | 953 |
918 //operator 2 unmodulated | 954 //operator 2 unmodulated |
919 context->operators[channel*4+2].mod_src[0] = NULL; | 955 context->operators[channel*4+2].mod_src[0] = NULL; |
920 | 956 |
922 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; |
923 context->operators[channel*4+3].mod_src[1] = NULL; | 959 context->operators[channel*4+3].mod_src[1] = NULL; |
924 break; | 960 break; |
925 case 2: | 961 case 2: |
926 //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 | |
927 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; |
928 context->operators[channel*4+1].mod_src[1] = NULL; | 966 context->operators[channel*4+1].mod_src[1] = NULL; |
929 | 967 |
930 //operator 2 unmodulated | 968 //operator 2 unmodulated |
931 context->operators[channel*4+2].mod_src[0] = NULL; | 969 context->operators[channel*4+2].mod_src[0] = NULL; |
932 | 970 |
933 //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 | |
934 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; |
935 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; |
936 break; | 976 break; |
937 case 3: | 977 case 3: |
938 //operator 3 unmodulated | 978 //operator 3 unmodulated |
941 | 981 |
942 //operator 2 modulated by operator 1 | 982 //operator 2 modulated by operator 1 |
943 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; |
944 | 984 |
945 //operator 4 modulated by operator 2+3 | 985 //operator 4 modulated by operator 2+3 |
946 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; | |
947 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; |
948 break; | 990 break; |
949 case 4: | 991 case 4: |
950 //operator 3 unmodulated | 992 //operator 3 unmodulated |
951 context->operators[channel*4+1].mod_src[0] = NULL; | 993 context->operators[channel*4+1].mod_src[0] = NULL; |
958 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; |
959 context->operators[channel*4+3].mod_src[1] = NULL; | 1001 context->operators[channel*4+3].mod_src[1] = NULL; |
960 break; | 1002 break; |
961 case 5: | 1003 case 5: |
962 //operator 3 modulated by operator 1 | 1004 //operator 3 modulated by operator 1 |
963 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; | |
964 context->operators[channel*4+1].mod_src[1] = NULL; | 1008 context->operators[channel*4+1].mod_src[1] = NULL; |
965 | 1009 |
966 //operator 2 modulated by operator 1 | 1010 //operator 2 modulated by operator 1 |
967 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; |
968 | 1012 |
969 //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 | |
970 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; |
971 context->operators[channel*4+3].mod_src[1] = NULL; | 1017 context->operators[channel*4+3].mod_src[1] = NULL; |
972 break; | 1018 break; |
973 case 6: | 1019 case 6: |
974 //operator 3 unmodulated | 1020 //operator 3 unmodulated |