www.pudn.com > potemkin_sourceforPSP.rar > ARMInterpret.cpp
#include "stdafx.h"
#include "ARM.h"
#include "ARMInterpret.h"
//Unusual instructions that are not necessary/possible to recompile live here...
// these don't need to check the condition bits
// condition checks are emitted around the INTERPRET IR instruction
void Int_MSR(u32 op, int value)
{
int m = (op>>16) & 0xF;
int mask = 0;
u32 val = value;
if ((op>>22)&1)
{
ARMState *currentARM = static_cast(currentCPU);
currentARM->spsr = (currentARM->spsr & ~mask) | (val & mask);
}
else
{
ARMState *currentARM = static_cast(currentCPU);
u32 newval = currentARM->GetCPSR();
if (currentARM->GetMode()>0x10)
{
if (m&1) mask|=0xFF;
if (m&2) mask|=0xFF00;
if (m&4) mask|=0xFF0000;
}
else
{
LOG(CPU,"Access violation");
}
if (m&8) mask|=0xFF000000;
newval = (newval & ~mask) | (val & mask);
currentARM->ModeSwitch((ARMMode)(newval&0x1f));
currentARM->SetCPSR(newval);
}
}
void Int_MSRreg(u32 op)
{
ARMState *currentARM = static_cast(currentCPU);
Int_MSR(op, currentARM->r[op&0xf]);
// LOG(CPU,"MSR");
}
void Int_MSRimm(u32 op)
{
Int_MSR(op, _rotr(op&0xFF,(op>>7)&0x1E));
// LOG(CPU,"MSR");
}
void Int_MRS(u32 op)
{
ARMState *currentARM = static_cast(currentCPU);
int rd = (op>>12)&0xf;
if ((op>>22)&1) // if R bit
{
currentARM->r[rd] = currentARM->spsr;
}
else
currentARM->r[rd] = currentARM->GetCPSR();
// LOG(CPU,"MRS");
}
void Int_LDC(u32 op)
{
ARMState *currentARM = static_cast(currentCPU);
bool longload=(op&(1<<22))?true:false;
int cpDestReg = (op>>12)&0xF;
int rn = (op>>16)&0xF;
int cpNum = (op>>8)&0xF;
int offset = (op)&0xFF;
LOG(CPU,"LDC: r%d -> CP%d.r%d (offset %d)",rn,cpNum,cpDestReg,offset);
}
void Int_STC(u32 op)
{
ARMState *currentARM = static_cast(currentCPU);
bool longload=(op&(1<<22))?true:false;
int cpSourceReg = (op>>12)&0xF;
int rn = (op>>16)&0xF;
int cpNum = (op>>8)&0xF;
int offset = (op)&0xFF;
LOG(CPU,"STC: r%d <- CP%d.r%d (offset %d)",rn,cpNum,cpSourceReg,offset);
}
union CP15_Reg1_0
{
u32 hex;
struct
{
unsigned protectionUnitEnable:1;
unsigned reservedSBZ:1;
unsigned dcacheEnable:1;
unsigned reservedSBO:4;
unsigned bigEndian:1;
unsigned reservedSBZ2:4;
unsigned icacheEnable:1; //bit 12
unsigned altVector:1;
unsigned roundRobin:1; //ds enables this
unsigned configureDisableTBITLoad:1; //?
unsigned dataRAMEnable:1;
unsigned dataRAMLoadMode:1;
unsigned instructionRAMEnable:1;
unsigned instructionRAMLoadMode:1;
unsigned reservedSBZ3:12; //ds enables one up here
};
};
//reg2 bit 0-7 contains Cachable bit for regions 0-7
//reg3 bit 0-7 contains Bufferable bit for regions 0-7
//reg5 contains 8 sets of 4 bits, each one specifying who can access the area how
//reg6:
union CP15_Reg6_n
{
u32 hex;
struct
{
unsigned enable:1;
unsigned size:5; //real size appears to be 1<(currentCPU);
int rd = (op>>12)&0xf;
int crn = (op>>16)&0xf;
int crm = (op)&0xf;
int cpNum = (op>>8)&0xf;
int opcode1 = (op>>21)&0x7;
int opcode2 = (op>>5)&0x7;
LOG(CPU,"MRC: P%d: r%d <- crn%d:crm%d (op %d:%d)",cpNum,rd,crn,crm,opcode1,opcode2);
}
void Int_MCR(u32 op)
{
ARMState *currentARM = static_cast(currentCPU);
int rd = (op>>12)&0xf;
u32 d = currentARM->r[rd];
int crn = (op>>16)&0xf;
int crm = (op)&0xf;
int cpNum = (op>>8)&0xf;
int opcode1 = (op>>21)&0x7;
int opcode2 = (op>>5)&0x7;
LOG(CPU,"MCR: P%d: r%d (%08x)-> crn%d:crm%d (op %d:%d)",cpNum,rd,currentARM->r[rd],crn,crm,opcode1,opcode2);
switch (crn) {
case 6:
LOG(CPU,"-- Memory region %d setup:",crm);
LOG(CPU,"-- Region: %08x, size %08x, enable=%d",d&0xFFFFFFC0,1<<((d&0x3E)>>1),d&1);
break;
case 7:
switch (crm)
{
case 0:
if (opcode2==4)
LOG(CPU,"-- Sleep (wait for interrupt)");
break;
case 5:
LOG(CPU,"-- Instruction cache flush");
//opcode2==0 : whole ==1: single entry (rd = address)
break;
case 13:
LOG(CPU,"-- Instruction cache prefetch");
break;
case 6:
LOG(CPU,"-- Data cache flush");
//opcode2==0 : whole ==1: single entry (rd = address)
break;
case 10:
switch (opcode2)
{
case 1:
LOG(CPU,"-- Data cache entry clean");
break;
case 4:
LOG(CPU,"-- Drain write buffer");
break;
}
//opcode2==1 only
break;
case 14:
LOG(CPU,"-- Data cache entry clean and flush");
//opcode2==1 only
break;
default:
;
}
break;
case 15:
switch (crm)
{
case 8:
if (opcode2==2)
LOG(CPU,"-- Sleep (wait for interrupt) OLD ENCODING");
break;
}
case 9:
switch (crm)
{
case 0:
LOG(CPU,"-- Cache lockdown operation .. investigate");
break;
case 1:
LOG(CPU,"-- TCM operation .. investigate"); //tightly coupled memory
break;
}
break;
case 13:
LOG(CPU,"-- Current process ID access");
break;
}
}