storing all the PU shito in this branch for future use

This commit is contained in:
StapleButter 2018-12-07 14:20:38 +01:00
parent 0b1c2f9691
commit f8ff6e2e3f
7 changed files with 390 additions and 71 deletions

View File

@ -100,8 +100,8 @@ void ARM::Reset()
void ARMv5::Reset() void ARMv5::Reset()
{ {
ARM::Reset();
CP15Reset(); CP15Reset();
ARM::Reset();
} }
@ -158,7 +158,7 @@ void ARM::SetupCodeMem(u32 addr)
NDS::ARM7GetMemRegion(addr, false, &CodeMem); NDS::ARM7GetMemRegion(addr, false, &CodeMem);
} }
} }
namespace GPU{extern u16 VCount;}
void ARMv5::JumpTo(u32 addr, bool restorecpsr) void ARMv5::JumpTo(u32 addr, bool restorecpsr)
{ {
if (restorecpsr) if (restorecpsr)
@ -173,10 +173,19 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
//if (addr == 0x0201764C) printf("capture test %d: R1=%08X\n", R[6], R[1]); //if (addr == 0x0201764C) printf("capture test %d: R1=%08X\n", R[6], R[1]);
//if (addr == 0x020175D8) printf("capture test %d: res=%08X\n", R[6], R[0]); //if (addr == 0x020175D8) printf("capture test %d: res=%08X\n", R[6], R[0]);
// R0=DMA# R1=src R2=size // R0=DMA# R1=src R2=size
if (addr==0x1FFD9E0) printf("[%03d] FMVdec\n", GPU::VCount);
if (R[15]==0x1FFDF40) printf("[%03d] FMVdec FINISHED\n", GPU::VCount);
if (addr==0x202585C)
{
//u32 dorp; NDS::ARM9Read32(0x20630DC, &dorp);
//printf("[%03d] IRQ handler thing. wait=%08X\n", GPU::VCount, dorp);
}
u32 oldregion = R[15] >> 23; u32 oldregion = R[15] >> 23;
u32 newregion = addr >> 23; u32 newregion = addr >> 23;
s32 cycles;
if (addr & 0x1) if (addr & 0x1)
{ {
addr &= ~0x1; addr &= ~0x1;
@ -190,13 +199,13 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
{ {
NextInstr[0] = CodeRead32(addr-2) >> 16; NextInstr[0] = CodeRead32(addr-2) >> 16;
NextInstr[1] = CodeRead32(addr+2); NextInstr[1] = CodeRead32(addr+2);
Cycles += NDS::ARM9MemTimings[CodeRegion][2] * 2; cycles = NDS::ARM9MemTimings[CodeRegion][2] * 2;
} }
else else
{ {
NextInstr[0] = CodeRead32(addr); NextInstr[0] = CodeRead32(addr);
NextInstr[1] = NextInstr[0] >> 16; NextInstr[1] = NextInstr[0] >> 16;
Cycles += NDS::ARM9MemTimings[CodeRegion][2]; cycles = NDS::ARM9MemTimings[CodeRegion][2];
} }
CPSR |= 0x20; CPSR |= 0x20;
@ -210,10 +219,22 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
NextInstr[0] = CodeRead32(addr); NextInstr[0] = CodeRead32(addr);
NextInstr[1] = CodeRead32(addr+4); NextInstr[1] = CodeRead32(addr+4);
Cycles += NDS::ARM9MemTimings[CodeRegion][2] * 2; cycles = NDS::ARM9MemTimings[CodeRegion][2] * 2;
CPSR &= ~0x20; CPSR &= ~0x20;
} }
// TODO: investigate this
// firmware jumps to region 01FFxxxx, but region 5 (01000000-02000000) is set to non-executable
// is melonDS fucked up somewhere, or is the DS PU just incomplete/crapoed?
/*if (!(PU_Map[addr>>12] & 0x04))
{
printf("jumped to %08X. very bad\n", addr);
PrefetchAbort();
return;
}*/
Cycles += cycles;
} }
void ARMv4::JumpTo(u32 addr, bool restorecpsr) void ARMv4::JumpTo(u32 addr, bool restorecpsr)
@ -365,6 +386,15 @@ void ARM::UpdateMode(u32 oldmode, u32 newmode)
} }
#undef SWAP #undef SWAP
if (Num == 0)
{
/*if ((newmode & 0x1F) == 0x16)
((ARMv5*)this)->PU_Map = ((ARMv5*)this)->PU_UserMap;
else
((ARMv5*)this)->PU_Map = ((ARMv5*)this)->PU_PrivMap;*/
//if ((newmode & 0x1F) == 0x10) printf("!! USER MODE\n");
}
} }
void ARM::TriggerIRQ() void ARM::TriggerIRQ()
@ -382,6 +412,43 @@ void ARM::TriggerIRQ()
JumpTo(ExceptionBase + 0x18); JumpTo(ExceptionBase + 0x18);
} }
void ARMv5::PrefetchAbort()
{
printf("prefetch abort\n");
u32 oldcpsr = CPSR;
CPSR &= ~0xBF;
CPSR |= 0x97;
UpdateMode(oldcpsr, CPSR);
// this shouldn't happen, but if it does, we're stuck in some nasty endless loop
// so better take care of it
if (!(PU_Map[ExceptionBase>>12] & 0x04))
{
printf("!!!!! EXCEPTION REGION NOT READABLE. THIS IS VERY BAD!!\n");
NDS::Stop();
return;
}
R_IRQ[2] = oldcpsr;
R[14] = R[15] + (oldcpsr & 0x20 ? 2 : 0);
JumpTo(ExceptionBase + 0x0C);
}
void ARMv5::DataAbort()
{
printf("data abort\n");
u32 oldcpsr = CPSR;
CPSR &= ~0xBF;
CPSR |= 0x97;
UpdateMode(oldcpsr, CPSR);
R_IRQ[2] = oldcpsr;
R[14] = R[15] + (oldcpsr & 0x20 ? 6 : 4);
JumpTo(ExceptionBase + 0x10);
}
s32 ARMv5::Execute() s32 ARMv5::Execute()
{ {
if (Halted) if (Halted)

View File

@ -166,6 +166,9 @@ public:
void JumpTo(u32 addr, bool restorecpsr = false); void JumpTo(u32 addr, bool restorecpsr = false);
void PrefetchAbort();
void DataAbort();
s32 Execute(); s32 Execute();
// all code accesses are forced nonseq 32bit // all code accesses are forced nonseq 32bit
@ -223,6 +226,8 @@ public:
void UpdateDTCMSetting(); void UpdateDTCMSetting();
void UpdateITCMSetting(); void UpdateITCMSetting();
void UpdatePURegions();
void CP15Write(u32 id, u32 val); void CP15Write(u32 id, u32 val);
u32 CP15Read(u32 id); u32 CP15Read(u32 id);
@ -243,6 +248,16 @@ public:
u32 PU_DataRW; u32 PU_DataRW;
u32 PU_Region[8]; u32 PU_Region[8];
// 0=dataR 1=dataW 2=codeR 4=datacache 5=datawrite 6=codecache
// seems the DS operates entirely under privileged mode? it never sets user regions to be read/writable
// TODO: investigate
u8 PU_UserMap[0x100000];
u8 PU_PrivMap[0x100000];
//u8* PU_Map;
#define PU_Map PU_PrivMap
bool CodeCached;
}; };
class ARMv4 : public ARM class ARMv4 : public ARM

