- // WDT timers
- for (i = 0; i < 2; i++) {
- void *pregs = Pico32xMem->sh2_peri_regs[i];
- if (PREG8(pregs, 0x80) & 0x20) { // TME
- timer_cycles[i] += cycles;
- cnt = PREG8(pregs, 0x81);
- while (timer_cycles[i] >= timer_tick_cycles[i]) {
- timer_cycles[i] -= timer_tick_cycles[i];
- cnt++;
- }
- if (cnt >= 0x100) {
- int level = PREG8(pregs, 0xe3) >> 4;
- int vector = PREG8(pregs, 0xe4) & 0x7f;
- elprintf(EL_32X, "%csh2 WDT irq (%d, %d)",
- i ? 's' : 'm', level, vector);
- sh2_internal_irq(&sh2s[i], level, vector);
- cnt &= 0xff;
- }
- PREG8(pregs, 0x81) = cnt;
+ 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);