diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ARM.cpp | 77 | ||||
-rw-r--r-- | src/ARM.h | 15 | ||||
-rw-r--r-- | src/ARMInterpreter.cpp | 16 | ||||
-rw-r--r-- | src/CP15.cpp | 333 | ||||
-rw-r--r-- | src/DMA.cpp | 4 | ||||
-rw-r--r-- | src/GPU.cpp | 5 | ||||
-rw-r--r-- | src/NDS.cpp | 11 |
7 files changed, 390 insertions, 71 deletions
diff --git a/src/ARM.cpp b/src/ARM.cpp index 64196f6..10e2e04 100644 --- a/src/ARM.cpp +++ b/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) @@ -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 diff --git a/src/ARMInterpreter.cpp b/src/ARMInterpreter.cpp index b29f558..1312771 100644 --- a/src/ARMInterpreter.cpp +++ b/src/ARMInterpreter.cpp @@ -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; diff --git a/src/CP15.cpp b/src/CP15.cpp index 3507b57..0665137 100644 --- a/src/CP15.cpp +++ b/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; } diff --git a/src/DMA.cpp b/src/DMA.cpp index 95aa9e6..2f7d9bb 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -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); diff --git a/src/GPU.cpp b/src/GPU.cpp index aba97a5..9d79848 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -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) { diff --git a/src/NDS.cpp b/src/NDS.cpp index 38cc611..2c3f5cd 100644 --- a/src/NDS.cpp +++ b/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; |