diff --git a/extern/ESFMu/esfm.c b/extern/ESFMu/esfm.c index 64d142e0d..e033b4d45 100644 --- a/extern/ESFMu/esfm.c +++ b/extern/ESFMu/esfm.c @@ -1751,7 +1751,7 @@ ESFM_process_feedback(esfm_chip *chip) uint32 basefreq, phase_offset; uint3 block; uint10 f_num; - int32_t in1 = 0, in2 = 0, wave_out; + int32_t wave_out, wave_last; int32_t phase_feedback; uint19 regressed_phase; int iter_counter; @@ -1792,55 +1792,68 @@ ESFM_process_feedback(esfm_chip *chip) "movl %%r11d, %k[out] \n\t" "movw $29, %%dx \n" "1: \n\t" - "movl %k[p_acc], %%eax \n\t" - "shrl $9, %%eax \n\t" + // phase_feedback = (wave_out + wave_last) >> 2; "movl %k[out], %k[p_fb] \n\t" "addl %%r11d, %k[p_fb] \n\t" "sarl $2, %k[p_fb] \n\t" + // wave_last = wave_out + "movl %k[out], %%r11d \n\t" + // phase = phase_feedback >> mod_in_shift; "movl %k[p_fb], %%ebx \n\t" "movb %b[mod_in], %%cl \n\t" "sarl %%cl, %%ebx \n\t" + // phase += phase_acc >> 9; + "movl %k[p_acc], %%eax \n\t" + "shrl $9, %%eax \n\t" "addl %%ebx, %%eax \n\t" + // lookup = logsinrom[(waveform << 10) | (phase & 0x3ff)]; "andq $0x3ff, %%rax \n\t" - "movl %k[out], %%r11d \n\t" - "movl $0x1fff, %%ecx \n\t" "movzwl (%%r8, %%rax, 2), %%ebx \n\t" "movl %%ebx, %%eax \n\t" + // level = (lookup & 0x1fff) + (envelope << 3); + "movl $0x1fff, %%ecx \n\t" "andl %%ecx, %%eax \n\t" "addl %%r10d, %%eax \n\t" + // if (level > 0x1fff) level = 0x1fff; "cmpl %%ecx, %%eax \n\t" "cmoval %%ecx, %%eax \n\t" + // wave_out = exprom[level & 0xff] >> (level >> 8); "movb %%ah, %%cl \n\t" "movzbl %%al, %%eax \n\t" "movzwl (%%r9, %%rax, 2), %k[out] \n\t" - "shrl %%cl, %k[out] \n\t" + "shrl %%cl, %k[out] \n\t" + // if (lookup & 0x8000) wave_out = -wave_out; + // in other words, lookup is negative "movl %k[out], %%ecx \n\t" "negl %%ecx \n\t" "testw %%bx, %%bx \n\t" "cmovsl %%ecx, %k[out] \n\t" + // phase_acc += phase_offset "addl %k[p_off], %k[p_acc] \n\t" + // loop "decw %%dx \n\t" "jne 1b \n\t" - : [p_fb] "+r" (phase_feedback), - [p_acc] "+r" (phase_acc), - [out] "+r" (wave_out) - : [p_off] "g" ((uint32_t)phase_offset), - [mod_in] "g" ((uint8_t)mod_in_shift), - [wave] "g" ((uint8_t)waveform), - [eg_out] "g" ((uint32_t)eg_output), - [sinrom] "m" (logsinrom), - [exprom] "m" (exprom) + : [p_fb] "=&r" (phase_feedback), + [p_acc] "+r" (phase_acc), + [out] "+r" (wave_out) + : [p_off] "g" ((uint32_t)phase_offset), + [mod_in] "g" ((uint8_t)mod_in_shift), + [wave] "g" ((uint8_t)waveform), + [eg_out] "g" ((uint32_t)eg_output), + [sinrom] "m" (logsinrom), + [exprom] "m" (exprom) : "cc", "ax", "bx", "cx", "dx", "r8", "r9", "r10", "r11" ); #else + wave_out = 0; + wave_last = 0; for (iter_counter = 28; iter_counter >= 0; iter_counter--) { - phase = phase_acc >> 9; - phase_feedback = (in1 + in2) >> 2; - phase += phase_feedback >> mod_in_shift; + phase_feedback = (wave_out + wave_last) >> 2; + wave_last = wave_out; + phase = phase_feedback >> mod_in_shift; + phase += phase_acc >> 9; wave_out = ESFM_envelope_wavegen(waveform, phase, eg_output); - in2 = in1; - in1 = wave_out; phase_acc += phase_offset; } #endif