doDMA(source, dest, sourceIncrement, destIncrement,
doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement,
void CPUCheckDMA(int reason, int dmamask){  // DMA 0  if((DM0CNT_H & 0x8000) && (dmamask & 1)) {   if(((DM0CNT_H >> 12) & 3) == reason) {     u32 sourceIncrement = 4;     u32 destIncrement = 4;     switch((DM0CNT_H >> 7) & 3) {     case 0:       break;     case 1:       sourceIncrement = (u32)-4;       break;     case 2:       sourceIncrement = 0;       break;     }     switch((DM0CNT_H >> 5) & 3) {     case 0:       break;     case 1:       destIncrement = (u32)-4;       break;     case 2:       destIncrement = 0;       break;     }           u32 source = DM0SAD_L | (DM0SAD_H << 16);     u32 dest = DM0DAD_L | (DM0DAD_H << 16);#ifdef DEV_VERSION     if(systemVerbose & VERBOSE_DMA0) {       int count = (DM0CNT_L ? DM0CNT_L : 0x4000) << 1;       if(DM0CNT_H & 0x0400)         count <<= 1;       log("DMA0: s=%08x d=%08x c=%04x count=%08x\n", source, dest, DM0CNT_H,           count);     }#endif     doDMA(source, dest, sourceIncrement, destIncrement,           DM0CNT_L ? DM0CNT_L : 0x4000,           DM0CNT_H & 0x0400);     if(DM0CNT_H & 0x4000) {       IF |= 0x0100;       UPDATE_REG(0x202, IF);     }          if(((DM0CNT_H >> 5) & 3) != 3) {       DM0DAD_L = dest & 0xFFFF;       DM0DAD_H = dest >> 16;       UPDATE_REG(0xB4, DM0DAD_L);       UPDATE_REG(0xB6, DM0DAD_H);     }     DM0SAD_L = source & 0xFFFF;     DM0SAD_H = source >> 16;     UPDATE_REG(0xB0, DM0SAD_L);     UPDATE_REG(0xB2, DM0SAD_H);           if(!(DM0CNT_H & 0x0200) || !(DM0CNT_H & 0x3000)) {       DM0CNT_H &= 0x7FFF;       UPDATE_REG(0xBA, DM0CNT_H);              DM0DAD_L = dma0DestReload & 0xFFFF;       DM0DAD_H = dma0DestReload >> 16;       UPDATE_REG(0xB4, DM0DAD_L);       UPDATE_REG(0xB6, DM0DAD_H);              DM0SAD_L = dma0SourceReload & 0xFFFF;       DM0SAD_H = dma0SourceReload >> 16;       UPDATE_REG(0xB0, DM0SAD_L);       UPDATE_REG(0xB2, DM0SAD_H);     }   }  }     // DMA 1  if((DM1CNT_H & 0x8000) && (dmamask & 2)) {    if(((DM1CNT_H >> 12) & 3) == reason) {      u32 sourceIncrement = 4;      u32 destIncrement = 4;      switch((DM1CNT_H >> 7) & 3) {      case 0:        break;      case 1:        sourceIncrement = (u32)-4;        break;      case 2:        sourceIncrement = 0;        break;      }      switch((DM1CNT_H >> 5) & 3) {      case 0:        break;      case 1:        destIncrement = (u32)-4;        break;      case 2:        destIncrement = 0;        break;      }            u32 source = DM1SAD_L | (DM1SAD_H << 16);      u32 dest = DM1DAD_L | (DM1DAD_H << 16);      if(reason == 3) {#ifdef DEV_VERSION        if(systemVerbose & VERBOSE_DMA1) {          log("DMA1: s=%08x d=%08x c=%04x bytes=%08x\n", source, dest,              DM1CNT_H,              16);        }#endif          doDMA(source, dest, sourceIncrement, 0, 4,              0x0400);      } else {#ifdef DEV_VERSION        if(systemVerbose & VERBOSE_DMA1) {          int count = (DM1CNT_L ? DM1CNT_L : 0x4000) << 1;          if(DM1CNT_H & 0x0400)            count <<= 1;          log("DMA1: s=%08x d=%08x c=%04x bytes=%08x\n", source, dest,              DM1CNT_H,              count);        }#endif                  doDMA(source, dest, sourceIncrement, destIncrement,              DM1CNT_L ? DM1CNT_L : 0x4000,              DM1CNT_H & 0x0400);      }              if(DM1CNT_H & 0x4000) {        IF |= 0x0200;        UPDATE_REG(0x202, IF);      }            if((((DM1CNT_H >> 5) & 3) != 3) && (reason != 3)) {        DM1DAD_L = dest & 0xFFFF;        DM1DAD_H = dest >> 16;        UPDATE_REG(0xC0, DM1DAD_L);        UPDATE_REG(0xC2, DM1DAD_H);      }      DM1SAD_L = source & 0xFFFF;      DM1SAD_H = source >> 16;      UPDATE_REG(0xBC, DM1SAD_L);      UPDATE_REG(0xBE, DM1SAD_H);            if(!(DM1CNT_H & 0x0200) || !(DM1CNT_H & 0x3000)) {        DM1CNT_H &= 0x7FFF;        UPDATE_REG(0xC6, DM1CNT_H);                DM1DAD_L = dma1DestReload & 0xFFFF;        DM1DAD_H = dma1DestReload >> 16;        UPDATE_REG(0xC0, DM1DAD_L);        UPDATE_REG(0xC2, DM1DAD_H);                DM1SAD_L = dma1SourceReload & 0xFFFF;        DM1SAD_H = dma1SourceReload >> 16;        UPDATE_REG(0xBC, DM1SAD_L);        UPDATE_REG(0xBE, DM1SAD_H);      }    }  }    // DMA 2  if((DM2CNT_H & 0x8000) && (dmamask & 4)) {    if(((DM2CNT_H >> 12) & 3) == reason) {      u32 sourceIncrement = 4;      u32 destIncrement = 4;      switch((DM2CNT_H >> 7) & 3) {      case 0:        break;      case 1:        sourceIncrement = (u32)-4;        break;      case 2:        sourceIncrement = 0;        break;      }      switch((DM2CNT_H >> 5) & 3) {      case 0:        break;      case 1:        destIncrement = (u32)-4;        break;      case 2:        destIncrement = 0;        break;      }            u32 source = DM2SAD_L | (DM2SAD_H << 16);      u32 dest = DM2DAD_L | (DM2DAD_H << 16);      if(reason == 3) {#ifdef DEV_VERSION        if(systemVerbose & VERBOSE_DMA2) {          int count = (4) << 2;          log("DMA2: s=%08x d=%08x c=%04x bytes=%08x\n", source, dest,              DM2CNT_H,              count);        }#endif                          doDMA(source, dest, sourceIncrement, 0, 4,              0x0400);      } else {#ifdef DEV_VERSION        if(systemVerbose & VERBOSE_DMA2) {          int count = (DM2CNT_L ? DM2CNT_L : 0x4000) << 1;          if(DM2CNT_H & 0x0400)            count <<= 1;          log("DMA2: s=%08x d=%08x c=%04x bytes=%08x\n", source, dest,              DM2CNT_H,              count);        }#endif                          doDMA(source, dest, sourceIncrement, destIncrement,              DM2CNT_L ? DM2CNT_L : 0x4000,              DM2CNT_H & 0x0400);      }      if(DM2CNT_H & 0x4000) {        IF |= 0x0400;        UPDATE_REG(0x202, IF);      }            if((((DM2CNT_H >> 5) & 3) != 3) && (reason != 3)) {        DM2DAD_L = dest & 0xFFFF;        DM2DAD_H = dest >> 16;        UPDATE_REG(0xCC, DM2DAD_L);        UPDATE_REG(0xCE, DM2DAD_H);      }      DM2SAD_L = source & 0xFFFF;      DM2SAD_H = source >> 16;      UPDATE_REG(0xC8, DM2SAD_L);      UPDATE_REG(0xCA, DM2SAD_H);            if(!(DM2CNT_H & 0x0200) || !(DM2CNT_H & 0x3000)) {        DM2CNT_H &= 0x7FFF;        UPDATE_REG(0xD2, DM2CNT_H);               DM2DAD_L = dma2DestReload & 0xFFFF;        DM2DAD_H = dma2DestReload >> 16;        UPDATE_REG(0xCC, DM2DAD_L);        UPDATE_REG(0xCE, DM2DAD_H);                DM2SAD_L = dma2SourceReload & 0xFFFF;        DM2SAD_H = dma2SourceReload >> 16;        UPDATE_REG(0xC8, DM2SAD_L);        UPDATE_REG(0xCA, DM2SAD_H);      }    }  }  // DMA 3  if((DM3CNT_H & 0x8000) && (dmamask & 8)) {    if(((DM3CNT_H >> 12) & 3) == reason) {      u32 sourceIncrement = 4;      u32 destIncrement = 4;      switch((DM3CNT_H >> 7) & 3) {      case 0:        break;      case 1:        sourceIncrement = (u32)-4;        break;      case 2:        sourceIncrement = 0;        break;      }      switch((DM3CNT_H >> 5) & 3) {      case 0:        break;      case 1:        destIncrement = (u32)-4;        break;      case 2:        destIncrement = 0;        break;      }            u32 source = DM3SAD_L | (DM3SAD_H << 16);      u32 dest = DM3DAD_L | (DM3DAD_H << 16);#ifdef DEV_VERSION      if(systemVerbose & VERBOSE_DMA3) {        int count = (DM3CNT_L ? DM3CNT_L : 0x10000) << 1;        if(DM3CNT_H & 0x0400)          count <<= 1;        log("DMA3: s=%08x d=%08x c=%04x bytes=%08x\n", source, dest,            DM3CNT_H,            count);      }#endif                      doDMA(source, dest, sourceIncrement, destIncrement,            DM3CNT_L ? DM3CNT_L : 0x10000,            DM3CNT_H & 0x0400);      if(DM3CNT_H & 0x4000) {        IF |= 0x0800;        UPDATE_REG(0x202, IF);      }            if(((DM3CNT_H >> 5) & 3) != 3) {        DM3DAD_L = dest & 0xFFFF;        DM3DAD_H = dest >> 16;        UPDATE_REG(0xD8, DM3DAD_L);        UPDATE_REG(0xDA, DM3DAD_H);      }      DM3SAD_L = source & 0xFFFF;      DM3SAD_H = source >> 16;      UPDATE_REG(0xD4, DM3SAD_L);      UPDATE_REG(0xD6, DM3SAD_H);            if(!(DM3CNT_H & 0x0200) || !(DM3CNT_H & 0x3000)) {        DM3CNT_H &= 0x7FFF;        UPDATE_REG(0xDE, DM3CNT_H);               DM3DAD_L = dma3DestReload & 0xFFFF;        DM3DAD_H = dma3DestReload >> 16;        UPDATE_REG(0xD8, DM3DAD_L);        UPDATE_REG(0xDA, DM3DAD_H);                DM3SAD_L = dma3SourceReload & 0xFFFF;        DM3SAD_H = dma3SourceReload >> 16;        UPDATE_REG(0xD4, DM3SAD_L);        UPDATE_REG(0xD6, DM3SAD_H);      }    }  }}