void V_Core::StartADMAWrite(u16 *pMem, u32 sz) { #ifndef ENABLE_NEW_IOPDMA_SPU2 int size = (sz)&(~511); if(MsgAutoDMA()) ConLog("* SPU2-X: DMA%c AutoDMA Transfer of %d bytes to %x (%02x %x %04x).\n", GetDmaIndexChar(), size<<1, TSA, DMABits, AutoDMACtrl, (~Regs.ATTR)&0x7fff); InputDataProgress = 0; if((AutoDMACtrl&(Index+1))==0) { TSA = 0x2000 + (Index<<10); DMAICounter = size; } else if(size>=512) { InputDataLeft = size; if(AdmaInProgress==0) { #ifdef PCM24_S1_INTERLEAVE if((Index==1)&&((PlayMode&8)==8)) { AutoDMAReadBuffer(Index,1); } else { AutoDMAReadBuffer(Index,0); } #else if( ((PlayMode&4)==4) && (Index==0) ) Cores[0].InputPosRead=0; AutoDMAReadBuffer(0); #endif if(size==512) DMAICounter = size; } AdmaInProgress = 1; } else { InputDataLeft = 0; DMAICounter = 1; } TADR = MADR + (size<<1); #endif }
void StartADMAWrite(int core,u16 *pMem, u32 sz) { int size=(sz)&(~511); if(MsgAutoDMA()) ConLog(" * SPU2: DMA%c AutoDMA Transfer of %d bytes to %x (%02x %x %04x).\n", (core==0)?'4':'7',size<<1,Cores[core].TSA,Cores[core].DMABits,Cores[core].AutoDMACtrl,(~Cores[core].Regs.ATTR)&0x7fff); Cores[core].InputDataProgress=0; if((Cores[core].AutoDMACtrl&(core+1))==0) { Cores[core].TSA=0x2000+(core<<10); Cores[core].DMAICounter=size; } else if(size>=512) { Cores[core].InputDataLeft=size; if(Cores[core].AdmaInProgress==0) { #ifdef PCM24_S1_INTERLEAVE if((core==1)&&((PlayMode&8)==8)) { AutoDMAReadBuffer(core,1); } else { AutoDMAReadBuffer(core,0); } #else if(((PlayMode&4)==4)&&(core==0)) Cores[0].InputPos=0; AutoDMAReadBuffer(core,0); #endif if(size==512) Cores[core].DMAICounter=size; } Cores[core].AdmaInProgress=1; } else { Cores[core].InputDataLeft=0; Cores[core].DMAICounter=1; } Cores[core].TADR=Cores[core].MADR+(size<<1); }
s32 V_Core::NewDmaWrite(u32* data, u32 bytesLeft, u32* bytesProcessed) { #ifdef ENABLE_NEW_IOPDMA_SPU2 bool DmaStarting = !DmaStarted; DmaStarted = true; if(bytesLeft<2) { // execute interrupt code early NewDmaInterrupt(); *bytesProcessed = bytesLeft; return 0; } if( IsDevBuild ) { DebugCores[Index].lastsize = bytesLeft; DebugCores[Index].dmaFlag = 1; } TSA &= ~7; bool adma_enable = ((AutoDMACtrl&(Index+1))==(Index+1)); if(adma_enable) { TSA&=0x1fff; if(MsgAutoDMA() && DmaStarting) ConLog("* SPU2-X: DMA%c AutoDMA Transfer of %d bytes to %x (%02x %x %04x).\n", GetDmaIndexChar(), bytesLeft<<1, TSA, DMABits, AutoDMACtrl, (~Regs.ATTR)&0x7fff); u32 processed = 0; while((AutoDmaFree>0)&&(bytesLeft>=0x400)) { // copy block LogAutoDMA( Index ? ADMA7LogFile : ADMA4LogFile ); // HACKFIX!! DMAPtr can be invalid after a savestate load, so the savestate just forces it // to NULL and we ignore it here. (used to work in old VM editions of PCSX2 with fixed // addressing, but new PCSX2s have dynamic memory addressing). s16* mptr = (s16*)data; if(false)//(mode) { //memcpy((ADMATempBuffer+(InputPosWrite<<1)),mptr,0x400); memcpy(GetMemPtr(0x2000+(Index<<10)+InputPosWrite),mptr,0x400); mptr+=0x200; // Flag interrupt? If IRQA occurs between start and dest, flag it. // Important: Test both core IRQ settings for either DMA! u32 dummyTSA = 0x2000+(Index<<10)+InputPosWrite; u32 dummyTDA = 0x2000+(Index<<10)+InputPosWrite+0x200; for( int i=0; i<2; i++ ) { if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) ) { SetIrqCall(i); } } } else { //memcpy((ADMATempBuffer+InputPosWrite),mptr,0x200); memcpy(GetMemPtr(0x2000+(Index<<10)+InputPosWrite),mptr,0x200); mptr+=0x100; // Flag interrupt? If IRQA occurs between start and dest, flag it. // Important: Test both core IRQ settings for either DMA! u32 dummyTSA = 0x2000+(Index<<10)+InputPosWrite; u32 dummyTDA = 0x2000+(Index<<10)+InputPosWrite+0x100; for( int i=0; i<2; i++ ) { if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) ) { SetIrqCall(i); } } //memcpy((ADMATempBuffer+InputPosWrite+0x200),mptr,0x200); memcpy(GetMemPtr(0x2200+(Index<<10)+InputPosWrite),mptr,0x200); mptr+=0x100; // Flag interrupt? If IRQA occurs between start and dest, flag it. // Important: Test both core IRQ settings for either DMA! dummyTSA = 0x2200+(Index<<10)+InputPosWrite; dummyTDA = 0x2200+(Index<<10)+InputPosWrite+0x100; for( int i=0; i<2; i++ ) { if( Cores[i].IRQEnable && (Cores[i].IRQA >= dummyTSA) && (Cores[i].IRQA < dummyTDA) ) { SetIrqCall(i); } } } // See ReadInput at mixer.cpp for explanation on the commented out lines // InputPosWrite = (InputPosWrite + 0x100) & 0x1ff; AutoDmaFree -= 0x200; processed += 0x400; bytesLeft -= 0x400; } if(processed==0) { *bytesProcessed = 0; return 768*15; // pause a bit } else { *bytesProcessed = processed; return 0; // auto pause } } else { if(MsgDMA() && DmaStarting) ConLog("* SPU2-X: DMA%c Transfer of %d bytes to %x (%02x %x %04x).\n", GetDmaIndexChar(),bytesLeft,TSA,DMABits,AutoDMACtrl,(~Regs.ATTR)&0x7fff); if(bytesLeft> 2048) bytesLeft = 2048; // TODO: Sliced transfers? PlainDMAWrite((u16*)data,bytesLeft/2); } Regs.STATX &= ~0x80; Regs.STATX |= 0x400; #endif *bytesProcessed = bytesLeft; return 0; }