diff --git a/src/agb/GBAcpu.h b/src/agb/GBAcpu.h
new file mode 100644
index 00000000..53384e9d
--- /dev/null
+++ b/src/agb/GBAcpu.h
@@ -0,0 +1,302 @@
+// -*- C++ -*-
+// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
+// Copyright (C) 1999-2003 Forgotten
+// Copyright (C) 2005 Forgotten and the VBA development team
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or(at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#ifndef VBA_GBAcpu_H
+#define VBA_GBAcpu_H
+
+extern int armExecute();
+extern int thumbExecute();
+
+#ifdef __GNUC__
+# define INSN_REGPARM __attribute__((regparm(1)))
+# define LIKELY(x) __builtin_expect(!!(x),1)
+# define UNLIKELY(x) __builtin_expect(!!(x),0)
+#else
+# define INSN_REGPARM /*nothing*/
+# define LIKELY(x) (x)
+# define UNLIKELY(x) (x)
+#endif
+
+#define UPDATE_REG(address, value)\
+  {\
+    WRITE16LE(((u16 *)&ioMem[address]),value);\
+  }\
+
+#define ARM_PREFETCH \
+  {\
+    cpuPrefetch[0] = CPUReadMemoryQuick(armNextPC);\
+    cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);\
+  }
+
+#define THUMB_PREFETCH \
+  {\
+    cpuPrefetch[0] = CPUReadHalfWordQuick(armNextPC);\
+    cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);\
+  }
+
+#define ARM_PREFETCH_NEXT \
+  cpuPrefetch[1] = CPUReadMemoryQuick(armNextPC+4);
+
+#define THUMB_PREFETCH_NEXT\
+  cpuPrefetch[1] = CPUReadHalfWordQuick(armNextPC+2);
+
+
+extern int SWITicks;
+extern u32 mastercode;
+extern bool busPrefetch;
+extern bool busPrefetchEnable;
+extern u32 busPrefetchCount;
+extern int cpuNextEvent;
+extern bool holdState;
+extern u32 cpuPrefetch[2];
+extern int cpuTotalTicks;
+extern u8 memoryWait[16];
+extern u8 memoryWait32[16];
+extern u8 memoryWaitSeq[16];
+extern u8 memoryWaitSeq32[16];
+extern u8 cpuBitsSet[256];
+extern u8 cpuLowestBitSet[256];
+extern void CPUSwitchMode(int mode, bool saveState, bool breakLoop);
+extern void CPUSwitchMode(int mode, bool saveState);
+extern void CPUUpdateCPSR();
+extern void CPUUpdateFlags(bool breakLoop);
+extern void CPUUpdateFlags();
+extern void CPUUndefinedException();
+extern void CPUSoftwareInterrupt();
+extern void CPUSoftwareInterrupt(int comment);
+
+
+// Waitstates when accessing data
+inline int dataTicksAccess16(u32 address) // DATA 8/16bits NON SEQ
+{
+  int addr = (address>>24)&15;
+  int value =  memoryWait[addr];
+
+  if ((addr>=0x08) || (addr < 0x02))
+  {
+    busPrefetchCount=0;
+    busPrefetch=false;
+  }
+  else if (busPrefetch)
+  {
+    int waitState = value;
+    if (!waitState)
+      waitState = 1;
+    busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
+  }
+
+  return value;
+}
+
+inline int dataTicksAccess32(u32 address) // DATA 32bits NON SEQ
+{
+  int addr = (address>>24)&15;
+  int value = memoryWait32[addr];
+
+  if ((addr>=0x08) || (addr < 0x02))
+  {
+    busPrefetchCount=0;
+    busPrefetch=false;
+  }
+  else if (busPrefetch)
+  {
+    int waitState = value;
+    if (!waitState)
+      waitState = 1;
+    busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
+  }
+
+  return value;
+}
+
+inline int dataTicksAccessSeq16(u32 address)// DATA 8/16bits SEQ
+{
+  int addr = (address>>24)&15;
+  int value = memoryWaitSeq[addr];
+
+  if ((addr>=0x08) || (addr < 0x02))
+  {
+    busPrefetchCount=0;
+    busPrefetch=false;
+  }
+  else if (busPrefetch)
+  {
+    int waitState = value;
+    if (!waitState)
+      waitState = 1;
+    busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
+  }
+
+  return value;
+}
+
+inline int dataTicksAccessSeq32(u32 address)// DATA 32bits SEQ
+{
+  int addr = (address>>24)&15;
+  int value =  memoryWaitSeq32[addr];
+
+  if ((addr>=0x08) || (addr < 0x02))
+  {
+    busPrefetchCount=0;
+    busPrefetch=false;
+  }
+  else if (busPrefetch)
+  {
+    int waitState = value;
+    if (!waitState)
+      waitState = 1;
+    busPrefetchCount = ((busPrefetchCount+1)<<waitState) - 1;
+  }
+
+  return value;
+}
+
+
+// Waitstates when executing opcode
+inline int codeTicksAccess16(u32 address) // THUMB NON SEQ
+{
+  int addr = (address>>24)&15;
+
+  if ((addr>=0x08) && (addr<=0x0D))
+  {
+    if (busPrefetchCount&0x1)
+    {
+      if (busPrefetchCount&0x2)
+      {
+        busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
+        return 0;
+      }
+      busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
+      return memoryWaitSeq[addr]-1;
+    }
+    else
+    {
+      busPrefetchCount=0;
+      return memoryWait[addr];
+    }
+  }
+  else
+  {
+    busPrefetchCount = 0;
+    return memoryWait[addr];
+  }
+}
+
+inline int codeTicksAccess32(u32 address) // ARM NON SEQ
+{
+  int addr = (address>>24)&15;
+
+  if ((addr>=0x08) && (addr<=0x0D))
+  {
+    if (busPrefetchCount&0x1)
+    {
+      if (busPrefetchCount&0x2)
+      {
+        busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
+        return 0;
+      }
+      busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
+      return memoryWaitSeq[addr] - 1;
+    }
+    else
+    {
+      busPrefetchCount = 0;
+      return memoryWait32[addr];
+    }
+  }
+  else
+  {
+    busPrefetchCount = 0;
+    return memoryWait32[addr];
+  }
+}
+
+inline int codeTicksAccessSeq16(u32 address) // THUMB SEQ
+{
+  int addr = (address>>24)&15;
+
+  if ((addr>=0x08) && (addr<=0x0D))
+  {
+    if (busPrefetchCount&0x1)
+    {
+      busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
+      return 0;
+    }
+    else
+    if (busPrefetchCount>0xFF)
+    {
+      busPrefetchCount=0;
+      return memoryWait[addr];
+    }
+    else
+      return memoryWaitSeq[addr];
+  }
+  else
+  {
+    busPrefetchCount = 0;
+    return memoryWaitSeq[addr];
+  }
+}
+
+inline int codeTicksAccessSeq32(u32 address) // ARM SEQ
+{
+  int addr = (address>>24)&15;
+
+  if ((addr>=0x08) && (addr<=0x0D))
+  {
+    if (busPrefetchCount&0x1)
+    {
+      if (busPrefetchCount&0x2)
+      {
+        busPrefetchCount = ((busPrefetchCount&0xFF)>>2) | (busPrefetchCount&0xFFFFFF00);
+        return 0;
+      }
+      busPrefetchCount = ((busPrefetchCount&0xFF)>>1) | (busPrefetchCount&0xFFFFFF00);
+      return memoryWaitSeq[addr];
+    }
+    else
+    if (busPrefetchCount>0xFF)
+    {
+      busPrefetchCount=0;
+      return memoryWait32[addr];
+    }
+    else
+      return memoryWaitSeq32[addr];
+  }
+  else
+  {
+    return memoryWaitSeq32[addr];
+  }
+}
+
+
+// Emulates the Cheat System (m) code
+inline void cpuMasterCodeCheck()
+{
+  if((mastercode) && (mastercode == armNextPC))
+  {
+    u32 joy = 0;
+    if(systemReadJoypads())
+      joy = systemReadJoypad(-1);
+    u32 ext = (joy >> 10);
+    cpuTotalTicks += cheatsCheckKeys(P1^0x3FF, ext);
+  }
+}
+
+#endif //VBA_GBAcpu_H