#include "virt_arm.h" #if HOST_CPU==CPU_X86 && !defined(HOST_NO_REC) #define C_CORE namespace VARM { //#define CPUReadHalfWordQuick(addr) arm_ReadMem16(addr & 0x7FFFFF) //#define CPUReadMemoryQuick(addr) (*(u32*)(addr)) #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 { u8 B0; u8 B1; u8 B2; u8 B3; } B; struct { u16 W0; u16 W1; } W; 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); /* CPUUpdateCPSR(); switch(armMode) { case 0x10: case 0x1F: reg[R13_USR].I = reg[13].I; reg[R14_USR].I = reg[14].I; reg[17].I = reg[16].I; break; case 0x11: CPUSwap(®[R8_FIQ].I, ®[8].I); CPUSwap(®[R9_FIQ].I, ®[9].I); CPUSwap(®[R10_FIQ].I, ®[10].I); CPUSwap(®[R11_FIQ].I, ®[11].I); CPUSwap(®[R12_FIQ].I, ®[12].I); reg[R13_FIQ].I = reg[13].I; reg[R14_FIQ].I = reg[14].I; reg[SPSR_FIQ].I = reg[17].I; break; case 0x12: reg[R13_IRQ].I = reg[13].I; reg[R14_IRQ].I = reg[14].I; reg[SPSR_IRQ].I = reg[17].I; break; case 0x13: reg[R13_SVC].I = reg[13].I; reg[R14_SVC].I = reg[14].I; reg[SPSR_SVC].I = reg[17].I; break; case 0x17: reg[R13_ABT].I = reg[13].I; reg[R14_ABT].I = reg[14].I; reg[SPSR_ABT].I = reg[17].I; break; case 0x1b: reg[R13_UND].I = reg[13].I; reg[R14_UND].I = reg[14].I; reg[SPSR_UND].I = reg[17].I; break; } u32 CPSR = reg[16].I; u32 SPSR = reg[17].I; switch(mode) { case 0x10: case 0x1F: reg[13].I = reg[R13_USR].I; reg[14].I = reg[R14_USR].I; reg[16].I = SPSR; break; case 0x11: CPUSwap(®[8].I, ®[R8_FIQ].I); CPUSwap(®[9].I, ®[R9_FIQ].I); CPUSwap(®[10].I, ®[R10_FIQ].I); CPUSwap(®[11].I, ®[R11_FIQ].I); CPUSwap(®[12].I, ®[R12_FIQ].I); reg[13].I = reg[R13_FIQ].I; reg[14].I = reg[R14_FIQ].I; if(saveState) reg[17].I = CPSR; else reg[17].I = reg[SPSR_FIQ].I; break; case 0x12: reg[13].I = reg[R13_IRQ].I; reg[14].I = reg[R14_IRQ].I; reg[16].I = SPSR; if(saveState) reg[17].I = CPSR; else reg[17].I = reg[SPSR_IRQ].I; break; case 0x13: reg[13].I = reg[R13_SVC].I; reg[14].I = reg[R14_SVC].I; reg[16].I = SPSR; if(saveState) reg[17].I = CPSR; else reg[17].I = reg[SPSR_SVC].I; break; case 0x17: reg[13].I = reg[R13_ABT].I; reg[14].I = reg[R14_ABT].I; reg[16].I = SPSR; if(saveState) reg[17].I = CPSR; else reg[17].I = reg[SPSR_ABT].I; break; case 0x1b: reg[13].I = reg[R13_UND].I; reg[14].I = reg[R14_UND].I; reg[16].I = SPSR; if(saveState) reg[17].I = CPSR; else reg[17].I = reg[SPSR_UND].I; break; default: printf("Unsupported ARM mode %02x\n", mode); die("Arm error.."); break; } armMode = mode; CPUUpdateFlags(); CPUUpdateCPSR();*/ } 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++) { int count = 0; for (int j = 0; j < 8; j++) if (i & (1 << j)) count++; cpuBitsSet[i] = count; } } } void virt_arm_reset() { VARM::virt_arm_reset(); } void virt_arm_init() { VARM::virt_arm_init(); } u32 __fastcall virt_arm_op(u32 opcode) { return VARM::virt_arm_op(opcode); } u32& virt_arm_reg(u32 id) { return VARM::arm_Reg[id].I; } #endif