+// DMAC handling
+static struct {
+ unsigned int sar0, dar0, tcr0; // src addr, dst addr, transfer count
+ unsigned int chcr0; // chan ctl
+ unsigned int sar1, dar1, tcr1; // same for chan 1
+ unsigned int chcr1;
+ int pad[4];
+ unsigned int dmaor;
+} * dmac0;
+
+static void dma_68k2sh2_do(void)
+{
+ unsigned short *dreqlen = &Pico32x.regs[0x10 / 2];
+ int i;
+
+ if (dmac0->tcr0 != *dreqlen)
+ elprintf(EL_32X|EL_ANOMALY, "tcr0 and dreq len differ: %d != %d", dmac0->tcr0, *dreqlen);
+
+ for (i = 0; i < Pico32x.dmac_ptr && dmac0->tcr0 > 0; i++) {
+ extern void p32x_sh2_write16(u32 a, u32 d);
+ elprintf(EL_32X|EL_ANOMALY, "dmaw [%08x] %04x, left %d", dmac0->dar0, Pico32x.dmac_fifo[i], *dreqlen);
+ p32x_sh2_write16(dmac0->dar0, Pico32x.dmac_fifo[i]);
+ dmac0->dar0 += 2;
+ dmac0->tcr0--;
+ (*dreqlen)--;
+ }
+
+ Pico32x.dmac_ptr = 0; // HACK
+ Pico32x.regs[6 / 2] &= ~P32XS_FULL;
+ if (*dreqlen == 0)
+ Pico32x.regs[6 / 2] &= ~P32XS_68S; // transfer complete
+ if (dmac0->tcr0 == 0)
+ dmac0->chcr0 |= 2; // DMA has ended normally
+ p32x_poll_undetect(&m68k_poll, P32XF_68KPOLL);
+}
+
+// ------------------------------------------------------------------
+