flycast/core/hw/arm7/virt_arm.cpp

214 lines
3.3 KiB
C++
Raw Normal View History

2020-03-28 16:58:01 +00:00
#include "build.h"
2013-12-19 17:10:14 +00:00
#if HOST_CPU==CPU_X86 && FEAT_AREC != DYNAREC_NONE
2013-12-19 17:10:14 +00:00
2020-03-28 16:58:01 +00:00
#include "virt_arm.h"
2013-12-19 17:10:14 +00:00
namespace VARM
{
#define CPUReadByte(addr) (*(u8*)(addr))
#define CPUReadMemory(addr) (*(u32*)(addr))
#define CPUReadHalfWord(addr) (*(u16*)(addr))
#define CPUReadHalfWordSigned(addr) (*(s16*)(addr))
#define CPUWriteMemory(addr,data) (*(u32*)addr=data)
#define CPUWriteHalfWord(addr,data) (*(u16*)addr=data)
#define CPUWriteByte(addr,data) (*(u8*)addr=data)
#define reg arm_Reg
#define armNextPC arm_ArmNextPC
#define CPUUpdateTicksAccesint(a) 1
#define CPUUpdateTicksAccessSeq32(a) 1
#define CPUUpdateTicksAccesshort(a) 1
#define CPUUpdateTicksAccess32(a) 1
#define CPUUpdateTicksAccess16(a) 1
typedef union
{
struct
{
2013-12-19 17:10:14 +00:00
u8 B0;
u8 B1;
u8 B2;
u8 B3;
} B;
struct
{
2013-12-19 17:10:14 +00:00
u16 W0;
u16 W1;
} W;
2013-12-19 17:10:14 +00:00
u32 I;
} reg_pair;
u32 arm_ArmNextPC;
reg_pair arm_Reg[45];
void CPUSwap(u32 *a, u32 *b)
{
u32 c = *b;
*b = *a;
*a = c;
}
bool N_FLAG;
bool Z_FLAG;
bool C_FLAG;
bool V_FLAG;
bool armIrqEnable;
bool armFiqEnable;
int armMode;
u8 cpuBitsSet[256];
void CPUSwitchMode(int mode, bool saveState, bool breakLoop=true);
void CPUFiq();
void CPUUpdateCPSR();
void CPUUpdateFlags();
void CPUSoftwareInterrupt(int comment);
void CPUUndefinedException();
void CPUInterrupt();
u32 virt_arm_op(u32 opcode)
{
u32 clockTicks=0;
armNextPC=reg[15].I=0;
#include "arm-new.h"
verify(reg[15].I==0);
verify(arm_ArmNextPC==0);
return clockTicks;
}
void CPUSwitchMode(int mode, bool saveState, bool breakLoop)
{
verify(mode==0x10);
}
void CPUUpdateCPSR()
{
u32 CPSR = reg[16].I & 0x40;
if(N_FLAG)
CPSR |= 0x80000000;
if(Z_FLAG)
CPSR |= 0x40000000;
if(C_FLAG)
CPSR |= 0x20000000;
if(V_FLAG)
CPSR |= 0x10000000;
/*if(!armState)
CPSR |= 0x00000020;*/
if (!armFiqEnable)
CPSR |= 0x40;
if(!armIrqEnable)
CPSR |= 0x80;
CPSR |= (armMode & 0x1F);
reg[16].I = CPSR;
verify(armMode==0);
verify(armFiqEnable==false);
verify(armIrqEnable==false);
}
void CPUUpdateFlags()
{
u32 CPSR = reg[16].I;
N_FLAG = (CPSR & 0x80000000) ? true: false;
Z_FLAG = (CPSR & 0x40000000) ? true: false;
C_FLAG = (CPSR & 0x20000000) ? true: false;
V_FLAG = (CPSR & 0x10000000) ? true: false;
//armState = (CPSR & 0x20) ? false : true;
armIrqEnable = (CPSR & 0x80) ? false : true;
armFiqEnable = (CPSR & 0x40) ? false : true;
verify(armMode==0);
verify(armFiqEnable==false);
verify(armIrqEnable==false);
}
void CPUSoftwareInterrupt(int comment)
{
die("Can't happen");
}
void CPUUndefinedException()
{
die("Can't happen");
}
void virt_arm_reset()
{
// clean registers
memset(&arm_Reg[0], 0, sizeof(arm_Reg));
armMode = 0x0;
reg[13].I = 0x03007F00;
reg[15].I = 0x0000000;
reg[16].I = 0x00000000;
// disable FIQ
reg[16].I |= 0x40;
CPUUpdateCPSR();
armNextPC = reg[15].I;
reg[15].I += 4;
//arm_FiqPending = false;
}
void virt_arm_init()
{
virt_arm_reset();
for (int i = 0; i < 256; i++)
2013-12-19 17:10:14 +00:00
{
int count = 0;
for (int j = 0; j < 8; j++)
if (i & (1 << j))
2013-12-19 17:10:14 +00:00
count++;
2013-12-19 17:10:14 +00:00
cpuBitsSet[i] = count;
}
}
}
void virt_arm_reset()
{
VARM::virt_arm_reset();
}
void virt_arm_init()
{
VARM::virt_arm_init();
}
2015-05-08 16:59:20 +00:00
u32 DYNACALL virt_arm_op(u32 opcode)
2013-12-19 17:10:14 +00:00
{
return VARM::virt_arm_op(opcode);
}
u32& virt_arm_reg(u32 id)
{
return VARM::arm_Reg[id].I;
}
2014-03-24 22:12:30 +00:00
#endif