View File

@ -34,8 +34,8 @@ void A_UNK(ARM* cpu)
//for (int i = 0; i < 16; i++) printf("R%d: %08X\n", i, cpu->R[i]); //for (int i = 0; i < 16; i++) printf("R%d: %08X\n", i, cpu->R[i]);
//NDS::Halt(); //NDS::Halt();
u32 oldcpsr = cpu->CPSR; u32 oldcpsr = cpu->CPSR;
cpu->CPSR &= ~0xFF; cpu->CPSR &= ~0xBF;
cpu->CPSR |= 0xDB; cpu->CPSR |= 0x9B;
cpu->UpdateMode(oldcpsr, cpu->CPSR); cpu->UpdateMode(oldcpsr, cpu->CPSR);
cpu->R_UND[2] = oldcpsr; cpu->R_UND[2] = oldcpsr;
@ -48,8 +48,8 @@ void T_UNK(ARM* cpu)
printf("undefined THUMB%d instruction %04X @ %08X\n", cpu->Num?7:9, cpu->CurInstr, cpu->R[15]-4); printf("undefined THUMB%d instruction %04X @ %08X\n", cpu->Num?7:9, cpu->CurInstr, cpu->R[15]-4);
//NDS::Halt(); //NDS::Halt();
u32 oldcpsr = cpu->CPSR; u32 oldcpsr = cpu->CPSR;
cpu->CPSR &= ~0xFF; cpu->CPSR &= ~0xBF;
cpu->CPSR |= 0xDB; cpu->CPSR |= 0x9B;
cpu->UpdateMode(oldcpsr, cpu->CPSR); cpu->UpdateMode(oldcpsr, cpu->CPSR);
cpu->R_UND[2] = oldcpsr; cpu->R_UND[2] = oldcpsr;
@ -221,8 +221,8 @@ void A_MRC(ARM* cpu)
void A_SVC(ARM* cpu) void A_SVC(ARM* cpu)
{ {
u32 oldcpsr = cpu->CPSR; u32 oldcpsr = cpu->CPSR;
cpu->CPSR &= ~0xFF; cpu->CPSR &= ~0xBF;
cpu->CPSR |= 0xD3; cpu->CPSR |= 0x93;
cpu->UpdateMode(oldcpsr, cpu->CPSR); cpu->UpdateMode(oldcpsr, cpu->CPSR);
cpu->R_SVC[2] = oldcpsr; cpu->R_SVC[2] = oldcpsr;
@ -233,8 +233,8 @@ void A_SVC(ARM* cpu)
void T_SVC(ARM* cpu) void T_SVC(ARM* cpu)
{ {
u32 oldcpsr = cpu->CPSR; u32 oldcpsr = cpu->CPSR;
cpu->CPSR &= ~0xFF; cpu->CPSR &= ~0xBF;
cpu->CPSR |= 0xD3; cpu->CPSR |= 0x93;
cpu->UpdateMode(oldcpsr, cpu->CPSR); cpu->UpdateMode(oldcpsr, cpu->CPSR);
cpu->R_SVC[2] = oldcpsr; cpu->R_SVC[2] = oldcpsr;

View File

@ -25,7 +25,7 @@
void ARMv5::CP15Reset() void ARMv5::CP15Reset()
{ {
CP15Control = 0x78; // dunno CP15Control = 0x2078; // dunno
DTCMSetting = 0; DTCMSetting = 0;
ITCMSetting = 0; ITCMSetting = 0;
@ -36,6 +36,16 @@ void ARMv5::CP15Reset()
ITCMSize = 0; ITCMSize = 0;
DTCMBase = 0xFFFFFFFF; DTCMBase = 0xFFFFFFFF;
DTCMSize = 0; DTCMSize = 0;
PU_CodeCacheable = 0;
PU_DataCacheable = 0;
PU_DataCacheWrite = 0;
PU_CodeRW = 0;
PU_DataRW = 0;
memset(PU_Region, 0, 8*sizeof(u32));
UpdatePURegions();
} }
void ARMv5::CP15DoSavestate(Savestate* file) void ARMv5::CP15DoSavestate(Savestate* file)
@ -64,13 +74,13 @@ void ARMv5::UpdateDTCMSetting()
{ {
DTCMBase = DTCMSetting & 0xFFFFF000; DTCMBase = DTCMSetting & 0xFFFFF000;
DTCMSize = 0x200 << ((DTCMSetting >> 1) & 0x1F); DTCMSize = 0x200 << ((DTCMSetting >> 1) & 0x1F);
//printf("DTCM [%08X] enabled at %08X, size %X\n", DTCMSetting, DTCMBase, DTCMSize); printf("DTCM [%08X] enabled at %08X, size %X\n", DTCMSetting, DTCMBase, DTCMSize);
} }
else else
{ {
DTCMBase = 0xFFFFFFFF; DTCMBase = 0xFFFFFFFF;
DTCMSize = 0; DTCMSize = 0;
//printf("DTCM disabled\n"); printf("DTCM disabled\n");
} }
} }
@ -79,12 +89,128 @@ void ARMv5::UpdateITCMSetting()
if (CP15Control & (1<<18)) if (CP15Control & (1<<18))
{ {
ITCMSize = 0x200 << ((ITCMSetting >> 1) & 0x1F); ITCMSize = 0x200 << ((ITCMSetting >> 1) & 0x1F);
//printf("ITCM [%08X] enabled at %08X, size %X\n", ITCMSetting, 0, ITCMSize); printf("ITCM [%08X] enabled at %08X, size %X\n", ITCMSetting, 0, ITCMSize);
} }
else else
{ {
ITCMSize = 0; ITCMSize = 0;
//printf("ITCM disabled\n"); printf("ITCM disabled\n");
}
}
void ARMv5::UpdatePURegions()
{
if (!(CP15Control & (1<<0)))
{
// PU disabled
u8 mask = 0x07;
if (CP15Control & (1<<2)) mask |= 0x30;
if (CP15Control & (1<<12)) mask |= 0x40;
memset(PU_UserMap, mask, 0x100000);
memset(PU_PrivMap, mask, 0x100000);
return;
}
memset(PU_UserMap, 0, 0x100000);
memset(PU_PrivMap, 0, 0x100000);
u32 coderw = PU_CodeRW;
u32 datarw = PU_DataRW;
u32 codecache, datacache, datawrite;
// datacache/datawrite
// 0/0: goes to memory
// 0/1: goes to memory
// 1/0: goes to memory and cache
// 1/1: goes to cache
if (CP15Control & (1<<12))
codecache = PU_CodeCacheable;
else
codecache = 0;
if (CP15Control & (1<<2))
{
datacache = PU_DataCacheable;
datawrite = PU_DataCacheWrite;
}
else
{
datacache = 0;
datawrite = 0;
}
for (int n = 0; n < 8; n++)
{
u32 rgn = PU_Region[n];
if (!(rgn & (1<<0))) continue;
u32 start = rgn >> 12;
u32 sz = 2 << ((rgn >> 1) & 0x1F);
u32 end = start + (sz >> 12);
// TODO: check alignment of start
u8 usermask = 0;
u8 privmask = 0;
switch (datarw & 0xF)
{
case 0: break;
case 1: privmask |= 0x03; break;
case 2: privmask |= 0x03; usermask |= 0x01; break;
case 3: privmask |= 0x03; usermask |= 0x03; break;
case 5: privmask |= 0x01; break;
case 6: privmask |= 0x01; usermask |= 0x01; break;
default: printf("!! BAD DATARW VALUE %d\n", datarw&0xF);
}
switch (coderw & 0xF)
{
case 0: break;
case 1: privmask |= 0x04; break;
case 2: privmask |= 0x04; usermask |= 0x04; break;
case 3: privmask |= 0x04; usermask |= 0x04; break;
case 5: privmask |= 0x04; break;
case 6: privmask |= 0x04; usermask |= 0x04; break;
default: printf("!! BAD CODERW VALUE %d\n", datarw&0xF);
}
if (datacache & 0x1)
{
privmask |= 0x10;
usermask |= 0x10;
if (datawrite & 0x1)
{
privmask |= 0x20;
usermask |= 0x20;
}
}
if (codecache & 0x1)
{
privmask |= 0x40;
usermask |= 0x40;
}
printf("PU region %d: %08X-%08X, user=%02X priv=%02X\n", n, start<<12, end<<12, usermask, privmask);
for (u32 i = start; i < end; i++)
{
PU_UserMap[i] = usermask;
PU_PrivMap[i] = privmask;
}
coderw >>= 4;
datarw >>= 4;
codecache >>= 1;
datacache >>= 1;
datawrite >>= 1;
} }
} }
@ -96,28 +222,39 @@ void ARMv5::CP15Write(u32 id, u32 val)
switch (id) switch (id)
{ {
case 0x100: case 0x100:
val &= 0x000FF085; {
CP15Control &= ~0x000FF085; u32 old = CP15Control;
CP15Control |= val; val &= 0x000FF085;
UpdateDTCMSetting(); CP15Control &= ~0x000FF085;
UpdateITCMSetting(); CP15Control |= val;
printf("CP15Control = %08X (%08X->%08X)\n", CP15Control, old, val);
UpdateDTCMSetting();
UpdateITCMSetting();
if ((old & 0x1005) != (val & 0x1005)) UpdatePURegions();
if (val & (1<<7)) printf("!!!! ARM9 BIG ENDIAN MODE. VERY BAD. SHIT GONNA ASPLODE NOW\n");
if (val & (1<<13)) ExceptionBase = 0xFFFF0000;
else ExceptionBase = 0x00000000;
}
return; return;
case 0x200: // data cacheable case 0x200: // data cacheable
PU_DataCacheable = val; PU_DataCacheable = val;
printf("PU: DataCacheable=%08X\n", val); printf("PU: DataCacheable=%08X\n", val);
UpdatePURegions();
return; return;
case 0x201: // code cacheable case 0x201: // code cacheable
PU_CodeCacheable = val; PU_CodeCacheable = val;
printf("PU: CodeCacheable=%08X\n", val); printf("PU: CodeCacheable=%08X\n", val);
UpdatePURegions();
return; return;
case 0x300: // data cache write-buffer case 0x300: // data cache write-buffer
PU_DataCacheWrite = val; PU_DataCacheWrite = val;
printf("PU: DataCacheWrite=%08X\n", val); printf("PU: DataCacheWrite=%08X\n", val);
UpdatePURegions();
return; return;
@ -132,6 +269,7 @@ void ARMv5::CP15Write(u32 id, u32 val)
PU_DataRW |= ((val & 0x3000) << 12); PU_DataRW |= ((val & 0x3000) << 12);
PU_DataRW |= ((val & 0xC000) << 14); PU_DataRW |= ((val & 0xC000) << 14);
printf("PU: DataRW=%08X (legacy %08X)\n", PU_DataRW, val); printf("PU: DataRW=%08X (legacy %08X)\n", PU_DataRW, val);
UpdatePURegions();
return; return;
case 0x501: // legacy code permissions case 0x501: // legacy code permissions
@ -145,16 +283,19 @@ void ARMv5::CP15Write(u32 id, u32 val)
PU_CodeRW |= ((val & 0x3000) << 12); PU_CodeRW |= ((val & 0x3000) << 12);
PU_CodeRW |= ((val & 0xC000) << 14); PU_CodeRW |= ((val & 0xC000) << 14);
printf("PU: CodeRW=%08X (legacy %08X)\n", PU_CodeRW, val); printf("PU: CodeRW=%08X (legacy %08X)\n", PU_CodeRW, val);
UpdatePURegions();
return; return;
case 0x502: // data permissions case 0x502: // data permissions
PU_DataRW = val; PU_DataRW = val;
printf("PU: DataRW=%08X\n", PU_DataRW); printf("PU: DataRW=%08X\n", PU_DataRW);
UpdatePURegions();
return; return;
case 0x503: // code permissions case 0x503: // code permissions
PU_CodeRW = val; PU_CodeRW = val;
printf("PU: CodeRW=%08X\n", PU_CodeRW); printf("PU: CodeRW=%08X\n", PU_CodeRW);
UpdatePURegions();
return; return;
@ -179,6 +320,7 @@ void ARMv5::CP15Write(u32 id, u32 val)
printf("%s, ", val&1 ? "enabled":"disabled"); printf("%s, ", val&1 ? "enabled":"disabled");
printf("%08X-", val&0xFFFFF000); printf("%08X-", val&0xFFFFF000);
printf("%08X\n", (val&0xFFFFF000)+(2<<((val&0x3E)>>1))); printf("%08X\n", (val&0xFFFFF000)+(2<<((val&0x3E)>>1)));
UpdatePURegions();
return; return;
@ -318,7 +460,7 @@ u32 ARMv5::CP15Read(u32 id)
u32 ARMv5::CodeRead32(u32 addr) u32 ARMv5::CodeRead32(u32 addr)
{ {
// PU/cache check here u8 pu = PU_Map[addr>>12];
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
@ -328,34 +470,49 @@ u32 ARMv5::CodeRead32(u32 addr)
u32 ret; u32 ret;
CodeRegion = NDS::ARM9Read32(addr, &ret); CodeRegion = NDS::ARM9Read32(addr, &ret);
if (pu & 0x40) CodeRegion = NDS::Region9_ICache;
return ret; return ret;
} }
bool ARMv5::DataRead8(u32 addr, u32* val, u32 flags) bool ARMv5::DataRead8(u32 addr, u32* val, u32 flags)
{ {
// PU/cache check here u8 pu = PU_Map[addr>>12];
/*if (!(pu & 0x01))
{
DataAbort();
return false;
}*/
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_ITCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*val = *(u8*)&ITCM[addr & 0x7FFF]; *val = *(u8*)&ITCM[addr & 0x7FFF];
return true; return true;
} }
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_DTCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*val = *(u8*)&DTCM[(addr - DTCMBase) & 0x3FFF]; *val = *(u8*)&DTCM[(addr - DTCMBase) & 0x3FFF];
return true; return true;
} }
DataRegion = NDS::ARM9Read8(addr, val); DataRegion = NDS::ARM9Read8(addr, val);
if (flags & RWFlags_Nonseq) if (pu & 0x10)
DataCycles = NDS::ARM9MemTimings[DataRegion][0]; {
DataRegion = NDS::Region9_DCache;
if (flags & RWFlags_Nonseq) DataCycles = 2;
else DataCycles += 2;
}
else else
DataCycles += NDS::ARM9MemTimings[DataRegion][1]; {
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
}
return true; return true;
} }
@ -363,28 +520,42 @@ bool ARMv5::DataRead16(u32 addr, u32* val, u32 flags)
{ {
addr &= ~1; addr &= ~1;
// PU/cache check here u8 pu = PU_Map[addr>>12];
/*if (!(pu & 0x01))
{
DataAbort();
return false;
}*/
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_ITCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*val = *(u16*)&ITCM[addr & 0x7FFF]; *val = *(u16*)&ITCM[addr & 0x7FFF];
return true; return true;
} }
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_DTCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*val = *(u16*)&DTCM[(addr - DTCMBase) & 0x3FFF]; *val = *(u16*)&DTCM[(addr - DTCMBase) & 0x3FFF];
return true; return true;
} }
DataRegion = NDS::ARM9Read16(addr, val); DataRegion = NDS::ARM9Read16(addr, val);
if (flags & RWFlags_Nonseq) if (pu & 0x10)
DataCycles = NDS::ARM9MemTimings[DataRegion][0]; {
DataRegion = NDS::Region9_DCache;
if (flags & RWFlags_Nonseq) DataCycles = 2;
else DataCycles += 2;
}
else else
DataCycles += NDS::ARM9MemTimings[DataRegion][1]; {
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
}
return true; return true;
} }
@ -392,55 +563,83 @@ bool ARMv5::DataRead32(u32 addr, u32* val, u32 flags)
{ {
addr &= ~3; addr &= ~3;
// PU/cache check here u8 pu = PU_Map[addr>>12];
/*if (!(pu & 0x01))
{
DataAbort();
return false;
}*/
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_ITCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*val = *(u32*)&ITCM[addr & 0x7FFF]; *val = *(u32*)&ITCM[addr & 0x7FFF];
return true; return true;
} }
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_DTCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*val = *(u32*)&DTCM[(addr - DTCMBase) & 0x3FFF]; *val = *(u32*)&DTCM[(addr - DTCMBase) & 0x3FFF];
return true; return true;
} }
DataRegion = NDS::ARM9Read32(addr, val); DataRegion = NDS::ARM9Read32(addr, val);
if (flags & RWFlags_Nonseq) if (pu & 0x10)
DataCycles = NDS::ARM9MemTimings[DataRegion][2]; {
DataRegion = NDS::Region9_DCache;
if (flags & RWFlags_Nonseq) DataCycles = 2;
else DataCycles += 2;
}
else else
DataCycles += NDS::ARM9MemTimings[DataRegion][3]; {
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
}
return true; return true;
} }
bool ARMv5::DataWrite8(u32 addr, u8 val, u32 flags) bool ARMv5::DataWrite8(u32 addr, u8 val, u32 flags)
{ {
// PU/cache check here u8 pu = PU_Map[addr>>12];
/*if (!(pu & 0x02))
{
DataAbort();
return false;
}*/
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_ITCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*(u8*)&ITCM[addr & 0x7FFF] = val; *(u8*)&ITCM[addr & 0x7FFF] = val;
return true; return true;
} }
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_DTCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*(u8*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val; *(u8*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val;
return true; return true;
} }
DataRegion = NDS::ARM9Write8(addr, val); DataRegion = NDS::ARM9Write8(addr, val);
if (flags & RWFlags_Nonseq) if (pu & 0x20)
DataCycles = NDS::ARM9MemTimings[DataRegion][0]; {
DataRegion = NDS::Region9_DCache;
if (flags & RWFlags_Nonseq) DataCycles = 2;
else DataCycles += 2;
}
else else
DataCycles += NDS::ARM9MemTimings[DataRegion][1]; {
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
}
return true; return true;
} }
@ -448,28 +647,42 @@ bool ARMv5::DataWrite16(u32 addr, u16 val, u32 flags)
{ {
addr &= ~1; addr &= ~1;
// PU/cache check here u8 pu = PU_Map[addr>>12];
/*if (!(pu & 0x02))
{
DataAbort();
return false;
}*/
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_ITCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*(u16*)&ITCM[addr & 0x7FFF] = val; *(u16*)&ITCM[addr & 0x7FFF] = val;
return true; return true;
} }
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_DTCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*(u16*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val; *(u16*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val;
return true; return true;
} }
DataRegion = NDS::ARM9Write16(addr, val); DataRegion = NDS::ARM9Write16(addr, val);
if (flags & RWFlags_Nonseq) if (pu & 0x20)
DataCycles = NDS::ARM9MemTimings[DataRegion][0]; {
DataRegion = NDS::Region9_DCache;
if (flags & RWFlags_Nonseq) DataCycles = 2;
else DataCycles += 2;
}
else else
DataCycles += NDS::ARM9MemTimings[DataRegion][1]; {
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
}
return true; return true;
} }
@ -477,28 +690,42 @@ bool ARMv5::DataWrite32(u32 addr, u32 val, u32 flags)
{ {
addr &= ~3; addr &= ~3;
// PU/cache check here u8 pu = PU_Map[addr>>12];
/*if (!(pu & 0x02))
{
DataAbort();
return false;
}*/
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_ITCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*(u32*)&ITCM[addr & 0x7FFF] = val; *(u32*)&ITCM[addr & 0x7FFF] = val;
return true; return true;
} }
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize)) if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
{ {
DataRegion = NDS::Region9_ITCM; DataRegion = NDS::Region9_DTCM;
DataCycles += 1; if (flags & RWFlags_Nonseq) DataCycles = 1;
else DataCycles += 1;
*(u32*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val; *(u32*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val;
return true; return true;
} }
DataRegion = NDS::ARM9Write32(addr, val); DataRegion = NDS::ARM9Write32(addr, val);
if (flags & RWFlags_Nonseq) if (pu & 0x20)
DataCycles = NDS::ARM9MemTimings[DataRegion][2]; {
DataRegion = NDS::Region9_DCache;
if (flags & RWFlags_Nonseq) DataCycles = 2;
else DataCycles += 2;
}
else else
DataCycles += NDS::ARM9MemTimings[DataRegion][3]; {
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
}
return true; return true;
} }

