diff options
Diffstat (limited to 'src/ARM.h')
-rw-r--r-- | src/ARM.h | 187 |
1 files changed, 89 insertions, 98 deletions
@@ -48,8 +48,6 @@ public: ClockDiffMask = (1<<shift) - 1; } - virtual void CalculateTimings() = 0; - virtual void JumpTo(u32 addr, bool restorecpsr = false) = 0; void RestoreCPSR(); @@ -107,15 +105,17 @@ public: void SetupCodeMem(u32 addr); - virtual bool DataRead8(u32 addr, u32* val, u32 flags) = 0; - virtual bool DataRead16(u32 addr, u32* val, u32 flags) = 0; - virtual bool DataRead32(u32 addr, u32* val, u32 flags) = 0; - virtual bool DataWrite8(u32 addr, u8 val, u32 flags) = 0; - virtual bool DataWrite16(u32 addr, u16 val, u32 flags) = 0; - virtual bool DataWrite32(u32 addr, u32 val, u32 flags) = 0; + virtual void DataRead8(u32 addr, u32* val) = 0; + virtual void DataRead16(u32 addr, u32* val) = 0; + virtual void DataRead32(u32 addr, u32* val) = 0; + virtual void DataRead32S(u32 addr, u32* val) = 0; + virtual void DataWrite8(u32 addr, u8 val) = 0; + virtual void DataWrite16(u32 addr, u16 val) = 0; + virtual void DataWrite32(u32 addr, u32 val) = 0; + virtual void DataWrite32S(u32 addr, u32 val) = 0; virtual void AddCycles_C() = 0; - virtual void AddCycles_CI(s32 num) = 0; + virtual void AddCycles_CI(s32 numI) = 0; virtual void AddCycles_CDI() = 0; virtual void AddCycles_CD() = 0; @@ -131,9 +131,10 @@ public: s32 CyclesToRun; u32 Halted; - int CodeRegion; + u32 CodeRegion; + s32 CodeCycles; - int DataRegion; + u32 DataRegion; s32 DataCycles; u32 R[16]; // heh @@ -162,7 +163,7 @@ public: void DoSavestate(Savestate* file); - void CalculateTimings(); + void UpdateRegionTimings(u32 addrstart, u32 addrend); void JumpTo(u32 addr, bool restorecpsr = false); @@ -174,48 +175,52 @@ public: // all code accesses are forced nonseq 32bit u32 CodeRead32(u32 addr); - bool DataRead8(u32 addr, u32* val, u32 flags); - bool DataRead16(u32 addr, u32* val, u32 flags); - bool DataRead32(u32 addr, u32* val, u32 flags); - bool DataWrite8(u32 addr, u8 val, u32 flags); - bool DataWrite16(u32 addr, u16 val, u32 flags); - bool DataWrite32(u32 addr, u32 val, u32 flags); + void DataRead8(u32 addr, u32* val); + void DataRead16(u32 addr, u32* val); + void DataRead32(u32 addr, u32* val); + void DataRead32S(u32 addr, u32* val); + void DataWrite8(u32 addr, u8 val); + void DataWrite16(u32 addr, u16 val); + void DataWrite32(u32 addr, u32 val); + void DataWrite32S(u32 addr, u32 val); void AddCycles_C() { // code only. always nonseq 32-bit for ARM9. - Cycles += NDS::ARM9MemTimings[CodeRegion][2]; + s32 numC = (R[15] & 0x2) ? 0 : CodeCycles; + Cycles += numC; } - void AddCycles_CI(s32 num) + void AddCycles_CI(s32 numI) { // code+internal - Cycles += NDS::ARM9MemTimings[CodeRegion][2] + num; + s32 numC = (R[15] & 0x2) ? 0 : CodeCycles; + Cycles += numC + numI; } void AddCycles_CDI() { // LDR/LDM cycles. ARM9 seems to skip the internal cycle there. // TODO: ITCM data fetches shouldn't be parallelized, they say - s32 numC = NDS::ARM9MemTimings[CodeRegion][2]; + s32 numC = (R[15] & 0x2) ? 0 : CodeCycles; s32 numD = DataCycles; - if (DataRegion != CodeRegion) + //if (DataRegion != CodeRegion) Cycles += std::max(numC + numD - 6, std::max(numC, numD)); - else - Cycles += numC + numD; + //else + // Cycles += numC + numD; } void AddCycles_CD() { // TODO: ITCM data fetches shouldn't be parallelized, they say - s32 numC = NDS::ARM9MemTimings[CodeRegion][2]; + s32 numC = (R[15] & 0x2) ? 0 : CodeCycles; s32 numD = DataCycles; - if (DataRegion != CodeRegion) + //if (DataRegion != CodeRegion) Cycles += std::max(numC + numD - 6, std::max(numC, numD)); - else - Cycles += numC + numD; + //else + // Cycles += numC + numD; } void GetCodeMemRegion(u32 addr, NDS::MemRegion* region); @@ -250,14 +255,14 @@ public: 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; + u8 PU_UserMap[0x100000]; + + // games operate under system mode, generally #define PU_Map PU_PrivMap - bool CodeCached; + // code/16N/32N/32S + u8 MemTimings[0x100000][4]; }; class ARMv4 : public ARM @@ -265,122 +270,108 @@ class ARMv4 : public ARM public: ARMv4(); - void CalculateTimings(); - void JumpTo(u32 addr, bool restorecpsr = false); s32 Execute(); u16 CodeRead16(u32 addr) { - u32 ret; - CodeRegion = NDS::ARM7Read16(addr, &ret); - return ret; + return NDS::ARM7Read16(addr); } u32 CodeRead32(u32 addr) { - u32 ret; - CodeRegion = NDS::ARM7Read32(addr, &ret); - return ret; + return NDS::ARM7Read32(addr); } - bool DataRead8(u32 addr, u32* val, u32 flags) + void DataRead8(u32 addr, u32* val) { - DataRegion = NDS::ARM7Read8(addr, val); - if (flags & RWFlags_Nonseq) - DataCycles = NDS::ARM7MemTimings[DataRegion][0]; - else - DataCycles += NDS::ARM7MemTimings[DataRegion][1]; - - return true; + *val = NDS::ARM7Read8(addr); + DataRegion = addr >> 24; + DataCycles = NDS::ARM7MemTimings[DataRegion][0]; } - bool DataRead16(u32 addr, u32* val, u32 flags) + void DataRead16(u32 addr, u32* val) { addr &= ~1; - DataRegion = NDS::ARM7Read16(addr, val); - if (flags & RWFlags_Nonseq) - DataCycles = NDS::ARM7MemTimings[DataRegion][0]; - else - DataCycles += NDS::ARM7MemTimings[DataRegion][1]; - - return true; + *val = NDS::ARM7Read16(addr); + DataRegion = addr >> 24; + DataCycles = NDS::ARM7MemTimings[DataRegion][0]; } - bool DataRead32(u32 addr, u32* val, u32 flags) + void DataRead32(u32 addr, u32* val) { addr &= ~3; - DataRegion = NDS::ARM7Read32(addr, val); - if (flags & RWFlags_Nonseq) - DataCycles = NDS::ARM7MemTimings[DataRegion][2]; - else - DataCycles += NDS::ARM7MemTimings[DataRegion][3]; - - return true; + *val = NDS::ARM7Read32(addr); + DataRegion = addr >> 24; + DataCycles = NDS::ARM7MemTimings[DataRegion][2]; } - bool DataWrite8(u32 addr, u8 val, u32 flags) + void DataRead32S(u32 addr, u32* val) { - DataRegion = NDS::ARM7Write8(addr, val); - if (flags & RWFlags_Nonseq) - DataCycles = NDS::ARM7MemTimings[DataRegion][0]; - else - DataCycles += NDS::ARM7MemTimings[DataRegion][1]; + addr &= ~3; - return true; + *val = NDS::ARM7Read32(addr); + DataCycles += NDS::ARM7MemTimings[DataRegion][3]; } - bool DataWrite16(u32 addr, u16 val, u32 flags) + void DataWrite8(u32 addr, u8 val) { - addr &= ~1; + NDS::ARM7Write8(addr, val); + DataRegion = addr >> 24; + DataCycles = NDS::ARM7MemTimings[DataRegion][0]; + } - DataRegion = NDS::ARM7Write16(addr, val); - if (flags & RWFlags_Nonseq) - DataCycles = NDS::ARM7MemTimings[DataRegion][0]; - else - DataCycles += NDS::ARM7MemTimings[DataRegion][1]; + void DataWrite16(u32 addr, u16 val) + { + addr &= ~1; - return true; + NDS::ARM7Write16(addr, val); + DataRegion = addr >> 24; + DataCycles = NDS::ARM7MemTimings[DataRegion][0]; } - bool DataWrite32(u32 addr, u32 val, u32 flags) + void DataWrite32(u32 addr, u32 val) { addr &= ~3; - DataRegion = NDS::ARM7Write32(addr, val); - if (flags & RWFlags_Nonseq) - DataCycles = NDS::ARM7MemTimings[DataRegion][2]; - else - DataCycles += NDS::ARM7MemTimings[DataRegion][3]; + NDS::ARM7Write32(addr, val); + DataRegion = addr >> 24; + DataCycles = NDS::ARM7MemTimings[DataRegion][2]; + } + + void DataWrite32S(u32 addr, u32 val) + { + addr &= ~3; - return true; + NDS::ARM7Write32(addr, val); + DataCycles += NDS::ARM7MemTimings[DataRegion][3]; } void AddCycles_C() { // code only. this code fetch is sequential. - Cycles += NDS::ARM7MemTimings[CodeRegion][(CPSR&0x20)?1:3]; + Cycles += NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?1:3]; } void AddCycles_CI(s32 num) { // code+internal. results in a nonseq code fetch. - Cycles += NDS::ARM7MemTimings[CodeRegion][(CPSR&0x20)?0:2] + num; + Cycles += NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2] + num; } void AddCycles_CDI() { // LDR/LDM cycles. - s32 numC = NDS::ARM7MemTimings[CodeRegion][(CPSR&0x20)?0:2]; + s32 numC = NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2]; s32 numD = DataCycles; - if (DataRegion == NDS::Region7_MainRAM) + if (DataRegion == 0x02) // mainRAM { - if (CodeRegion == NDS::Region7_MainRAM) + if (CodeRegion == 0x02) Cycles += numC + numD; else { @@ -388,7 +379,7 @@ public: Cycles += std::max(numC + numD - 3, std::max(numC, numD)); } } - else if (CodeRegion == NDS::Region7_MainRAM) + else if (CodeRegion == 0x02) { numD++; Cycles += std::max(numC + numD - 3, std::max(numC, numD)); @@ -402,17 +393,17 @@ public: void AddCycles_CD() { // TODO: max gain should be 5c when writing to mainRAM - s32 numC = NDS::ARM7MemTimings[CodeRegion][(CPSR&0x20)?0:2]; + s32 numC = NDS::ARM7MemTimings[CodeCycles][(CPSR&0x20)?0:2]; s32 numD = DataCycles; - if (DataRegion == NDS::Region7_MainRAM) + if (DataRegion == 0x02) { - if (CodeRegion == NDS::Region7_MainRAM) + if (CodeRegion == 0x02) Cycles += numC + numD; else Cycles += std::max(numC + numD - 3, std::max(numC, numD)); } - else if (CodeRegion == NDS::Region7_MainRAM) + else if (CodeRegion == 0x02) { Cycles += std::max(numC + numD - 3, std::max(numC, numD)); } |