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 +#include +#include +#include +#include + +#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)<> 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 +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 +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 +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 +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> 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 +#include +#include +#include +#include + +#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<>(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<>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 #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)<>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)<>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)<>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)<>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)<>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)<>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)<>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)<>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)<> 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)<> 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)<> 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)<> 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)<> 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)<> 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)<> 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)<> 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)<> 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)<> 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)<> 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)<> 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 - 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 - 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 - 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<>(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< + + + + - - - - 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"> + + + +