- int tm = (Pico32x.regs[0x30 / 2] & 0x0f00) >> 8;
- if (tm == 0)
- return; // TODO: verify
-
- Pico32x.pwm_irq_sample_cnt += pwm_line_samples;
- if (Pico32x.pwm_irq_sample_cnt >= (tm << 16)) {
- Pico32x.pwm_irq_sample_cnt -= tm << 16;
- Pico32x.sh2irqs |= P32XI_PWM;
- p32x_update_irls();
+ 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];
+ }
+
+ mem->pwm[pwm_ptr * 2 ] = mem->pwm_current[0];
+ mem->pwm[pwm_ptr * 2 + 1] = mem->pwm_current[1];
+ pwm_ptr = (pwm_ptr + 1) & (PWM_BUFF_LEN - 1);
+
+ if (--Pico32x.pwm_irq_cnt == 0) {
+ Pico32x.pwm_irq_cnt = pwm_irq_reload;
+ do_pwm_irq(sh2, m68k_cycles);
+ }