improve implementation
This commit is contained in:
parent
960f063eaa
commit
63d4b78733
|
@ -1168,21 +1168,23 @@ void ARMv4::DataRead16(u32 addr, u32* val)
|
||||||
DataCycles = NDS.ARM7MemTimings[addr >> 15][0];
|
DataCycles = NDS.ARM7MemTimings[addr >> 15][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv4::DataRead32(u32 addr, u32* val)
|
bool ARMv4::DataRead32(u32 addr, u32* val)
|
||||||
{
|
{
|
||||||
addr &= ~3;
|
addr &= ~3;
|
||||||
|
|
||||||
*val = BusRead32(addr);
|
*val = BusRead32(addr);
|
||||||
DataRegion = addr;
|
DataRegion = addr;
|
||||||
DataCycles = NDS.ARM7MemTimings[addr >> 15][2];
|
DataCycles = NDS.ARM7MemTimings[addr >> 15][2];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv4::DataRead32S(u32 addr, u32* val)
|
bool ARMv4::DataRead32S(u32 addr, u32* val)
|
||||||
{
|
{
|
||||||
addr &= ~3;
|
addr &= ~3;
|
||||||
|
|
||||||
*val = BusRead32(addr);
|
*val = BusRead32(addr);
|
||||||
DataCycles += NDS.ARM7MemTimings[addr >> 15][3];
|
DataCycles += NDS.ARM7MemTimings[addr >> 15][3];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv4::DataWrite8(u32 addr, u8 val)
|
void ARMv4::DataWrite8(u32 addr, u8 val)
|
||||||
|
|
12
src/ARM.h
12
src/ARM.h
|
@ -130,8 +130,8 @@ public:
|
||||||
|
|
||||||
virtual void DataRead8(u32 addr, u32* val) = 0;
|
virtual void DataRead8(u32 addr, u32* val) = 0;
|
||||||
virtual void DataRead16(u32 addr, u32* val) = 0;
|
virtual void DataRead16(u32 addr, u32* val) = 0;
|
||||||
virtual void DataRead32(u32 addr, u32* val) = 0;
|
virtual bool DataRead32(u32 addr, u32* val) = 0;
|
||||||
virtual void DataRead32S(u32 addr, u32* val) = 0;
|
virtual bool DataRead32S(u32 addr, u32* val) = 0;
|
||||||
virtual void DataWrite8(u32 addr, u8 val) = 0;
|
virtual void DataWrite8(u32 addr, u8 val) = 0;
|
||||||
virtual void DataWrite16(u32 addr, u16 val) = 0;
|
virtual void DataWrite16(u32 addr, u16 val) = 0;
|
||||||
virtual void DataWrite32(u32 addr, u32 val) = 0;
|
virtual void DataWrite32(u32 addr, u32 val) = 0;
|
||||||
|
@ -251,8 +251,8 @@ public:
|
||||||
|
|
||||||
void DataRead8(u32 addr, u32* val) override;
|
void DataRead8(u32 addr, u32* val) override;
|
||||||
void DataRead16(u32 addr, u32* val) override;
|
void DataRead16(u32 addr, u32* val) override;
|
||||||
void DataRead32(u32 addr, u32* val) override;
|
bool DataRead32(u32 addr, u32* val) override;
|
||||||
void DataRead32S(u32 addr, u32* val) override;
|
bool DataRead32S(u32 addr, u32* val) override;
|
||||||
void DataWrite8(u32 addr, u8 val) override;
|
void DataWrite8(u32 addr, u8 val) override;
|
||||||
void DataWrite16(u32 addr, u16 val) override;
|
void DataWrite16(u32 addr, u16 val) override;
|
||||||
void DataWrite32(u32 addr, u32 val) override;
|
void DataWrite32(u32 addr, u32 val) override;
|
||||||
|
@ -400,8 +400,8 @@ public:
|
||||||
|
|
||||||
void DataRead8(u32 addr, u32* val) override;
|
void DataRead8(u32 addr, u32* val) override;
|
||||||
void DataRead16(u32 addr, u32* val) override;
|
void DataRead16(u32 addr, u32* val) override;
|
||||||
void DataRead32(u32 addr, u32* val) override;
|
bool DataRead32(u32 addr, u32* val) override;
|
||||||
void DataRead32S(u32 addr, u32* val) override;
|
bool DataRead32S(u32 addr, u32* val) override;
|
||||||
void DataWrite8(u32 addr, u8 val) override;
|
void DataWrite8(u32 addr, u8 val) override;
|
||||||
void DataWrite16(u32 addr, u16 val) override;
|
void DataWrite16(u32 addr, u16 val) override;
|
||||||
void DataWrite32(u32 addr, u32 val) override;
|
void DataWrite32(u32 addr, u32 val) override;
|
||||||
|
|
|
@ -395,12 +395,14 @@ void A_LDM(ARM* cpu)
|
||||||
u32 baseid = (cpu->CurInstr >> 16) & 0xF;
|
u32 baseid = (cpu->CurInstr >> 16) & 0xF;
|
||||||
u32 base = cpu->R[baseid];
|
u32 base = cpu->R[baseid];
|
||||||
u32 wbbase;
|
u32 wbbase;
|
||||||
|
u32 oldbase = base;
|
||||||
u32 preinc = (cpu->CurInstr & (1<<24));
|
u32 preinc = (cpu->CurInstr & (1<<24));
|
||||||
bool first = true;
|
bool first = true;
|
||||||
int abortreg = 16;
|
bool dataabort = false;
|
||||||
|
|
||||||
if (!(cpu->CurInstr & (1<<23)))
|
if (!(cpu->CurInstr & (1<<23))) // decrement
|
||||||
{
|
{
|
||||||
|
// decrement is actually an increment starting from the end address
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
if (cpu->CurInstr & (1<<i))
|
if (cpu->CurInstr & (1<<i))
|
||||||
|
@ -416,61 +418,43 @@ void A_LDM(ARM* cpu)
|
||||||
preinc = !preinc;
|
preinc = !preinc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for data aborts
|
// switch to user mode regs
|
||||||
if (cpu->Num == 0)
|
|
||||||
{
|
|
||||||
u32 tmpbase = base;
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
if (cpu->CurInstr & (1<<i))
|
|
||||||
{
|
|
||||||
if (preinc) tmpbase += 4;
|
|
||||||
if(((ARMv5*)cpu)->PU_Map[tmpbase>>12] & 0x01)
|
|
||||||
{
|
|
||||||
if (!preinc) tmpbase += 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
abortreg = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15)))
|
if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15)))
|
||||||
cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10, true);
|
cpu->UpdateMode(cpu->CPSR, (cpu->CPSR&~0x1F)|0x10, true);
|
||||||
|
|
||||||
for (int i = 0; i < std::min(15, abortreg); i++)
|
for (int i = 0; i < 15; i++)
|
||||||
{
|
{
|
||||||
if (cpu->CurInstr & (1<<i))
|
if (cpu->CurInstr & (1<<i))
|
||||||
{
|
{
|
||||||
if (preinc) base += 4;
|
if (preinc) base += 4;
|
||||||
if (first) cpu->DataRead32 (base, &cpu->R[i]);
|
if (first) {if (!cpu->DataRead32 (base, &cpu->R[i])) {dataabort = true; goto abortjump;}}
|
||||||
else cpu->DataRead32S(base, &cpu->R[i]);
|
else if (!cpu->DataRead32S(base, &cpu->R[i])) {dataabort = true; goto abortjump;}
|
||||||
first = false;
|
first = false;
|
||||||
if (!preinc) base += 4;
|
if (!preinc) base += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 pc;
|
u32 pc;
|
||||||
if ((cpu->CurInstr & (1<<15)) && (abortreg == 16))
|
if ((cpu->CurInstr & (1<<15)))
|
||||||
{
|
{
|
||||||
if (preinc) base += 4;
|
if (preinc) base += 4;
|
||||||
if (first) cpu->DataRead32 (base, &pc);
|
if (first) {if (!cpu->DataRead32 (base, &pc)) dataabort = true;}
|
||||||
else cpu->DataRead32S(base, &pc);
|
else if (!cpu->DataRead32S(base, &pc)) dataabort = true;
|
||||||
if (!preinc) base += 4;
|
if (!preinc) base += 4;
|
||||||
|
|
||||||
if (cpu->Num == 1)
|
if (cpu->Num == 1)
|
||||||
pc &= ~0x1;
|
pc &= ~0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abortjump:
|
||||||
|
|
||||||
|
// switch back to previous regs
|
||||||
if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15)))
|
if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15)))
|
||||||
cpu->UpdateMode((cpu->CPSR&~0x1F)|0x10, cpu->CPSR, true);
|
cpu->UpdateMode((cpu->CPSR&~0x1F)|0x10, cpu->CPSR, true);
|
||||||
|
|
||||||
// if it's 16 then there was no data abort
|
if (!dataabort)
|
||||||
if (abortreg == 16)
|
|
||||||
{
|
{
|
||||||
|
// writeback to base
|
||||||
if (cpu->CurInstr & (1<<21))
|
if (cpu->CurInstr & (1<<21))
|
||||||
{
|
{
|
||||||
// post writeback
|
// post writeback
|
||||||
|
@ -490,13 +474,11 @@ void A_LDM(ARM* cpu)
|
||||||
cpu->R[baseid] = wbbase;
|
cpu->R[baseid] = wbbase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jump if pc got written
|
||||||
if (cpu->CurInstr & (1<<15))
|
if (cpu->CurInstr & (1<<15))
|
||||||
cpu->JumpTo(pc, cpu->CurInstr & (1<<22));
|
cpu->JumpTo(pc, cpu->CurInstr & (1<<22));
|
||||||
}
|
}
|
||||||
else
|
else cpu->R[baseid] = oldbase; // restore original value of base in case the reg got written to
|
||||||
{
|
|
||||||
((ARMv5*)cpu)->DataAbort();
|
|
||||||
}
|
|
||||||
|
|
||||||
cpu->AddCycles_CDI();
|
cpu->AddCycles_CDI();
|
||||||
}
|
}
|
||||||
|
|
22
src/CP15.cpp
22
src/CP15.cpp
|
@ -863,12 +863,12 @@ void ARMv5::DataRead16(u32 addr, u32* val)
|
||||||
DataCycles = MemTimings[addr >> 12][1];
|
DataCycles = MemTimings[addr >> 12][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DataRead32(u32 addr, u32* val)
|
bool ARMv5::DataRead32(u32 addr, u32* val)
|
||||||
{
|
{
|
||||||
if (!(PU_Map[addr>>12] & 0x01))
|
if (!(PU_Map[addr>>12] & 0x01))
|
||||||
{
|
{
|
||||||
DataAbort();
|
DataAbort();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataRegion = addr;
|
DataRegion = addr;
|
||||||
|
@ -879,38 +879,46 @@ void ARMv5::DataRead32(u32 addr, u32* val)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataCycles = 1;
|
DataCycles = 1;
|
||||||
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = BusRead32(addr);
|
*val = BusRead32(addr);
|
||||||
DataCycles = MemTimings[addr >> 12][2];
|
DataCycles = MemTimings[addr >> 12][2];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DataRead32S(u32 addr, u32* val)
|
bool ARMv5::DataRead32S(u32 addr, u32* val)
|
||||||
{
|
{
|
||||||
|
if (!(PU_Map[addr>>12] & 0x01))
|
||||||
|
{
|
||||||
|
DataAbort();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
addr &= ~3;
|
addr &= ~3;
|
||||||
|
|
||||||
if (addr < ITCMSize)
|
if (addr < ITCMSize)
|
||||||
{
|
{
|
||||||
DataCycles += 1;
|
DataCycles += 1;
|
||||||
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
*val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)];
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
if ((addr & DTCMMask) == DTCMBase)
|
if ((addr & DTCMMask) == DTCMBase)
|
||||||
{
|
{
|
||||||
DataCycles += 1;
|
DataCycles += 1;
|
||||||
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
*val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)];
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = BusRead32(addr);
|
*val = BusRead32(addr);
|
||||||
DataCycles += MemTimings[addr >> 12][3];
|
DataCycles += MemTimings[addr >> 12][3];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv5::DataWrite8(u32 addr, u8 val)
|
void ARMv5::DataWrite8(u32 addr, u8 val)
|
||||||
|
|
Loading…
Reference in New Issue