View File

@ -255,7 +255,7 @@ s32 DMA::Run(s32 cycles)
readfn(CurSrcAddr, &val); readfn(CurSrcAddr, &val);
writefn(CurDstAddr, val); writefn(CurDstAddr, val);
s32 c = (Waitstates[0][(CurSrcAddr >> 24) & 0xF] + Waitstates[0][(CurDstAddr >> 24) & 0xF]); s32 c = 1;//(Waitstates[0][(CurSrcAddr >> 24) & 0xF] + Waitstates[0][(CurDstAddr >> 24) & 0xF]);
cycles -= c; cycles -= c;
NDS::RunTimingCriticalDevices(CPU, c); NDS::RunTimingCriticalDevices(CPU, c);
@ -294,7 +294,7 @@ s32 DMA::Run(s32 cycles)
readfn(CurSrcAddr, &val); readfn(CurSrcAddr, &val);
writefn(CurDstAddr, val); writefn(CurDstAddr, val);
s32 c = (Waitstates[1][(CurSrcAddr >> 24) & 0xF] + Waitstates[1][(CurDstAddr >> 24) & 0xF]); s32 c = 1;//(Waitstates[1][(CurSrcAddr >> 24) & 0xF] + Waitstates[1][(CurDstAddr >> 24) & 0xF]);
cycles -= c; cycles -= c;
NDS::RunTimingCriticalDevices(CPU, c); NDS::RunTimingCriticalDevices(CPU, c);

