start devolving things.

also implement proper DMA timings.

will not build. don't try.
This commit is contained in:
StapleButter 2018-12-08 22:33:41 +01:00
parent 86dae1a25c
commit c6fb152d80
5 changed files with 382 additions and 460 deletions

View File

@ -57,61 +57,6 @@ DMA::DMA(u32 cpu, u32 num)
else
CountMask = (num==3 ? 0x0000FFFF : 0x00003FFF);
// TODO: merge with the one in ARM.cpp, somewhere
for (int i = 0; i < 16; i++)
{
Waitstates[0][i] = 1;
Waitstates[1][i] = 1;
}
if (!cpu)
{
// ARM9
// note: 33MHz cycles
Waitstates[0][0x2] = 1;
Waitstates[0][0x3] = 1;
Waitstates[0][0x4] = 1;
Waitstates[0][0x5] = 1;
Waitstates[0][0x6] = 1;
Waitstates[0][0x7] = 1;
Waitstates[0][0x8] = 6;
Waitstates[0][0x9] = 6;
Waitstates[0][0xA] = 10;
Waitstates[0][0xF] = 1;
Waitstates[1][0x2] = 2;
Waitstates[1][0x3] = 1;
Waitstates[1][0x4] = 1;
Waitstates[1][0x5] = 2;
Waitstates[1][0x6] = 2;
Waitstates[1][0x7] = 1;
Waitstates[1][0x8] = 12;
Waitstates[1][0x9] = 12;
Waitstates[1][0xA] = 10;
Waitstates[1][0xF] = 1;
}
else
{
// ARM7
Waitstates[0][0x0] = 1;
Waitstates[0][0x2] = 1;
Waitstates[0][0x3] = 1;
Waitstates[0][0x4] = 1;
Waitstates[0][0x6] = 1;
Waitstates[0][0x8] = 6;
Waitstates[0][0x9] = 6;
Waitstates[0][0xA] = 10;
Waitstates[1][0x0] = 1;
Waitstates[1][0x2] = 2;
Waitstates[1][0x3] = 1;
Waitstates[1][0x4] = 1;
Waitstates[1][0x6] = 2;
Waitstates[1][0x8] = 12;
Waitstates[1][0x9] = 12;
Waitstates[1][0xA] = 10;
}
Reset();
}
@ -244,8 +189,55 @@ s32 DMA::Run(s32 cycles)
Executing = true;
// add NS penalty for first accesses in burst
bool burststart;
if (StartMode == 0x07 && RemCount > 112)
burststart = (IterCount == 112);
else
burststart = (IterCount == RemCount);
if (!(Cnt & 0x04000000))
{
int unitcycles;
if (Num == 0)
{
if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02)
{
unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 12][0] + NDS::ARM9MemTimings[CurDstAddr >> 12][0];
}
else
{
unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 12][1] + NDS::ARM9MemTimings[CurDstAddr >> 12][1];
if ((CurSrcAddr >> 24) == (CurDstAddr >> 24))
unitcycles++;
if (burststart)
{
cycles -= (NDS::ARM9MemTimings[CurSrcAddr >> 12][0] + NDS::ARM9MemTimings[CurDstAddr >> 12][0]);
cycles += unitcycles;
}
}
}
else
{
if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02)
{
unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 17][0] + NDS::ARM7MemTimings[CurDstAddr >> 17][0];
}
else
{
unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 17][1] + NDS::ARM7MemTimings[CurDstAddr >> 17][1];
if ((CurSrcAddr >> 23) == (CurDstAddr >> 23))
unitcycles++;
if (burststart)
{
cycles -= (NDS::ARM7MemTimings[CurSrcAddr >> 17][0] + NDS::ARM7MemTimings[CurDstAddr >> 17][0]);
cycles += unitcycles;
}
}
}
int (*readfn)(u32,u32*) = CPU ? NDS::ARM7Read16 : NDS::ARM9Read16;
int (*writefn)(u32,u16) = CPU ? NDS::ARM7Write16 : NDS::ARM9Write16;
@ -255,8 +247,7 @@ s32 DMA::Run(s32 cycles)
readfn(CurSrcAddr, &val);
writefn(CurDstAddr, val);
s32 c = 1;//(Waitstates[0][(CurSrcAddr >> 24) & 0xF] + Waitstates[0][(CurDstAddr >> 24) & 0xF]);
cycles -= c;
cycles -= unitcycles;
NDS::RunTimingCriticalDevices(CPU, c);
CurSrcAddr += SrcAddrInc<<1;
@ -267,23 +258,49 @@ s32 DMA::Run(s32 cycles)
}
else
{
// optimized path for typical GXFIFO DMA
// likely not worth it tbh
/*if (IsGXFIFODMA)
int unitcycles;
if (Num == 0)
{
while (IterCount > 0 && cycles > 0)
if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02)
{
GPU3D::WriteToGXFIFO(*(u32*)&NDS::MainRAM[CurSrcAddr&0x3FFFFF]);
s32 c = (Waitstates[1][0x2] + Waitstates[1][0x4]);
cycles -= c;
NDS::RunTimingCriticalDevices(0, c);
CurSrcAddr += SrcAddrInc<<2;
IterCount--;
RemCount--;
unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 12][2] + NDS::ARM9MemTimings[CurDstAddr >> 12][2];
}
}*/
else
{
unitcycles = NDS::ARM9MemTimings[CurSrcAddr >> 12][3] + NDS::ARM9MemTimings[CurDstAddr >> 12][3];
if ((CurSrcAddr >> 24) == (CurDstAddr >> 24))
unitcycles++;
else if ((CurSrcAddr >> 24) == 0x02)
unitcycles--;
if (burststart)
{
cycles -= (NDS::ARM9MemTimings[CurSrcAddr >> 12][2] + NDS::ARM9MemTimings[CurDstAddr >> 12][2]);
cycles += unitcycles;
}
}
}
else
{
if ((CurSrcAddr >> 24) == 0x02 && (CurDstAddr >> 24) == 0x02)
{
unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 17][2] + NDS::ARM7MemTimings[CurDstAddr >> 17][2];
}
else
{
unitcycles = NDS::ARM7MemTimings[CurSrcAddr >> 17][3] + NDS::ARM7MemTimings[CurDstAddr >> 17][3];
if ((CurSrcAddr >> 23) == (CurDstAddr >> 23))
unitcycles++;
else if ((CurSrcAddr >> 24) == 0x02)
unitcycles--;
if (burststart)
{
cycles -= (NDS::ARM7MemTimings[CurSrcAddr >> 17][2] + NDS::ARM7MemTimings[CurDstAddr >> 17][2]);
cycles += unitcycles;
}
}
}
int (*readfn)(u32,u32*) = CPU ? NDS::ARM7Read32 : NDS::ARM9Read32;
int (*writefn)(u32,u32) = CPU ? NDS::ARM7Write32 : NDS::ARM9Write32;
@ -294,8 +311,7 @@ s32 DMA::Run(s32 cycles)
readfn(CurSrcAddr, &val);
writefn(CurDstAddr, val);
s32 c = 1;//(Waitstates[1][(CurSrcAddr >> 24) & 0xF] + Waitstates[1][(CurDstAddr >> 24) & 0xF]);
cycles -= c;
cycles -= unitcycles;
NDS::RunTimingCriticalDevices(CPU, c);
CurSrcAddr += SrcAddrInc<<2;

