storing all the PU shito in this branch for future use
This commit is contained in:
parent
0b1c2f9691
commit
f8ff6e2e3f
77
src/ARM.cpp
77
src/ARM.cpp
|
@ -100,8 +100,8 @@ void ARM::Reset()
|
|||
|
||||
void ARMv5::Reset()
|
||||
{
|
||||
ARM::Reset();
|
||||
CP15Reset();
|
||||
ARM::Reset();
|
||||
}
|
||||
|
||||
|
||||
|
@ -158,7 +158,7 @@ void ARM::SetupCodeMem(u32 addr)
|
|||
NDS::ARM7GetMemRegion(addr, false, &CodeMem);
|
||||
}
|
||||
}
|
||||
|
||||
namespace GPU{extern u16 VCount;}
|
||||
void ARMv5::JumpTo(u32 addr, bool 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 == 0x020175D8) printf("capture test %d: res=%08X\n", R[6], R[0]);
|
||||
// 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 newregion = addr >> 23;
|
||||
|
||||
s32 cycles;
|
||||
|
||||
if (addr & 0x1)
|
||||
{
|
||||
addr &= ~0x1;
|
||||
|
@ -190,13 +199,13 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
|
|||
{
|
||||
NextInstr[0] = CodeRead32(addr-2) >> 16;
|
||||
NextInstr[1] = CodeRead32(addr+2);
|
||||
Cycles += NDS::ARM9MemTimings[CodeRegion][2] * 2;
|
||||
cycles = NDS::ARM9MemTimings[CodeRegion][2] * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
NextInstr[0] = CodeRead32(addr);
|
||||
NextInstr[1] = NextInstr[0] >> 16;
|
||||
Cycles += NDS::ARM9MemTimings[CodeRegion][2];
|
||||
cycles = NDS::ARM9MemTimings[CodeRegion][2];
|
||||
}
|
||||
|
||||
CPSR |= 0x20;
|
||||
|
@ -210,10 +219,22 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
|
|||
|
||||
NextInstr[0] = CodeRead32(addr);
|
||||
NextInstr[1] = CodeRead32(addr+4);
|
||||
Cycles += NDS::ARM9MemTimings[CodeRegion][2] * 2;
|
||||
cycles = NDS::ARM9MemTimings[CodeRegion][2] * 2;
|
||||
|
||||
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)
|
||||
|
@ -365,6 +386,15 @@ void ARM::UpdateMode(u32 oldmode, u32 newmode)
|
|||
}
|
||||
|
||||
#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()
|
||||
|
@ -382,6 +412,43 @@ void ARM::TriggerIRQ()
|
|||
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()
|
||||
{
|
||||
if (Halted)
|
||||
|
|
15
src/ARM.h
15
src/ARM.h
|
@ -166,6 +166,9 @@ public:
|
|||
|
||||
void JumpTo(u32 addr, bool restorecpsr = false);
|
||||
|
||||
void PrefetchAbort();
|
||||
void DataAbort();
|
||||
|
||||
s32 Execute();
|
||||
|
||||
// all code accesses are forced nonseq 32bit
|
||||
|
@ -223,6 +226,8 @@ public:
|
|||
void UpdateDTCMSetting();
|
||||
void UpdateITCMSetting();
|
||||
|
||||
void UpdatePURegions();
|
||||
|
||||
void CP15Write(u32 id, u32 val);
|
||||
u32 CP15Read(u32 id);
|
||||
|
||||
|
@ -243,6 +248,16 @@ public:
|
|||
u32 PU_DataRW;
|
||||
|
||||
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
|
||||
|
|
|
@ -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]);
|
||||
//NDS::Halt();
|
||||
u32 oldcpsr = cpu->CPSR;
|
||||
cpu->CPSR &= ~0xFF;
|
||||
cpu->CPSR |= 0xDB;
|
||||
cpu->CPSR &= ~0xBF;
|
||||
cpu->CPSR |= 0x9B;
|
||||
cpu->UpdateMode(oldcpsr, cpu->CPSR);
|
||||
|
||||
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);
|
||||
//NDS::Halt();
|
||||
u32 oldcpsr = cpu->CPSR;
|
||||
cpu->CPSR &= ~0xFF;
|
||||
cpu->CPSR |= 0xDB;
|
||||
cpu->CPSR &= ~0xBF;
|
||||
cpu->CPSR |= 0x9B;
|
||||
cpu->UpdateMode(oldcpsr, cpu->CPSR);
|
||||
|
||||
cpu->R_UND[2] = oldcpsr;
|
||||
|
@ -221,8 +221,8 @@ void A_MRC(ARM* cpu)
|
|||
void A_SVC(ARM* cpu)
|
||||
{
|
||||
u32 oldcpsr = cpu->CPSR;
|
||||
cpu->CPSR &= ~0xFF;
|
||||
cpu->CPSR |= 0xD3;
|
||||
cpu->CPSR &= ~0xBF;
|
||||
cpu->CPSR |= 0x93;
|
||||
cpu->UpdateMode(oldcpsr, cpu->CPSR);
|
||||
|
||||
cpu->R_SVC[2] = oldcpsr;
|
||||
|
@ -233,8 +233,8 @@ void A_SVC(ARM* cpu)
|
|||
void T_SVC(ARM* cpu)
|
||||
{
|
||||
u32 oldcpsr = cpu->CPSR;
|
||||
cpu->CPSR &= ~0xFF;
|
||||
cpu->CPSR |= 0xD3;
|
||||
cpu->CPSR &= ~0xBF;
|
||||
cpu->CPSR |= 0x93;
|
||||
cpu->UpdateMode(oldcpsr, cpu->CPSR);
|
||||
|
||||
cpu->R_SVC[2] = oldcpsr;
|
||||
|
|
333
src/CP15.cpp
333
src/CP15.cpp
|
@ -25,7 +25,7 @@
|
|||
|
||||
void ARMv5::CP15Reset()
|
||||
{
|
||||
CP15Control = 0x78; // dunno
|
||||
CP15Control = 0x2078; // dunno
|
||||
|
||||
DTCMSetting = 0;
|
||||
ITCMSetting = 0;
|
||||
|
@ -36,6 +36,16 @@ void ARMv5::CP15Reset()
|
|||
ITCMSize = 0;
|
||||
DTCMBase = 0xFFFFFFFF;
|
||||
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)
|
||||
|
@ -64,13 +74,13 @@ void ARMv5::UpdateDTCMSetting()
|
|||
{
|
||||
DTCMBase = DTCMSetting & 0xFFFFF000;
|
||||
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
|
||||
{
|
||||
DTCMBase = 0xFFFFFFFF;
|
||||
DTCMSize = 0;
|
||||
//printf("DTCM disabled\n");
|
||||
printf("DTCM disabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,12 +89,128 @@ void ARMv5::UpdateITCMSetting()
|
|||
if (CP15Control & (1<<18))
|
||||
{
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
case 0x100:
|
||||
val &= 0x000FF085;
|
||||
CP15Control &= ~0x000FF085;
|
||||
CP15Control |= val;
|
||||
UpdateDTCMSetting();
|
||||
UpdateITCMSetting();
|
||||
{
|
||||
u32 old = CP15Control;
|
||||
val &= 0x000FF085;
|
||||
CP15Control &= ~0x000FF085;
|
||||
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;
|
||||
|
||||
|
||||
case 0x200: // data cacheable
|
||||
PU_DataCacheable = val;
|
||||
printf("PU: DataCacheable=%08X\n", val);
|
||||
UpdatePURegions();
|
||||
return;
|
||||
|
||||
case 0x201: // code cacheable
|
||||
PU_CodeCacheable = val;
|
||||
printf("PU: CodeCacheable=%08X\n", val);
|
||||
UpdatePURegions();
|
||||
return;
|
||||
|
||||
|
||||
case 0x300: // data cache write-buffer
|
||||
PU_DataCacheWrite = val;
|
||||
printf("PU: DataCacheWrite=%08X\n", val);
|
||||
UpdatePURegions();
|
||||
return;
|
||||
|
||||
|
||||
|
@ -132,6 +269,7 @@ void ARMv5::CP15Write(u32 id, u32 val)
|
|||
PU_DataRW |= ((val & 0x3000) << 12);
|
||||
PU_DataRW |= ((val & 0xC000) << 14);
|
||||
printf("PU: DataRW=%08X (legacy %08X)\n", PU_DataRW, val);
|
||||
UpdatePURegions();
|
||||
return;
|
||||
|
||||
case 0x501: // legacy code permissions
|
||||
|
@ -145,16 +283,19 @@ void ARMv5::CP15Write(u32 id, u32 val)
|
|||
PU_CodeRW |= ((val & 0x3000) << 12);
|
||||
PU_CodeRW |= ((val & 0xC000) << 14);
|
||||
printf("PU: CodeRW=%08X (legacy %08X)\n", PU_CodeRW, val);
|
||||
UpdatePURegions();
|
||||
return;
|
||||
|
||||
case 0x502: // data permissions
|
||||
PU_DataRW = val;
|
||||
printf("PU: DataRW=%08X\n", PU_DataRW);
|
||||
UpdatePURegions();
|
||||
return;
|
||||
|
||||
case 0x503: // code permissions
|
||||
PU_CodeRW = val;
|
||||
printf("PU: CodeRW=%08X\n", PU_CodeRW);
|
||||
UpdatePURegions();
|
||||
return;
|
||||
|
||||
|
||||
|
@ -179,6 +320,7 @@ void ARMv5::CP15Write(u32 id, u32 val)
|
|||
printf("%s, ", val&1 ? "enabled":"disabled");
|
||||
printf("%08X-", val&0xFFFFF000);
|
||||
printf("%08X\n", (val&0xFFFFF000)+(2<<((val&0x3E)>>1)));
|
||||
UpdatePURegions();
|
||||
return;
|
||||
|
||||
|
||||
|
@ -318,7 +460,7 @@ u32 ARMv5::CP15Read(u32 id)
|
|||
|
||||
u32 ARMv5::CodeRead32(u32 addr)
|
||||
{
|
||||
// PU/cache check here
|
||||
u8 pu = PU_Map[addr>>12];
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
|
@ -328,34 +470,49 @@ u32 ARMv5::CodeRead32(u32 addr)
|
|||
|
||||
u32 ret;
|
||||
CodeRegion = NDS::ARM9Read32(addr, &ret);
|
||||
if (pu & 0x40) CodeRegion = NDS::Region9_ICache;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*val = *(u8*)&ITCM[addr & 0x7FFF];
|
||||
return true;
|
||||
}
|
||||
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
DataRegion = NDS::Region9_DTCM;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*val = *(u8*)&DTCM[(addr - DTCMBase) & 0x3FFF];
|
||||
return true;
|
||||
}
|
||||
|
||||
DataRegion = NDS::ARM9Read8(addr, val);
|
||||
if (flags & RWFlags_Nonseq)
|
||||
DataCycles = NDS::ARM9MemTimings[DataRegion][0];
|
||||
if (pu & 0x10)
|
||||
{
|
||||
DataRegion = NDS::Region9_DCache;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 2;
|
||||
else DataCycles += 2;
|
||||
}
|
||||
else
|
||||
DataCycles += NDS::ARM9MemTimings[DataRegion][1];
|
||||
{
|
||||
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
|
||||
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -363,28 +520,42 @@ bool ARMv5::DataRead16(u32 addr, u32* val, u32 flags)
|
|||
{
|
||||
addr &= ~1;
|
||||
|
||||
// PU/cache check here
|
||||
u8 pu = PU_Map[addr>>12];
|
||||
/*if (!(pu & 0x01))
|
||||
{
|
||||
DataAbort();
|
||||
return false;
|
||||
}*/
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*val = *(u16*)&ITCM[addr & 0x7FFF];
|
||||
return true;
|
||||
}
|
||||
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
DataRegion = NDS::Region9_DTCM;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*val = *(u16*)&DTCM[(addr - DTCMBase) & 0x3FFF];
|
||||
return true;
|
||||
}
|
||||
|
||||
DataRegion = NDS::ARM9Read16(addr, val);
|
||||
if (flags & RWFlags_Nonseq)
|
||||
DataCycles = NDS::ARM9MemTimings[DataRegion][0];
|
||||
if (pu & 0x10)
|
||||
{
|
||||
DataRegion = NDS::Region9_DCache;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 2;
|
||||
else DataCycles += 2;
|
||||
}
|
||||
else
|
||||
DataCycles += NDS::ARM9MemTimings[DataRegion][1];
|
||||
{
|
||||
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
|
||||
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -392,55 +563,83 @@ bool ARMv5::DataRead32(u32 addr, u32* val, u32 flags)
|
|||
{
|
||||
addr &= ~3;
|
||||
|
||||
// PU/cache check here
|
||||
u8 pu = PU_Map[addr>>12];
|
||||
/*if (!(pu & 0x01))
|
||||
{
|
||||
DataAbort();
|
||||
return false;
|
||||
}*/
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*val = *(u32*)&ITCM[addr & 0x7FFF];
|
||||
return true;
|
||||
}
|
||||
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
DataRegion = NDS::Region9_DTCM;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*val = *(u32*)&DTCM[(addr - DTCMBase) & 0x3FFF];
|
||||
return true;
|
||||
}
|
||||
|
||||
DataRegion = NDS::ARM9Read32(addr, val);
|
||||
if (flags & RWFlags_Nonseq)
|
||||
DataCycles = NDS::ARM9MemTimings[DataRegion][2];
|
||||
if (pu & 0x10)
|
||||
{
|
||||
DataRegion = NDS::Region9_DCache;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 2;
|
||||
else DataCycles += 2;
|
||||
}
|
||||
else
|
||||
DataCycles += NDS::ARM9MemTimings[DataRegion][3];
|
||||
{
|
||||
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
|
||||
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*(u8*)&ITCM[addr & 0x7FFF] = val;
|
||||
return true;
|
||||
}
|
||||
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
DataRegion = NDS::Region9_DTCM;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*(u8*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
DataRegion = NDS::ARM9Write8(addr, val);
|
||||
if (flags & RWFlags_Nonseq)
|
||||
DataCycles = NDS::ARM9MemTimings[DataRegion][0];
|
||||
if (pu & 0x20)
|
||||
{
|
||||
DataRegion = NDS::Region9_DCache;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 2;
|
||||
else DataCycles += 2;
|
||||
}
|
||||
else
|
||||
DataCycles += NDS::ARM9MemTimings[DataRegion][1];
|
||||
{
|
||||
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
|
||||
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -448,28 +647,42 @@ bool ARMv5::DataWrite16(u32 addr, u16 val, u32 flags)
|
|||
{
|
||||
addr &= ~1;
|
||||
|
||||
// PU/cache check here
|
||||
u8 pu = PU_Map[addr>>12];
|
||||
/*if (!(pu & 0x02))
|
||||
{
|
||||
DataAbort();
|
||||
return false;
|
||||
}*/
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*(u16*)&ITCM[addr & 0x7FFF] = val;
|
||||
return true;
|
||||
}
|
||||
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
DataRegion = NDS::Region9_DTCM;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*(u16*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
DataRegion = NDS::ARM9Write16(addr, val);
|
||||
if (flags & RWFlags_Nonseq)
|
||||
DataCycles = NDS::ARM9MemTimings[DataRegion][0];
|
||||
if (pu & 0x20)
|
||||
{
|
||||
DataRegion = NDS::Region9_DCache;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 2;
|
||||
else DataCycles += 2;
|
||||
}
|
||||
else
|
||||
DataCycles += NDS::ARM9MemTimings[DataRegion][1];
|
||||
{
|
||||
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
|
||||
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -477,28 +690,42 @@ bool ARMv5::DataWrite32(u32 addr, u32 val, u32 flags)
|
|||
{
|
||||
addr &= ~3;
|
||||
|
||||
// PU/cache check here
|
||||
u8 pu = PU_Map[addr>>12];
|
||||
/*if (!(pu & 0x02))
|
||||
{
|
||||
DataAbort();
|
||||
return false;
|
||||
}*/
|
||||
|
||||
if (addr < ITCMSize)
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*(u32*)&ITCM[addr & 0x7FFF] = val;
|
||||
return true;
|
||||
}
|
||||
if (addr >= DTCMBase && addr < (DTCMBase + DTCMSize))
|
||||
{
|
||||
DataRegion = NDS::Region9_ITCM;
|
||||
DataCycles += 1;
|
||||
DataRegion = NDS::Region9_DTCM;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 1;
|
||||
else DataCycles += 1;
|
||||
*(u32*)&DTCM[(addr - DTCMBase) & 0x3FFF] = val;
|
||||
return true;
|
||||
}
|
||||
|
||||
DataRegion = NDS::ARM9Write32(addr, val);
|
||||
if (flags & RWFlags_Nonseq)
|
||||
DataCycles = NDS::ARM9MemTimings[DataRegion][2];
|
||||
if (pu & 0x20)
|
||||
{
|
||||
DataRegion = NDS::Region9_DCache;
|
||||
if (flags & RWFlags_Nonseq) DataCycles = 2;
|
||||
else DataCycles += 2;
|
||||
}
|
||||
else
|
||||
DataCycles += NDS::ARM9MemTimings[DataRegion][3];
|
||||
{
|
||||
if (flags & RWFlags_Nonseq) DataCycles = NDS::ARM9MemTimings[DataRegion][0];
|
||||
else DataCycles += NDS::ARM9MemTimings[DataRegion][1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -255,7 +255,7 @@ s32 DMA::Run(s32 cycles)
|
|||
readfn(CurSrcAddr, &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;
|
||||
NDS::RunTimingCriticalDevices(CPU, c);
|
||||
|
||||
|
@ -294,7 +294,7 @@ s32 DMA::Run(s32 cycles)
|
|||
readfn(CurSrcAddr, &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;
|
||||
NDS::RunTimingCriticalDevices(CPU, c);
|
||||
|
||||
|
|
|
@ -653,12 +653,12 @@ void MapVRAM_I(u32 bank, u8 cnt)
|
|||
void DisplaySwap(u32 val)
|
||||
{
|
||||
if (val)
|
||||
{
|
||||
{printf("main GPU on top screen\n");
|
||||
GPU2D_A->SetFramebuffer(&Framebuffer[256*0]);
|
||||
GPU2D_B->SetFramebuffer(&Framebuffer[256*192]);
|
||||
}
|
||||
else
|
||||
{
|
||||
{printf("main GPU on bottom screen\n");
|
||||
GPU2D_A->SetFramebuffer(&Framebuffer[256*192]);
|
||||
GPU2D_B->SetFramebuffer(&Framebuffer[256*0]);
|
||||
}
|
||||
|
@ -813,6 +813,7 @@ void StartScanline(u32 line)
|
|||
GPU2D_A->VBlank();
|
||||
GPU2D_B->VBlank();
|
||||
GPU3D::VBlank();
|
||||
printf("VBlank. PC=%08X\n", NDS::GetPC(0));
|
||||
}
|
||||
else if (VCount == 144)
|
||||
{
|
||||
|
|
11
src/NDS.cpp
11
src/NDS.cpp
|
@ -226,6 +226,15 @@ void CalculateTimings(int arm9shift)
|
|||
{
|
||||
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
|
||||
{
|
||||
ARM9MemTimings[i][0] = 1; // 16-bit N
|
||||
|
@ -1030,7 +1039,7 @@ void HandleTimerOverflow(u32 tid)
|
|||
timer->Counter += timer->Reload << 16;
|
||||
if (timer->Cnt & (1<<6))
|
||||
SetIRQ(tid >> 2, IRQ_Timer0 + (tid & 0x3));
|
||||
|
||||
//if (tid<4) printf("[%03d] timer%d IRQ\n", GPU::VCount, tid);
|
||||
if ((tid & 0x3) == 3)
|
||||
return;
|
||||
|
||||
|
|
Loading…
Reference in New Issue