diff -urN ../VisualBoyAdvance-20061204/src/GBA-arm.cpp src/GBA-arm.cpp
--- ../VisualBoyAdvance-20061204/src/GBA-arm.cpp	1970-01-01 09:00:00 +0900
+++ src/GBA-arm.cpp	2006-12-05 00:18:42 +0900
@@ -0,0 +1,2964 @@
+// -*- C++ -*-
+// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
+// Copyright (C) 1999-2003 Forgotten
+// Copyright (C) 2005-2006 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.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "GBA.h"
+#include "GBAcpu.h"
+#include "GBAinline.h"
+#include "Globals.h"
+#include "Gfx.h"
+#include "EEprom.h"
+#include "Flash.h"
+#include "Sound.h"
+#include "Sram.h"
+#include "bios.h"
+#include "unzip.h"
+#include "Cheats.h"
+#include "NLS.h"
+#include "elf.h"
+#include "Util.h"
+#include "Port.h"
+#include "agbprint.h"
+#ifdef PROFILING
+#include "prof/prof.h"
+#endif
+
+#ifdef _MSC_VER
+ // Disable "empty statement" warnings
+ #pragma warning(disable: 4390)
+ // Visual C's inline assembler treats "offset" as a reserved word, so we
+ // tell it otherwise.  If you want to use it, write "OFFSET" in capitals.
+ #define offset offset_
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+
+static int clockTicks;
+
+static INSN_REGPARM void armUnknownInsn(u32 opcode)
+{
+#ifdef DEV_VERSION
+    if (systemVerbose & VERBOSE_UNDEFINED) {
+        log("Undefined ARM instruction %08x at %08x\n", opcode,
+            armNextPC-4);
+    }
+#endif
+    CPUUndefinedException();
+}
+
+#ifdef BKPT_SUPPORT
+static INSN_REGPARM void armBreakpoint(u32 opcode)
+{
+    extern void (*dbgSignal)(int,int);
+    reg[15].I -= 4;
+    armNextPC -= 4;
+    dbgSignal(5, (opcode & 0x0f) | ((opcode>>4) & 0xfff0));
+    clockTicks = -1;
+}
+#endif
+
+
+// Subroutine to count instructions (for debugging/optimizing)
+//#define INSN_COUNTER  // comment out if you don't want it
+#ifdef INSN_COUNTER
+static void count(u32 opcode, int cond_res)
+{
+    static int insncount = 0;    // number of insns seen
+    static int executed = 0;     // number of insns executed
+    static int mergewith[4096];  // map instructions to routines
+    static int count[4096];      // count of each 12-bit code
+    int index = ((opcode>>16)&0xFF0) | ((opcode>>4)&0x0F);
+    static FILE *outfile = NULL;
+
+    if (!insncount) {
+        for (int i = 0; i < 4096; i++) {
+            for (int j = 0; j < i; j++) {
+                if (armInsnTable[i] == armInsnTable[j])
+                    break;
+            }
+            mergewith[i] = j;
+        }
+        outfile = fopen("VBA-armcount.txt", "w");
+    }
+    if (cond_res) {
+        count[mergewith[index]]++;
+        executed++;
+    }
+    insncount++;
+    if (outfile && insncount%1000000 == 0) {
+        fprintf(outfile, "Total instructions: %d\n", insncount);
+        fprintf(outfile, "Instructions executed: %d\n", executed);
+        for (int i = 0; i < 4096; i++) {
+            if (count[i])
+                fprintf(outfile, "arm%03X: %d\n", i, count[i]);
+        }
+    }
+}
+#endif
+
+// Common macros //////////////////////////////////////////////////////////
+
+#ifdef BKPT_SUPPORT
+#define CONSOLE_OUTPUT(a,b) do { \
+    extern void (*dbgOutput)(char *, u32);                      \
+    if ((opcode == 0xe0000000) && (reg[0].I == 0xC0DED00D)) {   \
+        dbgOutput((a), (b));                                    \
+} while (0)
+#else
+#define CONSOLE_OUTPUT(a,b)  /* nothing */
+#endif
+
+#define NEG(i) ((i) >> 31)
+#define POS(i) ((~(i)) >> 31)
+
+// The following macros are used for optimization; any not defined for a
+// particular compiler/CPU combination default to the C core versions.
+//
+//    ALU_INIT_C:   Used at the beginning of ALU instructions (AND/EOR/...).
+//    (ALU_INIT_NC) Can consist of variable declarations, like the C core,
+//                  or the start of a continued assembly block, like the
+//                  x86-optimized version.  The _C version is used when the
+//                  carry flag from the shift operation is needed (logical
+//                  operations that set condition codes, like ANDS); the
+//                  _NC version is used when the carry result is ignored.
+//    VALUE_XXX: Retrieve the second operand's value for an ALU instruction.
+//               The _C and _NC versions are used the same way as ALU_INIT.
+//    OP_XXX: ALU operations.  XXX is the instruction name.
+//    ALU_FINISH: Appended to all ALU instructions.  Usually empty, but if
+//                ALU_INIT started a block ALU_FINISH can be used to end it
+//                (as with the asm(...) statement in the x86 core).
+//    SETCOND_NONE: Used in multiply instructions in place of SETCOND_MUL
+//                  when the condition codes are not set.  Usually empty.
+//    SETCOND_MUL: Used in multiply instructions to set the condition codes.
+//    ROR_IMM_MSR: Used to rotate the immediate operand for MSR.
+//    ROR_OFFSET: Used to rotate the `offset' parameter for LDR and STR
+//                instructions.
+//    RRX_OFFSET: Used to rotate (RRX) the `offset' parameter for LDR and
+//                STR instructions.
+
+#ifndef C_CORE
+
+#if 0  // definitions have changed
+//#ifdef __POWERPC__
+            #define OP_SUBS \
+            {\
+                register int Flags;                             \
+                register int Result;                            \
+                asm volatile("subco. %0, %2, %3\n"              \
+                            "mcrxr cr1\n"                       \
+                            "mfcr %1\n"                         \
+                            : "=r" (Result),                    \
+                              "=r" (Flags)                      \
+                            : "r" (reg[base].I),                \
+                              "r" (value)                       \
+                            );                                  \
+                reg[dest].I = Result;                           \
+                Z_FLAG = (Flags >> 29) & 1;                     \
+                N_FLAG = (Flags >> 31) & 1;                     \
+                C_FLAG = (Flags >> 25) & 1;                     \
+                V_FLAG = (Flags >> 26) & 1;                     \
+            }
+            #define OP_RSBS \
+            {\
+                register int Flags;                             \
+                register int Result;                            \
+                asm volatile("subfco. %0, %2, %3\n"             \
+                            "mcrxr cr1\n"                       \
+                            "mfcr %1\n"                         \
+                            : "=r" (Result),                    \
+                              "=r" (Flags)                      \
+                            : "r" (reg[base].I),                \
+                              "r" (value)                       \
+                            );                                  \
+                reg[dest].I = Result;                           \
+                Z_FLAG = (Flags >> 29) & 1;                     \
+                N_FLAG = (Flags >> 31) & 1;                     \
+                C_FLAG = (Flags >> 25) & 1;                     \
+                V_FLAG = (Flags >> 26) & 1;                     \
+            }
+            #define OP_ADDS \
+            {\
+                register int Flags;                             \
+                register int Result;                            \
+                asm volatile("addco. %0, %2, %3\n"              \
+                            "mcrxr cr1\n"                       \
+                            "mfcr %1\n"                         \
+                            : "=r" (Result),                    \
+                              "=r" (Flags)                      \
+                            : "r" (reg[base].I),                \
+                              "r" (value)                       \
+                            );                                  \
+                reg[dest].I = Result;                           \
+                Z_FLAG = (Flags >> 29) & 1;                     \
+                N_FLAG = (Flags >> 31) & 1;                     \
+                C_FLAG = (Flags >> 25) & 1;                     \
+                V_FLAG = (Flags >> 26) & 1;                     \
+            }
+            #define OP_ADCS \
+            {\
+                register int Flags;                             \
+                register int Result;                            \
+                asm volatile("mtspr xer, %4\n"                  \
+                             "addeo. %0, %2, %3\n"              \
+                             "mcrxr cr1\n"                      \
+                             "mfcr      %1\n"                   \
+                             : "=r" (Result),                   \
+                               "=r" (Flags)                     \
+                             : "r" (reg[base].I),               \
+                               "r" (value),                     \
+                               "r" (C_FLAG << 29)               \
+                             );                                 \
+                reg[dest].I = Result;                           \
+                Z_FLAG = (Flags >> 29) & 1;                     \
+                N_FLAG = (Flags >> 31) & 1;                     \
+                C_FLAG = (Flags >> 25) & 1;                     \
+                V_FLAG = (Flags >> 26) & 1;                     \
+            }
+            #define OP_SBCS \
+            {\
+                register int Flags;                             \
+                register int Result;                            \
+                asm volatile("mtspr xer, %4\n"                  \
+                             "subfeo. %0, %3, %2\n"             \
+                             "mcrxr cr1\n"                      \
+                             "mfcr      %1\n"                   \
+                             : "=r" (Result),                   \
+                               "=r" (Flags)                     \
+                             : "r" (reg[base].I),               \
+                               "r" (value),                     \
+                               "r" (C_FLAG << 29)               \
+                             );                                 \
+                reg[dest].I = Result;                           \
+                Z_FLAG = (Flags >> 29) & 1;                     \
+                N_FLAG = (Flags >> 31) & 1;                     \
+                C_FLAG = (Flags >> 25) & 1;                     \
+                V_FLAG = (Flags >> 26) & 1;                     \
+            }
+            #define OP_RSCS \
+            {\
+                register int Flags;                             \
+                register int Result;                            \
+                asm volatile("mtspr xer, %4\n"                  \
+                             "subfeo. %0, %2, %3\n"             \
+                             "mcrxr cr1\n"                      \
+                             "mfcr      %1\n"                   \
+                             : "=r" (Result),                   \
+                               "=r" (Flags)                     \
+                             : "r" (reg[base].I),               \
+                               "r" (value),                     \
+                               "r" (C_FLAG << 29)               \
+                             );                                 \
+                reg[dest].I = Result;                           \
+                Z_FLAG = (Flags >> 29) & 1;                     \
+                N_FLAG = (Flags >> 31) & 1;                     \
+                C_FLAG = (Flags >> 25) & 1;                     \
+                V_FLAG = (Flags >> 26) & 1;                     \
+            }
+            #define OP_CMP \
+            {\
+                register int Flags;                             \
+                register int Result;                            \
+                asm volatile("subco. %0, %2, %3\n"              \
+                            "mcrxr cr1\n"                       \
+                            "mfcr %1\n"                         \
+                            : "=r" (Result),                    \
+                              "=r" (Flags)                      \
+                            : "r" (reg[base].I),                \
+                              "r" (value)                       \
+                            );                                  \
+                Z_FLAG = (Flags >> 29) & 1;                     \
+                N_FLAG = (Flags >> 31) & 1;                     \
+                C_FLAG = (Flags >> 25) & 1;                     \
+                V_FLAG = (Flags >> 26) & 1;                     \
+            }
+            #define OP_CMN \
+            {\
+                register int Flags;                             \
+                register int Result;                            \
+                asm volatile("addco. %0, %2, %3\n"              \
+                            "mcrxr cr1\n"                       \
+                            "mfcr %1\n"                         \
+                            : "=r" (Result),                    \
+                              "=r" (Flags)                      \
+                            : "r" (reg[base].I),                \
+                              "r" (value)                       \
+                            );                                  \
+                Z_FLAG = (Flags >> 29) & 1;                     \
+                N_FLAG = (Flags >> 31) & 1;                     \
+                C_FLAG = (Flags >> 25) & 1;                     \
+                V_FLAG = (Flags >> 26) & 1;                     \
+            }
+
+#else  // !__POWERPC__
+
+// Macros to emit instructions in the format used by the particular compiler.
+// We use GNU assembler syntax: "op src, dest" rather than "op dest, src"
+
+#ifdef __GNUC__
+ #define ALU_HEADER           asm("mov %%ecx, %%edi; "
+ #define ALU_TRAILER          : "=D" (opcode) : "c" (opcode) : "eax", "ebx", "edx", "esi")
+ #define EMIT0(op)            #op"; "
+ #define EMIT1(op,arg)        #op" "arg"; "
+ #define EMIT2(op,src,dest)   #op" "src", "dest"; "
+ #define CONST(val)           "$"#val
+ #define VAR(var)             #var
+ #define VARL(var)            #var
+ #define REGREF1(index)       "reg("index")"
+ #define REGREF2(index,scale) "reg(,"index","#scale")"
+ #define LABEL(n)             #n": "
+ #define LABELREF(n,dir)      #n#dir
+ #define al "%%al"
+ #define ah "%%ah"
+ #define eax "%%eax"
+ #define bl "%%bl"
+ #define bh "%%bh"
+ #define ebx "%%ebx"
+ #define cl "%%cl"
+ #define ch "%%ch"
+ #define ecx "%%ecx"
+ #define dl "%%dl"
+ #define dh "%%dh"
+ #define edx "%%edx"
+ #define esp "%%esp"
+ #define ebp "%%ebp"
+ #define esi "%%esi"
+ #define edi "%%edi"
+ #define movzx movzb
+#else
+ #define ALU_HEADER           __asm { __asm mov ecx, opcode
+ #define ALU_TRAILER          }
+ #define EMIT0(op)            __asm op
+ #define EMIT1(op,arg)        __asm op arg
+ #define EMIT2(op,src,dest)   __asm op dest, src
+ #define CONST(val)           val
+ #define VAR(var)             var
+ #define VARL(var)            dword ptr var
+ #define REGREF1(index)       reg[index]
+ #define REGREF2(index,scale) reg[index*scale]
+ #define LABEL(n)             __asm l##n:
+ #define LABELREF(n,dir)      l##n
+#endif
+
+//X//#ifndef _MSC_VER
+// ALU op register usage:
+//    EAX -> 2nd operand value, result (RSB/RSC)
+//    EBX -> C_OUT (carry flag from shift/rotate)
+//    ECX -> opcode (input), shift/rotate count
+//    EDX -> Rn (base) value, result (all except RSB/RSC)
+//    ESI -> Rd (destination) index * 4
+
+// Helper macros for loading value / shift count
+#define VALUE_LOAD_IMM \
+        EMIT2(and, CONST(0x0F), eax)            \
+        EMIT2(mov, REGREF2(eax,4), eax)         \
+        EMIT2(shr, CONST(7), ecx)               \
+        EMIT2(and, CONST(0x1F), ecx)
+#define VALUE_LOAD_REG \
+        EMIT2(and, CONST(0x0F), eax)            \
+        EMIT2(mov, REGREF2(eax,4), eax)         \
+        EMIT2(movzx, ch, ecx)                   \
+        EMIT2(and, CONST(0x0F), ecx)            \
+        EMIT2(mov, REGREF2(ecx,4), ecx)
+
+// Helper macros for setting flags
+#define SETCOND_LOGICAL \
+    EMIT1(sets, VAR(N_FLAG))            \
+    EMIT1(setz, VAR(Z_FLAG))            \
+    EMIT2(mov, bl, VAR(C_FLAG))
+#define SETCOND_ADD \
+    EMIT1(sets, VAR(N_FLAG))            \
+    EMIT1(setz, VAR(Z_FLAG))            \
+    EMIT1(seto, VAR(V_FLAG))            \
+    EMIT1(setc, VAR(C_FLAG))
+#define SETCOND_SUB \
+    EMIT1(sets, VAR(N_FLAG))            \
+    EMIT1(setz, VAR(Z_FLAG))            \
+    EMIT1(seto, VAR(V_FLAG))            \
+    EMIT1(setnc, VAR(C_FLAG))
+
+// ALU initialization
+#define ALU_INIT(LOAD_C_FLAG) \
+    ALU_HEADER                          \
+    LOAD_C_FLAG                         \
+    EMIT2(mov, ecx, edx)                \
+    EMIT2(shr, CONST(14), edx)          \
+    EMIT2(mov, ecx, eax)                \
+    EMIT2(mov, ecx, esi)                \
+    EMIT2(shr, CONST(10), esi)          \
+    EMIT2(and, CONST(0x3C), edx)        \
+    EMIT2(mov, REGREF1(edx), edx)       \
+    EMIT2(and, CONST(0x3C), esi)
+
+#define LOAD_C_FLAG_YES EMIT2(mov, VAR(C_FLAG), bl)
+#define LOAD_C_FLAG_NO  /*nothing*/
+#define ALU_INIT_C ALU_INIT(LOAD_C_FLAG_YES)
+#define ALU_INIT_NC ALU_INIT(LOAD_C_FLAG_NO)
+
+// Macros to load the value operand for an ALU op; these all set N/Z
+// according to the value
+
+// OP Rd,Rb,Rm LSL #
+#define VALUE_LSL_IMM_C \
+    VALUE_LOAD_IMM                      \
+    EMIT1(jnz, LABELREF(1,f))           \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(shl, cl, eax)                 \
+    EMIT1(setc, bl)                     \
+    LABEL(0)
+#define VALUE_LSL_IMM_NC \
+    VALUE_LOAD_IMM                      \
+    EMIT2(shl, cl, eax)
+
+// OP Rd,Rb,Rm LSL Rs
+#define VALUE_LSL_REG_C \
+    VALUE_LOAD_REG                      \
+    EMIT2(test, cl, cl)                 \
+    EMIT1(jz, LABELREF(0,f))            \
+    EMIT2(cmp, CONST(0x20), cl)         \
+    EMIT1(je, LABELREF(1,f))            \
+    EMIT1(ja, LABELREF(2,f))            \
+    EMIT2(shl, cl, eax)                 \
+    EMIT1(setc, bl)                     \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(test, CONST(1), al)           \
+    EMIT1(setnz, bl)                    \
+    EMIT2(xor, eax, eax)                \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(2)                            \
+    EMIT2(xor, ebx, ebx)                \
+    EMIT2(xor, eax, eax)                \
+    LABEL(0)
+#define VALUE_LSL_REG_NC \
+    VALUE_LOAD_REG                      \
+    EMIT2(cmp, CONST(0x20), cl)         \
+    EMIT1(jae, LABELREF(1,f))           \
+    EMIT2(shl, cl, eax)                 \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(xor, eax, eax)                \
+    LABEL(0)
+
+// OP Rd,Rb,Rm LSR #
+#define VALUE_LSR_IMM_C \
+    VALUE_LOAD_IMM                      \
+    EMIT1(jz, LABELREF(1,f))            \
+    EMIT2(shr, cl, eax)                 \
+    EMIT1(setc, bl)                     \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(test, eax, eax)               \
+    EMIT1(sets, bl)                     \
+    EMIT2(xor, eax, eax)                \
+    LABEL(0)
+#define VALUE_LSR_IMM_NC \
+    VALUE_LOAD_IMM                      \
+    EMIT1(jz, LABELREF(1,f))            \
+    EMIT2(shr, cl, eax)                 \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(xor, eax, eax)                \
+    LABEL(0)
+
+// OP Rd,Rb,Rm LSR Rs
+#define VALUE_LSR_REG_C \
+    VALUE_LOAD_REG                      \
+    EMIT2(test, cl, cl)                 \
+    EMIT1(jz, LABELREF(0,f))            \
+    EMIT2(cmp, CONST(0x20), cl)         \
+    EMIT1(je, LABELREF(1,f))            \
+    EMIT1(ja, LABELREF(2,f))            \
+    EMIT2(shr, cl, eax)                 \
+    EMIT1(setc, bl)                     \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(test, eax, eax)               \
+    EMIT1(sets, bl)                     \
+    EMIT2(xor, eax, eax)                \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(2)                            \
+    EMIT2(xor, ebx, ebx)                \
+    EMIT2(xor, eax, eax)                \
+    LABEL(0)
+#define VALUE_LSR_REG_NC \
+    VALUE_LOAD_REG                      \
+    EMIT2(cmp, CONST(0x20), cl)         \
+    EMIT1(jae, LABELREF(1,f))           \
+    EMIT2(shr, cl, eax)                 \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(xor, eax, eax)                \
+    LABEL(0)
+
+// OP Rd,Rb,Rm ASR #
+#define VALUE_ASR_IMM_C \
+    VALUE_LOAD_IMM                      \
+    EMIT1(jz, LABELREF(1,f))            \
+    EMIT2(sar, cl, eax)                 \
+    EMIT1(setc, bl)                     \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(sar, CONST(31), eax)          \
+    EMIT1(sets, bl)                     \
+    LABEL(0)
+#define VALUE_ASR_IMM_NC \
+    VALUE_LOAD_IMM                      \
+    EMIT1(jz, LABELREF(1,f))            \
+    EMIT2(sar, cl, eax)                 \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(sar, CONST(31), eax)          \
+    LABEL(0)
+
+// OP Rd,Rb,Rm ASR Rs
+#define VALUE_ASR_REG_C \
+    VALUE_LOAD_REG                      \
+    EMIT2(test, cl, cl)                 \
+    EMIT1(jz, LABELREF(0,f))            \
+    EMIT2(cmp, CONST(0x20), cl)         \
+    EMIT1(jae, LABELREF(1,f))           \
+    EMIT2(sar, cl, eax)                 \
+    EMIT1(setc, bl)                     \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(sar, CONST(31), eax)          \
+    EMIT1(sets, bl)                     \
+    LABEL(0)
+#define VALUE_ASR_REG_NC \
+    VALUE_LOAD_REG                      \
+    EMIT2(cmp, CONST(0x20), cl)         \
+    EMIT1(jae, LABELREF(1,f))           \
+    EMIT2(sar, cl, eax)                 \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(sar, CONST(31), eax)          \
+    LABEL(0)
+
+// OP Rd,Rb,Rm ROR #
+#define VALUE_ROR_IMM_C \
+    VALUE_LOAD_IMM                      \
+    EMIT1(jz, LABELREF(1,f))            \
+    EMIT2(ror, cl, eax)                 \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(bt, CONST(0), ebx)            \
+    EMIT2(rcr, CONST(1), eax)           \
+    LABEL(0)                            \
+    EMIT1(setc, bl)
+#define VALUE_ROR_IMM_NC \
+    VALUE_LOAD_IMM                      \
+    EMIT1(jz, LABELREF(1,f))            \
+    EMIT2(ror, cl, eax)                 \
+    EMIT1(jmp, LABELREF(0,f))           \
+    LABEL(1)                            \
+    EMIT2(bt, CONST(0), VARL(C_FLAG))   \
+    EMIT2(rcr, CONST(1), eax)           \
+    LABEL(0)
+
+// OP Rd,Rb,Rm ROR Rs
+#define VALUE_ROR_REG_C \
+    VALUE_LOAD_REG                      \
+    EMIT2(bt, CONST(0), ebx)            \
+    EMIT2(ror, cl, eax)                 \
+    EMIT1(setc, bl)
+#define VALUE_ROR_REG_NC \
+    VALUE_LOAD_REG                      \
+    EMIT2(ror, cl, eax)
+
+// OP Rd,Rb,# ROR #
+#define VALUE_IMM_C \
+    EMIT2(movzx, ch, ecx)               \
+    EMIT2(add, ecx, ecx)                \
+    EMIT2(movzx, al, eax)               \
+    EMIT2(bt, CONST(0), ebx)            \
+    EMIT2(ror, cl, eax)                 \
+    EMIT1(setc, bl)
+#define VALUE_IMM_NC \
+    EMIT2(movzx, ch, ecx)               \
+    EMIT2(add, ecx, ecx)                \
+    EMIT2(movzx, al, eax)               \
+    EMIT2(ror, cl, eax)
+
+// Macros to perform ALU ops
+
+// Set condition codes iff the destination register is not R15 (PC)
+#define CHECK_PC(OP, SETCOND) \
+    EMIT2(cmp, CONST(0x3C), esi)        \
+    EMIT1(je, LABELREF(8,f))            \
+    OP SETCOND                          \
+    EMIT1(jmp, LABELREF(9,f))           \
+    LABEL(8)                            \
+    OP                                  \
+    LABEL(9)
+
+#define OP_AND \
+    EMIT2(and, eax, edx)                \
+    EMIT2(mov, edx, REGREF1(esi))
+#define OP_ANDS   CHECK_PC(OP_AND, SETCOND_LOGICAL)
+#define OP_EOR \
+    EMIT2(xor, eax, edx)                \
+    EMIT2(mov, edx, REGREF1(esi))
+#define OP_EORS   CHECK_PC(OP_EOR, SETCOND_LOGICAL)
+#define OP_SUB \
+    EMIT2(sub, eax, edx)                \
+    EMIT2(mov, edx, REGREF1(esi))
+#define OP_SUBS   CHECK_PC(OP_SUB, SETCOND_SUB)
+#define OP_RSB \
+    EMIT2(sub, edx, eax)                \
+    EMIT2(mov, eax, REGREF1(esi))
+#define OP_RSBS   CHECK_PC(OP_RSB, SETCOND_SUB)
+#define OP_ADD \
+    EMIT2(add, eax, edx)                \
+    EMIT2(mov, edx, REGREF1(esi))
+#define OP_ADDS   CHECK_PC(OP_ADD, SETCOND_ADD)
+#define OP_ADC \
+    EMIT2(bt, CONST(0), VARL(C_FLAG))   \
+    EMIT2(adc, eax, edx)                \
+    EMIT2(mov, edx, REGREF1(esi))
+#define OP_ADCS   CHECK_PC(OP_ADC, SETCOND_ADD)
+#define OP_SBC \
+    EMIT2(bt, CONST(0), VARL(C_FLAG))   \
+    EMIT0(cmc)                          \
+    EMIT2(sbb, eax, edx)                \
+    EMIT2(mov, edx, REGREF1(esi))
+#define OP_SBCS   CHECK_PC(OP_SBC, SETCOND_SUB)
+#define OP_RSC \
+    EMIT2(bt, CONST(0), VARL(C_FLAG))   \
+    EMIT0(cmc)                          \
+    EMIT2(sbb, edx, eax)                \
+    EMIT2(mov, eax, REGREF1(esi))
+#define OP_RSCS   CHECK_PC(OP_RSC, SETCOND_SUB)
+#define OP_TST \
+    EMIT2(and, eax, edx)                \
+    SETCOND_LOGICAL
+#define OP_TEQ \
+    EMIT2(xor, eax, edx)                \
+    SETCOND_LOGICAL
+#define OP_CMP \
+    EMIT2(sub, eax, edx)                \
+    SETCOND_SUB
+#define OP_CMN \
+    EMIT2(add, eax, edx)                \
+    SETCOND_ADD
+#define OP_ORR \
+    EMIT2(or, eax, edx)                 \
+    EMIT2(mov, edx, REGREF1(esi))
+#define OP_ORRS   CHECK_PC(OP_ORR, SETCOND_LOGICAL)
+#define OP_MOV \
+    EMIT2(mov, eax, REGREF1(esi))
+#define OP_MOVS   CHECK_PC(EMIT2(test,eax,eax) EMIT2(mov,eax,REGREF1(esi)), SETCOND_LOGICAL)
+#define OP_BIC \
+    EMIT1(not, eax)                     \
+    EMIT2(and, eax, edx)                \
+    EMIT2(mov, edx, REGREF1(esi))
+#define OP_BICS   CHECK_PC(OP_BIC, SETCOND_LOGICAL)
+#define OP_MVN \
+    EMIT1(not, eax)                     \
+    EMIT2(mov, eax, REGREF1(esi))
+#define OP_MVNS   CHECK_PC(OP_MVN, SETCOND_LOGICAL)
+
+// ALU cleanup macro
+#define ALU_FINISH  ALU_TRAILER
+
+// End of ALU macros
+//X//#endif //_MSC_VER
+
+#ifdef __GNUC__
+
+#define ROR_IMM_MSR \
+    asm ("ror %%cl, %%eax;"             \
+         : "=a" (value)                 \
+         : "a" (opcode & 0xFF), "c" (shift));
+
+#define ROR_OFFSET \
+    asm("ror %%cl, %0"                  \
+        : "=r" (offset)                 \
+        : "0" (offset), "c" (shift));
+
+#define RRX_OFFSET \
+    asm("btl $0, C_FLAG;"               \
+        "rcr $1, %0"                    \
+        : "=r" (offset)                 \
+        : "0" (offset));
+
+#else  // !__GNUC__, i.e. Visual C++
+
+#define ROR_IMM_MSR \
+    __asm {                             \
+        __asm mov ecx, shift            \
+        __asm ror value, cl             \
+     }
+
+
+#define ROR_OFFSET \
+    __asm {                             \
+        __asm mov ecx, shift            \
+        __asm ror offset, cl            \
+    }
+
+#define RRX_OFFSET \
+    __asm {                             \
+        __asm bt dword ptr C_FLAG, 0    \
+        __asm rcr offset, 1             \
+    }
+
+#endif  // !__GNUC__
+
+#endif  // !__POWERPC__
+#endif  // !C_CORE
+
+// C core
+
+#define C_SETCOND_LOGICAL \
+    N_FLAG = ((s32)res < 0) ? true : false;             \
+    Z_FLAG = (res == 0) ? true : false;                 \
+    C_FLAG = C_OUT;
+#define C_SETCOND_ADD \
+    N_FLAG = ((s32)res < 0) ? true : false;             \
+    Z_FLAG = (res == 0) ? true : false;                 \
+    V_FLAG = ((NEG(lhs) & NEG(rhs) & POS(res)) |        \
+              (POS(lhs) & POS(rhs) & NEG(res))) ? true : false;\
+    C_FLAG = ((NEG(lhs) & NEG(rhs)) |                   \
+              (NEG(lhs) & POS(res)) |                   \
+              (NEG(rhs) & POS(res))) ? true : false;
+#define C_SETCOND_SUB \
+    N_FLAG = ((s32)res < 0) ? true : false;             \
+    Z_FLAG = (res == 0) ? true : false;                 \
+    V_FLAG = ((NEG(lhs) & POS(rhs) & POS(res)) |        \
+              (POS(lhs) & NEG(rhs) & NEG(res))) ? true : false;\
+    C_FLAG = ((NEG(lhs) & POS(rhs)) |                   \
+              (NEG(lhs) & POS(res)) |                   \
+              (POS(rhs) & POS(res))) ? true : false;
+
+#ifndef ALU_INIT_C
+ #define ALU_INIT_C \
+    int dest = (opcode>>12) & 15;                       \
+    bool C_OUT = C_FLAG;                                \
+    u32 value;
+#endif
+// OP Rd,Rb,Rm LSL #
+#ifndef VALUE_LSL_IMM_C
+ #define VALUE_LSL_IMM_C \
+    unsigned int shift = (opcode >> 7) & 0x1F;          \
+    if (LIKELY(!shift)) {  /* LSL #0 most common? */    \
+        value = reg[opcode & 0x0F].I;                   \
+    } else {                                            \
+        u32 v = reg[opcode & 0x0F].I;                   \
+        C_OUT = (v >> (32 - shift)) & 1 ? true : false; \
+        value = v << shift;                             \
+    }
+#endif
+// OP Rd,Rb,Rm LSL Rs
+#ifndef VALUE_LSL_REG_C
+ #define VALUE_LSL_REG_C \
+    unsigned int shift = reg[(opcode >> 8)&15].B.B0;    \
+    if (LIKELY(shift)) {                                \
+        if (shift == 32) {                              \
+            value = 0;                                  \
+            C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false);\
+        } else if (LIKELY(shift < 32)) {                \
+            u32 v = reg[opcode & 0x0F].I;               \
+            C_OUT = (v >> (32 - shift)) & 1 ? true : false;\
+            value = v << shift;                         \
+        } else {                                        \
+            value = 0;                                  \
+            C_OUT = false;                              \
+        }                                               \
+    } else {                                            \
+        value = reg[opcode & 0x0F].I;                   \
+    }
+#endif
+// OP Rd,Rb,Rm LSR #
+#ifndef VALUE_LSR_IMM_C
+ #define VALUE_LSR_IMM_C \
+    unsigned int shift = (opcode >> 7) & 0x1F;          \
+    if (LIKELY(shift)) {                                \
+        u32 v = reg[opcode & 0x0F].I;                   \
+        C_OUT = (v >> (shift - 1)) & 1 ? true : false;  \
+        value = v >> shift;                             \
+    } else {                                            \
+        value = 0;                                      \
+        C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false;\
+    }
+#endif
+// OP Rd,Rb,Rm LSR Rs
+#ifndef VALUE_LSR_REG_C
+ #define VALUE_LSR_REG_C \
+    unsigned int shift = reg[(opcode >> 8)&15].B.B0;    \
+    if (LIKELY(shift)) {                                \
+        if (shift == 32) {                              \
+            value = 0;                                  \
+            C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false);\
+        } else if (LIKELY(shift < 32)) {                \
+            u32 v = reg[opcode & 0x0F].I;               \
+            C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
+            value = v >> shift;                         \
+        } else {                                        \
+            value = 0;                                  \
+            C_OUT = false;                              \
+        }                                               \
+    } else {                                            \
+        value = reg[opcode & 0x0F].I;                   \
+    }
+#endif
+// OP Rd,Rb,Rm ASR #
+#ifndef VALUE_ASR_IMM_C
+ #define VALUE_ASR_IMM_C \
+    unsigned int shift = (opcode >> 7) & 0x1F;          \
+    if (LIKELY(shift)) {                                \
+        /* VC++ BUG: u32 v; (s32)v>>n is optimized to shr! */ \
+        s32 v = reg[opcode & 0x0F].I;                   \
+        C_OUT = (v >> (int)(shift - 1)) & 1 ? true : false;\
+        value = v >> (int)shift;                        \
+    } else {                                            \
+        if (reg[opcode & 0x0F].I & 0x80000000) {        \
+            value = 0xFFFFFFFF;                         \
+            C_OUT = true;                               \
+        } else {                                        \
+            value = 0;                                  \
+            C_OUT = false;                              \
+        }                                               \
+    }
+#endif
+// OP Rd,Rb,Rm ASR Rs
+#ifndef VALUE_ASR_REG_C
+ #define VALUE_ASR_REG_C \
+    unsigned int shift = reg[(opcode >> 8)&15].B.B0;    \
+    if (LIKELY(shift < 32)) {                           \
+        if (LIKELY(shift)) {                            \
+            s32 v = reg[opcode & 0x0F].I;               \
+            C_OUT = (v >> (int)(shift - 1)) & 1 ? true : false;\
+            value = v >> (int)shift;                    \
+        } else {                                        \
+            value = reg[opcode & 0x0F].I;               \
+        }                                               \
+    } else {                                            \
+        if (reg[opcode & 0x0F].I & 0x80000000) {        \
+            value = 0xFFFFFFFF;                         \
+            C_OUT = true;                               \
+        } else {                                        \
+            value = 0;                                  \
+            C_OUT = false;                              \
+        }                                               \
+    }
+#endif
+// OP Rd,Rb,Rm ROR #
+#ifndef VALUE_ROR_IMM_C
+ #define VALUE_ROR_IMM_C \
+    unsigned int shift = (opcode >> 7) & 0x1F;          \
+    if (LIKELY(shift)) {                                \
+        u32 v = reg[opcode & 0x0F].I;                   \
+        C_OUT = (v >> (shift - 1)) & 1 ? true : false;  \
+        value = ((v << (32 - shift)) |                  \
+                 (v >> shift));                         \
+    } else {                                            \
+        u32 v = reg[opcode & 0x0F].I;                   \
+        C_OUT = (v & 1) ? true : false;                 \
+        value = ((v >> 1) |                             \
+                 (C_FLAG << 31));                       \
+    }
+#endif
+// OP Rd,Rb,Rm ROR Rs
+#ifndef VALUE_ROR_REG_C
+ #define VALUE_ROR_REG_C \
+    unsigned int shift = reg[(opcode >> 8)&15].B.B0;    \
+    if (LIKELY(shift & 0x1F)) {                         \
+        u32 v = reg[opcode & 0x0F].I;                   \
+        C_OUT = (v >> (shift - 1)) & 1 ? true : false;  \
+        value = ((v << (32 - shift)) |                  \
+                 (v >> shift));                         \
+    } else {                                            \
+        value = reg[opcode & 0x0F].I;                   \
+        if (shift)                                      \
+            C_OUT = (value & 0x80000000 ? true : false);\
+    }
+#endif
+// OP Rd,Rb,# ROR #
+#ifndef VALUE_IMM_C
+ #define VALUE_IMM_C \
+    int shift = (opcode & 0xF00) >> 7;                  \
+    if (UNLIKELY(shift)) {                              \
+        u32 v = opcode & 0xFF;                          \
+        C_OUT = (v >> (shift - 1)) & 1 ? true : false;  \
+        value = ((v << (32 - shift)) |                  \
+                 (v >> shift));                         \
+    } else {                                            \
+        value = opcode & 0xFF;                          \
+    }
+#endif
+
+// Make the non-carry versions default to the carry versions
+// (this is fine for C--the compiler will optimize the dead code out)
+#ifndef ALU_INIT_NC
+ #define ALU_INIT_NC ALU_INIT_C
+#endif
+#ifndef VALUE_LSL_IMM_NC
+ #define VALUE_LSL_IMM_NC VALUE_LSL_IMM_C
+#endif
+#ifndef VALUE_LSL_REG_NC
+ #define VALUE_LSL_REG_NC VALUE_LSL_REG_C
+#endif
+#ifndef VALUE_LSR_IMM_NC
+ #define VALUE_LSR_IMM_NC VALUE_LSR_IMM_C
+#endif
+#ifndef VALUE_LSR_REG_NC
+ #define VALUE_LSR_REG_NC VALUE_LSR_REG_C
+#endif
+#ifndef VALUE_ASR_IMM_NC
+ #define VALUE_ASR_IMM_NC VALUE_ASR_IMM_C
+#endif
+#ifndef VALUE_ASR_REG_NC
+ #define VALUE_ASR_REG_NC VALUE_ASR_REG_C
+#endif
+#ifndef VALUE_ROR_IMM_NC
+ #define VALUE_ROR_IMM_NC VALUE_ROR_IMM_C
+#endif
+#ifndef VALUE_ROR_REG_NC
+ #define VALUE_ROR_REG_NC VALUE_ROR_REG_C
+#endif
+#ifndef VALUE_IMM_NC
+ #define VALUE_IMM_NC VALUE_IMM_C
+#endif
+
+#define C_CHECK_PC(SETCOND) if (LIKELY(dest != 15)) { SETCOND }
+#ifndef OP_AND
+ #define OP_AND \
+    u32 res = reg[(opcode>>16)&15].I & value;           \
+    reg[dest].I = res;
+#endif
+#ifndef OP_ANDS
+ #define OP_ANDS   OP_AND C_CHECK_PC(C_SETCOND_LOGICAL)
+#endif
+#ifndef OP_EOR
+ #define OP_EOR \
+    u32 res = reg[(opcode>>16)&15].I ^ value;           \
+    reg[dest].I = res;
+#endif
+#ifndef OP_EORS
+ #define OP_EORS   OP_EOR C_CHECK_PC(C_SETCOND_LOGICAL)
+#endif
+#ifndef OP_SUB
+ #define OP_SUB \
+    u32 lhs = reg[(opcode>>16)&15].I;                   \
+    u32 rhs = value;                                    \
+    u32 res = lhs - rhs;                                \
+    reg[dest].I = res;
+#endif
+#ifndef OP_SUBS
+ #define OP_SUBS   OP_SUB C_CHECK_PC(C_SETCOND_SUB)
+#endif
+#ifndef OP_RSB
+ #define OP_RSB \
+    u32 lhs = reg[(opcode>>16)&15].I;                   \
+    u32 rhs = value;                                    \
+    u32 res = rhs - lhs;                                \
+    reg[dest].I = res;
+#endif
+#ifndef OP_RSBS
+ #define OP_RSBS   OP_RSB C_CHECK_PC(C_SETCOND_SUB)
+#endif
+#ifndef OP_ADD
+ #define OP_ADD \
+    u32 lhs = reg[(opcode>>16)&15].I;                   \
+    u32 rhs = value;                                    \
+    u32 res = lhs + rhs;                                \
+    reg[dest].I = res;
+#endif
+#ifndef OP_ADDS
+ #define OP_ADDS   OP_ADD C_CHECK_PC(C_SETCOND_ADD)
+#endif
+#ifndef OP_ADC
+ #define OP_ADC \
+    u32 lhs = reg[(opcode>>16)&15].I;                   \
+    u32 rhs = value;                                    \
+    u32 res = lhs + rhs + (u32)C_FLAG;                  \
+    reg[dest].I = res;
+#endif
+#ifndef OP_ADCS
+ #define OP_ADCS   OP_ADC C_CHECK_PC(C_SETCOND_ADD)
+#endif
+#ifndef OP_SBC
+ #define OP_SBC \
+    u32 lhs = reg[(opcode>>16)&15].I;                   \
+    u32 rhs = value;                                    \
+    u32 res = lhs - rhs - !((u32)C_FLAG);               \
+    reg[dest].I = res;
+#endif
+#ifndef OP_SBCS
+ #define OP_SBCS   OP_SBC C_CHECK_PC(C_SETCOND_SUB)
+#endif
+#ifndef OP_RSC
+ #define OP_RSC \
+    u32 lhs = reg[(opcode>>16)&15].I;                   \
+    u32 rhs = value;                                    \
+    u32 res = rhs - lhs - !((u32)C_FLAG);               \
+    reg[dest].I = res;
+#endif
+#ifndef OP_RSCS
+ #define OP_RSCS   OP_RSC C_CHECK_PC(C_SETCOND_SUB)
+#endif
+#ifndef OP_TST
+ #define OP_TST \
+    u32 res = reg[(opcode >> 16) & 0x0F].I & value;     \
+    C_SETCOND_LOGICAL;
+#endif
+#ifndef OP_TEQ
+ #define OP_TEQ \
+    u32 res = reg[(opcode >> 16) & 0x0F].I ^ value;     \
+    C_SETCOND_LOGICAL;
+#endif
+#ifndef OP_CMP
+ #define OP_CMP \
+    u32 lhs = reg[(opcode>>16)&15].I;                   \
+    u32 rhs = value;                                    \
+    u32 res = lhs - rhs;                                \
+    C_SETCOND_SUB;
+#endif
+#ifndef OP_CMN
+ #define OP_CMN \
+    u32 lhs = reg[(opcode>>16)&15].I;                   \
+    u32 rhs = value;                                    \
+    u32 res = lhs + rhs;                                \
+    C_SETCOND_ADD;
+#endif
+#ifndef OP_ORR
+ #define OP_ORR \
+    u32 res = reg[(opcode >> 16) & 0x0F].I | value;     \
+    reg[dest].I = res;
+#endif
+#ifndef OP_ORRS
+ #define OP_ORRS   OP_ORR C_CHECK_PC(C_SETCOND_LOGICAL)
+#endif
+#ifndef OP_MOV
+ #define OP_MOV \
+    u32 res = value;                                    \
+    reg[dest].I = res;
+#endif
+#ifndef OP_MOVS
+ #define OP_MOVS   OP_MOV C_CHECK_PC(C_SETCOND_LOGICAL)
+#endif
+#ifndef OP_BIC
+ #define OP_BIC \
+    u32 res = reg[(opcode >> 16) & 0x0F].I & (~value);  \
+    reg[dest].I = res;
+#endif
+#ifndef OP_BICS
+ #define OP_BICS   OP_BIC C_CHECK_PC(C_SETCOND_LOGICAL)
+#endif
+#ifndef OP_MVN
+ #define OP_MVN \
+    u32 res = ~value;                                   \
+    reg[dest].I = res;
+#endif
+#ifndef OP_MVNS
+ #define OP_MVNS   OP_MVN C_CHECK_PC(C_SETCOND_LOGICAL)
+#endif
+
+#ifndef SETCOND_NONE
+ #define SETCOND_NONE /*nothing*/
+#endif
+#ifndef SETCOND_MUL
+ #define SETCOND_MUL \
+     N_FLAG = ((s32)reg[dest].I < 0) ? true : false;    \
+     Z_FLAG = reg[dest].I ? false : true;
+#endif
+#ifndef SETCOND_MULL
+ #define SETCOND_MULL \
+     N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
+     Z_FLAG = reg[dest].I || reg[acc].I ? false : true;
+#endif
+
+#ifndef ALU_FINISH
+ #define ALU_FINISH /*nothing*/
+#endif
+
+#ifndef ROR_IMM_MSR
+ #define ROR_IMM_MSR \
+    u32 v = opcode & 0xff;                              \
+    value = ((v << (32 - shift)) | (v >> shift));
+#endif
+#ifndef ROR_OFFSET
+ #define ROR_OFFSET \
+    offset = ((offset << (32 - shift)) | (offset >> shift));
+#endif
+#ifndef RRX_OFFSET
+ #define RRX_OFFSET \
+    offset = ((offset >> 1) | ((int)C_FLAG << 31));
+#endif
+
+// ALU ops (except multiply) //////////////////////////////////////////////
+
+// ALU_INIT: init code (ALU_INIT_C or ALU_INIT_NC)
+// GETVALUE: load value and shift/rotate (VALUE_XXX)
+// OP: ALU operation (OP_XXX)
+// MODECHANGE: MODECHANGE_NO or MODECHANGE_YES
+// ISREGSHIFT: 1 for insns of the form ...,Rn LSL/etc Rs; 0 otherwise
+// ALU_INIT, GETVALUE, OP, and ALU_FINISH are concatenated in order.
+#define ALU_INSN(ALU_INIT, GETVALUE, OP, MODECHANGE, ISREGSHIFT) \
+    ALU_INIT GETVALUE OP ALU_FINISH;                            \
+    if (LIKELY((opcode & 0x0000F000) != 0x0000F000)) {          \
+        clockTicks = 1 + ISREGSHIFT                             \
+                       + codeTicksAccessSeq32(armNextPC);       \
+    } else {                                                    \
+        MODECHANGE;                                             \
+        if (armState) {                                         \
+            reg[15].I &= 0xFFFFFFFC;                            \
+            armNextPC = reg[15].I;                              \
+            reg[15].I += 4;                                     \
+            ARM_PREFETCH;                                       \
+        } else {                                                \
+            reg[15].I &= 0xFFFFFFFE;                            \
+            armNextPC = reg[15].I;                              \
+            reg[15].I += 2;                                     \
+            THUMB_PREFETCH;                                     \
+        }                                                       \
+        clockTicks = 3 + ISREGSHIFT                             \
+                       + codeTicksAccess32(armNextPC)           \
+                       + codeTicksAccessSeq32(armNextPC)        \
+                       + codeTicksAccessSeq32(armNextPC);       \
+    }
+
+#define MODECHANGE_NO  /*nothing*/
+#define MODECHANGE_YES CPUSwitchMode(reg[17].I & 0x1f, false);
+
+#define DEFINE_ALU_INSN_C(CODE1, CODE2, OP, MODECHANGE) \
+  static INSN_REGPARM void arm##CODE1##0(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSL_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\
+  static INSN_REGPARM void arm##CODE1##1(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSL_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\
+  static INSN_REGPARM void arm##CODE1##2(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSR_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\
+  static INSN_REGPARM void arm##CODE1##3(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_LSR_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\
+  static INSN_REGPARM void arm##CODE1##4(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ASR_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\
+  static INSN_REGPARM void arm##CODE1##5(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ASR_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\
+  static INSN_REGPARM void arm##CODE1##6(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ROR_IMM_C, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\
+  static INSN_REGPARM void arm##CODE1##7(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_ROR_REG_C, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\
+  static INSN_REGPARM void arm##CODE2##0(u32 opcode) { ALU_INSN(ALU_INIT_C, VALUE_IMM_C,     OP_##OP, MODECHANGE_##MODECHANGE, 0); }
+#define DEFINE_ALU_INSN_NC(CODE1, CODE2, OP, MODECHANGE) \
+  static INSN_REGPARM void arm##CODE1##0(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSL_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\
+  static INSN_REGPARM void arm##CODE1##1(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSL_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\
+  static INSN_REGPARM void arm##CODE1##2(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSR_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\
+  static INSN_REGPARM void arm##CODE1##3(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_LSR_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\
+  static INSN_REGPARM void arm##CODE1##4(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ASR_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\
+  static INSN_REGPARM void arm##CODE1##5(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ASR_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\
+  static INSN_REGPARM void arm##CODE1##6(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ROR_IMM_NC, OP_##OP, MODECHANGE_##MODECHANGE, 0); }\
+  static INSN_REGPARM void arm##CODE1##7(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_ROR_REG_NC, OP_##OP, MODECHANGE_##MODECHANGE, 1); }\
+  static INSN_REGPARM void arm##CODE2##0(u32 opcode) { ALU_INSN(ALU_INIT_NC, VALUE_IMM_NC,     OP_##OP, MODECHANGE_##MODECHANGE, 0); }
+
+// AND
+DEFINE_ALU_INSN_NC(00, 20, AND,  NO)
+// ANDS
+DEFINE_ALU_INSN_C (01, 21, ANDS, YES)
+
+// EOR
+DEFINE_ALU_INSN_NC(02, 22, EOR,  NO)
+// EORS
+DEFINE_ALU_INSN_C (03, 23, EORS, YES)
+
+// SUB
+DEFINE_ALU_INSN_NC(04, 24, SUB,  NO)
+// SUBS
+DEFINE_ALU_INSN_NC(05, 25, SUBS, YES)
+
+// RSB
+DEFINE_ALU_INSN_NC(06, 26, RSB,  NO)
+// RSBS
+DEFINE_ALU_INSN_NC(07, 27, RSBS, YES)
+
+// ADD
+DEFINE_ALU_INSN_NC(08, 28, ADD,  NO)
+// ADDS
+DEFINE_ALU_INSN_NC(09, 29, ADDS, YES)
+
+// ADC
+DEFINE_ALU_INSN_NC(0A, 2A, ADC,  NO)
+// ADCS
+DEFINE_ALU_INSN_NC(0B, 2B, ADCS, YES)
+
+// SBC
+DEFINE_ALU_INSN_NC(0C, 2C, SBC,  NO)
+// SBCS
+DEFINE_ALU_INSN_NC(0D, 2D, SBCS, YES)
+
+// RSC
+DEFINE_ALU_INSN_NC(0E, 2E, RSC,  NO)
+// RSCS
+DEFINE_ALU_INSN_NC(0F, 2F, RSCS, YES)
+
+// TST
+DEFINE_ALU_INSN_C (11, 31, TST,  NO)
+
+// TEQ
+DEFINE_ALU_INSN_C (13, 33, TEQ,  NO)
+
+// CMP
+DEFINE_ALU_INSN_NC(15, 35, CMP,  NO)
+
+// CMN
+DEFINE_ALU_INSN_NC(17, 37, CMN,  NO)
+
+// ORR
+DEFINE_ALU_INSN_NC(18, 38, ORR,  NO)
+// ORRS
+DEFINE_ALU_INSN_C (19, 39, ORRS, YES)
+
+// MOV
+DEFINE_ALU_INSN_NC(1A, 3A, MOV,  NO)
+// MOVS
+DEFINE_ALU_INSN_C (1B, 3B, MOVS, YES)
+
+// BIC
+DEFINE_ALU_INSN_NC(1C, 3C, BIC,  NO)
+// BICS
+DEFINE_ALU_INSN_C (1D, 3D, BICS, YES)
+
+// MVN
+DEFINE_ALU_INSN_NC(1E, 3E, MVN,  NO)
+// MVNS
+DEFINE_ALU_INSN_C (1F, 3F, MVNS, YES)
+
+// Multiply instructions //////////////////////////////////////////////////
+
+// OP: OP_MUL, OP_MLA etc.
+// SETCOND: SETCOND_NONE, SETCOND_MUL, or SETCOND_MULL
+// CYCLES: base cycle count (1, 2, or 3)
+#define MUL_INSN(OP, SETCOND, CYCLES) \
+    int mult = (opcode & 0x0F);                         \
+    u32 rs = reg[(opcode >> 8) & 0x0F].I;               \
+    int acc = (opcode >> 12) & 0x0F;   /* or destLo */  \
+    int dest = (opcode >> 16) & 0x0F;  /* or destHi */  \
+    OP;                                                 \
+    SETCOND;                                            \
+    if ((s32)rs < 0)                                    \
+        rs = ~rs;                                       \
+    if ((rs & 0xFFFFFF00) == 0)                         \
+        clockTicks += 0;                                \
+    else if ((rs & 0xFFFF0000) == 0)                    \
+        clockTicks += 1;                                \
+    else if ((rs & 0xFF000000) == 0)                    \
+        clockTicks += 2;                                \
+    else                                                \
+        clockTicks += 3;                                \
+    if (busPrefetchCount == 0)                          \
+        busPrefetchCount = ((busPrefetchCount+1)<<clockTicks) - 1; \
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+
+#define OP_MUL \
+    reg[dest].I = reg[mult].I * rs;
+#define OP_MLA \
+    reg[dest].I = reg[mult].I * rs + reg[acc].I;
+#define OP_MULL(SIGN) \
+    SIGN##64 res = (SIGN##64)(SIGN##32)reg[mult].I      \
+                 * (SIGN##64)(SIGN##32)rs;              \
+    reg[acc].I = (u32)res;                              \
+    reg[dest].I = (u32)(res >> 32);
+#define OP_MLAL(SIGN) \
+    SIGN##64 res = ((SIGN##64)reg[dest].I<<32 | reg[acc].I)\
+                 + ((SIGN##64)(SIGN##32)reg[mult].I     \
+                    * (SIGN##64)(SIGN##32)rs);          \
+    reg[acc].I = (u32)res;                              \
+    reg[dest].I = (u32)(res >> 32);
+#define OP_UMULL OP_MULL(u)
+#define OP_UMLAL OP_MLAL(u)
+#define OP_SMULL OP_MULL(s)
+#define OP_SMLAL OP_MLAL(s)
+
+// MUL Rd, Rm, Rs
+static INSN_REGPARM void arm009(u32 opcode) { MUL_INSN(OP_MUL, SETCOND_NONE, 1); }
+// MULS Rd, Rm, Rs
+static INSN_REGPARM void arm019(u32 opcode) { MUL_INSN(OP_MUL, SETCOND_MUL, 1); }
+
+// MLA Rd, Rm, Rs, Rn
+static INSN_REGPARM void arm029(u32 opcode) { MUL_INSN(OP_MLA, SETCOND_NONE, 2); }
+// MLAS Rd, Rm, Rs, Rn
+static INSN_REGPARM void arm039(u32 opcode) { MUL_INSN(OP_MLA, SETCOND_MUL, 2); }
+
+// UMULL RdLo, RdHi, Rn, Rs
+static INSN_REGPARM void arm089(u32 opcode) { MUL_INSN(OP_UMULL, SETCOND_NONE, 2); }
+// UMULLS RdLo, RdHi, Rn, Rs
+static INSN_REGPARM void arm099(u32 opcode) { MUL_INSN(OP_UMULL, SETCOND_MULL, 2); }
+
+// UMLAL RdLo, RdHi, Rn, Rs
+static INSN_REGPARM void arm0A9(u32 opcode) { MUL_INSN(OP_UMLAL, SETCOND_NONE, 3); }
+// UMLALS RdLo, RdHi, Rn, Rs
+static INSN_REGPARM void arm0B9(u32 opcode) { MUL_INSN(OP_UMLAL, SETCOND_MULL, 3); }
+
+// SMULL RdLo, RdHi, Rm, Rs
+static INSN_REGPARM void arm0C9(u32 opcode) { MUL_INSN(OP_SMULL, SETCOND_NONE, 2); }
+// SMULLS RdLo, RdHi, Rm, Rs
+static INSN_REGPARM void arm0D9(u32 opcode) { MUL_INSN(OP_SMULL, SETCOND_MULL, 2); }
+
+// SMLAL RdLo, RdHi, Rm, Rs
+static INSN_REGPARM void arm0E9(u32 opcode) { MUL_INSN(OP_SMLAL, SETCOND_NONE, 3); }
+// SMLALS RdLo, RdHi, Rm, Rs
+static INSN_REGPARM void arm0F9(u32 opcode) { MUL_INSN(OP_SMLAL, SETCOND_MULL, 3); }
+
+// Misc instructions //////////////////////////////////////////////////////
+
+// SWP Rd, Rm, [Rn]
+static INSN_REGPARM void arm109(u32 opcode)
+{
+    u32 address = reg[(opcode >> 16) & 15].I;
+    u32 temp = CPUReadMemory(address);
+    CPUWriteMemory(address, reg[opcode&15].I);
+    reg[(opcode >> 12) & 15].I = temp;
+    clockTicks = 4 + dataTicksAccess32(address) + dataTicksAccess32(address)
+                   + codeTicksAccess32(armNextPC);
+}
+
+// SWPB Rd, Rm, [Rn]
+static INSN_REGPARM void arm149(u32 opcode)
+{
+    u32 address = reg[(opcode >> 16) & 15].I;
+    u32 temp = CPUReadByte(address);
+    CPUWriteByte(address, reg[opcode&15].B.B0);
+    reg[(opcode>>12)&15].I = temp;
+    clockTicks = 4 + dataTicksAccess32(address) + dataTicksAccess32(address)
+                   + codeTicksAccess32(armNextPC);
+}
+
+// MRS Rd, CPSR
+static INSN_REGPARM void arm100(u32 opcode)
+{
+    if (LIKELY((opcode & 0x0FFF0FFF) == 0x010F0000)) {
+        CPUUpdateCPSR();
+        reg[(opcode >> 12) & 0x0F].I = reg[16].I;
+    } else {
+        armUnknownInsn(opcode);
+    }
+}
+
+// MRS Rd, SPSR
+static INSN_REGPARM void arm140(u32 opcode)
+{
+    if (LIKELY((opcode & 0x0FFF0FFF) == 0x014F0000)) {
+        reg[(opcode >> 12) & 0x0F].I = reg[17].I;
+    } else {
+        armUnknownInsn(opcode);
+    }
+}
+
+// MSR CPSR_fields, Rm
+static INSN_REGPARM void arm120(u32 opcode)
+{
+    if (LIKELY((opcode & 0x0FF0FFF0) == 0x0120F000)) {
+        CPUUpdateCPSR();
+        u32 value = reg[opcode & 15].I;
+        u32 newValue = reg[16].I;
+        if (armMode > 0x10) {
+            if (opcode & 0x00010000)
+                newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF);
+            if (opcode & 0x00020000)
+                newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00);
+            if (opcode & 0x00040000)
+                newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000);
+        }
+        if (opcode & 0x00080000)
+            newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000);
+        newValue |= 0x10;
+        CPUSwitchMode(newValue & 0x1F, false);
+        reg[16].I = newValue;
+        CPUUpdateFlags();
+        if (!armState) {  // this should not be allowed, but it seems to work
+            THUMB_PREFETCH;
+            reg[15].I = armNextPC + 2;
+        }
+    } else {
+        armUnknownInsn(opcode);
+    }
+}
+
+// MSR SPSR_fields, Rm
+static INSN_REGPARM void arm160(u32 opcode)
+{
+    if (LIKELY((opcode & 0x0FF0FFF0) == 0x0160F000)) {
+        u32 value = reg[opcode & 15].I;
+        if (armMode > 0x10 && armMode < 0x1F) {
+            if (opcode & 0x00010000)
+                reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF);
+            if (opcode & 0x00020000)
+                reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00);
+            if (opcode & 0x00040000)
+                reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000);
+            if (opcode & 0x00080000)
+                reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000);
+        }
+    } else {
+        armUnknownInsn(opcode);
+    }
+}
+
+// MSR CPSR_fields, #
+static INSN_REGPARM void arm320(u32 opcode)
+{
+    if (LIKELY((opcode & 0x0FF0F000) == 0x0320F000)) {
+        CPUUpdateCPSR();
+        u32 value = opcode & 0xFF;
+        int shift = (opcode & 0xF00) >> 7;
+        if (shift) {
+            ROR_IMM_MSR;
+        }
+        u32 newValue = reg[16].I;
+        if (armMode > 0x10) {
+            if (opcode & 0x00010000)
+                newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF);
+            if (opcode & 0x00020000)
+                newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00);
+            if (opcode & 0x00040000)
+                newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000);
+        }
+        if (opcode & 0x00080000)
+            newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000);
+
+        newValue |= 0x10;
+
+        CPUSwitchMode(newValue & 0x1F, false);
+        reg[16].I = newValue;
+        CPUUpdateFlags();
+        if (!armState) {  // this should not be allowed, but it seems to work
+            THUMB_PREFETCH;
+            reg[15].I = armNextPC + 2;
+        }
+    } else {
+        armUnknownInsn(opcode);
+    }
+}
+
+// MSR SPSR_fields, #
+static INSN_REGPARM void arm360(u32 opcode)
+{
+    if (LIKELY((opcode & 0x0FF0F000) == 0x0360F000)) {
+        if (armMode > 0x10 && armMode < 0x1F) {
+            u32 value = opcode & 0xFF;
+            int shift = (opcode & 0xF00) >> 7;
+            if (shift) {
+                ROR_IMM_MSR;
+            }
+            if (opcode & 0x00010000)
+                reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF);
+            if (opcode & 0x00020000)
+                reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00);
+            if (opcode & 0x00040000)
+                reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000);
+            if (opcode & 0x00080000)
+                reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000);
+        }
+    } else {
+        armUnknownInsn(opcode);
+    }
+}
+
+// BX Rm
+static INSN_REGPARM void arm121(u32 opcode)
+{
+    if (LIKELY((opcode & 0x0FFFFFF0) == 0x012FFF10)) {
+        int base = opcode & 0x0F;
+        busPrefetchCount = 0;
+        armState = reg[base].I & 1 ? false : true;
+        if (armState) {
+            reg[15].I = reg[base].I & 0xFFFFFFFC;
+            armNextPC = reg[15].I;
+            reg[15].I += 4;
+            ARM_PREFETCH;
+            clockTicks = 3 + codeTicksAccessSeq32(armNextPC)
+                           + codeTicksAccessSeq32(armNextPC)
+                           + codeTicksAccess32(armNextPC);
+        } else {
+            reg[15].I = reg[base].I & 0xFFFFFFFE;
+            armNextPC = reg[15].I;
+            reg[15].I += 2;
+            THUMB_PREFETCH;
+            clockTicks = 3 + codeTicksAccessSeq16(armNextPC)
+                           + codeTicksAccessSeq16(armNextPC)
+                           + codeTicksAccess16(armNextPC);
+        }
+    } else {
+        armUnknownInsn(opcode);
+    }
+}
+
+// Load/store /////////////////////////////////////////////////////////////
+
+#define OFFSET_IMM \
+    int offset = opcode & 0xFFF;
+#define OFFSET_IMM8 \
+    int offset = ((opcode & 0x0F) | ((opcode>>4) & 0xF0));
+#define OFFSET_REG \
+    int offset = reg[opcode & 15].I;
+#define OFFSET_LSL \
+    int offset = reg[opcode & 15].I << ((opcode>>7) & 31);
+#define OFFSET_LSR \
+    int shift = (opcode >> 7) & 31;                     \
+    int offset = shift ? reg[opcode & 15].I >> shift : 0;
+#define OFFSET_ASR \
+    int shift = (opcode >> 7) & 31;                     \
+    int offset;                                         \
+    if (shift)                                          \
+        offset = (int)((s32)reg[opcode & 15].I >> shift);\
+    else if (reg[opcode & 15].I & 0x80000000)           \
+        offset = 0xFFFFFFFF;                            \
+    else                                                \
+        offset = 0;
+#define OFFSET_ROR \
+    int shift = (opcode >> 7) & 31;                     \
+    u32 offset = reg[opcode & 15].I;                    \
+    if (shift) {                                        \
+        ROR_OFFSET;                                     \
+    } else {                                            \
+        RRX_OFFSET;                                     \
+    }
+
+#define ADDRESS_POST (reg[base].I)
+#define ADDRESS_PREDEC (reg[base].I - offset)
+#define ADDRESS_PREINC (reg[base].I + offset)
+
+#define OP_STR    CPUWriteMemory(address, reg[dest].I)
+#define OP_STRH   CPUWriteHalfWord(address, reg[dest].W.W0)
+#define OP_STRB   CPUWriteByte(address, reg[dest].B.B0)
+#define OP_LDR    reg[dest].I = CPUReadMemory(address)
+#define OP_LDRH   reg[dest].I = CPUReadHalfWord(address)
+#define OP_LDRB   reg[dest].I = CPUReadByte(address)
+#define OP_LDRSH  reg[dest].I = (s16)CPUReadHalfWordSigned(address)
+#define OP_LDRSB  reg[dest].I = (s8)CPUReadByte(address)
+
+#define WRITEBACK_NONE     /*nothing*/
+#define WRITEBACK_PRE      reg[base].I = address
+#define WRITEBACK_POSTDEC  reg[base].I = address - offset
+#define WRITEBACK_POSTINC  reg[base].I = address + offset
+
+#define LDRSTR_INIT(CALC_OFFSET, CALC_ADDRESS) \
+    if (busPrefetchCount == 0)                          \
+        busPrefetch = busPrefetchEnable;                \
+    int dest = (opcode >> 12) & 15;                     \
+    int base = (opcode >> 16) & 15;                     \
+    CALC_OFFSET;                                        \
+    u32 address = CALC_ADDRESS;
+
+#define STR(CALC_OFFSET, CALC_ADDRESS, STORE_DATA, WRITEBACK1, WRITEBACK2, SIZE) \
+    LDRSTR_INIT(CALC_OFFSET, CALC_ADDRESS);             \
+    WRITEBACK1;                                         \
+    STORE_DATA;                                         \
+    WRITEBACK2;                                         \
+    clockTicks = 2 + dataTicksAccess##SIZE(address)     \
+                   + codeTicksAccess32(armNextPC);
+#define LDR(CALC_OFFSET, CALC_ADDRESS, LOAD_DATA, WRITEBACK, SIZE) \
+    LDRSTR_INIT(CALC_OFFSET, CALC_ADDRESS);             \
+    LOAD_DATA;                                          \
+    if (dest != base)                                   \
+        WRITEBACK;                                      \
+    clockTicks = 0;                                     \
+    if (dest == 15) {                                   \
+        reg[15].I &= 0xFFFFFFFC;                        \
+        armNextPC = reg[15].I;                          \
+        reg[15].I += 4;                                 \
+        ARM_PREFETCH;                                   \
+        clockTicks += 2 + dataTicksAccessSeq32(address) \
+                        + dataTicksAccessSeq32(address);\
+    }                                                   \
+    clockTicks += 3 + dataTicksAccess##SIZE(address)    \
+                    + codeTicksAccess32(armNextPC);
+#define STR_POSTDEC(CALC_OFFSET, STORE_DATA, SIZE) \
+  STR(CALC_OFFSET, ADDRESS_POST, STORE_DATA, WRITEBACK_NONE, WRITEBACK_POSTDEC, SIZE)
+#define STR_POSTINC(CALC_OFFSET, STORE_DATA, SIZE) \
+  STR(CALC_OFFSET, ADDRESS_POST, STORE_DATA, WRITEBACK_NONE, WRITEBACK_POSTINC, SIZE)
+#define STR_PREDEC(CALC_OFFSET, STORE_DATA, SIZE) \
+  STR(CALC_OFFSET, ADDRESS_PREDEC, STORE_DATA, WRITEBACK_NONE, WRITEBACK_NONE, SIZE)
+#define STR_PREDEC_WB(CALC_OFFSET, STORE_DATA, SIZE) \
+  STR(CALC_OFFSET, ADDRESS_PREDEC, STORE_DATA, WRITEBACK_PRE, WRITEBACK_NONE, SIZE)
+#define STR_PREINC(CALC_OFFSET, STORE_DATA, SIZE) \
+  STR(CALC_OFFSET, ADDRESS_PREINC, STORE_DATA, WRITEBACK_NONE, WRITEBACK_NONE, SIZE)
+#define STR_PREINC_WB(CALC_OFFSET, STORE_DATA, SIZE) \
+  STR(CALC_OFFSET, ADDRESS_PREINC, STORE_DATA, WRITEBACK_PRE, WRITEBACK_NONE, SIZE)
+#define LDR_POSTDEC(CALC_OFFSET, LOAD_DATA, SIZE) \
+  LDR(CALC_OFFSET, ADDRESS_POST, LOAD_DATA, WRITEBACK_POSTDEC, SIZE)
+#define LDR_POSTINC(CALC_OFFSET, LOAD_DATA, SIZE) \
+  LDR(CALC_OFFSET, ADDRESS_POST, LOAD_DATA, WRITEBACK_POSTINC, SIZE)
+#define LDR_PREDEC(CALC_OFFSET, LOAD_DATA, SIZE) \
+  LDR(CALC_OFFSET, ADDRESS_PREDEC, LOAD_DATA, WRITEBACK_NONE, SIZE)
+#define LDR_PREDEC_WB(CALC_OFFSET, LOAD_DATA, SIZE) \
+  LDR(CALC_OFFSET, ADDRESS_PREDEC, LOAD_DATA, WRITEBACK_PRE, SIZE)
+#define LDR_PREINC(CALC_OFFSET, LOAD_DATA, SIZE) \
+  LDR(CALC_OFFSET, ADDRESS_PREINC, LOAD_DATA, WRITEBACK_NONE, SIZE)
+#define LDR_PREINC_WB(CALC_OFFSET, LOAD_DATA, SIZE) \
+  LDR(CALC_OFFSET, ADDRESS_PREINC, LOAD_DATA, WRITEBACK_PRE, SIZE)
+
+// STRH Rd, [Rn], -Rm
+static INSN_REGPARM void arm00B(u32 opcode) { STR_POSTDEC(OFFSET_REG, OP_STRH, 16); }
+// STRH Rd, [Rn], #-offset
+static INSN_REGPARM void arm04B(u32 opcode) { STR_POSTDEC(OFFSET_IMM8, OP_STRH, 16); }
+// STRH Rd, [Rn], Rm
+static INSN_REGPARM void arm08B(u32 opcode) { STR_POSTINC(OFFSET_REG, OP_STRH, 16); }
+// STRH Rd, [Rn], #offset
+static INSN_REGPARM void arm0CB(u32 opcode) { STR_POSTINC(OFFSET_IMM8, OP_STRH, 16); }
+// STRH Rd, [Rn, -Rm]
+static INSN_REGPARM void arm10B(u32 opcode) { STR_PREDEC(OFFSET_REG, OP_STRH, 16); }
+// STRH Rd, [Rn, -Rm]!
+static INSN_REGPARM void arm12B(u32 opcode) { STR_PREDEC_WB(OFFSET_REG, OP_STRH, 16); }
+// STRH Rd, [Rn, -#offset]
+static INSN_REGPARM void arm14B(u32 opcode) { STR_PREDEC(OFFSET_IMM8, OP_STRH, 16); }
+// STRH Rd, [Rn, -#offset]!
+static INSN_REGPARM void arm16B(u32 opcode) { STR_PREDEC_WB(OFFSET_IMM8, OP_STRH, 16); }
+// STRH Rd, [Rn, Rm]
+static INSN_REGPARM void arm18B(u32 opcode) { STR_PREINC(OFFSET_REG, OP_STRH, 16); }
+// STRH Rd, [Rn, Rm]!
+static INSN_REGPARM void arm1AB(u32 opcode) { STR_PREINC_WB(OFFSET_REG, OP_STRH, 16); }
+// STRH Rd, [Rn, #offset]
+static INSN_REGPARM void arm1CB(u32 opcode) { STR_PREINC(OFFSET_IMM8, OP_STRH, 16); }
+// STRH Rd, [Rn, #offset]!
+static INSN_REGPARM void arm1EB(u32 opcode) { STR_PREINC_WB(OFFSET_IMM8, OP_STRH, 16); }
+
+// LDRH Rd, [Rn], -Rm
+static INSN_REGPARM void arm01B(u32 opcode) { LDR_POSTDEC(OFFSET_REG, OP_LDRH, 16); }
+// LDRH Rd, [Rn], #-offset
+static INSN_REGPARM void arm05B(u32 opcode) { LDR_POSTDEC(OFFSET_IMM8, OP_LDRH, 16); }
+// LDRH Rd, [Rn], Rm
+static INSN_REGPARM void arm09B(u32 opcode) { LDR_POSTINC(OFFSET_REG, OP_LDRH, 16); }
+// LDRH Rd, [Rn], #offset
+static INSN_REGPARM void arm0DB(u32 opcode) { LDR_POSTINC(OFFSET_IMM8, OP_LDRH, 16); }
+// LDRH Rd, [Rn, -Rm]
+static INSN_REGPARM void arm11B(u32 opcode) { LDR_PREDEC(OFFSET_REG, OP_LDRH, 16); }
+// LDRH Rd, [Rn, -Rm]!
+static INSN_REGPARM void arm13B(u32 opcode) { LDR_PREDEC_WB(OFFSET_REG, OP_LDRH, 16); }
+// LDRH Rd, [Rn, -#offset]
+static INSN_REGPARM void arm15B(u32 opcode) { LDR_PREDEC(OFFSET_IMM8, OP_LDRH, 16); }
+// LDRH Rd, [Rn, -#offset]!
+static INSN_REGPARM void arm17B(u32 opcode) { LDR_PREDEC_WB(OFFSET_IMM8, OP_LDRH, 16); }
+// LDRH Rd, [Rn, Rm]
+static INSN_REGPARM void arm19B(u32 opcode) { LDR_PREINC(OFFSET_REG, OP_LDRH, 16); }
+// LDRH Rd, [Rn, Rm]!
+static INSN_REGPARM void arm1BB(u32 opcode) { LDR_PREINC_WB(OFFSET_REG, OP_LDRH, 16); }
+// LDRH Rd, [Rn, #offset]
+static INSN_REGPARM void arm1DB(u32 opcode) { LDR_PREINC(OFFSET_IMM8, OP_LDRH, 16); }
+// LDRH Rd, [Rn, #offset]!
+static INSN_REGPARM void arm1FB(u32 opcode) { LDR_PREINC_WB(OFFSET_IMM8, OP_LDRH, 16); }
+
+// LDRSB Rd, [Rn], -Rm
+static INSN_REGPARM void arm01D(u32 opcode) { LDR_POSTDEC(OFFSET_REG, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn], #-offset
+static INSN_REGPARM void arm05D(u32 opcode) { LDR_POSTDEC(OFFSET_IMM8, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn], Rm
+static INSN_REGPARM void arm09D(u32 opcode) { LDR_POSTINC(OFFSET_REG, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn], #offset
+static INSN_REGPARM void arm0DD(u32 opcode) { LDR_POSTINC(OFFSET_IMM8, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn, -Rm]
+static INSN_REGPARM void arm11D(u32 opcode) { LDR_PREDEC(OFFSET_REG, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn, -Rm]!
+static INSN_REGPARM void arm13D(u32 opcode) { LDR_PREDEC_WB(OFFSET_REG, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn, -#offset]
+static INSN_REGPARM void arm15D(u32 opcode) { LDR_PREDEC(OFFSET_IMM8, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn, -#offset]!
+static INSN_REGPARM void arm17D(u32 opcode) { LDR_PREDEC_WB(OFFSET_IMM8, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn, Rm]
+static INSN_REGPARM void arm19D(u32 opcode) { LDR_PREINC(OFFSET_REG, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn, Rm]!
+static INSN_REGPARM void arm1BD(u32 opcode) { LDR_PREINC_WB(OFFSET_REG, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn, #offset]
+static INSN_REGPARM void arm1DD(u32 opcode) { LDR_PREINC(OFFSET_IMM8, OP_LDRSB, 16); }
+// LDRSB Rd, [Rn, #offset]!
+static INSN_REGPARM void arm1FD(u32 opcode) { LDR_PREINC_WB(OFFSET_IMM8, OP_LDRSB, 16); }
+
+// LDRSH Rd, [Rn], -Rm
+static INSN_REGPARM void arm01F(u32 opcode) { LDR_POSTDEC(OFFSET_REG, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn], #-offset
+static INSN_REGPARM void arm05F(u32 opcode) { LDR_POSTDEC(OFFSET_IMM8, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn], Rm
+static INSN_REGPARM void arm09F(u32 opcode) { LDR_POSTINC(OFFSET_REG, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn], #offset
+static INSN_REGPARM void arm0DF(u32 opcode) { LDR_POSTINC(OFFSET_IMM8, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn, -Rm]
+static INSN_REGPARM void arm11F(u32 opcode) { LDR_PREDEC(OFFSET_REG, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn, -Rm]!
+static INSN_REGPARM void arm13F(u32 opcode) { LDR_PREDEC_WB(OFFSET_REG, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn, -#offset]
+static INSN_REGPARM void arm15F(u32 opcode) { LDR_PREDEC(OFFSET_IMM8, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn, -#offset]!
+static INSN_REGPARM void arm17F(u32 opcode) { LDR_PREDEC_WB(OFFSET_IMM8, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn, Rm]
+static INSN_REGPARM void arm19F(u32 opcode) { LDR_PREINC(OFFSET_REG, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn, Rm]!
+static INSN_REGPARM void arm1BF(u32 opcode) { LDR_PREINC_WB(OFFSET_REG, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn, #offset]
+static INSN_REGPARM void arm1DF(u32 opcode) { LDR_PREINC(OFFSET_IMM8, OP_LDRSH, 16); }
+// LDRSH Rd, [Rn, #offset]!
+static INSN_REGPARM void arm1FF(u32 opcode) { LDR_PREINC_WB(OFFSET_IMM8, OP_LDRSH, 16); }
+
+// STR[T] Rd, [Rn], -#
+// Note: STR and STRT do the same thing on the GBA (likewise for LDR/LDRT etc)
+static INSN_REGPARM void arm400(u32 opcode) { STR_POSTDEC(OFFSET_IMM, OP_STR, 32); }
+// LDR[T] Rd, [Rn], -#
+static INSN_REGPARM void arm410(u32 opcode) { LDR_POSTDEC(OFFSET_IMM, OP_LDR, 32); }
+// STRB[T] Rd, [Rn], -#
+static INSN_REGPARM void arm440(u32 opcode) { STR_POSTDEC(OFFSET_IMM, OP_STRB, 16); }
+// LDRB[T] Rd, [Rn], -#
+static INSN_REGPARM void arm450(u32 opcode) { LDR_POSTDEC(OFFSET_IMM, OP_LDRB, 16); }
+// STR[T] Rd, [Rn], #
+static INSN_REGPARM void arm480(u32 opcode) { STR_POSTINC(OFFSET_IMM, OP_STR, 32); }
+// LDR Rd, [Rn], #
+static INSN_REGPARM void arm490(u32 opcode) { LDR_POSTINC(OFFSET_IMM, OP_LDR, 32); }
+// STRB[T] Rd, [Rn], #
+static INSN_REGPARM void arm4C0(u32 opcode) { STR_POSTINC(OFFSET_IMM, OP_STRB, 16); }
+// LDRB[T] Rd, [Rn], #
+static INSN_REGPARM void arm4D0(u32 opcode) { LDR_POSTINC(OFFSET_IMM, OP_LDRB, 16); }
+// STR Rd, [Rn, -#]
+static INSN_REGPARM void arm500(u32 opcode) { STR_PREDEC(OFFSET_IMM, OP_STR, 32); }
+// LDR Rd, [Rn, -#]
+static INSN_REGPARM void arm510(u32 opcode) { LDR_PREDEC(OFFSET_IMM, OP_LDR, 32); }
+// STR Rd, [Rn, -#]!
+static INSN_REGPARM void arm520(u32 opcode) { STR_PREDEC_WB(OFFSET_IMM, OP_STR, 32); }
+// LDR Rd, [Rn, -#]!
+static INSN_REGPARM void arm530(u32 opcode) { LDR_PREDEC_WB(OFFSET_IMM, OP_LDR, 32); }
+// STRB Rd, [Rn, -#]
+static INSN_REGPARM void arm540(u32 opcode) { STR_PREDEC(OFFSET_IMM, OP_STRB, 16); }
+// LDRB Rd, [Rn, -#]
+static INSN_REGPARM void arm550(u32 opcode) { LDR_PREDEC(OFFSET_IMM, OP_LDRB, 16); }
+// STRB Rd, [Rn, -#]!
+static INSN_REGPARM void arm560(u32 opcode) { STR_PREDEC_WB(OFFSET_IMM, OP_STRB, 16); }
+// LDRB Rd, [Rn, -#]!
+static INSN_REGPARM void arm570(u32 opcode) { LDR_PREDEC_WB(OFFSET_IMM, OP_LDRB, 16); }
+// STR Rd, [Rn, #]
+static INSN_REGPARM void arm580(u32 opcode) { STR_PREINC(OFFSET_IMM, OP_STR, 32); }
+// LDR Rd, [Rn, #]
+static INSN_REGPARM void arm590(u32 opcode) { LDR_PREINC(OFFSET_IMM, OP_LDR, 32); }
+// STR Rd, [Rn, #]!
+static INSN_REGPARM void arm5A0(u32 opcode) { STR_PREINC_WB(OFFSET_IMM, OP_STR, 32); }
+// LDR Rd, [Rn, #]!
+static INSN_REGPARM void arm5B0(u32 opcode) { LDR_PREINC_WB(OFFSET_IMM, OP_LDR, 32); }
+// STRB Rd, [Rn, #]
+static INSN_REGPARM void arm5C0(u32 opcode) { STR_PREINC(OFFSET_IMM, OP_STRB, 16); }
+// LDRB Rd, [Rn, #]
+static INSN_REGPARM void arm5D0(u32 opcode) { LDR_PREINC(OFFSET_IMM, OP_LDRB, 16); }
+// STRB Rd, [Rn, #]!
+static INSN_REGPARM void arm5E0(u32 opcode) { STR_PREINC_WB(OFFSET_IMM, OP_STRB, 16); }
+// LDRB Rd, [Rn, #]!
+static INSN_REGPARM void arm5F0(u32 opcode) { LDR_PREINC_WB(OFFSET_IMM, OP_LDRB, 16); }
+
+// STR[T] Rd, [Rn], -Rm, LSL #
+static INSN_REGPARM void arm600(u32 opcode) { STR_POSTDEC(OFFSET_LSL, OP_STR, 32); }
+// STR[T] Rd, [Rn], -Rm, LSR #
+static INSN_REGPARM void arm602(u32 opcode) { STR_POSTDEC(OFFSET_LSR, OP_STR, 32); }
+// STR[T] Rd, [Rn], -Rm, ASR #
+static INSN_REGPARM void arm604(u32 opcode) { STR_POSTDEC(OFFSET_ASR, OP_STR, 32); }
+// STR[T] Rd, [Rn], -Rm, ROR #
+static INSN_REGPARM void arm606(u32 opcode) { STR_POSTDEC(OFFSET_ROR, OP_STR, 32); }
+// LDR[T] Rd, [Rn], -Rm, LSL #
+static INSN_REGPARM void arm610(u32 opcode) { LDR_POSTDEC(OFFSET_LSL, OP_LDR, 32); }
+// LDR[T] Rd, [Rn], -Rm, LSR #
+static INSN_REGPARM void arm612(u32 opcode) { LDR_POSTDEC(OFFSET_LSR, OP_LDR, 32); }
+// LDR[T] Rd, [Rn], -Rm, ASR #
+static INSN_REGPARM void arm614(u32 opcode) { LDR_POSTDEC(OFFSET_ASR, OP_LDR, 32); }
+// LDR[T] Rd, [Rn], -Rm, ROR #
+static INSN_REGPARM void arm616(u32 opcode) { LDR_POSTDEC(OFFSET_ROR, OP_LDR, 32); }
+// STRB[T] Rd, [Rn], -Rm, LSL #
+static INSN_REGPARM void arm640(u32 opcode) { STR_POSTDEC(OFFSET_LSL, OP_STRB, 16); }
+// STRB[T] Rd, [Rn], -Rm, LSR #
+static INSN_REGPARM void arm642(u32 opcode) { STR_POSTDEC(OFFSET_LSR, OP_STRB, 16); }
+// STRB[T] Rd, [Rn], -Rm, ASR #
+static INSN_REGPARM void arm644(u32 opcode) { STR_POSTDEC(OFFSET_ASR, OP_STRB, 16); }
+// STRB[T] Rd, [Rn], -Rm, ROR #
+static INSN_REGPARM void arm646(u32 opcode) { STR_POSTDEC(OFFSET_ROR, OP_STRB, 16); }
+// LDRB[T] Rd, [Rn], -Rm, LSL #
+static INSN_REGPARM void arm650(u32 opcode) { LDR_POSTDEC(OFFSET_LSL, OP_LDRB, 16); }
+// LDRB[T] Rd, [Rn], -Rm, LSR #
+static INSN_REGPARM void arm652(u32 opcode) { LDR_POSTDEC(OFFSET_LSR, OP_LDRB, 16); }
+// LDRB[T] Rd, [Rn], -Rm, ASR #
+static INSN_REGPARM void arm654(u32 opcode) { LDR_POSTDEC(OFFSET_ASR, OP_LDRB, 16); }
+// LDRB Rd, [Rn], -Rm, ROR #
+static INSN_REGPARM void arm656(u32 opcode) { LDR_POSTDEC(OFFSET_ROR, OP_LDRB, 16); }
+// STR[T] Rd, [Rn], Rm, LSL #
+static INSN_REGPARM void arm680(u32 opcode) { STR_POSTINC(OFFSET_LSL, OP_STR, 32); }
+// STR[T] Rd, [Rn], Rm, LSR #
+static INSN_REGPARM void arm682(u32 opcode) { STR_POSTINC(OFFSET_LSR, OP_STR, 32); }
+// STR[T] Rd, [Rn], Rm, ASR #
+static INSN_REGPARM void arm684(u32 opcode) { STR_POSTINC(OFFSET_ASR, OP_STR, 32); }
+// STR[T] Rd, [Rn], Rm, ROR #
+static INSN_REGPARM void arm686(u32 opcode) { STR_POSTINC(OFFSET_ROR, OP_STR, 32); }
+// LDR[T] Rd, [Rn], Rm, LSL #
+static INSN_REGPARM void arm690(u32 opcode) { LDR_POSTINC(OFFSET_LSL, OP_LDR, 32); }
+// LDR[T] Rd, [Rn], Rm, LSR #
+static INSN_REGPARM void arm692(u32 opcode) { LDR_POSTINC(OFFSET_LSR, OP_LDR, 32); }
+// LDR[T] Rd, [Rn], Rm, ASR #
+static INSN_REGPARM void arm694(u32 opcode) { LDR_POSTINC(OFFSET_ASR, OP_LDR, 32); }
+// LDR[T] Rd, [Rn], Rm, ROR #
+static INSN_REGPARM void arm696(u32 opcode) { LDR_POSTINC(OFFSET_ROR, OP_LDR, 32); }
+// STRB[T] Rd, [Rn], Rm, LSL #
+static INSN_REGPARM void arm6C0(u32 opcode) { STR_POSTINC(OFFSET_LSL, OP_STRB, 16); }
+// STRB[T] Rd, [Rn], Rm, LSR #
+static INSN_REGPARM void arm6C2(u32 opcode) { STR_POSTINC(OFFSET_LSR, OP_STRB, 16); }
+// STRB[T] Rd, [Rn], Rm, ASR #
+static INSN_REGPARM void arm6C4(u32 opcode) { STR_POSTINC(OFFSET_ASR, OP_STRB, 16); }
+// STRB[T] Rd, [Rn], Rm, ROR #
+static INSN_REGPARM void arm6C6(u32 opcode) { STR_POSTINC(OFFSET_ROR, OP_STRB, 16); }
+// LDRB[T] Rd, [Rn], Rm, LSL #
+static INSN_REGPARM void arm6D0(u32 opcode) { LDR_POSTINC(OFFSET_LSL, OP_LDRB, 16); }
+// LDRB[T] Rd, [Rn], Rm, LSR #
+static INSN_REGPARM void arm6D2(u32 opcode) { LDR_POSTINC(OFFSET_LSR, OP_LDRB, 16); }
+// LDRB[T] Rd, [Rn], Rm, ASR #
+static INSN_REGPARM void arm6D4(u32 opcode) { LDR_POSTINC(OFFSET_ASR, OP_LDRB, 16); }
+// LDRB[T] Rd, [Rn], Rm, ROR #
+static INSN_REGPARM void arm6D6(u32 opcode) { LDR_POSTINC(OFFSET_ROR, OP_LDRB, 16); }
+// STR Rd, [Rn, -Rm, LSL #]
+static INSN_REGPARM void arm700(u32 opcode) { STR_PREDEC(OFFSET_LSL, OP_STR, 32); }
+// STR Rd, [Rn, -Rm, LSR #]
+static INSN_REGPARM void arm702(u32 opcode) { STR_PREDEC(OFFSET_LSR, OP_STR, 32); }
+// STR Rd, [Rn, -Rm, ASR #]
+static INSN_REGPARM void arm704(u32 opcode) { STR_PREDEC(OFFSET_ASR, OP_STR, 32); }
+// STR Rd, [Rn, -Rm, ROR #]
+static INSN_REGPARM void arm706(u32 opcode) { STR_PREDEC(OFFSET_ROR, OP_STR, 32); }
+// LDR Rd, [Rn, -Rm, LSL #]
+static INSN_REGPARM void arm710(u32 opcode) { LDR_PREDEC(OFFSET_LSL, OP_LDR, 32); }
+// LDR Rd, [Rn, -Rm, LSR #]
+static INSN_REGPARM void arm712(u32 opcode) { LDR_PREDEC(OFFSET_LSR, OP_LDR, 32); }
+// LDR Rd, [Rn, -Rm, ASR #]
+static INSN_REGPARM void arm714(u32 opcode) { LDR_PREDEC(OFFSET_ASR, OP_LDR, 32); }
+// LDR Rd, [Rn, -Rm, ROR #]
+static INSN_REGPARM void arm716(u32 opcode) { LDR_PREDEC(OFFSET_ROR, OP_LDR, 32); }
+// STR Rd, [Rn, -Rm, LSL #]!
+static INSN_REGPARM void arm720(u32 opcode) { STR_PREDEC_WB(OFFSET_LSL, OP_STR, 32); }
+// STR Rd, [Rn, -Rm, LSR #]!
+static INSN_REGPARM void arm722(u32 opcode) { STR_PREDEC_WB(OFFSET_LSR, OP_STR, 32); }
+// STR Rd, [Rn, -Rm, ASR #]!
+static INSN_REGPARM void arm724(u32 opcode) { STR_PREDEC_WB(OFFSET_ASR, OP_STR, 32); }
+// STR Rd, [Rn, -Rm, ROR #]!
+static INSN_REGPARM void arm726(u32 opcode) { STR_PREDEC_WB(OFFSET_ROR, OP_STR, 32); }
+// LDR Rd, [Rn, -Rm, LSL #]!
+static INSN_REGPARM void arm730(u32 opcode) { LDR_PREDEC_WB(OFFSET_LSL, OP_LDR, 32); }
+// LDR Rd, [Rn, -Rm, LSR #]!
+static INSN_REGPARM void arm732(u32 opcode) { LDR_PREDEC_WB(OFFSET_LSR, OP_LDR, 32); }
+// LDR Rd, [Rn, -Rm, ASR #]!
+static INSN_REGPARM void arm734(u32 opcode) { LDR_PREDEC_WB(OFFSET_ASR, OP_LDR, 32); }
+// LDR Rd, [Rn, -Rm, ROR #]!
+static INSN_REGPARM void arm736(u32 opcode) { LDR_PREDEC_WB(OFFSET_ROR, OP_LDR, 32); }
+// STRB Rd, [Rn, -Rm, LSL #]
+static INSN_REGPARM void arm740(u32 opcode) { STR_PREDEC(OFFSET_LSL, OP_STRB, 16); }
+// STRB Rd, [Rn, -Rm, LSR #]
+static INSN_REGPARM void arm742(u32 opcode) { STR_PREDEC(OFFSET_LSR, OP_STRB, 16); }
+// STRB Rd, [Rn, -Rm, ASR #]
+static INSN_REGPARM void arm744(u32 opcode) { STR_PREDEC(OFFSET_ASR, OP_STRB, 16); }
+// STRB Rd, [Rn, -Rm, ROR #]
+static INSN_REGPARM void arm746(u32 opcode) { STR_PREDEC(OFFSET_ROR, OP_STRB, 16); }
+// LDRB Rd, [Rn, -Rm, LSL #]
+static INSN_REGPARM void arm750(u32 opcode) { LDR_PREDEC(OFFSET_LSL, OP_LDRB, 16); }
+// LDRB Rd, [Rn, -Rm, LSR #]
+static INSN_REGPARM void arm752(u32 opcode) { LDR_PREDEC(OFFSET_LSR, OP_LDRB, 16); }
+// LDRB Rd, [Rn, -Rm, ASR #]
+static INSN_REGPARM void arm754(u32 opcode) { LDR_PREDEC(OFFSET_ASR, OP_LDRB, 16); }
+// LDRB Rd, [Rn, -Rm, ROR #]
+static INSN_REGPARM void arm756(u32 opcode) { LDR_PREDEC(OFFSET_ROR, OP_LDRB, 16); }
+// STRB Rd, [Rn, -Rm, LSL #]!
+static INSN_REGPARM void arm760(u32 opcode) { STR_PREDEC_WB(OFFSET_LSL, OP_STRB, 16); }
+// STRB Rd, [Rn, -Rm, LSR #]!
+static INSN_REGPARM void arm762(u32 opcode) { STR_PREDEC_WB(OFFSET_LSR, OP_STRB, 16); }
+// STRB Rd, [Rn, -Rm, ASR #]!
+static INSN_REGPARM void arm764(u32 opcode) { STR_PREDEC_WB(OFFSET_ASR, OP_STRB, 16); }
+// STRB Rd, [Rn, -Rm, ROR #]!
+static INSN_REGPARM void arm766(u32 opcode) { STR_PREDEC_WB(OFFSET_ROR, OP_STRB, 16); }
+// LDRB Rd, [Rn, -Rm, LSL #]!
+static INSN_REGPARM void arm770(u32 opcode) { LDR_PREDEC_WB(OFFSET_LSL, OP_LDRB, 16); }
+// LDRB Rd, [Rn, -Rm, LSR #]!
+static INSN_REGPARM void arm772(u32 opcode) { LDR_PREDEC_WB(OFFSET_LSR, OP_LDRB, 16); }
+// LDRB Rd, [Rn, -Rm, ASR #]!
+static INSN_REGPARM void arm774(u32 opcode) { LDR_PREDEC_WB(OFFSET_ASR, OP_LDRB, 16); }
+// LDRB Rd, [Rn, -Rm, ROR #]!
+static INSN_REGPARM void arm776(u32 opcode) { LDR_PREDEC_WB(OFFSET_ROR, OP_LDRB, 16); }
+// STR Rd, [Rn, Rm, LSL #]
+static INSN_REGPARM void arm780(u32 opcode) { STR_PREINC(OFFSET_LSL, OP_STR, 32); }
+// STR Rd, [Rn, Rm, LSR #]
+static INSN_REGPARM void arm782(u32 opcode) { STR_PREINC(OFFSET_LSR, OP_STR, 32); }
+// STR Rd, [Rn, Rm, ASR #]
+static INSN_REGPARM void arm784(u32 opcode) { STR_PREINC(OFFSET_ASR, OP_STR, 32); }
+// STR Rd, [Rn, Rm, ROR #]
+static INSN_REGPARM void arm786(u32 opcode) { STR_PREINC(OFFSET_ROR, OP_STR, 32); }
+// LDR Rd, [Rn, Rm, LSL #]
+static INSN_REGPARM void arm790(u32 opcode) { LDR_PREINC(OFFSET_LSL, OP_LDR, 32); }
+// LDR Rd, [Rn, Rm, LSR #]
+static INSN_REGPARM void arm792(u32 opcode) { LDR_PREINC(OFFSET_LSR, OP_LDR, 32); }
+// LDR Rd, [Rn, Rm, ASR #]
+static INSN_REGPARM void arm794(u32 opcode) { LDR_PREINC(OFFSET_ASR, OP_LDR, 32); }
+// LDR Rd, [Rn, Rm, ROR #]
+static INSN_REGPARM void arm796(u32 opcode) { LDR_PREINC(OFFSET_ROR, OP_LDR, 32); }
+// STR Rd, [Rn, Rm, LSL #]!
+static INSN_REGPARM void arm7A0(u32 opcode) { STR_PREINC_WB(OFFSET_LSL, OP_STR, 32); }
+// STR Rd, [Rn, Rm, LSR #]!
+static INSN_REGPARM void arm7A2(u32 opcode) { STR_PREINC_WB(OFFSET_LSR, OP_STR, 32); }
+// STR Rd, [Rn, Rm, ASR #]!
+static INSN_REGPARM void arm7A4(u32 opcode) { STR_PREINC_WB(OFFSET_ASR, OP_STR, 32); }
+// STR Rd, [Rn, Rm, ROR #]!
+static INSN_REGPARM void arm7A6(u32 opcode) { STR_PREINC_WB(OFFSET_ROR, OP_STR, 32); }
+// LDR Rd, [Rn, Rm, LSL #]!
+static INSN_REGPARM void arm7B0(u32 opcode) { LDR_PREINC_WB(OFFSET_LSL, OP_LDR, 32); }
+// LDR Rd, [Rn, Rm, LSR #]!
+static INSN_REGPARM void arm7B2(u32 opcode) { LDR_PREINC_WB(OFFSET_LSR, OP_LDR, 32); }
+// LDR Rd, [Rn, Rm, ASR #]!
+static INSN_REGPARM void arm7B4(u32 opcode) { LDR_PREINC_WB(OFFSET_ASR, OP_LDR, 32); }
+// LDR Rd, [Rn, Rm, ROR #]!
+static INSN_REGPARM void arm7B6(u32 opcode) { LDR_PREINC_WB(OFFSET_ROR, OP_LDR, 32); }
+// STRB Rd, [Rn, Rm, LSL #]
+static INSN_REGPARM void arm7C0(u32 opcode) { STR_PREINC(OFFSET_LSL, OP_STRB, 16); }
+// STRB Rd, [Rn, Rm, LSR #]
+static INSN_REGPARM void arm7C2(u32 opcode) { STR_PREINC(OFFSET_LSR, OP_STRB, 16); }
+// STRB Rd, [Rn, Rm, ASR #]
+static INSN_REGPARM void arm7C4(u32 opcode) { STR_PREINC(OFFSET_ASR, OP_STRB, 16); }
+// STRB Rd, [Rn, Rm, ROR #]
+static INSN_REGPARM void arm7C6(u32 opcode) { STR_PREINC(OFFSET_ROR, OP_STRB, 16); }
+// LDRB Rd, [Rn, Rm, LSL #]
+static INSN_REGPARM void arm7D0(u32 opcode) { LDR_PREINC(OFFSET_LSL, OP_LDRB, 16); }
+// LDRB Rd, [Rn, Rm, LSR #]
+static INSN_REGPARM void arm7D2(u32 opcode) { LDR_PREINC(OFFSET_LSR, OP_LDRB, 16); }
+// LDRB Rd, [Rn, Rm, ASR #]
+static INSN_REGPARM void arm7D4(u32 opcode) { LDR_PREINC(OFFSET_ASR, OP_LDRB, 16); }
+// LDRB Rd, [Rn, Rm, ROR #]
+static INSN_REGPARM void arm7D6(u32 opcode) { LDR_PREINC(OFFSET_ROR, OP_LDRB, 16); }
+// STRB Rd, [Rn, Rm, LSL #]!
+static INSN_REGPARM void arm7E0(u32 opcode) { STR_PREINC_WB(OFFSET_LSL, OP_STRB, 16); }
+// STRB Rd, [Rn, Rm, LSR #]!
+static INSN_REGPARM void arm7E2(u32 opcode) { STR_PREINC_WB(OFFSET_LSR, OP_STRB, 16); }
+// STRB Rd, [Rn, Rm, ASR #]!
+static INSN_REGPARM void arm7E4(u32 opcode) { STR_PREINC_WB(OFFSET_ASR, OP_STRB, 16); }
+// STRB Rd, [Rn, Rm, ROR #]!
+static INSN_REGPARM void arm7E6(u32 opcode) { STR_PREINC_WB(OFFSET_ROR, OP_STRB, 16); }
+// LDRB Rd, [Rn, Rm, LSL #]!
+static INSN_REGPARM void arm7F0(u32 opcode) { LDR_PREINC_WB(OFFSET_LSL, OP_LDRB, 16); }
+// LDRB Rd, [Rn, Rm, LSR #]!
+static INSN_REGPARM void arm7F2(u32 opcode) { LDR_PREINC_WB(OFFSET_LSR, OP_LDRB, 16); }
+// LDRB Rd, [Rn, Rm, ASR #]!
+static INSN_REGPARM void arm7F4(u32 opcode) { LDR_PREINC_WB(OFFSET_ASR, OP_LDRB, 16); }
+// LDRB Rd, [Rn, Rm, ROR #]!
+static INSN_REGPARM void arm7F6(u32 opcode) { LDR_PREINC_WB(OFFSET_ROR, OP_LDRB, 16); }
+
+// STM/LDM ////////////////////////////////////////////////////////////////
+
+#define STM_REG(bit,num) \
+    if (opcode & (1U<<(bit))) {                         \
+        CPUWriteMemory(address, reg[(num)].I);          \
+        if (!count) {                                   \
+            clockTicks += 1 + dataTicksAccess32(address);\
+        } else {                                        \
+            clockTicks += 1 + dataTicksAccessSeq32(address);\
+        }                                               \
+        count++;                                        \
+        address += 4;                                   \
+    }
+#define STMW_REG(bit,num) \
+    if (opcode & (1U<<(bit))) {                         \
+        CPUWriteMemory(address, reg[(num)].I);          \
+        if (!count) {                                   \
+            clockTicks += 1 + dataTicksAccess32(address);\
+        } else {                                        \
+            clockTicks += 1 + dataTicksAccessSeq32(address);\
+        }                                               \
+        reg[base].I = temp;                             \
+        count++;                                        \
+        address += 4;                                   \
+    }
+#define LDM_REG(bit,num) \
+    if (opcode & (1U<<(bit))) {                         \
+        reg[(num)].I = CPUReadMemory(address);          \
+        if (!count) {                                   \
+            clockTicks += 1 + dataTicksAccess32(address);\
+        } else {                                        \
+            clockTicks += 1 + dataTicksAccessSeq32(address);\
+        }                                               \
+        count++;                                        \
+        address += 4;                                   \
+    }
+#define STM_LOW(STORE_REG) \
+    STORE_REG(0, 0);                                    \
+    STORE_REG(1, 1);                                    \
+    STORE_REG(2, 2);                                    \
+    STORE_REG(3, 3);                                    \
+    STORE_REG(4, 4);                                    \
+    STORE_REG(5, 5);                                    \
+    STORE_REG(6, 6);                                    \
+    STORE_REG(7, 7);
+#define STM_HIGH(STORE_REG) \
+    STORE_REG(8, 8);                                    \
+    STORE_REG(9, 9);                                    \
+    STORE_REG(10, 10);                                  \
+    STORE_REG(11, 11);                                  \
+    STORE_REG(12, 12);                                  \
+    STORE_REG(13, 13);                                  \
+    STORE_REG(14, 14);
+#define STM_HIGH_2(STORE_REG) \
+    if (armMode == 0x11) {                              \
+        STORE_REG(8, R8_FIQ);                           \
+        STORE_REG(9, R9_FIQ);                           \
+        STORE_REG(10, R10_FIQ);                         \
+        STORE_REG(11, R11_FIQ);                         \
+        STORE_REG(12, R12_FIQ);                         \
+    } else {                                            \
+        STORE_REG(8, 8);                                \
+        STORE_REG(9, 9);                                \
+        STORE_REG(10, 10);                              \
+        STORE_REG(11, 11);                              \
+        STORE_REG(12, 12);                              \
+    }                                                   \
+    if (armMode != 0x10 && armMode != 0x1F) {           \
+        STORE_REG(13, R13_USR);                         \
+        STORE_REG(14, R14_USR);                         \
+    } else {                                            \
+        STORE_REG(13, 13);                              \
+        STORE_REG(14, 14);                              \
+    }
+#define STM_PC \
+    if (opcode & (1U<<15)) {                            \
+        CPUWriteMemory(address, reg[15].I+4);           \
+        if (!count) {                                   \
+            clockTicks += 1 + dataTicksAccess32(address);\
+        } else {                                        \
+            clockTicks += 1 + dataTicksAccessSeq32(address);\
+        }                                               \
+        count++;                                        \
+    }
+#define STMW_PC \
+    if (opcode & (1U<<15)) {                            \
+        CPUWriteMemory(address, reg[15].I+4);           \
+        if (!count) {                                   \
+            clockTicks += 1 + dataTicksAccess32(address);\
+        } else {                                        \
+            clockTicks += 1 + dataTicksAccessSeq32(address);\
+        }                                               \
+        reg[base].I = temp;                             \
+        count++;                                        \
+    }
+#define LDM_LOW \
+    LDM_REG(0, 0);                                      \
+    LDM_REG(1, 1);                                      \
+    LDM_REG(2, 2);                                      \
+    LDM_REG(3, 3);                                      \
+    LDM_REG(4, 4);                                      \
+    LDM_REG(5, 5);                                      \
+    LDM_REG(6, 6);                                      \
+    LDM_REG(7, 7);
+#define LDM_HIGH \
+    LDM_REG(8, 8);                                      \
+    LDM_REG(9, 9);                                      \
+    LDM_REG(10, 10);                                    \
+    LDM_REG(11, 11);                                    \
+    LDM_REG(12, 12);                                    \
+    LDM_REG(13, 13);                                    \
+    LDM_REG(14, 14);
+#define LDM_HIGH_2 \
+    if (armMode == 0x11) {                              \
+        LDM_REG(8, R8_FIQ);                             \
+        LDM_REG(9, R9_FIQ);                             \
+        LDM_REG(10, R10_FIQ);                           \
+        LDM_REG(11, R11_FIQ);                           \
+        LDM_REG(12, R12_FIQ);                           \
+    } else {                                            \
+        LDM_REG(8, 8);                                  \
+        LDM_REG(9, 9);                                  \
+        LDM_REG(10, 10);                                \
+        LDM_REG(11, 11);                                \
+        LDM_REG(12, 12);                                \
+    }                                                   \
+    if (armMode != 0x10 && armMode != 0x1F) {           \
+        LDM_REG(13, R13_USR);                           \
+        LDM_REG(14, R14_USR);                           \
+    } else {                                            \
+        LDM_REG(13, 13);                                \
+        LDM_REG(14, 14);                                \
+    }
+#define STM_ALL \
+    STM_LOW(STM_REG);                                   \
+    STM_HIGH(STM_REG);                                  \
+    STM_PC;
+#define STMW_ALL \
+    STM_LOW(STMW_REG);                                  \
+    STM_HIGH(STMW_REG);                                 \
+    STMW_PC;
+#define LDM_ALL \
+    LDM_LOW;                                            \
+    LDM_HIGH;                                           \
+    if (opcode & (1U<<15)) {                            \
+        reg[15].I = CPUReadMemory(address);             \
+        if (!count) {                                   \
+            clockTicks += 1 + dataTicksAccess32(address);\
+        } else {                                        \
+            clockTicks += 1 + dataTicksAccessSeq32(address);\
+        }                                               \
+        count++;                                        \
+    }                                                   \
+    if (opcode & (1U<<15)) {                            \
+        armNextPC = reg[15].I;                          \
+        reg[15].I += 4;                                 \
+        ARM_PREFETCH;                                   \
+        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);\
+    }
+#define STM_ALL_2 \
+    STM_LOW(STM_REG);                                   \
+    STM_HIGH_2(STM_REG);                                \
+    STM_PC;
+#define STMW_ALL_2 \
+    STM_LOW(STMW_REG);                                  \
+    STM_HIGH_2(STMW_REG);                               \
+    STMW_PC;
+#define LDM_ALL_2 \
+    LDM_LOW;                                            \
+    if (opcode & (1U<<15)) {                            \
+        LDM_HIGH;                                       \
+        reg[15].I = CPUReadMemory(address);             \
+        if (!count) {                                   \
+            clockTicks += 1 + dataTicksAccess32(address); \
+        } else {                                        \
+            clockTicks += 1 + dataTicksAccessSeq32(address); \
+        }                                               \
+        count++;                                        \
+    } else {                                            \
+        LDM_HIGH_2;                                     \
+    }
+#define LDM_ALL_2B \
+    if (opcode & (1U<<15)) {                            \
+        CPUSwitchMode(reg[17].I & 0x1F, false);         \
+        if (armState) {                                 \
+            armNextPC = reg[15].I & 0xFFFFFFFC;         \
+            reg[15].I = armNextPC + 4;                  \
+            ARM_PREFETCH;                               \
+        } else {                                        \
+            armNextPC = reg[15].I & 0xFFFFFFFE;         \
+            reg[15].I = armNextPC + 2;                  \
+            THUMB_PREFETCH;                             \
+        }                                               \
+        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);\
+    }
+
+
+// STMDA Rn, {Rlist}
+static INSN_REGPARM void arm800(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = (temp + 4) & 0xFFFFFFFC;
+    int count = 0;
+    STM_ALL;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMDA Rn, {Rlist}
+static INSN_REGPARM void arm810(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = (temp + 4) & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMDA Rn!, {Rlist}
+static INSN_REGPARM void arm820(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = (temp+4) & 0xFFFFFFFC;
+    int count = 0;
+    STMW_ALL;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMDA Rn!, {Rlist}
+static INSN_REGPARM void arm830(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = (temp + 4) & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+    if (!(opcode & (1U << base)))
+        reg[base].I = temp;
+}
+
+// STMDA Rn, {Rlist}^
+static INSN_REGPARM void arm840(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = (temp+4) & 0xFFFFFFFC;
+    int count = 0;
+    STM_ALL_2;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMDA Rn, {Rlist}^
+static INSN_REGPARM void arm850(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = (temp + 4) & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL_2;
+    LDM_ALL_2B;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMDA Rn!, {Rlist}^
+static INSN_REGPARM void arm860(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = (temp+4) & 0xFFFFFFFC;
+    int count = 0;
+    STMW_ALL_2;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMDA Rn!, {Rlist}^
+static INSN_REGPARM void arm870(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = (temp + 4) & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL_2;
+    if (!(opcode & (1U << base)))
+        reg[base].I = temp;
+    LDM_ALL_2B;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMIA Rn, {Rlist}
+static INSN_REGPARM void arm880(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = reg[base].I & 0xFFFFFFFC;
+    int count = 0;
+    STM_ALL;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMIA Rn, {Rlist}
+static INSN_REGPARM void arm890(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = reg[base].I & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMIA Rn!, {Rlist}
+static INSN_REGPARM void arm8A0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = reg[base].I & 0xFFFFFFFC;
+    int count = 0;
+    u32 temp = reg[base].I +
+        4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]);
+    STMW_ALL;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMIA Rn!, {Rlist}
+static INSN_REGPARM void arm8B0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I +
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = reg[base].I & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+    if (!(opcode & (1U << base)))
+        reg[base].I = temp;
+}
+
+// STMIA Rn, {Rlist}^
+static INSN_REGPARM void arm8C0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = reg[base].I & 0xFFFFFFFC;
+    int count = 0;
+    STM_ALL_2;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMIA Rn, {Rlist}^
+static INSN_REGPARM void arm8D0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = reg[base].I & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL_2;
+    LDM_ALL_2B;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMIA Rn!, {Rlist}^
+static INSN_REGPARM void arm8E0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = reg[base].I & 0xFFFFFFFC;
+    int count = 0;
+    u32 temp = reg[base].I +
+        4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]);
+    STMW_ALL_2;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMIA Rn!, {Rlist}^
+static INSN_REGPARM void arm8F0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I +
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = reg[base].I & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL_2;
+    if (!(opcode & (1U << base)))
+        reg[base].I = temp;
+    LDM_ALL_2B;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMDB Rn, {Rlist}
+static INSN_REGPARM void arm900(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = temp & 0xFFFFFFFC;
+    int count = 0;
+    STM_ALL;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMDB Rn, {Rlist}
+static INSN_REGPARM void arm910(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = temp & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMDB Rn!, {Rlist}
+static INSN_REGPARM void arm920(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = temp & 0xFFFFFFFC;
+    int count = 0;
+    STMW_ALL;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMDB Rn!, {Rlist}
+static INSN_REGPARM void arm930(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = temp & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+    if (!(opcode & (1U << base)))
+        reg[base].I = temp;
+}
+
+// STMDB Rn, {Rlist}^
+static INSN_REGPARM void arm940(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = temp & 0xFFFFFFFC;
+    int count = 0;
+    STM_ALL_2;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMDB Rn, {Rlist}^
+static INSN_REGPARM void arm950(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = temp & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL_2;
+    LDM_ALL_2B;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMDB Rn!, {Rlist}^
+static INSN_REGPARM void arm960(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = temp & 0xFFFFFFFC;
+    int count = 0;
+    STMW_ALL_2;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMDB Rn!, {Rlist}^
+static INSN_REGPARM void arm970(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I -
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = temp & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL_2;
+    if (!(opcode & (1U << base)))
+        reg[base].I = temp;
+    LDM_ALL_2B;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMIB Rn, {Rlist}
+static INSN_REGPARM void arm980(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = (reg[base].I+4) & 0xFFFFFFFC;
+    int count = 0;
+    STM_ALL;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMIB Rn, {Rlist}
+static INSN_REGPARM void arm990(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = (reg[base].I+4) & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMIB Rn!, {Rlist}
+static INSN_REGPARM void arm9A0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = (reg[base].I+4) & 0xFFFFFFFC;
+    int count = 0;
+    u32 temp = reg[base].I +
+        4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]);
+    STMW_ALL;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMIB Rn!, {Rlist}
+static INSN_REGPARM void arm9B0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I +
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = (reg[base].I+4) & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+    if (!(opcode & (1U << base)))
+        reg[base].I = temp;
+}
+
+// STMIB Rn, {Rlist}^
+static INSN_REGPARM void arm9C0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = (reg[base].I+4) & 0xFFFFFFFC;
+    int count = 0;
+    STM_ALL_2;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMIB Rn, {Rlist}^
+static INSN_REGPARM void arm9D0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = (reg[base].I+4) & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL_2;
+    LDM_ALL_2B;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// STMIB Rn!, {Rlist}^
+static INSN_REGPARM void arm9E0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 address = (reg[base].I+4) & 0xFFFFFFFC;
+    int count = 0;
+    u32 temp = reg[base].I +
+        4 * (cpuBitsSet[opcode & 0xFF] + cpuBitsSet[(opcode >> 8) & 255]);
+    STMW_ALL_2;
+    clockTicks += 1 + codeTicksAccess32(armNextPC);
+}
+
+// LDMIB Rn!, {Rlist}^
+static INSN_REGPARM void arm9F0(u32 opcode)
+{
+    if (busPrefetchCount == 0)
+        busPrefetch = busPrefetchEnable;
+    int base = (opcode & 0x000F0000) >> 16;
+    u32 temp = reg[base].I +
+        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
+    u32 address = (reg[base].I+4) & 0xFFFFFFFC;
+    int count = 0;
+    LDM_ALL_2;
+    if (!(opcode & (1U << base)))
+        reg[base].I = temp;
+    LDM_ALL_2B;
+    clockTicks += 2 + codeTicksAccess32(armNextPC);
+}
+
+// B/BL/SWI and (unimplemented) coproc support ////////////////////////////
+
+// B <offset>
+static INSN_REGPARM void armA00(u32 opcode)
+{
+    int offset = opcode & 0x00FFFFFF;
+    if (offset & 0x00800000)
+        offset |= 0xFF000000;  // negative offset
+    reg[15].I += offset<<2;
+    armNextPC = reg[15].I;
+    reg[15].I += 4;
+    ARM_PREFETCH;
+    clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
+    clockTicks += 2 + codeTicksAccess32(armNextPC)
+                    + codeTicksAccessSeq32(armNextPC);
+    busPrefetchCount = 0;
+}
+
+// BL <offset>
+static INSN_REGPARM void armB00(u32 opcode)
+{
+    int offset = opcode & 0x00FFFFFF;
+    if (offset & 0x00800000)
+        offset |= 0xFF000000;  // negative offset
+    reg[14].I = reg[15].I - 4;
+    reg[15].I += offset<<2;
+    armNextPC = reg[15].I;
+    reg[15].I += 4;
+    ARM_PREFETCH;
+    clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
+    clockTicks += 2 + codeTicksAccess32(armNextPC)
+                    + codeTicksAccessSeq32(armNextPC);
+    busPrefetchCount = 0;
+}
+
+
+#ifdef GP_SUPPORT
+// MRC
+static INSN_REGPARM void armE01(u32 opcode)
+{
+}
+#else
+ #define armE01 armUnknownInsn
+#endif
+
+
+// SWI <comment>
+static INSN_REGPARM void armF00(u32 opcode)
+{
+    clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
+    clockTicks += 2 + codeTicksAccess32(armNextPC)
+                    + codeTicksAccessSeq32(armNextPC);
+    busPrefetchCount = 0;
+    CPUSoftwareInterrupt(opcode & 0x00FFFFFF);
+}
+
+// Instruction table //////////////////////////////////////////////////////
+
+typedef INSN_REGPARM void (*insnfunc_t)(u32 opcode);
+#define REP16(insn) \
+    insn,insn,insn,insn,insn,insn,insn,insn,\
+    insn,insn,insn,insn,insn,insn,insn,insn
+#define REP256(insn) \
+    REP16(insn),REP16(insn),REP16(insn),REP16(insn),\
+    REP16(insn),REP16(insn),REP16(insn),REP16(insn),\
+    REP16(insn),REP16(insn),REP16(insn),REP16(insn),\
+    REP16(insn),REP16(insn),REP16(insn),REP16(insn)
+#define arm_UI armUnknownInsn
+#ifdef BKPT_SUPPORT
+ #define arm_BP armBreakpoint
+#else
+ #define arm_BP armUnknownInsn
+#endif
+static insnfunc_t armInsnTable[4096] = {
+    arm000,arm001,arm002,arm003,arm004,arm005,arm006,arm007,  // 000
+    arm000,arm009,arm002,arm00B,arm004,arm_UI,arm006,arm_UI,  // 008
+    arm010,arm011,arm012,arm013,arm014,arm015,arm016,arm017,  // 010
+    arm010,arm019,arm012,arm01B,arm014,arm01D,arm016,arm01F,  // 018
+    arm020,arm021,arm022,arm023,arm024,arm025,arm026,arm027,  // 020
+    arm020,arm029,arm022,arm_UI,arm024,arm_UI,arm026,arm_UI,  // 028
+    arm030,arm031,arm032,arm033,arm034,arm035,arm036,arm037,  // 030
+    arm030,arm039,arm032,arm_UI,arm034,arm01D,arm036,arm01F,  // 038
+    arm040,arm041,arm042,arm043,arm044,arm045,arm046,arm047,  // 040
+    arm040,arm_UI,arm042,arm04B,arm044,arm_UI,arm046,arm_UI,  // 048
+    arm050,arm051,arm052,arm053,arm054,arm055,arm056,arm057,  // 050
+    arm050,arm_UI,arm052,arm05B,arm054,arm05D,arm056,arm05F,  // 058
+    arm060,arm061,arm062,arm063,arm064,arm065,arm066,arm067,  // 060
+    arm060,arm_UI,arm062,arm_UI,arm064,arm_UI,arm066,arm_UI,  // 068
+    arm070,arm071,arm072,arm073,arm074,arm075,arm076,arm077,  // 070
+    arm070,arm_UI,arm072,arm_UI,arm074,arm05D,arm076,arm05F,  // 078
+    arm080,arm081,arm082,arm083,arm084,arm085,arm086,arm087,  // 080
+    arm080,arm089,arm082,arm08B,arm084,arm_UI,arm086,arm_UI,  // 088
+    arm090,arm091,arm092,arm093,arm094,arm095,arm096,arm097,  // 090
+    arm090,arm099,arm092,arm09B,arm094,arm09D,arm096,arm09F,  // 098
+    arm0A0,arm0A1,arm0A2,arm0A3,arm0A4,arm0A5,arm0A6,arm0A7,  // 0A0
+    arm0A0,arm0A9,arm0A2,arm_UI,arm0A4,arm_UI,arm0A6,arm_UI,  // 0A8
+    arm0B0,arm0B1,arm0B2,arm0B3,arm0B4,arm0B5,arm0B6,arm0B7,  // 0B0
+    arm0B0,arm0B9,arm0B2,arm_UI,arm0B4,arm09D,arm0B6,arm09F,  // 0B8
+    arm0C0,arm0C1,arm0C2,arm0C3,arm0C4,arm0C5,arm0C6,arm0C7,  // 0C0
+    arm0C0,arm0C9,arm0C2,arm0CB,arm0C4,arm_UI,arm0C6,arm_UI,  // 0C8
+    arm0D0,arm0D1,arm0D2,arm0D3,arm0D4,arm0D5,arm0D6,arm0D7,  // 0D0
+    arm0D0,arm0D9,arm0D2,arm0DB,arm0D4,arm0DD,arm0D6,arm0DF,  // 0D8
+    arm0E0,arm0E1,arm0E2,arm0E3,arm0E4,arm0E5,arm0E6,arm0E7,  // 0E0
+    arm0E0,arm0E9,arm0E2,arm_UI,arm0E4,arm_UI,arm0E6,arm_UI,  // 0E8
+    arm0F0,arm0F1,arm0F2,arm0F3,arm0F4,arm0F5,arm0F6,arm0F7,  // 0F0
+    arm0F0,arm0F9,arm0F2,arm_UI,arm0F4,arm0DD,arm0F6,arm0DF,  // 0F8
+
+    arm100,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,  // 100
+    arm_UI,arm109,arm_UI,arm10B,arm_UI,arm_UI,arm_UI,arm_UI,  // 108
+    arm110,arm111,arm112,arm113,arm114,arm115,arm116,arm117,  // 110
+    arm110,arm_UI,arm112,arm11B,arm114,arm11D,arm116,arm11F,  // 118
+    arm120,arm121,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_BP,  // 120
+    arm_UI,arm_UI,arm_UI,arm12B,arm_UI,arm_UI,arm_UI,arm_UI,  // 128
+    arm130,arm131,arm132,arm133,arm134,arm135,arm136,arm137,  // 130
+    arm130,arm_UI,arm132,arm13B,arm134,arm13D,arm136,arm13F,  // 138
+    arm140,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,  // 140
+    arm_UI,arm149,arm_UI,arm14B,arm_UI,arm_UI,arm_UI,arm_UI,  // 148
+    arm150,arm151,arm152,arm153,arm154,arm155,arm156,arm157,  // 150
+    arm150,arm_UI,arm152,arm15B,arm154,arm15D,arm156,arm15F,  // 158
+    arm160,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,arm_UI,  // 160
+    arm_UI,arm_UI,arm_UI,arm16B,arm_UI,arm_UI,arm_UI,arm_UI,  // 168
+    arm170,arm171,arm172,arm173,arm174,arm175,arm176,arm177,  // 170
+    arm170,arm_UI,arm172,arm17B,arm174,arm17D,arm176,arm17F,  // 178
+    arm180,arm181,arm182,arm183,arm184,arm185,arm186,arm187,  // 180
+    arm180,arm_UI,arm182,arm18B,arm184,arm_UI,arm186,arm_UI,  // 188
+    arm190,arm191,arm192,arm193,arm194,arm195,arm196,arm197,  // 190
+    arm190,arm_UI,arm192,arm19B,arm194,arm19D,arm196,arm19F,  // 198
+    arm1A0,arm1A1,arm1A2,arm1A3,arm1A4,arm1A5,arm1A6,arm1A7,  // 1A0
+    arm1A0,arm_UI,arm1A2,arm1AB,arm1A4,arm_UI,arm1A6,arm_UI,  // 1A8
+    arm1B0,arm1B1,arm1B2,arm1B3,arm1B4,arm1B5,arm1B6,arm1B7,  // 1B0
+    arm1B0,arm_UI,arm1B2,arm1BB,arm1B4,arm1BD,arm1B6,arm1BF,  // 1B8
+    arm1C0,arm1C1,arm1C2,arm1C3,arm1C4,arm1C5,arm1C6,arm1C7,  // 1C0
+    arm1C0,arm_UI,arm1C2,arm1CB,arm1C4,arm_UI,arm1C6,arm_UI,  // 1C8
+    arm1D0,arm1D1,arm1D2,arm1D3,arm1D4,arm1D5,arm1D6,arm1D7,  // 1D0
+    arm1D0,arm_UI,arm1D2,arm1DB,arm1D4,arm1DD,arm1D6,arm1DF,  // 1D8
+    arm1E0,arm1E1,arm1E2,arm1E3,arm1E4,arm1E5,arm1E6,arm1E7,  // 1E0
+    arm1E0,arm_UI,arm1E2,arm1EB,arm1E4,arm_UI,arm1E6,arm_UI,  // 1E8
+    arm1F0,arm1F1,arm1F2,arm1F3,arm1F4,arm1F5,arm1F6,arm1F7,  // 1F0
+    arm1F0,arm_UI,arm1F2,arm1FB,arm1F4,arm1FD,arm1F6,arm1FF,  // 1F8
+
+    REP16(arm200),REP16(arm210),REP16(arm220),REP16(arm230),  // 200
+    REP16(arm240),REP16(arm250),REP16(arm260),REP16(arm270),  // 240
+    REP16(arm280),REP16(arm290),REP16(arm2A0),REP16(arm2B0),  // 280
+    REP16(arm2C0),REP16(arm2D0),REP16(arm2E0),REP16(arm2F0),  // 2C0
+    REP16(arm_UI),REP16(arm310),REP16(arm320),REP16(arm330),  // 300
+    REP16(arm_UI),REP16(arm350),REP16(arm360),REP16(arm370),  // 340
+    REP16(arm380),REP16(arm390),REP16(arm3A0),REP16(arm3B0),  // 380
+    REP16(arm3C0),REP16(arm3D0),REP16(arm3E0),REP16(arm3F0),  // 3C0
+
+    REP16(arm400),REP16(arm410),REP16(arm400),REP16(arm410),  // 400
+    REP16(arm440),REP16(arm450),REP16(arm440),REP16(arm450),  // 440
+    REP16(arm480),REP16(arm490),REP16(arm480),REP16(arm490),  // 480
+    REP16(arm4C0),REP16(arm4D0),REP16(arm4C0),REP16(arm4D0),  // 4C0
+    REP16(arm500),REP16(arm510),REP16(arm520),REP16(arm530),  // 500
+    REP16(arm540),REP16(arm550),REP16(arm560),REP16(arm570),  // 540
+    REP16(arm580),REP16(arm590),REP16(arm5A0),REP16(arm5B0),  // 580
+    REP16(arm5C0),REP16(arm5D0),REP16(arm5E0),REP16(arm5F0),  // 5C0
+
+    arm600,arm_UI,arm602,arm_UI,arm604,arm_UI,arm606,arm_UI,  // 600
+    arm600,arm_UI,arm602,arm_UI,arm604,arm_UI,arm606,arm_UI,  // 608
+    arm610,arm_UI,arm612,arm_UI,arm614,arm_UI,arm616,arm_UI,  // 610
+    arm610,arm_UI,arm612,arm_UI,arm614,arm_UI,arm616,arm_UI,  // 618
+    arm600,arm_UI,arm602,arm_UI,arm604,arm_UI,arm606,arm_UI,  // 620
+    arm600,arm_UI,arm602,arm_UI,arm604,arm_UI,arm606,arm_UI,  // 628
+    arm610,arm_UI,arm612,arm_UI,arm614,arm_UI,arm616,arm_UI,  // 630
+    arm610,arm_UI,arm612,arm_UI,arm614,arm_UI,arm616,arm_UI,  // 638
+    arm640,arm_UI,arm642,arm_UI,arm644,arm_UI,arm646,arm_UI,  // 640
+    arm640,arm_UI,arm642,arm_UI,arm644,arm_UI,arm646,arm_UI,  // 648
+    arm650,arm_UI,arm652,arm_UI,arm654,arm_UI,arm656,arm_UI,  // 650
+    arm650,arm_UI,arm652,arm_UI,arm654,arm_UI,arm656,arm_UI,  // 658
+    arm640,arm_UI,arm642,arm_UI,arm644,arm_UI,arm646,arm_UI,  // 660
+    arm640,arm_UI,arm642,arm_UI,arm644,arm_UI,arm646,arm_UI,  // 668
+    arm650,arm_UI,arm652,arm_UI,arm654,arm_UI,arm656,arm_UI,  // 670
+    arm650,arm_UI,arm652,arm_UI,arm654,arm_UI,arm656,arm_UI,  // 678
+    arm680,arm_UI,arm682,arm_UI,arm684,arm_UI,arm686,arm_UI,  // 680
+    arm680,arm_UI,arm682,arm_UI,arm684,arm_UI,arm686,arm_UI,  // 688
+    arm690,arm_UI,arm692,arm_UI,arm694,arm_UI,arm696,arm_UI,  // 690
+    arm690,arm_UI,arm692,arm_UI,arm694,arm_UI,arm696,arm_UI,  // 698
+    arm680,arm_UI,arm682,arm_UI,arm684,arm_UI,arm686,arm_UI,  // 6A0
+    arm680,arm_UI,arm682,arm_UI,arm684,arm_UI,arm686,arm_UI,  // 6A8
+    arm690,arm_UI,arm692,arm_UI,arm694,arm_UI,arm696,arm_UI,  // 6B0
+    arm690,arm_UI,arm692,arm_UI,arm694,arm_UI,arm696,arm_UI,  // 6B8
+    arm6C0,arm_UI,arm6C2,arm_UI,arm6C4,arm_UI,arm6C6,arm_UI,  // 6C0
+    arm6C0,arm_UI,arm6C2,arm_UI,arm6C4,arm_UI,arm6C6,arm_UI,  // 6C8
+    arm6D0,arm_UI,arm6D2,arm_UI,arm6D4,arm_UI,arm6D6,arm_UI,  // 6D0
+    arm6D0,arm_UI,arm6D2,arm_UI,arm6D4,arm_UI,arm6D6,arm_UI,  // 6D8
+    arm6C0,arm_UI,arm6C2,arm_UI,arm6C4,arm_UI,arm6C6,arm_UI,  // 6E0
+    arm6C0,arm_UI,arm6C2,arm_UI,arm6C4,arm_UI,arm6C6,arm_UI,  // 6E8
+    arm6D0,arm_UI,arm6D2,arm_UI,arm6D4,arm_UI,arm6D6,arm_UI,  // 6F0
+    arm6D0,arm_UI,arm6D2,arm_UI,arm6D4,arm_UI,arm6D6,arm_UI,  // 6F8
+
+    arm700,arm_UI,arm702,arm_UI,arm704,arm_UI,arm706,arm_UI,  // 700
+    arm700,arm_UI,arm702,arm_UI,arm704,arm_UI,arm706,arm_UI,  // 708
+    arm710,arm_UI,arm712,arm_UI,arm714,arm_UI,arm716,arm_UI,  // 710
+    arm710,arm_UI,arm712,arm_UI,arm714,arm_UI,arm716,arm_UI,  // 718
+    arm720,arm_UI,arm722,arm_UI,arm724,arm_UI,arm726,arm_UI,  // 720
+    arm720,arm_UI,arm722,arm_UI,arm724,arm_UI,arm726,arm_UI,  // 728
+    arm730,arm_UI,arm732,arm_UI,arm734,arm_UI,arm736,arm_UI,  // 730
+    arm730,arm_UI,arm732,arm_UI,arm734,arm_UI,arm736,arm_UI,  // 738
+    arm740,arm_UI,arm742,arm_UI,arm744,arm_UI,arm746,arm_UI,  // 740
+    arm740,arm_UI,arm742,arm_UI,arm744,arm_UI,arm746,arm_UI,  // 748
+    arm750,arm_UI,arm752,arm_UI,arm754,arm_UI,arm756,arm_UI,  // 750
+    arm750,arm_UI,arm752,arm_UI,arm754,arm_UI,arm756,arm_UI,  // 758
+    arm760,arm_UI,arm762,arm_UI,arm764,arm_UI,arm766,arm_UI,  // 760
+    arm760,arm_UI,arm762,arm_UI,arm764,arm_UI,arm766,arm_UI,  // 768
+    arm770,arm_UI,arm772,arm_UI,arm774,arm_UI,arm776,arm_UI,  // 770
+    arm770,arm_UI,arm772,arm_UI,arm774,arm_UI,arm776,arm_UI,  // 778
+    arm780,arm_UI,arm782,arm_UI,arm784,arm_UI,arm786,arm_UI,  // 780
+    arm780,arm_UI,arm782,arm_UI,arm784,arm_UI,arm786,arm_UI,  // 788
+    arm790,arm_UI,arm792,arm_UI,arm794,arm_UI,arm796,arm_UI,  // 790
+    arm790,arm_UI,arm792,arm_UI,arm794,arm_UI,arm796,arm_UI,  // 798
+    arm7A0,arm_UI,arm7A2,arm_UI,arm7A4,arm_UI,arm7A6,arm_UI,  // 7A0
+    arm7A0,arm_UI,arm7A2,arm_UI,arm7A4,arm_UI,arm7A6,arm_UI,  // 7A8
+    arm7B0,arm_UI,arm7B2,arm_UI,arm7B4,arm_UI,arm7B6,arm_UI,  // 7B0
+    arm7B0,arm_UI,arm7B2,arm_UI,arm7B4,arm_UI,arm7B6,arm_UI,  // 7B8
+    arm7C0,arm_UI,arm7C2,arm_UI,arm7C4,arm_UI,arm7C6,arm_UI,  // 7C0
+    arm7C0,arm_UI,arm7C2,arm_UI,arm7C4,arm_UI,arm7C6,arm_UI,  // 7C8
+    arm7D0,arm_UI,arm7D2,arm_UI,arm7D4,arm_UI,arm7D6,arm_UI,  // 7D0
+    arm7D0,arm_UI,arm7D2,arm_UI,arm7D4,arm_UI,arm7D6,arm_UI,  // 7D8
+    arm7E0,arm_UI,arm7E2,arm_UI,arm7E4,arm_UI,arm7E6,arm_UI,  // 7E0
+    arm7E0,arm_UI,arm7E2,arm_UI,arm7E4,arm_UI,arm7E6,arm_UI,  // 7E8
+    arm7F0,arm_UI,arm7F2,arm_UI,arm7F4,arm_UI,arm7F6,arm_UI,  // 7F0
+    arm7F0,arm_UI,arm7F2,arm_UI,arm7F4,arm_UI,arm7F6,arm_BP,  // 7F8
+
+    REP16(arm800),REP16(arm810),REP16(arm820),REP16(arm830),  // 800
+    REP16(arm840),REP16(arm850),REP16(arm860),REP16(arm870),  // 840
+    REP16(arm880),REP16(arm890),REP16(arm8A0),REP16(arm8B0),  // 880
+    REP16(arm8C0),REP16(arm8D0),REP16(arm8E0),REP16(arm8F0),  // 8C0
+    REP16(arm900),REP16(arm910),REP16(arm920),REP16(arm930),  // 900
+    REP16(arm940),REP16(arm950),REP16(arm960),REP16(arm970),  // 940
+    REP16(arm980),REP16(arm990),REP16(arm9A0),REP16(arm9B0),  // 980
+    REP16(arm9C0),REP16(arm9D0),REP16(arm9E0),REP16(arm9F0),  // 9C0
+
+    REP256(armA00),                                           // A00
+    REP256(armB00),                                           // B00
+    REP256(arm_UI),                                           // C00
+    REP256(arm_UI),                                           // D00
+
+    arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,  // E00
+    arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,  // E08
+    arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,  // E10
+    arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,arm_UI,armE01,  // E18
+    REP16(arm_UI),                                            // E20
+    REP16(arm_UI),                                            // E30
+    REP16(arm_UI),REP16(arm_UI),REP16(arm_UI),REP16(arm_UI),  // E40
+    REP16(arm_UI),REP16(arm_UI),REP16(arm_UI),REP16(arm_UI),  // E80
+    REP16(arm_UI),REP16(arm_UI),REP16(arm_UI),REP16(arm_UI),  // EC0
+
+    REP256(armF00),                                           // F00
+};
+
+// Wrapper routine (execution loop) ///////////////////////////////////////
+
+#include<time.h>
+static void tester(void) {
+  static int ran=0;if(ran)return;ran=1;
+  FILE*f=fopen("p:\\timing.txt","w");if(!f)return;
+  for (int op=/*0*/9; op</*0xF00*/10;op++){if(armInsnTable[op]==arm_UI)continue;
+    int i;for(i=0;i<op;i++)if(armInsnTable[op]==armInsnTable[i])break;if(i<op)continue;
+    for(i=0;i<16;i++)reg[i].I=0x3100000;
+    clock_t s=clock();for(i=0;i<10000000;i++)armInsnTable[op](0);clock_t e=clock();
+    fprintf(f,"arm%03X %6d\n",op,e-s);fflush(f);
+  }fclose(f);
+}
+
+int armExecute()
+{
+    do {
+        cpuMasterCodeCheck();
+
+        if ((armNextPC & 0x0803FFFF) == 0x08020000)
+          busPrefetchCount = 0x100;
+
+        u32 opcode = cpuPrefetch[0];
+        cpuPrefetch[0] = cpuPrefetch[1];
+
+        busPrefetch = false;
+        if (busPrefetchCount & 0xFFFFFE00)
+            busPrefetchCount = 0x100 | (busPrefetchCount & 0xFF);
+
+        clockTicks = 0;
+        int oldArmNextPC = armNextPC;
+
+#ifndef FINAL_VERSION
+        if (armNextPC == stop) {
+            armNextPC++;
+        }
+#endif
+
+        armNextPC = reg[15].I;
+        reg[15].I += 4;
+        ARM_PREFETCH_NEXT;
+
+        int cond = opcode >> 28;
+        bool cond_res = true;
+        if (UNLIKELY(cond != 0x0E)) {  // most opcodes are AL (always)
+            switch(cond) {
+              case 0x00: // EQ
+                cond_res = Z_FLAG;
+                break;
+              case 0x01: // NE
+                cond_res = !Z_FLAG;
+                break;
+              case 0x02: // CS
+                cond_res = C_FLAG;
+                break;
+              case 0x03: // CC
+                cond_res = !C_FLAG;
+                break;
+              case 0x04: // MI
+                cond_res = N_FLAG;
+                break;
+              case 0x05: // PL
+                cond_res = !N_FLAG;
+                break;
+              case 0x06: // VS
+                cond_res = V_FLAG;
+                break;
+              case 0x07: // VC
+                cond_res = !V_FLAG;
+                break;
+              case 0x08: // HI
+                cond_res = C_FLAG && !Z_FLAG;
+                break;
+              case 0x09: // LS
+                cond_res = !C_FLAG || Z_FLAG;
+                break;
+              case 0x0A: // GE
+                cond_res = N_FLAG == V_FLAG;
+                break;
+              case 0x0B: // LT
+                cond_res = N_FLAG != V_FLAG;
+                break;
+              case 0x0C: // GT
+                cond_res = !Z_FLAG &&(N_FLAG == V_FLAG);
+                break;
+              case 0x0D: // LE
+                cond_res = Z_FLAG || (N_FLAG != V_FLAG);
+                break;
+              case 0x0E: // AL (impossible, checked above)
+                cond_res = true;
+                break;
+              case 0x0F:
+              default:
+                // ???
+                cond_res = false;
+                break;
+            }
+        }
+
+        if (cond_res)
+            (*armInsnTable[((opcode>>16)&0xFF0) | ((opcode>>4)&0x0F)])(opcode);
+#ifdef INSN_COUNTER
+        count(opcode, cond_res);
+#endif
+        if (clockTicks < 0)
+            return 0;
+        if (clockTicks == 0)
+            clockTicks = 1 + codeTicksAccessSeq32(oldArmNextPC);
+        cpuTotalTicks += clockTicks;
+
+    } while (cpuTotalTicks<cpuNextEvent && armState && !holdState && !SWITicks);
+
+    return 1;
+}
diff -urN ../VisualBoyAdvance-20061204/src/GBA-thumb.cpp src/GBA-thumb.cpp
--- ../VisualBoyAdvance-20061204/src/GBA-thumb.cpp	1970-01-01 09:00:00 +0900
+++ src/GBA-thumb.cpp	2006-12-05 00:18:42 +0900
@@ -0,0 +1,2327 @@
+// -*- C++ -*-
+// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
+// Copyright (C) 1999-2003 Forgotten
+// Copyright (C) 2005-2006 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.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "GBA.h"
+#include "GBAcpu.h"
+#include "GBAinline.h"
+#include "Globals.h"
+#include "Gfx.h"
+#include "EEprom.h"
+#include "Flash.h"
+#include "Sound.h"
+#include "Sram.h"
+#include "bios.h"
+#include "unzip.h"
+#include "Cheats.h"
+#include "NLS.h"
+#include "elf.h"
+#include "Util.h"
+#include "Port.h"
+#include "agbprint.h"
+#ifdef PROFILING
+#include "prof/prof.h"
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+
+static int clockTicks;
+
+static INSN_REGPARM void thumbUnknownInsn(u32 opcode)
+{
+#ifdef DEV_VERSION
+  if(systemVerbose & VERBOSE_UNDEFINED)
+    log("Undefined THUMB instruction %04x at %08x\n", opcode, armNextPC-2);
+#endif
+  CPUUndefinedException();
+}
+
+#ifdef BKPT_SUPPORT
+static INSN_REGPARM void thumbBreakpoint(u32 opcode)
+{
+  extern void (*dbgSignal)(int,int);
+  reg[15].I -= 2;
+  armNextPC -= 2;
+  dbgSignal(5, opcode & 255);
+  clockTicks = -1;
+}
+#endif
+
+// Common macros //////////////////////////////////////////////////////////
+
+#ifdef BKPT_SUPPORT
+# define THUMB_CONSOLE_OUTPUT(a,b) do {                     \
+    if ((opcode == 0x4000) && (reg[0].I == 0xC0DED00D)) {   \
+      extern void (*dbgOutput)(char *, u32);                \
+      dbgOutput((a), (b));                                  \
+    }                                                       \
+} while (0)
+# define UPDATE_OLDREG do {                                 \
+    if (debugger_last) {                                    \
+        snprintf(oldbuffer, sizeof(oldbuffer), "%08X",      \
+                 armState ? reg[15].I - 4 : reg[15].I - 2); \
+        int i;						    \
+        for (i = 0; i < 18; i++) {                          \
+            oldreg[i] = reg[i].I;                           \
+        }                                                   \
+    }                                                       \
+} while (0)
+#else
+# define THUMB_CONSOLE_OUTPUT(a,b)
+# define UPDATE_OLDREG
+#endif
+
+#define NEG(i) ((i) >> 31)
+#define POS(i) ((~(i)) >> 31)
+
+#ifndef C_CORE
+#ifdef __GNUC__
+#ifdef __POWERPC__
+  #define ADD_RD_RS_RN(N) \
+            {										\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("addco. %0, %2, %3\n"	\
+                            "mcrxr cr1\n"			\
+                            "mfcr %1\n"				\
+                            : "=r" (Result), 		\
+                              "=r" (Flags)			\
+                            : "r" (reg[source].I), 	\
+                              "r" (reg[N].I)		\
+                            );						\
+                reg[dest].I = Result;				\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define ADD_RD_RS_O3(N) \
+            {										\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("addco. %0, %2, %3\n"	\
+                            "mcrxr cr1\n"			\
+                            "mfcr %1\n"				\
+                            : "=r" (Result), 		\
+                              "=r" (Flags)			\
+                            : "r" (reg[source].I), 	\
+                              "r" (N)				\
+                            );						\
+                reg[dest].I = Result;				\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define ADD_RD_RS_O3_0 ADD_RD_RS_O3
+  #define ADD_RN_O8(d) \
+            {\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("addco. %0, %2, %3\n"	\
+                            "mcrxr cr1\n"			\
+                            "mfcr %1\n"				\
+                            : "=r" (Result), 		\
+                              "=r" (Flags)			\
+                            : "r" (reg[(d)].I), 	\
+                              "r" (opcode & 255)	\
+                            );						\
+                reg[(d)].I = Result;				\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define CMN_RD_RS \
+            {\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("addco. %0, %2, %3\n"	\
+                            "mcrxr cr1\n"			\
+                            "mfcr %1\n"				\
+                            : "=r" (Result), 		\
+                              "=r" (Flags)			\
+                            : "r" (reg[dest].I), 	\
+                              "r" (value)			\
+                            );						\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define ADC_RD_RS \
+            {\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("mtspr xer, %4\n"		\
+                             "addeo. %0, %2, %3\n"	\
+                             "mcrxr cr1\n"			\
+                             "mfcr	%1\n"			\
+                             : "=r" (Result),		\
+                               "=r" (Flags)			\
+                             : "r" (reg[dest].I),	\
+                               "r" (value),			\
+                               "r" (C_FLAG << 29)	\
+                             );						\
+                reg[dest].I = Result;				\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define SUB_RD_RS_RN(N) \
+            {\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("subco. %0, %2, %3\n"	\
+                            "mcrxr cr1\n"			\
+                            "mfcr %1\n"				\
+                            : "=r" (Result), 		\
+                              "=r" (Flags)			\
+                            : "r" (reg[source].I), 	\
+                              "r" (reg[N].I)		\
+                            );						\
+                reg[dest].I = Result;				\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define SUB_RD_RS_O3(N) \
+            {\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("subco. %0, %2, %3\n"	\
+                            "mcrxr cr1\n"			\
+                            "mfcr %1\n"				\
+                            : "=r" (Result), 		\
+                              "=r" (Flags)			\
+                            : "r" (reg[source].I), 	\
+                              "r" (N)				\
+                            );						\
+                reg[dest].I = Result;				\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define SUB_RD_RS_O3_0 SUB_RD_RS_O3
+  #define SUB_RN_O8(d) \
+            {\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("subco. %0, %2, %3\n"	\
+                            "mcrxr cr1\n"			\
+                            "mfcr %1\n"				\
+                            : "=r" (Result), 		\
+                              "=r" (Flags)			\
+                            : "r" (reg[(d)].I), 	\
+                              "r" (opcode & 255)	\
+                            );						\
+                reg[(d)].I = Result;				\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define CMP_RN_O8(d) \
+            {\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("subco. %0, %2, %3\n"	\
+                            "mcrxr cr1\n"			\
+                            "mfcr %1\n"				\
+                            : "=r" (Result), 		\
+                              "=r" (Flags)			\
+                            : "r" (reg[(d)].I), 	\
+                              "r" (opcode & 255)	\
+                            );						\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define SBC_RD_RS \
+            {\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("mtspr xer, %4\n"		\
+                             "subfeo. %0, %3, %2\n"	\
+                             "mcrxr cr1\n"			\
+                             "mfcr	%1\n"			\
+                             : "=r" (Result),		\
+                               "=r" (Flags)			\
+                             : "r" (reg[dest].I),	\
+                               "r" (value),			\
+                               "r" (C_FLAG << 29) 	\
+                             );						\
+                reg[dest].I = Result;				\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define NEG_RD_RS \
+            {\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("subfco. %0, %2, %3\n"	\
+                            "mcrxr cr1\n"			\
+                            "mfcr %1\n"				\
+                            : "=r" (Result), 		\
+                              "=r" (Flags)			\
+                            : "r" (reg[source].I), 	\
+                              "r" (0)				\
+                            );						\
+                reg[dest].I = Result;				\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+  #define CMP_RD_RS \
+            {\
+                register int Flags;					\
+                register int Result;				\
+                asm volatile("subco. %0, %2, %3\n"	\
+                            "mcrxr cr1\n"			\
+                            "mfcr %1\n"				\
+                            : "=r" (Result), 		\
+                              "=r" (Flags)			\
+                            : "r" (reg[dest].I), 	\
+                              "r" (value)			\
+                            );						\
+                Z_FLAG = (Flags >> 29) & 1;			\
+                N_FLAG = (Flags >> 31) & 1;			\
+                C_FLAG = (Flags >> 25) & 1;			\
+                V_FLAG = (Flags >> 26) & 1;			\
+            }
+#else
+  #define ADD_RN_O8(d) \
+     asm ("andl $0xFF, %%eax;"\
+          "addl %%eax, %0;"\
+          "setsb N_FLAG;"\
+          "setzb Z_FLAG;"\
+          "setcb C_FLAG;"\
+          "setob V_FLAG;"\
+          : "=m" (reg[(d)].I));
+  #define CMN_RD_RS \
+     asm ("add %0, %1;"\
+          "setsb N_FLAG;"\
+          "setzb Z_FLAG;"\
+          "setcb C_FLAG;"\
+          "setob V_FLAG;"\
+          : \
+          : "r" (value), "r" (reg[dest].I):"1");
+  #define ADC_RD_RS \
+     asm ("bt $0, C_FLAG;"\
+          "adc %1, %%ebx;"\
+          "setsb N_FLAG;"\
+          "setzb Z_FLAG;"\
+          "setcb C_FLAG;"\
+          "setob V_FLAG;"\
+          : "=b" (reg[dest].I)\
+          : "r" (value), "b" (reg[dest].I));
+  #define SUB_RN_O8(d) \
+     asm ("andl $0xFF, %%eax;"\
+          "subl %%eax, %0;"\
+          "setsb N_FLAG;"\
+          "setzb Z_FLAG;"\
+          "setncb C_FLAG;"\
+          "setob V_FLAG;"\
+          : "=m" (reg[(d)].I));
+  #define MOV_RN_O8(d) \
+     asm ("andl $0xFF, %%eax;"\
+          "movb $0, N_FLAG;"\
+          "movl %%eax, %0;"\
+          "setzb Z_FLAG;"\
+          : "=m" (reg[(d)].I));
+  #define CMP_RN_O8(d) \
+     asm ("andl $0xFF, %%eax;"\
+          "cmpl %%eax, %0;"\
+          "setsb N_FLAG;"\
+          "setzb Z_FLAG;"\
+          "setncb C_FLAG;"\
+          "setob V_FLAG;"\
+          : \
+          : "m" (reg[(d)].I));
+  #define SBC_RD_RS \
+     asm volatile ("bt $0, C_FLAG;"\
+                   "cmc;"\
+                   "sbb %1, %%ebx;"\
+                   "setsb N_FLAG;"\
+                   "setzb Z_FLAG;"\
+                   "setncb C_FLAG;"\
+                   "setob V_FLAG;"\
+                   : "=b" (reg[dest].I)\
+                   : "r" (value), "b" (reg[dest].I) : "cc", "memory");
+  #define LSL_RD_RS \
+         asm ("shl %%cl, %%eax;"\
+              "setcb C_FLAG;"\
+              : "=a" (value)\
+              : "a" (reg[dest].I), "c" (value));
+  #define LSR_RD_RS \
+         asm ("shr %%cl, %%eax;"\
+              "setcb C_FLAG;"\
+              : "=a" (value)\
+              : "a" (reg[dest].I), "c" (value));
+  #define ASR_RD_RS \
+         asm ("sar %%cl, %%eax;"\
+              "setcb C_FLAG;"\
+              : "=a" (value)\
+              : "a" (reg[dest].I), "c" (value));
+  #define ROR_RD_RS \
+         asm ("ror %%cl, %%eax;"\
+              "setcb C_FLAG;"\
+              : "=a" (value)\
+              : "a" (reg[dest].I), "c" (value));
+  #define NEG_RD_RS \
+     asm ("neg %%ebx;"\
+          "setsb N_FLAG;"\
+          "setzb Z_FLAG;"\
+          "setncb C_FLAG;"\
+          "setob V_FLAG;"\
+          : "=b" (reg[dest].I)\
+          : "b" (reg[source].I));
+  #define CMP_RD_RS \
+     asm ("sub %0, %1;"\
+          "setsb N_FLAG;"\
+          "setzb Z_FLAG;"\
+          "setncb C_FLAG;"\
+          "setob V_FLAG;"\
+          : \
+          : "r" (value), "r" (reg[dest].I):"1");
+  #define IMM5_INSN(OP,N) \
+     asm("movl %%eax,%%ecx;"         \
+         "shrl $1,%%eax;"            \
+         "andl $7,%%ecx;"            \
+         "andl $0x1C,%%eax;"         \
+         "movl reg(%%eax),%%edx;"    \
+         OP                          \
+         "setsb N_FLAG;"             \
+         "setzb Z_FLAG;"             \
+         "movl %%edx,reg(,%%ecx,4);" \
+         : : "i" (N))
+  #define IMM5_INSN_0(OP)            \
+     asm("movl %%eax,%%ecx;"         \
+         "shrl $1,%%eax;"            \
+         "andl $7,%%ecx;"            \
+         "andl $0x1C,%%eax;"         \
+         "movl reg(%%eax),%%edx;"    \
+         OP                          \
+         "setsb N_FLAG;"             \
+         "setzb Z_FLAG;"             \
+         "movl %%edx,reg(,%%ecx,4);" \
+         : : )
+  #define IMM5_LSL \
+         "shll %0,%%edx;"\
+         "setcb C_FLAG;"
+  #define IMM5_LSL_0 \
+         "testl %%edx,%%edx;"
+  #define IMM5_LSR \
+         "shrl %0,%%edx;"\
+         "setcb C_FLAG;"
+  #define IMM5_LSR_0 \
+         "testl %%edx,%%edx;"\
+         "setsb C_FLAG;"\
+         "xorl %%edx,%%edx;"
+  #define IMM5_ASR \
+         "sarl %0,%%edx;"\
+         "setcb C_FLAG;"
+  #define IMM5_ASR_0 \
+         "sarl $31,%%edx;"\
+         "setsb C_FLAG;"
+  #define THREEARG_INSN(OP,N) \
+     asm("movl %%eax,%%edx;"       \
+         "shrl $1,%%edx;"          \
+         "andl $0x1C,%%edx;"       \
+         "andl $7,%%eax;"          \
+         "movl reg(%%edx),%%ecx;"  \
+         OP(N)                     \
+         "setsb N_FLAG;"           \
+         "setzb Z_FLAG;"           \
+         "movl %%ecx,reg(,%%eax,4)"::)
+  #define ADD_RD_RS_RN(N)          \
+         "add (reg+"#N"*4),%%ecx;" \
+         "setcb C_FLAG;"           \
+         "setob V_FLAG;"
+  #define ADD_RD_RS_O3(N)          \
+         "add $"#N",%%ecx;"        \
+         "setcb C_FLAG;"           \
+         "setob V_FLAG;"
+  #define ADD_RD_RS_O3_0(N)        \
+         "movb $0,C_FLAG;"         \
+         "add $0,%%ecx;"           \
+         "movb $0,V_FLAG;"
+  #define SUB_RD_RS_RN(N) \
+         "sub (reg+"#N"*4),%%ecx;" \
+         "setncb C_FLAG;"          \
+         "setob V_FLAG;"
+  #define SUB_RD_RS_O3(N) \
+         "sub $"#N",%%ecx;"        \
+         "setncb C_FLAG;"          \
+         "setob V_FLAG;"
+  #define SUB_RD_RS_O3_0(N)        \
+         "movb $1,C_FLAG;"         \
+         "sub $0,%%ecx;"           \
+         "movb $0,V_FLAG;"
+#endif
+#else // !__GNUC__
+  #define ADD_RD_RS_RN(N) \
+   {\
+     __asm mov eax, source\
+     __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
+     __asm add ebx, dword ptr [OFFSET reg+4*N]\
+     __asm mov eax, dest\
+     __asm mov dword ptr [OFFSET reg+4*eax], ebx\
+     __asm sets byte ptr N_FLAG\
+     __asm setz byte ptr Z_FLAG\
+     __asm setc byte ptr C_FLAG\
+     __asm seto byte ptr V_FLAG\
+   }
+  #define ADD_RD_RS_O3(N) \
+   {\
+     __asm mov eax, source\
+     __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
+     __asm add ebx, N\
+     __asm mov eax, dest\
+     __asm mov dword ptr [OFFSET reg+4*eax], ebx\
+     __asm sets byte ptr N_FLAG\
+     __asm setz byte ptr Z_FLAG\
+     __asm setc byte ptr C_FLAG\
+     __asm seto byte ptr V_FLAG\
+   }
+  #define ADD_RD_RS_O3_0 \
+   {\
+     __asm mov eax, source\
+     __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
+     __asm add ebx, 0\
+     __asm mov eax, dest\
+     __asm mov dword ptr [OFFSET reg+4*eax], ebx\
+     __asm sets byte ptr N_FLAG\
+     __asm setz byte ptr Z_FLAG\
+     __asm mov byte ptr C_FLAG, 0\
+     __asm mov byte ptr V_FLAG, 0\
+   }
+  #define ADD_RN_O8(d) \
+   {\
+     __asm mov ebx, opcode\
+     __asm and ebx, 255\
+     __asm add dword ptr [OFFSET reg+4*(d)], ebx\
+     __asm sets byte ptr N_FLAG\
+     __asm setz byte ptr Z_FLAG\
+     __asm setc byte ptr C_FLAG\
+     __asm seto byte ptr V_FLAG\
+   }
+  #define CMN_RD_RS \
+     {\
+       __asm mov eax, dest\
+       __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
+       __asm add ebx, value\
+       __asm sets byte ptr N_FLAG\
+       __asm setz byte ptr Z_FLAG\
+       __asm setc byte ptr C_FLAG\
+       __asm seto byte ptr V_FLAG\
+     }
+  #define ADC_RD_RS \
+     {\
+       __asm mov ebx, dest\
+       __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
+       __asm bt word ptr C_FLAG, 0\
+       __asm adc ebx, value\
+       __asm mov eax, dest\
+       __asm mov dword ptr [OFFSET reg+4*eax], ebx\
+       __asm sets byte ptr N_FLAG\
+       __asm setz byte ptr Z_FLAG\
+       __asm setc byte ptr C_FLAG\
+       __asm seto byte ptr V_FLAG\
+     }
+  #define SUB_RD_RS_RN(N) \
+   {\
+     __asm mov eax, source\
+     __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
+     __asm sub ebx, dword ptr [OFFSET reg+4*N]\
+     __asm mov eax, dest\
+     __asm mov dword ptr [OFFSET reg+4*eax], ebx\
+     __asm sets byte ptr N_FLAG\
+     __asm setz byte ptr Z_FLAG\
+     __asm setnc byte ptr C_FLAG\
+     __asm seto byte ptr V_FLAG\
+   }
+  #define SUB_RD_RS_O3(N) \
+   {\
+     __asm mov eax, source\
+     __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
+     __asm sub ebx, N\
+     __asm mov eax, dest\
+     __asm mov dword ptr [OFFSET reg+4*eax], ebx\
+     __asm sets byte ptr N_FLAG\
+     __asm setz byte ptr Z_FLAG\
+     __asm setnc byte ptr C_FLAG\
+     __asm seto byte ptr V_FLAG\
+   }
+  #define SUB_RD_RS_O3_0 \
+   {\
+     __asm mov eax, source\
+     __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
+     __asm sub ebx, 0\
+     __asm mov eax, dest\
+     __asm mov dword ptr [OFFSET reg+4*eax], ebx\
+     __asm sets byte ptr N_FLAG\
+     __asm setz byte ptr Z_FLAG\
+     __asm mov byte ptr C_FLAG, 1\
+     __asm mov byte ptr V_FLAG, 0\
+   }
+  #define SUB_RN_O8(d) \
+   {\
+     __asm mov ebx, opcode\
+     __asm and ebx, 255\
+     __asm sub dword ptr [OFFSET reg + 4*(d)], ebx\
+     __asm sets byte ptr N_FLAG\
+     __asm setz byte ptr Z_FLAG\
+     __asm setnc byte ptr C_FLAG\
+     __asm seto byte ptr V_FLAG\
+   }
+  #define MOV_RN_O8(d) \
+   {\
+     __asm mov eax, opcode\
+     __asm and eax, 255\
+     __asm mov dword ptr [OFFSET reg+4*(d)], eax\
+     __asm sets byte ptr N_FLAG\
+     __asm setz byte ptr Z_FLAG\
+   }
+  #define CMP_RN_O8(d) \
+   {\
+     __asm mov eax, dword ptr [OFFSET reg+4*(d)]\
+     __asm mov ebx, opcode\
+     __asm and ebx, 255\
+     __asm sub eax, ebx\
+     __asm sets byte ptr N_FLAG\
+     __asm setz byte ptr Z_FLAG\
+     __asm setnc byte ptr C_FLAG\
+     __asm seto byte ptr V_FLAG\
+   }
+  #define SBC_RD_RS \
+     {\
+       __asm mov ebx, dest\
+       __asm mov ebx, dword ptr [OFFSET reg + 4*ebx]\
+       __asm mov eax, value\
+       __asm bt word ptr C_FLAG, 0\
+       __asm cmc\
+       __asm sbb ebx, eax\
+       __asm mov eax, dest\
+       __asm mov dword ptr [OFFSET reg + 4*eax], ebx\
+       __asm sets byte ptr N_FLAG\
+       __asm setz byte ptr Z_FLAG\
+       __asm setnc byte ptr C_FLAG\
+       __asm seto byte ptr V_FLAG\
+     }
+  #define LSL_RD_RM_I5 \
+     {\
+       __asm mov eax, source\
+       __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
+       __asm mov cl, byte ptr shift\
+       __asm shl eax, cl\
+       __asm mov value, eax\
+       __asm setc byte ptr C_FLAG\
+     }
+  #define LSL_RD_RS \
+         {\
+           __asm mov eax, dest\
+           __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
+           __asm mov cl, byte ptr value\
+           __asm shl eax, cl\
+           __asm mov value, eax\
+           __asm setc byte ptr C_FLAG\
+         }
+  #define LSR_RD_RM_I5 \
+     {\
+       __asm mov eax, source\
+       __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
+       __asm mov cl, byte ptr shift\
+       __asm shr eax, cl\
+       __asm mov value, eax\
+       __asm setc byte ptr C_FLAG\
+     }
+  #define LSR_RD_RS \
+         {\
+           __asm mov eax, dest\
+           __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
+           __asm mov cl, byte ptr value\
+           __asm shr eax, cl\
+           __asm mov value, eax\
+           __asm setc byte ptr C_FLAG\
+         }
+  #define ASR_RD_RM_I5 \
+     {\
+       __asm mov eax, source\
+       __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
+       __asm mov cl, byte ptr shift\
+       __asm sar eax, cl\
+       __asm mov value, eax\
+       __asm setc byte ptr C_FLAG\
+     }
+  #define ASR_RD_RS \
+         {\
+           __asm mov eax, dest\
+           __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
+           __asm mov cl, byte ptr value\
+           __asm sar eax, cl\
+           __asm mov value, eax\
+           __asm setc byte ptr C_FLAG\
+         }
+  #define ROR_RD_RS \
+         {\
+           __asm mov eax, dest\
+           __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
+           __asm mov cl, byte ptr value\
+           __asm ror eax, cl\
+           __asm mov value, eax\
+           __asm setc byte ptr C_FLAG\
+         }
+  #define NEG_RD_RS \
+     {\
+       __asm mov ebx, source\
+       __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
+       __asm neg ebx\
+       __asm mov eax, dest\
+       __asm mov dword ptr [OFFSET reg+4*eax],ebx\
+       __asm sets byte ptr N_FLAG\
+       __asm setz byte ptr Z_FLAG\
+       __asm setnc byte ptr C_FLAG\
+       __asm seto byte ptr V_FLAG\
+     }
+  #define CMP_RD_RS \
+     {\
+       __asm mov eax, dest\
+       __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
+       __asm sub ebx, value\
+       __asm sets byte ptr N_FLAG\
+       __asm setz byte ptr Z_FLAG\
+       __asm setnc byte ptr C_FLAG\
+       __asm seto byte ptr V_FLAG\
+     }
+#endif
+#endif
+
+// C core
+#ifndef ADDCARRY
+ #define ADDCARRY(a, b, c) \
+  C_FLAG = ((NEG(a) & NEG(b)) |\
+            (NEG(a) & POS(c)) |\
+            (NEG(b) & POS(c))) ? true : false;
+#endif
+#ifndef ADDOVERFLOW
+ #define ADDOVERFLOW(a, b, c) \
+  V_FLAG = ((NEG(a) & NEG(b) & POS(c)) |\
+            (POS(a) & POS(b) & NEG(c))) ? true : false;
+#endif
+#ifndef SUBCARRY
+ #define SUBCARRY(a, b, c) \
+  C_FLAG = ((NEG(a) & POS(b)) |\
+            (NEG(a) & POS(c)) |\
+            (POS(b) & POS(c))) ? true : false;
+#endif
+#ifndef SUBOVERFLOW
+ #define SUBOVERFLOW(a, b, c)\
+  V_FLAG = ((NEG(a) & POS(b) & POS(c)) |\
+            (POS(a) & NEG(b) & NEG(c))) ? true : false;
+#endif
+#ifndef ADD_RD_RS_RN
+ #define ADD_RD_RS_RN(N) \
+   {\
+     u32 lhs = reg[source].I;\
+     u32 rhs = reg[N].I;\
+     u32 res = lhs + rhs;\
+     reg[dest].I = res;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     ADDCARRY(lhs, rhs, res);\
+     ADDOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef ADD_RD_RS_O3
+ #define ADD_RD_RS_O3(N) \
+   {\
+     u32 lhs = reg[source].I;\
+     u32 rhs = N;\
+     u32 res = lhs + rhs;\
+     reg[dest].I = res;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     ADDCARRY(lhs, rhs, res);\
+     ADDOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef ADD_RD_RS_O3_0
+# define ADD_RD_RS_O3_0 ADD_RD_RS_O3
+#endif
+#ifndef ADD_RN_O8
+ #define ADD_RN_O8(d) \
+   {\
+     u32 lhs = reg[(d)].I;\
+     u32 rhs = (opcode & 255);\
+     u32 res = lhs + rhs;\
+     reg[(d)].I = res;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     ADDCARRY(lhs, rhs, res);\
+     ADDOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef CMN_RD_RS
+ #define CMN_RD_RS \
+   {\
+     u32 lhs = reg[dest].I;\
+     u32 rhs = value;\
+     u32 res = lhs + rhs;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     ADDCARRY(lhs, rhs, res);\
+     ADDOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef ADC_RD_RS
+ #define ADC_RD_RS \
+   {\
+     u32 lhs = reg[dest].I;\
+     u32 rhs = value;\
+     u32 res = lhs + rhs + (u32)C_FLAG;\
+     reg[dest].I = res;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     ADDCARRY(lhs, rhs, res);\
+     ADDOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef SUB_RD_RS_RN
+ #define SUB_RD_RS_RN(N) \
+   {\
+     u32 lhs = reg[source].I;\
+     u32 rhs = reg[N].I;\
+     u32 res = lhs - rhs;\
+     reg[dest].I = res;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     SUBCARRY(lhs, rhs, res);\
+     SUBOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef SUB_RD_RS_O3
+ #define SUB_RD_RS_O3(N) \
+   {\
+     u32 lhs = reg[source].I;\
+     u32 rhs = N;\
+     u32 res = lhs - rhs;\
+     reg[dest].I = res;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     SUBCARRY(lhs, rhs, res);\
+     SUBOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef SUB_RD_RS_O3_0
+# define SUB_RD_RS_O3_0 SUB_RD_RS_O3
+#endif
+#ifndef SUB_RN_O8
+ #define SUB_RN_O8(d) \
+   {\
+     u32 lhs = reg[(d)].I;\
+     u32 rhs = (opcode & 255);\
+     u32 res = lhs - rhs;\
+     reg[(d)].I = res;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     SUBCARRY(lhs, rhs, res);\
+     SUBOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef MOV_RN_O8
+ #define MOV_RN_O8(d) \
+   {\
+     reg[d].I = opcode & 255;\
+     N_FLAG = false;\
+     Z_FLAG = (reg[d].I ? false : true);\
+   }
+#endif
+#ifndef CMP_RN_O8
+ #define CMP_RN_O8(d) \
+   {\
+     u32 lhs = reg[(d)].I;\
+     u32 rhs = (opcode & 255);\
+     u32 res = lhs - rhs;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     SUBCARRY(lhs, rhs, res);\
+     SUBOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef SBC_RD_RS
+ #define SBC_RD_RS \
+   {\
+     u32 lhs = reg[dest].I;\
+     u32 rhs = value;\
+     u32 res = lhs - rhs - !((u32)C_FLAG);\
+     reg[dest].I = res;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     SUBCARRY(lhs, rhs, res);\
+     SUBOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef LSL_RD_RM_I5
+ #define LSL_RD_RM_I5 \
+   {\
+     C_FLAG = (reg[source].I >> (32 - shift)) & 1 ? true : false;\
+     value = reg[source].I << shift;\
+   }
+#endif
+#ifndef LSL_RD_RS
+ #define LSL_RD_RS \
+   {\
+     C_FLAG = (reg[dest].I >> (32 - value)) & 1 ? true : false;\
+     value = reg[dest].I << value;\
+   }
+#endif
+#ifndef LSR_RD_RM_I5
+ #define LSR_RD_RM_I5 \
+   {\
+     C_FLAG = (reg[source].I >> (shift - 1)) & 1 ? true : false;\
+     value = reg[source].I >> shift;\
+   }
+#endif
+#ifndef LSR_RD_RS
+ #define LSR_RD_RS \
+   {\
+     C_FLAG = (reg[dest].I >> (value - 1)) & 1 ? true : false;\
+     value = reg[dest].I >> value;\
+   }
+#endif
+#ifndef ASR_RD_RM_I5
+ #define ASR_RD_RM_I5 \
+   {\
+     C_FLAG = ((s32)reg[source].I >> (int)(shift - 1)) & 1 ? true : false;\
+     value = (s32)reg[source].I >> (int)shift;\
+   }
+#endif
+#ifndef ASR_RD_RS
+ #define ASR_RD_RS \
+   {\
+     C_FLAG = ((s32)reg[dest].I >> (int)(value - 1)) & 1 ? true : false;\
+     value = (s32)reg[dest].I >> (int)value;\
+   }
+#endif
+#ifndef ROR_RD_RS
+ #define ROR_RD_RS \
+   {\
+     C_FLAG = (reg[dest].I >> (value - 1)) & 1 ? true : false;\
+     value = ((reg[dest].I << (32 - value)) |\
+              (reg[dest].I >> value));\
+   }
+#endif
+#ifndef NEG_RD_RS
+ #define NEG_RD_RS \
+   {\
+     u32 lhs = reg[source].I;\
+     u32 rhs = 0;\
+     u32 res = rhs - lhs;\
+     reg[dest].I = res;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     SUBCARRY(rhs, lhs, res);\
+     SUBOVERFLOW(rhs, lhs, res);\
+   }
+#endif
+#ifndef CMP_RD_RS
+ #define CMP_RD_RS \
+   {\
+     u32 lhs = reg[dest].I;\
+     u32 rhs = value;\
+     u32 res = lhs - rhs;\
+     Z_FLAG = (res == 0) ? true : false;\
+     N_FLAG = NEG(res) ? true : false;\
+     SUBCARRY(lhs, rhs, res);\
+     SUBOVERFLOW(lhs, rhs, res);\
+   }
+#endif
+#ifndef IMM5_INSN
+ #define IMM5_INSN(OP,N) \
+  int dest = opcode & 0x07;\
+  int source = (opcode >> 3) & 0x07;\
+  u32 value;\
+  OP(N);\
+  reg[dest].I = value;\
+  N_FLAG = (value & 0x80000000 ? true : false);\
+  Z_FLAG = (value ? false : true);
+ #define IMM5_INSN_0(OP) \
+  int dest = opcode & 0x07;\
+  int source = (opcode >> 3) & 0x07;\
+  u32 value;\
+  OP;\
+  reg[dest].I = value;\
+  N_FLAG = (value & 0x80000000 ? true : false);\
+  Z_FLAG = (value ? false : true);
+ #define IMM5_LSL(N) \
+  int shift = N;\
+  LSL_RD_RM_I5;
+ #define IMM5_LSL_0 \
+  value = reg[source].I;
+ #define IMM5_LSR(N) \
+  int shift = N;\
+  LSR_RD_RM_I5;
+ #define IMM5_LSR_0 \
+  C_FLAG = reg[source].I & 0x80000000 ? true : false;\
+  value = 0;
+ #define IMM5_ASR(N) \
+  int shift = N;\
+  ASR_RD_RM_I5;
+ #define IMM5_ASR_0 \
+  if(reg[source].I & 0x80000000) {\
+    value = 0xFFFFFFFF;\
+    C_FLAG = true;\
+  } else {\
+    value = 0;\
+    C_FLAG = false;\
+  }
+#endif
+#ifndef THREEARG_INSN
+ #define THREEARG_INSN(OP,N) \
+  int dest = opcode & 0x07;          \
+  int source = (opcode >> 3) & 0x07; \
+  OP(N);
+#endif
+
+// Shift instructions /////////////////////////////////////////////////////
+
+#define DEFINE_IMM5_INSN(OP,BASE) \
+  static INSN_REGPARM void thumb##BASE##_00(u32 opcode) { IMM5_INSN_0(OP##_0); } \
+  static INSN_REGPARM void thumb##BASE##_01(u32 opcode) { IMM5_INSN(OP, 1); } \
+  static INSN_REGPARM void thumb##BASE##_02(u32 opcode) { IMM5_INSN(OP, 2); } \
+  static INSN_REGPARM void thumb##BASE##_03(u32 opcode) { IMM5_INSN(OP, 3); } \
+  static INSN_REGPARM void thumb##BASE##_04(u32 opcode) { IMM5_INSN(OP, 4); } \
+  static INSN_REGPARM void thumb##BASE##_05(u32 opcode) { IMM5_INSN(OP, 5); } \
+  static INSN_REGPARM void thumb##BASE##_06(u32 opcode) { IMM5_INSN(OP, 6); } \
+  static INSN_REGPARM void thumb##BASE##_07(u32 opcode) { IMM5_INSN(OP, 7); } \
+  static INSN_REGPARM void thumb##BASE##_08(u32 opcode) { IMM5_INSN(OP, 8); } \
+  static INSN_REGPARM void thumb##BASE##_09(u32 opcode) { IMM5_INSN(OP, 9); } \
+  static INSN_REGPARM void thumb##BASE##_0A(u32 opcode) { IMM5_INSN(OP,10); } \
+  static INSN_REGPARM void thumb##BASE##_0B(u32 opcode) { IMM5_INSN(OP,11); } \
+  static INSN_REGPARM void thumb##BASE##_0C(u32 opcode) { IMM5_INSN(OP,12); } \
+  static INSN_REGPARM void thumb##BASE##_0D(u32 opcode) { IMM5_INSN(OP,13); } \
+  static INSN_REGPARM void thumb##BASE##_0E(u32 opcode) { IMM5_INSN(OP,14); } \
+  static INSN_REGPARM void thumb##BASE##_0F(u32 opcode) { IMM5_INSN(OP,15); } \
+  static INSN_REGPARM void thumb##BASE##_10(u32 opcode) { IMM5_INSN(OP,16); } \
+  static INSN_REGPARM void thumb##BASE##_11(u32 opcode) { IMM5_INSN(OP,17); } \
+  static INSN_REGPARM void thumb##BASE##_12(u32 opcode) { IMM5_INSN(OP,18); } \
+  static INSN_REGPARM void thumb##BASE##_13(u32 opcode) { IMM5_INSN(OP,19); } \
+  static INSN_REGPARM void thumb##BASE##_14(u32 opcode) { IMM5_INSN(OP,20); } \
+  static INSN_REGPARM void thumb##BASE##_15(u32 opcode) { IMM5_INSN(OP,21); } \
+  static INSN_REGPARM void thumb##BASE##_16(u32 opcode) { IMM5_INSN(OP,22); } \
+  static INSN_REGPARM void thumb##BASE##_17(u32 opcode) { IMM5_INSN(OP,23); } \
+  static INSN_REGPARM void thumb##BASE##_18(u32 opcode) { IMM5_INSN(OP,24); } \
+  static INSN_REGPARM void thumb##BASE##_19(u32 opcode) { IMM5_INSN(OP,25); } \
+  static INSN_REGPARM void thumb##BASE##_1A(u32 opcode) { IMM5_INSN(OP,26); } \
+  static INSN_REGPARM void thumb##BASE##_1B(u32 opcode) { IMM5_INSN(OP,27); } \
+  static INSN_REGPARM void thumb##BASE##_1C(u32 opcode) { IMM5_INSN(OP,28); } \
+  static INSN_REGPARM void thumb##BASE##_1D(u32 opcode) { IMM5_INSN(OP,29); } \
+  static INSN_REGPARM void thumb##BASE##_1E(u32 opcode) { IMM5_INSN(OP,30); } \
+  static INSN_REGPARM void thumb##BASE##_1F(u32 opcode) { IMM5_INSN(OP,31); }
+
+// LSL Rd, Rm, #Imm 5
+DEFINE_IMM5_INSN(IMM5_LSL,00)
+// LSR Rd, Rm, #Imm 5
+DEFINE_IMM5_INSN(IMM5_LSR,08)
+// ASR Rd, Rm, #Imm 5
+DEFINE_IMM5_INSN(IMM5_ASR,10)
+
+// 3-argument ADD/SUB /////////////////////////////////////////////////////
+
+#define DEFINE_REG3_INSN(OP,BASE) \
+  static INSN_REGPARM void thumb##BASE##_0(u32 opcode) { THREEARG_INSN(OP,0); } \
+  static INSN_REGPARM void thumb##BASE##_1(u32 opcode) { THREEARG_INSN(OP,1); } \
+  static INSN_REGPARM void thumb##BASE##_2(u32 opcode) { THREEARG_INSN(OP,2); } \
+  static INSN_REGPARM void thumb##BASE##_3(u32 opcode) { THREEARG_INSN(OP,3); } \
+  static INSN_REGPARM void thumb##BASE##_4(u32 opcode) { THREEARG_INSN(OP,4); } \
+  static INSN_REGPARM void thumb##BASE##_5(u32 opcode) { THREEARG_INSN(OP,5); } \
+  static INSN_REGPARM void thumb##BASE##_6(u32 opcode) { THREEARG_INSN(OP,6); } \
+  static INSN_REGPARM void thumb##BASE##_7(u32 opcode) { THREEARG_INSN(OP,7); }
+
+#define DEFINE_IMM3_INSN(OP,BASE) \
+  static INSN_REGPARM void thumb##BASE##_0(u32 opcode) { THREEARG_INSN(OP##_0,0); } \
+  static INSN_REGPARM void thumb##BASE##_1(u32 opcode) { THREEARG_INSN(OP,1); } \
+  static INSN_REGPARM void thumb##BASE##_2(u32 opcode) { THREEARG_INSN(OP,2); } \
+  static INSN_REGPARM void thumb##BASE##_3(u32 opcode) { THREEARG_INSN(OP,3); } \
+  static INSN_REGPARM void thumb##BASE##_4(u32 opcode) { THREEARG_INSN(OP,4); } \
+  static INSN_REGPARM void thumb##BASE##_5(u32 opcode) { THREEARG_INSN(OP,5); } \
+  static INSN_REGPARM void thumb##BASE##_6(u32 opcode) { THREEARG_INSN(OP,6); } \
+  static INSN_REGPARM void thumb##BASE##_7(u32 opcode) { THREEARG_INSN(OP,7); }
+
+// ADD Rd, Rs, Rn
+DEFINE_REG3_INSN(ADD_RD_RS_RN,18)
+// SUB Rd, Rs, Rn
+DEFINE_REG3_INSN(SUB_RD_RS_RN,1A)
+// ADD Rd, Rs, #Offset3
+DEFINE_IMM3_INSN(ADD_RD_RS_O3,1C)
+// SUB Rd, Rs, #Offset3
+DEFINE_IMM3_INSN(SUB_RD_RS_O3,1E)
+
+// MOV/CMP/ADD/SUB immediate //////////////////////////////////////////////
+
+// MOV R0, #Offset8
+static INSN_REGPARM void thumb20(u32 opcode) { MOV_RN_O8(0); }
+// MOV R1, #Offset8
+static INSN_REGPARM void thumb21(u32 opcode) { MOV_RN_O8(1); }
+// MOV R2, #Offset8
+static INSN_REGPARM void thumb22(u32 opcode) { MOV_RN_O8(2); }
+// MOV R3, #Offset8
+static INSN_REGPARM void thumb23(u32 opcode) { MOV_RN_O8(3); }
+// MOV R4, #Offset8
+static INSN_REGPARM void thumb24(u32 opcode) { MOV_RN_O8(4); }
+// MOV R5, #Offset8
+static INSN_REGPARM void thumb25(u32 opcode) { MOV_RN_O8(5); }
+// MOV R6, #Offset8
+static INSN_REGPARM void thumb26(u32 opcode) { MOV_RN_O8(6); }
+// MOV R7, #Offset8
+static INSN_REGPARM void thumb27(u32 opcode) { MOV_RN_O8(7); }
+
+// CMP R0, #Offset8
+static INSN_REGPARM void thumb28(u32 opcode) { CMP_RN_O8(0); }
+// CMP R1, #Offset8
+static INSN_REGPARM void thumb29(u32 opcode) { CMP_RN_O8(1); }
+// CMP R2, #Offset8
+static INSN_REGPARM void thumb2A(u32 opcode) { CMP_RN_O8(2); }
+// CMP R3, #Offset8
+static INSN_REGPARM void thumb2B(u32 opcode) { CMP_RN_O8(3); }
+// CMP R4, #Offset8
+static INSN_REGPARM void thumb2C(u32 opcode) { CMP_RN_O8(4); }
+// CMP R5, #Offset8
+static INSN_REGPARM void thumb2D(u32 opcode) { CMP_RN_O8(5); }
+// CMP R6, #Offset8
+static INSN_REGPARM void thumb2E(u32 opcode) { CMP_RN_O8(6); }
+// CMP R7, #Offset8
+static INSN_REGPARM void thumb2F(u32 opcode) { CMP_RN_O8(7); }
+
+// ADD R0,#Offset8
+static INSN_REGPARM void thumb30(u32 opcode) { ADD_RN_O8(0); }
+// ADD R1,#Offset8
+static INSN_REGPARM void thumb31(u32 opcode) { ADD_RN_O8(1); }
+// ADD R2,#Offset8
+static INSN_REGPARM void thumb32(u32 opcode) { ADD_RN_O8(2); }
+// ADD R3,#Offset8
+static INSN_REGPARM void thumb33(u32 opcode) { ADD_RN_O8(3); }
+// ADD R4,#Offset8
+static INSN_REGPARM void thumb34(u32 opcode) { ADD_RN_O8(4); }
+// ADD R5,#Offset8
+static INSN_REGPARM void thumb35(u32 opcode) { ADD_RN_O8(5); }
+// ADD R6,#Offset8
+static INSN_REGPARM void thumb36(u32 opcode) { ADD_RN_O8(6); }
+// ADD R7,#Offset8
+static INSN_REGPARM void thumb37(u32 opcode) { ADD_RN_O8(7); }
+
+// SUB R0,#Offset8
+static INSN_REGPARM void thumb38(u32 opcode) { SUB_RN_O8(0); }
+// SUB R1,#Offset8
+static INSN_REGPARM void thumb39(u32 opcode) { SUB_RN_O8(1); }
+// SUB R2,#Offset8
+static INSN_REGPARM void thumb3A(u32 opcode) { SUB_RN_O8(2); }
+// SUB R3,#Offset8
+static INSN_REGPARM void thumb3B(u32 opcode) { SUB_RN_O8(3); }
+// SUB R4,#Offset8
+static INSN_REGPARM void thumb3C(u32 opcode) { SUB_RN_O8(4); }
+// SUB R5,#Offset8
+static INSN_REGPARM void thumb3D(u32 opcode) { SUB_RN_O8(5); }
+// SUB R6,#Offset8
+static INSN_REGPARM void thumb3E(u32 opcode) { SUB_RN_O8(6); }
+// SUB R7,#Offset8
+static INSN_REGPARM void thumb3F(u32 opcode) { SUB_RN_O8(7); }
+
+// ALU operations /////////////////////////////////////////////////////////
+
+// AND Rd, Rs
+static INSN_REGPARM void thumb40_0(u32 opcode)
+{
+  int dest = opcode & 7;
+  reg[dest].I &= reg[(opcode >> 3)&7].I;
+  N_FLAG = reg[dest].I & 0x80000000 ? true : false;
+  Z_FLAG = reg[dest].I ? false : true;
+  THUMB_CONSOLE_OUTPUT(NULL, reg[2].I);
+}
+
+// EOR Rd, Rs
+static INSN_REGPARM void thumb40_1(u32 opcode)
+{
+  int dest = opcode & 7;
+  reg[dest].I ^= reg[(opcode >> 3)&7].I;
+  N_FLAG = reg[dest].I & 0x80000000 ? true : false;
+  Z_FLAG = reg[dest].I ? false : true;
+}
+
+// LSL Rd, Rs
+static INSN_REGPARM void thumb40_2(u32 opcode)
+{
+  int dest = opcode & 7;
+  u32 value = reg[(opcode >> 3)&7].B.B0;
+  if(value) {
+    if(value == 32) {
+      value = 0;
+      C_FLAG = (reg[dest].I & 1 ? true : false);
+    } else if(value < 32) {
+      LSL_RD_RS;
+    } else {
+      value = 0;
+      C_FLAG = false;
+    }
+    reg[dest].I = value;
+  }
+  N_FLAG = reg[dest].I & 0x80000000 ? true : false;
+  Z_FLAG = reg[dest].I ? false : true;
+  clockTicks = codeTicksAccess16(armNextPC)+2;
+}
+
+// LSR Rd, Rs
+static INSN_REGPARM void thumb40_3(u32 opcode)
+{
+  int dest = opcode & 7;
+  u32 value = reg[(opcode >> 3)&7].B.B0;
+  if(value) {
+    if(value == 32) {
+      value = 0;
+      C_FLAG = (reg[dest].I & 0x80000000 ? true : false);
+    } else if(value < 32) {
+      LSR_RD_RS;
+    } else {
+      value = 0;
+      C_FLAG = false;
+    }
+    reg[dest].I = value;
+  }
+  N_FLAG = reg[dest].I & 0x80000000 ? true : false;
+  Z_FLAG = reg[dest].I ? false : true;
+  clockTicks = codeTicksAccess16(armNextPC)+2;
+}
+
+// ASR Rd, Rs
+static INSN_REGPARM void thumb41_0(u32 opcode)
+{
+  int dest = opcode & 7;
+  u32 value = reg[(opcode >> 3)&7].B.B0;
+  if(value) {
+    if(value < 32) {
+      ASR_RD_RS;
+      reg[dest].I = value;
+    } else {
+      if(reg[dest].I & 0x80000000){
+        reg[dest].I = 0xFFFFFFFF;
+        C_FLAG = true;
+      } else {
+        reg[dest].I = 0x00000000;
+        C_FLAG = false;
+      }
+    }
+  }
+  N_FLAG = reg[dest].I & 0x80000000 ? true : false;
+  Z_FLAG = reg[dest].I ? false : true;
+  clockTicks = codeTicksAccess16(armNextPC)+2;
+}
+
+// ADC Rd, Rs
+static INSN_REGPARM void thumb41_1(u32 opcode)
+{
+  int dest = opcode & 0x07;
+  u32 value = reg[(opcode >> 3)&7].I;
+  ADC_RD_RS;
+}
+
+// SBC Rd, Rs
+static INSN_REGPARM void thumb41_2(u32 opcode)
+{
+  int dest = opcode & 0x07;
+  u32 value = reg[(opcode >> 3)&7].I;
+  SBC_RD_RS;
+}
+
+// ROR Rd, Rs
+static INSN_REGPARM void thumb41_3(u32 opcode)
+{
+  int dest = opcode & 7;
+  u32 value = reg[(opcode >> 3)&7].B.B0;
+
+  if(value) {
+    value = value & 0x1f;
+    if(value == 0) {
+      C_FLAG = (reg[dest].I & 0x80000000 ? true : false);
+    } else {
+      ROR_RD_RS;
+      reg[dest].I = value;
+    }
+  }
+  clockTicks = codeTicksAccess16(armNextPC)+2;
+  N_FLAG = reg[dest].I & 0x80000000 ? true : false;
+  Z_FLAG = reg[dest].I ? false : true;
+}
+
+// TST Rd, Rs
+static INSN_REGPARM void thumb42_0(u32 opcode)
+{
+  u32 value = reg[opcode & 7].I & reg[(opcode >> 3) & 7].I;
+  N_FLAG = value & 0x80000000 ? true : false;
+  Z_FLAG = value ? false : true;
+}
+
+// NEG Rd, Rs
+static INSN_REGPARM void thumb42_1(u32 opcode)
+{
+  int dest = opcode & 7;
+  int source = (opcode >> 3) & 7;
+  NEG_RD_RS;
+}
+
+// CMP Rd, Rs
+static INSN_REGPARM void thumb42_2(u32 opcode)
+{
+  int dest = opcode & 7;
+  u32 value = reg[(opcode >> 3)&7].I;
+  CMP_RD_RS;
+}
+
+// CMN Rd, Rs
+static INSN_REGPARM void thumb42_3(u32 opcode)
+{
+  int dest = opcode & 7;
+  u32 value = reg[(opcode >> 3)&7].I;
+  CMN_RD_RS;
+}
+
+// ORR Rd, Rs
+static INSN_REGPARM void thumb43_0(u32 opcode)
+{
+  int dest = opcode & 7;
+  reg[dest].I |= reg[(opcode >> 3) & 7].I;
+  Z_FLAG = reg[dest].I ? false : true;
+  N_FLAG = reg[dest].I & 0x80000000 ? true : false;
+}
+
+// MUL Rd, Rs
+static INSN_REGPARM void thumb43_1(u32 opcode)
+{
+  clockTicks = 1;
+  int dest = opcode & 7;
+  u32 rm = reg[dest].I;
+  reg[dest].I = reg[(opcode >> 3) & 7].I * rm;
+  if (((s32)rm) < 0)
+    rm = ~rm;
+  if ((rm & 0xFFFFFF00) == 0)
+    clockTicks += 0;
+  else if ((rm & 0xFFFF0000) == 0)
+    clockTicks += 1;
+  else if ((rm & 0xFF000000) == 0)
+    clockTicks += 2;
+  else
+    clockTicks += 3;
+  busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
+  clockTicks += codeTicksAccess16(armNextPC) + 1;
+  Z_FLAG = reg[dest].I ? false : true;
+  N_FLAG = reg[dest].I & 0x80000000 ? true : false;
+}
+
+// BIC Rd, Rs
+static INSN_REGPARM void thumb43_2(u32 opcode)
+{
+  int dest = opcode & 7;
+  reg[dest].I &= (~reg[(opcode >> 3) & 7].I);
+  Z_FLAG = reg[dest].I ? false : true;
+  N_FLAG = reg[dest].I & 0x80000000 ? true : false;
+}
+
+// MVN Rd, Rs
+static INSN_REGPARM void thumb43_3(u32 opcode)
+{
+  int dest = opcode & 7;
+  reg[dest].I = ~reg[(opcode >> 3) & 7].I;
+  Z_FLAG = reg[dest].I ? false : true;
+  N_FLAG = reg[dest].I & 0x80000000 ? true : false;
+}
+
+// High-register instructions and BX //////////////////////////////////////
+
+// ADD Rd, Hs
+static INSN_REGPARM void thumb44_1(u32 opcode)
+{
+  reg[opcode&7].I += reg[((opcode>>3)&7)+8].I;
+}
+
+// ADD Hd, Rs
+static INSN_REGPARM void thumb44_2(u32 opcode)
+{
+  reg[(opcode&7)+8].I += reg[(opcode>>3)&7].I;
+  if((opcode&7) == 7) {
+    reg[15].I &= 0xFFFFFFFE;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC)*2
+        + codeTicksAccess16(armNextPC) + 3;
+  }
+}
+
+// ADD Hd, Hs
+static INSN_REGPARM void thumb44_3(u32 opcode)
+{
+  reg[(opcode&7)+8].I += reg[((opcode>>3)&7)+8].I;
+  if((opcode&7) == 7) {
+    reg[15].I &= 0xFFFFFFFE;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC)*2
+        + codeTicksAccess16(armNextPC) + 3;
+  }
+}
+
+// CMP Rd, Hs
+static INSN_REGPARM void thumb45_1(u32 opcode)
+{
+  int dest = opcode & 7;
+  u32 value = reg[((opcode>>3)&7)+8].I;
+  CMP_RD_RS;
+}
+
+// CMP Hd, Rs
+static INSN_REGPARM void thumb45_2(u32 opcode)
+{
+  int dest = (opcode & 7) + 8;
+  u32 value = reg[(opcode>>3)&7].I;
+  CMP_RD_RS;
+}
+
+// CMP Hd, Hs
+static INSN_REGPARM void thumb45_3(u32 opcode)
+{
+  int dest = (opcode & 7) + 8;
+  u32 value = reg[((opcode>>3)&7)+8].I;
+  CMP_RD_RS;
+}
+
+// MOV Rd, Hs
+static INSN_REGPARM void thumb46_1(u32 opcode)
+{
+  reg[opcode&7].I = reg[((opcode>>3)&7)+8].I;
+}
+
+// MOV Hd, Rs
+static INSN_REGPARM void thumb46_2(u32 opcode)
+{
+  reg[(opcode&7)+8].I = reg[(opcode>>3)&7].I;
+  if((opcode&7) == 7) {
+    UPDATE_OLDREG;
+    reg[15].I &= 0xFFFFFFFE;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC)*2
+        + codeTicksAccess16(armNextPC) + 3;
+  }
+}
+
+// MOV Hd, Hs
+static INSN_REGPARM void thumb46_3(u32 opcode)
+{
+  reg[(opcode&7)+8].I = reg[((opcode>>3)&7)+8].I;
+  if((opcode&7) == 7) {
+    UPDATE_OLDREG;
+    reg[15].I &= 0xFFFFFFFE;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC)*2
+        + codeTicksAccess16(armNextPC) + 3;
+  }
+}
+
+
+// BX Rs
+static INSN_REGPARM void thumb47(u32 opcode)
+{
+  int base = (opcode >> 3) & 15;
+  busPrefetchCount=0;
+  UPDATE_OLDREG;
+  reg[15].I = reg[base].I;
+  if(reg[base].I & 1) {
+    armState = false;
+    reg[15].I &= 0xFFFFFFFE;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC)
+        + codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 3;
+  } else {
+    armState = true;
+    reg[15].I &= 0xFFFFFFFC;
+    armNextPC = reg[15].I;
+    reg[15].I += 4;
+    ARM_PREFETCH;
+    clockTicks = codeTicksAccessSeq32(armNextPC)
+        + codeTicksAccessSeq32(armNextPC) + codeTicksAccess32(armNextPC) + 3;
+  }
+}
+
+// Load/store instructions ////////////////////////////////////////////////
+
+// LDR R0~R7,[PC, #Imm]
+static INSN_REGPARM void thumb48(u32 opcode)
+{
+  u8 regist = (opcode >> 8) & 7;
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = (reg[15].I & 0xFFFFFFFC) + ((opcode & 0xFF) << 2);
+  reg[regist].I = CPUReadMemoryQuick(address);
+  busPrefetchCount=0;
+  clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC);
+}
+
+// STR Rd, [Rs, Rn]
+static INSN_REGPARM void thumb50(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
+  CPUWriteMemory(address, reg[opcode & 7].I);
+  clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2;
+}
+
+// STRH Rd, [Rs, Rn]
+static INSN_REGPARM void thumb52(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
+  CPUWriteHalfWord(address, reg[opcode&7].W.W0);
+  clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2;
+}
+
+// STRB Rd, [Rs, Rn]
+static INSN_REGPARM void thumb54(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + reg[(opcode >>6)&7].I;
+  CPUWriteByte(address, reg[opcode & 7].B.B0);
+  clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2;
+}
+
+// LDSB Rd, [Rs, Rn]
+static INSN_REGPARM void thumb56(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
+  reg[opcode&7].I = (s8)CPUReadByte(address);
+  clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC);
+}
+
+// LDR Rd, [Rs, Rn]
+static INSN_REGPARM void thumb58(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
+  reg[opcode&7].I = CPUReadMemory(address);
+  clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC);
+}
+
+// LDRH Rd, [Rs, Rn]
+static INSN_REGPARM void thumb5A(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
+  reg[opcode&7].I = CPUReadHalfWord(address);
+  clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC);
+}
+
+// LDRB Rd, [Rs, Rn]
+static INSN_REGPARM void thumb5C(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
+  reg[opcode&7].I = CPUReadByte(address);
+  clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC);
+}
+
+// LDSH Rd, [Rs, Rn]
+static INSN_REGPARM void thumb5E(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
+  reg[opcode&7].I = (s16)CPUReadHalfWordSigned(address);
+  clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC);
+}
+
+// STR Rd, [Rs, #Imm]
+static INSN_REGPARM void thumb60(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<2);
+  CPUWriteMemory(address, reg[opcode&7].I);
+  clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2;
+}
+
+// LDR Rd, [Rs, #Imm]
+static INSN_REGPARM void thumb68(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<2);
+  reg[opcode&7].I = CPUReadMemory(address);
+  clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC);
+}
+
+// STRB Rd, [Rs, #Imm]
+static INSN_REGPARM void thumb70(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31));
+  CPUWriteByte(address, reg[opcode&7].B.B0);
+  clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2;
+}
+
+// LDRB Rd, [Rs, #Imm]
+static INSN_REGPARM void thumb78(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31));
+  reg[opcode&7].I = CPUReadByte(address);
+  clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC);
+}
+
+// STRH Rd, [Rs, #Imm]
+static INSN_REGPARM void thumb80(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<1);
+  CPUWriteHalfWord(address, reg[opcode&7].W.W0);
+  clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2;
+}
+
+// LDRH Rd, [Rs, #Imm]
+static INSN_REGPARM void thumb88(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<1);
+  reg[opcode&7].I = CPUReadHalfWord(address);
+  clockTicks = 3 + dataTicksAccess16(address) + codeTicksAccess16(armNextPC);
+}
+
+// STR R0~R7, [SP, #Imm]
+static INSN_REGPARM void thumb90(u32 opcode)
+{
+  u8 regist = (opcode >> 8) & 7;
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[13].I + ((opcode&255)<<2);
+  CPUWriteMemory(address, reg[regist].I);
+  clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2;
+}
+
+// LDR R0~R7, [SP, #Imm]
+static INSN_REGPARM void thumb98(u32 opcode)
+{
+  u8 regist = (opcode >> 8) & 7;
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[13].I + ((opcode&255)<<2);
+  reg[regist].I = CPUReadMemoryQuick(address);
+  clockTicks = 3 + dataTicksAccess32(address) + codeTicksAccess16(armNextPC);
+}
+
+// PC/stack-related ///////////////////////////////////////////////////////
+
+// ADD R0~R7, PC, Imm
+static INSN_REGPARM void thumbA0(u32 opcode)
+{
+  u8 regist = (opcode >> 8) & 7;
+  reg[regist].I = (reg[15].I & 0xFFFFFFFC) + ((opcode&255)<<2);
+}
+
+// ADD R0~R7, SP, Imm
+static INSN_REGPARM void thumbA8(u32 opcode)
+{
+  u8 regist = (opcode >> 8) & 7;
+  reg[regist].I = reg[13].I + ((opcode&255)<<2);
+}
+
+// ADD SP, Imm
+static INSN_REGPARM void thumbB0(u32 opcode)
+{
+  int offset = (opcode & 127) << 2;
+  if(opcode & 0x80)
+    offset = -offset;
+  reg[13].I += offset;
+}
+
+// Push and pop ///////////////////////////////////////////////////////////
+
+#define PUSH_REG(val, r)                                    \
+  if (opcode & (val)) {                                     \
+    CPUWriteMemory(address, reg[(r)].I);                    \
+    if (!count) {                                           \
+        clockTicks += 1 + dataTicksAccess32(address);       \
+    } else {                                                \
+        clockTicks += 1 + dataTicksAccessSeq32(address);    \
+    }                                                       \
+    count++;                                                \
+    address += 4;                                           \
+  }
+
+#define POP_REG(val, r)                                     \
+  if (opcode & (val)) {                                     \
+    reg[(r)].I = CPUReadMemory(address);                    \
+    if (!count) {                                           \
+        clockTicks += 1 + dataTicksAccess32(address);       \
+    } else {                                                \
+        clockTicks += 1 + dataTicksAccessSeq32(address);    \
+    }                                                       \
+    count++;                                                \
+    address += 4;                                           \
+  }
+
+// PUSH {Rlist}
+static INSN_REGPARM void thumbB4(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  int count = 0;
+  u32 temp = reg[13].I - 4 * cpuBitsSet[opcode & 0xff];
+  u32 address = temp & 0xFFFFFFFC;
+  PUSH_REG(1, 0);
+  PUSH_REG(2, 1);
+  PUSH_REG(4, 2);
+  PUSH_REG(8, 3);
+  PUSH_REG(16, 4);
+  PUSH_REG(32, 5);
+  PUSH_REG(64, 6);
+  PUSH_REG(128, 7);
+  clockTicks += 1 + codeTicksAccess16(armNextPC);
+  reg[13].I = temp;
+}
+
+// PUSH {Rlist, LR}
+static INSN_REGPARM void thumbB5(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  int count = 0;
+  u32 temp = reg[13].I - 4 - 4 * cpuBitsSet[opcode & 0xff];
+  u32 address = temp & 0xFFFFFFFC;
+  PUSH_REG(1, 0);
+  PUSH_REG(2, 1);
+  PUSH_REG(4, 2);
+  PUSH_REG(8, 3);
+  PUSH_REG(16, 4);
+  PUSH_REG(32, 5);
+  PUSH_REG(64, 6);
+  PUSH_REG(128, 7);
+  PUSH_REG(256, 14);
+  clockTicks += 1 + codeTicksAccess16(armNextPC);
+  reg[13].I = temp;
+}
+
+// POP {Rlist}
+static INSN_REGPARM void thumbBC(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  int count = 0;
+  u32 address = reg[13].I & 0xFFFFFFFC;
+  u32 temp = reg[13].I + 4*cpuBitsSet[opcode & 0xFF];
+  POP_REG(1, 0);
+  POP_REG(2, 1);
+  POP_REG(4, 2);
+  POP_REG(8, 3);
+  POP_REG(16, 4);
+  POP_REG(32, 5);
+  POP_REG(64, 6);
+  POP_REG(128, 7);
+  reg[13].I = temp;
+  clockTicks = 2 + codeTicksAccess16(armNextPC);
+}
+
+// POP {Rlist, PC}
+static INSN_REGPARM void thumbBD(u32 opcode)
+{
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  int count = 0;
+  u32 address = reg[13].I & 0xFFFFFFFC;
+  u32 temp = reg[13].I + 4 + 4*cpuBitsSet[opcode & 0xFF];
+  POP_REG(1, 0);
+  POP_REG(2, 1);
+  POP_REG(4, 2);
+  POP_REG(8, 3);
+  POP_REG(16, 4);
+  POP_REG(32, 5);
+  POP_REG(64, 6);
+  POP_REG(128, 7);
+  reg[15].I = (CPUReadMemory(address) & 0xFFFFFFFE);
+  if (!count) {
+    clockTicks += 1 + dataTicksAccess32(address);
+  } else {
+    clockTicks += 1 + dataTicksAccessSeq32(address);
+  }
+  count++;
+  armNextPC = reg[15].I;
+  reg[15].I += 2;
+  reg[13].I = temp;
+  THUMB_PREFETCH;
+  busPrefetchCount = 0;
+  clockTicks += 3 + codeTicksAccess16(armNextPC) + codeTicksAccess16(armNextPC);
+}
+
+// Load/store multiple ////////////////////////////////////////////////////
+
+#define THUMB_STM_REG(val,r,b)                              \
+  if(opcode & (val)) {                                      \
+    CPUWriteMemory(address, reg[(r)].I);                    \
+    reg[(b)].I = temp;                                      \
+    if (!count) {                                           \
+        clockTicks += 1 + dataTicksAccess32(address);       \
+    } else {                                                \
+        clockTicks += 1 + dataTicksAccessSeq32(address);    \
+    }                                                       \
+    count++;                                                \
+    address += 4;                                           \
+  }
+
+#define THUMB_LDM_REG(val,r)                                \
+  if(opcode & (val)) {                                      \
+    reg[(r)].I = CPUReadMemory(address);                    \
+    if (!count) {                                           \
+        clockTicks += 1 + dataTicksAccess32(address);       \
+    } else {                                                \
+        clockTicks += 1 + dataTicksAccessSeq32(address);    \
+    }                                                       \
+    count++;                                                \
+    address += 4;                                           \
+  }
+
+// STM R0~7!, {Rlist}
+static INSN_REGPARM void thumbC0(u32 opcode)
+{
+  u8 regist = (opcode >> 8) & 7;
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[regist].I & 0xFFFFFFFC;
+  u32 temp = reg[regist].I + 4*cpuBitsSet[opcode & 0xff];
+  int count = 0;
+  // store
+  THUMB_STM_REG(1, 0, regist);
+  THUMB_STM_REG(2, 1, regist);
+  THUMB_STM_REG(4, 2, regist);
+  THUMB_STM_REG(8, 3, regist);
+  THUMB_STM_REG(16, 4, regist);
+  THUMB_STM_REG(32, 5, regist);
+  THUMB_STM_REG(64, 6, regist);
+  THUMB_STM_REG(128, 7, regist);
+  clockTicks = 1 + codeTicksAccess16(armNextPC);
+}
+
+// LDM R0~R7!, {Rlist}
+static INSN_REGPARM void thumbC8(u32 opcode)
+{
+  u8 regist = (opcode >> 8) & 7;
+  if (busPrefetchCount == 0)
+    busPrefetch = busPrefetchEnable;
+  u32 address = reg[regist].I & 0xFFFFFFFC;
+  u32 temp = reg[regist].I + 4*cpuBitsSet[opcode & 0xFF];
+  int count = 0;
+  // load
+  THUMB_LDM_REG(1, 0);
+  THUMB_LDM_REG(2, 1);
+  THUMB_LDM_REG(4, 2);
+  THUMB_LDM_REG(8, 3);
+  THUMB_LDM_REG(16, 4);
+  THUMB_LDM_REG(32, 5);
+  THUMB_LDM_REG(64, 6);
+  THUMB_LDM_REG(128, 7);
+  clockTicks = 2 + codeTicksAccess16(armNextPC);
+  if(!(opcode & (1<<regist)))
+    reg[regist].I = temp;
+}
+
+// Conditional branches ///////////////////////////////////////////////////
+
+// BEQ offset
+static INSN_REGPARM void thumbD0(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(Z_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BNE offset
+static INSN_REGPARM void thumbD1(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(!Z_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BCS offset
+static INSN_REGPARM void thumbD2(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(C_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BCC offset
+static INSN_REGPARM void thumbD3(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(!C_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BMI offset
+static INSN_REGPARM void thumbD4(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(N_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BPL offset
+static INSN_REGPARM void thumbD5(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(!N_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BVS offset
+static INSN_REGPARM void thumbD6(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(V_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BVC offset
+static INSN_REGPARM void thumbD7(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(!V_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BHI offset
+static INSN_REGPARM void thumbD8(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(C_FLAG && !Z_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BLS offset
+static INSN_REGPARM void thumbD9(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(!C_FLAG || Z_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BGE offset
+static INSN_REGPARM void thumbDA(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(N_FLAG == V_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BLT offset
+static INSN_REGPARM void thumbDB(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(N_FLAG != V_FLAG) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BGT offset
+static INSN_REGPARM void thumbDC(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(!Z_FLAG && (N_FLAG == V_FLAG)) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// BLE offset
+static INSN_REGPARM void thumbDD(u32 opcode)
+{
+  UPDATE_OLDREG;
+  if(Z_FLAG || (N_FLAG != V_FLAG)) {
+    reg[15].I += ((s8)(opcode & 0xFF)) << 1;
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH;
+    clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+        codeTicksAccess16(armNextPC)+3;
+    busPrefetchCount=0;
+  }
+}
+
+// SWI, B, BL /////////////////////////////////////////////////////////////
+
+// SWI #comment
+static INSN_REGPARM void thumbDF(u32 opcode)
+{
+  u32 address = 0;
+  clockTicks = codeTicksAccessSeq16(address) + codeTicksAccessSeq16(address) +
+      codeTicksAccess16(address)+3;
+  busPrefetchCount=0;
+  CPUSoftwareInterrupt(opcode & 0xFF);
+}
+
+// B offset
+static INSN_REGPARM void thumbE0(u32 opcode)
+{
+  int offset = (opcode & 0x3FF) << 1;
+  if(opcode & 0x0400)
+    offset |= 0xFFFFF800;
+  reg[15].I += offset;
+  armNextPC = reg[15].I;
+  reg[15].I += 2;
+  THUMB_PREFETCH;
+  clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
+      codeTicksAccess16(armNextPC) + 3;
+  busPrefetchCount=0;
+}
+
+// BLL #offset (forward)
+static INSN_REGPARM void thumbF0(u32 opcode)
+{
+  int offset = (opcode & 0x7FF);
+  reg[14].I = reg[15].I + (offset << 12);
+  clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
+}
+
+// BLL #offset (backward)
+static INSN_REGPARM void thumbF4(u32 opcode)
+{
+  int offset = (opcode & 0x7FF);
+  reg[14].I = reg[15].I + ((offset << 12) | 0xFF800000);
+  clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
+}
+
+// BLH #offset
+static INSN_REGPARM void thumbF8(u32 opcode)
+{
+  int offset = (opcode & 0x7FF);
+  u32 temp = reg[15].I-2;
+  reg[15].I = (reg[14].I + (offset<<1))&0xFFFFFFFE;
+  armNextPC = reg[15].I;
+  reg[15].I += 2;
+  reg[14].I = temp|1;
+  THUMB_PREFETCH;
+  clockTicks = codeTicksAccessSeq16(armNextPC) +
+      codeTicksAccess16(armNextPC) + codeTicksAccessSeq16(armNextPC) + 3;
+  busPrefetchCount = 0;
+}
+
+// Instruction table //////////////////////////////////////////////////////
+
+typedef INSN_REGPARM void (*insnfunc_t)(u32 opcode);
+#define thumbUI thumbUnknownInsn
+#ifdef BKPT_SUPPORT
+ #define thumbBP thumbBreakpoint
+#else
+ #define thumbBP thumbUnknownInsn
+#endif
+static insnfunc_t thumbInsnTable[1024] = {
+  thumb00_00,thumb00_01,thumb00_02,thumb00_03,thumb00_04,thumb00_05,thumb00_06,thumb00_07,  // 00
+  thumb00_08,thumb00_09,thumb00_0A,thumb00_0B,thumb00_0C,thumb00_0D,thumb00_0E,thumb00_0F,
+  thumb00_10,thumb00_11,thumb00_12,thumb00_13,thumb00_14,thumb00_15,thumb00_16,thumb00_17,
+  thumb00_18,thumb00_19,thumb00_1A,thumb00_1B,thumb00_1C,thumb00_1D,thumb00_1E,thumb00_1F,
+  thumb08_00,thumb08_01,thumb08_02,thumb08_03,thumb08_04,thumb08_05,thumb08_06,thumb08_07,  // 08
+  thumb08_08,thumb08_09,thumb08_0A,thumb08_0B,thumb08_0C,thumb08_0D,thumb08_0E,thumb08_0F,
+  thumb08_10,thumb08_11,thumb08_12,thumb08_13,thumb08_14,thumb08_15,thumb08_16,thumb08_17,
+  thumb08_18,thumb08_19,thumb08_1A,thumb08_1B,thumb08_1C,thumb08_1D,thumb08_1E,thumb08_1F,
+  thumb10_00,thumb10_01,thumb10_02,thumb10_03,thumb10_04,thumb10_05,thumb10_06,thumb10_07,  // 10
+  thumb10_08,thumb10_09,thumb10_0A,thumb10_0B,thumb10_0C,thumb10_0D,thumb10_0E,thumb10_0F,
+  thumb10_10,thumb10_11,thumb10_12,thumb10_13,thumb10_14,thumb10_15,thumb10_16,thumb10_17,
+  thumb10_18,thumb10_19,thumb10_1A,thumb10_1B,thumb10_1C,thumb10_1D,thumb10_1E,thumb10_1F,
+  thumb18_0,thumb18_1,thumb18_2,thumb18_3,thumb18_4,thumb18_5,thumb18_6,thumb18_7,          // 18
+  thumb1A_0,thumb1A_1,thumb1A_2,thumb1A_3,thumb1A_4,thumb1A_5,thumb1A_6,thumb1A_7,
+  thumb1C_0,thumb1C_1,thumb1C_2,thumb1C_3,thumb1C_4,thumb1C_5,thumb1C_6,thumb1C_7,
+  thumb1E_0,thumb1E_1,thumb1E_2,thumb1E_3,thumb1E_4,thumb1E_5,thumb1E_6,thumb1E_7,
+  thumb20,thumb20,thumb20,thumb20,thumb21,thumb21,thumb21,thumb21,  // 20
+  thumb22,thumb22,thumb22,thumb22,thumb23,thumb23,thumb23,thumb23,
+  thumb24,thumb24,thumb24,thumb24,thumb25,thumb25,thumb25,thumb25,
+  thumb26,thumb26,thumb26,thumb26,thumb27,thumb27,thumb27,thumb27,
+  thumb28,thumb28,thumb28,thumb28,thumb29,thumb29,thumb29,thumb29,  // 28
+  thumb2A,thumb2A,thumb2A,thumb2A,thumb2B,thumb2B,thumb2B,thumb2B,
+  thumb2C,thumb2C,thumb2C,thumb2C,thumb2D,thumb2D,thumb2D,thumb2D,
+  thumb2E,thumb2E,thumb2E,thumb2E,thumb2F,thumb2F,thumb2F,thumb2F,
+  thumb30,thumb30,thumb30,thumb30,thumb31,thumb31,thumb31,thumb31,  // 30
+  thumb32,thumb32,thumb32,thumb32,thumb33,thumb33,thumb33,thumb33,
+  thumb34,thumb34,thumb34,thumb34,thumb35,thumb35,thumb35,thumb35,
+  thumb36,thumb36,thumb36,thumb36,thumb37,thumb37,thumb37,thumb37,
+  thumb38,thumb38,thumb38,thumb38,thumb39,thumb39,thumb39,thumb39,  // 38
+  thumb3A,thumb3A,thumb3A,thumb3A,thumb3B,thumb3B,thumb3B,thumb3B,
+  thumb3C,thumb3C,thumb3C,thumb3C,thumb3D,thumb3D,thumb3D,thumb3D,
+  thumb3E,thumb3E,thumb3E,thumb3E,thumb3F,thumb3F,thumb3F,thumb3F,
+  thumb40_0,thumb40_1,thumb40_2,thumb40_3,thumb41_0,thumb41_1,thumb41_2,thumb41_3,  // 40
+  thumb42_0,thumb42_1,thumb42_2,thumb42_3,thumb43_0,thumb43_1,thumb43_2,thumb43_3,
+  thumbUI,thumb44_1,thumb44_2,thumb44_3,thumbUI,thumb45_1,thumb45_2,thumb45_3,
+  thumbUI,thumb46_1,thumb46_2,thumb46_3,thumb47,thumb47,thumbUI,thumbUI,
+  thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,  // 48
+  thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,
+  thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,
+  thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,thumb48,
+  thumb50,thumb50,thumb50,thumb50,thumb50,thumb50,thumb50,thumb50,  // 50
+  thumb52,thumb52,thumb52,thumb52,thumb52,thumb52,thumb52,thumb52,
+  thumb54,thumb54,thumb54,thumb54,thumb54,thumb54,thumb54,thumb54,
+  thumb56,thumb56,thumb56,thumb56,thumb56,thumb56,thumb56,thumb56,
+  thumb58,thumb58,thumb58,thumb58,thumb58,thumb58,thumb58,thumb58,  // 58
+  thumb5A,thumb5A,thumb5A,thumb5A,thumb5A,thumb5A,thumb5A,thumb5A,
+  thumb5C,thumb5C,thumb5C,thumb5C,thumb5C,thumb5C,thumb5C,thumb5C,
+  thumb5E,thumb5E,thumb5E,thumb5E,thumb5E,thumb5E,thumb5E,thumb5E,
+  thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,  // 60
+  thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,
+  thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,
+  thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,thumb60,
+  thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,  // 68
+  thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,
+  thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,
+  thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,thumb68,
+  thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,  // 70
+  thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,
+  thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,
+  thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,thumb70,
+  thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,  // 78
+  thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,
+  thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,
+  thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,thumb78,
+  thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,  // 80
+  thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,
+  thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,
+  thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,thumb80,
+  thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,  // 88
+  thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,
+  thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,
+  thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,thumb88,
+  thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,  // 90
+  thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,
+  thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,
+  thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,thumb90,
+  thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,  // 98
+  thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,
+  thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,
+  thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,thumb98,
+  thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,  // A0
+  thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,
+  thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,
+  thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,thumbA0,
+  thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,  // A8
+  thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,
+  thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,
+  thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,thumbA8,
+  thumbB0,thumbB0,thumbB0,thumbB0,thumbUI,thumbUI,thumbUI,thumbUI,  // B0
+  thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,
+  thumbB4,thumbB4,thumbB4,thumbB4,thumbB5,thumbB5,thumbB5,thumbB5,
+  thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,
+  thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,  // B8
+  thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,
+  thumbBC,thumbBC,thumbBC,thumbBC,thumbBD,thumbBD,thumbBD,thumbBD,
+  thumbBP,thumbBP,thumbBP,thumbBP,thumbUI,thumbUI,thumbUI,thumbUI,
+  thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,  // C0
+  thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,
+  thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,
+  thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,thumbC0,
+  thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,  // C8
+  thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,
+  thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,
+  thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,thumbC8,
+  thumbD0,thumbD0,thumbD0,thumbD0,thumbD1,thumbD1,thumbD1,thumbD1,  // D0
+  thumbD2,thumbD2,thumbD2,thumbD2,thumbD3,thumbD3,thumbD3,thumbD3,
+  thumbD4,thumbD4,thumbD4,thumbD4,thumbD5,thumbD5,thumbD5,thumbD5,
+  thumbD6,thumbD6,thumbD6,thumbD6,thumbD7,thumbD7,thumbD7,thumbD7,
+  thumbD8,thumbD8,thumbD8,thumbD8,thumbD9,thumbD9,thumbD9,thumbD9,  // D8
+  thumbDA,thumbDA,thumbDA,thumbDA,thumbDB,thumbDB,thumbDB,thumbDB,
+  thumbDC,thumbDC,thumbDC,thumbDC,thumbDD,thumbDD,thumbDD,thumbDD,
+  thumbUI,thumbUI,thumbUI,thumbUI,thumbDF,thumbDF,thumbDF,thumbDF,
+  thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,  // E0
+  thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,
+  thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,
+  thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,thumbE0,
+  thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,  // E8
+  thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,
+  thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,
+  thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,thumbUI,
+  thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,  // F0
+  thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,thumbF0,
+  thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,
+  thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,thumbF4,
+  thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,  // F8
+  thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,
+  thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,
+  thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,thumbF8,
+};
+
+// Wrapper routine (execution loop) ///////////////////////////////////////
+
+int thumbExecute()
+{
+  do {
+    cpuMasterCodeCheck();
+
+    //if ((armNextPC & 0x0803FFFF) == 0x08020000)
+    //    busPrefetchCount=0x100;
+
+    u32 opcode = cpuPrefetch[0];
+    cpuPrefetch[0] = cpuPrefetch[1];
+
+    busPrefetch = false;
+    if (busPrefetchCount & 0xFFFFFF00)
+      busPrefetchCount = 0x100 | (busPrefetchCount & 0xFF);
+    clockTicks = 0;
+    u32 oldArmNextPC = armNextPC;
+#ifndef FINAL_VERSION
+    if(armNextPC == stop) {
+      armNextPC++;
+    }
+#endif
+
+    armNextPC = reg[15].I;
+    reg[15].I += 2;
+    THUMB_PREFETCH_NEXT;
+
+    (*thumbInsnTable[opcode>>6])(opcode);
+
+    if (clockTicks < 0)
+      return 0;
+    if (clockTicks==0)
+      clockTicks = codeTicksAccessSeq16(oldArmNextPC) + 1;
+    cpuTotalTicks += clockTicks;
+
+  } while (cpuTotalTicks < cpuNextEvent && !armState && !holdState && !SWITicks);
+  return 1;
+}
diff -urN ../VisualBoyAdvance-20061204/src/GBA.cpp src/GBA.cpp
--- ../VisualBoyAdvance-20061204/src/GBA.cpp	2006-08-25 23:13:38 +0900
+++ src/GBA.cpp	2006-12-05 00:18:42 +0900
@@ -23,6 +23,7 @@
 #include <string.h>
 
 #include "GBA.h"
+#include "GBAcpu.h"
 #include "GBAinline.h"
 #include "Globals.h"
 #include "Gfx.h"
@@ -42,29 +43,6 @@
 #include "prof/prof.h"
 #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);
-
 #ifdef __GNUC__
 #define _stricmp strcasecmp
 #endif
@@ -513,210 +491,6 @@
 #endif
 
 
-// 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)<<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)<<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)<<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)<<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];
-  }
-}
-
-
 inline int CPUUpdateTicks()
 {
   int cpuLoopTicks = lcdTicks;
@@ -3127,249 +2901,6 @@
   timerOnOffDelay = 0;
 }
 
-void CPUWriteHalfWord(u32 address, u16 value)
-{
-#ifdef DEV_VERSION
-  if(address & 1) {
-    if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
-      log("Unaligned halfword write: %04x to %08x from %08x\n",
-          value,
-          address,
-          armMode ? armNextPC - 4 : armNextPC - 2);
-    }
-  }
-#endif
-  
-  switch(address >> 24) {
-  case 2:
-#ifdef BKPT_SUPPORT
-    if(*((u16 *)&freezeWorkRAM[address & 0x3FFFE]))
-      cheatsWriteHalfWord(address & 0x203FFFE,
-                          value);
-    else
-#endif
-      WRITE16LE(((u16 *)&workRAM[address & 0x3FFFE]),value);
-    break;
-  case 3:
-#ifdef BKPT_SUPPORT
-    if(*((u16 *)&freezeInternalRAM[address & 0x7ffe]))
-      cheatsWriteHalfWord(address & 0x3007ffe,
-                          value);
-    else
-#endif
-      WRITE16LE(((u16 *)&internalRAM[address & 0x7ffe]), value);
-    break;    
-  case 4:
-    if(address < 0x4000400)
-      CPUUpdateRegister(address & 0x3fe, value);
-    else goto unwritable;
-    break;
-  case 5:
-#ifdef BKPT_SUPPORT
-    if(*((u16 *)&freezePRAM[address & 0x03fe]))
-      cheatsWriteHalfWord(address & 0x70003fe,
-                          value);
-    else
-#endif
-    WRITE16LE(((u16 *)&paletteRAM[address & 0x3fe]), value);
-    break;
-  case 6:
-    address = (address & 0x1fffe);
-    if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
-        return;
-    if ((address & 0x18000) == 0x18000)
-      address &= 0x17fff;
-#ifdef BKPT_SUPPORT
-    if(*((u16 *)&freezeVRAM[address]))
-      cheatsWriteHalfWord(address + 0x06000000,
-                          value);
-    else
-#endif
-    WRITE16LE(((u16 *)&vram[address]), value); 
-    break;
-  case 7:
-#ifdef BKPT_SUPPORT
-    if(*((u16 *)&freezeOAM[address & 0x03fe]))
-      cheatsWriteHalfWord(address & 0x70003fe,
-                          value);
-    else
-#endif
-    WRITE16LE(((u16 *)&oam[address & 0x3fe]), value);
-    break;
-  case 8:
-  case 9:
-    if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) {
-      if(!rtcWrite(address, value))
-        goto unwritable;
-    } else if(!agbPrintWrite(address, value)) goto unwritable;
-    break;
-  case 13:
-    if(cpuEEPROMEnabled) {
-      eepromWrite(address, (u8)value);
-      break;
-    }
-    goto unwritable;
-  case 14:
-    if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled) {
-      (*cpuSaveGameFunc)(address, (u8)value);
-      break;
-    }
-    goto unwritable;
-  default:
-  unwritable:
-#ifdef DEV_VERSION
-    if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
-      log("Illegal halfword write: %04x to %08x from %08x\n",
-          value,
-          address,
-          armMode ? armNextPC - 4 : armNextPC - 2);
-    }
-#endif
-    break;
-  }
-}
-
-void CPUWriteByte(u32 address, u8 b)
-{
-  switch(address >> 24) {
-  case 2:
-#ifdef BKPT_SUPPORT
-      if(freezeWorkRAM[address & 0x3FFFF])
-        cheatsWriteByte(address & 0x203FFFF, b);
-      else
-#endif  
-        workRAM[address & 0x3FFFF] = b;
-    break;
-  case 3:
-#ifdef BKPT_SUPPORT
-    if(freezeInternalRAM[address & 0x7fff])
-      cheatsWriteByte(address & 0x3007fff, b);
-    else
-#endif
-      internalRAM[address & 0x7fff] = b;
-    break;
-  case 4:
-    if(address < 0x4000400) {
-      switch(address & 0x3FF) {
-      case 0x301:
-	if(b == 0x80)
-	  stopState = true;
-	holdState = 1;
-	holdType = -1;
-  cpuNextEvent = cpuTotalTicks;
-	break;
-      case 0x60:
-      case 0x61:
-      case 0x62:
-      case 0x63:
-      case 0x64:
-      case 0x65:
-      case 0x68:
-      case 0x69:
-      case 0x6c:
-      case 0x6d:
-      case 0x70:
-      case 0x71:
-      case 0x72:
-      case 0x73:
-      case 0x74:
-      case 0x75:
-      case 0x78:
-      case 0x79:
-      case 0x7c:
-      case 0x7d:
-      case 0x80:
-      case 0x81:
-      case 0x84:
-      case 0x85:
-      case 0x90:
-      case 0x91:
-      case 0x92:
-      case 0x93:
-      case 0x94:
-      case 0x95:
-      case 0x96:
-      case 0x97:
-      case 0x98:
-      case 0x99:
-      case 0x9a:
-      case 0x9b:
-      case 0x9c:
-      case 0x9d:
-      case 0x9e:
-      case 0x9f:      
-	soundEvent(address&0xFF, b);
-	break;
-      default:
-	if(address & 1)
-	  CPUUpdateRegister(address & 0x3fe,
-			    ((READ16LE(((u16 *)&ioMem[address & 0x3fe])))
-			     & 0x00FF) |
-			    b<<8);
-	else
-	  CPUUpdateRegister(address & 0x3fe,
-			    ((READ16LE(((u16 *)&ioMem[address & 0x3fe])) & 0xFF00) | b));
-      }
-      break;
-    } else goto unwritable;
-    break;
-  case 5:
-    // no need to switch
-    *((u16 *)&paletteRAM[address & 0x3FE]) = (b << 8) | b;
-    break;
-  case 6:
-    address = (address & 0x1fffe);
-    if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
-        return;
-    if ((address & 0x18000) == 0x18000)
-      address &= 0x17fff;
-
-    // no need to switch 
-    // byte writes to OBJ VRAM are ignored
-    if ((address) < objTilesAddress[((DISPCNT&7)+1)>>2])
-    {
-#ifdef BKPT_SUPPORT
-      if(freezeVRAM[address])
-        cheatsWriteByte(address + 0x06000000, b);
-      else
-#endif  
-            *((u16 *)&vram[address]) = (b << 8) | b;
-    }
-    break;
-  case 7:
-    // no need to switch
-    // byte writes to OAM are ignored
-    //    *((u16 *)&oam[address & 0x3FE]) = (b << 8) | b;
-    break;    
-  case 13:
-    if(cpuEEPROMEnabled) {
-      eepromWrite(address, b);
-      break;
-    }
-    goto unwritable;
-  case 14:
-      if (!(saveType == 5) && (!eepromInUse | cpuSramEnabled | cpuFlashEnabled)) {
-
-    //if(!cpuEEPROMEnabled && (cpuSramEnabled | cpuFlashEnabled)) { 
-
-        (*cpuSaveGameFunc)(address, b);
-      break;
-    }
-    // default
-  default:
-  unwritable:
-#ifdef DEV_VERSION
-    if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
-      log("Illegal byte write: %02x to %08x from %08x\n",
-          b,
-          address,
-          armMode ? armNextPC - 4 : armNextPC -2 );
-    }
-#endif
-    break;
-  }
-}
-
 u8 cpuBitsSet[256];
 u8 cpuLowestBitSet[256];
 
@@ -3865,25 +3396,14 @@
 #endif /* FINAL_VERSION */
 
     if(!holdState && !SWITicks) {
-
-      // Emulates the Cheat System (m) code
-      if((cheatsEnabled) && (mastercode) && (mastercode == armNextPC))
-      {
-        u32 joy = 0;
-        if(systemReadJoypads())
-          joy = systemReadJoypad(-1);
-        u32 ext = (joy >> 10);
-        cpuTotalTicks += cheatsCheckKeys(P1^0x3FF, ext);
-      }
-
-      if ((armNextPC & 0x0803FFFF) == 0x08020000)
-        busPrefetchCount=0x100;
-
       if(armState) {
-#include "arm-new.h"
+        if (!armExecute())
+          return;
       } else {
-#include "thumb.h"
+        if (!thumbExecute())
+          return;
       }
+      clockTicks = 0;
     } else
       clockTicks = CPUUpdateTicks();
 
diff -urN ../VisualBoyAdvance-20061204/src/GBA.h src/GBA.h
--- ../VisualBoyAdvance-20061204/src/GBA.h	2006-08-25 23:13:38 +0900
+++ src/GBA.h	2006-12-05 00:15:16 +0900
@@ -113,8 +113,6 @@
 extern void doMirroring(bool);
 extern void CPUUpdateRegister(u32, u16);
 extern void applyTimer ();
-extern void CPUWriteHalfWord(u32, u16);
-extern void CPUWriteByte(u32, u8);
 extern void CPUInit(const char *,bool);
 extern void CPUReset();
 extern void CPULoop(int);
diff -urN ../VisualBoyAdvance-20061204/src/GBAcpu.h src/GBAcpu.h
--- ../VisualBoyAdvance-20061204/src/GBAcpu.h	1970-01-01 09:00:00 +0900
+++ src/GBAcpu.h	2006-12-05 00:18:42 +0900
@@ -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((cheatsEnabled) && (mastercode) && (mastercode == armNextPC))
+  {
+    u32 joy = 0;
+    if(systemReadJoypads())
+      joy = systemReadJoypad(-1);
+    u32 ext = (joy >> 10);
+    cpuTotalTicks += cheatsCheckKeys(P1^0x3FF, ext);
+  }
+}
+
+#endif //VBA_GBAcpu_H
diff -urN ../VisualBoyAdvance-20061204/src/GBAinline.h src/GBAinline.h
--- ../VisualBoyAdvance-20061204/src/GBAinline.h	2006-09-04 06:52:25 +0900
+++ src/GBAinline.h	2006-12-05 00:18:42 +0900
@@ -23,7 +23,15 @@
 #include "System.h"
 #include "Port.h"
 #include "RTC.h"
+#include "Sound.h"
+#include "agbprint.h"
 
+extern const u32 objTilesAddress[3];
+
+extern bool stopState;
+extern bool holdState;
+extern int holdType;
+extern int cpuNextEvent;
 extern bool cpuSramEnabled;
 extern bool cpuFlashEnabled;
 extern bool cpuEEPROMEnabled;
@@ -485,4 +493,247 @@
   }
 }
 
+static inline void CPUWriteHalfWord(u32 address, u16 value)
+{
+#ifdef DEV_VERSION
+  if(address & 1) {
+    if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
+      log("Unaligned halfword write: %04x to %08x from %08x\n",
+          value,
+          address,
+          armMode ? armNextPC - 4 : armNextPC - 2);
+    }
+  }
+#endif
+  
+  switch(address >> 24) {
+  case 2:
+#ifdef BKPT_SUPPORT
+    if(*((u16 *)&freezeWorkRAM[address & 0x3FFFE]))
+      cheatsWriteHalfWord(address & 0x203FFFE,
+                          value);
+    else
+#endif
+      WRITE16LE(((u16 *)&workRAM[address & 0x3FFFE]),value);
+    break;
+  case 3:
+#ifdef BKPT_SUPPORT
+    if(*((u16 *)&freezeInternalRAM[address & 0x7ffe]))
+      cheatsWriteHalfWord(address & 0x3007ffe,
+                          value);
+    else
+#endif
+      WRITE16LE(((u16 *)&internalRAM[address & 0x7ffe]), value);
+    break;    
+  case 4:
+    if(address < 0x4000400)
+      CPUUpdateRegister(address & 0x3fe, value);
+    else goto unwritable;
+    break;
+  case 5:
+#ifdef BKPT_SUPPORT
+    if(*((u16 *)&freezePRAM[address & 0x03fe]))
+      cheatsWriteHalfWord(address & 0x70003fe,
+                          value);
+    else
+#endif
+    WRITE16LE(((u16 *)&paletteRAM[address & 0x3fe]), value);
+    break;
+  case 6:
+    address = (address & 0x1fffe);
+    if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
+        return;
+    if ((address & 0x18000) == 0x18000)
+      address &= 0x17fff;
+#ifdef BKPT_SUPPORT
+    if(*((u16 *)&freezeVRAM[address]))
+      cheatsWriteHalfWord(address + 0x06000000,
+                          value);
+    else
+#endif
+    WRITE16LE(((u16 *)&vram[address]), value); 
+    break;
+  case 7:
+#ifdef BKPT_SUPPORT
+    if(*((u16 *)&freezeOAM[address & 0x03fe]))
+      cheatsWriteHalfWord(address & 0x70003fe,
+                          value);
+    else
+#endif
+    WRITE16LE(((u16 *)&oam[address & 0x3fe]), value);
+    break;
+  case 8:
+  case 9:
+    if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8) {
+      if(!rtcWrite(address, value))
+        goto unwritable;
+    } else if(!agbPrintWrite(address, value)) goto unwritable;
+    break;
+  case 13:
+    if(cpuEEPROMEnabled) {
+      eepromWrite(address, (u8)value);
+      break;
+    }
+    goto unwritable;
+  case 14:
+    if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled) {
+      (*cpuSaveGameFunc)(address, (u8)value);
+      break;
+    }
+    goto unwritable;
+  default:
+  unwritable:
+#ifdef DEV_VERSION
+    if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
+      log("Illegal halfword write: %04x to %08x from %08x\n",
+          value,
+          address,
+          armMode ? armNextPC - 4 : armNextPC - 2);
+    }
+#endif
+    break;
+  }
+}
+
+static inline void CPUWriteByte(u32 address, u8 b)
+{
+  switch(address >> 24) {
+  case 2:
+#ifdef BKPT_SUPPORT
+      if(freezeWorkRAM[address & 0x3FFFF])
+        cheatsWriteByte(address & 0x203FFFF, b);
+      else
+#endif  
+        workRAM[address & 0x3FFFF] = b;
+    break;
+  case 3:
+#ifdef BKPT_SUPPORT
+    if(freezeInternalRAM[address & 0x7fff])
+      cheatsWriteByte(address & 0x3007fff, b);
+    else
+#endif
+      internalRAM[address & 0x7fff] = b;
+    break;
+  case 4:
+    if(address < 0x4000400) {
+      switch(address & 0x3FF) {
+      case 0x301:
+	if(b == 0x80)
+	  stopState = true;
+	holdState = 1;
+	holdType = -1;
+  cpuNextEvent = cpuTotalTicks;
+	break;
+      case 0x60:
+      case 0x61:
+      case 0x62:
+      case 0x63:
+      case 0x64:
+      case 0x65:
+      case 0x68:
+      case 0x69:
+      case 0x6c:
+      case 0x6d:
+      case 0x70:
+      case 0x71:
+      case 0x72:
+      case 0x73:
+      case 0x74:
+      case 0x75:
+      case 0x78:
+      case 0x79:
+      case 0x7c:
+      case 0x7d:
+      case 0x80:
+      case 0x81:
+      case 0x84:
+      case 0x85:
+      case 0x90:
+      case 0x91:
+      case 0x92:
+      case 0x93:
+      case 0x94:
+      case 0x95:
+      case 0x96:
+      case 0x97:
+      case 0x98:
+      case 0x99:
+      case 0x9a:
+      case 0x9b:
+      case 0x9c:
+      case 0x9d:
+      case 0x9e:
+      case 0x9f:      
+	soundEvent(address&0xFF, b);
+	break;
+      default:
+	if(address & 1)
+	  CPUUpdateRegister(address & 0x3fe,
+			    ((READ16LE(((u16 *)&ioMem[address & 0x3fe])))
+			     & 0x00FF) |
+			    b<<8);
+	else
+	  CPUUpdateRegister(address & 0x3fe,
+			    ((READ16LE(((u16 *)&ioMem[address & 0x3fe])) & 0xFF00) | b));
+      }
+      break;
+    } else goto unwritable;
+    break;
+  case 5:
+    // no need to switch
+    *((u16 *)&paletteRAM[address & 0x3FE]) = (b << 8) | b;
+    break;
+  case 6:
+    address = (address & 0x1fffe);
+    if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
+        return;
+    if ((address & 0x18000) == 0x18000)
+      address &= 0x17fff;
+
+    // no need to switch 
+    // byte writes to OBJ VRAM are ignored
+    if ((address) < objTilesAddress[((DISPCNT&7)+1)>>2])
+    {
+#ifdef BKPT_SUPPORT
+      if(freezeVRAM[address])
+        cheatsWriteByte(address + 0x06000000, b);
+      else
+#endif  
+            *((u16 *)&vram[address]) = (b << 8) | b;
+    }
+    break;
+  case 7:
+    // no need to switch
+    // byte writes to OAM are ignored
+    //    *((u16 *)&oam[address & 0x3FE]) = (b << 8) | b;
+    break;    
+  case 13:
+    if(cpuEEPROMEnabled) {
+      eepromWrite(address, b);
+      break;
+    }
+    goto unwritable;
+  case 14:
+      if (!(saveType == 5) && (!eepromInUse | cpuSramEnabled | cpuFlashEnabled)) {
+
+    //if(!cpuEEPROMEnabled && (cpuSramEnabled | cpuFlashEnabled)) { 
+
+        (*cpuSaveGameFunc)(address, b);
+      break;
+    }
+    // default
+  default:
+  unwritable:
+#ifdef DEV_VERSION
+    if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
+      log("Illegal byte write: %02x to %08x from %08x\n",
+          b,
+          address,
+          armMode ? armNextPC - 4 : armNextPC -2 );
+    }
+#endif
+    break;
+  }
+}
+
 #endif //VBA_GBAinline_H
diff -urN ../VisualBoyAdvance-20061204/src/arm-new.h src/arm-new.h
--- ../VisualBoyAdvance-20061204/src/arm-new.h	2006-08-25 22:30:08 +0900
+++ src/arm-new.h	2006-12-05 00:18:42 +0900
@@ -1,8701 +0,0 @@
-// -*- C++ -*-
-// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
-// Copyright (C) 1999-2003 Forgotten
-// Copyright (C) 2005-2006 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.
-
-#ifdef BKPT_SUPPORT
-#define CONSOLE_OUTPUT(a,b) \
-    extern void (*dbgOutput)(char *, u32);\
-    if((opcode == 0xe0000000) && (reg[0].I == 0xC0DED00D)) {\
-      dbgOutput((a), (b));\
-    }
-#else
-#define CONSOLE_OUTPUT(a,b)
-#endif
-
-#define OP_AND \
-      reg[dest].I = reg[(opcode>>16)&15].I & value;\
-      CONSOLE_OUTPUT(NULL,reg[2].I);
-
-#define OP_ANDS \
-      reg[dest].I = reg[(opcode>>16)&15].I & value;\
-      \
-      N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
-      Z_FLAG = (reg[dest].I) ? false : true;\
-      C_FLAG = C_OUT;
-
-#define OP_EOR \
-      reg[dest].I = reg[(opcode>>16)&15].I ^ value;
-
-#define OP_EORS \
-      reg[dest].I = reg[(opcode>>16)&15].I ^ value;\
-      \
-      N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
-      Z_FLAG = (reg[dest].I) ? false : true;\
-      C_FLAG = C_OUT;
-#ifdef C_CORE
-#define NEG(i) ((i) >> 31)
-#define POS(i) ((~(i)) >> 31)
-#define ADDCARRY(a, b, c) \
-  C_FLAG = ((NEG(a) & NEG(b)) |\
-            (NEG(a) & POS(c)) |\
-            (NEG(b) & POS(c))) ? true : false;
-#define ADDOVERFLOW(a, b, c) \
-  V_FLAG = ((NEG(a) & NEG(b) & POS(c)) |\
-            (POS(a) & POS(b) & NEG(c))) ? true : false;
-#define SUBCARRY(a, b, c) \
-  C_FLAG = ((NEG(a) & POS(b)) |\
-            (NEG(a) & POS(c)) |\
-            (POS(b) & POS(c))) ? true : false;
-#define SUBOVERFLOW(a, b, c)\
-  V_FLAG = ((NEG(a) & POS(b) & POS(c)) |\
-            (POS(a) & NEG(b) & NEG(c))) ? true : false;
-#define OP_SUB \
-    {\
-      reg[dest].I = reg[base].I - value;\
-    }
-#define OP_SUBS \
-   {\
-     u32 lhs = reg[base].I;\
-     u32 rhs = value;\
-     u32 res = lhs - rhs;\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(lhs, rhs, res);\
-     SUBOVERFLOW(lhs, rhs, res);\
-   }
-#define OP_RSB \
-    {\
-      reg[dest].I = value - reg[base].I;\
-    }
-#define OP_RSBS \
-   {\
-     u32 lhs = reg[base].I;\
-     u32 rhs = value;\
-     u32 res = rhs - lhs;\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(rhs, lhs, res);\
-     SUBOVERFLOW(rhs, lhs, res);\
-   }
-#define OP_ADD \
-    {\
-      reg[dest].I = reg[base].I + value;\
-    }
-#define OP_ADDS \
-   {\
-     u32 lhs = reg[base].I;\
-     u32 rhs = value;\
-     u32 res = lhs + rhs;\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     ADDCARRY(lhs, rhs, res);\
-     ADDOVERFLOW(lhs, rhs, res);\
-   }
-#define OP_ADC \
-    {\
-      reg[dest].I = reg[base].I + value + (u32)C_FLAG;\
-    }
-#define OP_ADCS \
-   {\
-     u32 lhs = reg[base].I;\
-     u32 rhs = value;\
-     u32 res = lhs + rhs + (u32)C_FLAG;\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     ADDCARRY(lhs, rhs, res);\
-     ADDOVERFLOW(lhs, rhs, res);\
-   }
-#define OP_SBC \
-    {\
-      reg[dest].I = reg[base].I - value - !((u32)C_FLAG);\
-    }
-#define OP_SBCS \
-   {\
-     u32 lhs = reg[base].I;\
-     u32 rhs = value;\
-     u32 res = lhs - rhs - !((u32)C_FLAG);\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(lhs, rhs, res);\
-     SUBOVERFLOW(lhs, rhs, res);\
-   }
-#define OP_RSC \
-    {\
-      reg[dest].I = value - reg[base].I - !((u32)C_FLAG);\
-    }
-#define OP_RSCS \
-   {\
-     u32 lhs = reg[base].I;\
-     u32 rhs = value;\
-     u32 res = rhs - lhs - !((u32)C_FLAG);\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(rhs, lhs, res);\
-     SUBOVERFLOW(rhs, lhs, res);\
-   }
-#define OP_CMP \
-   {\
-     u32 lhs = reg[base].I;\
-     u32 rhs = value;\
-     u32 res = lhs - rhs;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(lhs, rhs, res);\
-     SUBOVERFLOW(lhs, rhs, res);\
-   }
-#define OP_CMN \
-   {\
-     u32 lhs = reg[base].I;\
-     u32 rhs = value;\
-     u32 res = lhs + rhs;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     ADDCARRY(lhs, rhs, res);\
-     ADDOVERFLOW(lhs, rhs, res);\
-   }
-
-#define LOGICAL_LSL_REG \
-   {\
-     u32 v = reg[opcode & 0x0f].I;\
-     C_OUT = (v >> (32 - shift)) & 1 ? true : false;\
-     value = v << shift;\
-   }
-#define LOGICAL_LSR_REG \
-   {\
-     u32 v = reg[opcode & 0x0f].I;\
-     C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
-     value = v >> shift;\
-   }
-#define LOGICAL_ASR_REG \
-   {\
-     u32 v = reg[opcode & 0x0f].I;\
-     C_OUT = ((s32)v >> (int)(shift - 1)) & 1 ? true : false;\
-     value = (s32)v >> (int)shift;\
-   }
-#define LOGICAL_ROR_REG \
-   {\
-     u32 v = reg[opcode & 0x0f].I;\
-     C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
-     value = ((v << (32 - shift)) |\
-              (v >> shift));\
-   }
-#define LOGICAL_RRX_REG \
-   {\
-     u32 v = reg[opcode & 0x0f].I;\
-     shift = (int)C_FLAG;\
-     C_OUT = (v  & 1) ? true : false;\
-     value = ((v >> 1) |\
-              (shift << 31));\
-   }
-#define LOGICAL_ROR_IMM \
-   {\
-     u32 v = opcode & 0xff;\
-     C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
-     value = ((v << (32 - shift)) |\
-              (v >> shift));\
-   }
-#define ARITHMETIC_LSL_REG \
-   {\
-     u32 v = reg[opcode & 0x0f].I;\
-     value = v << shift;\
-   }
-#define ARITHMETIC_LSR_REG \
-   {\
-     u32 v = reg[opcode & 0x0f].I;\
-     value = v >> shift;\
-   }
-#define ARITHMETIC_ASR_REG \
-   {\
-     u32 v = reg[opcode & 0x0f].I;\
-     value = (s32)v >> (int)shift;\
-   }
-#define ARITHMETIC_ROR_REG \
-   {\
-     u32 v = reg[opcode & 0x0f].I;\
-     value = ((v << (32 - shift)) |\
-              (v >> shift));\
-   }
-#define ARITHMETIC_RRX_REG \
-   {\
-     u32 v = reg[opcode & 0x0f].I;\
-     shift = (int)C_FLAG;\
-     value = ((v >> 1) |\
-              (shift << 31));\
-   }
-#define ARITHMETIC_ROR_IMM \
-   {\
-     u32 v = opcode & 0xff;\
-     value = ((v << (32 - shift)) |\
-              (v >> shift));\
-   }
-#define ROR_IMM_MSR \
-   {\
-     u32 v = opcode & 0xff;\
-     value = ((v << (32 - shift)) |\
-              (v >> shift));\
-   }
-#define ROR_VALUE \
-   {\
-     value = ((value << (32 - shift)) |\
-              (value >> shift));\
-   }
-#define RCR_VALUE \
-   {\
-     shift = (int)C_FLAG;\
-     value = ((value >> 1) |\
-              (shift << 31));\
-   }
-#else
-#ifdef __GNUC__
-        #ifdef __POWERPC__
-            #define OP_SUB \
-                {\
-                reg[dest].I = reg[base].I - value;\
-                }
-            #define OP_SUBS \
-            {\
-                register int Flags;                             \
-                register int Result;                            \
-                asm volatile("subco. %0, %2, %3\n"              \
-                            "mcrxr cr1\n"                       \
-                            "mfcr %1\n"                         \
-                            : "=r" (Result),                    \
-                              "=r" (Flags)                      \
-                            : "r" (reg[base].I),                \
-                              "r" (value)                       \
-                            );                                  \
-                reg[dest].I = Result;                           \
-                Z_FLAG = (Flags >> 29) & 1;                     \
-                N_FLAG = (Flags >> 31) & 1;                     \
-                C_FLAG = (Flags >> 25) & 1;                     \
-                V_FLAG = (Flags >> 26) & 1;                     \
-            }
-            #define OP_RSB \
-                {\
-                reg[dest].I = value - reg[base].I;\
-                }
-            #define OP_RSBS \
-            {\
-                register int Flags;                             \
-                register int Result;                            \
-                asm volatile("subfco. %0, %2, %3\n"             \
-                            "mcrxr cr1\n"                       \
-                            "mfcr %1\n"                         \
-                            : "=r" (Result),                    \
-                              "=r" (Flags)                      \
-                            : "r" (reg[base].I),                \
-                              "r" (value)                       \
-                            );                                  \
-                reg[dest].I = Result;                           \
-                Z_FLAG = (Flags >> 29) & 1;                     \
-                N_FLAG = (Flags >> 31) & 1;                     \
-                C_FLAG = (Flags >> 25) & 1;                     \
-                V_FLAG = (Flags >> 26) & 1;                     \
-            }
-            #define OP_ADD \
-                {\
-                reg[dest].I = reg[base].I + value;\
-                }
-
-            #define OP_ADDS \
-            {\
-                register int Flags;                             \
-                register int Result;                            \
-                asm volatile("addco. %0, %2, %3\n"              \
-                            "mcrxr cr1\n"                       \
-                            "mfcr %1\n"                         \
-                            : "=r" (Result),                    \
-                              "=r" (Flags)                      \
-                            : "r" (reg[base].I),                \
-                              "r" (value)                       \
-                            );                                  \
-                reg[dest].I = Result;                           \
-                Z_FLAG = (Flags >> 29) & 1;                     \
-                N_FLAG = (Flags >> 31) & 1;                     \
-                C_FLAG = (Flags >> 25) & 1;                     \
-                V_FLAG = (Flags >> 26) & 1;                     \
-            }
-            #define OP_ADC \
-            {\
-                reg[dest].I = reg[base].I + value + (u32)C_FLAG;\
-            }
-            #define OP_ADCS \
-            {\
-                register int Flags;                             \
-                register int Result;                            \
-                asm volatile("mtspr xer, %4\n"                  \
-                             "addeo. %0, %2, %3\n"              \
-                             "mcrxr cr1\n"                      \
-                             "mfcr      %1\n"                   \
-                             : "=r" (Result),                   \
-                               "=r" (Flags)                     \
-                             : "r" (reg[base].I),               \
-                               "r" (value),                     \
-                               "r" (C_FLAG << 29)               \
-                             );                                 \
-                reg[dest].I = Result;                           \
-                Z_FLAG = (Flags >> 29) & 1;                     \
-                N_FLAG = (Flags >> 31) & 1;                     \
-                C_FLAG = (Flags >> 25) & 1;                     \
-                V_FLAG = (Flags >> 26) & 1;                     \
-            }
-            #define OP_SBC \
-                {\
-                reg[dest].I = reg[base].I - value - (C_FLAG^1);\
-                }
-            #define OP_SBCS \
-            {\
-                register int Flags;                             \
-                register int Result;                            \
-                asm volatile("mtspr xer, %4\n"                  \
-                             "subfeo. %0, %3, %2\n"             \
-                             "mcrxr cr1\n"                      \
-                             "mfcr      %1\n"                   \
-                             : "=r" (Result),                   \
-                               "=r" (Flags)                     \
-                             : "r" (reg[base].I),               \
-                               "r" (value),                     \
-                               "r" (C_FLAG << 29)               \
-                             );                                 \
-                reg[dest].I = Result;                           \
-                Z_FLAG = (Flags >> 29) & 1;                     \
-                N_FLAG = (Flags >> 31) & 1;                     \
-                C_FLAG = (Flags >> 25) & 1;                     \
-                V_FLAG = (Flags >> 26) & 1;                     \
-            }
-            #define OP_RSC \
-                {\
-                reg[dest].I = value - reg[base].I - (C_FLAG^1);\
-                }
-            #define OP_RSCS \
-            {\
-                register int Flags;                             \
-                register int Result;                            \
-                asm volatile("mtspr xer, %4\n"                  \
-                             "subfeo. %0, %2, %3\n"             \
-                             "mcrxr cr1\n"                      \
-                             "mfcr      %1\n"                   \
-                             : "=r" (Result),                   \
-                               "=r" (Flags)                     \
-                             : "r" (reg[base].I),               \
-                               "r" (value),                     \
-                               "r" (C_FLAG << 29)               \
-                             );                                 \
-                reg[dest].I = Result;                           \
-                Z_FLAG = (Flags >> 29) & 1;                     \
-                N_FLAG = (Flags >> 31) & 1;                     \
-                C_FLAG = (Flags >> 25) & 1;                     \
-                V_FLAG = (Flags >> 26) & 1;                     \
-            }
-            #define OP_CMP \
-            {\
-                register int Flags;                             \
-                register int Result;                            \
-                asm volatile("subco. %0, %2, %3\n"              \
-                            "mcrxr cr1\n"                       \
-                            "mfcr %1\n"                         \
-                            : "=r" (Result),                    \
-                              "=r" (Flags)                      \
-                            : "r" (reg[base].I),                \
-                              "r" (value)                       \
-                            );                                  \
-                Z_FLAG = (Flags >> 29) & 1;                     \
-                N_FLAG = (Flags >> 31) & 1;                     \
-                C_FLAG = (Flags >> 25) & 1;                     \
-                V_FLAG = (Flags >> 26) & 1;                     \
-            }
-            #define OP_CMN \
-            {\
-                register int Flags;                             \
-                register int Result;                            \
-                asm volatile("addco. %0, %2, %3\n"              \
-                            "mcrxr cr1\n"                       \
-                            "mfcr %1\n"                         \
-                            : "=r" (Result),                    \
-                              "=r" (Flags)                      \
-                            : "r" (reg[base].I),                \
-                              "r" (value)                       \
-                            );                                  \
-                Z_FLAG = (Flags >> 29) & 1;                     \
-                N_FLAG = (Flags >> 31) & 1;                     \
-                C_FLAG = (Flags >> 25) & 1;                     \
-                V_FLAG = (Flags >> 26) & 1;                     \
-            }
-            
-            #define LOGICAL_LSL_REG \
-            {\
-                u32 v = reg[opcode & 0x0f].I;\
-                C_OUT = (v >> (32 - shift)) & 1 ? true : false;\
-                value = v << shift;\
-            }
-            #define LOGICAL_LSR_REG \
-            {\
-                u32 v = reg[opcode & 0x0f].I;\
-                C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
-                value = v >> shift;\
-            }
-            #define LOGICAL_ASR_REG \
-            {\
-                u32 v = reg[opcode & 0x0f].I;\
-                C_OUT = ((s32)v >> (int)(shift - 1)) & 1 ? true : false;\
-                value = (s32)v >> (int)shift;\
-            }
-            #define LOGICAL_ROR_REG \
-            {\
-                u32 v = reg[opcode & 0x0f].I;\
-                C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
-                value = ((v << (32 - shift)) |\
-                        (v >> shift));\
-            }
-            #define LOGICAL_RRX_REG \
-            {\
-                u32 v = reg[opcode & 0x0f].I;\
-                shift = (int)C_FLAG;\
-                C_OUT = (v  & 1) ? true : false;\
-                value = ((v >> 1) |\
-                        (shift << 31));\
-            }
-            #define LOGICAL_ROR_IMM \
-            {\
-                u32 v = opcode & 0xff;\
-                C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
-                value = ((v << (32 - shift)) |\
-                        (v >> shift));\
-            }
-            #define ARITHMETIC_LSL_REG \
-            {\
-                u32 v = reg[opcode & 0x0f].I;\
-                value = v << shift;\
-            }
-            #define ARITHMETIC_LSR_REG \
-            {\
-                u32 v = reg[opcode & 0x0f].I;\
-                value = v >> shift;\
-            }
-            #define ARITHMETIC_ASR_REG \
-            {\
-                u32 v = reg[opcode & 0x0f].I;\
-                value = (s32)v >> (int)shift;\
-            }
-            #define ARITHMETIC_ROR_REG \
-            {\
-                u32 v = reg[opcode & 0x0f].I;\
-                value = ((v << (32 - shift)) |\
-                        (v >> shift));\
-            }
-            #define ARITHMETIC_RRX_REG \
-            {\
-                u32 v = reg[opcode & 0x0f].I;\
-                shift = (int)C_FLAG;\
-                value = ((v >> 1) |\
-                        (shift << 31));\
-            }
-            #define ARITHMETIC_ROR_IMM \
-            {\
-                u32 v = opcode & 0xff;\
-                value = ((v << (32 - shift)) |\
-                        (v >> shift));\
-            }
-            #define ROR_IMM_MSR \
-            {\
-                u32 v = opcode & 0xff;\
-                value = ((v << (32 - shift)) |\
-                        (v >> shift));\
-            }
-            #define ROR_VALUE \
-            {\
-                value = ((value << (32 - shift)) |\
-                        (value >> shift));\
-            }
-            #define RCR_VALUE \
-            {\
-                shift = (int)C_FLAG;\
-                value = ((value >> 1) |\
-                        (shift << 31));\
-            }
-#else
-#define OP_SUB \
-     asm ("sub %1, %%ebx;"\
-                  : "=b" (reg[dest].I)\
-                  : "r" (value), "b" (reg[base].I));
-
-#define OP_SUBS \
-     asm ("sub %1, %%ebx;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setncb C_FLAG;"\
-          "setob V_FLAG;"\
-                  : "=b" (reg[dest].I)\
-                  : "r" (value), "b" (reg[base].I));
-
-#define OP_RSB \
-            asm  ("sub %1, %%ebx;"\
-                 : "=b" (reg[dest].I)\
-                 : "r" (reg[base].I), "b" (value));
-
-#define OP_RSBS \
-            asm  ("sub %1, %%ebx;"\
-                  "setsb N_FLAG;"\
-                  "setzb Z_FLAG;"\
-                  "setncb C_FLAG;"\
-                  "setob V_FLAG;"\
-                 : "=b" (reg[dest].I)\
-                 : "r" (reg[base].I), "b" (value));
-
-#define OP_ADD \
-            asm  ("add %1, %%ebx;"\
-                 : "=b" (reg[dest].I)\
-                 : "r" (value), "b" (reg[base].I));
-
-#define OP_ADDS \
-            asm  ("add %1, %%ebx;"\
-                  "setsb N_FLAG;"\
-                  "setzb Z_FLAG;"\
-                  "setcb C_FLAG;"\
-                  "setob V_FLAG;"\
-                 : "=b" (reg[dest].I)\
-                 : "r" (value), "b" (reg[base].I));
-
-#define OP_ADC \
-            asm  ("bt $0, C_FLAG;"\
-                  "adc %1, %%ebx;"\
-                 : "=b" (reg[dest].I)\
-                 : "r" (value), "b" (reg[base].I));
-
-#define OP_ADCS \
-            asm  ("bt $0, C_FLAG;"\
-                  "adc %1, %%ebx;"\
-                  "setsb N_FLAG;"\
-                  "setzb Z_FLAG;"\
-                  "setcb C_FLAG;"\
-                  "setob V_FLAG;"\
-                 : "=b" (reg[dest].I)\
-                 : "r" (value), "b" (reg[base].I));
-
-#define OP_SBC \
-            asm  ("bt $0, C_FLAG;"\
-                  "cmc;"\
-                  "sbb %1, %%ebx;"\
-                 : "=b" (reg[dest].I)\
-                 : "r" (value), "b" (reg[base].I));
-
-#define OP_SBCS \
-            asm  ("bt $0, C_FLAG;"\
-                  "cmc;"\
-                  "sbb %1, %%ebx;"\
-                  "setsb N_FLAG;"\
-                  "setzb Z_FLAG;"\
-                  "setncb C_FLAG;"\
-                  "setob V_FLAG;"\
-                 : "=b" (reg[dest].I)\
-                 : "r" (value), "b" (reg[base].I));
-#define OP_RSC \
-            asm  ("bt $0, C_FLAG;"\
-                  "cmc;"\
-                  "sbb %1, %%ebx;"\
-                 : "=b" (reg[dest].I)\
-                 : "r" (reg[base].I), "b" (value));
-
-#define OP_RSCS \
-            asm  ("bt $0, C_FLAG;"\
-                  "cmc;"\
-                  "sbb %1, %%ebx;"\
-                  "setsb N_FLAG;"\
-                  "setzb Z_FLAG;"\
-                  "setncb C_FLAG;"\
-                  "setob V_FLAG;"\
-                 : "=b" (reg[dest].I)\
-                 : "r" (reg[base].I), "b" (value));
-#define OP_CMP \
-            asm  ("sub %0, %1;"\
-                  "setsb N_FLAG;"\
-                  "setzb Z_FLAG;"\
-                  "setncb C_FLAG;"\
-                  "setob V_FLAG;"\
-                 :\
-                 : "r" (value), "r" (reg[base].I));
-
-#define OP_CMN \
-            asm  ("add %0, %1;"\
-                  "setsb N_FLAG;"\
-                  "setzb Z_FLAG;"\
-                  "setcb C_FLAG;"\
-                  "setob V_FLAG;"\
-                 : \
-                 : "r" (value), "r" (reg[base].I));
-#define LOGICAL_LSL_REG \
-       asm("shl %%cl, %%eax;"\
-           "setcb %%cl;"\
-           : "=a" (value), "=c" (C_OUT)\
-           : "a" (reg[opcode & 0x0f].I), "c" (shift));
-
-#define LOGICAL_LSR_REG \
-       asm("shr %%cl, %%eax;"\
-           "setcb %%cl;"\
-           : "=a" (value), "=c" (C_OUT)\
-           : "a" (reg[opcode & 0x0f].I), "c" (shift));
-
-#define LOGICAL_ASR_REG \
-       asm("sar %%cl, %%eax;"\
-           "setcb %%cl;"\
-           : "=a" (value), "=c" (C_OUT)\
-           : "a" (reg[opcode & 0x0f].I), "c" (shift));
-
-#define LOGICAL_ROR_REG \
-       asm("ror %%cl, %%eax;"\
-           "setcb %%cl;"\
-           : "=a" (value), "=c" (C_OUT)\
-           : "a" (reg[opcode & 0x0f].I), "c" (shift));       
-
-#define LOGICAL_RRX_REG \
-       asm("bt $0, C_FLAG;"\
-           "rcr $1, %%eax;"\
-           "setcb %%cl;"\
-           : "=a" (value), "=c" (C_OUT)\
-           : "a" (reg[opcode & 0x0f].I));       
-
-#define LOGICAL_ROR_IMM \
-       asm("ror %%cl, %%eax;"\
-           "setcb %%cl;"\
-           : "=a" (value), "=c" (C_OUT)\
-           : "a" (opcode & 0xff), "c" (shift));
-#define ARITHMETIC_LSL_REG \
-       asm("\
-             shl %%cl, %%eax;"\
-           : "=a" (value)\
-           : "a" (reg[opcode & 0x0f].I), "c" (shift));
-
-#define ARITHMETIC_LSR_REG \
-       asm("\
-             shr %%cl, %%eax;"\
-           : "=a" (value)\
-           : "a" (reg[opcode & 0x0f].I), "c" (shift));
-
-#define ARITHMETIC_ASR_REG \
-       asm("\
-             sar %%cl, %%eax;"\
-           : "=a" (value)\
-           : "a" (reg[opcode & 0x0f].I), "c" (shift));
-
-#define ARITHMETIC_ROR_REG \
-       asm("\
-             ror %%cl, %%eax;"\
-           : "=a" (value)\
-           : "a" (reg[opcode & 0x0f].I), "c" (shift));       
-
-#define ARITHMETIC_RRX_REG \
-       asm("\
-             bt $0, C_FLAG;\
-             rcr $1, %%eax;"\
-           : "=a" (value)\
-           : "a" (reg[opcode & 0x0f].I));       
-
-#define ARITHMETIC_ROR_IMM \
-       asm("\
-             ror %%cl, %%eax;"\
-           : "=a" (value)\
-           : "a" (opcode & 0xff), "c" (shift));
-#define ROR_IMM_MSR \
-      asm ("ror %%cl, %%eax;"\
-           : "=a" (value)\
-           : "a" (opcode & 0xFF), "c" (shift));
-#define ROR_VALUE \
-      asm("ror %%cl, %0"\
-          : "=r" (value)\
-          : "r" (value), "c" (shift));
-#define RCR_VALUE \
-      asm("bt $0, C_FLAG;"\
-          "rcr $1, %0"\
-          : "=r" (value)\
-          : "r" (value));
-#endif
-#else
-#define OP_SUB \
-      {\
-        __asm mov ebx, base\
-        __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
-        __asm sub ebx, value\
-        __asm mov eax, dest\
-        __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-      }
-
-#define OP_SUBS \
-      {\
-        __asm mov ebx, base\
-        __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
-        __asm sub ebx, value\
-        __asm mov eax, dest\
-        __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-        __asm sets byte ptr N_FLAG\
-        __asm setz byte ptr Z_FLAG\
-        __asm setnc byte ptr C_FLAG\
-        __asm seto byte ptr V_FLAG\
-      }
-
-#define OP_RSB \
-      {\
-        __asm mov ebx, base\
-        __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
-        __asm mov eax, value\
-        __asm sub eax, ebx\
-        __asm mov ebx, dest\
-        __asm mov dword ptr [OFFSET reg+4*ebx], eax\
-      }
-
-#define OP_RSBS \
-      {\
-        __asm mov ebx, base\
-        __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
-        __asm mov eax, value\
-        __asm sub eax, ebx\
-        __asm mov ebx, dest\
-        __asm mov dword ptr [OFFSET reg+4*ebx], eax\
-        __asm sets byte ptr N_FLAG\
-        __asm setz byte ptr Z_FLAG\
-        __asm setnc byte ptr C_FLAG\
-        __asm seto byte ptr V_FLAG\
-      }
-
-#define OP_ADD \
-      {\
-        __asm mov ebx, base\
-        __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
-        __asm add ebx, value\
-        __asm mov eax, dest\
-        __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-      }
-
-#define OP_ADDS \
-      {\
-        __asm mov ebx, base\
-        __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
-        __asm add ebx, value\
-        __asm mov eax, dest\
-        __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-        __asm sets byte ptr N_FLAG\
-        __asm setz byte ptr Z_FLAG\
-        __asm setc byte ptr C_FLAG\
-        __asm seto byte ptr V_FLAG\
-      }
-
-#define OP_ADC \
-      {\
-        __asm mov ebx, base\
-        __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
-        __asm bt word ptr C_FLAG, 0\
-        __asm adc ebx, value\
-        __asm mov eax, dest\
-        __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-      }
-
-#define OP_ADCS \
-      {\
-        __asm mov ebx, base\
-        __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
-        __asm bt word ptr C_FLAG, 0\
-        __asm adc ebx, value\
-        __asm mov eax, dest\
-        __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-        __asm sets byte ptr N_FLAG\
-        __asm setz byte ptr Z_FLAG\
-        __asm setc byte ptr C_FLAG\
-        __asm seto byte ptr V_FLAG\
-      }
-
-#define OP_SBC \
-      {\
-        __asm mov ebx, base\
-        __asm mov ebx, dword ptr [OFFSET reg + 4*ebx]\
-        __asm mov eax, value\
-        __asm bt word ptr C_FLAG, 0\
-        __asm cmc\
-        __asm sbb ebx, eax\
-        __asm mov eax, dest\
-        __asm mov dword ptr [OFFSET reg + 4*eax], ebx\
-      }
-
-#define OP_SBCS \
-      {\
-        __asm mov ebx, base\
-        __asm mov ebx, dword ptr [OFFSET reg + 4*ebx]\
-        __asm mov eax, value\
-        __asm bt word ptr C_FLAG, 0\
-        __asm cmc\
-        __asm sbb ebx, eax\
-        __asm mov eax, dest\
-        __asm mov dword ptr [OFFSET reg + 4*eax], ebx\
-        __asm sets byte ptr N_FLAG\
-        __asm setz byte ptr Z_FLAG\
-        __asm setnc byte ptr C_FLAG\
-        __asm seto byte ptr V_FLAG\
-      }
-#define OP_RSC \
-      {\
-        __asm mov ebx, value\
-        __asm mov eax, base\
-        __asm mov eax, dword ptr[OFFSET reg + 4*eax]\
-        __asm bt word ptr C_FLAG, 0\
-        __asm cmc\
-        __asm sbb ebx, eax\
-        __asm mov eax, dest\
-        __asm mov dword ptr [OFFSET reg + 4*eax], ebx\
-      }
-
-#define OP_RSCS \
-      {\
-        __asm mov ebx, value\
-        __asm mov eax, base\
-        __asm mov eax, dword ptr[OFFSET reg + 4*eax]\
-        __asm bt word ptr C_FLAG, 0\
-        __asm cmc\
-        __asm sbb ebx, eax\
-        __asm mov eax, dest\
-        __asm mov dword ptr [OFFSET reg + 4*eax], ebx\
-        __asm sets byte ptr N_FLAG\
-        __asm setz byte ptr Z_FLAG\
-        __asm setnc byte ptr C_FLAG\
-        __asm seto byte ptr V_FLAG\
-      }
-#define OP_CMP \
-     {\
-       __asm mov eax, base\
-       __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
-       __asm sub ebx, value\
-       __asm sets byte ptr N_FLAG\
-       __asm setz byte ptr Z_FLAG\
-       __asm setnc byte ptr C_FLAG\
-       __asm seto byte ptr V_FLAG\
-     }
-
-#define OP_CMN \
-     {\
-       __asm mov eax, base\
-       __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
-       __asm add ebx, value\
-       __asm sets byte ptr N_FLAG\
-       __asm setz byte ptr Z_FLAG\
-       __asm setc byte ptr C_FLAG\
-       __asm seto byte ptr V_FLAG\
-     }
-#define LOGICAL_LSL_REG \
-        __asm mov eax, opcode\
-        __asm and eax, 0x0f\
-        __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
-        __asm mov cl, byte ptr shift\
-        __asm shl eax, cl\
-        __asm mov value, eax\
-        __asm setc byte ptr C_OUT
-
-#define LOGICAL_LSR_REG \
-        __asm mov eax, opcode\
-        __asm and eax, 0x0f\
-        __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
-        __asm mov cl, byte ptr shift\
-        __asm shr eax, cl\
-        __asm mov value, eax\
-        __asm setc byte ptr C_OUT
-
-#define LOGICAL_ASR_REG \
-        __asm mov eax, opcode\
-        __asm and eax, 0x0f\
-        __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
-        __asm mov cl, byte ptr shift\
-        __asm sar eax, cl\
-        __asm mov value, eax\
-        __asm setc byte ptr C_OUT
-
-#define LOGICAL_ROR_REG \
-        __asm mov eax, opcode\
-        __asm and eax, 0x0F\
-        __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
-        __asm mov cl, byte ptr shift\
-        __asm ror eax, cl\
-        __asm mov value, eax\
-        __asm setc byte ptr C_OUT
-
-#define LOGICAL_RRX_REG \
-        __asm mov eax, opcode\
-        __asm and eax, 0x0F\
-        __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
-        __asm bt word ptr C_OUT, 0\
-        __asm rcr eax, 1\
-        __asm mov value, eax\
-        __asm setc byte ptr C_OUT
-
-#define LOGICAL_ROR_IMM \
-        __asm mov eax, opcode\
-        __asm and eax, 0xff\
-        __asm mov cl, byte ptr shift\
-        __asm ror eax, cl\
-        __asm mov value, eax\
-        __asm setc byte ptr C_OUT
-#define ARITHMETIC_LSL_REG \
-        __asm mov eax, opcode\
-        __asm and eax, 0x0f\
-        __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
-        __asm mov cl, byte ptr shift\
-        __asm shl eax, cl\
-        __asm mov value, eax
-
-#define ARITHMETIC_LSR_REG \
-        __asm mov eax, opcode\
-        __asm and eax, 0x0f\
-        __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
-        __asm mov cl, byte ptr shift\
-        __asm shr eax, cl\
-        __asm mov value, eax
-
-#define ARITHMETIC_ASR_REG \
-        __asm mov eax, opcode\
-        __asm and eax, 0x0f\
-        __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
-        __asm mov cl, byte ptr shift\
-        __asm sar eax, cl\
-        __asm mov value, eax
-
-#define ARITHMETIC_ROR_REG \
-        __asm mov eax, opcode\
-        __asm and eax, 0x0F\
-        __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
-        __asm mov cl, byte ptr shift\
-        __asm ror eax, cl\
-        __asm mov value, eax
-
-#define ARITHMETIC_RRX_REG \
-        __asm mov eax, opcode\
-        __asm and eax, 0x0F\
-        __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
-        __asm bt word ptr C_FLAG, 0\
-        __asm rcr eax, 1\
-        __asm mov value, eax
-
-#define ARITHMETIC_ROR_IMM \
-        __asm mov eax, opcode\
-        __asm and eax, 0xff\
-        __asm mov cl, byte ptr shift\
-        __asm ror eax, cl\
-        __asm mov value, eax
-#define ROR_IMM_MSR \
-      {\
-        __asm mov eax, opcode\
-        __asm and eax, 0xff\
-        __asm mov cl, byte ptr shift\
-        __asm ror eax, CL\
-        __asm mov value, eax\
-      }
-#define ROR_VALUE \
-      {\
-        __asm mov cl, byte ptr shift\
-        __asm ror dword ptr value, cl\
-      }
-#define RCR_VALUE \
-      {\
-        __asm mov cl, byte ptr shift\
-        __asm bt word ptr C_FLAG, 0\
-        __asm rcr dword ptr value, 1\
-      }
-#endif
-#endif
-
-#define OP_TST \
-      u32 res = reg[base].I & value;\
-      N_FLAG = (res & 0x80000000) ? true : false;\
-      Z_FLAG = (res) ? false : true;\
-      C_FLAG = C_OUT;
-
-#define OP_TEQ \
-      u32 res = reg[base].I ^ value;\
-      N_FLAG = (res & 0x80000000) ? true : false;\
-      Z_FLAG = (res) ? false : true;\
-      C_FLAG = C_OUT;
-
-#define OP_ORR \
-    reg[dest].I = reg[base].I | value;
-
-#define OP_ORRS \
-    reg[dest].I = reg[base].I | value;\
-    N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
-    Z_FLAG = (reg[dest].I) ? false : true;\
-    C_FLAG = C_OUT;
-
-#define OP_MOV \
-    reg[dest].I = value;
-
-#define OP_MOVS \
-    reg[dest].I = value;\
-    N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
-    Z_FLAG = (reg[dest].I) ? false : true;\
-    C_FLAG = C_OUT;
-
-#define OP_BIC \
-    reg[dest].I = reg[base].I & (~value);
-
-#define OP_BICS \
-    reg[dest].I = reg[base].I & (~value);\
-    N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
-    Z_FLAG = (reg[dest].I) ? false : true;\
-    C_FLAG = C_OUT;
-
-#define OP_MVN \
-    reg[dest].I = ~value;
-
-#define OP_MVNS \
-    reg[dest].I = ~value; \
-    N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
-    Z_FLAG = (reg[dest].I) ? false : true;\
-    C_FLAG = C_OUT;
-
-#define CASE_16(BASE) \
-  case BASE:\
-  case BASE+1:\
-  case BASE+2:\
-  case BASE+3:\
-  case BASE+4:\
-  case BASE+5:\
-  case BASE+6:\
-  case BASE+7:\
-  case BASE+8:\
-  case BASE+9:\
-  case BASE+10:\
-  case BASE+11:\
-  case BASE+12:\
-  case BASE+13:\
-  case BASE+14:\
-  case BASE+15:
-
-#define CASE_256(BASE) \
-  CASE_16(BASE)\
-  CASE_16(BASE+0x10)\
-  CASE_16(BASE+0x20)\
-  CASE_16(BASE+0x30)\
-  CASE_16(BASE+0x40)\
-  CASE_16(BASE+0x50)\
-  CASE_16(BASE+0x60)\
-  CASE_16(BASE+0x70)\
-  CASE_16(BASE+0x80)\
-  CASE_16(BASE+0x90)\
-  CASE_16(BASE+0xa0)\
-  CASE_16(BASE+0xb0)\
-  CASE_16(BASE+0xc0)\
-  CASE_16(BASE+0xd0)\
-  CASE_16(BASE+0xe0)\
-  CASE_16(BASE+0xf0)
-
-#define LOGICAL_DATA_OPCODE(OPCODE, OPCODE2, BASE) \
-  case BASE: \
-  case BASE+8:\
-    {\
-      /* OP Rd,Rb,Rm LSL # */ \
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      \
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        LOGICAL_LSL_REG\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+2:\
-  case BASE+10:\
-    {\
-       /* OP Rd,Rb,Rm LSR # */ \
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        LOGICAL_LSR_REG\
-      } else {\
-        value = 0;\
-        C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false;\
-      }\
-      \
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+4:\
-  case BASE+12:\
-    {\
-       /* OP Rd,Rb,Rm ASR # */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        LOGICAL_ASR_REG\
-      } else {\
-        if(reg[opcode & 0x0F].I & 0x80000000){\
-          value = 0xFFFFFFFF;\
-          C_OUT = true;\
-        } else {\
-          value = 0;\
-          C_OUT = false;\
-        }                   \
-      }\
-      \
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+6:\
-  case BASE+14:\
-    {\
-       /* OP Rd,Rb,Rm ROR # */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        LOGICAL_ROR_REG\
-      } else {\
-        LOGICAL_RRX_REG\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+1:\
-    {\
-       /* OP Rd,Rb,Rm LSL Rs */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        if(shift == 32) {\
-          value = 0;\
-          C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false);\
-        } else if(shift < 32) {\
-           LOGICAL_LSL_REG\
-        } else {\
-          value = 0;\
-          C_OUT = false;\
-        }\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+3:\
-    {\
-       /* OP Rd,Rb,Rm LSR Rs */ \
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        if(shift == 32) {\
-          value = 0;\
-          C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false);\
-        } else if(shift < 32) {\
-            LOGICAL_LSR_REG\
-        } else {\
-          value = 0;\
-          C_OUT = false;\
-        }\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+5:\
-    {\
-       /* OP Rd,Rb,Rm ASR Rs */ \
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift < 32) {\
-        if(shift) {\
-          LOGICAL_ASR_REG\
-        } else {\
-          value = reg[opcode & 0x0F].I;\
-        }\
-      } else {\
-        if(reg[opcode & 0x0F].I & 0x80000000){\
-          value = 0xFFFFFFFF;\
-          C_OUT = true;\
-        } else {\
-          value = 0;\
-          C_OUT = false;\
-        }\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+7:\
-    {\
-       /* OP Rd,Rb,Rm ROR Rs */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        shift &= 0x1f;\
-        if(shift) {\
-          LOGICAL_ROR_REG\
-        } else {\
-          value = reg[opcode & 0x0F].I;\
-          C_OUT = (value & 0x80000000 ? true : false);\
-        }\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-        C_OUT = (value & 0x80000000 ? true : false);\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+0x200:\
-  case BASE+0x201:\
-  case BASE+0x202:\
-  case BASE+0x203:\
-  case BASE+0x204:\
-  case BASE+0x205:\
-  case BASE+0x206:\
-  case BASE+0x207:\
-  case BASE+0x208:\
-  case BASE+0x209:\
-  case BASE+0x20a:\
-  case BASE+0x20b:\
-  case BASE+0x20c:\
-  case BASE+0x20d:\
-  case BASE+0x20e:\
-  case BASE+0x20f:\
-    {\
-      int shift = (opcode & 0xF00) >> 7;\
-      int base = (opcode >> 16) & 0x0F;\
-      int dest = (opcode >> 12) & 0x0F;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        LOGICAL_ROR_IMM\
-      } else {\
-        value = opcode & 0xff;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;
-
-#define LOGICAL_DATA_OPCODE_WITHOUT_base(OPCODE, OPCODE2, BASE) \
-  case BASE: \
-  case BASE+8:\
-    {\
-      /* OP Rd,Rb,Rm LSL # */ \
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      \
-      if(shift) {\
-        LOGICAL_LSL_REG\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+2:\
-  case BASE+10:\
-    {\
-       /* OP Rd,Rb,Rm LSR # */ \
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        LOGICAL_LSR_REG\
-      } else {\
-        value = 0;\
-        C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false;\
-      }\
-      \
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+4:\
-  case BASE+12:\
-    {\
-       /* OP Rd,Rb,Rm ASR # */\
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        LOGICAL_ASR_REG\
-      } else {\
-        if(reg[opcode & 0x0F].I & 0x80000000){\
-          value = 0xFFFFFFFF;\
-          C_OUT = true;\
-        } else {\
-          value = 0;\
-          C_OUT = false;\
-        }                   \
-      }\
-      \
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+6:\
-  case BASE+14:\
-    {\
-       /* OP Rd,Rb,Rm ROR # */\
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        LOGICAL_ROR_REG\
-      } else {\
-        LOGICAL_RRX_REG\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+1:\
-    {\
-       /* OP Rd,Rb,Rm LSL Rs */\
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        if(shift == 32) {\
-          value = 0;\
-          C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false);\
-        } else if(shift < 32) {\
-           LOGICAL_LSL_REG\
-        } else {\
-          value = 0;\
-          C_OUT = false;\
-        }\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+3:\
-    {\
-       /* OP Rd,Rb,Rm LSR Rs */ \
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        if(shift == 32) {\
-          value = 0;\
-          C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false);\
-        } else if(shift < 32) {\
-            LOGICAL_LSR_REG\
-        } else {\
-          value = 0;\
-          C_OUT = false;\
-        }\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+5:\
-    {\
-       /* OP Rd,Rb,Rm ASR Rs */ \
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift < 32) {\
-        if(shift) {\
-          LOGICAL_ASR_REG\
-        } else {\
-          value = reg[opcode & 0x0F].I;\
-        }\
-      } else {\
-        if(reg[opcode & 0x0F].I & 0x80000000){\
-          value = 0xFFFFFFFF;\
-          C_OUT = true;\
-        } else {\
-          value = 0;\
-          C_OUT = false;\
-        }\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+7:\
-    {\
-       /* OP Rd,Rb,Rm ROR Rs */\
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        shift &= 0x1f;\
-        if(shift) {\
-          LOGICAL_ROR_REG\
-        } else {\
-          value = reg[opcode & 0x0F].I;\
-          C_OUT = (value & 0x80000000 ? true : false);\
-        }\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-        C_OUT = (value & 0x80000000 ? true : false);\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+0x200:\
-  case BASE+0x201:\
-  case BASE+0x202:\
-  case BASE+0x203:\
-  case BASE+0x204:\
-  case BASE+0x205:\
-  case BASE+0x206:\
-  case BASE+0x207:\
-  case BASE+0x208:\
-  case BASE+0x209:\
-  case BASE+0x20a:\
-  case BASE+0x20b:\
-  case BASE+0x20c:\
-  case BASE+0x20d:\
-  case BASE+0x20e:\
-  case BASE+0x20f:\
-    {\
-      int shift = (opcode & 0xF00) >> 7;\
-      int dest = (opcode >> 12) & 0x0F;\
-      bool C_OUT = C_FLAG;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        LOGICAL_ROR_IMM\
-      } else {\
-        value = opcode & 0xff;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;
-
-#define ARITHMETIC_DATA_OPCODE(OPCODE, OPCODE2, BASE) \
-  case BASE:\
-  case BASE+8:\
-    {\
-      /* OP Rd,Rb,Rm LSL # */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        ARITHMETIC_LSL_REG\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+2:\
-  case BASE+10:\
-    {\
-      /* OP Rd,Rb,Rm LSR # */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        ARITHMETIC_LSR_REG\
-      } else {\
-        value = 0;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+4:\
-  case BASE+12:\
-    {\
-      /* OP Rd,Rb,Rm ASR # */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        ARITHMETIC_ASR_REG\
-      } else {\
-        if(reg[opcode & 0x0F].I & 0x80000000){\
-          value = 0xFFFFFFFF;\
-        } else value = 0;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+6:\
-  case BASE+14:\
-    {\
-      /* OP Rd,Rb,Rm ROR # */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = (opcode >> 7) & 0x1F;\
-      int dest = (opcode>>12) & 15;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-         ARITHMETIC_ROR_REG\
-      } else {\
-         ARITHMETIC_RRX_REG\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+1:\
-    {\
-      /* OP Rd,Rb,Rm LSL Rs */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        if(shift == 32) {\
-          value = 0;\
-        } else if(shift < 32) {\
-           ARITHMETIC_LSL_REG\
-        } else value = 0;\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+3:\
-    {\
-      /* OP Rd,Rb,Rm LSR Rs */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        if(shift == 32) {\
-          value = 0;\
-        } else if(shift < 32) {\
-           ARITHMETIC_LSR_REG\
-        } else value = 0;\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+5:\
-    {\
-      /* OP Rd,Rb,Rm ASR Rs */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift < 32) {\
-        if(shift) {\
-           ARITHMETIC_ASR_REG\
-        } else {\
-          value = reg[opcode & 0x0F].I;\
-        }\
-      } else {\
-        if(reg[opcode & 0x0F].I & 0x80000000){\
-          value = 0xFFFFFFFF;\
-        } else value = 0;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+7:\
-    {\
-      /* OP Rd,Rb,Rm ROR Rs */\
-      int base = (opcode >> 16) & 0x0F;\
-      int shift = reg[(opcode >> 8)&15].B.B0;\
-      int dest = (opcode>>12) & 15;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      if(shift) {\
-        shift &= 0x1f;\
-        if(shift) {\
-           ARITHMETIC_ROR_REG\
-        } else {\
-           value = reg[opcode & 0x0F].I;\
-        }\
-      } else {\
-        value = reg[opcode & 0x0F].I;\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;\
-  case BASE+0x200:\
-  case BASE+0x201:\
-  case BASE+0x202:\
-  case BASE+0x203:\
-  case BASE+0x204:\
-  case BASE+0x205:\
-  case BASE+0x206:\
-  case BASE+0x207:\
-  case BASE+0x208:\
-  case BASE+0x209:\
-  case BASE+0x20a:\
-  case BASE+0x20b:\
-  case BASE+0x20c:\
-  case BASE+0x20d:\
-  case BASE+0x20e:\
-  case BASE+0x20f:\
-    {\
-      int shift = (opcode & 0xF00) >> 7;\
-      int base = (opcode >> 16) & 0x0F;\
-      int dest = (opcode >> 12) & 0x0F;\
-      u32 value;\
-      if ((dest == 15)||((opcode & 0x02000010)==0x10))\
-      {\
-        clockTicks = 1+codeTicksAccess32(armNextPC);\
-        if ((opcode & 0x02000010)==0x10)\
-          clockTicks++;\
-      }\
-      {\
-        ARITHMETIC_ROR_IMM\
-      }\
-      if(dest == 15) {\
-        clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
-        OPCODE2\
-        /* todo */\
-        if(opcode & 0x00100000) {\
-          CPUSwitchMode(reg[17].I & 0x1f, false);\
-        }\
-        if(armState) {\
-          reg[15].I &= 0xFFFFFFFC;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 4;\
-          ARM_PREFETCH;\
-        } else {\
-          reg[15].I &= 0xFFFFFFFE;\
-          armNextPC = reg[15].I;\
-          reg[15].I += 2;\
-          THUMB_PREFETCH;\
-        }\
-      } else {\
-        OPCODE \
-      }\
-    }\
-    break;
-
-  u32 opcode = cpuPrefetch[0];
-  cpuPrefetch[0] = cpuPrefetch[1];
-
-  busPrefetch = false;
-  if (busPrefetchCount & 0xFFFFFE00)
-    busPrefetchCount = 0x100 | (busPrefetchCount & 0xFF);
-
-
-  clockTicks = 0;//codeTicksAccessSeq32(armNextPC)+1;
-  int oldArmNextPC = armNextPC;
-
-#ifndef FINAL_VERSION
-  if(armNextPC == stop) {
-    armNextPC++;
-  }
-#endif
-
-  armNextPC = reg[15].I;
-  reg[15].I += 4;
-  ARM_PREFETCH_NEXT;
-
-  int cond = opcode >> 28;
-  // suggested optimization for frequent cases
-  bool cond_res;
-  if(cond == 0x0e) {
-    cond_res = true;
-  } else {
-    switch(cond) { 
-    case 0x00: // EQ 
-      cond_res = Z_FLAG;
-      break;
-    case 0x01: // NE
-      cond_res = !Z_FLAG;
-      break; 
-    case 0x02: // CS
-      cond_res = C_FLAG;
-      break;
-    case 0x03: // CC
-      cond_res = !C_FLAG;
-      break;
-    case 0x04: // MI
-      cond_res = N_FLAG;
-      break;
-    case 0x05: // PL
-      cond_res = !N_FLAG;
-      break;
-    case 0x06: // VS
-      cond_res = V_FLAG;
-      break;
-    case 0x07: // VC
-      cond_res = !V_FLAG;
-      break;
-    case 0x08: // HI
-      cond_res = C_FLAG && !Z_FLAG;
-      break;
-    case 0x09: // LS
-      cond_res = !C_FLAG || Z_FLAG;
-      break;
-    case 0x0A: // GE
-      cond_res = N_FLAG == V_FLAG;
-      break;
-    case 0x0B: // LT
-      cond_res = N_FLAG != V_FLAG;
-      break;
-    case 0x0C: // GT
-      cond_res = !Z_FLAG &&(N_FLAG == V_FLAG);
-      break;    
-    case 0x0D: // LE
-      cond_res = Z_FLAG || (N_FLAG != V_FLAG);
-      break; 
-    case 0x0E: 
-      cond_res = true; 
-      break;
-    case 0x0F:
-    default:
-      // ???
-      cond_res = false;
-      break;
-    }
-  }
-  
-if(cond_res) {
-  switch(((opcode>>16)&0xFF0) | ((opcode>>4)&0x0F)) {
-    LOGICAL_DATA_OPCODE_WITHOUT_base(OP_AND,  OP_AND, 0x000);
-    LOGICAL_DATA_OPCODE_WITHOUT_base(OP_ANDS, OP_AND, 0x010);
-  case 0x009:
-    {
-      // MUL Rd, Rm, Rs
-      int dest = (opcode >> 16) & 0x0F;
-      int mult = (opcode & 0x0F);
-      clockTicks = 1; 
-      u32 rs = reg[(opcode >> 8) & 0x0F].I;
-      reg[dest].I = reg[mult].I * rs;
-      if(((s32)rs)<0)
-         rs = ~rs;
-      if((rs & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if ((rs & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if ((rs & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-      clockTicks += codeTicksAccess32(armNextPC) + 1;
-
-    }
-    break;
-  case 0x019:
-    {
-      // MULS Rd, Rm, Rs
-      int dest = (opcode >> 16) & 0x0F;
-      int mult = (opcode & 0x0F);
-      clockTicks = 1;
-      u32 rs = reg[(opcode >> 8) & 0x0F].I;
-      reg[dest].I = reg[mult].I * rs;
-      N_FLAG = (reg[dest].I & 0x80000000) ? true : false;
-      Z_FLAG = (reg[dest].I) ? false : true;
-      if(((s32)rs)<0)
-        rs = ~rs;
-      if((rs & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if ((rs & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if ((rs & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-      clockTicks += codeTicksAccess32(armNextPC) + 1;
-    }
-    break;
-  case 0x00b:
-  case 0x02b:
-    {
-      // STRH Rd, [Rn], -Rm
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = reg[opcode & 0x0F].I;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-      address -= offset;
-      reg[base].I = address;
-    }
-    break;
-  case 0x04b:
-  case 0x06b:
-    {
-      // STRH Rd, [Rn], #-offset
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
-      clockTicks = 2 + dataTicksAccess16(address)
-          + codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-      address -= offset;
-      reg[base].I = address;
-    }
-    break;
-  case 0x08b:
-  case 0x0ab:
-    {
-      // STRH Rd, [Rn], Rm
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = reg[opcode & 0x0F].I;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-      address += offset;
-      reg[base].I = address;
-    }
-    break;
-  case 0x0cb:
-  case 0x0eb:
-    {
-      // STRH Rd, [Rn], #offset
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-      address += offset;
-      reg[base].I = address;
-    }
-    break;
-  case 0x10b:
-    {
-      // STRH Rd, [Rn, -Rm]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - reg[opcode & 0x0F].I;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-    }
-    break;
-  case 0x12b:
-    {
-      // STRH Rd, [Rn, -Rm]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - reg[opcode & 0x0F].I;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-      reg[base].I = address;
-    }
-    break;
-  case 0x14b:
-    {
-      // STRH Rd, [Rn, -#offset]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-    }
-    break;
-  case 0x16b:
-    {
-      // STRH Rd, [Rn, -#offset]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-      reg[base].I = address;
-    }
-    break;
-  case 0x18b:
-    {
-      // STRH Rd, [Rn, Rm]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + reg[opcode & 0x0F].I;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-    }
-    break;
-  case 0x1ab:
-    {
-      // STRH Rd, [Rn, Rm]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + reg[opcode & 0x0F].I;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-      reg[base].I = address;
-    }
-    break;
-  case 0x1cb:
-    {
-      // STRH Rd, [Rn, #offset]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-    }
-    break;
-  case 0x1eb:
-    {
-      // STRH Rd, [Rn, #offset]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-      CPUWriteHalfWord(address, reg[dest].W.W0);
-      reg[base].I = address;
-    }
-    break;
-  case 0x01b:
-  case 0x03b:
-    {
-      // LDRH Rd, [Rn], -Rm
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = reg[opcode & 0x0F].I;
-      reg[dest].I = CPUReadHalfWord(address);
-      if(dest != base) {
-        address -= offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x05b:
-  case 0x07b:
-    {
-      // LDRH Rd, [Rn], #-offset
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
-      reg[dest].I = CPUReadHalfWord(address);
-      if(dest != base) {
-        address -= offset;
-        reg[base].I = address;
-      }
-      clockTicks=0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x09b:
-  case 0x0bb:
-    {
-      // LDRH Rd, [Rn], Rm
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = reg[opcode & 0x0F].I;
-      reg[dest].I = CPUReadHalfWord(address);
-      if(dest != base) {
-        address += offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x0db:
-  case 0x0fb:
-    {
-      // LDRH Rd, [Rn], #offset
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
-      reg[dest].I = CPUReadHalfWord(address);
-      if(dest != base) {
-        address += offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x11b:
-    {
-      // LDRH Rd, [Rn, -Rm]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - reg[opcode & 0x0F].I;
-      reg[dest].I = CPUReadHalfWord(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x13b:
-    {
-      // LDRH Rd, [Rn, -Rm]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - reg[opcode & 0x0F].I;
-      reg[dest].I = CPUReadHalfWord(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x15b:
-    {
-      // LDRH Rd, [Rn, -#offset]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = CPUReadHalfWord(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x17b:
-    {
-      // LDRH Rd, [Rn, -#offset]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = CPUReadHalfWord(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x19b:
-    {
-      // LDRH Rd, [Rn, Rm]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + reg[opcode & 0x0F].I;
-      reg[dest].I = CPUReadHalfWord(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x1bb:
-    {
-      // LDRH Rd, [Rn, Rm]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + reg[opcode & 0x0F].I;
-      reg[dest].I = CPUReadHalfWord(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x1db:
-    {
-      // LDRH Rd, [Rn, #offset]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = CPUReadHalfWord(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x1fb:
-    {
-      // LDRH Rd, [Rn, #offset]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = CPUReadHalfWord(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x01d:
-  case 0x03d:
-    {
-      // LDRSB Rd, [Rn], -Rm
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = reg[opcode & 0x0F].I;
-      reg[dest].I = (s8)CPUReadByte(address);
-      if(dest != base) {
-        address -= offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x05d:
-  case 0x07d:
-    {
-      // LDRSB Rd, [Rn], #-offset
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
-      reg[dest].I = (s8)CPUReadByte(address);
-      if(dest != base) {
-        address -= offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x09d:
-  case 0x0bd:
-    {
-      // LDRSB Rd, [Rn], Rm
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = reg[opcode & 0x0F].I;
-      reg[dest].I = (s8)CPUReadByte(address);
-      if(dest != base) {
-        address += offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x0dd:
-  case 0x0fd:
-    {
-      // LDRSB Rd, [Rn], #offset
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
-      reg[dest].I = (s8)CPUReadByte(address);
-      if(dest != base) {
-        address += offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x11d:
-    {
-      // LDRSB Rd, [Rn, -Rm]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - reg[opcode & 0x0F].I;
-      reg[dest].I = (s8)CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x13d:
-    {
-      // LDRSB Rd, [Rn, -Rm]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - reg[opcode & 0x0F].I;
-      reg[dest].I = (s8)CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x15d:
-    {
-      // LDRSB Rd, [Rn, -#offset]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = (s8)CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x17d:
-    {
-      // LDRSB Rd, [Rn, -#offset]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = (s8)CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x19d:
-    {
-      // LDRSB Rd, [Rn, Rm]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + reg[opcode & 0x0F].I;
-      reg[dest].I = (s8)CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x1bd:
-    {
-      // LDRSB Rd, [Rn, Rm]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + reg[opcode & 0x0F].I;
-      reg[dest].I = (s8)CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x1dd:
-    {
-      // LDRSB Rd, [Rn, #offset]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = (s8)CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x1fd:
-    {
-      // LDRSB Rd, [Rn, #offset]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = (s8)CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x01f:
-  case 0x03f:
-    {
-      // LDRSH Rd, [Rn], -Rm
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = reg[opcode & 0x0F].I;
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      if(dest != base) {
-        address -= offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x05f:
-  case 0x07f:
-    {
-      // LDRSH Rd, [Rn], #-offset
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      if(dest != base) {
-        address -= offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x09f:
-  case 0x0bf:
-    {
-      // LDRSH Rd, [Rn], Rm
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = reg[opcode & 0x0F].I;
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      if(dest != base) {
-        address += offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x0df:
-  case 0x0ff:
-    {
-      // LDRSH Rd, [Rn], #offset
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I;
-      int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      if(dest != base) {
-        address += offset;
-        reg[base].I = address;
-      }
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x11f:
-    {
-      // LDRSH Rd, [Rn, -Rm]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - reg[opcode & 0x0F].I;
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x13f:
-    {
-      // LDRSH Rd, [Rn, -Rm]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - reg[opcode & 0x0F].I;
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x15f:
-    {
-      // LDRSH Rd, [Rn, -#offset]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x17f:
-    {
-      // LDRSH Rd, [Rn, -#offset]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x19f:
-    {
-      // LDRSH Rd, [Rn, Rm]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + reg[opcode & 0x0F].I;
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x1bf:
-    {
-      // LDRSH Rd, [Rn, Rm]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + reg[opcode & 0x0F].I;
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x1df:
-    {
-      // LDRSH Rd, [Rn, #offset]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x1ff:
-    {
-      // LDRSH Rd, [Rn, #offset]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode >> 16) & 0x0F;
-      int dest = (opcode >> 12) & 0x0F;
-      u32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
-      reg[dest].I = (s16)CPUReadHalfWordSigned(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-    LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EOR,  OP_EOR, 0x020);
-    LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EORS, OP_EOR, 0x030);
-  case 0x029:
-    {
-      // MLA Rd, Rm, Rs, Rn
-      clockTicks = 2;
-      int dest = (opcode >> 16) & 0x0F;
-      int mult = (opcode & 0x0F);
-      u32 rs = reg[(opcode >> 8) & 0x0F].I;
-      reg[dest].I = reg[mult].I * rs + reg[(opcode>>12)&0x0f].I;
-      if((rs & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if ((rs & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if ((rs & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-      clockTicks += codeTicksAccess32(armNextPC) + 1;
-    }
-    break;
-  case 0x039:
-    {
-      // MLAS Rd, Rm, Rs, Rn
-      clockTicks = 2;
-      int dest = (opcode >> 16) & 0x0F;
-      int mult = (opcode & 0x0F);
-      u32 rs = reg[(opcode >> 8) & 0x0F].I;
-      reg[dest].I = reg[mult].I * rs + reg[(opcode>>12)&0x0f].I;
-      N_FLAG = (reg[dest].I & 0x80000000) ? true : false;
-      Z_FLAG = (reg[dest].I) ? false : true;
-      if(((s32)rs)<0)
-        rs = ~rs;
-      if((rs & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if ((rs & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if ((rs & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-      clockTicks += codeTicksAccess32(armNextPC) + 1;
-    }
-    break;
-    ARITHMETIC_DATA_OPCODE(OP_SUB,  OP_SUB, 0x040);
-    ARITHMETIC_DATA_OPCODE(OP_SUBS, OP_SUB, 0x050);
-    ARITHMETIC_DATA_OPCODE(OP_RSB,  OP_RSB, 0x060);
-    ARITHMETIC_DATA_OPCODE(OP_RSBS, OP_RSB, 0x070);
-    ARITHMETIC_DATA_OPCODE(OP_ADD,  OP_ADD, 0x080);
-    ARITHMETIC_DATA_OPCODE(OP_ADDS, OP_ADD, 0x090);
-  case 0x089:
-    {
-      // UMULL RdLo, RdHi, Rn, Rs
-      clockTicks = 2;
-      u32 umult = reg[(opcode & 0x0F)].I;
-      u32 usource = reg[(opcode >> 8) & 0x0F].I;
-      int destLo = (opcode >> 12) & 0x0F;         
-      int destHi = (opcode >> 16) & 0x0F;
-      u64 uTemp = ((u64)umult)*((u64)usource);
-      reg[destLo].I = (u32)uTemp;
-      reg[destHi].I = (u32)(uTemp >> 32);
-      if ((usource & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if ((usource & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if ((usource & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-      clockTicks += codeTicksAccess32(armNextPC) + 1;
-    }
-    break;
-  case 0x099:
-    {
-      // UMULLS RdLo, RdHi, Rn, Rs
-      clockTicks = 2;
-      u32 umult = reg[(opcode & 0x0F)].I;
-      u32 usource = reg[(opcode >> 8) & 0x0F].I;
-      int destLo = (opcode >> 12) & 0x0F;         
-      int destHi = (opcode >> 16) & 0x0F;
-      u64 uTemp = ((u64)umult)*((u64)usource);
-      reg[destLo].I = (u32)uTemp;
-      reg[destHi].I = (u32)(uTemp >> 32);
-      Z_FLAG = (uTemp) ? false : true;
-      N_FLAG = (reg[destHi].I & 0x80000000) ? true : false;
-      if ((usource & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if ((usource & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if ((usource & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-      clockTicks += codeTicksAccess32(armNextPC) + 1;
-    }
-    break;
-    ARITHMETIC_DATA_OPCODE(OP_ADC,  OP_ADC, 0x0a0);
-    ARITHMETIC_DATA_OPCODE(OP_ADCS, OP_ADC, 0x0b0);
-  case 0x0a9:
-    {
-      // UMLAL RdLo, RdHi, Rn, Rs
-      clockTicks = 3;
-      u32 umult = reg[(opcode & 0x0F)].I;
-      u32 usource = reg[(opcode >> 8) & 0x0F].I;
-      int destLo = (opcode >> 12) & 0x0F;         
-      int destHi = (opcode >> 16) & 0x0F;
-      u64 uTemp = (u64)reg[destHi].I;
-      uTemp <<= 32;
-      uTemp |= (u64)reg[destLo].I;
-      uTemp += ((u64)umult)*((u64)usource);
-      reg[destLo].I = (u32)uTemp;
-      reg[destHi].I = (u32)(uTemp >> 32);
-      if ((usource & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if ((usource & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if ((usource & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-      clockTicks += codeTicksAccess32(armNextPC) + 1;
-    }
-    break;
-  case 0x0b9:
-    {
-      // UMLALS RdLo, RdHi, Rn, Rs
-      clockTicks = 3;
-      u32 umult = reg[(opcode & 0x0F)].I;
-      u32 usource = reg[(opcode >> 8) & 0x0F].I;
-      int destLo = (opcode >> 12) & 0x0F;         
-      int destHi = (opcode >> 16) & 0x0F;
-      u64 uTemp = (u64)reg[destHi].I;
-      uTemp <<= 32;
-      uTemp |= (u64)reg[destLo].I;
-      uTemp += ((u64)umult)*((u64)usource);
-      reg[destLo].I = (u32)uTemp;
-      reg[destHi].I = (u32)(uTemp >> 32);
-      Z_FLAG = (uTemp) ? false : true;
-      N_FLAG = (reg[destHi].I & 0x80000000) ? true : false;
-      if ((usource & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if ((usource & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if ((usource & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-      clockTicks += codeTicksAccess32(armNextPC) + 1;
-    }
-    break;
-    ARITHMETIC_DATA_OPCODE(OP_SBC,  OP_SBC, 0x0c0);
-    ARITHMETIC_DATA_OPCODE(OP_SBCS, OP_SBC, 0x0d0);
-  case 0x0c9:
-    {
-      // SMULL RdLo, RdHi, Rm, Rs
-      clockTicks = 2;
-      int destLo = (opcode >> 12) & 0x0F;         
-      int destHi = (opcode >> 16) & 0x0F;
-      u32 rs = reg[(opcode >> 8) & 0x0F].I;
-      s64 m = (s32)reg[(opcode & 0x0F)].I;
-      s64 s = (s32)rs;
-      s64 sTemp = m*s;
-      reg[destLo].I = (u32)sTemp;
-      reg[destHi].I = (u32)(sTemp >> 32);
-      if(((s32)rs) < 0)
-        rs = ~rs;
-      if((rs & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if((rs & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if((rs & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-      clockTicks += codeTicksAccess32(armNextPC) + 1;
-    }
-    break;
-  case 0x0d9:
-    {
-      // SMULLS RdLo, RdHi, Rm, Rs
-      clockTicks = 2;
-      int destLo = (opcode >> 12) & 0x0F;         
-      int destHi = (opcode >> 16) & 0x0F;
-      u32 rs = reg[(opcode >> 8) & 0x0F].I;
-      s64 m = (s32)reg[(opcode & 0x0F)].I;
-      s64 s = (s32)rs;
-      s64 sTemp = m*s;
-      reg[destLo].I = (u32)sTemp;
-      reg[destHi].I = (u32)(sTemp >> 32);
-      Z_FLAG = (sTemp) ? false : true;
-      N_FLAG = (sTemp < 0) ? true : false;
-      if(((s32)rs) < 0)
-        rs = ~rs;
-      if((rs & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if((rs & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if((rs & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-      clockTicks += codeTicksAccess32(armNextPC) + 1;
-    }
-    break;
-    ARITHMETIC_DATA_OPCODE(OP_RSC,  OP_RSC, 0x0e0);
-    ARITHMETIC_DATA_OPCODE(OP_RSCS, OP_RSC, 0x0f0);
-  case 0x0e9:
-    {
-      // SMLAL RdLo, RdHi, Rm, Rs
-      clockTicks = codeTicksAccess32(armNextPC) + 4;
-      int destLo = (opcode >> 12) & 0x0F;         
-      int destHi = (opcode >> 16) & 0x0F;
-      u32 rs = reg[(opcode >> 8) & 0x0F].I;
-      s64 m = (s32)reg[(opcode & 0x0F)].I;
-      s64 s = (s32)rs;
-      s64 sTemp = (u64)reg[destHi].I;
-      sTemp <<= 32;
-      sTemp |= (u64)reg[destLo].I;
-      sTemp += m*s;
-      reg[destLo].I = (u32)sTemp;
-      reg[destHi].I = (u32)(sTemp >> 32);
-      if(((s32)rs) < 0)
-        rs = ~rs;
-      if((rs & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if((rs & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if((rs & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-    }
-    break;
-  case 0x0f9:
-    {
-      // SMLALS RdLo, RdHi, Rm, Rs
-      clockTicks = codeTicksAccess32(armNextPC) + 4;
-      int destLo = (opcode >> 12) & 0x0F;         
-      int destHi = (opcode >> 16) & 0x0F;
-      u32 rs = reg[(opcode >> 8) & 0x0F].I;
-      s64 m = (s32)reg[(opcode & 0x0F)].I;
-      s64 s = (s32)rs;
-      s64 sTemp = (u64)reg[destHi].I;
-      sTemp <<= 32;
-      sTemp |= (u64)reg[destLo].I;
-      sTemp += m*s;
-      reg[destLo].I = (u32)sTemp;
-      reg[destHi].I = (u32)(sTemp >> 32);
-      Z_FLAG = (sTemp) ? false : true;
-      N_FLAG = (sTemp < 0) ? true : false;
-      if(((s32)rs) < 0)
-        rs = ~rs;
-      if((rs & 0xFFFFFF00) == 0)
-        clockTicks += 0;
-      else if((rs & 0xFFFF0000) == 0)
-        clockTicks += 1;
-      else if((rs & 0xFF000000) == 0)
-        clockTicks += 2;
-      else
-        clockTicks += 3;
-      if (!busPrefetchCount)
-        busPrefetchCount = ((++busPrefetchCount)<<clockTicks) - 1;
-    }
-    break;
-    LOGICAL_DATA_OPCODE(OP_TST, OP_TST, 0x110);
-  case 0x100:
-    // MRS Rd, CPSR
-    // TODO: check if right instruction....
-    CPUUpdateCPSR();
-    reg[(opcode >> 12) & 0x0F].I = reg[16].I;
-    break;
-  case 0x109:
-    {
-      // SWP Rd, Rm, [Rn]
-      u32 address = reg[(opcode >> 16) & 15].I;
-      u32 temp = CPUReadMemory(address);
-      CPUWriteMemory(address, reg[opcode&15].I);
-      reg[(opcode >> 12) & 15].I = temp;
-      clockTicks = 4 + dataTicksAccess32(address) + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-    LOGICAL_DATA_OPCODE(OP_TEQ, OP_TEQ, 0x130);
-  case 0x120:
-    {
-      // MSR CPSR_fields, Rm
-      CPUUpdateCPSR();
-      u32 value = reg[opcode & 15].I;
-      u32 newValue = reg[16].I;
-      if(armMode > 0x10) {
-        if(opcode & 0x00010000)
-          newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF);
-        if(opcode & 0x00020000)
-          newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00);
-        if(opcode & 0x00040000)
-          newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000);
-      }
-      if(opcode & 0x00080000)
-        newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000);
-      newValue |= 0x10;
-      CPUSwitchMode(newValue & 0x1f, false);
-      reg[16].I = newValue;
-      CPUUpdateFlags();
-      if(!armState) { // this should not be allowed, but it seems to work
-        THUMB_PREFETCH;
-        reg[15].I = armNextPC + 2;
-      }
-    }
-    break;
-  case 0x121:
-    {
-      // BX Rm
-      // TODO: check if right instruction...
-      int base = opcode & 0x0F;
-      busPrefetchCount=0;
-      armState = reg[base].I & 1 ? false : true;
-      if(armState) {
-        reg[15].I = reg[base].I & 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks = codeTicksAccessSeq32(armNextPC) +
-            codeTicksAccessSeq32(armNextPC) + codeTicksAccess32(armNextPC) + 3;
-      } else {
-        reg[15].I = reg[base].I & 0xFFFFFFFE;
-        armNextPC = reg[15].I;
-        reg[15].I += 2;
-        THUMB_PREFETCH;
-        clockTicks = codeTicksAccessSeq16(armNextPC) +
-            codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 3;
-      }
-    }
-    break;
-    ARITHMETIC_DATA_OPCODE(OP_CMP, OP_CMP, 0x150);
-  case 0x140:
-    // MRS Rd, SPSR
-    // TODO: check if right instruction...
-    reg[(opcode >> 12) & 0x0F].I = reg[17].I;
-    break;
-  case 0x149:
-    {
-      // SWPB Rd, Rm, [Rn]
-      u32 address = reg[(opcode >> 16) & 15].I;
-      u32 temp = CPUReadByte(address);
-      CPUWriteByte(address, reg[opcode&15].B.B0);
-      reg[(opcode>>12)&15].I = temp;
-      clockTicks = 4 + dataTicksAccess32(address) + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-    ARITHMETIC_DATA_OPCODE(OP_CMN, OP_CMN, 0x170);
-  case 0x160:
-    {
-      // MSR SPSR_fields, Rm
-      u32 value = reg[opcode & 15].I;
-      if(armMode > 0x10 && armMode < 0x1f) {
-        if(opcode & 0x00010000)
-          reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF);
-        if(opcode & 0x00020000)
-          reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00);
-        if(opcode & 0x00040000)
-          reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000);
-        if(opcode & 0x00080000)
-          reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000);
-      }
-    }
-    break;
-    LOGICAL_DATA_OPCODE             (OP_ORR,  OP_ORR, 0x180);
-    LOGICAL_DATA_OPCODE             (OP_ORRS, OP_ORR, 0x190);
-    LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOV,  OP_MOV, 0x1a0);
-    LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOVS, OP_MOV, 0x1b0);
-    LOGICAL_DATA_OPCODE             (OP_BIC,  OP_BIC, 0x1c0);
-    LOGICAL_DATA_OPCODE             (OP_BICS, OP_BIC, 0x1d0);
-    LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVN,  OP_MVN, 0x1e0);
-    LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVNS, OP_MVN, 0x1f0);
-#ifdef BKPT_SUPPORT
-  case 0x127:
-  case 0x7ff: // for GDB support
-    extern void (*dbgSignal)(int,int);
-    reg[15].I -= 4;
-    armNextPC -= 4;
-    dbgSignal(5, (opcode & 0x0f)|((opcode>>4) & 0xfff0));
-    return;
-#endif
-  case 0x320:
-  case 0x321:
-  case 0x322:
-  case 0x323:
-  case 0x324:
-  case 0x325:
-  case 0x326:
-  case 0x327:
-  case 0x328:
-  case 0x329:
-  case 0x32a:
-  case 0x32b:
-  case 0x32c:
-  case 0x32d:
-  case 0x32e:
-  case 0x32f:
-    {
-      // MSR CPSR_fields, #
-      CPUUpdateCPSR();
-      u32 value = opcode & 0xFF;
-      int shift = (opcode & 0xF00) >> 7;
-      if(shift) {
-        ROR_IMM_MSR;
-      }
-      u32 newValue = reg[16].I;
-      if(armMode > 0x10) {
-        if(opcode & 0x00010000)
-          newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF);
-        if(opcode & 0x00020000)
-          newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00);
-        if(opcode & 0x00040000)
-          newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000);
-      }
-      if(opcode & 0x00080000)
-        newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000);
-
-      newValue |= 0x10;
-
-      CPUSwitchMode(newValue & 0x1f, false);
-      reg[16].I = newValue;
-      CPUUpdateFlags();
-      if(!armState) { // this should not be allowed, but it seems to work
-        THUMB_PREFETCH;
-        reg[15].I = armNextPC + 2;
-      }
-    }
-    break;
-  case 0x360:
-  case 0x361:
-  case 0x362:
-  case 0x363:
-  case 0x364:
-  case 0x365:
-  case 0x366:
-  case 0x367:
-  case 0x368:
-  case 0x369:
-  case 0x36a:
-  case 0x36b:
-  case 0x36c:
-  case 0x36d:
-  case 0x36e:
-  case 0x36f:
-    {
-      // MSR SPSR_fields, #
-      if(armMode > 0x10 && armMode < 0x1f) {
-        u32 value = opcode & 0xFF;
-        int shift = (opcode & 0xF00) >> 7;
-        if(shift) {
-          ROR_IMM_MSR;
-        }
-        if(opcode & 0x00010000)
-          reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF);
-        if(opcode & 0x00020000)
-          reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00);
-        if(opcode & 0x00040000)
-          reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000);
-        if(opcode & 0x00080000)
-          reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000);
-      }
-    }
-  break;
-  CASE_16(0x400)
-  // T versions shouldn't be different on GBA      
-  CASE_16(0x420)
-    {
-      // STR Rd, [Rn], -#
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteMemory(address, reg[dest].I);
-      reg[base].I = address - offset;
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x480)
-    // T versions shouldn't be different on GBA
-  CASE_16(0x4a0)
-    {
-      // STR Rd, [Rn], #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteMemory(address, reg[dest].I);
-      reg[base].I = address + offset;
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x500)
-    {
-      // STR Rd, [Rn, -#]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x520)
-    {
-      // STR Rd, [Rn, -#]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[base].I = address;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x580)
-    {
-      // STR Rd, [Rn, #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x5a0)
-    {
-      // STR Rd, [Rn, #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[base].I = address;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x410)
-    {
-      // LDR Rd, [Rn], -#
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I -= offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x430)
-    {
-      // LDRT Rd, [Rn], -#
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I -= offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x490)
-    {
-      // LDR Rd, [Rn], #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I += offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x4b0)
-    {
-      // LDRT Rd, [Rn], #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I += offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x510)
-    {
-      // LDR Rd, [Rn, -#]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadMemory(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x530)
-    {
-      // LDR Rd, [Rn, -#]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-  }
-    break;
-  CASE_16(0x590)
-    {
-      // LDR Rd, [Rn, #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadMemory(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x5b0)
-    {
-      // LDR Rd, [Rn, #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x440)
-    // T versions shouldn't be different on GBA      
-  CASE_16(0x460)
-    {
-      // STRB Rd, [Rn], -#
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteByte(address, reg[dest].B.B0);
-      reg[base].I = address - offset;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x4c0)
-    // T versions shouldn't be different on GBA
-  CASE_16(0x4e0)
-    {
-      // STRB Rd, [Rn], #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteByte(address, reg[dest].B.B0);
-      reg[base].I = address + offset;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x540)
-    {
-      // STRB Rd, [Rn, -#]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x560)
-    {
-      // STRB Rd, [Rn, -#]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[base].I = address;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x5c0)
-    {
-      // STRB Rd, [Rn, #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x5e0)
-    {
-      // STRB Rd, [Rn, #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[base].I = address;
-      CPUWriteByte(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x450)
-    // T versions shouldn't be different
-  CASE_16(0x470)
-    {
-      // LDRB Rd, [Rn], -#
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I -= offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x4d0)
-  CASE_16(0x4f0) // T versions should not be different
-    {
-      // LDRB Rd, [Rn], #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I += offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x550)
-    {
-      // LDRB Rd, [Rn, -#]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x570)
-    {
-      // LDRB Rd, [Rn, -#]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x5d0)
-    {
-      // LDRB Rd, [Rn, #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x5f0)
-    {
-      // LDRB Rd, [Rn, #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = opcode & 0xFFF;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x600:
-  case 0x608:
-    // T versions are the same
-  case 0x620:
-  case 0x628:
-    {
-      // STR Rd, [Rn], -Rm, LSL #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteMemory(address, reg[dest].I);
-      reg[base].I = address - offset;
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x602:
-  case 0x60a:
-    // T versions are the same
-  case 0x622:
-  case 0x62a:
-    {
-      // STR Rd, [Rn], -Rm, LSR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteMemory(address, reg[dest].I);
-      reg[base].I = address - offset;
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x604:
-  case 0x60c:
-    // T versions are the same
-  case 0x624:
-  case 0x62c:
-    {
-      // STR Rd, [Rn], -Rm, ASR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteMemory(address, reg[dest].I);
-      reg[base].I = address - offset;
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x606:
-  case 0x60e:
-    // T versions are the same
-  case 0x626:
-  case 0x62e:
-    {
-      // STR Rd, [Rn], -Rm, ROR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteMemory(address, reg[dest].I);
-      reg[base].I = address - value;
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x680:
-  case 0x688:
-    // T versions are the same
-  case 0x6a0:
-  case 0x6a8:
-    {
-      // STR Rd, [Rn], Rm, LSL #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteMemory(address, reg[dest].I);
-      reg[base].I = address + offset;
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x682:
-  case 0x68a:
-    // T versions are the same
-  case 0x6a2:
-  case 0x6aa:
-    {
-      // STR Rd, [Rn], Rm, LSR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteMemory(address, reg[dest].I);
-      reg[base].I = address + offset;
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x684:
-  case 0x68c:
-    // T versions are the same
-  case 0x6a4:
-  case 0x6ac:
-    {
-      // STR Rd, [Rn], Rm, ASR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteMemory(address, reg[dest].I);
-      reg[base].I = address + offset;
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x686:
-  case 0x68e:
-    // T versions are the same
-  case 0x6a6:
-  case 0x6ae:
-    {
-      // STR Rd, [Rn], Rm, ROR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteMemory(address, reg[dest].I);
-      reg[base].I = address + value;
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x700:
-  case 0x708:
-    {
-      // STR Rd, [Rn, -Rm, LSL #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x702:
-  case 0x70a:
-    {
-      // STR Rd, [Rn, -Rm, LSR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x704:
-  case 0x70c:
-    {
-      // STR Rd, [Rn, -Rm, ASR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x706:
-  case 0x70e:
-    {
-      // STR Rd, [Rn, -Rm, ROR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - value;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x720:
-  case 0x728:
-    {
-      // STR Rd, [Rn, -Rm, LSL #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[base].I = address;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x722:
-  case 0x72a:
-    {
-      // STR Rd, [Rn, -Rm, LSR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[base].I = address;      
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x724:
-  case 0x72c:
-    {
-      // STR Rd, [Rn, -Rm, ASR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[base].I = address;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x726:
-  case 0x72e:
-    {
-      // STR Rd, [Rn, -Rm, ROR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - value;
-      reg[base].I = address;      
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x780:
-  case 0x788:
-    {
-      // STR Rd, [Rn, Rm, LSL #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x782:
-  case 0x78a:
-    {
-      // STR Rd, [Rn, Rm, LSR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x784:
-  case 0x78c:
-    {
-      // STR Rd, [Rn, Rm, ASR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x786:
-  case 0x78e:
-    {
-      // STR Rd, [Rn, Rm, ROR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + value;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7a0:
-  case 0x7a8:
-    {
-      // STR Rd, [Rn, Rm, LSL #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[base].I = address;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7a2:
-  case 0x7aa:
-    {
-      // STR Rd, [Rn, Rm, LSR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[base].I = address;      
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7a4:
-  case 0x7ac:
-    {
-      // STR Rd, [Rn, Rm, ASR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[base].I = address;
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7a6:
-  case 0x7ae:
-    {
-      // STR Rd, [Rn, Rm, ROR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + value;
-      reg[base].I = address;      
-      CPUWriteMemory(address, reg[dest].I);
-      clockTicks = 2 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x610:
-  case 0x618:
-    // T versions are the same
-  case 0x630:
-  case 0x638:
-    {
-      // LDR Rd, [Rn], -Rm, LSL #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address - offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x612:
-  case 0x61a:
-    // T versions are the same
-  case 0x632:
-  case 0x63a:
-    {
-      // LDR Rd, [Rn], -Rm, LSR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address - offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x614:
-  case 0x61c:
-    // T versions are the same
-  case 0x634:
-  case 0x63c:
-    {
-      // LDR Rd, [Rn], -Rm, ASR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address - offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x616:
-  case 0x61e:
-    // T versions are the same
-  case 0x636:
-  case 0x63e:
-    {
-      // LDR Rd, [Rn], -Rm, ROR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address - value;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x690:
-  case 0x698:
-    // T versions are the same
-  case 0x6b0:
-  case 0x6b8:
-    {
-      // LDR Rd, [Rn], Rm, LSL #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address + offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x692:
-  case 0x69a:
-    // T versions are the same
-  case 0x6b2:
-  case 0x6ba:
-    {
-      // LDR Rd, [Rn], Rm, LSR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address + offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x694:
-  case 0x69c:
-    // T versions are the same
-  case 0x6b4:
-  case 0x6bc:
-    {
-      // LDR Rd, [Rn], Rm, ASR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address + offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x696:
-  case 0x69e:
-    // T versions are the same
-  case 0x6b6:
-  case 0x6be:
-    {
-      // LDR Rd, [Rn], Rm, ROR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address + value;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x710:
-  case 0x718:
-    {
-      // LDR Rd, [Rn, -Rm, LSL #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadMemory(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x712:
-  case 0x71a:
-    {
-      // LDR Rd, [Rn, -Rm, LSR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadMemory(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x714:
-  case 0x71c:
-    {
-      // LDR Rd, [Rn, -Rm, ASR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadMemory(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x716:
-  case 0x71e:
-    {
-      // LDR Rd, [Rn, -Rm, ROR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - value;
-      reg[dest].I = CPUReadMemory(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x730:
-  case 0x738:
-    {
-      // LDR Rd, [Rn, -Rm, LSL #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x732:
-  case 0x73a:
-    {
-      // LDR Rd, [Rn, -Rm, LSR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address;      
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x734:
-  case 0x73c:
-    {
-      // LDR Rd, [Rn, -Rm, ASR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x736:
-  case 0x73e:
-    {
-      // LDR Rd, [Rn, -Rm, ROR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - value;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address;      
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x790:
-  case 0x798:
-    {
-      // LDR Rd, [Rn, Rm, LSL #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadMemory(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x792:
-  case 0x79a:
-    {
-      // LDR Rd, [Rn, Rm, LSR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadMemory(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x794:
-  case 0x79c:
-    {
-      // LDR Rd, [Rn, Rm, ASR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadMemory(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x796:
-  case 0x79e:
-    {
-      // LDR Rd, [Rn, Rm, ROR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + value;
-      reg[dest].I = CPUReadMemory(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7b0:
-  case 0x7b8:
-    {
-      // LDR Rd, [Rn, Rm, LSL #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7b2:
-  case 0x7ba:
-    {
-      // LDR Rd, [Rn, Rm, LSR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address;      
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7b4:
-  case 0x7bc:
-    {
-      // LDR Rd, [Rn, Rm, ASR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7b6:
-  case 0x7be:
-    {
-      // LDR Rd, [Rn, Rm, ROR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + value;
-      reg[dest].I = CPUReadMemory(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess32(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x640:
-  case 0x648:
-    // T versions are the same
-  case 0x660:
-  case 0x668:
-    {
-      // STRB Rd, [Rn], -Rm, LSL #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteByte(address, reg[dest].B.B0);
-      reg[base].I = address - offset;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x642:
-  case 0x64a:
-    // T versions are the same
-  case 0x662:
-  case 0x66a:
-    {
-      // STRB Rd, [Rn], -Rm, LSR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteByte(address, reg[dest].B.B0);
-      reg[base].I = address - offset;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x644:
-  case 0x64c:
-    // T versions are the same
-  case 0x664:
-  case 0x66c:
-    {
-      // STRB Rd, [Rn], -Rm, ASR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteByte(address, reg[dest].B.B0);
-      reg[base].I = address - offset;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x646:
-  case 0x64e:
-    // T versions are the same
-  case 0x666:
-  case 0x66e:
-    {
-      // STRB Rd, [Rn], -Rm, ROR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteByte(address, reg[dest].B.B0);
-      reg[base].I = address - value;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x6c0:
-  case 0x6c8:
-    // T versions are the same
-  case 0x6e0:
-  case 0x6e8:
-    {
-      // STRB Rd, [Rn], Rm, LSL #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteByte(address, reg[dest].B.B0);
-      reg[base].I = address + offset;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x6c2:
-  case 0x6ca:
-    // T versions are the same
-  case 0x6e2:
-  case 0x6ea:
-    {
-      // STRB Rd, [Rn], Rm, LSR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteByte(address, reg[dest].B.B0);
-      reg[base].I = address + offset;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x6c4:
-  case 0x6cc:
-    // T versions are the same
-  case 0x6e4:
-  case 0x6ec:
-    {
-      // STRB Rd, [Rn], Rm, ASR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteByte(address, reg[dest].B.B0);
-      reg[base].I = address + offset;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x6c6:
-  case 0x6ce:
-    // T versions are the same
-  case 0x6e6:
-  case 0x6ee:
-    {
-      // STRB Rd, [Rn], Rm, ROR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      CPUWriteByte(address, reg[dest].B.B0);
-      reg[base].I = address + value;
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x740:
-  case 0x748:
-    {
-      // STRB Rd, [Rn, -Rm, LSL #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x742:
-  case 0x74a:
-    {
-      // STRB Rd, [Rn, -Rm, LSR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x744:
-  case 0x74c:
-    {
-      // STRB Rd, [Rn, -Rm, ASR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x746:
-  case 0x74e:
-    {
-      // STRB Rd, [Rn, -Rm, ROR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - value;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x760:
-  case 0x768:
-    {
-      // STRB Rd, [Rn, -Rm, LSL #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[base].I = address;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x762:
-  case 0x76a:
-    {
-      // STRB Rd, [Rn, -Rm, LSR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[base].I = address;      
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x764:
-  case 0x76c:
-    {
-      // STRB Rd, [Rn, -Rm, ASR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[base].I = address;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x766:
-  case 0x76e:
-    {
-      // STRB Rd, [Rn, -Rm, ROR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - value;
-      reg[base].I = address;      
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7c0:
-  case 0x7c8:
-    {
-      // STRB Rd, [Rn, Rm, LSL #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7c2:
-  case 0x7ca:
-    {
-      // STRB Rd, [Rn, Rm, LSR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7c4:
-  case 0x7cc:
-    {
-      // STRB Rd, [Rn, Rm, ASR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7c6:
-  case 0x7ce:
-    {
-      // STRB Rd, [Rn, Rm, ROR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + value;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7e0:
-  case 0x7e8:
-    {
-      // STRB Rd, [Rn, Rm, LSL #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[base].I = address;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7e2:
-  case 0x7ea:
-    {
-      // STRB Rd, [Rn, Rm, LSR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[base].I = address;      
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7e4:
-  case 0x7ec:
-    {
-      // STRB Rd, [Rn, Rm, ASR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[base].I = address;
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7e6:
-  case 0x7ee:
-    {
-      // STRB Rd, [Rn, Rm, ROR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + value;
-      reg[base].I = address;      
-      CPUWriteByte(address, reg[dest].B.B0);
-      clockTicks = 2 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x650:
-  case 0x658:
-    // T versions are the same
-  case 0x670:
-  case 0x678:
-    {
-      // LDRB Rd, [Rn], -Rm, LSL #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address - offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x652:
-  case 0x65a:
-    // T versions are the same
-  case 0x672:
-  case 0x67a:
-    {
-      // LDRB Rd, [Rn], -Rm, LSR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address - offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x654:
-  case 0x65c:
-    // T versions are the same
-  case 0x674:
-  case 0x67c:
-    {
-      // LDRB Rd, [Rn], -Rm, ASR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address - offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x656:
-  case 0x65e:
-    // T versions are the same
-  case 0x676:
-  case 0x67e:
-    {
-      // LDRB Rd, [Rn], -Rm, ROR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address - value;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x6d0:
-  case 0x6d8:
-    // T versions are the same
-  case 0x6f0:
-  case 0x6f8:
-    {
-      // LDRB Rd, [Rn], Rm, LSL #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address + offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x6d2:
-  case 0x6da:
-    // T versions are the same
-  case 0x6f2:
-  case 0x6fa:
-    {
-      // LDRB Rd, [Rn], Rm, LSR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address + offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x6d4:
-  case 0x6dc:
-    // T versions are the same
-  case 0x6f4:
-  case 0x6fc:
-    {
-      // LDRB Rd, [Rn], Rm, ASR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address + offset;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x6d6:
-  case 0x6de:
-    // T versions are the same
-  case 0x6f6:
-  case 0x6fe:
-    {
-      // LDRB Rd, [Rn], Rm, ROR #
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address + value;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x750:
-  case 0x758:
-    {
-      // LDRB Rd, [Rn, -Rm, LSL #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x752:
-  case 0x75a:
-    {
-      // LDRB Rd, [Rn, -Rm, LSR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x754:
-  case 0x75c:
-    {
-      // LDRB Rd, [Rn, -Rm, ASR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x756:
-  case 0x75e:
-    {
-      // LDRB Rd, [Rn, -Rm, ROR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - value;
-      reg[dest].I = CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x770:
-  case 0x778:
-    {
-      // LDRB Rd, [Rn, -Rm, LSL #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x772:
-  case 0x77a:
-    {
-      // LDRB Rd, [Rn, -Rm, LSR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;      
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x774:
-  case 0x77c:
-    {
-      // LDRB Rd, [Rn, -Rm, ASR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - offset;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x776:
-  case 0x77e:
-    {
-      // LDRB Rd, [Rn, -Rm, ROR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I - value;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;      
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7d0:
-  case 0x7d8:
-    {
-      // LDRB Rd, [Rn, Rm, LSL #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7d2:
-  case 0x7da:
-    {
-      // LDRB Rd, [Rn, Rm, LSR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7d4:
-  case 0x7dc:
-    {
-      // LDRB Rd, [Rn, Rm, ASR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7d6:
-  case 0x7de:
-    {
-      // LDRB Rd, [Rn, Rm, ROR #]
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + value;
-      reg[dest].I = CPUReadByte(address);
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7f0:
-  case 0x7f8:
-    {
-      // LDRB Rd, [Rn, Rm, LSL #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7f2:
-  case 0x7fa:
-    {
-      // LDRB Rd, [Rn, Rm, LSR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset = shift ? reg[opcode & 15].I >> shift : 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;      
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7f4:
-  case 0x7fc:
-    {
-      // LDRB Rd, [Rn, Rm, ASR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      int offset;
-      if(shift)
-        offset = (int)((s32)reg[opcode & 15].I >> shift);
-      else if(reg[opcode & 15].I & 0x80000000)
-        offset = 0xFFFFFFFF;
-      else
-        offset = 0;
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + offset;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-  case 0x7f6:
-  case 0x7fe:
-    {
-      // LDRB Rd, [Rn, Rm, ROR #]!
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int shift = (opcode >> 7) & 31;
-      u32 value = reg[opcode & 15].I;
-      if(shift) {
-        ROR_VALUE;
-      } else {
-        RCR_VALUE;
-      }
-      int dest = (opcode >> 12) & 15;
-      int base = (opcode >> 16) & 15;
-      u32 address = reg[base].I + value;
-      reg[dest].I = CPUReadByte(address);
-      if(dest != base)
-        reg[base].I = address;      
-      clockTicks = 0;
-      if(dest == 15) {
-        reg[15].I &= 0xFFFFFFFC;
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 3 + dataTicksAccess16(address) +
-          codeTicksAccess32(armNextPC);
-    }
-    break;
-#define STMW_REG(val,num) \
-  if(opcode & (val)) {\
-    CPUWriteMemory(address, reg[(num)].I);\
-    if(!offset) {\
-      reg[base].I = temp;\
-      clockTicks += 1 + dataTicksAccess32(address);\
-      offset = 1;\
-    } else {\
-      clockTicks += 1 + dataTicksAccessSeq32(address);\
-    }\
-    address += 4;\
-  }
-#define STM_REG(val,num) \
-  if(opcode & (val)) {\
-    CPUWriteMemory(address, reg[(num)].I);\
-    if(!offset) {\
-      clockTicks += 1 + dataTicksAccess32(address);\
-      offset = 1;\
-    } else {\
-      clockTicks += 1 + dataTicksAccessSeq32(address);\
-    }\
-    address += 4;\
-  }
-    
-  CASE_16(0x800)
-    {
-      // STMDA Rn, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = (temp + 4) & 0xFFFFFFFC;
-      int offset = 0;
-      STM_REG(1, 0);
-      STM_REG(2, 1);
-      STM_REG(4, 2);
-      STM_REG(8, 3);
-      STM_REG(16, 4);
-      STM_REG(32, 5);
-      STM_REG(64, 6);
-      STM_REG(128, 7);
-      STM_REG(256, 8);
-      STM_REG(512, 9);
-      STM_REG(1024, 10);
-      STM_REG(2048, 11);
-      STM_REG(4096, 12);
-      STM_REG(8192, 13);
-      STM_REG(16384, 14);
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x820)
-    {
-      // STMDA Rn!, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = (temp+4) & 0xFFFFFFFC;
-      int offset = 0;
-
-      STMW_REG(1, 0);
-      STMW_REG(2, 1);
-      STMW_REG(4, 2);
-      STMW_REG(8, 3);
-      STMW_REG(16, 4);
-      STMW_REG(32, 5);
-      STMW_REG(64, 6);
-      STMW_REG(128, 7);
-      STMW_REG(256, 8);
-      STMW_REG(512, 9);
-      STMW_REG(1024, 10);
-      STMW_REG(2048, 11);
-      STMW_REG(4096, 12);
-      STMW_REG(8192, 13);
-      STMW_REG(16384, 14);
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        reg[base].I = temp;
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-  break;
-  CASE_16(0x840)
-    {
-      // STMDA Rn, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = (temp+4) & 0xFFFFFFFC;
-      int offset = 0;
-
-      STM_REG(1, 0);
-      STM_REG(2, 1);
-      STM_REG(4, 2);
-      STM_REG(8, 3);
-      STM_REG(16, 4);
-      STM_REG(32, 5);
-      STM_REG(64, 6);
-      STM_REG(128, 7);
-
-      if(armMode == 0x11) {
-        STM_REG(256, R8_FIQ);
-        STM_REG(512, R9_FIQ);
-        STM_REG(1024, R10_FIQ);
-        STM_REG(2048, R11_FIQ);
-        STM_REG(4096, R12_FIQ);
-      } else {
-        STM_REG(256, 8);
-        STM_REG(512, 9);
-        STM_REG(1024, 10);
-        STM_REG(2048, 11);
-        STM_REG(4096, 12);
-      }
-
-      if(armMode != 0x10 && armMode != 0x1f) {
-        STM_REG(8192, R13_USR);
-        STM_REG(16384, R14_USR);
-      } else {
-        STM_REG(8192, 13);
-        STM_REG(16384, 14);
-      }
-
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x860)
-    {
-      // STMDA Rn!, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = (temp+4) & 0xFFFFFFFC;
-      int offset = 0;
-
-      STMW_REG(1, 0);
-      STMW_REG(2, 1);
-      STMW_REG(4, 2);
-      STMW_REG(8, 3);
-      STMW_REG(16, 4);
-      STMW_REG(32, 5);
-      STMW_REG(64, 6);
-      STMW_REG(128, 7);
-
-      if(armMode == 0x11) {
-        STMW_REG(256, R8_FIQ);
-        STMW_REG(512, R9_FIQ);
-        STMW_REG(1024, R10_FIQ);
-        STMW_REG(2048, R11_FIQ);
-        STMW_REG(4096, R12_FIQ);
-      } else {
-        STMW_REG(256, 8);
-        STMW_REG(512, 9);
-        STMW_REG(1024, 10);
-        STMW_REG(2048, 11);
-        STMW_REG(4096, 12);
-      }
-
-      if(armMode != 0x10 && armMode != 0x1f) {
-        STMW_REG(8192, R13_USR);
-        STMW_REG(16384, R14_USR);
-      } else {
-        STMW_REG(8192, 13);
-        STMW_REG(16384, 14);
-      }
-
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        reg[base].I = temp;
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  
-  CASE_16(0x880)
-    {
-      // STMIA Rn, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = reg[base].I & 0xFFFFFFFC;
-      int offset = 0;
-      STM_REG(1, 0);
-      STM_REG(2, 1);
-      STM_REG(4, 2);
-      STM_REG(8, 3);
-      STM_REG(16, 4);
-      STM_REG(32, 5);
-      STM_REG(64, 6);
-      STM_REG(128, 7);
-      STM_REG(256, 8);
-      STM_REG(512, 9);
-      STM_REG(1024, 10);
-      STM_REG(2048, 11);
-      STM_REG(4096, 12);
-      STM_REG(8192, 13);
-      STM_REG(16384, 14);
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-  break;
-  CASE_16(0x8a0)
-    {
-      // STMIA Rn!, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = reg[base].I & 0xFFFFFFFC;
-      int offset = 0;
-      u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
-                                  cpuBitsSet[(opcode >> 8) & 255]);
-      STMW_REG(1, 0);
-      STMW_REG(2, 1);
-      STMW_REG(4, 2);
-      STMW_REG(8, 3);
-      STMW_REG(16, 4);
-      STMW_REG(32, 5);
-      STMW_REG(64, 6);
-      STMW_REG(128, 7);
-      STMW_REG(256, 8);
-      STMW_REG(512, 9);
-      STMW_REG(1024, 10);
-      STMW_REG(2048, 11);
-      STMW_REG(4096, 12);
-      STMW_REG(8192, 13);
-      STMW_REG(16384, 14);
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset) {
-          reg[base].I = temp;
-          clockTicks += 1 + dataTicksAccess32(address);
-        } else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-  break;
-  CASE_16(0x8c0)
-    {
-      // STMIA Rn, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = reg[base].I & 0xFFFFFFFC;
-      int offset = 0;
-      STM_REG(1, 0);
-      STM_REG(2, 1);
-      STM_REG(4, 2);
-      STM_REG(8, 3);
-      STM_REG(16, 4);
-      STM_REG(32, 5);
-      STM_REG(64, 6);
-      STM_REG(128, 7);
-      if(armMode == 0x11) {
-        STM_REG(256, R8_FIQ);
-        STM_REG(512, R9_FIQ);
-        STM_REG(1024, R10_FIQ);
-        STM_REG(2048, R11_FIQ);
-        STM_REG(4096, R12_FIQ);
-      } else {
-        STM_REG(256, 8);
-        STM_REG(512, 9);
-        STM_REG(1024, 10);
-        STM_REG(2048, 11);
-        STM_REG(4096, 12);      
-      }
-      if(armMode != 0x10 && armMode != 0x1f) {
-        STM_REG(8192, R13_USR);
-        STM_REG(16384, R14_USR);
-      } else {
-        STM_REG(8192, 13);
-        STM_REG(16384, 14);
-      }
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x8e0)
-    {
-      // STMIA Rn!, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = reg[base].I & 0xFFFFFFFC;
-      int offset = 0;
-      u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
-                                  cpuBitsSet[(opcode >> 8) & 255]);    
-      STMW_REG(1, 0);
-      STMW_REG(2, 1);
-      STMW_REG(4, 2);
-      STMW_REG(8, 3);
-      STMW_REG(16, 4);
-      STMW_REG(32, 5);
-      STMW_REG(64, 6);
-      STMW_REG(128, 7);
-      if(armMode == 0x11) {
-        STMW_REG(256, R8_FIQ);
-        STMW_REG(512, R9_FIQ);
-        STMW_REG(1024, R10_FIQ);
-        STMW_REG(2048, R11_FIQ);
-        STMW_REG(4096, R12_FIQ);
-      } else {
-        STMW_REG(256, 8);
-        STMW_REG(512, 9);
-        STMW_REG(1024, 10);
-        STMW_REG(2048, 11);
-        STMW_REG(4096, 12);      
-      }
-      if(armMode != 0x10 && armMode != 0x1f) {
-        STMW_REG(8192, R13_USR);
-        STMW_REG(16384, R14_USR);
-      } else {
-        STMW_REG(8192, 13);
-        STMW_REG(16384, 14);
-      }
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset) {
-          reg[base].I = temp;
-          clockTicks += 1 + dataTicksAccess32(address);
-        } else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-    
-  CASE_16(0x900)
-    {
-      // STMDB Rn, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = temp & 0xFFFFFFFC;
-      int offset = 0;
-      STM_REG(1, 0);
-      STM_REG(2, 1);
-      STM_REG(4, 2);
-      STM_REG(8, 3);
-      STM_REG(16, 4);
-      STM_REG(32, 5);
-      STM_REG(64, 6);
-      STM_REG(128, 7);
-      STM_REG(256, 8);
-      STM_REG(512, 9);
-      STM_REG(1024, 10);
-      STM_REG(2048, 11);
-      STM_REG(4096, 12);
-      STM_REG(8192, 13);
-      STM_REG(16384, 14);
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x920)
-    {
-      // STMDB Rn!, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = temp & 0xFFFFFFFC;
-      int offset = 0;
-
-      STMW_REG(1, 0);
-      STMW_REG(2, 1);
-      STMW_REG(4, 2);
-      STMW_REG(8, 3);
-      STMW_REG(16, 4);
-      STMW_REG(32, 5);
-      STMW_REG(64, 6);
-      STMW_REG(128, 7);
-      STMW_REG(256, 8);
-      STMW_REG(512, 9);
-      STMW_REG(1024, 10);
-      STMW_REG(2048, 11);
-      STMW_REG(4096, 12);
-      STMW_REG(8192, 13);
-      STMW_REG(16384, 14);
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        reg[base].I = temp;
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-  break;
-  CASE_16(0x940)
-    {
-      // STMDB Rn, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = temp & 0xFFFFFFFC;
-      int offset = 0;
-
-      STM_REG(1, 0);
-      STM_REG(2, 1);
-      STM_REG(4, 2);
-      STM_REG(8, 3);
-      STM_REG(16, 4);
-      STM_REG(32, 5);
-      STM_REG(64, 6);
-      STM_REG(128, 7);
-
-      if(armMode == 0x11) {
-        STM_REG(256, R8_FIQ);
-        STM_REG(512, R9_FIQ);
-        STM_REG(1024, R10_FIQ);
-        STM_REG(2048, R11_FIQ);
-        STM_REG(4096, R12_FIQ);
-      } else {
-        STM_REG(256, 8);
-        STM_REG(512, 9);
-        STM_REG(1024, 10);
-        STM_REG(2048, 11);
-        STM_REG(4096, 12);
-      }
-
-      if(armMode != 0x10 && armMode != 0x1f) {
-        STM_REG(8192, R13_USR);
-        STM_REG(16384, R14_USR);
-      } else {
-        STM_REG(8192, 13);
-        STM_REG(16384, 14);
-      }
-
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x960)
-    {
-      // STMDB Rn!, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = temp & 0xFFFFFFFC;
-      int offset = 0;
-
-      STMW_REG(1, 0);
-      STMW_REG(2, 1);
-      STMW_REG(4, 2);
-      STMW_REG(8, 3);
-      STMW_REG(16, 4);
-      STMW_REG(32, 5);
-      STMW_REG(64, 6);
-      STMW_REG(128, 7);
-
-      if(armMode == 0x11) {
-        STMW_REG(256, R8_FIQ);
-        STMW_REG(512, R9_FIQ);
-        STMW_REG(1024, R10_FIQ);
-        STMW_REG(2048, R11_FIQ);
-        STMW_REG(4096, R12_FIQ);
-      } else {
-        STMW_REG(256, 8);
-        STMW_REG(512, 9);
-        STMW_REG(1024, 10);
-        STMW_REG(2048, 11);
-        STMW_REG(4096, 12);
-      }
-
-      if(armMode != 0x10 && armMode != 0x1f) {
-        STMW_REG(8192, R13_USR);
-        STMW_REG(16384, R14_USR);
-      } else {
-        STMW_REG(8192, 13);
-        STMW_REG(16384, 14);
-      }
-
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        reg[base].I = temp;
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-
-  CASE_16(0x980)
-    {
-      // STMIB Rn, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = (reg[base].I+4) & 0xFFFFFFFC;
-      int offset = 0;
-      STM_REG(1, 0);
-      STM_REG(2, 1);
-      STM_REG(4, 2);
-      STM_REG(8, 3);
-      STM_REG(16, 4);
-      STM_REG(32, 5);
-      STM_REG(64, 6);
-      STM_REG(128, 7);
-      STM_REG(256, 8);
-      STM_REG(512, 9);
-      STM_REG(1024, 10);
-      STM_REG(2048, 11);
-      STM_REG(4096, 12);
-      STM_REG(8192, 13);
-      STM_REG(16384, 14);
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x9a0)
-    {
-      // STMIB Rn!, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = (reg[base].I+4) & 0xFFFFFFFC;
-      int offset = 0;
-      u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
-                                  cpuBitsSet[(opcode >> 8) & 255]);
-      STMW_REG(1, 0);
-      STMW_REG(2, 1);
-      STMW_REG(4, 2);
-      STMW_REG(8, 3);
-      STMW_REG(16, 4);
-      STMW_REG(32, 5);
-      STMW_REG(64, 6);
-      STMW_REG(128, 7);
-      STMW_REG(256, 8);
-      STMW_REG(512, 9);
-      STMW_REG(1024, 10);
-      STMW_REG(2048, 11);
-      STMW_REG(4096, 12);
-      STMW_REG(8192, 13);
-      STMW_REG(16384, 14);
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset) {
-          reg[base].I = temp;
-          clockTicks += 1 + dataTicksAccess32(address);
-        } else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x9c0)
-    {
-      // STMIB Rn, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = (reg[base].I+4) & 0xFFFFFFFC;
-      int offset = 0;
-      STM_REG(1, 0);
-      STM_REG(2, 1);
-      STM_REG(4, 2);
-      STM_REG(8, 3);
-      STM_REG(16, 4);
-      STM_REG(32, 5);
-      STM_REG(64, 6);
-      STM_REG(128, 7);
-      if(armMode == 0x11) {
-        STM_REG(256, R8_FIQ);
-        STM_REG(512, R9_FIQ);
-        STM_REG(1024, R10_FIQ);
-        STM_REG(2048, R11_FIQ);
-        STM_REG(4096, R12_FIQ);
-      } else {
-        STM_REG(256, 8);
-        STM_REG(512, 9);
-        STM_REG(1024, 10);
-        STM_REG(2048, 11);
-        STM_REG(4096, 12);      
-      }
-      if(armMode != 0x10 && armMode != 0x1f) {
-        STM_REG(8192, R13_USR);
-        STM_REG(16384, R14_USR);
-      } else {
-        STM_REG(8192, 13);
-        STM_REG(16384, 14);
-      }
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x9e0)
-    {
-      // STMIB Rn!, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = (reg[base].I+4) & 0xFFFFFFFC;
-      int offset = 0;
-      u32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
-                                  cpuBitsSet[(opcode >> 8) & 255]);    
-      STMW_REG(1, 0);
-      STMW_REG(2, 1);
-      STMW_REG(4, 2);
-      STMW_REG(8, 3);
-      STMW_REG(16, 4);
-      STMW_REG(32, 5);
-      STMW_REG(64, 6);
-      STMW_REG(128, 7);
-      if(armMode == 0x11) {
-        STMW_REG(256, R8_FIQ);
-        STMW_REG(512, R9_FIQ);
-        STMW_REG(1024, R10_FIQ);
-        STMW_REG(2048, R11_FIQ);
-        STMW_REG(4096, R12_FIQ);
-      } else {
-        STMW_REG(256, 8);
-        STMW_REG(512, 9);
-        STMW_REG(1024, 10);
-        STMW_REG(2048, 11);
-        STMW_REG(4096, 12);      
-      }
-      if(armMode != 0x10 && armMode != 0x1f) {
-        STMW_REG(8192, R13_USR);
-        STMW_REG(16384, R14_USR);
-      } else {
-        STMW_REG(8192, 13);
-        STMW_REG(16384, 14);
-      }
-      if(opcode & 32768) {
-        CPUWriteMemory(address, reg[15].I+4);
-        if(!offset) {
-          reg[base].I = temp;
-          clockTicks += 1 + dataTicksAccess32(address);
-        } else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-      }
-      clockTicks += 1 + codeTicksAccess32(armNextPC);
-    }
-    break;
-    
-#define LDM_REG(val,num) \
-  if(opcode & (val)) {\
-    reg[(num)].I = CPUReadMemory(address);\
-    if(offset)\
-      clockTicks += 1 + dataTicksAccessSeq32(address);\
-    else {\
-      clockTicks += 1 + dataTicksAccess32(address);\
-      offset = 1;\
-    }\
-    address += 4;\
-  }
-
-  CASE_16(0x810)
-    {
-      // LDMDA Rn, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = (temp + 4) & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      LDM_REG(1, 0);
-      LDM_REG(2, 1);
-      LDM_REG(4, 2);
-      LDM_REG(8, 3);
-      LDM_REG(16, 4);
-      LDM_REG(32, 5);
-      LDM_REG(64, 6);
-      LDM_REG(128, 7);
-      LDM_REG(256, 8);
-      LDM_REG(512, 9);
-      LDM_REG(1024, 10);
-      LDM_REG(2048, 11);
-      LDM_REG(4096, 12);
-      LDM_REG(8192, 13);
-      LDM_REG(16384, 14);
-      if(opcode & 32768) {
-        reg[15].I = CPUReadMemory(address);
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x830)
-    {
-      // LDMDA Rn!, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = (temp + 4) & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      LDM_REG(1, 0);
-      LDM_REG(2, 1);
-      LDM_REG(4, 2);
-      LDM_REG(8, 3);
-      LDM_REG(16, 4);
-      LDM_REG(32, 5);
-      LDM_REG(64, 6);
-      LDM_REG(128, 7);
-      LDM_REG(256, 8);
-      LDM_REG(512, 9);
-      LDM_REG(1024, 10);
-      LDM_REG(2048, 11);
-      LDM_REG(4096, 12);
-      LDM_REG(8192, 13);
-      LDM_REG(16384, 14);
-      if(opcode & 32768) {
-        reg[15].I = CPUReadMemory(address);
-
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-      if(!(opcode & (1 << base)))
-        reg[base].I = temp;
-    }
-    break;
-  CASE_16(0x850)
-    {
-      // LDMDA Rn, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = (temp + 4) & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      if(opcode & 0x8000) {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-        LDM_REG(256, 8);
-        LDM_REG(512, 9);
-        LDM_REG(1024, 10);
-        LDM_REG(2048, 11);
-        LDM_REG(4096, 12);
-        LDM_REG(8192, 13);
-        LDM_REG(16384, 14);
-
-        reg[15].I = CPUReadMemory(address);
-
-        CPUSwitchMode(reg[17].I & 0x1f, false);
-        if(armState) {
-          armNextPC = reg[15].I & 0xFFFFFFFC;
-          reg[15].I = armNextPC + 4;
-          ARM_PREFETCH;
-        } else {
-          armNextPC = reg[15].I & 0xFFFFFFFE;
-          reg[15].I = armNextPC + 2;
-          THUMB_PREFETCH;
-        }
-      } else {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-
-        if(armMode == 0x11) {
-          LDM_REG(256, R8_FIQ);
-          LDM_REG(512, R9_FIQ);
-          LDM_REG(1024, R10_FIQ);
-          LDM_REG(2048, R11_FIQ);
-          LDM_REG(4096, R12_FIQ);
-        } else {
-          LDM_REG(256, 8);
-          LDM_REG(512, 9);
-          LDM_REG(1024, 10);
-          LDM_REG(2048, 11);
-          LDM_REG(4096, 12);
-        }
-
-        if(armMode != 0x10 && armMode != 0x1f) {
-          LDM_REG(8192, R13_USR);
-          LDM_REG(16384, R14_USR);
-        } else {
-          LDM_REG(8192, 13);
-          LDM_REG(16384, 14);
-        }
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-        clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x870)
-    {
-      // LDMDA Rn!, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = (temp + 4) & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      if(opcode & 0x8000) {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-        LDM_REG(256, 8);
-        LDM_REG(512, 9);
-        LDM_REG(1024, 10);
-        LDM_REG(2048, 11);
-        LDM_REG(4096, 12);
-        LDM_REG(8192, 13);
-        LDM_REG(16384, 14);
-
-        reg[15].I = CPUReadMemory(address);
-
-        if(!(opcode & (1 << base)))    
-          reg[base].I = temp;
-
-        CPUSwitchMode(reg[17].I & 0x1f, false);
-        if(armState) {
-          armNextPC = reg[15].I & 0xFFFFFFFC;
-          reg[15].I = armNextPC + 4;
-          ARM_PREFETCH;
-        } else {
-          armNextPC = reg[15].I & 0xFFFFFFFE;
-          reg[15].I = armNextPC + 2;
-          THUMB_PREFETCH;
-        }
-      } else {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-
-        if(armMode == 0x11) {
-          LDM_REG(256, R8_FIQ);
-          LDM_REG(512, R9_FIQ);
-          LDM_REG(1024, R10_FIQ);
-          LDM_REG(2048, R11_FIQ);
-          LDM_REG(4096, R12_FIQ);
-        } else {
-          LDM_REG(256, 8);
-          LDM_REG(512, 9);
-          LDM_REG(1024, 10);
-          LDM_REG(2048, 11);
-          LDM_REG(4096, 12);
-        }
-
-        if(armMode != 0x10 && armMode != 0x1f) {
-          LDM_REG(8192, R13_USR);
-          LDM_REG(16384, R14_USR);
-        } else {
-          LDM_REG(8192, 13);
-          LDM_REG(16384, 14);
-        }
-
-        if(!(opcode & (1 << base)))    
-          reg[base].I = temp;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-    break;
-    
-  CASE_16(0x890)
-    {
-      // LDMIA Rn, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = reg[base].I & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      LDM_REG(1, 0);
-      LDM_REG(2, 1);
-      LDM_REG(4, 2);
-      LDM_REG(8, 3);
-      LDM_REG(16, 4);
-      LDM_REG(32, 5);
-      LDM_REG(64, 6);
-      LDM_REG(128, 7);
-      LDM_REG(256, 8);
-      LDM_REG(512, 9);
-      LDM_REG(1024, 10);
-      LDM_REG(2048, 11);
-      LDM_REG(4096, 12);
-      LDM_REG(8192, 13);
-      LDM_REG(16384, 14);
-      if(opcode & 32768) {
-        reg[15].I = CPUReadMemory(address);
-
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-  break;
-  CASE_16(0x8b0)
-    {
-      // LDMIA Rn!, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I + 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = reg[base].I & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      LDM_REG(1, 0);
-      LDM_REG(2, 1);
-      LDM_REG(4, 2);
-      LDM_REG(8, 3);
-      LDM_REG(16, 4);
-      LDM_REG(32, 5);
-      LDM_REG(64, 6);
-      LDM_REG(128, 7);
-      LDM_REG(256, 8);
-      LDM_REG(512, 9);
-      LDM_REG(1024, 10);
-      LDM_REG(2048, 11);
-      LDM_REG(4096, 12);
-      LDM_REG(8192, 13);
-      LDM_REG(16384, 14);
-      if(opcode & 32768) {
-        reg[15].I = CPUReadMemory(address);
-
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-      if(!(opcode & (1 << base)))
-        reg[base].I = temp;
-    }
-    break;
-  CASE_16(0x8d0)
-    {
-      // LDMIA Rn, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = reg[base].I & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      if(opcode & 0x8000) {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-        LDM_REG(256, 8);
-        LDM_REG(512, 9);
-        LDM_REG(1024, 10);
-        LDM_REG(2048, 11);
-        LDM_REG(4096, 12);
-        LDM_REG(8192, 13);
-        LDM_REG(16384, 14);
-
-        reg[15].I = CPUReadMemory(address);
-
-        CPUSwitchMode(reg[17].I & 0x1f, false);
-        if(armState) {
-          armNextPC = reg[15].I & 0xFFFFFFFC;
-          reg[15].I = armNextPC + 4;
-          ARM_PREFETCH;
-        } else {
-          armNextPC = reg[15].I & 0xFFFFFFFE;
-          reg[15].I = armNextPC + 2;
-          THUMB_PREFETCH;
-        }
-      } else {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-
-        if(armMode == 0x11) {
-          LDM_REG(256, R8_FIQ);
-          LDM_REG(512, R9_FIQ);
-          LDM_REG(1024, R10_FIQ);
-          LDM_REG(2048, R11_FIQ);
-          LDM_REG(4096, R12_FIQ);
-        } else {
-          LDM_REG(256, 8);
-          LDM_REG(512, 9);
-          LDM_REG(1024, 10);
-          LDM_REG(2048, 11);
-          LDM_REG(4096, 12);
-        }
-
-        if(armMode != 0x10 && armMode != 0x1f) {
-          LDM_REG(8192, R13_USR);
-          LDM_REG(16384, R14_USR);
-        } else {
-          LDM_REG(8192, 13);
-          LDM_REG(16384, 14);
-        }
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-  break;
-  CASE_16(0x8f0)
-    {
-      // LDMIA Rn!, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I +
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = reg[base].I & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      if(opcode & 0x8000) {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-        LDM_REG(256, 8);
-        LDM_REG(512, 9);
-        LDM_REG(1024, 10);
-        LDM_REG(2048, 11);
-        LDM_REG(4096, 12);
-        LDM_REG(8192, 13);
-        LDM_REG(16384, 14);
-
-        reg[15].I = CPUReadMemory(address);
-
-        if(!(opcode & (1 << base)))    
-          reg[base].I = temp;
-
-        CPUSwitchMode(reg[17].I & 0x1f, false);
-        if(armState) {
-          armNextPC = reg[15].I & 0xFFFFFFFC;
-          reg[15].I = armNextPC + 4;
-          ARM_PREFETCH;
-        } else {
-          armNextPC = reg[15].I & 0xFFFFFFFE;
-          reg[15].I = armNextPC + 2;
-          THUMB_PREFETCH;
-        }
-      } else {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-
-        if(armMode == 0x11) {
-          LDM_REG(256, R8_FIQ);
-          LDM_REG(512, R9_FIQ);
-          LDM_REG(1024, R10_FIQ);
-          LDM_REG(2048, R11_FIQ);
-          LDM_REG(4096, R12_FIQ);
-        } else {
-          LDM_REG(256, 8);
-          LDM_REG(512, 9);
-          LDM_REG(1024, 10);
-          LDM_REG(2048, 11);
-          LDM_REG(4096, 12);
-        }
-
-        if(armMode != 0x10 && armMode != 0x1f) {
-          LDM_REG(8192, R13_USR);
-          LDM_REG(16384, R14_USR);
-        } else {
-          LDM_REG(8192, 13);
-          LDM_REG(16384, 14);
-        }
-
-        if(!(opcode & (1 << base)))    
-          reg[base].I = temp;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-    break;
-    
-  CASE_16(0x910)
-    {
-      // LDMDB Rn, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = temp & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      LDM_REG(1, 0);
-      LDM_REG(2, 1);
-      LDM_REG(4, 2);
-      LDM_REG(8, 3);
-      LDM_REG(16, 4);
-      LDM_REG(32, 5);
-      LDM_REG(64, 6);
-      LDM_REG(128, 7);
-      LDM_REG(256, 8);
-      LDM_REG(512, 9);
-      LDM_REG(1024, 10);
-      LDM_REG(2048, 11);
-      LDM_REG(4096, 12);
-      LDM_REG(8192, 13);
-      LDM_REG(16384, 14);
-      if(opcode & 32768) {
-        reg[15].I = CPUReadMemory(address);
-
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x930)
-    {
-      // LDMDB Rn!, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = temp & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      LDM_REG(1, 0);
-      LDM_REG(2, 1);
-      LDM_REG(4, 2);
-      LDM_REG(8, 3);
-      LDM_REG(16, 4);
-      LDM_REG(32, 5);
-      LDM_REG(64, 6);
-      LDM_REG(128, 7);
-      LDM_REG(256, 8);
-      LDM_REG(512, 9);
-      LDM_REG(1024, 10);
-      LDM_REG(2048, 11);
-      LDM_REG(4096, 12);
-      LDM_REG(8192, 13);
-      LDM_REG(16384, 14);
-      if(opcode & 32768) {
-        reg[15].I = CPUReadMemory(address);
-
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-      if(!(opcode & (1 << base)))
-        reg[base].I = temp;
-    }
-    break;
-  CASE_16(0x950)
-    {
-      // LDMDB Rn, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = temp & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      if(opcode & 0x8000) {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-        LDM_REG(256, 8);
-        LDM_REG(512, 9);
-        LDM_REG(1024, 10);
-        LDM_REG(2048, 11);
-        LDM_REG(4096, 12);
-        LDM_REG(8192, 13);
-        LDM_REG(16384, 14);
-
-        reg[15].I = CPUReadMemory(address);
-
-        CPUSwitchMode(reg[17].I & 0x1f, false);
-        if(armState) {
-          armNextPC = reg[15].I & 0xFFFFFFFC;
-          reg[15].I = armNextPC + 4;
-          ARM_PREFETCH;
-        } else {
-          armNextPC = reg[15].I & 0xFFFFFFFE;
-          reg[15].I = armNextPC + 2;
-          THUMB_PREFETCH;
-        }
-      } else {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-
-        if(armMode == 0x11) {
-          LDM_REG(256, R8_FIQ);
-          LDM_REG(512, R9_FIQ);
-          LDM_REG(1024, R10_FIQ);
-          LDM_REG(2048, R11_FIQ);
-          LDM_REG(4096, R12_FIQ);
-        } else {
-          LDM_REG(256, 8);
-          LDM_REG(512, 9);
-          LDM_REG(1024, 10);
-          LDM_REG(2048, 11);
-          LDM_REG(4096, 12);
-        }
-
-        if(armMode != 0x10 && armMode != 0x1f) {
-          LDM_REG(8192, R13_USR);
-          LDM_REG(16384, R14_USR);
-        } else {
-          LDM_REG(8192, 13);
-          LDM_REG(16384, 14);
-        }
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x970)
-    {
-      // LDMDB Rn!, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I - 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = temp & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      if(opcode & 0x8000) {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-        LDM_REG(256, 8);
-        LDM_REG(512, 9);
-        LDM_REG(1024, 10);
-        LDM_REG(2048, 11);
-        LDM_REG(4096, 12);
-        LDM_REG(8192, 13);
-        LDM_REG(16384, 14);
-
-        reg[15].I = CPUReadMemory(address);
-
-        if(!(opcode & (1 << base)))    
-          reg[base].I = temp;
-
-        CPUSwitchMode(reg[17].I & 0x1f, false);
-        if(armState) {
-          armNextPC = reg[15].I & 0xFFFFFFFC;
-          reg[15].I = armNextPC + 4;
-          ARM_PREFETCH;
-        } else {
-          armNextPC = reg[15].I & 0xFFFFFFFE;
-          reg[15].I = armNextPC + 2;
-          THUMB_PREFETCH;
-        }
-      } else {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-
-        if(armMode == 0x11) {
-          LDM_REG(256, R8_FIQ);
-          LDM_REG(512, R9_FIQ);
-          LDM_REG(1024, R10_FIQ);
-          LDM_REG(2048, R11_FIQ);
-          LDM_REG(4096, R12_FIQ);
-        } else {
-          LDM_REG(256, 8);
-          LDM_REG(512, 9);
-          LDM_REG(1024, 10);
-          LDM_REG(2048, 11);
-          LDM_REG(4096, 12);
-        }
-
-        if(armMode != 0x10 && armMode != 0x1f) {
-          LDM_REG(8192, R13_USR);
-          LDM_REG(16384, R14_USR);
-        } else {
-          LDM_REG(8192, 13);
-          LDM_REG(16384, 14);
-        }
-
-        if(!(opcode & (1 << base)))    
-          reg[base].I = temp;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-    break;
-    
-  CASE_16(0x990)
-    {
-      // LDMIB Rn, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = (reg[base].I+4) & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      LDM_REG(1, 0);
-      LDM_REG(2, 1);
-      LDM_REG(4, 2);
-      LDM_REG(8, 3);
-      LDM_REG(16, 4);
-      LDM_REG(32, 5);
-      LDM_REG(64, 6);
-      LDM_REG(128, 7);
-      LDM_REG(256, 8);
-      LDM_REG(512, 9);
-      LDM_REG(1024, 10);
-      LDM_REG(2048, 11);
-      LDM_REG(4096, 12);
-      LDM_REG(8192, 13);
-      LDM_REG(16384, 14);
-      if(opcode & 32768) {
-        reg[15].I = CPUReadMemory(address);
-
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x9b0)
-    {
-      // LDMIB Rn!, {Rlist}
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I + 
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = (reg[base].I+4) & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      LDM_REG(1, 0);
-      LDM_REG(2, 1);
-      LDM_REG(4, 2);
-      LDM_REG(8, 3);
-      LDM_REG(16, 4);
-      LDM_REG(32, 5);
-      LDM_REG(64, 6);
-      LDM_REG(128, 7);
-      LDM_REG(256, 8);
-      LDM_REG(512, 9);
-      LDM_REG(1024, 10);
-      LDM_REG(2048, 11);
-      LDM_REG(4096, 12);
-      LDM_REG(8192, 13);
-      LDM_REG(16384, 14);
-      if(opcode & 32768) {
-        reg[15].I = CPUReadMemory(address);
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + dataTicksAccessSeq32(address);
-
-        armNextPC = reg[15].I;
-        reg[15].I += 4;
-        ARM_PREFETCH;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-      if(!(opcode & (1 << base)))
-        reg[base].I = temp;
-    }
-    break;    
-  CASE_16(0x9d0)
-    {
-      // LDMIB Rn, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 address = (reg[base].I+4) & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      if(opcode & 0x8000) {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-        LDM_REG(256, 8);
-        LDM_REG(512, 9);
-        LDM_REG(1024, 10);
-        LDM_REG(2048, 11);
-        LDM_REG(4096, 12);
-        LDM_REG(8192, 13);
-        LDM_REG(16384, 14);
-
-        reg[15].I = CPUReadMemory(address);
-
-        CPUSwitchMode(reg[17].I & 0x1f, false);
-        if(armState) {
-          armNextPC = reg[15].I & 0xFFFFFFFC;
-          reg[15].I = armNextPC + 4;
-          ARM_PREFETCH;
-        } else {
-          armNextPC = reg[15].I & 0xFFFFFFFE;
-          reg[15].I = armNextPC + 2;
-          THUMB_PREFETCH;
-        }
-      } else {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-
-        if(armMode == 0x11) {
-          LDM_REG(256, R8_FIQ);
-          LDM_REG(512, R9_FIQ);
-          LDM_REG(1024, R10_FIQ);
-          LDM_REG(2048, R11_FIQ);
-          LDM_REG(4096, R12_FIQ);
-        } else {
-          LDM_REG(256, 8);
-          LDM_REG(512, 9);
-          LDM_REG(1024, 10);
-          LDM_REG(2048, 11);
-          LDM_REG(4096, 12);
-        }
-
-        if(armMode != 0x10 && armMode != 0x1f) {
-          LDM_REG(8192, R13_USR);
-          LDM_REG(16384, R14_USR);
-        } else {
-          LDM_REG(8192, 13);
-          LDM_REG(16384, 14);
-        }
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-    break;
-  CASE_16(0x9f0)
-    {
-      // LDMIB Rn!, {Rlist}^
-      if (!busPrefetchCount)
-        busPrefetch = busPrefetchEnable;
-      int base = (opcode & 0x000F0000) >> 16;
-      u32 temp = reg[base].I +
-        4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
-      u32 address = (reg[base].I+4) & 0xFFFFFFFC;
-      clockTicks = 0;
-      int offset = 0;
-      if(opcode & 0x8000) {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-        LDM_REG(256, 8);
-        LDM_REG(512, 9);
-        LDM_REG(1024, 10);
-        LDM_REG(2048, 11);
-        LDM_REG(4096, 12);
-        LDM_REG(8192, 13);
-        LDM_REG(16384, 14);
-
-        reg[15].I = CPUReadMemory(address);
-
-        if(!(opcode & (1 << base)))    
-          reg[base].I = temp;
-
-        CPUSwitchMode(reg[17].I & 0x1f, false);
-        if(armState) {
-          armNextPC = reg[15].I & 0xFFFFFFFC;
-          reg[15].I = armNextPC + 4;
-          ARM_PREFETCH;
-        } else {
-          armNextPC = reg[15].I & 0xFFFFFFFE;
-          reg[15].I = armNextPC + 2;
-          THUMB_PREFETCH;
-        }
-      } else {
-        LDM_REG(1, 0);
-        LDM_REG(2, 1);
-        LDM_REG(4, 2);
-        LDM_REG(8, 3);
-        LDM_REG(16, 4);
-        LDM_REG(32, 5);
-        LDM_REG(64, 6);
-        LDM_REG(128, 7);
-
-        if(armMode == 0x11) {
-          LDM_REG(256, R8_FIQ);
-          LDM_REG(512, R9_FIQ);
-          LDM_REG(1024, R10_FIQ);
-          LDM_REG(2048, R11_FIQ);
-          LDM_REG(4096, R12_FIQ);
-        } else {
-          LDM_REG(256, 8);
-          LDM_REG(512, 9);
-          LDM_REG(1024, 10);
-          LDM_REG(2048, 11);
-          LDM_REG(4096, 12);
-        }
-
-        if(armMode != 0x10 && armMode != 0x1f) {
-          LDM_REG(8192, R13_USR);
-          LDM_REG(16384, R14_USR);
-        } else {
-          LDM_REG(8192, 13);
-          LDM_REG(16384, 14);
-        }
-
-        if(!(opcode & (1 << base)))    
-          reg[base].I = temp;
-        if (!offset)
-          clockTicks += 1 + dataTicksAccess32(address);
-        else
-          clockTicks += 1 + dataTicksAccessSeq32(address);
-        clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
-      }
-      clockTicks += 2 + codeTicksAccess32(armNextPC);
-    }
-    break;    
-  CASE_256(0xa00)
-    {
-      // B <offset>
-      int offset = opcode & 0x00FFFFFF;
-      if(offset & 0x00800000) {
-        offset |= 0xFF000000;
-      }
-      offset <<= 2;
-      reg[15].I += offset;
-      armNextPC = reg[15].I;
-      reg[15].I += 4;
-      ARM_PREFETCH;
-      clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
-      clockTicks += 2 + codeTicksAccess32(armNextPC) +
-          codeTicksAccessSeq32(armNextPC);
-      busPrefetchCount=0;
-    }
-    break;
-  CASE_256(0xb00)
-    {
-      // BL <offset>
-      int offset = opcode & 0x00FFFFFF;
-      if(offset & 0x00800000) {
-        offset |= 0xFF000000;
-      }
-      offset <<= 2;
-      reg[14].I = reg[15].I - 4;
-      reg[15].I += offset;
-      armNextPC = reg[15].I;
-      reg[15].I += 4;
-      ARM_PREFETCH;
-      clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
-      clockTicks += 2 + codeTicksAccess32(armNextPC) +
-          codeTicksAccessSeq32(armNextPC);
-      busPrefetchCount=0;
-    }
-    break;
-  CASE_256(0xf00)
-    // SWI <comment>
-    clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
-    clockTicks += 2 + codeTicksAccess32(armNextPC) +
-        codeTicksAccessSeq32(armNextPC);
-    busPrefetchCount=0;
-    CPUSoftwareInterrupt(opcode & 0x00FFFFFF);  
-
-    break;
-#ifdef GP_SUPPORT
-  case 0xe11:
-  case 0xe13:
-  case 0xe15:
-  case 0xe17:
-  case 0xe19:
-  case 0xe1b:
-  case 0xe1d:
-  case 0xe1f:
-    // MRC
-    break;
-  case 0xe01:
-  case 0xe03:
-  case 0xe05:
-  case 0xe07:
-  case 0xe09:
-  case 0xe0b:
-  case 0xe0d:
-  case 0xe0f:
-    // MRC
-    break;    
-#endif
-  default:
-#ifdef DEV_VERSION
-    if(systemVerbose & VERBOSE_UNDEFINED)
-      log("Undefined ARM instruction %08x at %08x\n", opcode,
-          armNextPC-4);
-#endif
-    CPUUndefinedException();
-    break;
-    // END
-  }
-}
-
-if (clockTicks == 0)
-  clockTicks = codeTicksAccessSeq32(oldArmNextPC) + 1;
diff -urN ../VisualBoyAdvance-20061204/src/gtk/Makefile.am src/gtk/Makefile.am
--- ../VisualBoyAdvance-20061204/src/gtk/Makefile.am	2004-05-14 07:57:09 +0900
+++ src/gtk/Makefile.am	2006-12-05 00:18:42 +0900
@@ -49,6 +49,9 @@
 	../Flash.h		\
 	../GBA.cpp		\
 	../GBA.h		\
+	../GBA-arm.cpp		\
+	../GBA-thumb.cpp	\
+	../GBAcpu.h		\
 	../GBAinline.h		\
 	../Gfx.cpp		\
 	../Gfx.h		\
@@ -76,7 +79,6 @@
 	../admame.cpp		\
 	../agbprint.cpp		\
 	../agbprint.h		\
-	../arm-new.h		\
 	../armdis.cpp		\
 	../armdis.h		\
 	../bilinear.cpp		\
@@ -99,7 +101,6 @@
 	../remote.cpp		\
 	../scanline.cpp		\
 	../simple2x.cpp		\
-	../thumb.h		\
 	../unzip.cpp		\
 	../unzip.h
 
diff -urN ../VisualBoyAdvance-20061204/src/gtk/Makefile.in src/gtk/Makefile.in
--- ../VisualBoyAdvance-20061204/src/gtk/Makefile.in	2004-09-30 07:23:40 +0900
+++ src/gtk/Makefile.in	2006-12-05 00:18:42 +0900
@@ -207,6 +207,9 @@
 	../Flash.h		\
 	../GBA.cpp		\
 	../GBA.h		\
+	../GBA-arm.cpp		\
+	../GBA-thumb.cpp	\
+	../GBAcpu.h		\
 	../GBAinline.h		\
 	../Gfx.cpp		\
 	../Gfx.h		\
@@ -234,7 +237,6 @@
 	../admame.cpp		\
 	../agbprint.cpp		\
 	../agbprint.h		\
-	../arm-new.h		\
 	../armdis.cpp		\
 	../armdis.h		\
 	../bilinear.cpp		\
@@ -257,7 +259,6 @@
 	../remote.cpp		\
 	../scanline.cpp		\
 	../simple2x.cpp		\
-	../thumb.h		\
 	../unzip.cpp		\
 	../unzip.h
 
@@ -277,7 +278,7 @@
 libgba_a_LIBADD =
 am_libgba_a_OBJECTS = libgba_a-2xSaI.$(OBJEXT) libgba_a-Cheats.$(OBJEXT) \
 	libgba_a-EEprom.$(OBJEXT) libgba_a-Flash.$(OBJEXT) \
-	libgba_a-GBA.$(OBJEXT) libgba_a-Gfx.$(OBJEXT) \
+	libgba_a-GBA.$(OBJEXT) libgba_a-GBA-arm.$(OBJEXT) libgba_a-GBA-thumb.$(OBJEXT) libgba_a-Gfx.$(OBJEXT) \
 	libgba_a-Globals.$(OBJEXT) libgba_a-Mode0.$(OBJEXT) \
 	libgba_a-Mode1.$(OBJEXT) libgba_a-Mode2.$(OBJEXT) \
 	libgba_a-Mode3.$(OBJEXT) libgba_a-Mode4.$(OBJEXT) \
@@ -323,6 +324,8 @@
 @AMDEP_TRUE@	./$(DEPDIR)/libgba_a-EEprom.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/libgba_a-Flash.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/libgba_a-GBA.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/libgba_a-GBA-arm.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/libgba_a-GBA-thumb.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/libgba_a-Gfx.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/libgba_a-Globals.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/libgba_a-Mode0.Po \
@@ -442,6 +445,8 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgba_a-EEprom.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgba_a-Flash.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgba_a-GBA.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgba_a-GBA-arm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgba_a-GBA-thumb.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgba_a-Gfx.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgba_a-Globals.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgba_a-Mode0.Po@am__quote@
@@ -693,6 +698,50 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgba_a_CPPFLAGS) $(CPPFLAGS) $(libgba_a_CXXFLAGS) $(CXXFLAGS) -c -o libgba_a-GBA.obj `if test -f '../GBA.cpp'; then $(CYGPATH_W) '../GBA.cpp'; else $(CYGPATH_W) '$(srcdir)/../GBA.cpp'; fi`
 
+libgba_a-GBA-arm.o: ../GBA-arm.cpp
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgba_a_CPPFLAGS) $(CPPFLAGS) $(libgba_a_CXXFLAGS) $(CXXFLAGS) -MT libgba_a-GBA-arm.o -MD -MP -MF "$(DEPDIR)/libgba_a-GBA-arm.Tpo" \
+@am__fastdepCXX_TRUE@	  -c -o libgba_a-GBA-arm.o `test -f '../GBA-arm.cpp' || echo '$(srcdir)/'`../GBA-arm.cpp; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libgba_a-GBA-arm.Tpo" "$(DEPDIR)/libgba_a-GBA-arm.Po"; \
+@am__fastdepCXX_TRUE@	else rm -f "$(DEPDIR)/libgba_a-GBA-arm.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='../GBA-arm.cpp' object='libgba_a-GBA-arm.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/libgba_a-GBA-arm.Po' tmpdepfile='$(DEPDIR)/libgba_a-GBA-arm.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgba_a_CPPFLAGS) $(CPPFLAGS) $(libgba_a_CXXFLAGS) $(CXXFLAGS) -c -o libgba_a-GBA-arm.o `test -f '../GBA-arm.cpp' || echo '$(srcdir)/'`../GBA-arm.cpp
+
+libgba_a-GBA-arm.obj: ../GBA-arm.cpp
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgba_a_CPPFLAGS) $(CPPFLAGS) $(libgba_a_CXXFLAGS) $(CXXFLAGS) -MT libgba_a-GBA-arm.obj -MD -MP -MF "$(DEPDIR)/libgba_a-GBA-arm.Tpo" \
+@am__fastdepCXX_TRUE@	  -c -o libgba_a-GBA-arm.obj `if test -f '../GBA-arm.cpp'; then $(CYGPATH_W) '../GBA-arm.cpp'; else $(CYGPATH_W) '$(srcdir)/../GBA-arm.cpp'; fi`; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libgba_a-GBA-arm.Tpo" "$(DEPDIR)/libgba_a-GBA-arm.Po"; \
+@am__fastdepCXX_TRUE@	else rm -f "$(DEPDIR)/libgba_a-GBA-arm.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='../GBA-arm.cpp' object='libgba_a-GBA-arm.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/libgba_a-GBA-arm.Po' tmpdepfile='$(DEPDIR)/libgba_a-GBA-arm.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgba_a_CPPFLAGS) $(CPPFLAGS) $(libgba_a_CXXFLAGS) $(CXXFLAGS) -c -o libgba_a-GBA-arm.obj `if test -f '../GBA-arm.cpp'; then $(CYGPATH_W) '../GBA-arm.cpp'; else $(CYGPATH_W) '$(srcdir)/../GBA-arm.cpp'; fi`
+
+libgba_a-GBA-thumb.o: ../GBA-thumb.cpp
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgba_a_CPPFLAGS) $(CPPFLAGS) $(libgba_a_CXXFLAGS) $(CXXFLAGS) -MT libgba_a-GBA-thumb.o -MD -MP -MF "$(DEPDIR)/libgba_a-GBA-thumb.Tpo" \
+@am__fastdepCXX_TRUE@	  -c -o libgba_a-GBA-thumb.o `test -f '../GBA-thumb.cpp' || echo '$(srcdir)/'`../GBA-thumb.cpp; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libgba_a-GBA-thumb.Tpo" "$(DEPDIR)/libgba_a-GBA-thumb.Po"; \
+@am__fastdepCXX_TRUE@	else rm -f "$(DEPDIR)/libgba_a-GBA-thumb.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='../GBA-thumb.cpp' object='libgba_a-GBA-thumb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/libgba_a-GBA-thumb.Po' tmpdepfile='$(DEPDIR)/libgba_a-GBA-thumb.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgba_a_CPPFLAGS) $(CPPFLAGS) $(libgba_a_CXXFLAGS) $(CXXFLAGS) -c -o libgba_a-GBA-thumb.o `test -f '../GBA-thumb.cpp' || echo '$(srcdir)/'`../GBA-thumb.cpp
+
+libgba_a-GBA-thumb.obj: ../GBA-thumb.cpp
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgba_a_CPPFLAGS) $(CPPFLAGS) $(libgba_a_CXXFLAGS) $(CXXFLAGS) -MT libgba_a-GBA-thumb.obj -MD -MP -MF "$(DEPDIR)/libgba_a-GBA-thumb.Tpo" \
+@am__fastdepCXX_TRUE@	  -c -o libgba_a-GBA-thumb.obj `if test -f '../GBA-thumb.cpp'; then $(CYGPATH_W) '../GBA-thumb.cpp'; else $(CYGPATH_W) '$(srcdir)/../GBA-thumb.cpp'; fi`; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libgba_a-GBA-thumb.Tpo" "$(DEPDIR)/libgba_a-GBA-thumb.Po"; \
+@am__fastdepCXX_TRUE@	else rm -f "$(DEPDIR)/libgba_a-GBA-thumb.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='../GBA-thumb.cpp' object='libgba_a-GBA-thumb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/libgba_a-GBA-thumb.Po' tmpdepfile='$(DEPDIR)/libgba_a-GBA-thumb.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgba_a_CPPFLAGS) $(CPPFLAGS) $(libgba_a_CXXFLAGS) $(CXXFLAGS) -c -o libgba_a-GBA-thumb.obj `if test -f '../GBA-thumb.cpp'; then $(CYGPATH_W) '../GBA-thumb.cpp'; else $(CYGPATH_W) '$(srcdir)/../GBA-thumb.cpp'; fi`
+
 libgba_a-Gfx.o: ../Gfx.cpp
 @am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgba_a_CPPFLAGS) $(CPPFLAGS) $(libgba_a_CXXFLAGS) $(CXXFLAGS) -MT libgba_a-Gfx.o -MD -MP -MF "$(DEPDIR)/libgba_a-Gfx.Tpo" \
 @am__fastdepCXX_TRUE@	  -c -o libgba_a-Gfx.o `test -f '../Gfx.cpp' || echo '$(srcdir)/'`../Gfx.cpp; \
diff -urN ../VisualBoyAdvance-20061204/src/sdl/Makefile.am src/sdl/Makefile.am
--- ../VisualBoyAdvance-20061204/src/sdl/Makefile.am	2004-05-21 06:01:30 +0900
+++ src/sdl/Makefile.am	2006-12-05 00:18:42 +0900
@@ -16,6 +16,9 @@
 	../Flash.h		\
 	../GBA.cpp		\
 	../GBA.h		\
+	../GBA-arm.cpp		\
+	../GBA-thumb.cpp	\
+	../GBAcpu.h		\
 	../GBAinline.h		\
 	../Gfx.cpp		\
 	../Gfx.h		\
@@ -43,7 +46,6 @@
 	../admame.cpp		\
 	../agbprint.cpp		\
 	../agbprint.h		\
-	../arm-new.h		\
 	../armdis.cpp		\
 	../armdis.h		\
 	../bilinear.cpp		\
@@ -71,7 +73,6 @@
 	../remote.cpp		\
 	../scanline.cpp		\
 	../simple2x.cpp		\
-	../thumb.h		\
 	../unzip.cpp		\
 	../unzip.h
 
@@ -93,6 +94,9 @@
 	../Flash.h		\
 	../GBA.cpp		\
 	../GBA.h		\
+	../GBA-arm.cpp		\
+	../GBA-thumb.cpp	\
+	../GBAcpu.h		\
 	../GBAinline.h		\
 	../Gfx.cpp		\
 	../Gfx.h		\
@@ -120,7 +124,6 @@
 	../admame.cpp		\
 	../agbprint.cpp		\
 	../agbprint.h		\
-	../arm-new.h		\
 	../armdis.cpp		\
 	../armdis.h		\
 	../bios.cpp		\
@@ -143,7 +146,6 @@
 	../remote.cpp		\
 	../scanline.cpp		\
 	../simple2x.cpp		\
-	../thumb.h		\
 	../unzip.cpp		\
 	../unzip.h
 
diff -urN ../VisualBoyAdvance-20061204/src/sdl/Makefile.in src/sdl/Makefile.in
--- ../VisualBoyAdvance-20061204/src/sdl/Makefile.in	2004-09-30 07:23:39 +0900
+++ src/sdl/Makefile.in	2006-12-05 00:18:42 +0900
@@ -172,6 +172,9 @@
 	../Flash.h		\
 	../GBA.cpp		\
 	../GBA.h		\
+	../GBA-arm.cpp		\
+	../GBA-thumb.cpp	\
+	../GBAcpu.h		\
 	../GBAinline.h		\
 	../Gfx.cpp		\
 	../Gfx.h		\
@@ -199,7 +202,6 @@
 	../admame.cpp		\
 	../agbprint.cpp		\
 	../agbprint.h		\
-	../arm-new.h		\
 	../armdis.cpp		\
 	../armdis.h		\
 	../bilinear.cpp		\
@@ -227,7 +229,6 @@
 	../remote.cpp		\
 	../scanline.cpp		\
 	../simple2x.cpp		\
-	../thumb.h		\
 	../unzip.cpp		\
 	../unzip.h
 
@@ -250,6 +251,9 @@
 	../Flash.h		\
 	../GBA.cpp		\
 	../GBA.h		\
+	../GBA-arm.cpp		\
+	../GBA-thumb.cpp	\
+	../GBAcpu.h		\
 	../GBAinline.h		\
 	../Gfx.cpp		\
 	../Gfx.h		\
@@ -277,7 +281,6 @@
 	../admame.cpp		\
 	../agbprint.cpp		\
 	../agbprint.h		\
-	../arm-new.h		\
 	../armdis.cpp		\
 	../armdis.h		\
 	../bios.cpp		\
@@ -300,7 +303,6 @@
 	../remote.cpp		\
 	../scanline.cpp		\
 	../simple2x.cpp		\
-	../thumb.h		\
 	../unzip.cpp		\
 	../unzip.h
 
@@ -326,7 +328,7 @@
 
 am_TestEmu_OBJECTS = TestEmu.$(OBJEXT) debugger.$(OBJEXT) \
 	2xSaI.$(OBJEXT) Cheats.$(OBJEXT) EEprom.$(OBJEXT) \
-	Flash.$(OBJEXT) GBA.$(OBJEXT) Gfx.$(OBJEXT) Globals.$(OBJEXT) \
+	Flash.$(OBJEXT) GBA.$(OBJEXT) GBA-arm.$(OBJEXT) GBA-thumb.$(OBJEXT) Gfx.$(OBJEXT) Globals.$(OBJEXT) \
 	Mode0.$(OBJEXT) Mode1.$(OBJEXT) Mode2.$(OBJEXT) Mode3.$(OBJEXT) \
 	Mode4.$(OBJEXT) Mode5.$(OBJEXT) RTC.$(OBJEXT) Sound.$(OBJEXT) \
 	Sram.$(OBJEXT) Text.$(OBJEXT) Util.$(OBJEXT) admame.$(OBJEXT) \
@@ -339,7 +341,7 @@
 TestEmu_LDFLAGS =
 am_VisualBoyAdvance_OBJECTS = SDL.$(OBJEXT) debugger.$(OBJEXT) \
 	2xSaI.$(OBJEXT) Cheats.$(OBJEXT) EEprom.$(OBJEXT) \
-	Flash.$(OBJEXT) GBA.$(OBJEXT) Gfx.$(OBJEXT) Globals.$(OBJEXT) \
+	Flash.$(OBJEXT) GBA.$(OBJEXT) GBA-arm.$(OBJEXT) GBA-thumb.$(OBJEXT) Gfx.$(OBJEXT) Globals.$(OBJEXT) \
 	Mode0.$(OBJEXT) Mode1.$(OBJEXT) Mode2.$(OBJEXT) Mode3.$(OBJEXT) \
 	Mode4.$(OBJEXT) Mode5.$(OBJEXT) RTC.$(OBJEXT) Sound.$(OBJEXT) \
 	Sram.$(OBJEXT) Text.$(OBJEXT) Util.$(OBJEXT) admame.$(OBJEXT) \
@@ -357,7 +359,7 @@
 am__depfiles_maybe = depfiles
 @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/2xSaI.Po ./$(DEPDIR)/Cheats.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/EEprom.Po ./$(DEPDIR)/Flash.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/GBA.Po ./$(DEPDIR)/Gfx.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/GBA.Po ./$(DEPDIR)/GBA-arm.Po ./$(DEPDIR)/GBA-thumb.Po ./$(DEPDIR)/Gfx.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/Globals.Po ./$(DEPDIR)/Mode0.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/Mode1.Po ./$(DEPDIR)/Mode2.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/Mode3.Po ./$(DEPDIR)/Mode4.Po \
@@ -443,6 +445,8 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EEprom.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Flash.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GBA.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GBA-arm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GBA-thumb.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Gfx.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Globals.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mode0.Po@am__quote@
@@ -700,6 +704,50 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GBA.obj `if test -f '../GBA.cpp'; then $(CYGPATH_W) '../GBA.cpp'; else $(CYGPATH_W) '$(srcdir)/../GBA.cpp'; fi`
 
+GBA-arm.o: ../GBA-arm.cpp
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT GBA-arm.o -MD -MP -MF "$(DEPDIR)/GBA-arm.Tpo" \
+@am__fastdepCXX_TRUE@	  -c -o GBA-arm.o `test -f '../GBA-arm.cpp' || echo '$(srcdir)/'`../GBA-arm.cpp; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/GBA-arm.Tpo" "$(DEPDIR)/GBA-arm.Po"; \
+@am__fastdepCXX_TRUE@	else rm -f "$(DEPDIR)/GBA-arm.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='../GBA-arm.cpp' object='GBA-arm.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/GBA-arm.Po' tmpdepfile='$(DEPDIR)/GBA-arm.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GBA-arm.o `test -f '../GBA-arm.cpp' || echo '$(srcdir)/'`../GBA-arm.cpp
+
+GBA-arm.obj: ../GBA-arm.cpp
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT GBA-arm.obj -MD -MP -MF "$(DEPDIR)/GBA-arm.Tpo" \
+@am__fastdepCXX_TRUE@	  -c -o GBA-arm.obj `if test -f '../GBA-arm.cpp'; then $(CYGPATH_W) '../GBA-arm.cpp'; else $(CYGPATH_W) '$(srcdir)/../GBA-arm.cpp'; fi`; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/GBA-arm.Tpo" "$(DEPDIR)/GBA-arm.Po"; \
+@am__fastdepCXX_TRUE@	else rm -f "$(DEPDIR)/GBA-arm.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='../GBA-arm.cpp' object='GBA-arm.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/GBA-arm.Po' tmpdepfile='$(DEPDIR)/GBA-arm.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GBA-arm.obj `if test -f '../GBA-arm.cpp'; then $(CYGPATH_W) '../GBA-arm.cpp'; else $(CYGPATH_W) '$(srcdir)/../GBA-arm.cpp'; fi`
+
+GBA-thumb.o: ../GBA-thumb.cpp
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT GBA-thumb.o -MD -MP -MF "$(DEPDIR)/GBA-thumb.Tpo" \
+@am__fastdepCXX_TRUE@	  -c -o GBA-thumb.o `test -f '../GBA-thumb.cpp' || echo '$(srcdir)/'`../GBA-thumb.cpp; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/GBA-thumb.Tpo" "$(DEPDIR)/GBA-thumb.Po"; \
+@am__fastdepCXX_TRUE@	else rm -f "$(DEPDIR)/GBA-thumb.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='../GBA-thumb.cpp' object='GBA-thumb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/GBA-thumb.Po' tmpdepfile='$(DEPDIR)/GBA-thumb.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GBA-thumb.o `test -f '../GBA-thumb.cpp' || echo '$(srcdir)/'`../GBA-thumb.cpp
+
+GBA-thumb.obj: ../GBA-thumb.cpp
+@am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT GBA-thumb.obj -MD -MP -MF "$(DEPDIR)/GBA-thumb.Tpo" \
+@am__fastdepCXX_TRUE@	  -c -o GBA-thumb.obj `if test -f '../GBA-thumb.cpp'; then $(CYGPATH_W) '../GBA-thumb.cpp'; else $(CYGPATH_W) '$(srcdir)/../GBA-thumb.cpp'; fi`; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/GBA-thumb.Tpo" "$(DEPDIR)/GBA-thumb.Po"; \
+@am__fastdepCXX_TRUE@	else rm -f "$(DEPDIR)/GBA-thumb.Tpo"; exit 1; \
+@am__fastdepCXX_TRUE@	fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='../GBA-thumb.cpp' object='GBA-thumb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	depfile='$(DEPDIR)/GBA-thumb.Po' tmpdepfile='$(DEPDIR)/GBA-thumb.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o GBA-thumb.obj `if test -f '../GBA-thumb.cpp'; then $(CYGPATH_W) '../GBA-thumb.cpp'; else $(CYGPATH_W) '$(srcdir)/../GBA-thumb.cpp'; fi`
+
 Gfx.o: ../Gfx.cpp
 @am__fastdepCXX_TRUE@	if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT Gfx.o -MD -MP -MF "$(DEPDIR)/Gfx.Tpo" \
 @am__fastdepCXX_TRUE@	  -c -o Gfx.o `test -f '../Gfx.cpp' || echo '$(srcdir)/'`../Gfx.cpp; \
diff -urN ../VisualBoyAdvance-20061204/src/thumb.h src/thumb.h
--- ../VisualBoyAdvance-20061204/src/thumb.h	2006-06-25 05:21:47 +0900
+++ src/thumb.h	2006-12-05 00:18:42 +0900
@@ -1,2262 +0,0 @@
-// -*- C++ -*-
-// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
-// Copyright (C) 1999-2003 Forgotten
-// Copyright (C) 2005-2006 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.
-
-// The following define updates oldreg when debugger_last is activated
-
-#define UPDATE_OLD_REG \
-		   if (debugger_last) { \
-			   sprintf(oldbuffer,"%08x", armState ? reg[15].I - 4 : reg[15].I - 4); \
-			   for (xxx=0; xxx<18; xxx++){ \
-				   oldreg[xxx]=reg[xxx].I; \
-			   } \
-		   } 
-
-
-#ifdef C_CORE
-#define NEG(i) ((i) >> 31)
-#define POS(i) ((~(i)) >> 31)
-#define ADDCARRY(a, b, c) \
-  C_FLAG = ((NEG(a) & NEG(b)) |\
-            (NEG(a) & POS(c)) |\
-            (NEG(b) & POS(c))) ? true : false;
-#define ADDOVERFLOW(a, b, c) \
-  V_FLAG = ((NEG(a) & NEG(b) & POS(c)) |\
-            (POS(a) & POS(b) & NEG(c))) ? true : false;
-#define SUBCARRY(a, b, c) \
-  C_FLAG = ((NEG(a) & POS(b)) |\
-            (NEG(a) & POS(c)) |\
-            (POS(b) & POS(c))) ? true : false;
-#define SUBOVERFLOW(a, b, c)\
-  V_FLAG = ((NEG(a) & POS(b) & POS(c)) |\
-            (POS(a) & NEG(b) & NEG(c))) ? true : false;
-#define ADD_RD_RS_RN \
-   {\
-     u32 lhs = reg[source].I;\
-     u32 rhs = value;\
-     u32 res = lhs + rhs;\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     ADDCARRY(lhs, rhs, res);\
-     ADDOVERFLOW(lhs, rhs, res);\
-   }
-#define ADD_RD_RS_O3 \
-   {\
-     u32 lhs = reg[source].I;\
-     u32 rhs = value;\
-     u32 res = lhs + rhs;\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     ADDCARRY(lhs, rhs, res);\
-     ADDOVERFLOW(lhs, rhs, res);\
-   }
-#define ADD_RN_O8(d) \
-   {\
-     u32 lhs = reg[(d)].I;\
-     u32 rhs = (opcode & 255);\
-     u32 res = lhs + rhs;\
-     reg[(d)].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     ADDCARRY(lhs, rhs, res);\
-     ADDOVERFLOW(lhs, rhs, res);\
-   }
-#define CMN_RD_RS \
-   {\
-     u32 lhs = reg[dest].I;\
-     u32 rhs = value;\
-     u32 res = lhs + rhs;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     ADDCARRY(lhs, rhs, res);\
-     ADDOVERFLOW(lhs, rhs, res);\
-   }
-#define ADC_RD_RS \
-   {\
-     u32 lhs = reg[dest].I;\
-     u32 rhs = value;\
-     u32 res = lhs + rhs + (u32)C_FLAG;\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     ADDCARRY(lhs, rhs, res);\
-     ADDOVERFLOW(lhs, rhs, res);\
-   }
-#define SUB_RD_RS_RN \
-   {\
-     u32 lhs = reg[source].I;\
-     u32 rhs = value;\
-     u32 res = lhs - rhs;\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(lhs, rhs, res);\
-     SUBOVERFLOW(lhs, rhs, res);\
-   }
-#define SUB_RD_RS_O3 \
-   {\
-     u32 lhs = reg[source].I;\
-     u32 rhs = value;\
-     u32 res = lhs - rhs;\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(lhs, rhs, res);\
-     SUBOVERFLOW(lhs, rhs, res);\
-   }
-#define SUB_RN_O8(d) \
-   {\
-     u32 lhs = reg[(d)].I;\
-     u32 rhs = (opcode & 255);\
-     u32 res = lhs - rhs;\
-     reg[(d)].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(lhs, rhs, res);\
-     SUBOVERFLOW(lhs, rhs, res);\
-   }
-#define CMP_RN_O8(d) \
-   {\
-     u32 lhs = reg[(d)].I;\
-     u32 rhs = (opcode & 255);\
-     u32 res = lhs - rhs;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(lhs, rhs, res);\
-     SUBOVERFLOW(lhs, rhs, res);\
-   }
-#define SBC_RD_RS \
-   {\
-     u32 lhs = reg[dest].I;\
-     u32 rhs = value;\
-     u32 res = lhs - rhs - !((u32)C_FLAG);\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(lhs, rhs, res);\
-     SUBOVERFLOW(lhs, rhs, res);\
-   }
-#define LSL_RD_RM_I5 \
-   {\
-     C_FLAG = (reg[source].I >> (32 - shift)) & 1 ? true : false;\
-     value = reg[source].I << shift;\
-   }
-#define LSL_RD_RS \
-   {\
-     C_FLAG = (reg[dest].I >> (32 - value)) & 1 ? true : false;\
-     value = reg[dest].I << value;\
-   }
-#define LSR_RD_RM_I5 \
-   {\
-     C_FLAG = (reg[source].I >> (shift - 1)) & 1 ? true : false;\
-     value = reg[source].I >> shift;\
-   }
-#define LSR_RD_RS \
-   {\
-     C_FLAG = (reg[dest].I >> (value - 1)) & 1 ? true : false;\
-     value = reg[dest].I >> value;\
-   }
-#define ASR_RD_RM_I5 \
-   {\
-     C_FLAG = ((s32)reg[source].I >> (int)(shift - 1)) & 1 ? true : false;\
-     value = (s32)reg[source].I >> (int)shift;\
-   }
-#define ASR_RD_RS \
-   {\
-     C_FLAG = ((s32)reg[dest].I >> (int)(value - 1)) & 1 ? true : false;\
-     value = (s32)reg[dest].I >> (int)value;\
-   }
-#define ROR_RD_RS \
-   {\
-     C_FLAG = (reg[dest].I >> (value - 1)) & 1 ? true : false;\
-     value = ((reg[dest].I << (32 - value)) |\
-              (reg[dest].I >> value));\
-   }
-#define NEG_RD_RS \
-   {\
-     u32 lhs = reg[source].I;\
-     u32 rhs = 0;\
-     u32 res = rhs - lhs;\
-     reg[dest].I = res;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(rhs, lhs, res);\
-     SUBOVERFLOW(rhs, lhs, res);\
-   }
-#define CMP_RD_RS \
-   {\
-     u32 lhs = reg[dest].I;\
-     u32 rhs = value;\
-     u32 res = lhs - rhs;\
-     Z_FLAG = (res == 0) ? true : false;\
-     N_FLAG = NEG(res) ? true : false;\
-     SUBCARRY(lhs, rhs, res);\
-     SUBOVERFLOW(lhs, rhs, res);\
-   }
-#else
-#ifdef __GNUC__
-#ifdef __POWERPC__
-            #define ADD_RD_RS_RN \
-            {										\
-                register int Flags;					\
-                register int Result;				\
-                asm volatile("addco. %0, %2, %3\n"	\
-                            "mcrxr cr1\n"			\
-                            "mfcr %1\n"				\
-                            : "=r" (Result), 		\
-                              "=r" (Flags)			\
-                            : "r" (reg[source].I), 	\
-                              "r" (value)			\
-                            );						\
-                reg[dest].I = Result;				\
-                Z_FLAG = (Flags >> 29) & 1;			\
-                N_FLAG = (Flags >> 31) & 1;			\
-                C_FLAG = (Flags >> 25) & 1;			\
-                V_FLAG = (Flags >> 26) & 1;			\
-            }
-            #define ADD_RD_RS_O3 ADD_RD_RS_RN
-            #define ADD_RN_O8(d) \
-            {\
-                register int Flags;					\
-                register int Result;				\
-                asm volatile("addco. %0, %2, %3\n"	\
-                            "mcrxr cr1\n"			\
-                            "mfcr %1\n"				\
-                            : "=r" (Result), 		\
-                              "=r" (Flags)			\
-                            : "r" (reg[(d)].I), 	\
-                              "r" (opcode & 255)	\
-                            );						\
-                reg[(d)].I = Result;				\
-                Z_FLAG = (Flags >> 29) & 1;			\
-                N_FLAG = (Flags >> 31) & 1;			\
-                C_FLAG = (Flags >> 25) & 1;			\
-                V_FLAG = (Flags >> 26) & 1;			\
-            }
-            #define CMN_RD_RS \
-            {\
-                register int Flags;					\
-                register int Result;				\
-                asm volatile("addco. %0, %2, %3\n"	\
-                            "mcrxr cr1\n"			\
-                            "mfcr %1\n"				\
-                            : "=r" (Result), 		\
-                              "=r" (Flags)			\
-                            : "r" (reg[dest].I), 	\
-                              "r" (value)			\
-                            );						\
-                Z_FLAG = (Flags >> 29) & 1;			\
-                N_FLAG = (Flags >> 31) & 1;			\
-                C_FLAG = (Flags >> 25) & 1;			\
-                V_FLAG = (Flags >> 26) & 1;			\
-            }
-            #define ADC_RD_RS \
-            {\
-                register int Flags;					\
-                register int Result;				\
-                asm volatile("mtspr xer, %4\n"		\
-                             "addeo. %0, %2, %3\n"	\
-                             "mcrxr cr1\n"			\
-                             "mfcr	%1\n"			\
-                             : "=r" (Result),		\
-                               "=r" (Flags)			\
-                             : "r" (reg[dest].I),	\
-                               "r" (value),			\
-                               "r" (C_FLAG << 29)	\
-                             );						\
-                reg[dest].I = Result;				\
-                Z_FLAG = (Flags >> 29) & 1;			\
-                N_FLAG = (Flags >> 31) & 1;			\
-                C_FLAG = (Flags >> 25) & 1;			\
-                V_FLAG = (Flags >> 26) & 1;			\
-            }
-            #define SUB_RD_RS_RN \
-            {\
-                register int Flags;					\
-                register int Result;				\
-                asm volatile("subco. %0, %2, %3\n"	\
-                            "mcrxr cr1\n"			\
-                            "mfcr %1\n"				\
-                            : "=r" (Result), 		\
-                              "=r" (Flags)			\
-                            : "r" (reg[source].I), 	\
-                              "r" (value)			\
-                            );						\
-                reg[dest].I = Result;				\
-                Z_FLAG = (Flags >> 29) & 1;			\
-                N_FLAG = (Flags >> 31) & 1;			\
-                C_FLAG = (Flags >> 25) & 1;			\
-                V_FLAG = (Flags >> 26) & 1;			\
-            }
-            #define SUB_RD_RS_O3 SUB_RD_RS_RN
-            #define SUB_RN_O8(d) \
-            {\
-                register int Flags;					\
-                register int Result;				\
-                asm volatile("subco. %0, %2, %3\n"	\
-                            "mcrxr cr1\n"			\
-                            "mfcr %1\n"				\
-                            : "=r" (Result), 		\
-                              "=r" (Flags)			\
-                            : "r" (reg[(d)].I), 	\
-                              "r" (opcode & 255)	\
-                            );						\
-                reg[(d)].I = Result;				\
-                Z_FLAG = (Flags >> 29) & 1;			\
-                N_FLAG = (Flags >> 31) & 1;			\
-                C_FLAG = (Flags >> 25) & 1;			\
-                V_FLAG = (Flags >> 26) & 1;			\
-            }
-            #define CMP_RN_O8(d) \
-            {\
-                register int Flags;					\
-                register int Result;				\
-                asm volatile("subco. %0, %2, %3\n"	\
-                            "mcrxr cr1\n"			\
-                            "mfcr %1\n"				\
-                            : "=r" (Result), 		\
-                              "=r" (Flags)			\
-                            : "r" (reg[(d)].I), 	\
-                              "r" (opcode & 255)	\
-                            );						\
-                Z_FLAG = (Flags >> 29) & 1;			\
-                N_FLAG = (Flags >> 31) & 1;			\
-                C_FLAG = (Flags >> 25) & 1;			\
-                V_FLAG = (Flags >> 26) & 1;			\
-            }
-            #define SBC_RD_RS \
-            {\
-                register int Flags;					\
-                register int Result;				\
-                asm volatile("mtspr xer, %4\n"		\
-                             "subfeo. %0, %3, %2\n"	\
-                             "mcrxr cr1\n"			\
-                             "mfcr	%1\n"			\
-                             : "=r" (Result),		\
-                               "=r" (Flags)			\
-                             : "r" (reg[dest].I),	\
-                               "r" (value),			\
-                               "r" (C_FLAG << 29) 	\
-                             );						\
-                reg[dest].I = Result;				\
-                Z_FLAG = (Flags >> 29) & 1;			\
-                N_FLAG = (Flags >> 31) & 1;			\
-                C_FLAG = (Flags >> 25) & 1;			\
-                V_FLAG = (Flags >> 26) & 1;			\
-            }
-            #define LSL_RD_RM_I5 \
-            {\
-                C_FLAG = (reg[source].I >> (32 - shift)) & 1 ? true : false;\
-                value = reg[source].I << shift;\
-            }
-            #define LSL_RD_RS \
-            {\
-                C_FLAG = (reg[dest].I >> (32 - value)) & 1 ? true : false;\
-                value = reg[dest].I << value;\
-            }
-            #define LSR_RD_RM_I5 \
-            {\
-                C_FLAG = (reg[source].I >> (shift - 1)) & 1 ? true : false;\
-                value = reg[source].I >> shift;\
-            }
-            #define LSR_RD_RS \
-            {\
-                C_FLAG = (reg[dest].I >> (value - 1)) & 1 ? true : false;\
-                value = reg[dest].I >> value;\
-            }
-            #define ASR_RD_RM_I5 \
-            {\
-                C_FLAG = ((s32)reg[source].I >> (int)(shift - 1)) & 1 ? true : false;\
-                value = (s32)reg[source].I >> (int)shift;\
-            }
-            #define ASR_RD_RS \
-            {\
-                C_FLAG = ((s32)reg[dest].I >> (int)(value - 1)) & 1 ? true : false;\
-                value = (s32)reg[dest].I >> (int)value;\
-            }
-            #define ROR_RD_RS \
-            {\
-                C_FLAG = (reg[dest].I >> (value - 1)) & 1 ? true : false;\
-                value = ((reg[dest].I << (32 - value)) |\
-                        (reg[dest].I >> value));\
-            }
-            #define NEG_RD_RS \
-            {\
-                register int Flags;					\
-                register int Result;				\
-                asm volatile("subfco. %0, %2, %3\n"	\
-                            "mcrxr cr1\n"			\
-                            "mfcr %1\n"				\
-                            : "=r" (Result), 		\
-                              "=r" (Flags)			\
-                            : "r" (reg[source].I), 	\
-                              "r" (0)				\
-                            );						\
-                reg[dest].I = Result;				\
-                Z_FLAG = (Flags >> 29) & 1;			\
-                N_FLAG = (Flags >> 31) & 1;			\
-                C_FLAG = (Flags >> 25) & 1;			\
-                V_FLAG = (Flags >> 26) & 1;			\
-            }
-            #define CMP_RD_RS \
-            {\
-                register int Flags;					\
-                register int Result;				\
-                asm volatile("subco. %0, %2, %3\n"	\
-                            "mcrxr cr1\n"			\
-                            "mfcr %1\n"				\
-                            : "=r" (Result), 		\
-                              "=r" (Flags)			\
-                            : "r" (reg[dest].I), 	\
-                              "r" (value)			\
-                            );						\
-                Z_FLAG = (Flags >> 29) & 1;			\
-                N_FLAG = (Flags >> 31) & 1;			\
-                C_FLAG = (Flags >> 25) & 1;			\
-                V_FLAG = (Flags >> 26) & 1;			\
-            }
-#else
-#define ADD_RD_RS_RN \
-     asm ("add %1, %%ebx;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setcb C_FLAG;"\
-          "setob V_FLAG;"\
-          : "=b" (reg[dest].I)\
-          : "r" (value), "b" (reg[source].I));
-#define ADD_RD_RS_O3 \
-     asm ("add %1, %%ebx;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setcb C_FLAG;"\
-          "setob V_FLAG;"\
-          : "=b" (reg[dest].I)\
-          : "r" (value), "b" (reg[source].I));
-#define ADD_RN_O8(d) \
-     asm ("add %1, %%ebx;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setcb C_FLAG;"\
-          "setob V_FLAG;"\
-          : "=b" (reg[(d)].I)\
-          : "r" (opcode & 255), "b" (reg[(d)].I));
-#define CMN_RD_RS \
-     asm ("add %0, %1;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setcb C_FLAG;"\
-          "setob V_FLAG;"\
-          : \
-          : "r" (value), "r" (reg[dest].I):"1");
-#define ADC_RD_RS \
-     asm ("bt $0, C_FLAG;"\
-          "adc %1, %%ebx;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setcb C_FLAG;"\
-          "setob V_FLAG;"\
-          : "=b" (reg[dest].I)\
-          : "r" (value), "b" (reg[dest].I));
-#define SUB_RD_RS_RN \
-     asm ("sub %1, %%ebx;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setncb C_FLAG;"\
-          "setob V_FLAG;"\
-          : "=b" (reg[dest].I)\
-          : "r" (value), "b" (reg[source].I));
-#define SUB_RD_RS_O3 \
-     asm ("sub %1, %%ebx;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setncb C_FLAG;"\
-          "setob V_FLAG;"\
-          : "=b" (reg[dest].I)\
-          : "r" (value), "b" (reg[source].I));
-#define SUB_RN_O8(d) \
-     asm ("sub %1, %%ebx;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setncb C_FLAG;"\
-          "setob V_FLAG;"\
-          : "=b" (reg[(d)].I)\
-          : "r" (opcode & 255), "b" (reg[(d)].I));
-#define CMP_RN_O8(d) \
-     asm ("sub %0, %1;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setncb C_FLAG;"\
-          "setob V_FLAG;"\
-          : \
-          : "r" (opcode & 255), "r" (reg[(d)].I) : "1");
-#define SBC_RD_RS \
-     asm volatile ("bt $0, C_FLAG;"\
-                   "cmc;"\
-                   "sbb %1, %%ebx;"\
-                   "setsb N_FLAG;"\
-                   "setzb Z_FLAG;"\
-                   "setncb C_FLAG;"\
-                   "setob V_FLAG;"\
-                   : "=b" (reg[dest].I)\
-                   : "r" (value), "b" (reg[dest].I) : "cc", "memory");
-#define LSL_RD_RM_I5 \
-       asm ("shl %%cl, %%eax;"\
-            "setcb C_FLAG;"\
-            : "=a" (value)\
-            : "a" (reg[source].I), "c" (shift));
-#define LSL_RD_RS \
-         asm ("shl %%cl, %%eax;"\
-              "setcb C_FLAG;"\
-              : "=a" (value)\
-              : "a" (reg[dest].I), "c" (value));
-#define LSR_RD_RM_I5 \
-       asm ("shr %%cl, %%eax;"\
-            "setcb C_FLAG;"\
-            : "=a" (value)\
-            : "a" (reg[source].I), "c" (shift));
-#define LSR_RD_RS \
-         asm ("shr %%cl, %%eax;"\
-              "setcb C_FLAG;"\
-              : "=a" (value)\
-              : "a" (reg[dest].I), "c" (value));
-#define ASR_RD_RM_I5 \
-     asm ("sar %%cl, %%eax;"\
-          "setcb C_FLAG;"\
-          : "=a" (value)\
-          : "a" (reg[source].I), "c" (shift));
-#define ASR_RD_RS \
-         asm ("sar %%cl, %%eax;"\
-              "setcb C_FLAG;"\
-              : "=a" (value)\
-              : "a" (reg[dest].I), "c" (value));
-#define ROR_RD_RS \
-         asm ("ror %%cl, %%eax;"\
-              "setcb C_FLAG;"\
-              : "=a" (value)\
-              : "a" (reg[dest].I), "c" (value));
-#define NEG_RD_RS \
-     asm ("neg %%ebx;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setncb C_FLAG;"\
-          "setob V_FLAG;"\
-          : "=b" (reg[dest].I)\
-          : "b" (reg[source].I));
-#define CMP_RD_RS \
-     asm ("sub %0, %1;"\
-          "setsb N_FLAG;"\
-          "setzb Z_FLAG;"\
-          "setncb C_FLAG;"\
-          "setob V_FLAG;"\
-          : \
-          : "r" (value), "r" (reg[dest].I):"1");
-#endif
-#else
-#define ADD_RD_RS_RN \
-   {\
-     __asm mov eax, source\
-     __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
-     __asm add ebx, value\
-     __asm mov eax, dest\
-     __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-     __asm sets byte ptr N_FLAG\
-     __asm setz byte ptr Z_FLAG\
-     __asm setc byte ptr C_FLAG\
-     __asm seto byte ptr V_FLAG\
-   }
-#define ADD_RD_RS_O3 \
-   {\
-     __asm mov eax, source\
-     __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
-     __asm add ebx, value\
-     __asm mov eax, dest\
-     __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-     __asm sets byte ptr N_FLAG\
-     __asm setz byte ptr Z_FLAG\
-     __asm setc byte ptr C_FLAG\
-     __asm seto byte ptr V_FLAG\
-   }
-#define ADD_RN_O8(d) \
-   {\
-     __asm mov ebx, opcode\
-     __asm and ebx, 255\
-     __asm add dword ptr [OFFSET reg+4*(d)], ebx\
-     __asm sets byte ptr N_FLAG\
-     __asm setz byte ptr Z_FLAG\
-     __asm setc byte ptr C_FLAG\
-     __asm seto byte ptr V_FLAG\
-   }
-#define CMN_RD_RS \
-     {\
-       __asm mov eax, dest\
-       __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
-       __asm add ebx, value\
-       __asm sets byte ptr N_FLAG\
-       __asm setz byte ptr Z_FLAG\
-       __asm setc byte ptr C_FLAG\
-       __asm seto byte ptr V_FLAG\
-     }
-#define ADC_RD_RS \
-     {\
-       __asm mov ebx, dest\
-       __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
-       __asm bt word ptr C_FLAG, 0\
-       __asm adc ebx, value\
-       __asm mov eax, dest\
-       __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-       __asm sets byte ptr N_FLAG\
-       __asm setz byte ptr Z_FLAG\
-       __asm setc byte ptr C_FLAG\
-       __asm seto byte ptr V_FLAG\
-     }
-#define SUB_RD_RS_RN \
-   {\
-     __asm mov eax, source\
-     __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
-     __asm sub ebx, value\
-     __asm mov eax, dest\
-     __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-     __asm sets byte ptr N_FLAG\
-     __asm setz byte ptr Z_FLAG\
-     __asm setnc byte ptr C_FLAG\
-     __asm seto byte ptr V_FLAG\
-   }
-#define SUB_RD_RS_O3 \
-   {\
-     __asm mov eax, source\
-     __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
-     __asm sub ebx, value\
-     __asm mov eax, dest\
-     __asm mov dword ptr [OFFSET reg+4*eax], ebx\
-     __asm sets byte ptr N_FLAG\
-     __asm setz byte ptr Z_FLAG\
-     __asm setnc byte ptr C_FLAG\
-     __asm seto byte ptr V_FLAG\
-   }
-#define SUB_RN_O8(d) \
-   {\
-     __asm mov ebx, opcode\
-     __asm and ebx, 255\
-     __asm sub dword ptr [OFFSET reg + 4*(d)], ebx\
-     __asm sets byte ptr N_FLAG\
-     __asm setz byte ptr Z_FLAG\
-     __asm setnc byte ptr C_FLAG\
-     __asm seto byte ptr V_FLAG\
-   }
-#define CMP_RN_O8(d) \
-   {\
-     __asm mov eax, dword ptr [OFFSET reg+4*(d)]\
-     __asm mov ebx, opcode\
-     __asm and ebx, 255\
-     __asm sub eax, ebx\
-     __asm sets byte ptr N_FLAG\
-     __asm setz byte ptr Z_FLAG\
-     __asm setnc byte ptr C_FLAG\
-     __asm seto byte ptr V_FLAG\
-   }
-#define SBC_RD_RS \
-     {\
-       __asm mov ebx, dest\
-       __asm mov ebx, dword ptr [OFFSET reg + 4*ebx]\
-       __asm mov eax, value\
-       __asm bt word ptr C_FLAG, 0\
-       __asm cmc\
-       __asm sbb ebx, eax\
-       __asm mov eax, dest\
-       __asm mov dword ptr [OFFSET reg + 4*eax], ebx\
-       __asm sets byte ptr N_FLAG\
-       __asm setz byte ptr Z_FLAG\
-       __asm setnc byte ptr C_FLAG\
-       __asm seto byte ptr V_FLAG\
-     }
-#define LSL_RD_RM_I5 \
-     {\
-       __asm mov eax, source\
-       __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
-       __asm mov cl, byte ptr shift\
-       __asm shl eax, cl\
-       __asm mov value, eax\
-       __asm setc byte ptr C_FLAG\
-     }
-#define LSL_RD_RS \
-         {\
-           __asm mov eax, dest\
-           __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
-           __asm mov cl, byte ptr value\
-           __asm shl eax, cl\
-           __asm mov value, eax\
-           __asm setc byte ptr C_FLAG\
-         }
-#define LSR_RD_RM_I5 \
-     {\
-       __asm mov eax, source\
-       __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
-       __asm mov cl, byte ptr shift\
-       __asm shr eax, cl\
-       __asm mov value, eax\
-       __asm setc byte ptr C_FLAG\
-     }
-#define LSR_RD_RS \
-         {\
-           __asm mov eax, dest\
-           __asm mov eax, dword ptr [OFFSET reg + 4 * eax]\
-           __asm mov cl, byte ptr value\
-           __asm shr eax, cl\
-           __asm mov value, eax\
-           __asm setc byte ptr C_FLAG\
-         }
-#define ASR_RD_RM_I5 \
-     {\
-       __asm mov eax, source\
-       __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
-       __asm mov cl, byte ptr shift\
-       __asm sar eax, cl\
-       __asm mov value, eax\
-       __asm setc byte ptr C_FLAG\
-     }
-#define ASR_RD_RS \
-         {\
-           __asm mov eax, dest\
-           __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
-           __asm mov cl, byte ptr value\
-           __asm sar eax, cl\
-           __asm mov value, eax\
-           __asm setc byte ptr C_FLAG\
-         }
-#define ROR_RD_RS \
-         {\
-           __asm mov eax, dest\
-           __asm mov eax, dword ptr [OFFSET reg + 4*eax]\
-           __asm mov cl, byte ptr value\
-           __asm ror eax, cl\
-           __asm mov value, eax\
-           __asm setc byte ptr C_FLAG\
-         }
-#define NEG_RD_RS \
-     {\
-       __asm mov ebx, source\
-       __asm mov ebx, dword ptr [OFFSET reg+4*ebx]\
-       __asm neg ebx\
-       __asm mov eax, dest\
-       __asm mov dword ptr [OFFSET reg+4*eax],ebx\
-       __asm sets byte ptr N_FLAG\
-       __asm setz byte ptr Z_FLAG\
-       __asm setnc byte ptr C_FLAG\
-       __asm seto byte ptr V_FLAG\
-     }
-#define CMP_RD_RS \
-     {\
-       __asm mov eax, dest\
-       __asm mov ebx, dword ptr [OFFSET reg+4*eax]\
-       __asm sub ebx, value\
-       __asm sets byte ptr N_FLAG\
-       __asm setz byte ptr Z_FLAG\
-       __asm setnc byte ptr C_FLAG\
-       __asm seto byte ptr V_FLAG\
-     }
-#endif
-#endif
-
-
-#ifdef BKPT_SUPPORT
-u8 xxx;
-#endif
-
-u32 opcode = cpuPrefetch[0];
-cpuPrefetch[0] = cpuPrefetch[1];
-
-busPrefetch = false;
-  if (busPrefetchCount & 0xFFFFFF00)
-    busPrefetchCount = 0x100 | (busPrefetchCount & 0xFF);
-
-clockTicks = 0;
-u32 oldArmNextPC = armNextPC;
-#ifndef FINAL_VERSION
-if(armNextPC == stop) {
-  armNextPC++;
-}
-#endif
-
-armNextPC = reg[15].I;
-reg[15].I += 2;
-THUMB_PREFETCH_NEXT;
-
-switch(opcode >> 8) {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x07:
-   {
-     // LSL Rd, Rm, #Imm 5
-     int dest = opcode & 0x07;
-     int source = (opcode >> 3) & 0x07;
-     int shift = (opcode >> 6) & 0x1f;
-     u32 value;
-     
-     if(shift) {
-       LSL_RD_RM_I5;
-     } else {
-       value = reg[source].I;
-     }
-     reg[dest].I = value;
-     // C_FLAG set above
-     N_FLAG = (value & 0x80000000 ? true : false);
-     Z_FLAG = (value ? false : true);
-   }
-   break;
- case 0x08:
- case 0x09:
- case 0x0a:
- case 0x0b:
- case 0x0c:
- case 0x0d:
- case 0x0e:
- case 0x0f:
-   {
-     // LSR Rd, Rm, #Imm 5
-     int dest = opcode & 0x07;
-     int source = (opcode >> 3) & 0x07;
-     int shift = (opcode >> 6) & 0x1f;
-     u32 value;
-     
-     if(shift) {
-       LSR_RD_RM_I5;
-     } else {
-       C_FLAG = reg[source].I & 0x80000000 ? true : false;
-       value = 0;
-     }
-     reg[dest].I = value;
-     // C_FLAG set above
-     N_FLAG = (value & 0x80000000 ? true : false);
-     Z_FLAG = (value ? false : true);
-   }
-   break;
- case 0x10:
- case 0x11:
- case 0x12:
- case 0x13:
- case 0x14:
- case 0x15:
- case 0x16:
- case 0x17:
-   {     
-     // ASR Rd, Rm, #Imm 5
-     int dest = opcode & 0x07;
-     int source = (opcode >> 3) & 0x07;
-     int shift = (opcode >> 6) & 0x1f;
-     u32 value;
-     
-     if(shift) {
-       ASR_RD_RM_I5;
-     } else {
-       if(reg[source].I & 0x80000000) {
-         value = 0xFFFFFFFF;
-         C_FLAG = true;
-       } else {
-         value = 0;
-         C_FLAG = false;
-       }
-     }
-     reg[dest].I = value;
-     // C_FLAG set above
-     N_FLAG = (value & 0x80000000 ? true : false);
-     Z_FLAG = (value ? false :true);
-   }
-   break;
- case 0x18:
- case 0x19:
-   {
-     // ADD Rd, Rs, Rn
-     int dest = opcode & 0x07;
-     int source = (opcode >> 3) & 0x07;
-     u32 value = reg[(opcode>>6)& 0x07].I;
-     ADD_RD_RS_RN;
-   }
-   break;
- case 0x1a:
- case 0x1b:
-   {
-     // SUB Rd, Rs, Rn
-     int dest = opcode & 0x07;
-     int source = (opcode >> 3) & 0x07;
-     u32 value = reg[(opcode>>6)& 0x07].I;
-     SUB_RD_RS_RN;
-   }
-   break;
- case 0x1c:
- case 0x1d:
-   {
-     // ADD Rd, Rs, #Offset3
-     int dest = opcode & 0x07;
-     int source = (opcode >> 3) & 0x07;
-     u32 value = (opcode >> 6) & 7;
-     ADD_RD_RS_O3;
-   }
-   break;
- case 0x1e:
- case 0x1f:
-   {
-     // SUB Rd, Rs, #Offset3
-     int dest = opcode & 0x07;
-     int source = (opcode >> 3) & 0x07;
-     u32 value = (opcode >> 6) & 7;
-     SUB_RD_RS_O3;
-   }
-   break;
- case 0x20:
- case 0x21:
- case 0x22:
- case 0x23:
- case 0x24:
- case 0x25:
- case 0x26:
- case 0x27:
-     {
-   u8 regist = (opcode >> 8) & 7;
-   // MOV R0~R7, #Offset8
-   reg[regist].I = opcode & 255;
-   N_FLAG = false;
-   Z_FLAG = (reg[regist].I ? false : true);
-     }
-   break;
-case 0x28:
-   // CMP R0, #Offset8
-   CMP_RN_O8(0);
-   break;
- case 0x29:
-   // CMP R1, #Offset8
-   CMP_RN_O8(1);
-   break;
- case 0x2a:
-   // CMP R2, #Offset8
-   CMP_RN_O8(2);
-   break;
- case 0x2b:
-   // CMP R3, #Offset8
-   CMP_RN_O8(3);
-   break;
- case 0x2c:
-   // CMP R4, #Offset8
-   CMP_RN_O8(4);
-   break;
- case 0x2d:
-   // CMP R5, #Offset8
-   CMP_RN_O8(5);
-   break;
- case 0x2e:
-   // CMP R6, #Offset8
-   CMP_RN_O8(6);
-   break;
- case 0x2f:
-   // CMP R7, #Offset8
-   CMP_RN_O8(7);
-   break;
- case 0x30:
-   // ADD R0,#Offset8
-   ADD_RN_O8(0);
-   break;   
- case 0x31:
-   // ADD R1,#Offset8
-   ADD_RN_O8(1);
-   break;   
- case 0x32:
-   // ADD R2,#Offset8
-   ADD_RN_O8(2);
-   break;   
- case 0x33:
-   // ADD R3,#Offset8
-   ADD_RN_O8(3);
-   break;   
- case 0x34:
-   // ADD R4,#Offset8
-   ADD_RN_O8(4);
-   break;   
- case 0x35:
-   // ADD R5,#Offset8
-   ADD_RN_O8(5);
-   break;   
- case 0x36:
-   // ADD R6,#Offset8
-   ADD_RN_O8(6);
-   break;   
- case 0x37:
-   // ADD R7,#Offset8
-   ADD_RN_O8(7);
-   break;
- case 0x38:
-   // SUB R0,#Offset8
-   SUB_RN_O8(0);
-   break;
- case 0x39:
-   // SUB R1,#Offset8
-   SUB_RN_O8(1);
-   break;
- case 0x3a:
-   // SUB R2,#Offset8
-   SUB_RN_O8(2);
-   break;
- case 0x3b:
-   // SUB R3,#Offset8
-   SUB_RN_O8(3);
-   break;
- case 0x3c:
-   // SUB R4,#Offset8
-   SUB_RN_O8(4);
-   break;
- case 0x3d:
-   // SUB R5,#Offset8
-   SUB_RN_O8(5);
-   break;
- case 0x3e:
-   // SUB R6,#Offset8
-   SUB_RN_O8(6);
-   break;
- case 0x3f:
-   // SUB R7,#Offset8
-   SUB_RN_O8(7);
-   break;
-
- case 0x40:
-   switch((opcode >> 6) & 3) {
-   case 0x00:
-     {
-       // AND Rd, Rs
-       int dest = opcode & 7;
-       reg[dest].I &= reg[(opcode >> 3)&7].I;
-       N_FLAG = reg[dest].I & 0x80000000 ? true : false;
-       Z_FLAG = reg[dest].I ? false : true;
-#ifdef BKPT_SUPPORT     
-#define THUMB_CONSOLE_OUTPUT(a,b) \
-  if((opcode == 0x4000) && (reg[0].I == 0xC0DED00D)) {\
-    extern void (*dbgOutput)(char *, u32);\
-    dbgOutput((a), (b));\
-  }
-#else
-#define THUMB_CONSOLE_OUTPUT(a,b)
-#endif
-       THUMB_CONSOLE_OUTPUT(NULL, reg[2].I);
-     }
-     break;
-   case 0x01:
-     // EOR Rd, Rs
-     {
-       int dest = opcode & 7;
-       reg[dest].I ^= reg[(opcode >> 3)&7].I;
-       N_FLAG = reg[dest].I & 0x80000000 ? true : false;
-       Z_FLAG = reg[dest].I ? false : true;
-     }
-     break;
-   case 0x02:
-     // LSL Rd, Rs
-     {
-       int dest = opcode & 7;
-       u32 value = reg[(opcode >> 3)&7].B.B0;
-       if(value) {
-         if(value == 32) {
-           value = 0;
-           C_FLAG = (reg[dest].I & 1 ? true : false);
-         } else if(value < 32) {
-           LSL_RD_RS;
-         } else {
-           value = 0;
-           C_FLAG = false;
-         }
-         reg[dest].I = value;        
-       }
-       N_FLAG = reg[dest].I & 0x80000000 ? true : false;
-       Z_FLAG = reg[dest].I ? false : true;
-       clockTicks = codeTicksAccess16(armNextPC)+2;
-     }
-     break;
-   case 0x03:
-     {
-       // LSR Rd, Rs
-       int dest = opcode & 7;
-       u32 value = reg[(opcode >> 3)&7].B.B0;
-       if(value) {
-         if(value == 32) {
-           value = 0;
-           C_FLAG = (reg[dest].I & 0x80000000 ? true : false);
-         } else if(value < 32) {
-           LSR_RD_RS;
-         } else {
-           value = 0;
-           C_FLAG = false;
-         }
-         reg[dest].I = value;        
-       }
-       N_FLAG = reg[dest].I & 0x80000000 ? true : false;
-       Z_FLAG = reg[dest].I ? false : true;
-       clockTicks = codeTicksAccess16(armNextPC)+2;
-     }
-     break;
-   }
-   break;
- case 0x41:
-   switch((opcode >> 6) & 3) {
-   case 0x00:
-     {
-       // ASR Rd, Rs
-       int dest = opcode & 7;
-       u32 value = reg[(opcode >> 3)&7].B.B0;
-       // ASR
-       if(value) {
-         if(value < 32) {
-           ASR_RD_RS;
-           reg[dest].I = value;        
-         } else {
-           if(reg[dest].I & 0x80000000){
-             reg[dest].I = 0xFFFFFFFF;
-             C_FLAG = true;
-           } else {
-             reg[dest].I = 0x00000000;
-             C_FLAG = false;
-           }
-         }
-       }
-       N_FLAG = reg[dest].I & 0x80000000 ? true : false;
-       Z_FLAG = reg[dest].I ? false : true;
-       clockTicks = codeTicksAccess16(armNextPC)+2;
-     }
-     break;
-   case 0x01:
-     {
-       // ADC Rd, Rs
-       int dest = opcode & 0x07;
-       u32 value = reg[(opcode >> 3)&7].I;
-       // ADC
-       ADC_RD_RS;
-     }
-     break;
-   case 0x02:
-     {
-       // SBC Rd, Rs
-       int dest = opcode & 0x07;
-       u32 value = reg[(opcode >> 3)&7].I;
-       
-       // SBC
-       SBC_RD_RS;
-     }
-     break;
-   case 0x03:
-     // ROR Rd, Rs
-     {
-       int dest = opcode & 7;
-       u32 value = reg[(opcode >> 3)&7].B.B0;
-       
-       if(value) {
-         value = value & 0x1f;
-         if(value == 0) {
-           C_FLAG = (reg[dest].I & 0x80000000 ? true : false);
-         } else {
-           ROR_RD_RS;
-           reg[dest].I = value;
-         }
-       }
-       clockTicks = codeTicksAccess16(armNextPC)+2;
-       N_FLAG = reg[dest].I & 0x80000000 ? true : false;
-       Z_FLAG = reg[dest].I ? false : true;
-     }
-     break;
-   }
-   break;
- case 0x42:
-   switch((opcode >> 6) & 3) {
-   case 0x00:
-     {
-       // TST Rd, Rs
-       u32 value = reg[opcode & 7].I & reg[(opcode >> 3) & 7].I;
-       N_FLAG = value & 0x80000000 ? true : false;
-       Z_FLAG = value ? false : true;
-     }
-     break;
-   case 0x01:
-     {
-       // NEG Rd, Rs
-       int dest = opcode & 7;
-       int source = (opcode >> 3) & 7;
-       NEG_RD_RS;
-     }
-     break;
-   case 0x02:
-     {
-       // CMP Rd, Rs
-       int dest = opcode & 7;
-       u32 value = reg[(opcode >> 3)&7].I;
-       CMP_RD_RS;
-     }
-     break;
-   case 0x03:
-     {
-       // CMN Rd, Rs
-       int dest = opcode & 7;
-       u32 value = reg[(opcode >> 3)&7].I;
-       // CMN
-       CMN_RD_RS;
-     }
-     break;
-   }
-   break;
- case 0x43:
-   switch((opcode >> 6) & 3) {
-   case 0x00:
-     {
-       // ORR Rd, Rs       
-       int dest = opcode & 7;
-       reg[dest].I |= reg[(opcode >> 3) & 7].I;
-       Z_FLAG = reg[dest].I ? false : true;
-       N_FLAG = reg[dest].I & 0x80000000 ? true : false;
-     }
-     break;
-   case 0x01:
-     {
-       // MUL Rd, Rs
-       clockTicks = 1;
-       int dest = opcode & 7;
-       u32 rm = reg[dest].I;
-       reg[dest].I = reg[(opcode >> 3) & 7].I * rm;
-       if (((s32)rm) < 0)
-         rm = ~rm;
-       if ((rm & 0xFFFFFF00) == 0)
-         clockTicks += 0;
-       else if ((rm & 0xFFFF0000) == 0)
-         clockTicks += 1;
-       else if ((rm & 0xFF000000) == 0)
-         clockTicks += 2;
-       else
-         clockTicks += 3;
-      busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
-      clockTicks += codeTicksAccess16(armNextPC) + 1;
-       Z_FLAG = reg[dest].I ? false : true;
-       N_FLAG = reg[dest].I & 0x80000000 ? true : false;
-     }
-     break;
-   case 0x02:
-     {
-       // BIC Rd, Rs
-       int dest = opcode & 7;
-       reg[dest].I &= (~reg[(opcode >> 3) & 7].I);
-       Z_FLAG = reg[dest].I ? false : true;
-       N_FLAG = reg[dest].I & 0x80000000 ? true : false;
-     }
-     break;
-   case 0x03:
-     {
-       // MVN Rd, Rs
-       int dest = opcode & 7;
-       reg[dest].I = ~reg[(opcode >> 3) & 7].I;
-       Z_FLAG = reg[dest].I ? false : true;
-       N_FLAG = reg[dest].I & 0x80000000 ? true : false;
-     }
-     break;
-   }
-   break;
- case 0x44:
-   {
-     int dest = opcode & 7;
-     int base = (opcode >> 3) & 7;
-     switch((opcode >> 6)& 3) {
-     default:
-       goto unknown_thumb;
-     case 1:
-       // ADD Rd, Hs
-       reg[dest].I += reg[base+8].I;
-       break;
-     case 2:
-       // ADD Hd, Rs
-       reg[dest+8].I += reg[base].I;
-       if(dest == 7) {
-         reg[15].I &= 0xFFFFFFFE;
-         armNextPC = reg[15].I;
-         reg[15].I += 2;
-         THUMB_PREFETCH;
-         clockTicks = codeTicksAccessSeq16(armNextPC)+1;
-         clockTicks += clockTicks+codeTicksAccess16(armNextPC)+1;
-       }       
-       break;
-     case 3:
-       // ADD Hd, Hs
-       reg[dest+8].I += reg[base+8].I;
-       if(dest == 7) {
-         reg[15].I &= 0xFFFFFFFE;
-         armNextPC = reg[15].I;
-         reg[15].I += 2;
-         THUMB_PREFETCH;
-         clockTicks = codeTicksAccessSeq16(armNextPC)+1;
-         clockTicks += clockTicks+codeTicksAccess16(armNextPC)+1;     
-       }
-       break;
-     }
-   }
-   break;
- case 0x45:
-   {
-     int dest = opcode & 7;
-     int base = (opcode >> 3) & 7;
-     u32 value;
-     switch((opcode >> 6) & 3) {
-     case 0:
-       // CMP Rd, Hs
-       value = reg[base].I;
-       CMP_RD_RS;
-       break;
-     case 1:
-       // CMP Rd, Hs
-       value = reg[base+8].I;
-       CMP_RD_RS;
-       break;
-     case 2:
-       // CMP Hd, Rs
-       value = reg[base].I;
-       dest += 8;
-       CMP_RD_RS;
-       break;
-     case 3:
-       // CMP Hd, Hs
-       value = reg[base+8].I;
-       dest += 8;
-       CMP_RD_RS;
-       break;
-     }
-   }
-   break;
- case 0x46:
-   {
-     int dest = opcode & 7;
-     int base = (opcode >> 3) & 7;
-     switch((opcode >> 6) & 3) {
-     case 0:
-       // this form should not be used...
-       // MOV Rd, Rs
-       reg[dest].I = reg[base].I;
-       break;
-     case 1:
-       // MOV Rd, Hs
-       reg[dest].I = reg[base+8].I;
-       break;
-     case 2:
-       // MOV Hd, Rs
-       reg[dest+8].I = reg[base].I;
-       if(dest == 7) {
-#ifdef BKPT_SUPPORT
-	     UPDATE_OLD_REG
-#endif
-
-         reg[15].I &= 0xFFFFFFFE;
-         armNextPC = reg[15].I;
-         reg[15].I += 2;
-         THUMB_PREFETCH;
-         clockTicks = codeTicksAccessSeq16(armNextPC)+1;
-         clockTicks += clockTicks+codeTicksAccess16(armNextPC)+1; 
-       }
-       break;
-     case 3:
-       // MOV Hd, Hs
-       reg[dest+8].I = reg[base+8].I;
-       if(dest == 7) {
-
-#ifdef BKPT_SUPPORT
-	     UPDATE_OLD_REG
-#endif
-
-         reg[15].I &= 0xFFFFFFFE;
-         armNextPC = reg[15].I;
-         reg[15].I += 2;
-         THUMB_PREFETCH;
-         clockTicks = codeTicksAccessSeq16(armNextPC)+1;
-         clockTicks += clockTicks+codeTicksAccess16(armNextPC)+1; 
-       }   
-       break;
-     }
-   }
-   break;
- case 0x47:
-   {
-     int base = (opcode >> 3) & 7;
-     busPrefetchCount=0;
-     switch((opcode >>6) & 3) {
-     case 0:
-       // BX Rs
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-       reg[15].I = (reg[base].I) & 0xFFFFFFFE;
-       if(reg[base].I & 1) {
-         armState = false;
-         armNextPC = reg[15].I;
-         reg[15].I += 2;
-         THUMB_PREFETCH;
-         clockTicks = codeTicksAccessSeq16(armNextPC) +
-             codeTicksAccessSeq16(armNextPC) + codeTicksAccess16(armNextPC) + 3;
-       } else {
-         armState = true;
-         reg[15].I &= 0xFFFFFFFC;
-         armNextPC = reg[15].I;
-         reg[15].I += 4;
-         ARM_PREFETCH;
-         clockTicks = codeTicksAccessSeq32(armNextPC) +
-             codeTicksAccessSeq32(armNextPC) + codeTicksAccess32(armNextPC) + 3;
-       }
-       break;
-     case 1:
-       // BX Hs
-
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-
-       reg[15].I = (reg[8+base].I) & 0xFFFFFFFE;
-       if(reg[8+base].I & 1) {
-         armState = false;
-         armNextPC = reg[15].I;
-         reg[15].I += 2;
-         THUMB_PREFETCH;
-         clockTicks = dataTicksAccess16(armNextPC) + dataTicksAccess16(armNextPC) +
-             codeTicksAccess16(armNextPC) + 3;
-       } else {
-         armState = true;
-         reg[15].I &= 0xFFFFFFFC;       
-         armNextPC = reg[15].I;
-         reg[15].I += 4;
-         ARM_PREFETCH;
-         clockTicks = dataTicksAccess32(armNextPC) + dataTicksAccess32(armNextPC) +
-             codeTicksAccess32(armNextPC) + 3;
-       }
-       break;
-     default:
-       goto unknown_thumb;
-     }
-   }
-   break;
- case 0x48:
- case 0x49:
- case 0x4a:
- case 0x4b:
- case 0x4c:
- case 0x4d:
- case 0x4e:
- case 0x4f:
-   // LDR R0~R7,[PC, #Imm]
-   {
-   u8 regist = (opcode >> 8) & 7;
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = (reg[15].I & 0xFFFFFFFC) + ((opcode & 0xFF) << 2);
-     reg[regist].I = CPUReadMemoryQuick(address);
-     busPrefetchCount=0;
-     clockTicks = 3 + dataTicksAccess32(address) +
-         codeTicksAccess16(armNextPC);
-   }
-   break;
- case 0x50:
- case 0x51:
-   // STR Rd, [Rs, Rn]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
-     CPUWriteMemory(address,
-                    reg[opcode & 7].I);
-     clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2;
-   }
-   break;
- case 0x52:
- case 0x53:
-   // STRH Rd, [Rs, Rn]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
-     CPUWriteHalfWord(address,
-                      reg[opcode&7].W.W0);
-     clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2;
-   }
-   break;
- case 0x54:
- case 0x55:
-   // STRB Rd, [Rs, Rn]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + reg[(opcode >>6)&7].I;
-     CPUWriteByte(address,
-                  reg[opcode & 7].B.B0);
-     clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2;
-   }
-   break;
- case 0x56:
- case 0x57:
-   // LDSB Rd, [Rs, Rn]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
-     reg[opcode&7].I = (s8)CPUReadByte(address);
-     clockTicks = 3 + dataTicksAccess16(address) +
-         codeTicksAccess16(armNextPC);
-   }
-   break;
- case 0x58:
- case 0x59:
-   // LDR Rd, [Rs, Rn]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
-     reg[opcode&7].I = CPUReadMemory(address);
-     clockTicks = 3 + dataTicksAccess32(address) +
-         codeTicksAccess16(armNextPC);
-   }
-   break;
- case 0x5a:
- case 0x5b:
-   // LDRH Rd, [Rs, Rn]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
-     reg[opcode&7].I = CPUReadHalfWord(address);
-     clockTicks = 3 + dataTicksAccess32(address) +
-         codeTicksAccess16(armNextPC);
-   }
-   break;
- case 0x5c:
- case 0x5d:
-   // LDRB Rd, [Rs, Rn]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
-     reg[opcode&7].I = CPUReadByte(address);
-     clockTicks = 3 + dataTicksAccess16(address) +
-         codeTicksAccess16(armNextPC);
-   }
-   break;
- case 0x5e:
- case 0x5f:
-   // LDSH Rd, [Rs, Rn]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + reg[(opcode>>6)&7].I;
-     reg[opcode&7].I = (s16)CPUReadHalfWordSigned(address);
-     clockTicks = 3 + dataTicksAccess16(address) +
-         codeTicksAccess16(armNextPC);
-   }
-   break;
- case 0x60:
- case 0x61:
- case 0x62:
- case 0x63:
- case 0x64:
- case 0x65:
- case 0x66:
- case 0x67:
-   // STR Rd, [Rs, #Imm]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<2);
-     CPUWriteMemory(address,
-                    reg[opcode&7].I);
-     clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2;
-   }
-   break;
- case 0x68:
- case 0x69:
- case 0x6a:
- case 0x6b:
- case 0x6c:
- case 0x6d:
- case 0x6e:
- case 0x6f:
-   // LDR Rd, [Rs, #Imm]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<2);
-     reg[opcode&7].I = CPUReadMemory(address);
-     clockTicks = 3 + dataTicksAccess32(address) +
-         codeTicksAccess16(armNextPC);
-   }
-   break;
- case 0x70:
- case 0x71:
- case 0x72:
- case 0x73:
- case 0x74:
- case 0x75:
- case 0x76:
- case 0x77:
-   // STRB Rd, [Rs, #Imm]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31));
-     CPUWriteByte(address,
-                  reg[opcode&7].B.B0);
-     clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2;
-   }
-   break;
- case 0x78:
- case 0x79:
- case 0x7a:
- case 0x7b:
- case 0x7c:
- case 0x7d:
- case 0x7e:
- case 0x7f:
-   // LDRB Rd, [Rs, #Imm]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31));
-     reg[opcode&7].I = CPUReadByte(address);
-     clockTicks = 3 + dataTicksAccess16(address) +
-         codeTicksAccess16(armNextPC);
-   }
-   break;
- case 0x80:
- case 0x81:
- case 0x82:
- case 0x83:
- case 0x84:
- case 0x85:
- case 0x86:
- case 0x87:
-   // STRH Rd, [Rs, #Imm]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<1);
-     CPUWriteHalfWord(address,
-                      reg[opcode&7].W.W0);
-     clockTicks = dataTicksAccess16(address) + codeTicksAccess16(armNextPC) + 2;
-   }
-   break;   
- case 0x88:
- case 0x89:
- case 0x8a:
- case 0x8b:
- case 0x8c:
- case 0x8d:
- case 0x8e:
- case 0x8f:
-   // LDRH Rd, [Rs, #Imm]
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[(opcode>>3)&7].I + (((opcode>>6)&31)<<1);
-     reg[opcode&7].I = CPUReadHalfWord(address);
-     clockTicks = 3 + dataTicksAccess16(address) +
-         codeTicksAccess16(armNextPC);
-   }
-   break;
- case 0x90:
- case 0x91:
- case 0x92:
- case 0x93:
- case 0x94:
- case 0x95:
- case 0x96:
- case 0x97:
-   // STR R0~R7, [SP, #Imm]
-   {
-   u8 regist = (opcode >> 8) & 7;
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[13].I + ((opcode&255)<<2);
-     CPUWriteMemory(address, reg[regist].I);
-     clockTicks = dataTicksAccess32(address) + codeTicksAccess16(armNextPC) + 2;
-   }
-   break;      
- case 0x98:
- case 0x99:
- case 0x9a:
- case 0x9b:
- case 0x9c:
- case 0x9d:
- case 0x9e:
- case 0x9f:
-   // LDR R0~R7, [SP, #Imm]
-   {
-   u8 regist = (opcode >> 8) & 7;
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[13].I + ((opcode&255)<<2);   
-     reg[regist].I = CPUReadMemoryQuick(address);
-     clockTicks = 3 + dataTicksAccess32(address) +
-         codeTicksAccess16(armNextPC);
-   }
-   break;
- case 0xa0:
- case 0xa1:
- case 0xa2:
- case 0xa3:
- case 0xa4:
- case 0xa5:
- case 0xa6:
- case 0xa7:
-     {
-   // ADD R0~R7, PC, Imm
-   u8 regist = (opcode >> 8) & 7;
-   reg[regist].I = (reg[15].I & 0xFFFFFFFC) + ((opcode&255)<<2);
-     }
-   break;   
- case 0xa8:
- case 0xa9:
- case 0xaa:
- case 0xab:
- case 0xac:
- case 0xad:
- case 0xae:
- case 0xaf:
-     {
-   // ADD R0~R7, SP, Imm
-   u8 regist = (opcode >> 8) & 7;
-   reg[regist].I = reg[13].I + ((opcode&255)<<2);
-     }
-   break;     
- case 0xb0:
-   {
-     // ADD SP, Imm
-     int offset = (opcode & 127) << 2;
-     if(opcode & 0x80)
-       offset = -offset;
-     reg[13].I += offset;
-   }
-   break;
-#define PUSH_REG(val, r) \
-  if(opcode & (val)) {\
-    CPUWriteMemory(address, reg[(r)].I);\
-    if(offset)\
-      clockTicks += 1 + dataTicksAccessSeq32(address);\
-    else\
-      clockTicks += 1 + dataTicksAccess32(address);\
-    offset = 1;\
-    address += 4;\
-  }
- case 0xb4:
-   // PUSH {Rlist}
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     int offset = 0;
-     u32 temp = reg[13].I - 4 * cpuBitsSet[opcode & 0xff];
-     u32 address = temp & 0xFFFFFFFC;
-     PUSH_REG(1, 0);
-     PUSH_REG(2, 1);
-     PUSH_REG(4, 2);
-     PUSH_REG(8, 3);
-     PUSH_REG(16, 4);
-     PUSH_REG(32, 5);
-     PUSH_REG(64, 6);
-     PUSH_REG(128, 7);
-     clockTicks += codeTicksAccess16(armNextPC)+1;
-     reg[13].I = temp;
-   }
-   break;
- case 0xb5:
-   // PUSH {Rlist, LR}
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     int offset = 0;
-     u32 temp = reg[13].I - 4 - 4 * cpuBitsSet[opcode & 0xff];
-     u32 address = temp & 0xFFFFFFFC;
-     PUSH_REG(1, 0);
-     PUSH_REG(2, 1);
-     PUSH_REG(4, 2);
-     PUSH_REG(8, 3);
-     PUSH_REG(16, 4);
-     PUSH_REG(32, 5);
-     PUSH_REG(64, 6);
-     PUSH_REG(128, 7);
-     PUSH_REG(256, 14);
-     clockTicks += codeTicksAccess16(armNextPC)+1;
-     reg[13].I = temp;
-   }
-   break;
-#define POP_REG(val, r) \
-  if(opcode & (val)) {\
-    reg[(r)].I = CPUReadMemory(address);\
-    if(offset)\
-      clockTicks += 1 + dataTicksAccessSeq32(address);\
-    else\
-      clockTicks += 1 + dataTicksAccess32(address);\
-    offset = 1;\
-    address += 4;\
-  }
- case 0xbc:
-   // POP {Rlist}
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     int offset = 0;
-     u32 address = reg[13].I & 0xFFFFFFFC;
-     u32 temp = reg[13].I + 4*cpuBitsSet[opcode & 0xFF];
-     clockTicks = 0;
-     POP_REG(1, 0);
-     POP_REG(2, 1);
-     POP_REG(4, 2);
-     POP_REG(8, 3);
-     POP_REG(16, 4);
-     POP_REG(32, 5);
-     POP_REG(64, 6);
-     POP_REG(128, 7);
-     reg[13].I = temp;
-     clockTicks += codeTicksAccess16(armNextPC)+2;
-   }
-   break;   
- case 0xbd:
-   // POP {Rlist, PC}
-   {
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     int offset = 0;
-     u32 address = reg[13].I & 0xFFFFFFFC;
-     u32 temp = reg[13].I + 4 + 4*cpuBitsSet[opcode & 0xFF];
-     clockTicks = 0;
-     POP_REG(1, 0);
-     POP_REG(2, 1);
-     POP_REG(4, 2);
-     POP_REG(8, 3);
-     POP_REG(16, 4);
-     POP_REG(32, 5);
-     POP_REG(64, 6);
-     POP_REG(128, 7);
-     reg[15].I = (CPUReadMemory(address) & 0xFFFFFFFE);
-     if(offset)
-       clockTicks += 1 + dataTicksAccessSeq32(address);
-     else
-       clockTicks += 1 + dataTicksAccess32(address);
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     reg[13].I = temp;
-     THUMB_PREFETCH;
-     busPrefetchCount=0;
-     clockTicks += codeTicksAccess16(armNextPC) + codeTicksAccess16(armNextPC) + 3;
-   }
-   break;      
-#define THUMB_STM_REG(val,r,b) \
-  if(opcode & (val)) {\
-    CPUWriteMemory(address, reg[(r)].I);\
-    if(!offset) {\
-      reg[(b)].I = temp;\
-      clockTicks += 1 + dataTicksAccess32(address);\
-    } else \
-      clockTicks += 1 + dataTicksAccessSeq32(address);\
-    offset = 1;\
-    address += 4;\
-  }
- case 0xc0:
- case 0xc1:
- case 0xc2:
- case 0xc3:
- case 0xc4:
- case 0xc5:
- case 0xc6:
- case 0xc7:
-   {
-     // STM R0~7!, {Rlist}
-     u8 regist = (opcode >> 8) & 7;
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[regist].I & 0xFFFFFFFC;
-     u32 temp = reg[regist].I + 4*cpuBitsSet[opcode & 0xff];
-     int offset = 0;
-     // store
-     THUMB_STM_REG(1, 0, regist);
-     THUMB_STM_REG(2, 1, regist);
-     THUMB_STM_REG(4, 2, regist);
-     THUMB_STM_REG(8, 3, regist);
-     THUMB_STM_REG(16, 4, regist);
-     THUMB_STM_REG(32, 5, regist);
-     THUMB_STM_REG(64, 6, regist);
-     THUMB_STM_REG(128, 7, regist);
-     clockTicks = codeTicksAccess16(armNextPC)+1;
-   }
-   break;   
-#define THUMB_LDM_REG(val,r) \
-  if(opcode & (val)) {\
-    reg[(r)].I = CPUReadMemory(address);\
-    if(offset)\
-      clockTicks += 1 + dataTicksAccessSeq32(address);\
-    else \
-      clockTicks += 1 + dataTicksAccess32(address);\
-    offset = 1;\
-    address += 4;\
-  }
- case 0xc8:
- case 0xc9:
- case 0xca:
- case 0xcb:
- case 0xcc:
- case 0xcd:
- case 0xce:
- case 0xcf:
-   {
-     // LDM R0~R7!, {Rlist}
-     u8 regist = (opcode >> 8) & 7;
-     if (!busPrefetchCount)
-       busPrefetch = busPrefetchEnable;
-     u32 address = reg[regist].I & 0xFFFFFFFC;
-     u32 temp = reg[regist].I + 4*cpuBitsSet[opcode & 0xFF];
-     int offset = 0;
-     clockTicks = 0;
-     // load
-     THUMB_LDM_REG(1, 0);
-     THUMB_LDM_REG(2, 1);
-     THUMB_LDM_REG(4, 2);
-     THUMB_LDM_REG(8, 3);
-     THUMB_LDM_REG(16, 4);
-     THUMB_LDM_REG(32, 5);
-     THUMB_LDM_REG(64, 6);
-     THUMB_LDM_REG(128, 7);
-     clockTicks += codeTicksAccess16(armNextPC)+2;
-     if(!(opcode & (1<<regist)))
-       reg[regist].I = temp;
-   }
-   break;
- case 0xd0:
-   // BEQ offset
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-   if(Z_FLAG) {
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;      
- case 0xd1:
-   // BNE offset
-   if(!Z_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xd2:
-   // BCS offset
-   if(C_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xd3:
-   // BCC offset
-   if(!C_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xd4:
-   // BMI offset
-   if(N_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xd5:
-   // BPL offset
-   if(!N_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xd6:
-   // BVS offset
-   if(V_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xd7:
-   // BVC offset
-   if(!V_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xd8:
-   // BHI offset
-   if(C_FLAG && !Z_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xd9:
-   // BLS offset
-   if(!C_FLAG || Z_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xda:
-   // BGE offset
-   if(N_FLAG == V_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xdb:
-   // BLT offset
-   if(N_FLAG != V_FLAG) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xdc:
-   // BGT offset
-   if(!Z_FLAG && (N_FLAG == V_FLAG)) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xdd:
-   // BLE offset
-   if(Z_FLAG || (N_FLAG != V_FLAG)) {
-#ifdef BKPT_SUPPORT
-		 UPDATE_OLD_REG
-#endif
-     reg[15].I += ((s8)(opcode & 0xFF)) << 1;       
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC)+3;
-     busPrefetchCount=0;
-   }
-   break;   
- case 0xdf:
-     {
-   // SWI #comment
-   u32 address = 0;
-   clockTicks = codeTicksAccessSeq16(address) + codeTicksAccessSeq16(address) +
-       codeTicksAccess16(address)+3;
-   busPrefetchCount=0;
-   CPUSoftwareInterrupt(opcode & 0xFF);
-   break;
-     }
- case 0xe0:
- case 0xe1:
- case 0xe2:
- case 0xe3:
- case 0xe4:
- case 0xe5:
- case 0xe6:
- case 0xe7:
-   {
-     // B offset
-     int offset = (opcode & 0x3FF) << 1;
-     if(opcode & 0x0400)
-       offset |= 0xFFFFF800;
-     reg[15].I += offset;
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) + codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC) + 3;
-     busPrefetchCount=0;
-   }
-   break;
- case 0xf0:
- case 0xf1:
- case 0xf2:
- case 0xf3:
-   {
-     // BLL #offset
-     int offset = (opcode & 0x7FF);
-     reg[14].I = reg[15].I + (offset << 12);
-     clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
-   }
-   break;      
- case 0xf4:
- case 0xf5:
- case 0xf6:
- case 0xf7:
-   {
-     // BLL #offset
-     int offset = (opcode & 0x7FF);
-     reg[14].I = reg[15].I + ((offset << 12) | 0xFF800000);
-     clockTicks = codeTicksAccessSeq16(armNextPC) + 1;
-   }
-   break;   
- case 0xf8:
- case 0xf9:
- case 0xfa:
- case 0xfb:
- case 0xfc:
- case 0xfd:
- case 0xfe:
- case 0xff:
-   {
-     // BLH #offset
-     int offset = (opcode & 0x7FF);
-     u32 temp = reg[15].I-2;
-     reg[15].I = (reg[14].I + (offset<<1))&0xFFFFFFFE;
-     armNextPC = reg[15].I;
-     reg[15].I += 2;
-     reg[14].I = temp|1;
-     THUMB_PREFETCH;
-     clockTicks = codeTicksAccessSeq16(armNextPC) +
-         codeTicksAccess16(armNextPC) + codeTicksAccessSeq16(armNextPC) + 3;
-     busPrefetchCount = 0;
-   }
-   break;
-#ifdef BKPT_SUPPORT
- case 0xbe:
-   // BKPT #comment
-   extern void (*dbgSignal)(int,int);
-   reg[15].I -= 2;
-   armNextPC -= 2;   
-   dbgSignal(5, opcode & 255);
-   return;
-#endif
- case 0xb1:
- case 0xb2:
- case 0xb3:
- case 0xb6:
- case 0xb7:
- case 0xb8:
- case 0xb9:
- case 0xba:
- case 0xbb:
-#ifndef BKPT_SUPPORT
- case 0xbe:
-#endif
- case 0xbf:
- case 0xde:
- default:
- unknown_thumb:
-#ifdef DEV_VERSION
-   if(systemVerbose & VERBOSE_UNDEFINED)
-     log("Undefined THUMB instruction %04x at %08x\n", opcode, armNextPC-2);
-#endif
-   CPUUndefinedException();
-   break;
-}
-
-if (clockTicks==0)
-clockTicks = codeTicksAccessSeq16(oldArmNextPC) + 1;
diff -urN ../VisualBoyAdvance-20061204/win32/GBA.dsp win32/GBA.dsp
--- ../VisualBoyAdvance-20061204/win32/GBA.dsp	2004-11-05 09:51:52 +0900
+++ win32/GBA.dsp	2006-12-05 00:18:42 +0900
@@ -176,6 +176,14 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\src\GBA-arm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\GBA-thumb.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=..\src\Gfx.cpp
 # End Source File
 # Begin Source File
@@ -660,10 +668,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE="..\src\arm-new.h"
-# End Source File
-# Begin Source File
-
 SOURCE=..\src\armdis.h
 # End Source File
 # Begin Source File
@@ -996,10 +1000,6 @@
 # End Source File
 # Begin Source File
 
-SOURCE=..\src\thumb.h
-# End Source File
-# Begin Source File
-
 SOURCE=..\src\win32\TileView.h
 # End Source File
 # Begin Source File
diff -urN ../VisualBoyAdvance-20061204/win32/GBA.vcproj win32/GBA.vcproj
--- ../VisualBoyAdvance-20061204/win32/GBA.vcproj	2004-03-10 06:03:21 +0900
+++ win32/GBA.vcproj	2006-12-05 00:18:42 +0900
@@ -354,6 +354,12 @@
 					RelativePath="..\src\GBA.cpp">
 				</File>
 				<File
+					RelativePath="..\src\GBA-arm.cpp">
+				</File>
+				<File
+					RelativePath="..\src\GBA-thumb.cpp">
+				</File>
+				<File
 					RelativePath="..\src\Gfx.cpp">
 				</File>
 				<File
@@ -842,9 +848,6 @@
 				RelativePath="..\src\agbprint.h">
 			</File>
 			<File
-				RelativePath="..\src\arm-new.h">
-			</File>
-			<File
 				RelativePath="..\src\armdis.h">
 			</File>
 			<File
@@ -896,9 +899,6 @@
 				RelativePath="..\src\win32\stdafx.h">
 			</File>
 			<File
-				RelativePath="..\src\thumb.h">
-			</File>
-			<File
 				RelativePath="..\src\unzip.h">
 			</File>
 		</Filter>
diff -urN ../VisualBoyAdvance-20061204/win32/gba_sdl.dsp win32/gba_sdl.dsp
--- ../VisualBoyAdvance-20061204/win32/gba_sdl.dsp	2004-03-30 07:08:56 +0900
+++ win32/gba_sdl.dsp	2006-12-05 00:18:42 +0900
@@ -141,6 +141,14 @@
 # End Source File
 # Begin Source File
 
+SOURCE=..\src\GBA-arm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\GBA-thumb.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=..\src\Gfx.cpp
 # End Source File
 # Begin Source File
diff -urN ../VisualBoyAdvance-20061204/win32/gba_sdl.vcproj win32/gba_sdl.vcproj
--- ../VisualBoyAdvance-20061204/win32/gba_sdl.vcproj	2004-03-30 07:08:56 +0900
+++ win32/gba_sdl.vcproj	2006-12-05 00:18:42 +0900
@@ -147,6 +147,12 @@
 					RelativePath="..\src\GBA.cpp">
 				</File>
 				<File
+					RelativePath="..\src\GBA-arm.cpp">
+				</File>
+				<File
+					RelativePath="..\src\GBA-thumb.cpp">
+				</File>
+				<File
 					RelativePath="..\src\Gfx.cpp">
 				</File>
 				<File