View File

@ -65,8 +65,6 @@ public:
private:
u32 CPU, Num;
s32 Waitstates[2][16];
u32 StartMode;
u32 CurSrcAddr;
u32 CurDstAddr;

File diff suppressed because it is too large Load Diff

View File

@ -87,77 +87,15 @@ typedef struct
} Timer;
enum
{
Region9_Void = 0,
Region9_BIOS,
Region9_ICache,
Region9_DCache,
Region9_ITCM,
Region9_DTCM,
Region9_MainRAM,
Region9_SharedWRAM,
Region9_IO,
Region9_Palette,
Region9_VRAM_ABG,
Region9_VRAM_BBG,
Region9_VRAM_AOBJ,
Region9_VRAM_BOBJ,
Region9_VRAM_LCDC,
Region9_OAM,
Region9_GBAROM,
Region9_GBARAM,
Region9_MAX
};
enum
{
Region7_Void = 0,
Region7_BIOS,
Region7_MainRAM,
Region7_SharedWRAM,
Region7_ARM7WRAM,
Region7_IO,
Region7_Wifi0,
Region7_Wifi1,
Region7_VRAM,
Region7_GBAROM,
Region7_GBARAM,
Region7_MAX
};
typedef struct
{
u8 BusType; // 0=32bit 1=16bit 2=8bit/GBARAM 3=ARM9/internal
u8 DelayS; // baseline sequential access delay
u8 DelayN; // baseline nonsequential access delay
u8 _pad;
} RegionTimings;
typedef struct
{
int Region;
u8* Mem;
u32 Mask;
} MemRegion;
extern u8 ARM9MemTimings[Region9_MAX+1][4];
extern u8 ARM7MemTimings[Region7_MAX+1][4];
extern u8 ARM9MemTimings[0x100000][4];
extern u8 ARM7MemTimings[0x20000][4];
// hax
extern u32 IME[2];
@ -185,6 +123,9 @@ void Stop();
bool DoSavestate(Savestate* file);
void SetARM9RegionTimings(u32 addrstart, u32 addrend, int buswidth, int nonseq, int seq);
void SetARM7RegionTimings(u32 addrstart, u32 addrend, int buswidth, int nonseq, int seq);
bool LoadROM(const char* path, const char* sram, bool direct);
void LoadBIOS();
void SetupDirectBoot();
@ -224,21 +165,21 @@ void StopDMAs(u32 cpu, u32 mode);
void RunTimingCriticalDevices(u32 cpu, s32 cycles);
int ARM9Read8(u32 addr, u32* val);
int ARM9Read16(u32 addr, u32* val);
int ARM9Read32(u32 addr, u32* val);
int ARM9Write8(u32 addr, u8 val);
int ARM9Write16(u32 addr, u16 val);
int ARM9Write32(u32 addr, u32 val);
u8 ARM9Read8(u32 addr);
u16 ARM9Read16(u32 addr);
u32 ARM9Read32(u32 addr);
void ARM9Write8(u32 addr, u8 val);
void ARM9Write16(u32 addr, u16 val);
void ARM9Write32(u32 addr, u32 val);
bool ARM9GetMemRegion(u32 addr, bool write, MemRegion* region);
int ARM7Read8(u32 addr, u32* val);
int ARM7Read16(u32 addr, u32* val);
int ARM7Read32(u32 addr, u32* val);
int ARM7Write8(u32 addr, u8 val);
int ARM7Write16(u32 addr, u16 val);
int ARM7Write32(u32 addr, u32 val);
u8 ARM7Read8(u32 addr);
u16 ARM7Read16(u32 addr);
u32 ARM7Read32(u32 addr);
void ARM7Write8(u32 addr, u8 val);
void ARM7Write16(u32 addr, u16 val);
void ARM7Write32(u32 addr, u32 val);
bool ARM7GetMemRegion(u32 addr, bool write, MemRegion* region);

View File

@ -214,7 +214,7 @@ void Channel::FIFO_BufferData()
for (u32 i = 0; i < burstlen; i += 4)
{
NDS::ARM7Read32(SrcAddr + FIFOReadOffset, &FIFO[FIFOWritePos]);
FIFO[FIFOWritePos] = NDS::ARM7Read32(SrcAddr + FIFOReadOffset);
FIFOReadOffset += 4;
FIFOWritePos++;
FIFOWritePos &= 0x7;