- // 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;
+ while (sh2_cycles_diff >= pwm_cycles) {
+ struct Pico32xMem *mem = Pico32xMem;
+ short *fifo_l = mem->pwm_fifo[0];
+ short *fifo_r = mem->pwm_fifo[1];
+
+ 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]--;
+ }
+ 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[pwm_ptr * 2 ] = fifo_l[0];
+ mem->pwm[pwm_ptr * 2 + 1] = fifo_r[0];
+ pwm_ptr = (pwm_ptr + 1) & (PWM_BUFF_LEN - 1);
+
+ sh2_cycles_diff -= pwm_cycles;
+
+ if (--Pico32x.pwm_irq_cnt == 0) {
+ Pico32x.pwm_irq_cnt = pwm_irq_reload;
+ // irq also does dreq1, so call it after cycle update
+ do_irq = 1;
+ break;