View File

@ -653,12 +653,12 @@ void MapVRAM_I(u32 bank, u8 cnt)
void DisplaySwap(u32 val) void DisplaySwap(u32 val)
{ {
if (val) if (val)
{ {printf("main GPU on top screen\n");
GPU2D_A->SetFramebuffer(&Framebuffer[256*0]); GPU2D_A->SetFramebuffer(&Framebuffer[256*0]);
GPU2D_B->SetFramebuffer(&Framebuffer[256*192]); GPU2D_B->SetFramebuffer(&Framebuffer[256*192]);
} }
else else
{ {printf("main GPU on bottom screen\n");
GPU2D_A->SetFramebuffer(&Framebuffer[256*192]); GPU2D_A->SetFramebuffer(&Framebuffer[256*192]);
GPU2D_B->SetFramebuffer(&Framebuffer[256*0]); GPU2D_B->SetFramebuffer(&Framebuffer[256*0]);
} }
@ -813,6 +813,7 @@ void StartScanline(u32 line)
GPU2D_A->VBlank(); GPU2D_A->VBlank();
GPU2D_B->VBlank(); GPU2D_B->VBlank();
GPU3D::VBlank(); GPU3D::VBlank();
printf("VBlank. PC=%08X\n", NDS::GetPC(0));
} }
else if (VCount == 144) else if (VCount == 144)
{ {

View File

@ -226,6 +226,15 @@ void CalculateTimings(int arm9shift)
{ {
RegionTimings t = ARM9MemTimingInfo[i]; RegionTimings t = ARM9MemTimingInfo[i];
/*if (i==2||i==3) // ARM9 internal
{
ARM9MemTimings[i][0] = 5; // 16-bit N
ARM9MemTimings[i][1] = 5; // 16-bit S
ARM9MemTimings[i][2] = 5; // 32-bit N
ARM9MemTimings[i][3] = 5; // 32-bit S
continue;
}*/
if (t.BusType == 3) // ARM9 internal if (t.BusType == 3) // ARM9 internal
{ {
ARM9MemTimings[i][0] = 1; // 16-bit N ARM9MemTimings[i][0] = 1; // 16-bit N
@ -1030,7 +1039,7 @@ void HandleTimerOverflow(u32 tid)
timer->Counter += timer->Reload << 16; timer->Counter += timer->Reload << 16;
if (timer->Cnt & (1<<6)) if (timer->Cnt & (1<<6))
SetIRQ(tid >> 2, IRQ_Timer0 + (tid & 0x3)); SetIRQ(tid >> 2, IRQ_Timer0 + (tid & 0x3));
//if (tid<4) printf("[%03d] timer%d IRQ\n", GPU::VCount, tid);
if ((tid & 0x3) == 3) if ((tid & 0x3) == 3)
return; return;