- int cnt, i;
-
- cycles *= 3;
-
- // since we run things in async fashion, allow pwm to lag behind
- // but don't allow our "queue" to be infinite
- cnt = pwm_smp_expect - pwm_smp_cnt;
- if (cnt <= 0 || cnt * pwm_cycles < OSC_NTSC/7*3 / 60 / 2) {
- pwm_cycle_counter += cycles;
- while (pwm_cycle_counter > pwm_cycles) {
- pwm_cycle_counter -= pwm_cycles;
- pwm_smp_expect++;
+ if (v == 0)
+ return 0;
+ if (v > pwm_cycles)
+ v = pwm_cycles;
+ return ((int)v - pwm_cycles / 2) * pwm_mult;
+}
+
+#define consume_fifo(sh2, m68k_cycles) { \
+ int cycles_diff = ((m68k_cycles) * 3) - Pico32x.pwm_cycle_p; \
+ if (cycles_diff >= pwm_cycles) \
+ consume_fifo_do(sh2, m68k_cycles, cycles_diff); \
+}
+
+static void consume_fifo_do(SH2 *sh2, unsigned int m68k_cycles,
+ int sh2_cycles_diff)
+{
+ struct Pico32xMem *mem = Pico32xMem;
+ unsigned short *fifo_l = mem->pwm_fifo[0];
+ unsigned short *fifo_r = mem->pwm_fifo[1];
+ int sum = 0;
+
+ if (pwm_cycles == 0 || pwm_doing_fifo)
+ return;
+
+ elprintf(EL_PWM, "pwm: %u: consume %d/%d, %d,%d ptr %d",
+ m68k_cycles, sh2_cycles_diff, sh2_cycles_diff / pwm_cycles,
+ Pico32x.pwm_p[0], Pico32x.pwm_p[1], pwm_ptr);
+
+ // this is for recursion from dreq1 writes
+ pwm_doing_fifo = 1;
+
+ for (; sh2_cycles_diff >= pwm_cycles; sh2_cycles_diff -= pwm_cycles)
+ {
+ if (Pico32x.pwm_p[0] > 0) {
+ fifo_l[0] = fifo_l[1];
+ fifo_l[1] = fifo_l[2];
+ fifo_l[2] = fifo_l[3];
+ Pico32x.pwm_p[0]--;
+ mem->pwm_current[0] = convert_sample(fifo_l[0]);
+ sum += mem->pwm_current[0];
+ }
+ if (Pico32x.pwm_p[1] > 0) {
+ fifo_r[0] = fifo_r[1];
+ fifo_r[1] = fifo_r[2];
+ fifo_r[2] = fifo_r[3];
+ Pico32x.pwm_p[1]--;
+ mem->pwm_current[1] = convert_sample(fifo_r[0]);
+ sum += mem->pwm_current[1];