implement MR cont. for arm7 dma; also a hack?

the hack is to make arm9 dma contention work with prior improvements to synchronization
This commit is contained in:
Jaklyy 2024-12-14 17:15:06 -05:00
parent 4ea0e60e18
commit 2051d412d1
2 changed files with 218 additions and 5 deletions

View File

@ -579,14 +579,13 @@ void DMA::Run9()
{
while (IterCount > 0 && !Stall)
{
/*
u32 rgn = NDS.ARM9Regions[CurSrcAddr>>14] | NDS.ARM9Regions[CurDstAddr>>14];
if (rgn & Mem9_MainRAM)
{
NDS.ARM9.MRTrack.Type = MainRAMType::DMA16;
NDS.ARM9.MRTrack.Var = Num;
return;
}*/
}
Running = 2;
NDS.DMA9Timestamp += (UnitTimings9_16(burststart) << NDS.ARM9ClockShift);
@ -606,14 +605,13 @@ void DMA::Run9()
{
while (IterCount > 0 && !Stall)
{
/*
u32 rgn = NDS.ARM9Regions[CurSrcAddr>>14] | NDS.ARM9Regions[CurDstAddr>>14];
if (rgn & Mem9_MainRAM)
{
NDS.ARM9.MRTrack.Type = MainRAMType::DMA32;
NDS.ARM9.MRTrack.Var = Num;
return;
}*/
}
Running = 2;
NDS.DMA9Timestamp += (UnitTimings9_32(burststart) << NDS.ARM9ClockShift);
@ -670,12 +668,19 @@ void DMA::Run7()
// add NS penalty for first accesses in burst
bool burststart = (Running == 2);
Running = 1;
if (!(Cnt & (1<<26)))
{
while (IterCount > 0 && !Stall)
{
u32 rgn = NDS.ARM7Regions[CurSrcAddr>>15] | NDS.ARM7Regions[CurDstAddr>>15];
if (rgn & Mem7_MainRAM)
{
NDS.ARM7.MRTrack.Type = MainRAMType::DMA16;
NDS.ARM7.MRTrack.Var = Num;
return;
}
Running = 1;
NDS.ARM7Timestamp += UnitTimings7_16(burststart);
burststart = false;
@ -693,6 +698,14 @@ void DMA::Run7()
{
while (IterCount > 0 && !Stall)
{
u32 rgn = NDS.ARM7Regions[CurSrcAddr>>15] | NDS.ARM7Regions[CurDstAddr>>15];
if (rgn & Mem7_MainRAM)
{
NDS.ARM7.MRTrack.Type = MainRAMType::DMA32;
NDS.ARM7.MRTrack.Var = Num;
return;
}
Running = 1;
NDS.ARM7Timestamp += UnitTimings7_32(burststart);
burststart = false;

View File

@ -1407,6 +1407,204 @@ void NDS::MainRAMHandleARM7()
memset(&ARM7.MRTrack, 0, sizeof(ARM7.MRTrack));
break;
}
case MainRAMType::DMA32:
{
DMA* dma = &DMAs[ARM7.MRTrack.Var];
int burststart = dma->Running - 1;
u32 srcaddr = dma->CurSrcAddr;
u32 srcrgn = ARM7Regions[srcaddr>>15];
u32 dstaddr = dma->CurDstAddr;
u32 dstrgn = ARM7Regions[dstaddr>>15];
if (!ARM7.MRTrack.Progress)
{
if (srcrgn == Mem7_MainRAM)
{
if (burststart == 2 || A9WENTLAST || DMALastWasMainRAM || dma->SrcAddrInc <= 0)
{
if (ARM7Timestamp < MainRAMTimestamp) { ARM7Timestamp = MainRAMTimestamp; if (A9PRIORITY) return; }
MainRAMTimestamp = ARM7Timestamp + 9;
ARM7Timestamp += 6;
MainRAMLastAccess = A7LAST;
}
else
{
ARM7Timestamp += 2;
MainRAMTimestamp += 2;
}
DMALastWasMainRAM = true;
}
else
{
if (burststart == 2 || dma->SrcAddrInc <= 0) ARM7Timestamp += ARM7MemTimings[srcaddr>>15][2] + (ARM7MemTimings[srcaddr>>15][2] == 1);
else ARM7Timestamp += ARM7MemTimings[srcaddr>>15][3];
DMALastWasMainRAM = false;
}
DMAReadHold = ARM7Read32(srcaddr);
ARM7.MRTrack.Progress = 1;
}
else
{
if (dstrgn == Mem7_MainRAM)
{
if (burststart == 2 || A9WENTLAST || DMALastWasMainRAM || dma->DstAddrInc <= 0)
{
if (ARM7Timestamp < MainRAMTimestamp) { ARM7Timestamp = MainRAMTimestamp; if (A9PRIORITY) return; }
MainRAMTimestamp = ARM7Timestamp + 9;
ARM7Timestamp += 4;
MainRAMLastAccess = A7LAST;
}
else
{
ARM7Timestamp += 2;
MainRAMTimestamp += 2;
}
DMALastWasMainRAM = true;
}
else
{
if (burststart == 2 || dma->DstAddrInc <= 0) ARM7Timestamp += ARM7MemTimings[dstaddr>>15][2];
else ARM7Timestamp += ARM7MemTimings[dstaddr>>15][3] - (burststart <= 0);
DMALastWasMainRAM = false;
}
ARM7Write32(dstaddr, DMAReadHold);
dma->CurSrcAddr += dma->SrcAddrInc<<2;
dma->CurDstAddr += dma->DstAddrInc<<2;
dma->IterCount--;
dma->RemCount--;
burststart -= 1;
if (burststart <= 0) dma->Running = 1;
else dma->Running = 2;
//DMA7Timestamp = ARM7Timestamp;
memset(&ARM7.MRTrack, 0, sizeof(ARM7.MRTrack));
ConTSLock = false;
if (dma->RemCount)
{
if (dma->IterCount == 0)
{
dma->Running = 0;
ResumeCPU(1, 1<<dma->Num);
}
break;
}
if (!(dma->Cnt & (1<<25)))
dma->Cnt &= ~(1<<31);
if (dma->Cnt & (1<<30))
SetIRQ(1, IRQ_DMA0 + dma->Num);
dma->Running = 0;
dma->InProgress = false;
ResumeCPU(1, 1<<dma->Num);
}
break;
}
case MainRAMType::DMA16:
{
DMA* dma = &DMAs[ARM7.MRTrack.Var];
int burststart = dma->Running - 1;
u32 srcaddr = dma->CurSrcAddr;
u32 srcrgn = ARM7Regions[srcaddr>>15];
u32 dstaddr = dma->CurDstAddr;
u32 dstrgn = ARM7Regions[dstaddr>>15];
if (!ARM7.MRTrack.Progress)
{
if (srcrgn == Mem7_MainRAM)
{
if (burststart == 2 || A9WENTLAST || DMALastWasMainRAM || dma->SrcAddrInc <= 0)
{
if (ARM7Timestamp < MainRAMTimestamp) { ARM7Timestamp = MainRAMTimestamp; if (A9PRIORITY) return; }
MainRAMTimestamp = ARM7Timestamp + 8;
ARM7Timestamp += 5;
MainRAMLastAccess = A7LAST;
}
else
{
ARM7Timestamp += 1;
MainRAMTimestamp += 1;
}
DMALastWasMainRAM = true;
}
else
{
if (burststart == 2 || dma->SrcAddrInc <= 0) ARM7Timestamp += ARM7MemTimings[srcaddr>>15][0] + (ARM7MemTimings[srcaddr>>15][0] == 1);
else ARM7Timestamp += ARM7MemTimings[srcaddr>>15][1];
DMALastWasMainRAM = false;
}
DMAReadHold = ARM7Read16(srcaddr);
ARM7.MRTrack.Progress = 1;
}
else
{
if (dstrgn == Mem7_MainRAM)
{
if (burststart == 2 || A9WENTLAST || DMALastWasMainRAM || dma->DstAddrInc <= 0)
{
if (ARM7Timestamp < MainRAMTimestamp) { ARM7Timestamp = MainRAMTimestamp; if (A9PRIORITY) return; }
MainRAMTimestamp = ARM7Timestamp + 8;
ARM7Timestamp += 3;
MainRAMLastAccess = A7LAST;
}
else
{
ARM7Timestamp += 1;
MainRAMTimestamp += 1;
}
DMALastWasMainRAM = true;
}
else
{
if (burststart == 2 || dma->DstAddrInc <= 0) ARM7Timestamp += ARM7MemTimings[dstaddr>>15][0];
else ARM7Timestamp += ARM7MemTimings[dstaddr>>15][1] - (burststart <= 0);
DMALastWasMainRAM = false;
}
ARM7Write16(dstaddr, DMAReadHold);
dma->CurSrcAddr += dma->SrcAddrInc<<1;
dma->CurDstAddr += dma->DstAddrInc<<1;
dma->IterCount--;
dma->RemCount--;
burststart -= 1;
if (burststart <= 0) Running = 1;
else dma->Running = 2;
//DMA9Timestamp = (A9ContentionTS << ARM9ClockShift) - 1;
memset(&ARM7.MRTrack, 0, sizeof(ARM7.MRTrack));
ConTSLock = false;
if (dma->RemCount)
{
if (dma->IterCount == 0)
{
dma->Running = 0;
ResumeCPU(1, 1<<dma->Num);
}
break;
}
if (!(dma->Cnt & (1<<25)))
dma->Cnt &= ~(1<<31);
if (dma->Cnt & (1<<30))
SetIRQ(1, IRQ_DMA0 + dma->Num);
dma->Running = 0;
dma->InProgress = false;
ResumeCPU(1, 1<<dma->Num);
}
break;
}
}
}
@ -1570,6 +1768,8 @@ u32 NDS::RunFrame()
if (MainRAMHandle()) break;
}
ARM7Target = target; // this line proooobably shouldn't be? but if i dont do it then several games wont work with main ram contention implemented for arm9 dmas???
while (ARM7Timestamp < ARM7Target)
{
//printf("A7 LOOP: %lli %lli\n", ARM9Timestamp>>ARM9ClockShift, ARM7Timestamp);