summaryrefslogtreecommitdiffstats
path: root/src/core/arm/interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm/interpreter')
-rw-r--r--src/core/arm/interpreter/arm_interpreter.cpp39
-rw-r--r--src/core/arm/interpreter/arm_interpreter.h37
-rw-r--r--src/core/arm/interpreter/armemu.cpp3
-rw-r--r--src/core/arm/interpreter/armemu.h11
-rw-r--r--src/core/arm/interpreter/arminit.cpp8
-rw-r--r--src/core/arm/interpreter/armsupp.cpp68
6 files changed, 125 insertions, 41 deletions
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index 81f38f016..4045779d7 100644
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -31,30 +31,61 @@ ARM_Interpreter::ARM_Interpreter() {
m_state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
}
+ARM_Interpreter::~ARM_Interpreter() {
+ delete m_state;
+}
+
+/**
+ * Set the Program Counter to an address
+ * @param addr Address to set PC to
+ */
void ARM_Interpreter::SetPC(u32 pc) {
m_state->pc = m_state->Reg[15] = pc;
}
+/*
+ * Get the current Program Counter
+ * @return Returns current PC
+ */
u32 ARM_Interpreter::GetPC() const {
return m_state->pc;
}
+/**
+ * Get an ARM register
+ * @param index Register index (0-15)
+ * @return Returns the value in the register
+ */
u32 ARM_Interpreter::GetReg(int index) const {
return m_state->Reg[index];
}
+/**
+ * Set an ARM register
+ * @param index Register index (0-15)
+ * @param value Value to set register to
+ */
+void ARM_Interpreter::SetReg(int index, u32 value) {
+ m_state->Reg[index] = value;
+}
+
+/**
+ * Get the current CPSR register
+ * @return Returns the value of the CPSR register
+ */
u32 ARM_Interpreter::GetCPSR() const {
return m_state->Cpsr;
}
+/**
+ * Returns the number of clock ticks since the last reset
+ * @return Returns number of clock ticks
+ */
u64 ARM_Interpreter::GetTicks() const {
return ARMul_Time(m_state);
}
-ARM_Interpreter::~ARM_Interpreter() {
- delete m_state;
-}
-
+/// Execture next instruction
void ARM_Interpreter::ExecuteInstruction() {
m_state->step++;
m_state->cycle++;
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index 932046d9a..f3c86f8dd 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -12,22 +12,55 @@
class ARM_Interpreter : virtual public ARM_Interface {
public:
+
ARM_Interpreter();
~ARM_Interpreter();
- void ExecuteInstruction();
-
+ /**
+ * Set the Program Counter to an address
+ * @param addr Address to set PC to
+ */
void SetPC(u32 pc);
+ /*
+ * Get the current Program Counter
+ * @return Returns current PC
+ */
u32 GetPC() const;
+ /**
+ * Get an ARM register
+ * @param index Register index (0-15)
+ * @return Returns the value in the register
+ */
u32 GetReg(int index) const;
+ /**
+ * Set an ARM register
+ * @param index Register index (0-15)
+ * @param value Value to set register to
+ */
+ void SetReg(int index, u32 value);
+
+ /**
+ * Get the current CPSR register
+ * @return Returns the value of the CPSR register
+ */
u32 GetCPSR() const;
+ /**
+ * Returns the number of clock ticks since the last reset
+ * @return Returns number of clock ticks
+ */
u64 GetTicks() const;
+protected:
+
+ /// Execture next instruction
+ void ExecuteInstruction();
+
private:
+
ARMul_State* m_state;
DISALLOW_COPY_AND_ASSIGN(ARM_Interpreter);
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 46c51fbe8..6074ff480 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -16,6 +16,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+#include "core/hle/hle.h"
+
#include "arm_regformat.h"
#include "armdefs.h"
#include "armemu.h"
@@ -4558,6 +4560,7 @@ ARMul_Emulate26 (ARMul_State * state)
// ARMul_OSHandleSWI (state, BITS (0, 23));
// break;
//}
+ HLE::CallSyscall(instr);
ARMul_Abort (state, ARMul_SWIV);
break;
}
diff --git a/src/core/arm/interpreter/armemu.h b/src/core/arm/interpreter/armemu.h
index 7391dea7f..7c118948a 100644
--- a/src/core/arm/interpreter/armemu.h
+++ b/src/core/arm/interpreter/armemu.h
@@ -229,6 +229,17 @@ extern ARMword isize;
} \
while (0)
+#define SETABORT_SKIPBRANCH(i, m, d) \
+ do \
+ { \
+ int SETABORT_mode = (m); \
+ \
+ ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state)); \
+ ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT)) \
+ | (i) | SETABORT_mode)); \
+ } \
+ while (0)
+
//#ifndef MODE32
#define VECTORS 0x20
#define LEGALADDR 0x03ffffff
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp
index cdbd02f3c..a8aeecdea 100644
--- a/src/core/arm/interpreter/arminit.cpp
+++ b/src/core/arm/interpreter/arminit.cpp
@@ -530,9 +530,13 @@ ARMul_Abort (ARMul_State * state, ARMword vector)
isize);
break;
case ARMul_SWIV: /* Software Interrupt */
- SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
+ // Modified SETABORT that doesn't branch to a SVC vector as we are implementing this in HLE
+ // Instead of doing normal routine, backup R15 by one instruction (this is what PC will get
+ // set to, making it the next instruction after the SVC call), and skip setting the LR.
+ SETABORT_SKIPBRANCH (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
isize);
- break;
+ state->Reg[15] -= 4;
+ return;
case ARMul_PrefetchAbortV: /* Prefetch Abort */
state->AbortAddr = 1;
SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index a0c866c15..101b9807a 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -19,6 +19,8 @@
#include "armemu.h"
//#include "ansidecl.h"
#include "skyeye_defs.h"
+#include "core/hle/hle.h"
+
unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
unsigned cpnum);
//extern int skyeye_instr_debug;
@@ -734,39 +736,39 @@ ARMword
ARMul_MRC (ARMul_State * state, ARMword instr)
{
unsigned cpab;
- ARMword result = 0;
-
- //printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
- if (!CP_ACCESS_ALLOWED (state, CPNum)) {
- //chy 2004-07-19 should fix in the future????!!!!
- //printf("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n",CPNum, instr);
- ARMul_UndefInstr (state, instr);
- return -1;
- }
-
- cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
- while (cpab == ARMul_BUSY) {
- ARMul_Icycles (state, 1, 0);
- if (IntPending (state)) {
- cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
- instr, 0);
- return (0);
- }
- else
- cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
- &result);
- }
- if (cpab == ARMul_CANT) {
- printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr);
- ARMul_Abort (state, ARMul_UndefinedInstrV);
- /* Parent will destroy the flags otherwise. */
- result = ECC;
- }
- else {
- BUSUSEDINCPCN;
- ARMul_Ccycles (state, 1, 0);
- ARMul_Icycles (state, 1, 0);
- }
+ ARMword result = HLE::CallGetThreadCommandBuffer();
+
+ ////printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
+ //if (!CP_ACCESS_ALLOWED (state, CPNum)) {
+ // //chy 2004-07-19 should fix in the future????!!!!
+ // //printf("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n",CPNum, instr);
+ // ARMul_UndefInstr (state, instr);
+ // return -1;
+ //}
+
+ //cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
+ //while (cpab == ARMul_BUSY) {
+ // ARMul_Icycles (state, 1, 0);
+ // if (IntPending (state)) {
+ // cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
+ // instr, 0);
+ // return (0);
+ // }
+ // else
+ // cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
+ // &result);
+ //}
+ //if (cpab == ARMul_CANT) {
+ // printf ("SKYEYE ARMul_MRC,CANT UndefInstr CPnum is %x, instr %x\n", CPNum, instr);
+ // ARMul_Abort (state, ARMul_UndefinedInstrV);
+ // /* Parent will destroy the flags otherwise. */
+ // result = ECC;
+ //}
+ //else {
+ // BUSUSEDINCPCN;
+ // ARMul_Ccycles (state, 1, 0);
+ // ARMul_Icycles (state, 1, 0);
+ //}
return result;
}