diff --git a/pcsx2/IopDma.cpp b/pcsx2/IopDma.cpp index ddcdacc06b..5b91188c77 100644 --- a/pcsx2/IopDma.cpp +++ b/pcsx2/IopDma.cpp @@ -385,7 +385,7 @@ void IopDmaStart(int channel) IopDmaHandlers[channel].REG_CHCR() |= DMA_CTRL_ACTIVE; IopDmaHandlers[channel].ByteCount = size; - IopDmaHandlers[channel].Target = 0; + IopDmaHandlers[channel].NextUpdate = 0; IopDmaHandlers[channel].Activated = true; //SetDmaUpdateTarget(1); @@ -405,9 +405,8 @@ void IopDmaUpdate(u32 elapsed) { s32 MinDelay=0; - int doNotHang=10; do { - MinDelay = 0x7FFFFFFF; + MinDelay = 0x7FFFFFFF; // max possible value for (int i = 0;i < DMA_CHANNEL_MAX;i++) { @@ -415,12 +414,12 @@ void IopDmaUpdate(u32 elapsed) if ((ch->Activated) && (ch->REG_CHCR()&DMA_CTRL_ACTIVE)) { - ch->Target -= elapsed; - if (ch->Target <= 0) + ch->NextUpdate -= elapsed; + if (ch->NextUpdate <= 0) { if (ch->ByteCount <= 0) { - ch->Target = 0x7fffffff; + ch->NextUpdate = 0x7fffffff; ch->REG_CHCR() &= ~DMA_CTRL_ACTIVE; RaiseDmaIrq(i); @@ -432,58 +431,59 @@ void IopDmaUpdate(u32 elapsed) DmaHandler handler = (chcr & DMA_CTRL_DIRECTION) ? IopDmaHandlers[i].Write : IopDmaHandlers[i].Read; - u32 BCount = 0; - s32 Target = (handler) ? handler(i, (u32*)iopPhysMem(ch->REG_MADR()), ch->ByteCount, &BCount) : 0; + u32 ProcessedBytes = 0; + s32 RequestedDelay = (handler) ? handler(i, (u32*)iopPhysMem(ch->REG_MADR()), ch->ByteCount, &ProcessedBytes) : 0; - if(BCount>0) + if(ProcessedBytes>0) { - psxCpu->Clear(ch->REG_MADR(), BCount/4); + psxCpu->Clear(ch->REG_MADR(), ProcessedBytes/4); } - int TTarget = 100; - if (Target < 0) + int NextUpdateDelay = 100; + if (RequestedDelay < 0) // error code { // TODO: ... What to do if the handler gives an error code? :P ch->REG_CHCR() &= ~DMA_CTRL_ACTIVE; RaiseDmaIrq(i); IopDmaHandlers[i].Interrupt(i); } - else if (BCount > 0) + else if (ProcessedBytes > 0) // if not an error, continue transfer { - ch->REG_MADR()+= BCount; - ch->ByteCount -= BCount; + ch->REG_MADR()+= ProcessedBytes; + ch->ByteCount -= ProcessedBytes; - TTarget = BCount/4; // / ch->Width; + NextUpdateDelay = ProcessedBytes/4; // / ch->Width; } - if (Target != 0) TTarget = Target; + if (RequestedDelay != 0) NextUpdateDelay = RequestedDelay; - ch->Target += TTarget; - - TTarget = ch->Target; - if(TTarget < 0) - TTarget = 0; - - if (TTargetNextUpdate += NextUpdateDelay; } } - else - { - int TTarget = ch->Target; - if (TTargetNextUpdate; + if(nTarget < 0) nTarget = 0; + + if (nTarget0)); + while(MinDelay <= 0); if(MinDelay<0x7FFFFFFF) + { + // tell the iop when to call this function again SetDmaUpdateTarget(MinDelay); + } else + { + // bogus value so the function gets called again, not sure if it's necessary anymore SetDmaUpdateTarget(10000); + } } s32 errDmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed) diff --git a/pcsx2/IopDma.h b/pcsx2/IopDma.h index ff0d301bdc..a7c1d4b6fc 100644 --- a/pcsx2/IopDma.h +++ b/pcsx2/IopDma.h @@ -40,7 +40,7 @@ public: // and serves as a signal that the channel shoudl be handled by the loop. // temporary until I code a better method u32 ByteCount; - s32 Target; + s32 NextUpdate; u32& REG_MADR(void); u32& REG_BCR(void); diff --git a/pcsx2/IopSio2.cpp b/pcsx2/IopSio2.cpp index 24137aedf7..c930543c07 100644 --- a/pcsx2/IopSio2.cpp +++ b/pcsx2/IopSio2.cpp @@ -224,6 +224,9 @@ s32 sio2DmaRead(s32 channel, u32* tdata, u32 bytesLeft, u32* bytesProcessed) int read = 0; + // limit the burst length to avoid problems + //if(bytesLeft>2048) bytesLeft = 2048; + while (bytesLeft > 0) { (*(data++)) = sio2_fifoOut(); @@ -253,6 +256,9 @@ s32 sio2DmaWrite(s32 channel, u32* tdata, u32 bytesLeft, u32* bytesProcessed) //int available = sio2_getFifoInFree(); + // limit the burst length to avoid problems + //if(bytesLeft>2048) bytesLeft = 2048; + int written = 0; for(int i = 0; i < bytesLeft; i++)