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;