Cores/Nds/NDS.Dma.cs
namespace Emulotl.Nds;
public sealed partial class NDS
{
private const uint CPUStop_DMA9 = 0xFFF;
private const uint CPUStop_DMA7 = 0xFFF << 16;
private const uint CPUStop_GXStall = 1u << 31;
public DMA[] DMAs;
public uint[] DMA9Fill = new uint[4];
public uint CPUStop;
private void InitDmas()
{
DMAs = new DMA[8];
DMAs[0] = new DMA( 0, 0, this );
DMAs[1] = new DMA( 0, 1, this );
DMAs[2] = new DMA( 0, 2, this );
DMAs[3] = new DMA( 0, 3, this );
DMAs[4] = new DMA( 1, 0, this );
DMAs[5] = new DMA( 1, 1, this );
DMAs[6] = new DMA( 1, 2, this );
DMAs[7] = new DMA( 1, 3, this );
}
private void ResetDmas()
{
CPUStop = 0;
for ( int i = 0; i < 8; i++ )
DMAs[i].Reset();
Array.Clear( DMA9Fill );
}
public void StopCPU( uint cpu, uint mask )
{
if ( cpu != 0 )
{
CPUStop |= mask << 16;
ARM7.Halt( 2 );
}
else
{
CPUStop |= mask;
ARM9.Halt( 2 );
}
}
public void ResumeCPU( uint cpu, uint mask )
{
if ( cpu != 0 ) mask <<= 16;
CPUStop &= ~mask;
}
public bool DMAsInMode( uint cpu, uint mode )
{
cpu <<= 2;
if ( DMAs[cpu + 0].IsInMode( mode ) ) return true;
if ( DMAs[cpu + 1].IsInMode( mode ) ) return true;
if ( DMAs[cpu + 2].IsInMode( mode ) ) return true;
if ( DMAs[cpu + 3].IsInMode( mode ) ) return true;
return false;
}
public bool DMAsRunning( uint cpu )
{
cpu <<= 2;
if ( DMAs[cpu + 0].IsRunning() ) return true;
if ( DMAs[cpu + 1].IsRunning() ) return true;
if ( DMAs[cpu + 2].IsRunning() ) return true;
if ( DMAs[cpu + 3].IsRunning() ) return true;
return false;
}
public void GXFIFOStall()
{
if ( (CPUStop & CPUStop_GXStall) != 0 ) return;
CPUStop |= CPUStop_GXStall;
if ( CurCPU == 1 )
{
ARM9.Halt( 2 );
}
else
{
DMAs[0].StallIfRunning();
DMAs[1].StallIfRunning();
DMAs[2].StallIfRunning();
DMAs[3].StallIfRunning();
}
}
public void GXFIFOUnstall()
{
CPUStop &= ~CPUStop_GXStall;
}
public void CheckDMAs( uint cpu, uint mode )
{
cpu <<= 2;
DMAs[cpu + 0].StartIfNeeded( mode );
DMAs[cpu + 1].StartIfNeeded( mode );
DMAs[cpu + 2].StartIfNeeded( mode );
DMAs[cpu + 3].StartIfNeeded( mode );
}
public void StopDMAs( uint cpu, uint mode )
{
cpu <<= 2;
DMAs[cpu + 0].StopIfNeeded( mode );
DMAs[cpu + 1].StopIfNeeded( mode );
DMAs[cpu + 2].StopIfNeeded( mode );
DMAs[cpu + 3].StopIfNeeded( mode );
}
private void RunDMAs( uint cpu )
{
uint b = cpu << 2;
DMAs[b + 0].Run();
DMAs[b + 1].Run();
DMAs[b + 2].Run();
DMAs[b + 3].Run();
}
}