Mercurial > repos > blastem
comparison ym2612.c @ 1880:e77f7a7c79a5
Cache operator phase increment for a small perf improvement
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 07 Sep 2019 22:18:09 -0700 |
parents | 43a6cee4fd00 |
children | 32a3aa7b4a45 |
comparison
equal
deleted
inserted
replaced
1879:43a6cee4fd00 | 1880:e77f7a7c79a5 |
---|---|
386 context->lfo_counter--; | 386 context->lfo_counter--; |
387 } else { | 387 } else { |
388 context->lfo_counter = lfo_timer_values[context->lfo_freq]; | 388 context->lfo_counter = lfo_timer_values[context->lfo_freq]; |
389 context->lfo_am_step += 2; | 389 context->lfo_am_step += 2; |
390 context->lfo_am_step &= 0xFE; | 390 context->lfo_am_step &= 0xFE; |
391 uint8_t old_pm_step = context->lfo_pm_step; | |
391 context->lfo_pm_step = context->lfo_am_step / 8; | 392 context->lfo_pm_step = context->lfo_am_step / 8; |
393 if (context->lfo_pm_step != old_pm_step) { | |
394 for (int chan = 0; chan < NUM_CHANNELS; chan++) | |
395 { | |
396 if (context->channels[chan].pms) { | |
397 for (int op = chan * 4; op < (chan + 1) * 4; op++) | |
398 { | |
399 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op); | |
400 } | |
401 } | |
402 } | |
403 } | |
392 } | 404 } |
393 } | 405 } |
394 } | 406 } |
395 | 407 |
396 void ym_run_envelope(ym2612_context *context, ym_channel *channel, ym_operator *operator) | 408 void ym_run_envelope(ym2612_context *context, ym_channel *channel, ym_operator *operator) |
450 if (channel != 5 || !context->dac_enable) { | 462 if (channel != 5 || !context->dac_enable) { |
451 //printf("updating operator %d of channel %d\n", op, channel); | 463 //printf("updating operator %d of channel %d\n", op, channel); |
452 ym_operator * operator = context->operators + op; | 464 ym_operator * operator = context->operators + op; |
453 ym_channel * chan = context->channels + channel; | 465 ym_channel * chan = context->channels + channel; |
454 uint16_t phase = operator->phase_counter >> 10 & 0x3FF; | 466 uint16_t phase = operator->phase_counter >> 10 & 0x3FF; |
455 operator->phase_counter += ym_calc_phase_inc(context, operator, op); | 467 operator->phase_counter += operator->phase_inc;//ym_calc_phase_inc(context, operator, op); |
456 int16_t mod = 0; | 468 int16_t mod = 0; |
457 if (op & 3) { | 469 if (op & 3) { |
458 if (operator->mod_src[0]) { | 470 if (operator->mod_src[0]) { |
459 mod = *operator->mod_src[0]; | 471 mod = *operator->mod_src[0]; |
460 if (operator->mod_src[1]) { | 472 if (operator->mod_src[1]) { |
780 /*if ((value & 0x8) && !context->lfo_enable) { | 792 /*if ((value & 0x8) && !context->lfo_enable) { |
781 printf("LFO Enabled, Freq: %d\n", value & 0x7); | 793 printf("LFO Enabled, Freq: %d\n", value & 0x7); |
782 }*/ | 794 }*/ |
783 context->lfo_enable = value & 0x8; | 795 context->lfo_enable = value & 0x8; |
784 if (!context->lfo_enable) { | 796 if (!context->lfo_enable) { |
797 uint8_t old_pm_step = context->lfo_pm_step; | |
785 context->lfo_am_step = context->lfo_pm_step = 0; | 798 context->lfo_am_step = context->lfo_pm_step = 0; |
799 if (old_pm_step) { | |
800 for (int chan = 0; chan < NUM_CHANNELS; chan++) | |
801 { | |
802 if (context->channels[chan].pms) { | |
803 for (int op = chan * 4; op < (chan + 1) * 4; op++) | |
804 { | |
805 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op); | |
806 } | |
807 } | |
808 } | |
809 } | |
786 } | 810 } |
787 context->lfo_freq = value & 0x7; | 811 context->lfo_freq = value & 0x7; |
788 | 812 |
789 break; | 813 break; |
790 case REG_TIMERA_HIGH: | 814 case REG_TIMERA_HIGH: |
816 context->status &= ~BIT_STATUS_TIMERB; | 840 context->status &= ~BIT_STATUS_TIMERB; |
817 } | 841 } |
818 if (context->ch3_mode == CSM_MODE && (value & 0xC0) != CSM_MODE && context->csm_keyon) { | 842 if (context->ch3_mode == CSM_MODE && (value & 0xC0) != CSM_MODE && context->csm_keyon) { |
819 csm_keyoff(context); | 843 csm_keyoff(context); |
820 } | 844 } |
845 uint8_t old_mode = context->ch3_mode; | |
821 context->ch3_mode = value & 0xC0; | 846 context->ch3_mode = value & 0xC0; |
847 if (context->ch3_mode != old_mode) { | |
848 for (int op = 2 * 4; op < 3*4; op++) | |
849 { | |
850 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op); | |
851 } | |
852 } | |
822 break; | 853 break; |
823 } | 854 } |
824 case REG_KEY_ONOFF: { | 855 case REG_KEY_ONOFF: { |
825 uint8_t channel = value & 0x7; | 856 uint8_t channel = value & 0x7; |
826 if (channel != 3 && channel != 7) { | 857 if (channel != 3 && channel != 7) { |
868 switch (context->selected_reg & 0xF0) | 899 switch (context->selected_reg & 0xF0) |
869 { | 900 { |
870 case REG_DETUNE_MULT: | 901 case REG_DETUNE_MULT: |
871 operator->detune = value >> 4 & 0x7; | 902 operator->detune = value >> 4 & 0x7; |
872 operator->multiple = value & 0xF; | 903 operator->multiple = value & 0xF; |
904 operator->phase_inc = ym_calc_phase_inc(context, operator, op); | |
873 break; | 905 break; |
874 case REG_TOTAL_LEVEL: | 906 case REG_TOTAL_LEVEL: |
875 operator->total_level = (value & 0x7F) << 5; | 907 operator->total_level = (value & 0x7F) << 5; |
876 break; | 908 break; |
877 case REG_ATTACK_KS: | 909 case REG_ATTACK_KS: |
914 { | 946 { |
915 case REG_FNUM_LOW: | 947 case REG_FNUM_LOW: |
916 context->channels[channel].block = context->channels[channel].block_fnum_latch >> 3 & 0x7; | 948 context->channels[channel].block = context->channels[channel].block_fnum_latch >> 3 & 0x7; |
917 context->channels[channel].fnum = (context->channels[channel].block_fnum_latch & 0x7) << 8 | value; | 949 context->channels[channel].fnum = (context->channels[channel].block_fnum_latch & 0x7) << 8 | value; |
918 context->channels[channel].keycode = context->channels[channel].block << 2 | fnum_to_keycode[context->channels[channel].fnum >> 7]; | 950 context->channels[channel].keycode = context->channels[channel].block << 2 | fnum_to_keycode[context->channels[channel].fnum >> 7]; |
951 for (int op = channel * 4; op < (channel + 1) * 4; op++) | |
952 { | |
953 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op); | |
954 } | |
919 break; | 955 break; |
920 case REG_BLOCK_FNUM_H:{ | 956 case REG_BLOCK_FNUM_H:{ |
921 context->channels[channel].block_fnum_latch = value; | 957 context->channels[channel].block_fnum_latch = value; |
922 break; | 958 break; |
923 } | 959 } |
924 case REG_FNUM_LOW_CH3: | 960 case REG_FNUM_LOW_CH3: |
925 if (channel < 3) { | 961 if (channel < 3) { |
926 context->ch3_supp[channel].block = context->ch3_supp[channel].block_fnum_latch >> 3 & 0x7; | 962 context->ch3_supp[channel].block = context->ch3_supp[channel].block_fnum_latch >> 3 & 0x7; |
927 context->ch3_supp[channel].fnum = (context->ch3_supp[channel].block_fnum_latch & 0x7) << 8 | value; | 963 context->ch3_supp[channel].fnum = (context->ch3_supp[channel].block_fnum_latch & 0x7) << 8 | value; |
928 context->ch3_supp[channel].keycode = context->ch3_supp[channel].block << 2 | fnum_to_keycode[context->ch3_supp[channel].fnum >> 7]; | 964 context->ch3_supp[channel].keycode = context->ch3_supp[channel].block << 2 | fnum_to_keycode[context->ch3_supp[channel].fnum >> 7]; |
965 if (context->ch3_mode) { | |
966 int op = 2 * 4 + (channel < 2 ? (channel ^ 1) : channel); | |
967 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op); | |
968 } | |
929 } | 969 } |
930 break; | 970 break; |
931 case REG_BLOCK_FN_CH3: | 971 case REG_BLOCK_FN_CH3: |
932 if (channel < 3) { | 972 if (channel < 3) { |
933 context->ch3_supp[channel].block_fnum_latch = value; | 973 context->ch3_supp[channel].block_fnum_latch = value; |
1049 break; | 1089 break; |
1050 } | 1090 } |
1051 context->channels[channel].feedback = value >> 3 & 0x7; | 1091 context->channels[channel].feedback = value >> 3 & 0x7; |
1052 //printf("Algorithm %d, feedback %d for channel %d\n", value & 0x7, value >> 3 & 0x7, channel); | 1092 //printf("Algorithm %d, feedback %d for channel %d\n", value & 0x7, value >> 3 & 0x7, channel); |
1053 break; | 1093 break; |
1054 case REG_LR_AMS_PMS: | 1094 case REG_LR_AMS_PMS: { |
1095 uint8_t old_pms = context->channels[channel].pms; | |
1055 context->channels[channel].pms = (value & 0x7) * 32; | 1096 context->channels[channel].pms = (value & 0x7) * 32; |
1056 context->channels[channel].ams = value >> 4 & 0x3; | 1097 context->channels[channel].ams = value >> 4 & 0x3; |
1057 context->channels[channel].lr = value & 0xC0; | 1098 context->channels[channel].lr = value & 0xC0; |
1099 if (old_pms != context->channels[channel].pms) { | |
1100 for (int op = channel * 4; op < (channel + 1) * 4; op++) | |
1101 { | |
1102 context->operators[op].phase_inc = ym_calc_phase_inc(context, context->operators + op, op); | |
1103 } | |
1104 } | |
1058 //printf("Write of %X to LR_AMS_PMS reg for channel %d\n", value, channel); | 1105 //printf("Write of %X to LR_AMS_PMS reg for channel %d\n", value, channel); |
1059 break; | 1106 break; |
1107 } | |
1060 } | 1108 } |
1061 } | 1109 } |
1062 } | 1110 } |
1063 | 1111 |
1064 context->write_cycle = context->current_cycle; | 1112 context->write_cycle = context->current_cycle; |