diff --git a/Makefile b/Makefile
index be31de74..baded02c 100644
--- a/Makefile
+++ b/Makefile
@@ -75,9 +75,9 @@ CALTERNOBJ=${HQCDIR}/hq_implementation${OE}
MAINOBJ=${MAINDIR}/2xSaI${OE} ${MAINDIR}/admame${OE} ${MAINDIR}/agbprint${OE} ${MAINDIR}/armdis${OE} \
${MAINDIR}/bilinear${OE} ${MAINDIR}/bios${OE} ${MAINDIR}/Cheats${OE} ${MAINDIR}/CheatSearch${OE} \
-${MAINDIR}/EEprom${OE} ${MAINDIR}/elf${OE} ${MAINDIR}/Flash${OE} ${MAINDIR}/GBA${OE} \
-${MAINDIR}/gbafilter${OE} ${MAINDIR}/Gfx${OE} ${MAINDIR}/Globals${OE} ${MAINDIR}/interframe${OE} \
-${MAINDIR}/hq2x${OE} ${MAINDIR}/GBA-thumb${OE} ${MAINDIR}/GBA-arm${OE} ${MAINDIR}/Mode0${OE} \
+${MAINDIR}/EEprom${OE} ${MAINDIR}/elf${OE} ${MAINDIR}/Flash${OE} ${MAINDIR}/agb/GBA${OE} \
+${MAINDIR}/agb/gbafilter${OE} ${MAINDIR}/agb/GBAGFX${OE} ${MAINDIR}/Globals${OE} ${MAINDIR}/interframe${OE} \
+${MAINDIR}/hq2x${OE} ${MAINDIR}/agb/gba-thumb${OE} ${MAINDIR}/agb/gba-arm${OE} ${MAINDIR}/Mode0${OE} \
${MAINDIR}/Mode1${OE} ${MAINDIR}/Mode2${OE} ${MAINDIR}/Mode3${OE} ${MAINDIR}/Mode4${OE} \
${MAINDIR}/Mode5${OE} ${MAINDIR}/pixel${OE} \
${MAINDIR}/remote${OE} ${MAINDIR}/RTC${OE} ${MAINDIR}/scanline${OE} \
diff --git a/VBA.vcproj b/VBA.vcproj
index 289ea66d..08c8d47c 100644
--- a/VBA.vcproj
+++ b/VBA.vcproj
@@ -602,7 +602,7 @@
>
#include
-#include "GBA.h"
-#include "GBAinline.h"
+#include "agb/GBA.h"
+#include "agb/GBAinline.h"
#include "Cheats.h"
#include "Globals.h"
#include "NLS.h"
diff --git a/src/EEprom.cpp b/src/EEprom.cpp
index 7280339f..2b6b3800 100644
--- a/src/EEprom.cpp
+++ b/src/EEprom.cpp
@@ -17,7 +17,7 @@
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include
-#include "GBA.h"
+#include "agb/GBA.h"
#include "EEprom.h"
#include "Util.h"
diff --git a/src/Flash.cpp b/src/Flash.cpp
index 2cb81c71..362a424d 100644
--- a/src/Flash.cpp
+++ b/src/Flash.cpp
@@ -18,7 +18,7 @@
#include
#include
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Globals.h"
#include "Flash.h"
#include "Sram.h"
diff --git a/src/GBA-arm.cpp b/src/GBA-arm.cpp
deleted file mode 100644
index bda12b4f..00000000
--- a/src/GBA-arm.cpp
+++ /dev/null
@@ -1,2966 +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.
-
-#include
-#include
-#include
-#include
-#include
-
-#include "GBA.h"
-#include "GBAcpu.h"
-#include "GBAinline.h"
-#include "Globals.h"
-#include "EEprom.h"
-#include "Flash.h"
-#include "Sound.h"
-#include "Sram.h"
-#include "bios.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 GBA_LOGGING
- 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*0xF00*/10;op++){if(armInsnTable[op]==arm_UI)continue;
- int i;for(i=0;i> 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 "EEprom.h"
-#include "Flash.h"
-#include "Sound.h"
-#include "Sram.h"
-#include "bios.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
-#define snprintf _snprintf
-#endif
-
-///////////////////////////////////////////////////////////////////////////
-
-static int clockTicks;
-
-static INSN_REGPARM void thumbUnknownInsn(u32 opcode)
-{
-#ifdef GBA_LOGGING
- 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)(const 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 --git a/src/GBA.cpp b/src/GBA.cpp
deleted file mode 100644
index c3a4969f..00000000
--- a/src/GBA.cpp
+++ /dev/null
@@ -1,3983 +0,0 @@
-// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
-// Copyright (C) 1999-2003 Forgotten
-// Copyright (C) 2005-2006 Forgotten and the VBA development team
-// Copyright (C) VBA-M 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 "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 __GNUC__
-#define _stricmp strcasecmp
-#endif
-
-
-extern int emulating;
-#ifdef LINK_EMULATION
-extern int linktime;
-extern void StartLink(u16);
-extern void StartJOYLink(u16);
-extern void StartGPLink(u16);
-extern void LinkSSend(u16);
-extern void LinkUpdate(int);
-extern int linktime2;
-#endif
-int SWITicks = 0;
-int IRQTicks = 0;
-
-u32 mastercode = 0;
-int layerEnableDelay = 0;
-bool busPrefetch = false;
-bool busPrefetchEnable = false;
-u32 busPrefetchCount = 0;
-int cpuDmaTicksToUpdate = 0;
-int cpuDmaCount = 0;
-bool cpuDmaHack = false;
-u32 cpuDmaLast = 0;
-int dummyAddress = 0;
-
-bool cpuBreakLoop = false;
-int cpuNextEvent = 0;
-
-int gbaSaveType = 0; // used to remember the save type on reset
-bool intState = false;
-bool stopState = false;
-bool holdState = false;
-int holdType = 0;
-bool cpuSramEnabled = true;
-bool cpuFlashEnabled = true;
-bool cpuEEPROMEnabled = true;
-bool cpuEEPROMSensorEnabled = false;
-
-u32 cpuPrefetch[2];
-
-int cpuTotalTicks = 0;
-#ifdef PROFILING
-int profilingTicks = 0;
-int profilingTicksReload = 0;
-static profile_segment *profilSegment = NULL;
-#endif
-
-#ifdef BKPT_SUPPORT
-u8 freezeWorkRAM[0x40000];
-u8 freezeInternalRAM[0x8000];
-u8 freezeVRAM[0x18000];
-u8 freezePRAM[0x400];
-u8 freezeOAM[0x400];
-bool debugger_last;
-#endif
-
-int lcdTicks = (useBios && !skipBios) ? 1008 : 208;
-u8 timerOnOffDelay = 0;
-u16 timer0Value = 0;
-bool timer0On = false;
-int timer0Ticks = 0;
-int timer0Reload = 0;
-int timer0ClockReload = 0;
-u16 timer1Value = 0;
-bool timer1On = false;
-int timer1Ticks = 0;
-int timer1Reload = 0;
-int timer1ClockReload = 0;
-u16 timer2Value = 0;
-bool timer2On = false;
-int timer2Ticks = 0;
-int timer2Reload = 0;
-int timer2ClockReload = 0;
-u16 timer3Value = 0;
-bool timer3On = false;
-int timer3Ticks = 0;
-int timer3Reload = 0;
-int timer3ClockReload = 0;
-u32 dma0Source = 0;
-u32 dma0Dest = 0;
-u32 dma1Source = 0;
-u32 dma1Dest = 0;
-u32 dma2Source = 0;
-u32 dma2Dest = 0;
-u32 dma3Source = 0;
-u32 dma3Dest = 0;
-void (*cpuSaveGameFunc)(u32,u8) = flashSaveDecide;
-void (*renderLine)() = mode0RenderLine;
-bool fxOn = false;
-bool windowOn = false;
-int frameCount = 0;
-char buffer[1024];
-FILE *out = NULL;
-u32 lastTime = 0;
-int count = 0;
-
-int capture = 0;
-int capturePrevious = 0;
-int captureNumber = 0;
-
-const int TIMER_TICKS[4] = {
- 0,
- 6,
- 8,
- 10
-};
-
-const u32 objTilesAddress [3] = {0x010000, 0x014000, 0x014000};
-const u8 gamepakRamWaitState[4] = { 4, 3, 2, 8 };
-const u8 gamepakWaitState[4] = { 4, 3, 2, 8 };
-const u8 gamepakWaitState0[2] = { 2, 1 };
-const u8 gamepakWaitState1[2] = { 4, 1 };
-const u8 gamepakWaitState2[2] = { 8, 1 };
-const bool isInRom [16]=
- { false, false, false, false, false, false, false, false,
- true, true, true, true, true, true, false, false };
-
-u8 memoryWait[16] =
- { 0, 0, 2, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0 };
-u8 memoryWait32[16] =
- { 0, 0, 5, 0, 0, 1, 1, 0, 7, 7, 9, 9, 13, 13, 4, 0 };
-u8 memoryWaitSeq[16] =
- { 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 4, 4, 8, 8, 4, 0 };
-u8 memoryWaitSeq32[16] =
- { 0, 0, 5, 0, 0, 1, 1, 0, 5, 5, 9, 9, 17, 17, 4, 0 };
-
-// The videoMemoryWait constants are used to add some waitstates
-// if the opcode access video memory data outside of vblank/hblank
-// It seems to happen on only one ticks for each pixel.
-// Not used for now (too problematic with current code).
-//const u8 videoMemoryWait[16] =
-// {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-
-u8 biosProtected[4];
-
-#ifdef WORDS_BIGENDIAN
-bool cpuBiosSwapped = false;
-#endif
-
-u32 myROM[] = {
-0xEA000006,
-0xEA000093,
-0xEA000006,
-0x00000000,
-0x00000000,
-0x00000000,
-0xEA000088,
-0x00000000,
-0xE3A00302,
-0xE1A0F000,
-0xE92D5800,
-0xE55EC002,
-0xE28FB03C,
-0xE79BC10C,
-0xE14FB000,
-0xE92D0800,
-0xE20BB080,
-0xE38BB01F,
-0xE129F00B,
-0xE92D4004,
-0xE1A0E00F,
-0xE12FFF1C,
-0xE8BD4004,
-0xE3A0C0D3,
-0xE129F00C,
-0xE8BD0800,
-0xE169F00B,
-0xE8BD5800,
-0xE1B0F00E,
-0x0000009C,
-0x0000009C,
-0x0000009C,
-0x0000009C,
-0x000001F8,
-0x000001F0,
-0x000000AC,
-0x000000A0,
-0x000000FC,
-0x00000168,
-0xE12FFF1E,
-0xE1A03000,
-0xE1A00001,
-0xE1A01003,
-0xE2113102,
-0x42611000,
-0xE033C040,
-0x22600000,
-0xE1B02001,
-0xE15200A0,
-0x91A02082,
-0x3AFFFFFC,
-0xE1500002,
-0xE0A33003,
-0x20400002,
-0xE1320001,
-0x11A020A2,
-0x1AFFFFF9,
-0xE1A01000,
-0xE1A00003,
-0xE1B0C08C,
-0x22600000,
-0x42611000,
-0xE12FFF1E,
-0xE92D0010,
-0xE1A0C000,
-0xE3A01001,
-0xE1500001,
-0x81A000A0,
-0x81A01081,
-0x8AFFFFFB,
-0xE1A0000C,
-0xE1A04001,
-0xE3A03000,
-0xE1A02001,
-0xE15200A0,
-0x91A02082,
-0x3AFFFFFC,
-0xE1500002,
-0xE0A33003,
-0x20400002,
-0xE1320001,
-0x11A020A2,
-0x1AFFFFF9,
-0xE0811003,
-0xE1B010A1,
-0xE1510004,
-0x3AFFFFEE,
-0xE1A00004,
-0xE8BD0010,
-0xE12FFF1E,
-0xE0010090,
-0xE1A01741,
-0xE2611000,
-0xE3A030A9,
-0xE0030391,
-0xE1A03743,
-0xE2833E39,
-0xE0030391,
-0xE1A03743,
-0xE2833C09,
-0xE283301C,
-0xE0030391,
-0xE1A03743,
-0xE2833C0F,
-0xE28330B6,
-0xE0030391,
-0xE1A03743,
-0xE2833C16,
-0xE28330AA,
-0xE0030391,
-0xE1A03743,
-0xE2833A02,
-0xE2833081,
-0xE0030391,
-0xE1A03743,
-0xE2833C36,
-0xE2833051,
-0xE0030391,
-0xE1A03743,
-0xE2833CA2,
-0xE28330F9,
-0xE0000093,
-0xE1A00840,
-0xE12FFF1E,
-0xE3A00001,
-0xE3A01001,
-0xE92D4010,
-0xE3A03000,
-0xE3A04001,
-0xE3500000,
-0x1B000004,
-0xE5CC3301,
-0xEB000002,
-0x0AFFFFFC,
-0xE8BD4010,
-0xE12FFF1E,
-0xE3A0C301,
-0xE5CC3208,
-0xE15C20B8,
-0xE0110002,
-0x10222000,
-0x114C20B8,
-0xE5CC4208,
-0xE12FFF1E,
-0xE92D500F,
-0xE3A00301,
-0xE1A0E00F,
-0xE510F004,
-0xE8BD500F,
-0xE25EF004,
-0xE59FD044,
-0xE92D5000,
-0xE14FC000,
-0xE10FE000,
-0xE92D5000,
-0xE3A0C302,
-0xE5DCE09C,
-0xE35E00A5,
-0x1A000004,
-0x05DCE0B4,
-0x021EE080,
-0xE28FE004,
-0x159FF018,
-0x059FF018,
-0xE59FD018,
-0xE8BD5000,
-0xE169F00C,
-0xE8BD5000,
-0xE25EF004,
-0x03007FF0,
-0x09FE2000,
-0x09FFC000,
-0x03007FE0
-};
-
-variable_desc saveGameStruct[] = {
- { &DISPCNT , sizeof(u16) },
- { &DISPSTAT , sizeof(u16) },
- { &VCOUNT , sizeof(u16) },
- { &BG0CNT , sizeof(u16) },
- { &BG1CNT , sizeof(u16) },
- { &BG2CNT , sizeof(u16) },
- { &BG3CNT , sizeof(u16) },
- { &BG0HOFS , sizeof(u16) },
- { &BG0VOFS , sizeof(u16) },
- { &BG1HOFS , sizeof(u16) },
- { &BG1VOFS , sizeof(u16) },
- { &BG2HOFS , sizeof(u16) },
- { &BG2VOFS , sizeof(u16) },
- { &BG3HOFS , sizeof(u16) },
- { &BG3VOFS , sizeof(u16) },
- { &BG2PA , sizeof(u16) },
- { &BG2PB , sizeof(u16) },
- { &BG2PC , sizeof(u16) },
- { &BG2PD , sizeof(u16) },
- { &BG2X_L , sizeof(u16) },
- { &BG2X_H , sizeof(u16) },
- { &BG2Y_L , sizeof(u16) },
- { &BG2Y_H , sizeof(u16) },
- { &BG3PA , sizeof(u16) },
- { &BG3PB , sizeof(u16) },
- { &BG3PC , sizeof(u16) },
- { &BG3PD , sizeof(u16) },
- { &BG3X_L , sizeof(u16) },
- { &BG3X_H , sizeof(u16) },
- { &BG3Y_L , sizeof(u16) },
- { &BG3Y_H , sizeof(u16) },
- { &WIN0H , sizeof(u16) },
- { &WIN1H , sizeof(u16) },
- { &WIN0V , sizeof(u16) },
- { &WIN1V , sizeof(u16) },
- { &WININ , sizeof(u16) },
- { &WINOUT , sizeof(u16) },
- { &MOSAIC , sizeof(u16) },
- { &BLDMOD , sizeof(u16) },
- { &COLEV , sizeof(u16) },
- { &COLY , sizeof(u16) },
- { &DM0SAD_L , sizeof(u16) },
- { &DM0SAD_H , sizeof(u16) },
- { &DM0DAD_L , sizeof(u16) },
- { &DM0DAD_H , sizeof(u16) },
- { &DM0CNT_L , sizeof(u16) },
- { &DM0CNT_H , sizeof(u16) },
- { &DM1SAD_L , sizeof(u16) },
- { &DM1SAD_H , sizeof(u16) },
- { &DM1DAD_L , sizeof(u16) },
- { &DM1DAD_H , sizeof(u16) },
- { &DM1CNT_L , sizeof(u16) },
- { &DM1CNT_H , sizeof(u16) },
- { &DM2SAD_L , sizeof(u16) },
- { &DM2SAD_H , sizeof(u16) },
- { &DM2DAD_L , sizeof(u16) },
- { &DM2DAD_H , sizeof(u16) },
- { &DM2CNT_L , sizeof(u16) },
- { &DM2CNT_H , sizeof(u16) },
- { &DM3SAD_L , sizeof(u16) },
- { &DM3SAD_H , sizeof(u16) },
- { &DM3DAD_L , sizeof(u16) },
- { &DM3DAD_H , sizeof(u16) },
- { &DM3CNT_L , sizeof(u16) },
- { &DM3CNT_H , sizeof(u16) },
- { &TM0D , sizeof(u16) },
- { &TM0CNT , sizeof(u16) },
- { &TM1D , sizeof(u16) },
- { &TM1CNT , sizeof(u16) },
- { &TM2D , sizeof(u16) },
- { &TM2CNT , sizeof(u16) },
- { &TM3D , sizeof(u16) },
- { &TM3CNT , sizeof(u16) },
- { &P1 , sizeof(u16) },
- { &IE , sizeof(u16) },
- { &IF , sizeof(u16) },
- { &IME , sizeof(u16) },
- { &holdState, sizeof(bool) },
- { &holdType, sizeof(int) },
- { &lcdTicks, sizeof(int) },
- { &timer0On , sizeof(bool) },
- { &timer0Ticks , sizeof(int) },
- { &timer0Reload , sizeof(int) },
- { &timer0ClockReload , sizeof(int) },
- { &timer1On , sizeof(bool) },
- { &timer1Ticks , sizeof(int) },
- { &timer1Reload , sizeof(int) },
- { &timer1ClockReload , sizeof(int) },
- { &timer2On , sizeof(bool) },
- { &timer2Ticks , sizeof(int) },
- { &timer2Reload , sizeof(int) },
- { &timer2ClockReload , sizeof(int) },
- { &timer3On , sizeof(bool) },
- { &timer3Ticks , sizeof(int) },
- { &timer3Reload , sizeof(int) },
- { &timer3ClockReload , sizeof(int) },
- { &dma0Source , sizeof(u32) },
- { &dma0Dest , sizeof(u32) },
- { &dma1Source , sizeof(u32) },
- { &dma1Dest , sizeof(u32) },
- { &dma2Source , sizeof(u32) },
- { &dma2Dest , sizeof(u32) },
- { &dma3Source , sizeof(u32) },
- { &dma3Dest , sizeof(u32) },
- { &fxOn, sizeof(bool) },
- { &windowOn, sizeof(bool) },
- { &N_FLAG , sizeof(bool) },
- { &C_FLAG , sizeof(bool) },
- { &Z_FLAG , sizeof(bool) },
- { &V_FLAG , sizeof(bool) },
- { &armState , sizeof(bool) },
- { &armIrqEnable , sizeof(bool) },
- { &armNextPC , sizeof(u32) },
- { &armMode , sizeof(int) },
- { &saveType , sizeof(int) },
- { NULL, 0 }
-};
-
-static int romSize = 0x2000000;
-
-#ifdef PROFILING
-void cpuProfil(profile_segment *seg)
-{
- profilSegment = seg;
-}
-
-void cpuEnableProfiling(int hz)
-{
- if(hz == 0)
- hz = 100;
- profilingTicks = profilingTicksReload = 16777216 / hz;
- profSetHertz(hz);
-}
-#endif
-
-
-inline int CPUUpdateTicks()
-{
- int cpuLoopTicks = lcdTicks;
-
- if(soundTicks < cpuLoopTicks)
- cpuLoopTicks = soundTicks;
-
- if(timer0On && (timer0Ticks < cpuLoopTicks)) {
- cpuLoopTicks = timer0Ticks;
- }
- if(timer1On && !(TM1CNT & 4) && (timer1Ticks < cpuLoopTicks)) {
- cpuLoopTicks = timer1Ticks;
- }
- if(timer2On && !(TM2CNT & 4) && (timer2Ticks < cpuLoopTicks)) {
- cpuLoopTicks = timer2Ticks;
- }
- if(timer3On && !(TM3CNT & 4) && (timer3Ticks < cpuLoopTicks)) {
- cpuLoopTicks = timer3Ticks;
- }
-#ifdef PROFILING
- if(profilingTicksReload != 0) {
- if(profilingTicks < cpuLoopTicks) {
- cpuLoopTicks = profilingTicks;
- }
- }
-#endif
-
- if (SWITicks) {
- if (SWITicks < cpuLoopTicks)
- cpuLoopTicks = SWITicks;
- }
-
- if (IRQTicks) {
- if (IRQTicks < cpuLoopTicks)
- cpuLoopTicks = IRQTicks;
- }
-
- return cpuLoopTicks;
-}
-
-void CPUUpdateWindow0()
-{
- int x00 = WIN0H>>8;
- int x01 = WIN0H & 255;
-
- if(x00 <= x01) {
- for(int i = 0; i < 240; i++) {
- gfxInWin0[i] = (i >= x00 && i < x01);
- }
- } else {
- for(int i = 0; i < 240; i++) {
- gfxInWin0[i] = (i >= x00 || i < x01);
- }
- }
-}
-
-void CPUUpdateWindow1()
-{
- int x00 = WIN1H>>8;
- int x01 = WIN1H & 255;
-
- if(x00 <= x01) {
- for(int i = 0; i < 240; i++) {
- gfxInWin1[i] = (i >= x00 && i < x01);
- }
- } else {
- for(int i = 0; i < 240; i++) {
- gfxInWin1[i] = (i >= x00 || i < x01);
- }
- }
-}
-
-extern u32 line0[240];
-extern u32 line1[240];
-extern u32 line2[240];
-extern u32 line3[240];
-
-#define CLEAR_ARRAY(a) \
- {\
- u32 *array = (a);\
- for(int i = 0; i < 240; i++) {\
- *array++ = 0x80000000;\
- }\
- }\
-
-void CPUUpdateRenderBuffers(bool force)
-{
- if(!(layerEnable & 0x0100) || force) {
- CLEAR_ARRAY(line0);
- }
- if(!(layerEnable & 0x0200) || force) {
- CLEAR_ARRAY(line1);
- }
- if(!(layerEnable & 0x0400) || force) {
- CLEAR_ARRAY(line2);
- }
- if(!(layerEnable & 0x0800) || force) {
- CLEAR_ARRAY(line3);
- }
-}
-
-static bool CPUWriteState(gzFile gzFile)
-{
- utilWriteInt(gzFile, SAVE_GAME_VERSION);
-
- utilGzWrite(gzFile, &rom[0xa0], 16);
-
- utilWriteInt(gzFile, useBios);
-
- utilGzWrite(gzFile, ®[0], sizeof(reg));
-
- utilWriteData(gzFile, saveGameStruct);
-
- // new to version 0.7.1
- utilWriteInt(gzFile, stopState);
- // new to version 0.8
- utilWriteInt(gzFile, IRQTicks);
-
- utilGzWrite(gzFile, internalRAM, 0x8000);
- utilGzWrite(gzFile, paletteRAM, 0x400);
- utilGzWrite(gzFile, workRAM, 0x40000);
- utilGzWrite(gzFile, vram, 0x20000);
- utilGzWrite(gzFile, oam, 0x400);
- utilGzWrite(gzFile, pix, 4*241*162);
- utilGzWrite(gzFile, ioMem, 0x400);
-
- eepromSaveGame(gzFile);
- flashSaveGame(gzFile);
- soundSaveGame(gzFile);
-
- cheatsSaveGame(gzFile);
-
- // version 1.5
- rtcSaveGame(gzFile);
-
- return true;
-}
-
-bool CPUWriteState(const char *file)
-{
- gzFile gzFile = utilGzOpen(file, "wb");
-
- if(gzFile == NULL) {
- systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), file);
- return false;
- }
-
- bool res = CPUWriteState(gzFile);
-
- utilGzClose(gzFile);
-
- return res;
-}
-
-bool CPUWriteMemState(char *memory, int available)
-{
- gzFile gzFile = utilMemGzOpen(memory, available, "w");
-
- if(gzFile == NULL) {
- return false;
- }
-
- bool res = CPUWriteState(gzFile);
-
- long pos = utilGzMemTell(gzFile)+8;
-
- if(pos >= (available))
- res = false;
-
- utilGzClose(gzFile);
-
- return res;
-}
-
-static bool CPUReadState(gzFile gzFile)
-{
- int version = utilReadInt(gzFile);
-
- if(version > SAVE_GAME_VERSION || version < SAVE_GAME_VERSION_1) {
- systemMessage(MSG_UNSUPPORTED_VBA_SGM,
- N_("Unsupported VisualBoyAdvance save game version %d"),
- version);
- return false;
- }
-
- u8 romname[17];
-
- utilGzRead(gzFile, romname, 16);
-
- if(memcmp(&rom[0xa0], romname, 16) != 0) {
- romname[16]=0;
- for(int i = 0; i < 16; i++)
- if(romname[i] < 32)
- romname[i] = 32;
- systemMessage(MSG_CANNOT_LOAD_SGM, N_("Cannot load save game for %s"), romname);
- return false;
- }
-
- bool ub = utilReadInt(gzFile) ? true : false;
-
- if(ub != useBios) {
- if(useBios)
- systemMessage(MSG_SAVE_GAME_NOT_USING_BIOS,
- N_("Save game is not using the BIOS files"));
- else
- systemMessage(MSG_SAVE_GAME_USING_BIOS,
- N_("Save game is using the BIOS file"));
- return false;
- }
-
- utilGzRead(gzFile, ®[0], sizeof(reg));
-
- utilReadData(gzFile, saveGameStruct);
-
- if(version < SAVE_GAME_VERSION_3)
- stopState = false;
- else
- stopState = utilReadInt(gzFile) ? true : false;
-
- if(version < SAVE_GAME_VERSION_4)
- {
- IRQTicks = 0;
- intState = false;
- }
- else
- {
- IRQTicks = utilReadInt(gzFile);
- if (IRQTicks>0)
- intState = true;
- else
- {
- intState = false;
- IRQTicks = 0;
- }
- }
-
- utilGzRead(gzFile, internalRAM, 0x8000);
- utilGzRead(gzFile, paletteRAM, 0x400);
- utilGzRead(gzFile, workRAM, 0x40000);
- utilGzRead(gzFile, vram, 0x20000);
- utilGzRead(gzFile, oam, 0x400);
- if(version < SAVE_GAME_VERSION_6)
- utilGzRead(gzFile, pix, 4*240*160);
- else
- utilGzRead(gzFile, pix, 4*241*162);
- utilGzRead(gzFile, ioMem, 0x400);
-
- eepromReadGame(gzFile, version);
- flashReadGame(gzFile, version);
- soundReadGame(gzFile, version);
-
- if(version > SAVE_GAME_VERSION_1) {
- cheatsReadGame(gzFile, version);
- }
- if(version > SAVE_GAME_VERSION_6) {
- rtcReadGame(gzFile);
- }
-
- if(version <= SAVE_GAME_VERSION_7) {
- u32 temp;
-#define SWAP(a,b,c) \
- temp = (a);\
- (a) = (b)<<16|(c);\
- (b) = (temp) >> 16;\
- (c) = (temp) & 0xFFFF;
-
- SWAP(dma0Source, DM0SAD_H, DM0SAD_L);
- SWAP(dma0Dest, DM0DAD_H, DM0DAD_L);
- SWAP(dma1Source, DM1SAD_H, DM1SAD_L);
- SWAP(dma1Dest, DM1DAD_H, DM1DAD_L);
- SWAP(dma2Source, DM2SAD_H, DM2SAD_L);
- SWAP(dma2Dest, DM2DAD_H, DM2DAD_L);
- SWAP(dma3Source, DM3SAD_H, DM3SAD_L);
- SWAP(dma3Dest, DM3DAD_H, DM3DAD_L);
- }
-
- if(version <= SAVE_GAME_VERSION_8) {
- timer0ClockReload = TIMER_TICKS[TM0CNT & 3];
- timer1ClockReload = TIMER_TICKS[TM1CNT & 3];
- timer2ClockReload = TIMER_TICKS[TM2CNT & 3];
- timer3ClockReload = TIMER_TICKS[TM3CNT & 3];
-
- timer0Ticks = ((0x10000 - TM0D) << timer0ClockReload) - timer0Ticks;
- timer1Ticks = ((0x10000 - TM1D) << timer1ClockReload) - timer1Ticks;
- timer2Ticks = ((0x10000 - TM2D) << timer2ClockReload) - timer2Ticks;
- timer3Ticks = ((0x10000 - TM3D) << timer3ClockReload) - timer3Ticks;
- interp_rate();
- }
-
- // set pointers!
- layerEnable = layerSettings & DISPCNT;
-
- CPUUpdateRender();
- CPUUpdateRenderBuffers(true);
- CPUUpdateWindow0();
- CPUUpdateWindow1();
- gbaSaveType = 0;
- switch(saveType) {
- case 0:
- cpuSaveGameFunc = flashSaveDecide;
- break;
- case 1:
- cpuSaveGameFunc = sramWrite;
- gbaSaveType = 1;
- break;
- case 2:
- cpuSaveGameFunc = flashWrite;
- gbaSaveType = 2;
- break;
- case 3:
- break;
- case 5:
- gbaSaveType = 5;
- break;
- default:
- systemMessage(MSG_UNSUPPORTED_SAVE_TYPE,
- N_("Unsupported save type %d"), saveType);
- break;
- }
- if(eepromInUse)
- gbaSaveType = 3;
-
- systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
- if(armState) {
- ARM_PREFETCH;
- } else {
- THUMB_PREFETCH;
- }
-
- CPUUpdateRegister(0x204, CPUReadHalfWordQuick(0x4000204));
-
- return true;
-}
-
-bool CPUReadMemState(char *memory, int available)
-{
- gzFile gzFile = utilMemGzOpen(memory, available, "r");
-
- bool res = CPUReadState(gzFile);
-
- utilGzClose(gzFile);
-
- return res;
-}
-
-bool CPUReadState(const char * file)
-{
- gzFile gzFile = utilGzOpen(file, "rb");
-
- if(gzFile == NULL)
- return false;
-
- bool res = CPUReadState(gzFile);
-
- utilGzClose(gzFile);
-
- return res;
-}
-
-bool CPUExportEepromFile(const char *fileName)
-{
- if(eepromInUse) {
- FILE *file = fopen(fileName, "wb");
-
- if(!file) {
- systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"),
- fileName);
- return false;
- }
-
- for(int i = 0; i < eepromSize;) {
- for(int j = 0; j < 8; j++) {
- if(fwrite(&eepromData[i+7-j], 1, 1, file) != 1) {
- fclose(file);
- return false;
- }
- }
- i += 8;
- }
- fclose(file);
- }
- return true;
-}
-
-bool CPUWriteBatteryFile(const char *fileName)
-{
- if(gbaSaveType == 0) {
- if(eepromInUse)
- gbaSaveType = 3;
- else switch(saveType) {
- case 1:
- gbaSaveType = 1;
- break;
- case 2:
- gbaSaveType = 2;
- break;
- }
- }
-
- if((gbaSaveType) && (gbaSaveType!=5)) {
- FILE *file = fopen(fileName, "wb");
-
- if(!file) {
- systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"),
- fileName);
- return false;
- }
-
- // only save if Flash/Sram in use or EEprom in use
- if(gbaSaveType != 3) {
- if(gbaSaveType == 2) {
- if(fwrite(flashSaveMemory, 1, flashSize, file) != (size_t)flashSize) {
- fclose(file);
- return false;
- }
- } else {
- if(fwrite(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
- fclose(file);
- return false;
- }
- }
- } else {
- if(fwrite(eepromData, 1, eepromSize, file) != (size_t)eepromSize) {
- fclose(file);
- return false;
- }
- }
- fclose(file);
- }
- return true;
-}
-
-bool CPUReadGSASnapshot(const char *fileName)
-{
- int i;
- FILE *file = fopen(fileName, "rb");
-
- if(!file) {
- systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
- return false;
- }
-
- // check file size to know what we should read
- fseek(file, 0, SEEK_END);
-
- // long size = ftell(file);
- fseek(file, 0x0, SEEK_SET);
- fread(&i, 1, 4, file);
- fseek(file, i, SEEK_CUR); // Skip SharkPortSave
- fseek(file, 4, SEEK_CUR); // skip some sort of flag
- fread(&i, 1, 4, file); // name length
- fseek(file, i, SEEK_CUR); // skip name
- fread(&i, 1, 4, file); // desc length
- fseek(file, i, SEEK_CUR); // skip desc
- fread(&i, 1, 4, file); // notes length
- fseek(file, i, SEEK_CUR); // skip notes
- int saveSize;
- fread(&saveSize, 1, 4, file); // read length
- saveSize -= 0x1c; // remove header size
- char buffer[17];
- char buffer2[17];
- fread(buffer, 1, 16, file);
- buffer[16] = 0;
- for(i = 0; i < 16; i++)
- if(buffer[i] < 32)
- buffer[i] = 32;
- memcpy(buffer2, &rom[0xa0], 16);
- buffer2[16] = 0;
- for(i = 0; i < 16; i++)
- if(buffer2[i] < 32)
- buffer2[i] = 32;
- if(memcmp(buffer, buffer2, 16)) {
- systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR,
- N_("Cannot import snapshot for %s. Current game is %s"),
- buffer,
- buffer2);
- fclose(file);
- return false;
- }
- fseek(file, 12, SEEK_CUR); // skip some flags
- if(saveSize >= 65536) {
- if(fread(flashSaveMemory, 1, saveSize, file) != (size_t)saveSize) {
- fclose(file);
- return false;
- }
- } else {
- systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE,
- N_("Unsupported snapshot file %s"),
- fileName);
- fclose(file);
- return false;
- }
- fclose(file);
- CPUReset();
- return true;
-}
-
-bool CPUWriteGSASnapshot(const char *fileName,
- const char *title,
- const char *desc,
- const char *notes)
-{
- FILE *file = fopen(fileName, "wb");
-
- if(!file) {
- systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
- return false;
- }
-
- u8 buffer[17];
-
- utilPutDword(buffer, 0x0d); // SharkPortSave length
- fwrite(buffer, 1, 4, file);
- fwrite("SharkPortSave", 1, 0x0d, file);
- utilPutDword(buffer, 0x000f0000);
- fwrite(buffer, 1, 4, file); // save type 0x000f0000 = GBA save
- utilPutDword(buffer, (u32)strlen(title));
- fwrite(buffer, 1, 4, file); // title length
- fwrite(title, 1, strlen(title), file);
- utilPutDword(buffer, (u32)strlen(desc));
- fwrite(buffer, 1, 4, file); // desc length
- fwrite(desc, 1, strlen(desc), file);
- utilPutDword(buffer, (u32)strlen(notes));
- fwrite(buffer, 1, 4, file); // notes length
- fwrite(notes, 1, strlen(notes), file);
- int saveSize = 0x10000;
- if(gbaSaveType == 2)
- saveSize = flashSize;
- int totalSize = saveSize + 0x1c;
-
- utilPutDword(buffer, totalSize); // length of remainder of save - CRC
- fwrite(buffer, 1, 4, file);
-
- char temp[0x2001c];
- memset(temp, 0, 28);
- memcpy(temp, &rom[0xa0], 16); // copy internal name
- temp[0x10] = rom[0xbe]; // reserved area (old checksum)
- temp[0x11] = rom[0xbf]; // reserved area (old checksum)
- temp[0x12] = rom[0xbd]; // complement check
- temp[0x13] = rom[0xb0]; // maker
- temp[0x14] = 1; // 1 save ?
- memcpy(&temp[0x1c], flashSaveMemory, saveSize); // copy save
- fwrite(temp, 1, totalSize, file); // write save + header
- u32 crc = 0;
-
- for(int i = 0; i < totalSize; i++) {
- crc += ((u32)temp[i] << (crc % 0x18));
- }
-
- utilPutDword(buffer, crc);
- fwrite(buffer, 1, 4, file); // CRC?
-
- fclose(file);
- return true;
-}
-
-bool CPUImportEepromFile(const char *fileName)
-{
- FILE *file = fopen(fileName, "rb");
-
- if(!file)
- return false;
-
- // check file size to know what we should read
- fseek(file, 0, SEEK_END);
-
- long size = ftell(file);
- fseek(file, 0, SEEK_SET);
- if(size == 512 || size == 0x2000) {
- if(fread(eepromData, 1, size, file) != (size_t)size) {
- fclose(file);
- return false;
- }
- for(int i = 0; i < size;) {
- u8 tmp = eepromData[i];
- eepromData[i] = eepromData[7-i];
- eepromData[7-i] = tmp;
- i++;
- tmp = eepromData[i];
- eepromData[i] = eepromData[7-i];
- eepromData[7-i] = tmp;
- i++;
- tmp = eepromData[i];
- eepromData[i] = eepromData[7-i];
- eepromData[7-i] = tmp;
- i++;
- tmp = eepromData[i];
- eepromData[i] = eepromData[7-i];
- eepromData[7-i] = tmp;
- i++;
- i += 4;
- }
- } else
- return false;
- fclose(file);
- return true;
-}
-
-bool CPUReadBatteryFile(const char *fileName)
-{
- FILE *file = fopen(fileName, "rb");
-
- if(!file)
- return false;
-
- // check file size to know what we should read
- fseek(file, 0, SEEK_END);
-
- long size = ftell(file);
- fseek(file, 0, SEEK_SET);
- systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
-
- if(size == 512 || size == 0x2000) {
- if(fread(eepromData, 1, size, file) != (size_t)size) {
- fclose(file);
- return false;
- }
- } else {
- if(size == 0x20000) {
- if(fread(flashSaveMemory, 1, 0x20000, file) != 0x20000) {
- fclose(file);
- return false;
- }
- flashSetSize(0x20000);
- } else {
- if(fread(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
- fclose(file);
- return false;
- }
- flashSetSize(0x10000);
- }
- }
- fclose(file);
- return true;
-}
-
-bool CPUWritePNGFile(const char *fileName)
-{
- return utilWritePNGFile(fileName, 240, 160, pix);
-}
-
-bool CPUWriteBMPFile(const char *fileName)
-{
- return utilWriteBMPFile(fileName, 240, 160, pix);
-}
-
-bool CPUIsZipFile(const char * file)
-{
- if(strlen(file) > 4) {
- const char * p = strrchr(file,'.');
-
- if(p != NULL) {
- if(_stricmp(p, ".zip") == 0)
- return true;
- }
- }
-
- return false;
-}
-
-bool CPUIsGBAImage(const char * file)
-{
- cpuIsMultiBoot = false;
- if(strlen(file) > 4) {
- const char * p = strrchr(file,'.');
-
- if(p != NULL) {
- if(_stricmp(p, ".gba") == 0)
- return true;
- if(_stricmp(p, ".agb") == 0)
- return true;
- if(_stricmp(p, ".bin") == 0)
- return true;
- if(_stricmp(p, ".elf") == 0)
- return true;
- if(_stricmp(p, ".mb") == 0) {
- cpuIsMultiBoot = true;
- return true;
- }
- }
- }
-
- return false;
-}
-
-bool CPUIsGBABios(const char * file)
-{
- if(strlen(file) > 4) {
- const char * p = strrchr(file,'.');
-
- if(p != NULL) {
- if(_stricmp(p, ".gba") == 0)
- return true;
- if(_stricmp(p, ".agb") == 0)
- return true;
- if(_stricmp(p, ".bin") == 0)
- return true;
- if(_stricmp(p, ".bios") == 0)
- return true;
- if(_stricmp(p, ".rom") == 0)
- return true;
- }
- }
-
- return false;
-}
-
-bool CPUIsELF(const char *file)
-{
- if(strlen(file) > 4) {
- const char * p = strrchr(file,'.');
-
- if(p != NULL) {
- if(_stricmp(p, ".elf") == 0)
- return true;
- }
- }
- return false;
-}
-
-void CPUCleanUp()
-{
-#ifdef PROFILING
- if(profilingTicksReload) {
- profCleanup();
- }
-#endif
-
- if(rom != NULL) {
- free(rom);
- rom = NULL;
- }
-
- if(vram != NULL) {
- free(vram);
- vram = NULL;
- }
-
- if(paletteRAM != NULL) {
- free(paletteRAM);
- paletteRAM = NULL;
- }
-
- if(internalRAM != NULL) {
- free(internalRAM);
- internalRAM = NULL;
- }
-
- if(workRAM != NULL) {
- free(workRAM);
- workRAM = NULL;
- }
-
- if(bios != NULL) {
- free(bios);
- bios = NULL;
- }
-
- if(pix != NULL) {
- free(pix);
- pix = NULL;
- }
-
- if(oam != NULL) {
- free(oam);
- oam = NULL;
- }
-
- if(ioMem != NULL) {
- free(ioMem);
- ioMem = NULL;
- }
-
- elfCleanUp();
-
- systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
-
- emulating = 0;
-}
-
-int CPULoadRom(const char *szFile)
-{
- romSize = 0x2000000;
- if(rom != NULL) {
- CPUCleanUp();
- }
-
- systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
-
- rom = (u8 *)malloc(0x2000000);
- if(rom == NULL) {
- systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
- "ROM");
- return 0;
- }
- workRAM = (u8 *)calloc(1, 0x40000);
- if(workRAM == NULL) {
- systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
- "WRAM");
- return 0;
- }
-
- u8 *whereToLoad = cpuIsMultiBoot ? workRAM : rom;
-
- if(CPUIsELF(szFile)) {
- FILE *f = fopen(szFile, "rb");
- if(!f) {
- systemMessage(MSG_ERROR_OPENING_IMAGE, N_("Error opening image %s"),
- szFile);
- free(rom);
- rom = NULL;
- free(workRAM);
- workRAM = NULL;
- return 0;
- }
- bool res = elfRead(szFile, romSize, f);
- if(!res || romSize == 0) {
- free(rom);
- rom = NULL;
- free(workRAM);
- workRAM = NULL;
- elfCleanUp();
- return 0;
- }
- } else if(!utilLoad(szFile,
- utilIsGBAImage,
- whereToLoad,
- romSize)) {
- free(rom);
- rom = NULL;
- free(workRAM);
- workRAM = NULL;
- return 0;
- }
-
- u16 *temp = (u16 *)(rom+((romSize+1)&~1));
- int i;
- for(i = (romSize+1)&~1; i < 0x2000000; i+=2) {
- WRITE16LE(temp, (i >> 1) & 0xFFFF);
- temp++;
- }
-
- bios = (u8 *)calloc(1,0x4000);
- if(bios == NULL) {
- systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
- "BIOS");
- CPUCleanUp();
- return 0;
- }
- internalRAM = (u8 *)calloc(1,0x8000);
- if(internalRAM == NULL) {
- systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
- "IRAM");
- CPUCleanUp();
- return 0;
- }
- paletteRAM = (u8 *)calloc(1,0x400);
- if(paletteRAM == NULL) {
- systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
- "PRAM");
- CPUCleanUp();
- return 0;
- }
- vram = (u8 *)calloc(1, 0x20000);
- if(vram == NULL) {
- systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
- "VRAM");
- CPUCleanUp();
- return 0;
- }
- oam = (u8 *)calloc(1, 0x400);
- if(oam == NULL) {
- systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
- "OAM");
- CPUCleanUp();
- return 0;
- }
- pix = (u8 *)calloc(1, 4 * 241 * 162);
- if(pix == NULL) {
- systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
- "PIX");
- CPUCleanUp();
- return 0;
- }
- ioMem = (u8 *)calloc(1, 0x400);
- if(ioMem == NULL) {
- systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
- "IO");
- CPUCleanUp();
- return 0;
- }
-
- flashInit();
- eepromInit();
-
- CPUUpdateRenderBuffers(true);
-
- return romSize;
-}
-
-void doMirroring (bool b)
-{
- u32 mirroredRomSize = (((romSize)>>20) & 0x3F)<<20;
- u32 mirroredRomAddress = romSize;
- if ((mirroredRomSize <=0x800000) && (b))
- {
- mirroredRomAddress = mirroredRomSize;
- if (mirroredRomSize==0)
- mirroredRomSize=0x100000;
- while (mirroredRomAddress<0x01000000)
- {
- memcpy ((u16 *)(rom+mirroredRomAddress), (u16 *)(rom), mirroredRomSize);
- mirroredRomAddress+=mirroredRomSize;
- }
- }
-}
-
-void CPUUpdateRender()
-{
- switch(DISPCNT & 7) {
- case 0:
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
- cpuDisableSfx)
- renderLine = mode0RenderLine;
- else if(fxOn && !windowOn && !(layerEnable & 0x8000))
- renderLine = mode0RenderLineNoWindow;
- else
- renderLine = mode0RenderLineAll;
- break;
- case 1:
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
- cpuDisableSfx)
- renderLine = mode1RenderLine;
- else if(fxOn && !windowOn && !(layerEnable & 0x8000))
- renderLine = mode1RenderLineNoWindow;
- else
- renderLine = mode1RenderLineAll;
- break;
- case 2:
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
- cpuDisableSfx)
- renderLine = mode2RenderLine;
- else if(fxOn && !windowOn && !(layerEnable & 0x8000))
- renderLine = mode2RenderLineNoWindow;
- else
- renderLine = mode2RenderLineAll;
- break;
- case 3:
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
- cpuDisableSfx)
- renderLine = mode3RenderLine;
- else if(fxOn && !windowOn && !(layerEnable & 0x8000))
- renderLine = mode3RenderLineNoWindow;
- else
- renderLine = mode3RenderLineAll;
- break;
- case 4:
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
- cpuDisableSfx)
- renderLine = mode4RenderLine;
- else if(fxOn && !windowOn && !(layerEnable & 0x8000))
- renderLine = mode4RenderLineNoWindow;
- else
- renderLine = mode4RenderLineAll;
- break;
- case 5:
- if((!fxOn && !windowOn && !(layerEnable & 0x8000)) ||
- cpuDisableSfx)
- renderLine = mode5RenderLine;
- else if(fxOn && !windowOn && !(layerEnable & 0x8000))
- renderLine = mode5RenderLineNoWindow;
- else
- renderLine = mode5RenderLineAll;
- default:
- break;
- }
-}
-
-void CPUUpdateCPSR()
-{
- u32 CPSR = reg[16].I & 0x40;
- if(N_FLAG)
- CPSR |= 0x80000000;
- if(Z_FLAG)
- CPSR |= 0x40000000;
- if(C_FLAG)
- CPSR |= 0x20000000;
- if(V_FLAG)
- CPSR |= 0x10000000;
- if(!armState)
- CPSR |= 0x00000020;
- if(!armIrqEnable)
- CPSR |= 0x80;
- CPSR |= (armMode & 0x1F);
- reg[16].I = CPSR;
-}
-
-void CPUUpdateFlags(bool breakLoop)
-{
- u32 CPSR = reg[16].I;
-
- N_FLAG = (CPSR & 0x80000000) ? true: false;
- Z_FLAG = (CPSR & 0x40000000) ? true: false;
- C_FLAG = (CPSR & 0x20000000) ? true: false;
- V_FLAG = (CPSR & 0x10000000) ? true: false;
- armState = (CPSR & 0x20) ? false : true;
- armIrqEnable = (CPSR & 0x80) ? false : true;
- if(breakLoop) {
- if (armIrqEnable && (IF & IE) && (IME & 1))
- cpuNextEvent = cpuTotalTicks;
- }
-}
-
-void CPUUpdateFlags()
-{
- CPUUpdateFlags(true);
-}
-
-#ifdef WORDS_BIGENDIAN
-static void CPUSwap(volatile u32 *a, volatile u32 *b)
-{
- volatile u32 c = *b;
- *b = *a;
- *a = c;
-}
-#else
-static void CPUSwap(u32 *a, u32 *b)
-{
- u32 c = *b;
- *b = *a;
- *a = c;
-}
-#endif
-
-void CPUSwitchMode(int mode, bool saveState, bool breakLoop)
-{
- // if(armMode == mode)
- // return;
-
- CPUUpdateCPSR();
-
- switch(armMode) {
- case 0x10:
- case 0x1F:
- reg[R13_USR].I = reg[13].I;
- reg[R14_USR].I = reg[14].I;
- reg[17].I = reg[16].I;
- break;
- case 0x11:
- CPUSwap(®[R8_FIQ].I, ®[8].I);
- CPUSwap(®[R9_FIQ].I, ®[9].I);
- CPUSwap(®[R10_FIQ].I, ®[10].I);
- CPUSwap(®[R11_FIQ].I, ®[11].I);
- CPUSwap(®[R12_FIQ].I, ®[12].I);
- reg[R13_FIQ].I = reg[13].I;
- reg[R14_FIQ].I = reg[14].I;
- reg[SPSR_FIQ].I = reg[17].I;
- break;
- case 0x12:
- reg[R13_IRQ].I = reg[13].I;
- reg[R14_IRQ].I = reg[14].I;
- reg[SPSR_IRQ].I = reg[17].I;
- break;
- case 0x13:
- reg[R13_SVC].I = reg[13].I;
- reg[R14_SVC].I = reg[14].I;
- reg[SPSR_SVC].I = reg[17].I;
- break;
- case 0x17:
- reg[R13_ABT].I = reg[13].I;
- reg[R14_ABT].I = reg[14].I;
- reg[SPSR_ABT].I = reg[17].I;
- break;
- case 0x1b:
- reg[R13_UND].I = reg[13].I;
- reg[R14_UND].I = reg[14].I;
- reg[SPSR_UND].I = reg[17].I;
- break;
- }
-
- u32 CPSR = reg[16].I;
- u32 SPSR = reg[17].I;
-
- switch(mode) {
- case 0x10:
- case 0x1F:
- reg[13].I = reg[R13_USR].I;
- reg[14].I = reg[R14_USR].I;
- reg[16].I = SPSR;
- break;
- case 0x11:
- CPUSwap(®[8].I, ®[R8_FIQ].I);
- CPUSwap(®[9].I, ®[R9_FIQ].I);
- CPUSwap(®[10].I, ®[R10_FIQ].I);
- CPUSwap(®[11].I, ®[R11_FIQ].I);
- CPUSwap(®[12].I, ®[R12_FIQ].I);
- reg[13].I = reg[R13_FIQ].I;
- reg[14].I = reg[R14_FIQ].I;
- if(saveState)
- reg[17].I = CPSR;
- else
- reg[17].I = reg[SPSR_FIQ].I;
- break;
- case 0x12:
- reg[13].I = reg[R13_IRQ].I;
- reg[14].I = reg[R14_IRQ].I;
- reg[16].I = SPSR;
- if(saveState)
- reg[17].I = CPSR;
- else
- reg[17].I = reg[SPSR_IRQ].I;
- break;
- case 0x13:
- reg[13].I = reg[R13_SVC].I;
- reg[14].I = reg[R14_SVC].I;
- reg[16].I = SPSR;
- if(saveState)
- reg[17].I = CPSR;
- else
- reg[17].I = reg[SPSR_SVC].I;
- break;
- case 0x17:
- reg[13].I = reg[R13_ABT].I;
- reg[14].I = reg[R14_ABT].I;
- reg[16].I = SPSR;
- if(saveState)
- reg[17].I = CPSR;
- else
- reg[17].I = reg[SPSR_ABT].I;
- break;
- case 0x1b:
- reg[13].I = reg[R13_UND].I;
- reg[14].I = reg[R14_UND].I;
- reg[16].I = SPSR;
- if(saveState)
- reg[17].I = CPSR;
- else
- reg[17].I = reg[SPSR_UND].I;
- break;
- default:
- systemMessage(MSG_UNSUPPORTED_ARM_MODE, N_("Unsupported ARM mode %02x"), mode);
- break;
- }
- armMode = mode;
- CPUUpdateFlags(breakLoop);
- CPUUpdateCPSR();
-}
-
-void CPUSwitchMode(int mode, bool saveState)
-{
- CPUSwitchMode(mode, saveState, true);
-}
-
-void CPUUndefinedException()
-{
- u32 PC = reg[15].I;
- bool savedArmState = armState;
- CPUSwitchMode(0x1b, true, false);
- reg[14].I = PC - (savedArmState ? 4 : 2);
- reg[15].I = 0x04;
- armState = true;
- armIrqEnable = false;
- armNextPC = 0x04;
- ARM_PREFETCH;
- reg[15].I += 4;
-}
-
-void CPUSoftwareInterrupt()
-{
- u32 PC = reg[15].I;
- bool savedArmState = armState;
- CPUSwitchMode(0x13, true, false);
- reg[14].I = PC - (savedArmState ? 4 : 2);
- reg[15].I = 0x08;
- armState = true;
- armIrqEnable = false;
- armNextPC = 0x08;
- ARM_PREFETCH;
- reg[15].I += 4;
-}
-
-void CPUSoftwareInterrupt(int comment)
-{
- static bool disableMessage = false;
- if(armState) comment >>= 16;
-#ifdef BKPT_SUPPORT
- if(comment == 0xff) {
- extern void (*dbgOutput)(const char *, u32);
- dbgOutput(NULL, reg[0].I);
- return;
- }
-#endif
-#ifdef PROFILING
- if(comment == 0xfe) {
- profStartup(reg[0].I, reg[1].I);
- return;
- }
- if(comment == 0xfd) {
- profControl(reg[0].I);
- return;
- }
- if(comment == 0xfc) {
- profCleanup();
- return;
- }
- if(comment == 0xfb) {
- profCount();
- return;
- }
-#endif
- if(comment == 0xfa) {
- agbPrintFlush();
- return;
- }
-#ifdef SDL
- if(comment == 0xf9) {
- emulating = 0;
- cpuNextEvent = cpuTotalTicks;
- cpuBreakLoop = true;
- return;
- }
-#endif
- if(useBios) {
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_SWI) {
- log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
- armState ? armNextPC - 4: armNextPC -2,
- reg[0].I,
- reg[1].I,
- reg[2].I,
- VCOUNT);
- }
-#endif
- CPUSoftwareInterrupt();
- return;
- }
- // This would be correct, but it causes problems if uncommented
- // else {
- // biosProtected = 0xe3a02004;
- // }
-
- switch(comment) {
- case 0x00:
- BIOS_SoftReset();
- ARM_PREFETCH;
- break;
- case 0x01:
- BIOS_RegisterRamReset();
- break;
- case 0x02:
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_SWI) {
- log("Halt: (VCOUNT = %2d)\n",
- VCOUNT);
- }
-#endif
- holdState = true;
- holdType = -1;
- cpuNextEvent = cpuTotalTicks;
- break;
- case 0x03:
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_SWI) {
- log("Stop: (VCOUNT = %2d)\n",
- VCOUNT);
- }
-#endif
- holdState = true;
- holdType = -1;
- stopState = true;
- cpuNextEvent = cpuTotalTicks;
- break;
- case 0x04:
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_SWI) {
- log("IntrWait: 0x%08x,0x%08x (VCOUNT = %2d)\n",
- reg[0].I,
- reg[1].I,
- VCOUNT);
- }
-#endif
- CPUSoftwareInterrupt();
- break;
- case 0x05:
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_SWI) {
- log("VBlankIntrWait: (VCOUNT = %2d)\n",
- VCOUNT);
- }
-#endif
- CPUSoftwareInterrupt();
- break;
- case 0x06:
- CPUSoftwareInterrupt();
- break;
- case 0x07:
- CPUSoftwareInterrupt();
- break;
- case 0x08:
- BIOS_Sqrt();
- break;
- case 0x09:
- BIOS_ArcTan();
- break;
- case 0x0A:
- BIOS_ArcTan2();
- break;
- case 0x0B:
- {
- int len = (reg[2].I & 0x1FFFFF) >>1;
- if (!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + len) & 0xe000000) == 0))
- {
- if ((reg[2].I >> 24) & 1)
- {
- if ((reg[2].I >> 26) & 1)
- SWITicks = (7 + memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1);
- else
- SWITicks = (8 + memoryWait[(reg[1].I>>24) & 0xF]) * (len);
- }
- else
- {
- if ((reg[2].I >> 26) & 1)
- SWITicks = (10 + memoryWait32[(reg[0].I>>24) & 0xF] +
- memoryWait32[(reg[1].I>>24) & 0xF]) * (len>>1);
- else
- SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] +
- memoryWait[(reg[1].I>>24) & 0xF]) * len;
- }
- }
- }
- BIOS_CpuSet();
- break;
- case 0x0C:
- {
- int len = (reg[2].I & 0x1FFFFF) >>5;
- if (!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + len) & 0xe000000) == 0))
- {
- if ((reg[2].I >> 24) & 1)
- SWITicks = (6 + memoryWait32[(reg[1].I>>24) & 0xF] +
- 7 * (memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 1)) * len;
- else
- SWITicks = (9 + memoryWait32[(reg[0].I>>24) & 0xF] +
- memoryWait32[(reg[1].I>>24) & 0xF] +
- 7 * (memoryWaitSeq32[(reg[0].I>>24) & 0xF] +
- memoryWaitSeq32[(reg[1].I>>24) & 0xF] + 2)) * len;
- }
- }
- BIOS_CpuFastSet();
- break;
- case 0x0D:
- BIOS_GetBiosChecksum();
- break;
- case 0x0E:
- BIOS_BgAffineSet();
- break;
- case 0x0F:
- BIOS_ObjAffineSet();
- break;
- case 0x10:
- {
- int len = CPUReadHalfWord(reg[2].I);
- if (!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + len) & 0xe000000) == 0))
- SWITicks = (32 + memoryWait[(reg[0].I>>24) & 0xF]) * len;
- }
- BIOS_BitUnPack();
- break;
- case 0x11:
- {
- u32 len = CPUReadMemory(reg[0].I) >> 8;
- if(!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
- SWITicks = (9 + memoryWait[(reg[1].I>>24) & 0xF]) * len;
- }
- BIOS_LZ77UnCompWram();
- break;
- case 0x12:
- {
- u32 len = CPUReadMemory(reg[0].I) >> 8;
- if(!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
- SWITicks = (19 + memoryWait[(reg[1].I>>24) & 0xF]) * len;
- }
- BIOS_LZ77UnCompVram();
- break;
- case 0x13:
- {
- u32 len = CPUReadMemory(reg[0].I) >> 8;
- if(!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
- SWITicks = (29 + (memoryWait[(reg[0].I>>24) & 0xF]<<1)) * len;
- }
- BIOS_HuffUnComp();
- break;
- case 0x14:
- {
- u32 len = CPUReadMemory(reg[0].I) >> 8;
- if(!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
- SWITicks = (11 + memoryWait[(reg[0].I>>24) & 0xF] +
- memoryWait[(reg[1].I>>24) & 0xF]) * len;
- }
- BIOS_RLUnCompWram();
- break;
- case 0x15:
- {
- u32 len = CPUReadMemory(reg[0].I) >> 9;
- if(!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
- SWITicks = (34 + (memoryWait[(reg[0].I>>24) & 0xF] << 1) +
- memoryWait[(reg[1].I>>24) & 0xF]) * len;
- }
- BIOS_RLUnCompVram();
- break;
- case 0x16:
- {
- u32 len = CPUReadMemory(reg[0].I) >> 8;
- if(!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
- SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] +
- memoryWait[(reg[1].I>>24) & 0xF]) * len;
- }
- BIOS_Diff8bitUnFilterWram();
- break;
- case 0x17:
- {
- u32 len = CPUReadMemory(reg[0].I) >> 9;
- if(!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
- SWITicks = (39 + (memoryWait[(reg[0].I>>24) & 0xF]<<1) +
- memoryWait[(reg[1].I>>24) & 0xF]) * len;
- }
- BIOS_Diff8bitUnFilterVram();
- break;
- case 0x18:
- {
- u32 len = CPUReadMemory(reg[0].I) >> 9;
- if(!(((reg[0].I & 0xe000000) == 0) ||
- ((reg[0].I + (len & 0x1fffff)) & 0xe000000) == 0))
- SWITicks = (13 + memoryWait[(reg[0].I>>24) & 0xF] +
- memoryWait[(reg[1].I>>24) & 0xF]) * len;
- }
- BIOS_Diff16bitUnFilter();
- break;
- case 0x19:
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_SWI) {
- log("SoundBiasSet: 0x%08x (VCOUNT = %2d)\n",
- reg[0].I,
- VCOUNT);
- }
-#endif
- if(reg[0].I)
- systemSoundPause();
- else
- systemSoundResume();
- break;
- case 0x1F:
- BIOS_MidiKey2Freq();
- break;
- case 0x2A:
- BIOS_SndDriverJmpTableCopy();
- // let it go, because we don't really emulate this function
- default:
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_SWI) {
- log("SWI: %08x at %08x (0x%08x,0x%08x,0x%08x,VCOUNT = %2d)\n", comment,
- armState ? armNextPC - 4: armNextPC -2,
- reg[0].I,
- reg[1].I,
- reg[2].I,
- VCOUNT);
- }
-#endif
-
- if(!disableMessage) {
- systemMessage(MSG_UNSUPPORTED_BIOS_FUNCTION,
- N_("Unsupported BIOS function %02x called from %08x. A BIOS file is needed in order to get correct behaviour."),
- comment,
- armMode ? armNextPC - 4: armNextPC - 2);
- disableMessage = true;
- }
- break;
- }
-}
-
-void CPUCompareVCOUNT()
-{
- if(VCOUNT == (DISPSTAT >> 8)) {
- DISPSTAT |= 4;
- UPDATE_REG(0x04, DISPSTAT);
-
- if(DISPSTAT & 0x20) {
- IF |= 4;
- UPDATE_REG(0x202, IF);
- }
- } else {
- DISPSTAT &= 0xFFFB;
- UPDATE_REG(0x4, DISPSTAT);
- }
- if (layerEnableDelay>0)
- {
- layerEnableDelay--;
- if (layerEnableDelay==1)
- layerEnable = layerSettings & DISPCNT;
- }
-
-}
-
-void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
-{
- int sm = s >> 24;
- int dm = d >> 24;
- int sw = 0;
- int dw = 0;
- int sc = c;
-
- cpuDmaCount = c;
- // This is done to get the correct waitstates.
- if (sm>15)
- sm=15;
- if (dm>15)
- dm=15;
-
- //if ((sm>=0x05) && (sm<=0x07) || (dm>=0x05) && (dm <=0x07))
- // blank = (((DISPSTAT | ((DISPSTAT>>1)&1))==1) ? true : false);
-
- if(transfer32) {
- s &= 0xFFFFFFFC;
- if(s < 0x02000000 && (reg[15].I >> 24)) {
- while(c != 0) {
- CPUWriteMemory(d, 0);
- d += di;
- c--;
- }
- } else {
- while(c != 0) {
- cpuDmaLast = CPUReadMemory(s);
- CPUWriteMemory(d, cpuDmaLast);
- d += di;
- s += si;
- c--;
- }
- }
- } else {
- s &= 0xFFFFFFFE;
- si = (int)si >> 1;
- di = (int)di >> 1;
- if(s < 0x02000000 && (reg[15].I >> 24)) {
- while(c != 0) {
- CPUWriteHalfWord(d, 0);
- d += di;
- c--;
- }
- } else {
- while(c != 0) {
- cpuDmaLast = CPUReadHalfWord(s);
- CPUWriteHalfWord(d, cpuDmaLast);
- cpuDmaLast |= (cpuDmaLast<<16);
- d += di;
- s += si;
- c--;
- }
- }
- }
-
- cpuDmaCount = 0;
-
- int totalTicks = 0;
-
- if(transfer32) {
- sw =1+memoryWaitSeq32[sm & 15];
- dw =1+memoryWaitSeq32[dm & 15];
- totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait32[sm & 15] +
- memoryWaitSeq32[dm & 15];
- }
- else
- {
- sw = 1+memoryWaitSeq[sm & 15];
- dw = 1+memoryWaitSeq[dm & 15];
- totalTicks = (sw+dw)*(sc-1) + 6 + memoryWait[sm & 15] +
- memoryWaitSeq[dm & 15];
- }
-
- cpuDmaTicksToUpdate += totalTicks;
-
-}
-
-void CPUCheckDMA(int reason, int dmamask)
-{
- // DMA 0
- if((DM0CNT_H & 0x8000) && (dmamask & 1)) {
- if(((DM0CNT_H >> 12) & 3) == reason) {
- u32 sourceIncrement = 4;
- u32 destIncrement = 4;
- switch((DM0CNT_H >> 7) & 3) {
- case 0:
- break;
- case 1:
- sourceIncrement = (u32)-4;
- break;
- case 2:
- sourceIncrement = 0;
- break;
- }
- switch((DM0CNT_H >> 5) & 3) {
- case 0:
- break;
- case 1:
- destIncrement = (u32)-4;
- break;
- case 2:
- destIncrement = 0;
- break;
- }
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_DMA0) {
- int count = (DM0CNT_L ? DM0CNT_L : 0x4000) << 1;
- if(DM0CNT_H & 0x0400)
- count <<= 1;
- log("DMA0: s=%08x d=%08x c=%04x count=%08x\n", dma0Source, dma0Dest,
- DM0CNT_H,
- count);
- }
-#endif
- doDMA(dma0Source, dma0Dest, sourceIncrement, destIncrement,
- DM0CNT_L ? DM0CNT_L : 0x4000,
- DM0CNT_H & 0x0400);
- cpuDmaHack = true;
-
- if(DM0CNT_H & 0x4000) {
- IF |= 0x0100;
- UPDATE_REG(0x202, IF);
- cpuNextEvent = cpuTotalTicks;
- }
-
- if(((DM0CNT_H >> 5) & 3) == 3) {
- dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
- }
-
- if(!(DM0CNT_H & 0x0200) || (reason == 0)) {
- DM0CNT_H &= 0x7FFF;
- UPDATE_REG(0xBA, DM0CNT_H);
- }
- }
- }
-
- // DMA 1
- if((DM1CNT_H & 0x8000) && (dmamask & 2)) {
- if(((DM1CNT_H >> 12) & 3) == reason) {
- u32 sourceIncrement = 4;
- u32 destIncrement = 4;
- switch((DM1CNT_H >> 7) & 3) {
- case 0:
- break;
- case 1:
- sourceIncrement = (u32)-4;
- break;
- case 2:
- sourceIncrement = 0;
- break;
- }
- switch((DM1CNT_H >> 5) & 3) {
- case 0:
- break;
- case 1:
- destIncrement = (u32)-4;
- break;
- case 2:
- destIncrement = 0;
- break;
- }
- if(reason == 3) {
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_DMA1) {
- log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest,
- DM1CNT_H,
- 16);
- }
-#endif
- doDMA(dma1Source, dma1Dest, sourceIncrement, 0, 4,
- 0x0400);
- } else {
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_DMA1) {
- int count = (DM1CNT_L ? DM1CNT_L : 0x4000) << 1;
- if(DM1CNT_H & 0x0400)
- count <<= 1;
- log("DMA1: s=%08x d=%08x c=%04x count=%08x\n", dma1Source, dma1Dest,
- DM1CNT_H,
- count);
- }
-#endif
- doDMA(dma1Source, dma1Dest, sourceIncrement, destIncrement,
- DM1CNT_L ? DM1CNT_L : 0x4000,
- DM1CNT_H & 0x0400);
- }
- cpuDmaHack = true;
-
- if(DM1CNT_H & 0x4000) {
- IF |= 0x0200;
- UPDATE_REG(0x202, IF);
- cpuNextEvent = cpuTotalTicks;
- }
-
- if(((DM1CNT_H >> 5) & 3) == 3) {
- dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
- }
-
- if(!(DM1CNT_H & 0x0200) || (reason == 0)) {
- DM1CNT_H &= 0x7FFF;
- UPDATE_REG(0xC6, DM1CNT_H);
- }
- }
- }
-
- // DMA 2
- if((DM2CNT_H & 0x8000) && (dmamask & 4)) {
- if(((DM2CNT_H >> 12) & 3) == reason) {
- u32 sourceIncrement = 4;
- u32 destIncrement = 4;
- switch((DM2CNT_H >> 7) & 3) {
- case 0:
- break;
- case 1:
- sourceIncrement = (u32)-4;
- break;
- case 2:
- sourceIncrement = 0;
- break;
- }
- switch((DM2CNT_H >> 5) & 3) {
- case 0:
- break;
- case 1:
- destIncrement = (u32)-4;
- break;
- case 2:
- destIncrement = 0;
- break;
- }
- if(reason == 3) {
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_DMA2) {
- int count = (4) << 2;
- log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest,
- DM2CNT_H,
- count);
- }
-#endif
- doDMA(dma2Source, dma2Dest, sourceIncrement, 0, 4,
- 0x0400);
- } else {
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_DMA2) {
- int count = (DM2CNT_L ? DM2CNT_L : 0x4000) << 1;
- if(DM2CNT_H & 0x0400)
- count <<= 1;
- log("DMA2: s=%08x d=%08x c=%04x count=%08x\n", dma2Source, dma2Dest,
- DM2CNT_H,
- count);
- }
-#endif
- doDMA(dma2Source, dma2Dest, sourceIncrement, destIncrement,
- DM2CNT_L ? DM2CNT_L : 0x4000,
- DM2CNT_H & 0x0400);
- }
- cpuDmaHack = true;
-
- if(DM2CNT_H & 0x4000) {
- IF |= 0x0400;
- UPDATE_REG(0x202, IF);
- cpuNextEvent = cpuTotalTicks;
- }
-
- if(((DM2CNT_H >> 5) & 3) == 3) {
- dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
- }
-
- if(!(DM2CNT_H & 0x0200) || (reason == 0)) {
- DM2CNT_H &= 0x7FFF;
- UPDATE_REG(0xD2, DM2CNT_H);
- }
- }
- }
-
- // DMA 3
- if((DM3CNT_H & 0x8000) && (dmamask & 8)) {
- if(((DM3CNT_H >> 12) & 3) == reason) {
- u32 sourceIncrement = 4;
- u32 destIncrement = 4;
- switch((DM3CNT_H >> 7) & 3) {
- case 0:
- break;
- case 1:
- sourceIncrement = (u32)-4;
- break;
- case 2:
- sourceIncrement = 0;
- break;
- }
- switch((DM3CNT_H >> 5) & 3) {
- case 0:
- break;
- case 1:
- destIncrement = (u32)-4;
- break;
- case 2:
- destIncrement = 0;
- break;
- }
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_DMA3) {
- int count = (DM3CNT_L ? DM3CNT_L : 0x10000) << 1;
- if(DM3CNT_H & 0x0400)
- count <<= 1;
- log("DMA3: s=%08x d=%08x c=%04x count=%08x\n", dma3Source, dma3Dest,
- DM3CNT_H,
- count);
- }
-#endif
- doDMA(dma3Source, dma3Dest, sourceIncrement, destIncrement,
- DM3CNT_L ? DM3CNT_L : 0x10000,
- DM3CNT_H & 0x0400);
- if(DM3CNT_H & 0x4000) {
- IF |= 0x0800;
- UPDATE_REG(0x202, IF);
- cpuNextEvent = cpuTotalTicks;
- }
-
- if(((DM3CNT_H >> 5) & 3) == 3) {
- dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
- }
-
- if(!(DM3CNT_H & 0x0200) || (reason == 0)) {
- DM3CNT_H &= 0x7FFF;
- UPDATE_REG(0xDE, DM3CNT_H);
- }
- }
- }
-}
-
-void CPUUpdateRegister(u32 address, u16 value)
-{
- switch(address) {
- case 0x00:
- {
- if ((value & 7) >5)
- DISPCNT = (value &7);
- bool change = ((DISPCNT ^ value) & 0x80) ? true : false;
- bool changeBG = ((DISPCNT ^ value) & 0x0F00) ? true : false;
- u16 changeBGon = (((~DISPCNT) & value) & 0x0F00);
- DISPCNT = (value & 0xFFF7);
- UPDATE_REG(0x00, DISPCNT);
-
- if (changeBGon)
- {
- layerEnableDelay=4;
- layerEnable = layerSettings & value & (~changeBGon);
- }
- else
- layerEnable = layerSettings & value;
- // CPUUpdateTicks();
-
- windowOn = (layerEnable & 0x6000) ? true : false;
- if(change && !((value & 0x80))) {
- if(!(DISPSTAT & 1)) {
- lcdTicks = 1008;
- // VCOUNT = 0;
- // UPDATE_REG(0x06, VCOUNT);
- DISPSTAT &= 0xFFFC;
- UPDATE_REG(0x04, DISPSTAT);
- CPUCompareVCOUNT();
- }
- // (*renderLine)();
- }
- CPUUpdateRender();
- // we only care about changes in BG0-BG3
- if(changeBG)
- CPUUpdateRenderBuffers(false);
- }
- break;
- case 0x04:
- DISPSTAT = (value & 0xFF38) | (DISPSTAT & 7);
- UPDATE_REG(0x04, DISPSTAT);
- break;
- case 0x06:
- // not writable
- break;
- case 0x08:
- BG0CNT = (value & 0xDFCF);
- UPDATE_REG(0x08, BG0CNT);
- break;
- case 0x0A:
- BG1CNT = (value & 0xDFCF);
- UPDATE_REG(0x0A, BG1CNT);
- break;
- case 0x0C:
- BG2CNT = (value & 0xFFCF);
- UPDATE_REG(0x0C, BG2CNT);
- break;
- case 0x0E:
- BG3CNT = (value & 0xFFCF);
- UPDATE_REG(0x0E, BG3CNT);
- break;
- case 0x10:
- BG0HOFS = value & 511;
- UPDATE_REG(0x10, BG0HOFS);
- break;
- case 0x12:
- BG0VOFS = value & 511;
- UPDATE_REG(0x12, BG0VOFS);
- break;
- case 0x14:
- BG1HOFS = value & 511;
- UPDATE_REG(0x14, BG1HOFS);
- break;
- case 0x16:
- BG1VOFS = value & 511;
- UPDATE_REG(0x16, BG1VOFS);
- break;
- case 0x18:
- BG2HOFS = value & 511;
- UPDATE_REG(0x18, BG2HOFS);
- break;
- case 0x1A:
- BG2VOFS = value & 511;
- UPDATE_REG(0x1A, BG2VOFS);
- break;
- case 0x1C:
- BG3HOFS = value & 511;
- UPDATE_REG(0x1C, BG3HOFS);
- break;
- case 0x1E:
- BG3VOFS = value & 511;
- UPDATE_REG(0x1E, BG3VOFS);
- break;
- case 0x20:
- BG2PA = value;
- UPDATE_REG(0x20, BG2PA);
- break;
- case 0x22:
- BG2PB = value;
- UPDATE_REG(0x22, BG2PB);
- break;
- case 0x24:
- BG2PC = value;
- UPDATE_REG(0x24, BG2PC);
- break;
- case 0x26:
- BG2PD = value;
- UPDATE_REG(0x26, BG2PD);
- break;
- case 0x28:
- BG2X_L = value;
- UPDATE_REG(0x28, BG2X_L);
- gfxBG2Changed |= 1;
- break;
- case 0x2A:
- BG2X_H = (value & 0xFFF);
- UPDATE_REG(0x2A, BG2X_H);
- gfxBG2Changed |= 1;
- break;
- case 0x2C:
- BG2Y_L = value;
- UPDATE_REG(0x2C, BG2Y_L);
- gfxBG2Changed |= 2;
- break;
- case 0x2E:
- BG2Y_H = value & 0xFFF;
- UPDATE_REG(0x2E, BG2Y_H);
- gfxBG2Changed |= 2;
- break;
- case 0x30:
- BG3PA = value;
- UPDATE_REG(0x30, BG3PA);
- break;
- case 0x32:
- BG3PB = value;
- UPDATE_REG(0x32, BG3PB);
- break;
- case 0x34:
- BG3PC = value;
- UPDATE_REG(0x34, BG3PC);
- break;
- case 0x36:
- BG3PD = value;
- UPDATE_REG(0x36, BG3PD);
- break;
- case 0x38:
- BG3X_L = value;
- UPDATE_REG(0x38, BG3X_L);
- gfxBG3Changed |= 1;
- break;
- case 0x3A:
- BG3X_H = value & 0xFFF;
- UPDATE_REG(0x3A, BG3X_H);
- gfxBG3Changed |= 1;
- break;
- case 0x3C:
- BG3Y_L = value;
- UPDATE_REG(0x3C, BG3Y_L);
- gfxBG3Changed |= 2;
- break;
- case 0x3E:
- BG3Y_H = value & 0xFFF;
- UPDATE_REG(0x3E, BG3Y_H);
- gfxBG3Changed |= 2;
- break;
- case 0x40:
- WIN0H = value;
- UPDATE_REG(0x40, WIN0H);
- CPUUpdateWindow0();
- break;
- case 0x42:
- WIN1H = value;
- UPDATE_REG(0x42, WIN1H);
- CPUUpdateWindow1();
- break;
- case 0x44:
- WIN0V = value;
- UPDATE_REG(0x44, WIN0V);
- break;
- case 0x46:
- WIN1V = value;
- UPDATE_REG(0x46, WIN1V);
- break;
- case 0x48:
- WININ = value & 0x3F3F;
- UPDATE_REG(0x48, WININ);
- break;
- case 0x4A:
- WINOUT = value & 0x3F3F;
- UPDATE_REG(0x4A, WINOUT);
- break;
- case 0x4C:
- MOSAIC = value;
- UPDATE_REG(0x4C, MOSAIC);
- break;
- case 0x50:
- BLDMOD = value & 0x3FFF;
- UPDATE_REG(0x50, BLDMOD);
- fxOn = ((BLDMOD>>6)&3) != 0;
- CPUUpdateRender();
- break;
- case 0x52:
- COLEV = value & 0x1F1F;
- UPDATE_REG(0x52, COLEV);
- break;
- case 0x54:
- COLY = value & 0x1F;
- UPDATE_REG(0x54, COLY);
- break;
- case 0x60:
- case 0x62:
- case 0x64:
- case 0x68:
- case 0x6c:
- case 0x70:
- case 0x72:
- case 0x74:
- case 0x78:
- case 0x7c:
- case 0x80:
- case 0x84:
- soundEvent(address&0xFF, (u8)(value & 0xFF));
- soundEvent((address&0xFF)+1, (u8)(value>>8));
- break;
- case 0x82:
- case 0x88:
- case 0xa0:
- case 0xa2:
- case 0xa4:
- case 0xa6:
- case 0x90:
- case 0x92:
- case 0x94:
- case 0x96:
- case 0x98:
- case 0x9a:
- case 0x9c:
- case 0x9e:
- soundEvent(address&0xFF, value);
- break;
- case 0xB0:
- DM0SAD_L = value;
- UPDATE_REG(0xB0, DM0SAD_L);
- break;
- case 0xB2:
- DM0SAD_H = value & 0x07FF;
- UPDATE_REG(0xB2, DM0SAD_H);
- break;
- case 0xB4:
- DM0DAD_L = value;
- UPDATE_REG(0xB4, DM0DAD_L);
- break;
- case 0xB6:
- DM0DAD_H = value & 0x07FF;
- UPDATE_REG(0xB6, DM0DAD_H);
- break;
- case 0xB8:
- DM0CNT_L = value & 0x3FFF;
- UPDATE_REG(0xB8, 0);
- break;
- case 0xBA:
- {
- bool start = ((DM0CNT_H ^ value) & 0x8000) ? true : false;
- value &= 0xF7E0;
-
- DM0CNT_H = value;
- UPDATE_REG(0xBA, DM0CNT_H);
-
- if(start && (value & 0x8000)) {
- dma0Source = DM0SAD_L | (DM0SAD_H << 16);
- dma0Dest = DM0DAD_L | (DM0DAD_H << 16);
- CPUCheckDMA(0, 1);
- }
- }
- break;
- case 0xBC:
- DM1SAD_L = value;
- UPDATE_REG(0xBC, DM1SAD_L);
- break;
- case 0xBE:
- DM1SAD_H = value & 0x0FFF;
- UPDATE_REG(0xBE, DM1SAD_H);
- break;
- case 0xC0:
- DM1DAD_L = value;
- UPDATE_REG(0xC0, DM1DAD_L);
- break;
- case 0xC2:
- DM1DAD_H = value & 0x07FF;
- UPDATE_REG(0xC2, DM1DAD_H);
- break;
- case 0xC4:
- DM1CNT_L = value & 0x3FFF;
- UPDATE_REG(0xC4, 0);
- break;
- case 0xC6:
- {
- bool start = ((DM1CNT_H ^ value) & 0x8000) ? true : false;
- value &= 0xF7E0;
-
- DM1CNT_H = value;
- UPDATE_REG(0xC6, DM1CNT_H);
-
- if(start && (value & 0x8000)) {
- dma1Source = DM1SAD_L | (DM1SAD_H << 16);
- dma1Dest = DM1DAD_L | (DM1DAD_H << 16);
- CPUCheckDMA(0, 2);
- }
- }
- break;
- case 0xC8:
- DM2SAD_L = value;
- UPDATE_REG(0xC8, DM2SAD_L);
- break;
- case 0xCA:
- DM2SAD_H = value & 0x0FFF;
- UPDATE_REG(0xCA, DM2SAD_H);
- break;
- case 0xCC:
- DM2DAD_L = value;
- UPDATE_REG(0xCC, DM2DAD_L);
- break;
- case 0xCE:
- DM2DAD_H = value & 0x07FF;
- UPDATE_REG(0xCE, DM2DAD_H);
- break;
- case 0xD0:
- DM2CNT_L = value & 0x3FFF;
- UPDATE_REG(0xD0, 0);
- break;
- case 0xD2:
- {
- bool start = ((DM2CNT_H ^ value) & 0x8000) ? true : false;
-
- value &= 0xF7E0;
-
- DM2CNT_H = value;
- UPDATE_REG(0xD2, DM2CNT_H);
-
- if(start && (value & 0x8000)) {
- dma2Source = DM2SAD_L | (DM2SAD_H << 16);
- dma2Dest = DM2DAD_L | (DM2DAD_H << 16);
-
- CPUCheckDMA(0, 4);
- }
- }
- break;
- case 0xD4:
- DM3SAD_L = value;
- UPDATE_REG(0xD4, DM3SAD_L);
- break;
- case 0xD6:
- DM3SAD_H = value & 0x0FFF;
- UPDATE_REG(0xD6, DM3SAD_H);
- break;
- case 0xD8:
- DM3DAD_L = value;
- UPDATE_REG(0xD8, DM3DAD_L);
- break;
- case 0xDA:
- DM3DAD_H = value & 0x0FFF;
- UPDATE_REG(0xDA, DM3DAD_H);
- break;
- case 0xDC:
- DM3CNT_L = value;
- UPDATE_REG(0xDC, 0);
- break;
- case 0xDE:
- {
- bool start = ((DM3CNT_H ^ value) & 0x8000) ? true : false;
-
- value &= 0xFFE0;
-
- DM3CNT_H = value;
- UPDATE_REG(0xDE, DM3CNT_H);
-
- if(start && (value & 0x8000)) {
- dma3Source = DM3SAD_L | (DM3SAD_H << 16);
- dma3Dest = DM3DAD_L | (DM3DAD_H << 16);
- CPUCheckDMA(0,8);
- }
- }
- break;
- case 0x100:
- timer0Reload = value;
- interp_rate();
- break;
- case 0x102:
- timer0Value = value;
- timerOnOffDelay|=1;
- cpuNextEvent = cpuTotalTicks;
- break;
- case 0x104:
- timer1Reload = value;
- interp_rate();
- break;
- case 0x106:
- timer1Value = value;
- timerOnOffDelay|=2;
- cpuNextEvent = cpuTotalTicks;
- break;
- case 0x108:
- timer2Reload = value;
- break;
- case 0x10A:
- timer2Value = value;
- timerOnOffDelay|=4;
- cpuNextEvent = cpuTotalTicks;
- break;
- case 0x10C:
- timer3Reload = value;
- break;
- case 0x10E:
- timer3Value = value;
- timerOnOffDelay|=8;
- cpuNextEvent = cpuTotalTicks;
- break;
- case 0x128:
- #ifdef LINK_EMULATION
- if (linkenable)
- {
- StartLink(value);
- }
- else
-#endif
- {
- if(value & 0x80) {
- value &= 0xff7f;
- if(value & 1 && (value & 0x4000)) {
- UPDATE_REG(0x12a, 0xFF);
- IF |= 0x80;
- UPDATE_REG(0x202, IF);
- value &= 0x7f7f;
- }
- }
- UPDATE_REG(0x128, value);
- }
- break;
- case 0x12a:
- #ifdef LINK_EMULATION
- if(linkenable && lspeed)
- LinkSSend(value);
- #endif
- {
- UPDATE_REG(0x134, value);
- }
- break;
- case 0x130:
- P1 |= (value & 0x3FF);
- UPDATE_REG(0x130, P1);
- break;
- case 0x132:
- UPDATE_REG(0x132, value & 0xC3FF);
- break;
- case 0x134:
-#ifdef LINK_EMULATION
- if (linkenable)
- StartGPLink(value);
- else
-#endif
- UPDATE_REG(0x134, value);
-
- break;
- case 0x140:
-#ifdef LINK_EMULATION
- if (linkenable)
- StartJOYLink(value);
- else
-#endif
- UPDATE_REG(0x140, value);
-
- break;
- case 0x200:
- IE = value & 0x3FFF;
- UPDATE_REG(0x200, IE);
- if ((IME & 1) && (IF & IE) && armIrqEnable)
- cpuNextEvent = cpuTotalTicks;
- break;
- case 0x202:
- IF ^= (value & IF);
- UPDATE_REG(0x202, IF);
- break;
- case 0x204:
- {
- memoryWait[0x0e] = memoryWaitSeq[0x0e] = gamepakRamWaitState[value & 3];
-
- if(!speedHack) {
- memoryWait[0x08] = memoryWait[0x09] = gamepakWaitState[(value >> 2) & 3];
- memoryWaitSeq[0x08] = memoryWaitSeq[0x09] =
- gamepakWaitState0[(value >> 4) & 1];
-
- memoryWait[0x0a] = memoryWait[0x0b] = gamepakWaitState[(value >> 5) & 3];
- memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] =
- gamepakWaitState1[(value >> 7) & 1];
-
- memoryWait[0x0c] = memoryWait[0x0d] = gamepakWaitState[(value >> 8) & 3];
- memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] =
- gamepakWaitState2[(value >> 10) & 1];
- } else {
- memoryWait[0x08] = memoryWait[0x09] = 3;
- memoryWaitSeq[0x08] = memoryWaitSeq[0x09] = 1;
-
- memoryWait[0x0a] = memoryWait[0x0b] = 3;
- memoryWaitSeq[0x0a] = memoryWaitSeq[0x0b] = 1;
-
- memoryWait[0x0c] = memoryWait[0x0d] = 3;
- memoryWaitSeq[0x0c] = memoryWaitSeq[0x0d] = 1;
- }
-
- for(int i = 8; i < 15; i++) {
- memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1;
- memoryWaitSeq32[i] = memoryWaitSeq[i]*2 + 1;
- }
-
- if((value & 0x4000) == 0x4000) {
- busPrefetchEnable = true;
- busPrefetch = false;
- busPrefetchCount = 0;
- } else {
- busPrefetchEnable = false;
- busPrefetch = false;
- busPrefetchCount = 0;
- }
- UPDATE_REG(0x204, value & 0x7FFF);
-
- }
- break;
- case 0x208:
- IME = value & 1;
- UPDATE_REG(0x208, IME);
- if ((IME & 1) && (IF & IE) && armIrqEnable)
- cpuNextEvent = cpuTotalTicks;
- break;
- case 0x300:
- if(value != 0)
- value &= 0xFFFE;
- UPDATE_REG(0x300, value);
- break;
- default:
- UPDATE_REG(address&0x3FE, value);
- break;
- }
-}
-
-void applyTimer ()
-{
- if (timerOnOffDelay & 1)
- {
- timer0ClockReload = TIMER_TICKS[timer0Value & 3];
- if(!timer0On && (timer0Value & 0x80)) {
- // reload the counter
- TM0D = timer0Reload;
- timer0Ticks = (0x10000 - TM0D) << timer0ClockReload;
- UPDATE_REG(0x100, TM0D);
- }
- timer0On = timer0Value & 0x80 ? true : false;
- TM0CNT = timer0Value & 0xC7;
- interp_rate();
- UPDATE_REG(0x102, TM0CNT);
- // CPUUpdateTicks();
- }
- if (timerOnOffDelay & 2)
- {
- timer1ClockReload = TIMER_TICKS[timer1Value & 3];
- if(!timer1On && (timer1Value & 0x80)) {
- // reload the counter
- TM1D = timer1Reload;
- timer1Ticks = (0x10000 - TM1D) << timer1ClockReload;
- UPDATE_REG(0x104, TM1D);
- }
- timer1On = timer1Value & 0x80 ? true : false;
- TM1CNT = timer1Value & 0xC7;
- interp_rate();
- UPDATE_REG(0x106, TM1CNT);
- }
- if (timerOnOffDelay & 4)
- {
- timer2ClockReload = TIMER_TICKS[timer2Value & 3];
- if(!timer2On && (timer2Value & 0x80)) {
- // reload the counter
- TM2D = timer2Reload;
- timer2Ticks = (0x10000 - TM2D) << timer2ClockReload;
- UPDATE_REG(0x108, TM2D);
- }
- timer2On = timer2Value & 0x80 ? true : false;
- TM2CNT = timer2Value & 0xC7;
- UPDATE_REG(0x10A, TM2CNT);
- }
- if (timerOnOffDelay & 8)
- {
- timer3ClockReload = TIMER_TICKS[timer3Value & 3];
- if(!timer3On && (timer3Value & 0x80)) {
- // reload the counter
- TM3D = timer3Reload;
- timer3Ticks = (0x10000 - TM3D) << timer3ClockReload;
- UPDATE_REG(0x10C, TM3D);
- }
- timer3On = timer3Value & 0x80 ? true : false;
- TM3CNT = timer3Value & 0xC7;
- UPDATE_REG(0x10E, TM3CNT);
- }
- cpuNextEvent = CPUUpdateTicks();
- timerOnOffDelay = 0;
-}
-
-u8 cpuBitsSet[256];
-u8 cpuLowestBitSet[256];
-
-void CPUInit(const char *biosFileName, bool useBiosFile)
-{
-#ifdef WORDS_BIGENDIAN
- if(!cpuBiosSwapped) {
- for(unsigned int i = 0; i < sizeof(myROM)/4; i++) {
- WRITE32LE(&myROM[i], myROM[i]);
- }
- cpuBiosSwapped = true;
- }
-#endif
- gbaSaveType = 0;
- eepromInUse = 0;
- saveType = 0;
- useBios = false;
-
- if(useBiosFile) {
- int size = 0x4000;
- if(utilLoad(biosFileName,
- CPUIsGBABios,
- bios,
- size)) {
- if(size == 0x4000)
- useBios = true;
- else
- systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BIOS file size"));
- }
- }
-
- if(!useBios) {
- memcpy(bios, myROM, sizeof(myROM));
- }
-
- int i = 0;
-
- biosProtected[0] = 0x00;
- biosProtected[1] = 0xf0;
- biosProtected[2] = 0x29;
- biosProtected[3] = 0xe1;
-
- for(i = 0; i < 256; i++) {
- int count = 0;
- int j;
- for(j = 0; j < 8; j++)
- if(i & (1 << j))
- count++;
- cpuBitsSet[i] = count;
-
- for(j = 0; j < 8; j++)
- if(i & (1 << j))
- break;
- cpuLowestBitSet[i] = j;
- }
-
- for(i = 0; i < 0x400; i++)
- ioReadable[i] = true;
- for(i = 0x10; i < 0x48; i++)
- ioReadable[i] = false;
- for(i = 0x4c; i < 0x50; i++)
- ioReadable[i] = false;
- for(i = 0x54; i < 0x60; i++)
- ioReadable[i] = false;
- for(i = 0x8c; i < 0x90; i++)
- ioReadable[i] = false;
- for(i = 0xa0; i < 0xb8; i++)
- ioReadable[i] = false;
- for(i = 0xbc; i < 0xc4; i++)
- ioReadable[i] = false;
- for(i = 0xc8; i < 0xd0; i++)
- ioReadable[i] = false;
- for(i = 0xd4; i < 0xdc; i++)
- ioReadable[i] = false;
- for(i = 0xe0; i < 0x100; i++)
- ioReadable[i] = false;
- for(i = 0x110; i < 0x120; i++)
- ioReadable[i] = false;
- for(i = 0x12c; i < 0x130; i++)
- ioReadable[i] = false;
- for(i = 0x138; i < 0x140; i++)
- ioReadable[i] = false;
- for(i = 0x144; i < 0x150; i++)
- ioReadable[i] = false;
- for(i = 0x15c; i < 0x200; i++)
- ioReadable[i] = false;
- for(i = 0x20c; i < 0x300; i++)
- ioReadable[i] = false;
- for(i = 0x304; i < 0x400; i++)
- ioReadable[i] = false;
-
- if(romSize < 0x1fe2000) {
- *((u16 *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA
- *((u16 *)&rom[0x1fe209e]) = 0x4770; // BX LR
- } else {
- agbPrintEnable(false);
- }
-}
-
-void CPUReset()
-{
- if(gbaSaveType == 0) {
- if(eepromInUse)
- gbaSaveType = 3;
- else
- switch(saveType) {
- case 1:
- gbaSaveType = 1;
- break;
- case 2:
- gbaSaveType = 2;
- break;
- }
- }
- rtcReset();
- // clean registers
- memset(®[0], 0, sizeof(reg));
- // clean OAM
- memset(oam, 0, 0x400);
- // clean palette
- memset(paletteRAM, 0, 0x400);
- // clean picture
- memset(pix, 0, 4*160*240);
- // clean vram
- memset(vram, 0, 0x20000);
- // clean io memory
- memset(ioMem, 0, 0x400);
-
- DISPCNT = 0x0080;
- DISPSTAT = 0x0000;
- VCOUNT = (useBios && !skipBios) ? 0 :0x007E;
- BG0CNT = 0x0000;
- BG1CNT = 0x0000;
- BG2CNT = 0x0000;
- BG3CNT = 0x0000;
- BG0HOFS = 0x0000;
- BG0VOFS = 0x0000;
- BG1HOFS = 0x0000;
- BG1VOFS = 0x0000;
- BG2HOFS = 0x0000;
- BG2VOFS = 0x0000;
- BG3HOFS = 0x0000;
- BG3VOFS = 0x0000;
- BG2PA = 0x0100;
- BG2PB = 0x0000;
- BG2PC = 0x0000;
- BG2PD = 0x0100;
- BG2X_L = 0x0000;
- BG2X_H = 0x0000;
- BG2Y_L = 0x0000;
- BG2Y_H = 0x0000;
- BG3PA = 0x0100;
- BG3PB = 0x0000;
- BG3PC = 0x0000;
- BG3PD = 0x0100;
- BG3X_L = 0x0000;
- BG3X_H = 0x0000;
- BG3Y_L = 0x0000;
- BG3Y_H = 0x0000;
- WIN0H = 0x0000;
- WIN1H = 0x0000;
- WIN0V = 0x0000;
- WIN1V = 0x0000;
- WININ = 0x0000;
- WINOUT = 0x0000;
- MOSAIC = 0x0000;
- BLDMOD = 0x0000;
- COLEV = 0x0000;
- COLY = 0x0000;
- DM0SAD_L = 0x0000;
- DM0SAD_H = 0x0000;
- DM0DAD_L = 0x0000;
- DM0DAD_H = 0x0000;
- DM0CNT_L = 0x0000;
- DM0CNT_H = 0x0000;
- DM1SAD_L = 0x0000;
- DM1SAD_H = 0x0000;
- DM1DAD_L = 0x0000;
- DM1DAD_H = 0x0000;
- DM1CNT_L = 0x0000;
- DM1CNT_H = 0x0000;
- DM2SAD_L = 0x0000;
- DM2SAD_H = 0x0000;
- DM2DAD_L = 0x0000;
- DM2DAD_H = 0x0000;
- DM2CNT_L = 0x0000;
- DM2CNT_H = 0x0000;
- DM3SAD_L = 0x0000;
- DM3SAD_H = 0x0000;
- DM3DAD_L = 0x0000;
- DM3DAD_H = 0x0000;
- DM3CNT_L = 0x0000;
- DM3CNT_H = 0x0000;
- TM0D = 0x0000;
- TM0CNT = 0x0000;
- TM1D = 0x0000;
- TM1CNT = 0x0000;
- TM2D = 0x0000;
- TM2CNT = 0x0000;
- TM3D = 0x0000;
- TM3CNT = 0x0000;
- P1 = 0x03FF;
- IE = 0x0000;
- IF = 0x0000;
- IME = 0x0000;
-
- armMode = 0x1F;
-
- if(cpuIsMultiBoot) {
- reg[13].I = 0x03007F00;
- reg[15].I = 0x02000000;
- reg[16].I = 0x00000000;
- reg[R13_IRQ].I = 0x03007FA0;
- reg[R13_SVC].I = 0x03007FE0;
- armIrqEnable = true;
- } else {
- if(useBios && !skipBios) {
- reg[15].I = 0x00000000;
- armMode = 0x13;
- armIrqEnable = false;
- } else {
- reg[13].I = 0x03007F00;
- reg[15].I = 0x08000000;
- reg[16].I = 0x00000000;
- reg[R13_IRQ].I = 0x03007FA0;
- reg[R13_SVC].I = 0x03007FE0;
- armIrqEnable = true;
- }
- }
- armState = true;
- C_FLAG = V_FLAG = N_FLAG = Z_FLAG = false;
- UPDATE_REG(0x00, DISPCNT);
- UPDATE_REG(0x06, VCOUNT);
- UPDATE_REG(0x20, BG2PA);
- UPDATE_REG(0x26, BG2PD);
- UPDATE_REG(0x30, BG3PA);
- UPDATE_REG(0x36, BG3PD);
- UPDATE_REG(0x130, P1);
- UPDATE_REG(0x88, 0x200);
-
- // disable FIQ
- reg[16].I |= 0x40;
-
- CPUUpdateCPSR();
-
- armNextPC = reg[15].I;
- reg[15].I += 4;
-
- // reset internal state
- holdState = false;
- holdType = 0;
-
- biosProtected[0] = 0x00;
- biosProtected[1] = 0xf0;
- biosProtected[2] = 0x29;
- biosProtected[3] = 0xe1;
-
- lcdTicks = (useBios && !skipBios) ? 1008 : 208;
- timer0On = false;
- timer0Ticks = 0;
- timer0Reload = 0;
- timer0ClockReload = 0;
- timer1On = false;
- timer1Ticks = 0;
- timer1Reload = 0;
- timer1ClockReload = 0;
- timer2On = false;
- timer2Ticks = 0;
- timer2Reload = 0;
- timer2ClockReload = 0;
- timer3On = false;
- timer3Ticks = 0;
- timer3Reload = 0;
- timer3ClockReload = 0;
- dma0Source = 0;
- dma0Dest = 0;
- dma1Source = 0;
- dma1Dest = 0;
- dma2Source = 0;
- dma2Dest = 0;
- dma3Source = 0;
- dma3Dest = 0;
- cpuSaveGameFunc = flashSaveDecide;
- renderLine = mode0RenderLine;
- fxOn = false;
- windowOn = false;
- frameCount = 0;
- saveType = 0;
- layerEnable = DISPCNT & layerSettings;
-
- CPUUpdateRenderBuffers(true);
-
- for(int i = 0; i < 256; i++) {
- map[i].address = (u8 *)&dummyAddress;
- map[i].mask = 0;
- }
-
- map[0].address = bios;
- map[0].mask = 0x3FFF;
- map[2].address = workRAM;
- map[2].mask = 0x3FFFF;
- map[3].address = internalRAM;
- map[3].mask = 0x7FFF;
- map[4].address = ioMem;
- map[4].mask = 0x3FF;
- map[5].address = paletteRAM;
- map[5].mask = 0x3FF;
- map[6].address = vram;
- map[6].mask = 0x1FFFF;
- map[7].address = oam;
- map[7].mask = 0x3FF;
- map[8].address = rom;
- map[8].mask = 0x1FFFFFF;
- map[9].address = rom;
- map[9].mask = 0x1FFFFFF;
- map[10].address = rom;
- map[10].mask = 0x1FFFFFF;
- map[12].address = rom;
- map[12].mask = 0x1FFFFFF;
- map[14].address = flashSaveMemory;
- map[14].mask = 0xFFFF;
-
- eepromReset();
- flashReset();
-
- soundReset();
-
- CPUUpdateWindow0();
- CPUUpdateWindow1();
-
- // make sure registers are correctly initialized if not using BIOS
- if(!useBios) {
- if(cpuIsMultiBoot)
- BIOS_RegisterRamReset(0xfe);
- else
- BIOS_RegisterRamReset(0xff);
- } else {
- if(cpuIsMultiBoot)
- BIOS_RegisterRamReset(0xfe);
- }
-
- switch(cpuSaveType) {
- case 0: // automatic
- cpuSramEnabled = true;
- cpuFlashEnabled = true;
- cpuEEPROMEnabled = true;
- cpuEEPROMSensorEnabled = false;
- saveType = gbaSaveType = 0;
- break;
- case 1: // EEPROM
- cpuSramEnabled = false;
- cpuFlashEnabled = false;
- cpuEEPROMEnabled = true;
- cpuEEPROMSensorEnabled = false;
- saveType = gbaSaveType = 3;
- // EEPROM usage is automatically detected
- break;
- case 2: // SRAM
- cpuSramEnabled = true;
- cpuFlashEnabled = false;
- cpuEEPROMEnabled = false;
- cpuEEPROMSensorEnabled = false;
- cpuSaveGameFunc = sramDelayedWrite; // to insure we detect the write
- saveType = gbaSaveType = 1;
- break;
- case 3: // FLASH
- cpuSramEnabled = false;
- cpuFlashEnabled = true;
- cpuEEPROMEnabled = false;
- cpuEEPROMSensorEnabled = false;
- cpuSaveGameFunc = flashDelayedWrite; // to insure we detect the write
- saveType = gbaSaveType = 2;
- break;
- case 4: // EEPROM+Sensor
- cpuSramEnabled = false;
- cpuFlashEnabled = false;
- cpuEEPROMEnabled = true;
- cpuEEPROMSensorEnabled = true;
- // EEPROM usage is automatically detected
- saveType = gbaSaveType = 3;
- break;
- case 5: // NONE
- cpuSramEnabled = false;
- cpuFlashEnabled = false;
- cpuEEPROMEnabled = false;
- cpuEEPROMSensorEnabled = false;
- // no save at all
- saveType = gbaSaveType = 5;
- break;
- }
-
- ARM_PREFETCH;
-
- systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
-
- cpuDmaHack = false;
-
- lastTime = systemGetClock();
-
- SWITicks = 0;
-}
-
-void CPUInterrupt()
-{
- u32 PC = reg[15].I;
- bool savedState = armState;
- CPUSwitchMode(0x12, true, false);
- reg[14].I = PC;
- if(!savedState)
- reg[14].I += 2;
- reg[15].I = 0x18;
- armState = true;
- armIrqEnable = false;
-
- armNextPC = reg[15].I;
- reg[15].I += 4;
- ARM_PREFETCH;
-
- // if(!holdState)
- biosProtected[0] = 0x02;
- biosProtected[1] = 0xc0;
- biosProtected[2] = 0x5e;
- biosProtected[3] = 0xe5;
-}
-
-#ifdef SDL
-void log(const char *defaultMsg, ...)
-{
- char buffer[2048];
- va_list valist;
-
- va_start(valist, defaultMsg);
- vsprintf(buffer, defaultMsg, valist);
-
- if(out == NULL) {
- out = fopen("trace.log","w");
- }
-
- fputs(buffer, out);
-
- va_end(valist);
-}
-#else
-extern void winlog(const char *, ...);
-#endif
-
-void CPULoop(int ticks)
-{
- int clockTicks;
- int timerOverflow = 0;
- // variable used by the CPU core
- cpuTotalTicks = 0;
-#ifdef LINK_EMULATION
- if(linkenable)
- cpuNextEvent = 1;
-#endif
- cpuBreakLoop = false;
- cpuNextEvent = CPUUpdateTicks();
- if(cpuNextEvent > ticks)
- cpuNextEvent = ticks;
-
-
- for(;;) {
-#ifndef FINAL_VERSION
- if(systemDebug) {
- if(systemDebug >= 10 && !holdState) {
- CPUUpdateCPSR();
-#ifdef BKPT_SUPPORT
- if (debugger_last)
- {
- sprintf(buffer, "R00=%08x R01=%08x R02=%08x R03=%08x R04=%08x R05=%08x R06=%08x R07=%08x R08=%08x R09=%08x R10=%08x R11=%08x R12=%08x R13=%08x R14=%08x R15=%08x R16=%08x R17=%08x\n",
- oldreg[0], oldreg[1], oldreg[2], oldreg[3], oldreg[4], oldreg[5],
- oldreg[6], oldreg[7], oldreg[8], oldreg[9], oldreg[10], oldreg[11],
- oldreg[12], oldreg[13], oldreg[14], oldreg[15], oldreg[16],
- oldreg[17]);
- }
-#endif
- sprintf(buffer, "R00=%08x R01=%08x R02=%08x R03=%08x R04=%08x R05=%08x R06=%08x R07=%08x R08=%08x R09=%08x R10=%08x R11=%08x R12=%08x R13=%08x R14=%08x R15=%08x R16=%08x R17=%08x\n",
- reg[0].I, reg[1].I, reg[2].I, reg[3].I, reg[4].I, reg[5].I,
- reg[6].I, reg[7].I, reg[8].I, reg[9].I, reg[10].I, reg[11].I,
- reg[12].I, reg[13].I, reg[14].I, reg[15].I, reg[16].I,
- reg[17].I);
-#ifdef SDL
- log(buffer);
-#else
- winlog(buffer);
-#endif
- } else if(!holdState) {
- sprintf(buffer, "PC=%08x\n", armNextPC);
-#ifdef SDL
- log(buffer);
-#else
- winlog(buffer);
-#endif
- }
- }
-#endif /* FINAL_VERSION */
-
- if(!holdState && !SWITicks) {
- if(armState) {
- if (!armExecute())
- return;
- } else {
- if (!thumbExecute())
- return;
- }
- clockTicks = 0;
- } else
- clockTicks = CPUUpdateTicks();
-
- cpuTotalTicks += clockTicks;
-
-
- if(cpuTotalTicks >= cpuNextEvent) {
- int remainingTicks = cpuTotalTicks - cpuNextEvent;
-
- if (SWITicks)
- {
- SWITicks-=clockTicks;
- if (SWITicks<0)
- SWITicks = 0;
- }
-
- clockTicks = cpuNextEvent;
- cpuTotalTicks = 0;
- cpuDmaHack = false;
-
- updateLoop:
-
- if (IRQTicks)
- {
- IRQTicks -= clockTicks;
- if (IRQTicks<0)
- IRQTicks = 0;
- }
-
- lcdTicks -= clockTicks;
-
-
- if(lcdTicks <= 0) {
- if(DISPSTAT & 1) { // V-BLANK
- // if in V-Blank mode, keep computing...
- if(DISPSTAT & 2) {
- lcdTicks += 1008;
- VCOUNT++;
- UPDATE_REG(0x06, VCOUNT);
- DISPSTAT &= 0xFFFD;
- UPDATE_REG(0x04, DISPSTAT);
- CPUCompareVCOUNT();
- } else {
- lcdTicks += 224;
- DISPSTAT |= 2;
- UPDATE_REG(0x04, DISPSTAT);
- if(DISPSTAT & 16) {
- IF |= 2;
- UPDATE_REG(0x202, IF);
- }
- }
-
- if(VCOUNT >= 228) { //Reaching last line
- DISPSTAT &= 0xFFFC;
- UPDATE_REG(0x04, DISPSTAT);
- VCOUNT = 0;
- UPDATE_REG(0x06, VCOUNT);
- CPUCompareVCOUNT();
- }
- } else {
- int framesToSkip = systemFrameSkip;
- if(speedup)
- framesToSkip = 9; // try 6 FPS during speedup
-
- if(DISPSTAT & 2) {
- // if in H-Blank, leave it and move to drawing mode
- VCOUNT++;
- UPDATE_REG(0x06, VCOUNT);
-
- lcdTicks += 1008;
- DISPSTAT &= 0xFFFD;
- if(VCOUNT == 160) {
- count++;
- systemFrame();
-
- if((count % 10) == 0) {
- system10Frames(60);
- }
- if(count == 60) {
- u32 time = systemGetClock();
- if(time != lastTime) {
- u32 t = 100000/(time - lastTime);
- systemShowSpeed(t);
- } else
- systemShowSpeed(0);
- lastTime = time;
- count = 0;
- }
- u32 joy = 0;
- // update joystick information
- if(systemReadJoypads())
- // read default joystick
- joy = systemReadJoypad(-1);
- P1 = 0x03FF ^ (joy & 0x3FF);
- if(cpuEEPROMSensorEnabled)
- systemUpdateMotionSensor();
- UPDATE_REG(0x130, P1);
- u16 P1CNT = READ16LE(((u16 *)&ioMem[0x132]));
- // this seems wrong, but there are cases where the game
- // can enter the stop state without requesting an IRQ from
- // the joypad.
- if((P1CNT & 0x4000) || stopState) {
- u16 p1 = (0x3FF ^ P1) & 0x3FF;
- if(P1CNT & 0x8000) {
- if(p1 == (P1CNT & 0x3FF)) {
- IF |= 0x1000;
- UPDATE_REG(0x202, IF);
- }
- } else {
- if(p1 & P1CNT) {
- IF |= 0x1000;
- UPDATE_REG(0x202, IF);
- }
- }
- }
-
- u32 ext = (joy >> 10);
- // If no (m) code is enabled, apply the cheats at each LCDline
- if((cheatsEnabled) && (mastercode==0))
- remainingTicks += cheatsCheckKeys(P1^0x3FF, ext);
- speedup = (ext & 1) ? true : false;
- capture = (ext & 2) ? true : false;
-
- if(capture && !capturePrevious) {
- captureNumber++;
- systemScreenCapture(captureNumber);
- }
- capturePrevious = capture;
-
- DISPSTAT |= 1;
- DISPSTAT &= 0xFFFD;
- UPDATE_REG(0x04, DISPSTAT);
- if(DISPSTAT & 0x0008) {
- IF |= 1;
- UPDATE_REG(0x202, IF);
- }
- CPUCheckDMA(1, 0x0f);
- if(frameCount >= framesToSkip) {
- systemDrawScreen();
- frameCount = 0;
- } else
- frameCount++;
- if(systemPauseOnFrame())
- ticks = 0;
- }
-
- UPDATE_REG(0x04, DISPSTAT);
- CPUCompareVCOUNT();
-
- } else {
- if(frameCount >= framesToSkip)
- {
- (*renderLine)();
- switch(systemColorDepth) {
- case 16:
- {
- u16 *dest = (u16 *)pix + 242 * (VCOUNT+1);
- for(int x = 0; x < 240;) {
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
-
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
-
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
-
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
- }
- // for filters that read past the screen
- *dest++ = 0;
- }
- break;
- case 24:
- {
- u8 *dest = (u8 *)pix + 240 * VCOUNT * 3;
- for(int x = 0; x < 240;) {
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
-
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
-
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
-
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
- dest += 3;
- }
- }
- break;
- case 32:
- {
- u32 *dest = (u32 *)pix + 241 * (VCOUNT+1);
- for(int x = 0; x < 240; ) {
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
-
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
-
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
-
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
- }
- }
- break;
- }
- }
- // entering H-Blank
- DISPSTAT |= 2;
- UPDATE_REG(0x04, DISPSTAT);
- lcdTicks += 224;
- CPUCheckDMA(2, 0x0f);
- if(DISPSTAT & 16) {
- IF |= 2;
- UPDATE_REG(0x202, IF);
- }
- }
- }
- }
-
- // we shouldn't be doing sound in stop state, but we loose synchronization
- // if sound is disabled, so in stop state, soundTick will just produce
- // mute sound
- soundTicks -= clockTicks;
- if(soundTicks <= 0) {
- psoundTickfn();
- soundTicks += SOUND_CLOCK_TICKS;
- }
-
- if(!stopState) {
- if(timer0On) {
- timer0Ticks -= clockTicks;
- if(timer0Ticks <= 0) {
- timer0Ticks += (0x10000 - timer0Reload) << timer0ClockReload;
- timerOverflow |= 1;
- soundTimerOverflow(0);
- if(TM0CNT & 0x40) {
- IF |= 0x08;
- UPDATE_REG(0x202, IF);
- }
- }
- TM0D = 0xFFFF - (timer0Ticks >> timer0ClockReload);
- UPDATE_REG(0x100, TM0D);
- }
-
- if(timer1On) {
- if(TM1CNT & 4) {
- if(timerOverflow & 1) {
- TM1D++;
- if(TM1D == 0) {
- TM1D += timer1Reload;
- timerOverflow |= 2;
- soundTimerOverflow(1);
- if(TM1CNT & 0x40) {
- IF |= 0x10;
- UPDATE_REG(0x202, IF);
- }
- }
- UPDATE_REG(0x104, TM1D);
- }
- } else {
- timer1Ticks -= clockTicks;
- if(timer1Ticks <= 0) {
- timer1Ticks += (0x10000 - timer1Reload) << timer1ClockReload;
- timerOverflow |= 2;
- soundTimerOverflow(1);
- if(TM1CNT & 0x40) {
- IF |= 0x10;
- UPDATE_REG(0x202, IF);
- }
- }
- TM1D = 0xFFFF - (timer1Ticks >> timer1ClockReload);
- UPDATE_REG(0x104, TM1D);
- }
- }
-
- if(timer2On) {
- if(TM2CNT & 4) {
- if(timerOverflow & 2) {
- TM2D++;
- if(TM2D == 0) {
- TM2D += timer2Reload;
- timerOverflow |= 4;
- if(TM2CNT & 0x40) {
- IF |= 0x20;
- UPDATE_REG(0x202, IF);
- }
- }
- UPDATE_REG(0x108, TM2D);
- }
- } else {
- timer2Ticks -= clockTicks;
- if(timer2Ticks <= 0) {
- timer2Ticks += (0x10000 - timer2Reload) << timer2ClockReload;
- timerOverflow |= 4;
- if(TM2CNT & 0x40) {
- IF |= 0x20;
- UPDATE_REG(0x202, IF);
- }
- }
- TM2D = 0xFFFF - (timer2Ticks >> timer2ClockReload);
- UPDATE_REG(0x108, TM2D);
- }
- }
-
- if(timer3On) {
- if(TM3CNT & 4) {
- if(timerOverflow & 4) {
- TM3D++;
- if(TM3D == 0) {
- TM3D += timer3Reload;
- if(TM3CNT & 0x40) {
- IF |= 0x40;
- UPDATE_REG(0x202, IF);
- }
- }
- UPDATE_REG(0x10C, TM3D);
- }
- } else {
- timer3Ticks -= clockTicks;
- if(timer3Ticks <= 0) {
- timer3Ticks += (0x10000 - timer3Reload) << timer3ClockReload;
- if(TM3CNT & 0x40) {
- IF |= 0x40;
- UPDATE_REG(0x202, IF);
- }
- }
- TM3D = 0xFFFF - (timer3Ticks >> timer3ClockReload);
- UPDATE_REG(0x10C, TM3D);
- }
- }
- }
-
- timerOverflow = 0;
-
-
-
-#ifdef PROFILING
- profilingTicks -= clockTicks;
- if(profilingTicks <= 0) {
- profilingTicks += profilingTicksReload;
- if(profilSegment) {
- profile_segment *seg = profilSegment;
- do {
- u16 *b = (u16 *)seg->sbuf;
- int pc = ((reg[15].I - seg->s_lowpc) * seg->s_scale)/0x10000;
- if(pc >= 0 && pc < seg->ssiz) {
- b[pc]++;
- break;
- }
-
- seg = seg->next;
- } while(seg);
- }
- }
-#endif
-
- ticks -= clockTicks;
-#ifdef LINK_EMULATION
- if (linkenable)
- LinkUpdate(clockTicks);
-#endif
- cpuNextEvent = CPUUpdateTicks();
-
- if(cpuDmaTicksToUpdate > 0) {
- if(cpuDmaTicksToUpdate > cpuNextEvent)
- clockTicks = cpuNextEvent;
- else
- clockTicks = cpuDmaTicksToUpdate;
- cpuDmaTicksToUpdate -= clockTicks;
- if(cpuDmaTicksToUpdate < 0)
- cpuDmaTicksToUpdate = 0;
- cpuDmaHack = true;
- goto updateLoop;
- }
-#ifdef LINK_EMULATION
- if(linkenable)
- cpuNextEvent = 1;
-#endif
- if(IF && (IME & 1) && armIrqEnable) {
- int res = IF & IE;
- if(stopState)
- res &= 0x3080;
- if(res) {
- if (intState)
- {
- if (!IRQTicks)
- {
- CPUInterrupt();
- intState = false;
- holdState = false;
- stopState = false;
- holdType = 0;
- }
- }
- else
- {
- if (!holdState)
- {
- intState = true;
- IRQTicks=7;
- if (cpuNextEvent> IRQTicks)
- cpuNextEvent = IRQTicks;
- }
- else
- {
- CPUInterrupt();
- holdState = false;
- stopState = false;
- holdType = 0;
- }
- }
-
- // Stops the SWI Ticks emulation if an IRQ is executed
- //(to avoid problems with nested IRQ/SWI)
- if (SWITicks)
- SWITicks = 0;
- }
- }
-
- if(remainingTicks > 0) {
- if(remainingTicks > cpuNextEvent)
- clockTicks = cpuNextEvent;
- else
- clockTicks = remainingTicks;
- remainingTicks -= clockTicks;
- if(remainingTicks < 0)
- remainingTicks = 0;
- goto updateLoop;
- }
-
- if (timerOnOffDelay)
- applyTimer();
-
- if(cpuNextEvent > ticks)
- cpuNextEvent = ticks;
-
- if(ticks <= 0 || cpuBreakLoop)
- break;
-
- }
- }
-}
-
-
-
-struct EmulatedSystem GBASystem = {
- // emuMain
- CPULoop,
- // emuReset
- CPUReset,
- // emuCleanUp
- CPUCleanUp,
- // emuReadBattery
- CPUReadBatteryFile,
- // emuWriteBattery
- CPUWriteBatteryFile,
- // emuReadState
- CPUReadState,
- // emuWriteState
- CPUWriteState,
- // emuReadMemState
- CPUReadMemState,
- // emuWriteMemState
- CPUWriteMemState,
- // emuWritePNG
- CPUWritePNGFile,
- // emuWriteBMP
- CPUWriteBMPFile,
- // emuUpdateCPSR
- CPUUpdateCPSR,
- // emuHasDebugger
- true,
- // emuCount
-#ifdef FINAL_VERSION
- 250000
-#else
- 5000
-#endif
-};
diff --git a/src/GBA.h b/src/GBA.h
deleted file mode 100644
index f3c6a651..00000000
--- a/src/GBA.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// -*- 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_GBA_H
-#define VBA_GBA_H
-
-#include "System.h"
-
-#define SAVE_GAME_VERSION_1 1
-#define SAVE_GAME_VERSION_2 2
-#define SAVE_GAME_VERSION_3 3
-#define SAVE_GAME_VERSION_4 4
-#define SAVE_GAME_VERSION_5 5
-#define SAVE_GAME_VERSION_6 6
-#define SAVE_GAME_VERSION_7 7
-#define SAVE_GAME_VERSION_8 8
-#define SAVE_GAME_VERSION_9 9
-#define SAVE_GAME_VERSION_10 10
-#define SAVE_GAME_VERSION SAVE_GAME_VERSION_10
-
-typedef struct {
- u8 *address;
- u32 mask;
-} memoryMap;
-
-typedef union {
- struct {
-#ifdef WORDS_BIGENDIAN
- u8 B3;
- u8 B2;
- u8 B1;
- u8 B0;
-#else
- u8 B0;
- u8 B1;
- u8 B2;
- u8 B3;
-#endif
- } B;
- struct {
-#ifdef WORDS_BIGENDIAN
- u16 W1;
- u16 W0;
-#else
- u16 W0;
- u16 W1;
-#endif
- } W;
-#ifdef WORDS_BIGENDIAN
- volatile u32 I;
-#else
- u32 I;
-#endif
-} reg_pair;
-
-#ifndef NO_GBA_MAP
-extern memoryMap map[256];
-#endif
-
-extern reg_pair reg[45];
-extern u8 biosProtected[4];
-
-extern bool N_FLAG;
-extern bool Z_FLAG;
-extern bool C_FLAG;
-extern bool V_FLAG;
-extern bool armIrqEnable;
-extern bool armState;
-extern int armMode;
-extern void (*cpuSaveGameFunc)(u32,u8);
-
-#ifdef BKPT_SUPPORT
-extern u8 freezeWorkRAM[0x40000];
-extern u8 freezeInternalRAM[0x8000];
-extern u8 freezeVRAM[0x18000];
-extern u8 freezeOAM[0x400];
-extern u8 freezePRAM[0x400];
-extern bool debugger_last;
-extern int oldreg[17];
-extern char oldbuffer[10];
-#endif
-
-extern bool CPUReadGSASnapshot(const char *);
-extern bool CPUWriteGSASnapshot(const char *, const char *, const char *, const char *);
-extern bool CPUWriteBatteryFile(const char *);
-extern bool CPUReadBatteryFile(const char *);
-extern bool CPUExportEepromFile(const char *);
-extern bool CPUImportEepromFile(const char *);
-extern bool CPUWritePNGFile(const char *);
-extern bool CPUWriteBMPFile(const char *);
-extern void CPUCleanUp();
-extern void CPUUpdateRender();
-extern void CPUUpdateRenderBuffers(bool);
-extern bool CPUReadMemState(char *, int);
-extern bool CPUReadState(const char *);
-extern bool CPUWriteMemState(char *, int);
-extern bool CPUWriteState(const char *);
-extern int CPULoadRom(const char *);
-extern void doMirroring(bool);
-extern void CPUUpdateRegister(u32, u16);
-extern void applyTimer ();
-extern void CPUInit(const char *,bool);
-extern void CPUReset();
-extern void CPULoop(int);
-extern void CPUCheckDMA(int,int);
-extern bool CPUIsGBAImage(const char *);
-extern bool CPUIsZipFile(const char *);
-#ifdef PROFILING
-#include "prof/prof.h"
-extern void cpuProfil(profile_segment *seg);
-extern void cpuEnableProfiling(int hz);
-#endif
-
-extern struct EmulatedSystem GBASystem;
-
-#define R13_IRQ 18
-#define R14_IRQ 19
-#define SPSR_IRQ 20
-#define R13_USR 26
-#define R14_USR 27
-#define R13_SVC 28
-#define R14_SVC 29
-#define SPSR_SVC 30
-#define R13_ABT 31
-#define R14_ABT 32
-#define SPSR_ABT 33
-#define R13_UND 34
-#define R14_UND 35
-#define SPSR_UND 36
-#define R8_FIQ 37
-#define R9_FIQ 38
-#define R10_FIQ 39
-#define R11_FIQ 40
-#define R12_FIQ 41
-#define R13_FIQ 42
-#define R14_FIQ 43
-#define SPSR_FIQ 44
-
-#include "Cheats.h"
-#include "Globals.h"
-#include "EEprom.h"
-#include "Flash.h"
-
-#endif //VBA_GBA_H
diff --git a/src/GBAcpu.h b/src/GBAcpu.h
deleted file mode 100644
index 53384e9d..00000000
--- a/src/GBAcpu.h
+++ /dev/null
@@ -1,302 +0,0 @@
-// -*- 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((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 --git a/src/GBAinline.h b/src/GBAinline.h
deleted file mode 100644
index 51dcd011..00000000
--- a/src/GBAinline.h
+++ /dev/null
@@ -1,739 +0,0 @@
-// -*- 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_GBAinline_H
-#define VBA_GBAinline_H
-
-#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;
-extern bool cpuEEPROMSensorEnabled;
-extern bool cpuDmaHack;
-extern u32 cpuDmaLast;
-extern bool timer0On;
-extern int timer0Ticks;
-extern int timer0ClockReload;
-extern bool timer1On;
-extern int timer1Ticks;
-extern int timer1ClockReload;
-extern bool timer2On;
-extern int timer2Ticks;
-extern int timer2ClockReload;
-extern bool timer3On;
-extern int timer3Ticks;
-extern int timer3ClockReload;
-extern int cpuTotalTicks;
-
-#define CPUReadByteQuick(addr) \
- map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]
-
-#define CPUReadHalfWordQuick(addr) \
- READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
-
-#define CPUReadMemoryQuick(addr) \
- READ32LE(((u32*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
-
-static inline u32 CPUReadMemory(u32 address)
-{
-
-#ifdef GBA_LOGGING
- if(address & 3) {
- if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
- log("Unaligned word read: %08x at %08x\n", address, armMode ?
- armNextPC - 4 : armNextPC - 2);
- }
- }
-#endif
-
- u32 value;
- switch(address >> 24) {
- case 0:
- if(reg[15].I >> 24) {
- if(address < 0x4000) {
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_ILLEGAL_READ) {
- log("Illegal word read: %08x at %08x\n", address, armMode ?
- armNextPC - 4 : armNextPC - 2);
- }
-#endif
-
- value = READ32LE(((u32 *)&biosProtected));
- }
- else goto unreadable;
- } else
- value = READ32LE(((u32 *)&bios[address & 0x3FFC]));
- break;
- case 2:
- value = READ32LE(((u32 *)&workRAM[address & 0x3FFFC]));
- break;
- case 3:
- value = READ32LE(((u32 *)&internalRAM[address & 0x7ffC]));
- break;
- case 4:
- if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
- if(ioReadable[(address & 0x3fc) + 2])
- value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
- else
- value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
- } else goto unreadable;
- break;
- case 5:
- value = READ32LE(((u32 *)&paletteRAM[address & 0x3fC]));
- break;
- case 6:
- address = (address & 0x1fffc);
- if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
- {
- value = 0;
- break;
- }
- if ((address & 0x18000) == 0x18000)
- address &= 0x17fff;
- value = READ32LE(((u32 *)&vram[address]));
- break;
- case 7:
- value = READ32LE(((u32 *)&oam[address & 0x3FC]));
- break;
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- value = READ32LE(((u32 *)&rom[address&0x1FFFFFC]));
- break;
- case 13:
- if(cpuEEPROMEnabled)
- // no need to swap this
- return eepromRead(address);
- goto unreadable;
- case 14:
- if(cpuFlashEnabled | cpuSramEnabled)
- // no need to swap this
- return flashRead(address);
- // default
- default:
- unreadable:
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_ILLEGAL_READ) {
- log("Illegal word read: %08x at %08x\n", address, armMode ?
- armNextPC - 4 : armNextPC - 2);
- }
-#endif
-
- if(cpuDmaHack) {
- value = cpuDmaLast;
- } else {
- if(armState) {
- value = CPUReadMemoryQuick(reg[15].I);
- } else {
- value = CPUReadHalfWordQuick(reg[15].I) |
- CPUReadHalfWordQuick(reg[15].I) << 16;
- }
- }
- }
-
- if(address & 3) {
-#ifdef C_CORE
- int shift = (address & 3) << 3;
- value = (value >> shift) | (value << (32 - shift));
-#else
-#ifdef __GNUC__
- asm("and $3, %%ecx;"
- "shl $3 ,%%ecx;"
- "ror %%cl, %0"
- : "=r" (value)
- : "r" (value), "c" (address));
-#else
- __asm {
- mov ecx, address;
- and ecx, 3;
- shl ecx, 3;
- ror [dword ptr value], cl;
- }
-#endif
-#endif
- }
- return value;
-}
-
-extern u32 myROM[];
-
-static inline u32 CPUReadHalfWord(u32 address)
-{
-#ifdef GBA_LOGGING
- if(address & 1) {
- if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
- log("Unaligned halfword read: %08x at %08x\n", address, armMode ?
- armNextPC - 4 : armNextPC - 2);
- }
- }
-#endif
-
- u32 value;
-
- switch(address >> 24) {
- case 0:
- if (reg[15].I >> 24) {
- if(address < 0x4000) {
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_ILLEGAL_READ) {
- log("Illegal halfword read: %08x at %08x\n", address, armMode ?
- armNextPC - 4 : armNextPC - 2);
- }
-#endif
- value = READ16LE(((u16 *)&biosProtected[address&2]));
- } else goto unreadable;
- } else
- value = READ16LE(((u16 *)&bios[address & 0x3FFE]));
- break;
- case 2:
- value = READ16LE(((u16 *)&workRAM[address & 0x3FFFE]));
- break;
- case 3:
- value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
- break;
- case 4:
- if((address < 0x4000400) && ioReadable[address & 0x3fe])
- {
- value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
- if (((address & 0x3fe)>0xFF) && ((address & 0x3fe)<0x10E))
- {
- if (((address & 0x3fe) == 0x100) && timer0On)
- value = 0xFFFF - ((timer0Ticks-cpuTotalTicks) >> timer0ClockReload);
- else
- if (((address & 0x3fe) == 0x104) && timer1On && !(TM1CNT & 4))
- value = 0xFFFF - ((timer1Ticks-cpuTotalTicks) >> timer1ClockReload);
- else
- if (((address & 0x3fe) == 0x108) && timer2On && !(TM2CNT & 4))
- value = 0xFFFF - ((timer2Ticks-cpuTotalTicks) >> timer2ClockReload);
- else
- if (((address & 0x3fe) == 0x10C) && timer3On && !(TM3CNT & 4))
- value = 0xFFFF - ((timer3Ticks-cpuTotalTicks) >> timer3ClockReload);
- }
- }
- else goto unreadable;
- break;
- case 5:
- value = READ16LE(((u16 *)&paletteRAM[address & 0x3fe]));
- break;
- case 6:
- address = (address & 0x1fffe);
- if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
- {
- value = 0;
- break;
- }
- if ((address & 0x18000) == 0x18000)
- address &= 0x17fff;
- value = READ16LE(((u16 *)&vram[address]));
- break;
- case 7:
- value = READ16LE(((u16 *)&oam[address & 0x3fe]));
- break;
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
- value = rtcRead(address);
- else
- value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
- break;
- case 13:
- if(cpuEEPROMEnabled)
- // no need to swap this
- return eepromRead(address);
- goto unreadable;
- case 14:
- if(cpuFlashEnabled | cpuSramEnabled)
- // no need to swap this
- return flashRead(address);
- // default
- default:
- unreadable:
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_ILLEGAL_READ) {
- log("Illegal halfword read: %08x at %08x\n", address, armMode ?
- armNextPC - 4 : armNextPC - 2);
- }
-#endif
- if(cpuDmaHack) {
- value = cpuDmaLast & 0xFFFF;
- } else {
- if(armState) {
- value = CPUReadHalfWordQuick(reg[15].I + (address & 2));
- } else {
- value = CPUReadHalfWordQuick(reg[15].I);
- }
- }
- break;
- }
-
- if(address & 1) {
- value = (value >> 8) | (value << 24);
- }
-
- return value;
-}
-
-static inline u16 CPUReadHalfWordSigned(u32 address)
-{
- u16 value = CPUReadHalfWord(address);
- if((address & 1))
- value = (s8)value;
- return value;
-}
-
-static inline u8 CPUReadByte(u32 address)
-{
- switch(address >> 24) {
- case 0:
- if (reg[15].I >> 24) {
- if(address < 0x4000) {
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_ILLEGAL_READ) {
- log("Illegal byte read: %08x at %08x\n", address, armMode ?
- armNextPC - 4 : armNextPC - 2);
- }
-#endif
- return biosProtected[address & 3];
- } else goto unreadable;
- }
- return bios[address & 0x3FFF];
- case 2:
- return workRAM[address & 0x3FFFF];
- case 3:
- return internalRAM[address & 0x7fff];
- case 4:
- if((address < 0x4000400) && ioReadable[address & 0x3ff])
- return ioMem[address & 0x3ff];
- else goto unreadable;
- case 5:
- return paletteRAM[address & 0x3ff];
- case 6:
- address = (address & 0x1ffff);
- if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
- return 0;
- if ((address & 0x18000) == 0x18000)
- address &= 0x17fff;
- return vram[address];
- case 7:
- return oam[address & 0x3ff];
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- return rom[address & 0x1FFFFFF];
- case 13:
- if(cpuEEPROMEnabled)
- return eepromRead(address);
- goto unreadable;
- case 14:
- if(cpuSramEnabled | cpuFlashEnabled)
- return flashRead(address);
- if(cpuEEPROMSensorEnabled) {
- switch(address & 0x00008f00) {
- case 0x8200:
- return systemGetSensorX() & 255;
- case 0x8300:
- return (systemGetSensorX() >> 8)|0x80;
- case 0x8400:
- return systemGetSensorY() & 255;
- case 0x8500:
- return systemGetSensorY() >> 8;
- }
- }
- // default
- default:
- unreadable:
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_ILLEGAL_READ) {
- log("Illegal byte read: %08x at %08x\n", address, armMode ?
- armNextPC - 4 : armNextPC - 2);
- }
-#endif
- if(cpuDmaHack) {
- return cpuDmaLast & 0xFF;
- } else {
- if(armState) {
- return CPUReadByteQuick(reg[15].I+(address & 3));
- } else {
- return CPUReadByteQuick(reg[15].I+(address & 1));
- }
- }
- break;
- }
-}
-
-static inline void CPUWriteMemory(u32 address, u32 value)
-{
-
-#ifdef GBA_LOGGING
- if(address & 3) {
- if(systemVerbose & VERBOSE_UNALIGNED_MEMORY) {
- log("Unaligned word write: %08x to %08x from %08x\n",
- value,
- address,
- armMode ? armNextPC - 4 : armNextPC - 2);
- }
- }
-#endif
-
- switch(address >> 24) {
- case 0x02:
-#ifdef BKPT_SUPPORT
- if(*((u32 *)&freezeWorkRAM[address & 0x3FFFC]))
- cheatsWriteMemory(address & 0x203FFFC,
- value);
- else
-#endif
- WRITE32LE(((u32 *)&workRAM[address & 0x3FFFC]), value);
- break;
- case 0x03:
-#ifdef BKPT_SUPPORT
- if(*((u32 *)&freezeInternalRAM[address & 0x7ffc]))
- cheatsWriteMemory(address & 0x3007FFC,
- value);
- else
-#endif
- WRITE32LE(((u32 *)&internalRAM[address & 0x7ffC]), value);
- break;
- case 0x04:
- if(address < 0x4000400) {
- CPUUpdateRegister((address & 0x3FC), value & 0xFFFF);
- CPUUpdateRegister((address & 0x3FC) + 2, (value >> 16));
- } else goto unwritable;
- break;
- case 0x05:
-#ifdef BKPT_SUPPORT
- if(*((u32 *)&freezePRAM[address & 0x3fc]))
- cheatsWriteMemory(address & 0x70003FC,
- value);
- else
-#endif
- WRITE32LE(((u32 *)&paletteRAM[address & 0x3FC]), value);
- break;
- case 0x06:
- address = (address & 0x1fffc);
- if (((DISPCNT & 7) >2) && ((address & 0x1C000) == 0x18000))
- return;
- if ((address & 0x18000) == 0x18000)
- address &= 0x17fff;
-
-#ifdef BKPT_SUPPORT
- if(*((u32 *)&freezeVRAM[address]))
- cheatsWriteMemory(address + 0x06000000, value);
- else
-#endif
-
- WRITE32LE(((u32 *)&vram[address]), value);
- break;
- case 0x07:
-#ifdef BKPT_SUPPORT
- if(*((u32 *)&freezeOAM[address & 0x3fc]))
- cheatsWriteMemory(address & 0x70003FC,
- value);
- else
-#endif
- WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
- break;
- case 0x0D:
- if(cpuEEPROMEnabled) {
- eepromWrite(address, value);
- break;
- }
- goto unwritable;
- case 0x0E:
- if(!eepromInUse | cpuSramEnabled | cpuFlashEnabled) {
- (*cpuSaveGameFunc)(address, (u8)value);
- break;
- }
- // default
- default:
- unwritable:
-#ifdef GBA_LOGGING
- if(systemVerbose & VERBOSE_ILLEGAL_WRITE) {
- log("Illegal word write: %08x to %08x from %08x\n",
- value,
- address,
- armMode ? armNextPC - 4 : armNextPC - 2);
- }
-#endif
- break;
- }
-}
-
-static inline void CPUWriteHalfWord(u32 address, u16 value)
-{
-#ifdef GBA_LOGGING
- 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 GBA_LOGGING
- 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 GBA_LOGGING
- 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 --git a/src/Gfx.cpp b/src/Gfx.cpp
deleted file mode 100644
index 7dc47ef4..00000000
--- a/src/Gfx.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
-// Copyright (C) 1999-2003 Forgotten
-// Copyright (C) 2004 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 "System.h"
-
-int coeff[32] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
-
-u32 line0[240];
-u32 line1[240];
-u32 line2[240];
-u32 line3[240];
-u32 lineOBJ[240];
-u32 lineOBJWin[240];
-u32 lineMix[240];
-bool gfxInWin0[240];
-bool gfxInWin1[240];
-int lineOBJpixleft[128];
-
-int gfxBG2Changed = 0;
-int gfxBG3Changed = 0;
-
-int gfxBG2X = 0;
-int gfxBG2Y = 0;
-int gfxBG2LastX = 0;
-int gfxBG2LastY = 0;
-int gfxBG3X = 0;
-int gfxBG3Y = 0;
-int gfxBG3LastX = 0;
-int gfxBG3LastY = 0;
-int gfxLastVCOUNT = 0;
diff --git a/src/Gfx.h b/src/Gfx.h
deleted file mode 100644
index 597148ca..00000000
--- a/src/Gfx.h
+++ /dev/null
@@ -1,1602 +0,0 @@
-// -*- C++ -*-
-// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
-// Copyright (C) 1999-2003 Forgotten
-// Copyright (C) 2005 Forgotten and the VBA development team
-// Copyright (C) 2008 VBA-M 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_GFX_H
-#define VBA_GFX_H
-
-#include "GBA.h"
-#include "Gfx.h"
-#include "Globals.h"
-
-#include "Port.h"
-
-//#define SPRITE_DEBUG
-
-static void gfxDrawTextScreen(u16, u16, u16, u32 *);
-static void gfxDrawRotScreen(u16,
- u16, u16,
- u16, u16,
- u16, u16,
- u16, u16,
- int&, int&,
- int,
- u32*);
-static void gfxDrawRotScreen16Bit(u16,
- u16, u16,
- u16, u16,
- u16, u16,
- u16, u16,
- int&, int&,
- int,
- u32*);
-static void gfxDrawRotScreen256(u16,
- u16, u16,
- u16, u16,
- u16, u16,
- u16, u16,
- int&, int&,
- int,
- u32*);
-static void gfxDrawRotScreen16Bit160(u16,
- u16, u16,
- u16, u16,
- u16, u16,
- u16, u16,
- int&, int&,
- int,
- u32*);
-static void gfxDrawSprites(u32 *);
-static void gfxIncreaseBrightness(u32 *line, int coeff);
-static void gfxDecreaseBrightness(u32 *line, int coeff);
-static void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb);
-
-void mode0RenderLine();
-void mode0RenderLineNoWindow();
-void mode0RenderLineAll();
-
-void mode1RenderLine();
-void mode1RenderLineNoWindow();
-void mode1RenderLineAll();
-
-void mode2RenderLine();
-void mode2RenderLineNoWindow();
-void mode2RenderLineAll();
-
-void mode3RenderLine();
-void mode3RenderLineNoWindow();
-void mode3RenderLineAll();
-
-void mode4RenderLine();
-void mode4RenderLineNoWindow();
-void mode4RenderLineAll();
-
-void mode5RenderLine();
-void mode5RenderLineNoWindow();
-void mode5RenderLineAll();
-
-extern int coeff[32];
-extern u32 line0[240];
-extern u32 line1[240];
-extern u32 line2[240];
-extern u32 line3[240];
-extern u32 lineOBJ[240];
-extern u32 lineOBJWin[240];
-extern u32 lineMix[240];
-extern bool gfxInWin0[240];
-extern bool gfxInWin1[240];
-extern int lineOBJpixleft[128];
-
-extern int gfxBG2Changed;
-extern int gfxBG3Changed;
-
-extern int gfxBG2X;
-extern int gfxBG2Y;
-extern int gfxBG2LastX;
-extern int gfxBG2LastY;
-extern int gfxBG3X;
-extern int gfxBG3Y;
-extern int gfxBG3LastX;
-extern int gfxBG3LastY;
-extern int gfxLastVCOUNT;
-
-static inline void gfxClearArray(u32 *array)
-{
- for(int i = 0; i < 240; i++) {
- *array++ = 0x80000000;
- }
-}
-
-static inline void gfxDrawTextScreen(u16 control, u16 hofs, u16 vofs,
- u32 *line)
-{
- u16 *palette = (u16 *)paletteRAM;
- u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000];
- u16 *screenBase = (u16 *)&vram[((control >> 8) & 0x1f) * 0x800];
- u32 prio = ((control & 3)<<25) + 0x1000000;
- int sizeX = 256;
- int sizeY = 256;
- switch((control >> 14) & 3) {
- case 0:
- break;
- case 1:
- sizeX = 512;
- break;
- case 2:
- sizeY = 512;
- break;
- case 3:
- sizeX = 512;
- sizeY = 512;
- break;
- }
-
- int maskX = sizeX-1;
- int maskY = sizeY-1;
-
- bool mosaicOn = (control & 0x40) ? true : false;
-
- int xxx = hofs & maskX;
- int yyy = (vofs + VCOUNT) & maskY;
- int mosaicX = (MOSAIC & 0x000F)+1;
- int mosaicY = ((MOSAIC & 0x00F0)>>4)+1;
-
- if(mosaicOn) {
- if((VCOUNT % mosaicY) != 0) {
- mosaicY = VCOUNT - (VCOUNT % mosaicY);
- yyy = (vofs + mosaicY) & maskY;
- }
- }
-
- if(yyy > 255 && sizeY > 256) {
- yyy &= 255;
- screenBase += 0x400;
- if(sizeX > 256)
- screenBase += 0x400;
- }
-
- int yshift = ((yyy>>3)<<5);
- if((control) & 0x80) {
- u16 *screenSource = screenBase + 0x400 * (xxx>>8) + ((xxx & 255)>>3) + yshift;
- for(int x = 0; x < 240; x++) {
- u16 data = READ16LE(screenSource);
-
- int tile = data & 0x3FF;
- int tileX = (xxx & 7);
- int tileY = yyy & 7;
-
- if(tileX == 7)
- screenSource++;
-
- if(data & 0x0400)
- tileX = 7 - tileX;
- if(data & 0x0800)
- tileY = 7 - tileY;
-
- u8 color = charBase[tile * 64 + tileY * 8 + tileX];
-
- line[x] = color ? (READ16LE(&palette[color]) | prio): 0x80000000;
-
- xxx++;
- if(xxx == 256) {
- if(sizeX > 256)
- screenSource = screenBase + 0x400 + yshift;
- else {
- screenSource = screenBase + yshift;
- xxx = 0;
- }
- } else if(xxx >= sizeX) {
- xxx = 0;
- screenSource = screenBase + yshift;
- }
- }
- } else {
- u16 *screenSource = screenBase + 0x400*(xxx>>8)+((xxx&255)>>3) +
- yshift;
- for(int x = 0; x < 240; x++) {
- u16 data = READ16LE(screenSource);
-
- int tile = data & 0x3FF;
- int tileX = (xxx & 7);
- int tileY = yyy & 7;
-
- if(tileX == 7)
- screenSource++;
-
- if(data & 0x0400)
- tileX = 7 - tileX;
- if(data & 0x0800)
- tileY = 7 - tileY;
-
- u8 color = charBase[(tile<<5) + (tileY<<2) + (tileX>>1)];
-
- if(tileX & 1) {
- color = (color >> 4);
- } else {
- color &= 0x0F;
- }
-
- int pal = (data>>8) & 0xF0;
- line[x] = color ? (READ16LE(&palette[pal + color])|prio): 0x80000000;
-
- xxx++;
- if(xxx == 256) {
- if(sizeX > 256)
- screenSource = screenBase + 0x400 + yshift;
- else {
- screenSource = screenBase + yshift;
- xxx = 0;
- }
- } else if(xxx >= sizeX) {
- xxx = 0;
- screenSource = screenBase + yshift;
- }
- }
- }
- if(mosaicOn) {
- if(mosaicX > 1) {
- int m = 1;
- for(int i = 0; i < 239; i++) {
- line[i+1] = line[i];
- m++;
- if(m == mosaicX) {
- m = 1;
- i++;
- }
- }
- }
- }
-}
-
-static inline void gfxDrawRotScreen(u16 control,
- u16 x_l, u16 x_h,
- u16 y_l, u16 y_h,
- u16 pa, u16 pb,
- u16 pc, u16 pd,
- int& currentX, int& currentY,
- int changed,
- u32 *line)
-{
- u16 *palette = (u16 *)paletteRAM;
- u8 *charBase = &vram[((control >> 2) & 0x03) * 0x4000];
- u8 *screenBase = (u8 *)&vram[((control >> 8) & 0x1f) * 0x800];
- int prio = ((control & 3) << 25) + 0x1000000;
-
- int sizeX = 128;
- int sizeY = 128;
- switch((control >> 14) & 3) {
- case 0:
- break;
- case 1:
- sizeX = sizeY = 256;
- break;
- case 2:
- sizeX = sizeY = 512;
- break;
- case 3:
- sizeX = sizeY = 1024;
- break;
- }
-
- int maskX = sizeX-1;
- int maskY = sizeY-1;
-
- int yshift = ((control >> 14) & 3)+4;
-
- int dx = pa & 0x7FFF;
- if(pa & 0x8000)
- dx |= 0xFFFF8000;
- int dmx = pb & 0x7FFF;
- if(pb & 0x8000)
- dmx |= 0xFFFF8000;
- int dy = pc & 0x7FFF;
- if(pc & 0x8000)
- dy |= 0xFFFF8000;
- int dmy = pd & 0x7FFF;
- if(pd & 0x8000)
- dmy |= 0xFFFF8000;
-
- if(VCOUNT == 0)
- changed = 3;
-
- if(changed & 1) {
- currentX = (x_l) | ((x_h & 0x07FF)<<16);
- if(x_h & 0x0800)
- currentX |= 0xF8000000;
- } else {
- currentX += dmx;
- }
-
- if(changed & 2) {
- currentY = (y_l) | ((y_h & 0x07FF)<<16);
- if(y_h & 0x0800)
- currentY |= 0xF8000000;
- } else {
- currentY += dmy;
- }
-
- int realX = currentX;
- int realY = currentY;
-
- if(control & 0x40) {
- int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
- int y = (VCOUNT % mosaicY);
- realX -= y*dmx;
- realY -= y*dmy;
- }
-
- if(control & 0x2000) {
- for(int x = 0; x < 240; x++) {
- int xxx = (realX >> 8) & maskX;
- int yyy = (realY >> 8) & maskY;
-
- int tile = screenBase[(xxx>>3) + ((yyy>>3)<> 8);
- int yyy = (realY >> 8);
-
- if(xxx < 0 ||
- yyy < 0 ||
- xxx >= sizeX ||
- yyy >= sizeY) {
- line[x] = 0x80000000;
- } else {
- int tile = screenBase[(xxx>>3) + ((yyy>>3)< 1) {
- int m = 1;
- for(int i = 0; i < 239; i++) {
- line[i+1] = line[i];
- m++;
- if(m == mosaicX) {
- m = 1;
- i++;
- }
- }
- }
- }
-}
-
-static inline void gfxDrawRotScreen16Bit(u16 control,
- u16 x_l, u16 x_h,
- u16 y_l, u16 y_h,
- u16 pa, u16 pb,
- u16 pc, u16 pd,
- int& currentX, int& currentY,
- int changed,
- u32 *line)
-{
- u16 *screenBase = (u16 *)&vram[0];
- int prio = ((control & 3) << 25) + 0x1000000;
- int sizeX = 240;
- int sizeY = 160;
-
- int startX = (x_l) | ((x_h & 0x07FF)<<16);
- if(x_h & 0x0800)
- startX |= 0xF8000000;
- int startY = (y_l) | ((y_h & 0x07FF)<<16);
- if(y_h & 0x0800)
- startY |= 0xF8000000;
-
- int dx = pa & 0x7FFF;
- if(pa & 0x8000)
- dx |= 0xFFFF8000;
- int dmx = pb & 0x7FFF;
- if(pb & 0x8000)
- dmx |= 0xFFFF8000;
- int dy = pc & 0x7FFF;
- if(pc & 0x8000)
- dy |= 0xFFFF8000;
- int dmy = pd & 0x7FFF;
- if(pd & 0x8000)
- dmy |= 0xFFFF8000;
-
- if(VCOUNT == 0)
- changed = 3;
-
- if(changed & 1) {
- currentX = (x_l) | ((x_h & 0x07FF)<<16);
- if(x_h & 0x0800)
- currentX |= 0xF8000000;
- } else
- currentX += dmx;
-
- if(changed & 2) {
- currentY = (y_l) | ((y_h & 0x07FF)<<16);
- if(y_h & 0x0800)
- currentY |= 0xF8000000;
- } else {
- currentY += dmy;
- }
-
- int realX = currentX;
- int realY = currentY;
-
- if(control & 0x40) {
- int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
- int y = (VCOUNT % mosaicY);
- realX -= y*dmx;
- realY -= y*dmy;
- }
-
- int xxx = (realX >> 8);
- int yyy = (realY >> 8);
-
- for(int x = 0; x < 240; x++) {
- if(xxx < 0 ||
- yyy < 0 ||
- xxx >= sizeX ||
- yyy >= sizeY) {
- line[x] = 0x80000000;
- } else {
- line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio);
- }
- realX += dx;
- realY += dy;
-
- xxx = (realX >> 8);
- yyy = (realY >> 8);
- }
-
- if(control & 0x40) {
- int mosaicX = (MOSAIC & 0xF) + 1;
- if(mosaicX > 1) {
- int m = 1;
- for(int i = 0; i < 239; i++) {
- line[i+1] = line[i];
- m++;
- if(m == mosaicX) {
- m = 1;
- i++;
- }
- }
- }
- }
-}
-
-static inline void gfxDrawRotScreen256(u16 control,
- u16 x_l, u16 x_h,
- u16 y_l, u16 y_h,
- u16 pa, u16 pb,
- u16 pc, u16 pd,
- int ¤tX, int& currentY,
- int changed,
- u32 *line)
-{
- u16 *palette = (u16 *)paletteRAM;
- u8 *screenBase = (DISPCNT & 0x0010) ? &vram[0xA000] : &vram[0x0000];
- int prio = ((control & 3) << 25) + 0x1000000;
- int sizeX = 240;
- int sizeY = 160;
-
- int startX = (x_l) | ((x_h & 0x07FF)<<16);
- if(x_h & 0x0800)
- startX |= 0xF8000000;
- int startY = (y_l) | ((y_h & 0x07FF)<<16);
- if(y_h & 0x0800)
- startY |= 0xF8000000;
-
- int dx = pa & 0x7FFF;
- if(pa & 0x8000)
- dx |= 0xFFFF8000;
- int dmx = pb & 0x7FFF;
- if(pb & 0x8000)
- dmx |= 0xFFFF8000;
- int dy = pc & 0x7FFF;
- if(pc & 0x8000)
- dy |= 0xFFFF8000;
- int dmy = pd & 0x7FFF;
- if(pd & 0x8000)
- dmy |= 0xFFFF8000;
-
- if(VCOUNT == 0)
- changed = 3;
-
- if(changed & 1) {
- currentX = (x_l) | ((x_h & 0x07FF)<<16);
- if(x_h & 0x0800)
- currentX |= 0xF8000000;
- } else {
- currentX += dmx;
- }
-
- if(changed & 2) {
- currentY = (y_l) | ((y_h & 0x07FF)<<16);
- if(y_h & 0x0800)
- currentY |= 0xF8000000;
- } else {
- currentY += dmy;
- }
-
- int realX = currentX;
- int realY = currentY;
-
- if(control & 0x40) {
- int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
- int y = VCOUNT - (VCOUNT % mosaicY);
- realX = startX + y*dmx;
- realY = startY + y*dmy;
- }
-
- int xxx = (realX >> 8);
- int yyy = (realY >> 8);
-
- for(int x = 0; x < 240; x++) {
- if(xxx < 0 ||
- yyy < 0 ||
- xxx >= sizeX ||
- yyy >= sizeY) {
- line[x] = 0x80000000;
- } else {
- u8 color = screenBase[yyy * 240 + xxx];
-
- line[x] = color ? (READ16LE(&palette[color])|prio): 0x80000000;
- }
- realX += dx;
- realY += dy;
-
- xxx = (realX >> 8);
- yyy = (realY >> 8);
- }
-
- if(control & 0x40) {
- int mosaicX = (MOSAIC & 0xF) + 1;
- if(mosaicX > 1) {
- int m = 1;
- for(int i = 0; i < 239; i++) {
- line[i+1] = line[i];
- m++;
- if(m == mosaicX) {
- m = 1;
- i++;
- }
- }
- }
- }
-}
-
-static inline void gfxDrawRotScreen16Bit160(u16 control,
- u16 x_l, u16 x_h,
- u16 y_l, u16 y_h,
- u16 pa, u16 pb,
- u16 pc, u16 pd,
- int& currentX, int& currentY,
- int changed,
- u32 *line)
-{
- u16 *screenBase = (DISPCNT & 0x0010) ? (u16 *)&vram[0xa000] :
- (u16 *)&vram[0];
- int prio = ((control & 3) << 25) + 0x1000000;
- int sizeX = 160;
- int sizeY = 128;
-
- int startX = (x_l) | ((x_h & 0x07FF)<<16);
- if(x_h & 0x0800)
- startX |= 0xF8000000;
- int startY = (y_l) | ((y_h & 0x07FF)<<16);
- if(y_h & 0x0800)
- startY |= 0xF8000000;
-
- int dx = pa & 0x7FFF;
- if(pa & 0x8000)
- dx |= 0xFFFF8000;
- int dmx = pb & 0x7FFF;
- if(pb & 0x8000)
- dmx |= 0xFFFF8000;
- int dy = pc & 0x7FFF;
- if(pc & 0x8000)
- dy |= 0xFFFF8000;
- int dmy = pd & 0x7FFF;
- if(pd & 0x8000)
- dmy |= 0xFFFF8000;
-
- if(VCOUNT == 0)
- changed = 3;
-
- if(changed & 1) {
- currentX = (x_l) | ((x_h & 0x07FF)<<16);
- if(x_h & 0x0800)
- currentX |= 0xF8000000;
- } else {
- currentX += dmx;
- }
-
- if(changed & 2) {
- currentY = (y_l) | ((y_h & 0x07FF)<<16);
- if(y_h & 0x0800)
- currentY |= 0xF8000000;
- } else {
- currentY += dmy;
- }
-
- int realX = currentX;
- int realY = currentY;
-
- if(control & 0x40) {
- int mosaicY = ((MOSAIC & 0xF0)>>4) + 1;
- int y = VCOUNT - (VCOUNT % mosaicY);
- realX = startX + y*dmx;
- realY = startY + y*dmy;
- }
-
- int xxx = (realX >> 8);
- int yyy = (realY >> 8);
-
- for(int x = 0; x < 240; x++) {
- if(xxx < 0 ||
- yyy < 0 ||
- xxx >= sizeX ||
- yyy >= sizeY) {
- line[x] = 0x80000000;
- } else {
- line[x] = (READ16LE(&screenBase[yyy * sizeX + xxx]) | prio);
- }
- realX += dx;
- realY += dy;
-
- xxx = (realX >> 8);
- yyy = (realY >> 8);
- }
-
- if(control & 0x40) {
- int mosaicX = (MOSAIC & 0xF) + 1;
- if(mosaicX > 1) {
- int m = 1;
- for(int i = 0; i < 239; i++) {
- line[i+1] = line[i];
- m++;
- if(m == mosaicX) {
- m = 1;
- i++;
- }
- }
- }
- }
-}
-
-static inline void gfxDrawSprites(u32 *lineOBJ)
-{
- // lineOBJpix is used to keep track of the drawn OBJs
- // and to stop drawing them if the 'maximum number of OBJ per line'
- // has been reached.
- int lineOBJpix = (DISPCNT & 0x20) ? 954 : 1226;
- int m=0;
- gfxClearArray(lineOBJ);
- if(layerEnable & 0x1000) {
- u16 *sprites = (u16 *)oam;
- u16 *spritePalette = &((u16 *)paletteRAM)[256];
- int mosaicY = ((MOSAIC & 0xF000)>>12) + 1;
- int mosaicX = ((MOSAIC & 0xF00)>>8) + 1;
- for(int x = 0; x < 128 ; x++) {
- u16 a0 = READ16LE(sprites++);
- u16 a1 = READ16LE(sprites++);
- u16 a2 = READ16LE(sprites++);
- sprites++;
-
- lineOBJpixleft[x]=lineOBJpix;
-
- lineOBJpix-=2;
- if (lineOBJpix<=0)
- continue;
-
- if ((a0 & 0x0c00) == 0x0c00)
- a0 &=0xF3FF;
-
- if ((a0>>14) == 3)
- {
- a0 &= 0x3FFF;
- a1 &= 0x3FFF;
- }
-
- int sizeX = 8<<(a1>>14);
- int sizeY = sizeX;
-
- if ((a0>>14) & 1)
- {
- if (sizeX<32)
- sizeX<<=1;
- if (sizeY>8)
- sizeY>>=1;
- }
- else if ((a0>>14) & 2)
- {
- if (sizeX>8)
- sizeX>>=1;
- if (sizeY<32)
- sizeY<<=1;
- }
-
-#ifdef SPRITE_DEBUG
- int maskX = sizeX-1;
- int maskY = sizeY-1;
-#endif
-
- int sy = (a0 & 255);
- int sx = (a1 & 0x1FF);
-
- // computes ticks used by OBJ-WIN if OBJWIN is enabled
- if (((a0 & 0x0c00) == 0x0800) && (layerEnable & 0x8000))
- {
- if ((a0 & 0x0300) == 0x0300)
- {
- sizeX<<=1;
- sizeY<<=1;
- }
- if((sy+sizeY) > 256)
- sy -= 256;
- if ((sx+sizeX)> 512)
- sx-=512;
- if (sx<0)
- {
- sizeX+=sx;
- sx = 0;
- }
- else if ((sx+sizeX)>240)
- sizeX=240-sx;
- if ((VCOUNT>=sy) && (VCOUNT 256)
- sy -= 256;
- int t = VCOUNT - sy;
- if((t >= 0) && (t < fieldY)) {
- int startpix = 0;
- if ((sx+fieldX)> 512)
- {
- startpix=512-sx;
- }
- if (lineOBJpix>0)
- if((sx < 240) || startpix) {
- lineOBJpix-=8;
- // int t2 = t - (fieldY >> 1);
- int rot = (a1 >> 9) & 0x1F;
- u16 *OAM = (u16 *)oam;
- int dx = READ16LE(&OAM[3 + (rot << 4)]);
- if(dx & 0x8000)
- dx |= 0xFFFF8000;
- int dmx = READ16LE(&OAM[7 + (rot << 4)]);
- if(dmx & 0x8000)
- dmx |= 0xFFFF8000;
- int dy = READ16LE(&OAM[11 + (rot << 4)]);
- if(dy & 0x8000)
- dy |= 0xFFFF8000;
- int dmy = READ16LE(&OAM[15 + (rot << 4)]);
- if(dmy & 0x8000)
- dmy |= 0xFFFF8000;
-
- if(a0 & 0x1000) {
- t -= (t % mosaicY);
- }
-
- int realX = ((sizeX) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx
- + t * dmx;
- int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy
- + t * dmy;
-
- u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
-
- if(a0 & 0x2000) {
- int c = (a2 & 0x3FF);
- if((DISPCNT & 7) > 2 && (c < 512))
- continue;
- int inc = 32;
- if(DISPCNT & 0x40)
- inc = sizeX >> 2;
- else
- c &= 0x3FE;
- for(int x = 0; x < fieldX; x++) {
- if (x >= startpix)
- lineOBJpix-=2;
- if (lineOBJpix<0)
- continue;
- int xxx = realX >> 8;
- int yyy = realY >> 8;
-
- if(xxx < 0 || xxx >= sizeX ||
- yyy < 0 || yyy >= sizeY ||
- sx >= 240);
- else {
- u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
- + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +
- (xxx & 7))&0x7FFF)];
- if ((color==0) && (((prio >> 25)&3) <
- ((lineOBJ[sx]>>25)&3))) {
- lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
- if((a0 & 0x1000) && m)
- lineOBJ[sx]=(lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
- } else if((color) && (prio < (lineOBJ[sx]&0xFF000000))) {
- lineOBJ[sx] = READ16LE(&spritePalette[color]) | prio;
- if((a0 & 0x1000) && m)
- lineOBJ[sx]=(lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
- }
-
- if (a0 & 0x1000) {
- m++;
- if (m==mosaicX)
- m=0;
- }
-#ifdef SPRITE_DEBUG
- if(t == 0 || t == maskY || x == 0 || x == maskX)
- lineOBJ[sx] = 0x001F;
-#endif
- }
- sx = (sx+1)&511;
- realX += dx;
- realY += dy;
- }
- } else {
- int c = (a2 & 0x3FF);
- if((DISPCNT & 7) > 2 && (c < 512))
- continue;
-
- int inc = 32;
- if(DISPCNT & 0x40)
- inc = sizeX >> 3;
- int palette = (a2 >> 8) & 0xF0;
- for(int x = 0; x < fieldX; x++) {
- if (x >= startpix)
- lineOBJpix-=2;
- if (lineOBJpix<0)
- continue;
- int xxx = realX >> 8;
- int yyy = realY >> 8;
- if(xxx < 0 || xxx >= sizeX ||
- yyy < 0 || yyy >= sizeY ||
- sx >= 240);
- else {
- u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
- + ((yyy & 7)<<2) + ((xxx >> 3)<<5) +
- ((xxx & 7)>>1))&0x7FFF)];
- if(xxx & 1)
- color >>= 4;
- else
- color &= 0x0F;
-
- if ((color==0) && (((prio >> 25)&3) <
- ((lineOBJ[sx]>>25)&3))) {
- lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
- if((a0 & 0x1000) && m)
- lineOBJ[sx]=(lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
- } else if((color) && (prio < (lineOBJ[sx]&0xFF000000))) {
- lineOBJ[sx] = READ16LE(&spritePalette[palette+color]) | prio;
- if((a0 & 0x1000) && m)
- lineOBJ[sx]=(lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
- }
- }
- if((a0 & 0x1000) && m) {
- m++;
- if (m==mosaicX)
- m=0;
- }
-
-#ifdef SPRITE_DEBUG
- if(t == 0 || t == maskY || x == 0 || x == maskX)
- lineOBJ[sx] = 0x001F;
-#endif
- sx = (sx+1)&511;
- realX += dx;
- realY += dy;
-
- }
- }
- }
- }
- } else {
- if(sy+sizeY > 256)
- sy -= 256;
- int t = VCOUNT - sy;
- if((t >= 0) && (t < sizeY)) {
- int startpix = 0;
- if ((sx+sizeX)> 512)
- {
- startpix=512-sx;
- }
- if((sx < 240) || startpix) {
- lineOBJpix+=2;
- if(a0 & 0x2000) {
- if(a1 & 0x2000)
- t = sizeY - t - 1;
- int c = (a2 & 0x3FF);
- if((DISPCNT & 7) > 2 && (c < 512))
- continue;
-
- int inc = 32;
- if(DISPCNT & 0x40) {
- inc = sizeX >> 2;
- } else {
- c &= 0x3FE;
- }
- int xxx = 0;
- if(a1 & 0x1000)
- xxx = sizeX-1;
-
- if(a0 & 0x1000) {
- t -= (t % mosaicY);
- }
-
- int address = 0x10000 + ((((c+ (t>>3) * inc) << 5)
- + ((t & 7) << 3) + ((xxx>>3)<<6) + (xxx & 7)) & 0x7FFF);
-
- if(a1 & 0x1000)
- xxx = 7;
- u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
-
- for(int xx = 0; xx < sizeX; xx++) {
- if (xx >= startpix)
- lineOBJpix--;
- if (lineOBJpix<0)
- continue;
- if(sx < 240) {
- u8 color = vram[address];
- if ((color==0) && (((prio >> 25)&3) <
- ((lineOBJ[sx]>>25)&3))) {
- lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
- if((a0 & 0x1000) && m)
- lineOBJ[sx]=(lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
- } else if((color) && (prio < (lineOBJ[sx]&0xFF000000))) {
- lineOBJ[sx] = READ16LE(&spritePalette[color]) | prio;
- if((a0 & 0x1000) && m)
- lineOBJ[sx]=(lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
- }
-
- if (a0 & 0x1000) {
- m++;
- if (m==mosaicX)
- m=0;
- }
-
-#ifdef SPRITE_DEBUG
- if(t == 0 || t == maskY || xx == 0 || xx == maskX)
- lineOBJ[sx] = 0x001F;
-#endif
- }
-
- sx = (sx+1) & 511;
- if(a1 & 0x1000) {
- xxx--;
- address--;
- if(xxx == -1) {
- address -= 56;
- xxx = 7;
- }
- if(address < 0x10000)
- address += 0x8000;
- } else {
- xxx++;
- address++;
- if(xxx == 8) {
- address += 56;
- xxx = 0;
- }
- if(address > 0x17fff)
- address -= 0x8000;
- }
- }
- } else {
- if(a1 & 0x2000)
- t = sizeY - t - 1;
- int c = (a2 & 0x3FF);
- if((DISPCNT & 7) > 2 && (c < 512))
- continue;
-
- int inc = 32;
- if(DISPCNT & 0x40) {
- inc = sizeX >> 3;
- }
- int xxx = 0;
- if(a1 & 0x1000)
- xxx = sizeX - 1;
-
- if(a0 & 0x1000) {
- t -= (t % mosaicY);
- }
-
- int address = 0x10000 + ((((c + (t>>3) * inc)<<5)
- + ((t & 7)<<2) + ((xxx>>3)<<5) + ((xxx & 7) >> 1))&0x7FFF);
- u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
- int palette = (a2 >> 8) & 0xF0;
- if(a1 & 0x1000) {
- xxx = 7;
- for(int xx = sizeX - 1; xx >= 0; xx--) {
- if (xx >= startpix)
- lineOBJpix--;
- if (lineOBJpix<0)
- continue;
- if(sx < 240) {
- u8 color = vram[address];
- if(xx & 1) {
- color = (color >> 4);
- } else
- color &= 0x0F;
-
- if ((color==0) && (((prio >> 25)&3) <
- ((lineOBJ[sx]>>25)&3))) {
- lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
- if((a0 & 0x1000) && m)
- lineOBJ[sx]=(lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
- } else if((color) && (prio < (lineOBJ[sx]&0xFF000000))) {
- lineOBJ[sx] = READ16LE(&spritePalette[palette + color]) | prio;
- if((a0 & 0x1000) && m)
- lineOBJ[sx]=(lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
- }
- }
- if (a0 & 0x1000) {
- m++;
- if (m==mosaicX)
- m=0;
- }
-#ifdef SPRITE_DEBUG
- if(t == 0 || t == maskY || xx == 0 || xx == maskX)
- lineOBJ[sx] = 0x001F;
-#endif
- sx = (sx+1) & 511;
- xxx--;
- if(!(xx & 1))
- address--;
- if(xxx == -1) {
- xxx = 7;
- address -= 28;
- }
- if(address < 0x10000)
- address += 0x8000;
- }
- } else {
- for(int xx = 0; xx < sizeX; xx++) {
- if (xx >= startpix)
- lineOBJpix--;
- if (lineOBJpix<0)
- continue;
- if(sx < 240) {
- u8 color = vram[address];
- if(xx & 1) {
- color = (color >> 4);
- } else
- color &= 0x0F;
-
- if ((color==0) && (((prio >> 25)&3) <
- ((lineOBJ[sx]>>25)&3))) {
- lineOBJ[sx] = (lineOBJ[sx] & 0xF9FFFFFF) | prio;
- if((a0 & 0x1000) && m)
- lineOBJ[sx]=(lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
- } else if((color) && (prio < (lineOBJ[sx]&0xFF000000))) {
- lineOBJ[sx] = READ16LE(&spritePalette[palette + color]) | prio;
- if((a0 & 0x1000) && m)
- lineOBJ[sx]=(lineOBJ[sx-1] & 0xF9FFFFFF) | prio;
-
- }
- }
- if (a0 & 0x1000) {
- m++;
- if (m==mosaicX)
- m=0;
- }
-#ifdef SPRITE_DEBUG
- if(t == 0 || t == maskY || xx == 0 || xx == maskX)
- lineOBJ[sx] = 0x001F;
-#endif
- sx = (sx+1) & 511;
- xxx++;
- if(xx & 1)
- address++;
- if(xxx == 8) {
- address += 28;
- xxx = 0;
- }
- if(address > 0x17fff)
- address -= 0x8000;
- }
- }
- }
- }
- }
- }
- }
- }
-}
-
-static inline void gfxDrawOBJWin(u32 *lineOBJWin)
-{
- gfxClearArray(lineOBJWin);
- if((layerEnable & 0x9000) == 0x9000) {
- u16 *sprites = (u16 *)oam;
- // u16 *spritePalette = &((u16 *)paletteRAM)[256];
- for(int x = 0; x < 128 ; x++) {
- int lineOBJpix = lineOBJpixleft[x];
- u16 a0 = READ16LE(sprites++);
- u16 a1 = READ16LE(sprites++);
- u16 a2 = READ16LE(sprites++);
- sprites++;
-
- if (lineOBJpix<=0)
- continue;
-
- // ignores non OBJ-WIN and disabled OBJ-WIN
- if(((a0 & 0x0c00) != 0x0800) || ((a0 & 0x0300) == 0x0200))
- continue;
-
- if ((a0 & 0x0c00) == 0x0c00)
- a0 &=0xF3FF;
-
- if ((a0>>14) == 3)
- {
- a0 &= 0x3FFF;
- a1 &= 0x3FFF;
- }
-
- int sizeX = 8<<(a1>>14);
- int sizeY = sizeX;
-
- if ((a0>>14) & 1)
- {
- if (sizeX<32)
- sizeX<<=1;
- if (sizeY>8)
- sizeY>>=1;
- }
- else if ((a0>>14) & 2)
- {
- if (sizeX>8)
- sizeX>>=1;
- if (sizeY<32)
- sizeY<<=1;
- }
-
- int sy = (a0 & 255);
-
- if(a0 & 0x0100) {
- int fieldX = sizeX;
- int fieldY = sizeY;
- if(a0 & 0x0200) {
- fieldX <<= 1;
- fieldY <<= 1;
- }
- if((sy+fieldY) > 256)
- sy -= 256;
- int t = VCOUNT - sy;
- if((t >= 0) && (t < fieldY)) {
- int sx = (a1 & 0x1FF);
- int startpix = 0;
- if ((sx+fieldX)> 512)
- {
- startpix=512-sx;
- }
- if((sx < 240) || startpix) {
- lineOBJpix-=8;
- // int t2 = t - (fieldY >> 1);
- int rot = (a1 >> 9) & 0x1F;
- u16 *OAM = (u16 *)oam;
- int dx = READ16LE(&OAM[3 + (rot << 4)]);
- if(dx & 0x8000)
- dx |= 0xFFFF8000;
- int dmx = READ16LE(&OAM[7 + (rot << 4)]);
- if(dmx & 0x8000)
- dmx |= 0xFFFF8000;
- int dy = READ16LE(&OAM[11 + (rot << 4)]);
- if(dy & 0x8000)
- dy |= 0xFFFF8000;
- int dmy = READ16LE(&OAM[15 + (rot << 4)]);
- if(dmy & 0x8000)
- dmy |= 0xFFFF8000;
-
- int realX = ((sizeX) << 7) - (fieldX >> 1)*dx - (fieldY>>1)*dmx
- + t * dmx;
- int realY = ((sizeY) << 7) - (fieldX >> 1)*dy - (fieldY>>1)*dmy
- + t * dmy;
-
- // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
-
- if(a0 & 0x2000) {
- int c = (a2 & 0x3FF);
- if((DISPCNT & 7) > 2 && (c < 512))
- continue;
- int inc = 32;
- if(DISPCNT & 0x40)
- inc = sizeX >> 2;
- else
- c &= 0x3FE;
- for(int x = 0; x < fieldX; x++) {
- if (x >= startpix)
- lineOBJpix-=2;
- if (lineOBJpix<0)
- continue;
- int xxx = realX >> 8;
- int yyy = realY >> 8;
-
- if(xxx < 0 || xxx >= sizeX ||
- yyy < 0 || yyy >= sizeY ||
- sx >= 240) {
- } else {
- u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
- + ((yyy & 7)<<3) + ((xxx >> 3)<<6) +
- (xxx & 7))&0x7fff)];
- if(color) {
- lineOBJWin[sx] = 1;
- }
- }
- sx = (sx+1)&511;
- realX += dx;
- realY += dy;
- }
- } else {
- int c = (a2 & 0x3FF);
- if((DISPCNT & 7) > 2 && (c < 512))
- continue;
-
- int inc = 32;
- if(DISPCNT & 0x40)
- inc = sizeX >> 3;
- // int palette = (a2 >> 8) & 0xF0;
- for(int x = 0; x < fieldX; x++) {
- if (x >= startpix)
- lineOBJpix-=2;
- if (lineOBJpix<0)
- continue;
- int xxx = realX >> 8;
- int yyy = realY >> 8;
-
- // if(x == 0 || x == (sizeX-1) ||
- // t == 0 || t == (sizeY-1)) {
- // lineOBJ[sx] = 0x001F | prio;
- // } else {
- if(xxx < 0 || xxx >= sizeX ||
- yyy < 0 || yyy >= sizeY ||
- sx >= 240) {
- } else {
- u32 color = vram[0x10000 + ((((c + (yyy>>3) * inc)<<5)
- + ((yyy & 7)<<2) + ((xxx >> 3)<<5) +
- ((xxx & 7)>>1))&0x7fff)];
- if(xxx & 1)
- color >>= 4;
- else
- color &= 0x0F;
-
- if(color) {
- lineOBJWin[sx] = 1;
- }
- }
- // }
- sx = (sx+1)&511;
- realX += dx;
- realY += dy;
- }
- }
- }
- }
- } else {
- if((sy+sizeY) > 256)
- sy -= 256;
- int t = VCOUNT - sy;
- if((t >= 0) && (t < sizeY)) {
- int sx = (a1 & 0x1FF);
- int startpix = 0;
- if ((sx+sizeX)> 512)
- {
- startpix=512-sx;
- }
- if((sx < 240) || startpix) {
- lineOBJpix+=2;
- if(a0 & 0x2000) {
- if(a1 & 0x2000)
- t = sizeY - t - 1;
- int c = (a2 & 0x3FF);
- if((DISPCNT & 7) > 2 && (c < 512))
- continue;
-
- int inc = 32;
- if(DISPCNT & 0x40) {
- inc = sizeX >> 2;
- } else {
- c &= 0x3FE;
- }
- int xxx = 0;
- if(a1 & 0x1000)
- xxx = sizeX-1;
- int address = 0x10000 + ((((c+ (t>>3) * inc) << 5)
- + ((t & 7) << 3) + ((xxx>>3)<<6) + (xxx & 7))&0x7fff);
- if(a1 & 0x1000)
- xxx = 7;
- // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
- for(int xx = 0; xx < sizeX; xx++) {
- if (xx >= startpix)
- lineOBJpix--;
- if (lineOBJpix<0)
- continue;
- if(sx < 240) {
- u8 color = vram[address];
- if(color) {
- lineOBJWin[sx] = 1;
- }
- }
-
- sx = (sx+1) & 511;
- if(a1 & 0x1000) {
- xxx--;
- address--;
- if(xxx == -1) {
- address -= 56;
- xxx = 7;
- }
- if(address < 0x10000)
- address += 0x8000;
- } else {
- xxx++;
- address++;
- if(xxx == 8) {
- address += 56;
- xxx = 0;
- }
- if(address > 0x17fff)
- address -= 0x8000;
- }
- }
- } else {
- if(a1 & 0x2000)
- t = sizeY - t - 1;
- int c = (a2 & 0x3FF);
- if((DISPCNT & 7) > 2 && (c < 512))
- continue;
-
- int inc = 32;
- if(DISPCNT & 0x40) {
- inc = sizeX >> 3;
- }
- int xxx = 0;
- if(a1 & 0x1000)
- xxx = sizeX - 1;
- int address = 0x10000 + ((((c + (t>>3) * inc)<<5)
- + ((t & 7)<<2) + ((xxx>>3)<<5) + ((xxx & 7) >> 1))&0x7fff);
- // u32 prio = (((a2 >> 10) & 3) << 25) | ((a0 & 0x0c00)<<6);
- // int palette = (a2 >> 8) & 0xF0;
- if(a1 & 0x1000) {
- xxx = 7;
- for(int xx = sizeX - 1; xx >= 0; xx--) {
- if (xx >= startpix)
- lineOBJpix--;
- if (lineOBJpix<0)
- continue;
- if(sx < 240) {
- u8 color = vram[address];
- if(xx & 1) {
- color = (color >> 4);
- } else
- color &= 0x0F;
-
- if(color) {
- lineOBJWin[sx] = 1;
- }
- }
- sx = (sx+1) & 511;
- xxx--;
- if(!(xx & 1))
- address--;
- if(xxx == -1) {
- xxx = 7;
- address -= 28;
- }
- if(address < 0x10000)
- address += 0x8000;
- }
- } else {
- for(int xx = 0; xx < sizeX; xx++) {
- if (xx >= startpix)
- lineOBJpix--;
- if (lineOBJpix<0)
- continue;
- if(sx < 240) {
- u8 color = vram[address];
- if(xx & 1) {
- color = (color >> 4);
- } else
- color &= 0x0F;
-
- if(color) {
- lineOBJWin[sx] = 1;
- }
- }
- sx = (sx+1) & 511;
- xxx++;
- if(xx & 1)
- address++;
- if(xxx == 8) {
- address += 28;
- xxx = 0;
- }
- if(address > 0x17fff)
- address -= 0x8000;
- }
- }
- }
- }
- }
- }
- }
- }
-}
-
-static inline u32 gfxIncreaseBrightness(u32 color, int coeff)
-{
- color &= 0xffff;
- color = ((color << 16) | color) & 0x3E07C1F;
-
- color = color + (((0x3E07C1F - color) * coeff) >> 4);
- color &= 0x3E07C1F;
-
- return (color >> 16) | color;
-}
-
-static inline void gfxIncreaseBrightness(u32 *line, int coeff)
-{
- for(int x = 0; x < 240; x++) {
- u32 color = *line;
- int r = (color & 0x1F);
- int g = ((color >> 5) & 0x1F);
- int b = ((color >> 10) & 0x1F);
-
- r = r + (((31 - r) * coeff) >> 4);
- g = g + (((31 - g) * coeff) >> 4);
- b = b + (((31 - b) * coeff) >> 4);
- if(r > 31)
- r = 31;
- if(g > 31)
- g = 31;
- if(b > 31)
- b = 31;
- *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
- }
-}
-
-static inline u32 gfxDecreaseBrightness(u32 color, int coeff)
-{
- color &= 0xffff;
- color = ((color << 16) | color) & 0x3E07C1F;
-
- color = color - (((color * coeff) >> 4) & 0x3E07C1F);
-
- return (color >> 16) | color;
-}
-
-static inline void gfxDecreaseBrightness(u32 *line, int coeff)
-{
- for(int x = 0; x < 240; x++) {
- u32 color = *line;
- int r = (color & 0x1F);
- int g = ((color >> 5) & 0x1F);
- int b = ((color >> 10) & 0x1F);
-
- r = r - ((r * coeff) >> 4);
- g = g - ((g * coeff) >> 4);
- b = b - ((b * coeff) >> 4);
- if(r < 0)
- r = 0;
- if(g < 0)
- g = 0;
- if(b < 0)
- b = 0;
- *line++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
- }
-}
-
-static inline u32 gfxAlphaBlend(u32 color, u32 color2, int ca, int cb)
-{
- if(color < 0x80000000) {
- color&=0xffff;
- color2&=0xffff;
-
- color = ((color << 16) | color) & 0x03E07C1F;
- color2 = ((color2 << 16) | color2) & 0x03E07C1F;
- color = ((color * ca) + (color2 * cb)) >> 4;
-
- if ((ca + cb)>16)
- {
- if (color & 0x20)
- color |= 0x1f;
- if (color & 0x8000)
- color |= 0x7C00;
- if (color & 0x4000000)
- color |= 0x03E00000;
- }
-
- color &= 0x03E07C1F;
- color = (color >> 16) | color;
- }
- return color;
-}
-
-static inline void gfxAlphaBlend(u32 *ta, u32 *tb, int ca, int cb)
-{
- for(int x = 0; x < 240; x++) {
- u32 color = *ta;
- if(color < 0x80000000) {
- int r = (color & 0x1F);
- int g = ((color >> 5) & 0x1F);
- int b = ((color >> 10) & 0x1F);
- u32 color2 = (*tb++);
- int r0 = (color2 & 0x1F);
- int g0 = ((color2 >> 5) & 0x1F);
- int b0 = ((color2 >> 10) & 0x1F);
-
- r = ((r * ca) + (r0 * cb)) >> 4;
- g = ((g * ca) + (g0 * cb)) >> 4;
- b = ((b * ca) + (b0 * cb)) >> 4;
-
- if(r > 31)
- r = 31;
- if(g > 31)
- g = 31;
- if(b > 31)
- b = 31;
-
- *ta++ = (color & 0xFFFF0000) | (b << 10) | (g << 5) | r;
- } else {
- ta++;
- tb++;
- }
- }
-}
-
-#endif // VBA_GFX_H
diff --git a/src/Globals.cpp b/src/Globals.cpp
index a256ce37..a5350163 100644
--- a/src/Globals.cpp
+++ b/src/Globals.cpp
@@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "GBA.h"
+#include "agb/GBA.h"
#ifdef BKPT_SUPPORT
int oldreg[17];
diff --git a/src/Link.cpp b/src/Link.cpp
deleted file mode 100644
index 63b42e86..00000000
--- a/src/Link.cpp
+++ /dev/null
@@ -1,1083 +0,0 @@
-// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
-// Copyright (C) 1999-2003 Forgotten
-// Copyright (C) 2004 Forgotten and the VBA development team
-// This file was written by denopqrihg
-
-// 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.
-
-// Link.cpp : Emulation of GBA link accessories
-//
-
-#include "GBA.h"
-#include
-#include "win32/stdafx.h"
-#include "port.h"
-#include "Link.h"
-#include "win32/vba.h"
-#include "win32/MainWnd.h"
-#include "win32/LinkOptions.h"
-#include "win32/Reg.h"
-
-#define UPDATE_REG(address, value) WRITE16LE(((u16 *)&ioMem[address]),value)
-#define GBLINK_READY 8
-
-int linktime = 0;
-u8 tspeed=3;
-u8 transfer=0;
-LINKDATA *linkmem=NULL;
-int linkid = 0, vbaid = 0;
-HANDLE linksync[4];
-int savedlinktime=0;
-HANDLE mmf=NULL;
-char linkevent[] = "VBA link event ";
-static int i, j;
-int linktimeout = 1000;
-int linklog = 0;
-FILE *linklogfile = NULL;
-LANLINKDATA lanlink;
-u16 linkdata[4];
-int lspeed = 0;
-lserver ls;
-lclient lc;
-bool oncewait = false, after = false;
-bool adapter = false;
-bool linkenable = false;
-u8 rfu_cmd, rfu_qsend, rfu_qrecv;
-int rfu_state, rfu_polarity, linktime2, counter, rfu_masterq;
-int transferend, numtransfers = 0;
-u32 rfu_masterdata[32];
-
-extern unsigned char *gbMemory;
-extern int gbInterrupt;
-
-int trtimedata[4][4] = {{34080, 8520, 5680, 2840}, {65536, 16384, 10923, 5461}, {99609, 24903, 16602, 8301}, {133692, 33423, 22282, 11141}};
-int trtimeend[3][4] = {{72527, 18132, 12088, 6044}, {106608, 26652, 17768, 8884}, {133692, 33423, 22282, 11141}};
-int gbtime = 1024;
-
-DWORD WINAPI LinkClientThread(void *);
-DWORD WINAPI LinkServerThread(void *);
-int StartServer(void);
-int GetSioMode(u16, u16);
-u16 StartRFU(u16);
-
-char *MakeInstanceFilename(const char *Input)
-{
- if (vbaid == 0)
- return (char *)Input;
-
- static char *result=NULL;
- if (result!=NULL)
- free(result);
-
- result = (char *)malloc(strlen(Input)+3);
- char *p = strrchr((char *)Input, '.');
- sprintf(result, "%.*s-%d.%s", (int)(p-Input), Input, vbaid+1, p+1);
- return result;
-}
-
-
-void StartLink(WORD value){
- if(ioMem==NULL) return;
- if(adapter){
- UPDATE_REG(0x128, StartRFU(value));
- return;
- }
- switch(GetSioMode(value, READ16LE(&ioMem[0x134]))){
- case MULTIPLAYER:
- if(value & 0x80){
- if(!linkid){
- if(!transfer){
- if(lanlink.active){
- if(lanlink.connected){
- linkdata[0] = READ16LE(&ioMem[0x12a]);
- savedlinktime = linktime;
- tspeed = value & 3;
- ls.Send();
- transfer = 1;
- linktime = 0;
- UPDATE_REG(0x120, linkdata[0]);
- UPDATE_REG(0x122, 0xffff);
- WRITE32LE(&ioMem[0x124], 0xffffffff);
- if(lanlink.speed&&oncewait==false) ls.howmanytimes++;
- after = false;
- }
- } else if(linkmem->numgbas>1){
- ResetEvent(linksync[0]);
- linkmem->linkcmd[0] = ('M'<<8)+(value&3);
- linkmem->linkdata[0] = READ16LE(&ioMem[0x12a]);
- if(linkmem->numtransfers!=0) linkmem->lastlinktime = linktime;
- else linkmem->lastlinktime = 0;
- if((++linkmem->numtransfers)==0) linkmem->numtransfers=2;
- transfer = 1;
- linktime = 0;
- tspeed = value & 3;
- WRITE32LE(&ioMem[0x120], 0xffffffff);
- WRITE32LE(&ioMem[0x124], 0xffffffff);
- }
- }
- }
- value &= 0xff7f;
- value |= (transfer!=0)<<7;
- }
- value &= 0xff8b;
- value |= (linkid ? 0xc : 8);
- value |= linkid<<4;
- UPDATE_REG(0x128, value);
- if(linkid) UPDATE_REG(0x134, 7);
- else UPDATE_REG(0x134, 3);
- break;
- case NORMAL8:
- if(linklog) fprintf(linklogfile, "Attempt to use 8-bit Normal mode %04x\n", value);
- UPDATE_REG(0x128, value);
- break;
- case NORMAL32:
- if(linklog) fprintf(linklogfile, "Attempt to use 32-bit Normal mode %04x %x%x\n", value, READ16LE(&ioMem[0x122]), READ16LE(&ioMem[0x120]));
- UPDATE_REG(0x128, value);
- break;
- case UART:
- if(linklog) fprintf(linklogfile, "Attempt to use UART mode %04x\n", value);
- UPDATE_REG(0x128, value);
- break;
- default:
- UPDATE_REG(0x128, value);
- break;
- }
-}
-
-void StartGPLink(u16 value){
- if(!value){
- UPDATE_REG(0x134, 0);
- return;
- }
- switch(GetSioMode(READ16LE(&ioMem[0x128]), value)){
- case MULTIPLAYER:
- value &= 0xc0f0;
- value |= 3;
- if(linkid) value |= 4;
- UPDATE_REG(0x134, value);
- UPDATE_REG(0x128, ((READ16LE(&ioMem[0x128])&0xff8b)|(linkid ? 0xc : 8)|(linkid<<4)));
- return;
- break;
- case GP:
- if(linklog){
- if(value==0x8000) fprintf(linklogfile, "Circuit reset\n");
- else if(!adapter) fprintf(linklogfile, "Attempt to use General-purpose mode %04x\n", value);
- }
- if(adapter) rfu_state = RFU_INIT;
- // This was not there, but sonic games won't start if it's not here.
- UPDATE_REG(0x134, value);
- break;
- case JOYBUS:
- UPDATE_REG(0x134, value);
- break;
- default:
- UPDATE_REG(0x134, value);
- break;
- }
- return;
-}
-
-void StartJOYLink(u16 value){
- if(!value){
- UPDATE_REG(0x140, 0);
- return;
- }
- if(GetSioMode(READ16LE(&ioMem[0x128]), READ16LE(&ioMem[0x134]))==JOYBUS&&linklog) fprintf(linklogfile, "Attempt to use JOY-BUS mode %04x\n", value);
- return;
-}
-
-void LinkUpdate(int ticks){
- linktime += ticks;
- if(adapter){
- linktime2 += ticks;
- transferend -= ticks;
- if(transfer&&transferend<=0){
- transfer = 0;
- if(READ16LE(&ioMem[0x128])&0x4000){
- IF |= 0x80;
- UPDATE_REG(0x202, IF);
- }
- UPDATE_REG(0x128, READ16LE(&ioMem[0x128]) & 0xff7f);
- }
- return;
- }
-
- if(lanlink.active){
- if(lanlink.connected){
- if(after){
- if(linkid&&linktime>6044){
- lc.Recv();
- oncewait = true;
- } else return;
- }
- if(linkid&&!transfer&&lc.numtransfers>0&&linktime>=savedlinktime){
- linkdata[linkid] = READ16LE(&ioMem[0x12a]);
- if(!lc.oncesend) lc.Send();
- lc.oncesend = false;
- UPDATE_REG(0x120, linkdata[0]);
- UPDATE_REG(0x128, READ16LE(&ioMem[0x128]) | 0x80);
- transfer = 1;
- if(lc.numtransfers==1) linktime = 0;
- else linktime -= savedlinktime;
- }
- if(transfer&&linktime>=trtimeend[lanlink.numgbas-1][tspeed]){
- if(READ16LE(&ioMem[0x128]) & 0x4000){
- IF |= 0x80;
- UPDATE_REG(0x202, IF);
- }
- UPDATE_REG(0x128, (READ16LE(&ioMem[0x128]) & 0xff0f) | (linkid << 4));
- transfer = 0;
- linktime -= trtimeend[lanlink.numgbas-1][tspeed];
- oncewait = false;
- if(!lanlink.speed){
- if(linkid) lc.Recv();
- else ls.Recv();
- UPDATE_REG(0x122, linkdata[1]);
- UPDATE_REG(0x124, linkdata[2]);
- UPDATE_REG(0x126, linkdata[3]);
- if(linklog) fprintf(linklogfile, "%04x %04x %04x %04x %10u\n", linkdata[0], linkdata[1], linkdata[2], linkdata[3], savedlinktime);
- oncewait = true;
- } else {
- after = true;
- if(lanlink.numgbas==1){
- UPDATE_REG(0x122, linkdata[1]);
- UPDATE_REG(0x124, linkdata[2]);
- UPDATE_REG(0x126, linkdata[3]);
- if(linklog) fprintf(linklogfile, "%04x %04x %04x %04x %10u\n", linkdata[0], linkdata[1], linkdata[2], linkdata[3], savedlinktime);
- }
-
- }
- }
- }
- return;
- }
- // ** CRASH ** linkmem is NULL, todo investigate why, added null check
- if(linkid&&!transfer&&linkmem&&linktime>=linkmem->lastlinktime&&linkmem->numtransfers){
- linkmem->linkdata[linkid] = READ16LE(&ioMem[0x12a]);
-
- if(linkmem->numtransfers==1){
- linktime = 0;
- if(WaitForSingleObject(linksync[linkid], linktimeout)==WAIT_TIMEOUT) linkmem->numtransfers=0;
- } else linktime -= linkmem->lastlinktime;
-
- switch((linkmem->linkcmd[0])>>8){
- case 'M':
- tspeed = (linkmem->linkcmd[0]) & 3;
- transfer = 1;
- WRITE32LE(&ioMem[0x120], 0xffffffff);
- WRITE32LE(&ioMem[0x124], 0xffffffff);
- UPDATE_REG(0x128, READ16LE(&ioMem[0x128]) | 0x80);
- break;
- }
- }
-
- if(!transfer) return;
-
- if(transfer&&linktime>=trtimedata[transfer-1][tspeed]&&transfer<=linkmem->numgbas){
- if(transfer-linkid==2){
- SetEvent(linksync[linkid+1]);
- if(WaitForSingleObject(linksync[linkid], linktimeout)==WAIT_TIMEOUT)
- linkmem->numtransfers=0;
- ResetEvent(linksync[linkid]);
- if(linklog) fprintf(linklogfile, "%04x %04x %04x %04x %10u\n",
- linkmem->linkdata[0], linkmem->linkdata[1], linkmem->linkdata[2], linkmem->linkdata[3], linkmem->lastlinktime);
- }
-
-
- UPDATE_REG(0x11e + (transfer<<1), linkmem->linkdata[transfer-1]);
- transfer++;
- }
-
- if(transfer&&linktime>=trtimeend[linkmem->numgbas-2][tspeed]){
- if(linkid==linkmem->numgbas-1){
- SetEvent(linksync[0]);
- if(WaitForSingleObject(linksync[linkid], linktimeout)==WAIT_TIMEOUT)
- linkmem->numtransfers=0;
- ResetEvent(linksync[linkid]);
- if(linklog) fprintf(linklogfile, "%04x %04x %04x %04x %10u\n",
- linkmem->linkdata[0], linkmem->linkdata[1], linkmem->linkdata[2], linkmem->linkdata[3], linkmem->lastlinktime);
- }
- transfer = 0;
- linktime -= trtimeend[0][tspeed];
- if(READ16LE(&ioMem[0x128]) & 0x4000){
- IF |= 0x80;
- UPDATE_REG(0x202, IF);
- }
- UPDATE_REG(0x128, (READ16LE(&ioMem[0x128]) & 0xff0f) | (linkid << 4));
- linkmem->linkdata[linkid] = 0xffff;
- }
-
- return;
-}
-
-inline int GetSioMode(u16 reg1, u16 reg2){
- if(!(reg2&0x8000)){
- switch(reg1&0x3000){
- case 0x0000:
- return NORMAL8;
- case 0x1000:
- return NORMAL32;
- case 0x2000:
- return MULTIPLAYER;
- case 0x3000:
- return UART;
- }
- }
- if(reg2&0x4000) return JOYBUS;
- return GP;
-}
-
-u16 StartRFU(u16 value){
- switch(GetSioMode(value, READ16LE(&ioMem[0x134]))){
- case NORMAL8:
- rfu_polarity = 0;
- return value;
- break;
- case NORMAL32:
- if(value&8) value &= 0xfffb; // A kind of acknowledge procedure
- else value |= 4;
- if(value&0x80){
- if((value&3)==1) transferend = 2048;
- else transferend = 256;
- u16 a = READ16LE(&ioMem[0x122]);
- switch(rfu_state){
- case RFU_INIT:
- if(READ32LE(&ioMem[0x120])==0xb0bb8001){
- rfu_state = RFU_COMM; // end of startup
- }
- UPDATE_REG(0x122, READ16LE(&ioMem[0x120]));
- UPDATE_REG(0x120, a);
- break;
- case RFU_COMM:
- if(a==0x9966){
- rfu_cmd = ioMem[0x120];
- if((rfu_qsend=ioMem[0x121])!=0){
- rfu_state = RFU_SEND;
- counter = 0;
- }
- if(rfu_cmd==0x25||rfu_cmd==0x24){
- linkmem->rfu_q[vbaid] = rfu_qsend;
- }
- UPDATE_REG(0x120, 0);
- UPDATE_REG(0x122, 0x8000);
- } else if(a==0x8000){
- switch(rfu_cmd){
- case 0x1a: // check if someone joined
- if(linkmem->rfu_request[vbaid]!=0){
- rfu_state = RFU_RECV;
- rfu_qrecv = 1;
- }
- linkid = -1;
- rfu_cmd |= 0x80;
- break;
- case 0x1e: // receive broadcast data
- case 0x1d: // no visible difference
- rfu_polarity = 0;
- rfu_state = RFU_RECV;
- rfu_qrecv = 7;
- counter = 0;
- rfu_cmd |= 0x80;
- break;
- case 0x30:
- linkmem->rfu_request[vbaid] = 0;
- linkmem->rfu_q[vbaid] = 0;
- linkid = 0;
- numtransfers = 0;
- rfu_cmd |= 0x80;
- if(linkmem->numgbas==2) SetEvent(linksync[1-vbaid]);
- break;
- case 0x11: // ? always receives 0xff - I suspect it's something for 3+ players
- case 0x13: // unknown
- case 0x20: // this has something to do with 0x1f
- case 0x21: // this too
- rfu_cmd |= 0x80;
- rfu_polarity = 0;
- rfu_state = 3;
- rfu_qrecv = 1;
- break;
- case 0x26:
- if(linkid>0){
- rfu_qrecv = rfu_masterq;
- }
- if((rfu_qrecv=linkmem->rfu_q[1-vbaid])!=0){
- rfu_state = RFU_RECV;
- counter = 0;
- }
- rfu_cmd |= 0x80;
- break;
- case 0x24: // send data
- if((numtransfers++)==0) linktime = 1;
- linkmem->rfu_linktime[vbaid] = linktime;
- if(linkmem->numgbas==2){
- SetEvent(linksync[1-vbaid]);
- WaitForSingleObject(linksync[vbaid], linktimeout);
- ResetEvent(linksync[vbaid]);
- }
- rfu_cmd |= 0x80;
- linktime = 0;
- linkid = -1;
- break;
- case 0x25: // send & wait for data
- case 0x1f: // pick a server
- case 0x10: // init
- case 0x16: // send broadcast data
- case 0x17: // setup or something ?
- case 0x27: // wait for data ?
- case 0x3d: // init
- default:
- rfu_cmd |= 0x80;
- break;
- case 0xa5: // 2nd part of send&wait function 0x25
- case 0xa7: // 2nd part of wait function 0x27
- if(linkid==-1){
- linkid++;
- linkmem->rfu_linktime[vbaid] = 0;
- }
- if(linkid&&linkmem->rfu_request[1-vbaid]==0){
- linkmem->rfu_q[1-vbaid] = 0;
- transferend = 256;
- rfu_polarity = 1;
- rfu_cmd = 0x29;
- linktime = 0;
- break;
- }
- if((numtransfers++)==0) linktime = 0;
- linkmem->rfu_linktime[vbaid] = linktime;
- if(linkmem->numgbas==2){
- if(!linkid||(linkid&&numtransfers)) SetEvent(linksync[1-vbaid]);
- WaitForSingleObject(linksync[vbaid], linktimeout);
- ResetEvent(linksync[vbaid]);
- }
- if(linkid>0){
- memcpy(rfu_masterdata, linkmem->rfu_data[1-vbaid], 128);
- rfu_masterq = linkmem->rfu_q[1-vbaid];
- }
- transferend = linkmem->rfu_linktime[1-vbaid] - linktime + 256;
- if(transferend<256) transferend = 256;
- linktime = -transferend;
- rfu_polarity = 1;
- rfu_cmd = 0x28;
- break;
- }
- UPDATE_REG(0x122, 0x9966);
- UPDATE_REG(0x120, (rfu_qrecv<<8) | rfu_cmd);
- } else {
- UPDATE_REG(0x120, 0);
- UPDATE_REG(0x122, 0x8000);
- }
- break;
- case RFU_SEND:
- if(--rfu_qsend==0) rfu_state = RFU_COMM;
- switch(rfu_cmd){
- case 0x16:
- linkmem->rfu_bdata[vbaid][counter++] = READ32LE(&ioMem[0x120]);
- break;
- case 0x17:
- linkid = 1;
- break;
- case 0x1f:
- linkmem->rfu_request[1-vbaid] = 1;
- break;
- case 0x24:
- case 0x25:
- linkmem->rfu_data[vbaid][counter++] = READ32LE(&ioMem[0x120]);
- break;
- }
- UPDATE_REG(0x120, 0);
- UPDATE_REG(0x122, 0x8000);
- break;
- case RFU_RECV:
- if(--rfu_qrecv==0) rfu_state = RFU_COMM;
- switch(rfu_cmd){
- case 0x9d:
- case 0x9e:
- if(counter==0){
- UPDATE_REG(0x120, 0x61f1);
- UPDATE_REG(0x122, 0);
- counter++;
- break;
- }
- UPDATE_REG(0x120, linkmem->rfu_bdata[1-vbaid][counter-1]&0xffff);
- UPDATE_REG(0x122, linkmem->rfu_bdata[1-vbaid][counter-1]>>16);
- counter++;
- break;
- case 0xa6:
- if(linkid>0){
- UPDATE_REG(0x120, rfu_masterdata[counter]&0xffff);
- UPDATE_REG(0x122, rfu_masterdata[counter++]>>16);
- } else {
- UPDATE_REG(0x120, linkmem->rfu_data[1-vbaid][counter]&0xffff);
- UPDATE_REG(0x122, linkmem->rfu_data[1-vbaid][counter++]>>16);
- }
- break;
- case 0x93: // it seems like the game doesn't care about this value
- UPDATE_REG(0x120, 0x1234); // put anything in here
- UPDATE_REG(0x122, 0x0200); // also here, but it should be 0200
- break;
- case 0xa0:
- case 0xa1:
- UPDATE_REG(0x120, 0x641b);
- UPDATE_REG(0x122, 0x0000);
- break;
- case 0x9a:
- UPDATE_REG(0x120, 0x61f9);
- UPDATE_REG(0x122, 0);
- break;
- case 0x91:
- UPDATE_REG(0x120, 0x00ff);
- UPDATE_REG(0x122, 0x0000);
- break;
- default:
- UPDATE_REG(0x120, 0x0173);
- UPDATE_REG(0x122, 0x0000);
- break;
- }
- break;
- }
- transfer = 1;
- }
- if(rfu_polarity) value ^= 4; // sometimes it's the other way around
- default:
- return value;
- }
-}
-
-void gbLinkStart(u8 value){
-// Not in this version :-)
-}
-
-
-void gbLinkUpdate(void){
-}
-
-int InitLink(void){
- WSADATA wsadata;
- BOOL disable = true;
-
- linkid = 0;
-
- if(WSAStartup(MAKEWORD(1,1), &wsadata)!=0){
- WSACleanup();
- return 0;
- }
-
- if((lanlink.tcpsocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET){
- MessageBox(NULL, "Couldn't create socket.", "Error!", MB_OK);
- WSACleanup();
- return 0;
- }
-
- setsockopt(lanlink.tcpsocket, IPPROTO_TCP, TCP_NODELAY, (char*)&disable, sizeof(BOOL));
-
- if((mmf=CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(LINKDATA), "VBA link memory"))==NULL){
- closesocket(lanlink.tcpsocket);
- WSACleanup();
- MessageBox(NULL, "Error creating file mapping", "Error", MB_OK|MB_ICONEXCLAMATION);
- return 0;
- }
-
- if(GetLastError() == ERROR_ALREADY_EXISTS)
- vbaid = 1;
- else
- vbaid = 0;
-
- if((linkmem=(LINKDATA *)MapViewOfFile(mmf, FILE_MAP_WRITE, 0, 0, sizeof(LINKDATA)))==NULL){
- closesocket(lanlink.tcpsocket);
- WSACleanup();
- CloseHandle(mmf);
- MessageBox(NULL, "Error mapping file", "Error", MB_OK|MB_ICONEXCLAMATION);
- return 0;
- }
-
- if(linkmem->linkflags&LINK_PARENTLOST)
- vbaid = 0;
-
- if(vbaid==0){
- linkid = 0;
- if(linkmem->linkflags&LINK_PARENTLOST){
- linkmem->numgbas++;
- linkmem->linkflags &= ~LINK_PARENTLOST;
- }
- else
- linkmem->numgbas=1;
-
- for(i=0;i<4;i++){
- linkevent[15]=(char)i+'1';
- if((linksync[i]=CreateEvent(NULL, true, false, linkevent))==NULL){
- closesocket(lanlink.tcpsocket);
- WSACleanup();
- UnmapViewOfFile(linkmem);
- CloseHandle(mmf);
- for(j=0;jnumgbas;
- linkid = vbaid;
- linkmem->numgbas++;
-
- linklog = 0;
- if(linkmem->numgbas>4){
- linkmem->numgbas=4;
- closesocket(lanlink.tcpsocket);
- WSACleanup();
- MessageBox(NULL, "5 or more GBAs not supported.", "Error!", MB_OK|MB_ICONEXCLAMATION);
- UnmapViewOfFile(linkmem);
- CloseHandle(mmf);
- return 0;
- }
- for(i=0;i<4;i++){
- linkevent[15]=(char)i+'1';
- if((linksync[i]=OpenEvent(EVENT_ALL_ACCESS, false, linkevent))==NULL){
- closesocket(lanlink.tcpsocket);
- WSACleanup();
- CloseHandle(mmf);
- UnmapViewOfFile(linkmem);
- for(j=0;jlastlinktime=0xffffffff;
- linkmem->numtransfers=0;
- linkmem->linkflags=0;
- lanlink.connected = false;
- lanlink.thread = NULL;
- lanlink.speed = false;
- for(i=0;i<4;i++){
- linkmem->linkdata[i] = 0xffff;
- linkdata[i] = 0xffff;
- }
-return 1;
-}
-
-int openLinkLog(void){
- char filename[20];
- if(linklog){
- sprintf(filename, "vbalog%1d.txt", vbaid+1);
- if((linklogfile=fopen(filename, "at"))==NULL){
- linklog=false;
- return 0;
- }
- fprintf(linklogfile, "----- Log opened -----\n");
- }
- return 1;
-}
-
-void closeLinkLog()
-{
- if(linklogfile)
- {
- fclose(linklogfile);
- linklogfile=NULL;
- }
-}
-
-void CloseLink(void){
- if(lanlink.connected){
- if(linkid){
- char outbuffer[4];
- outbuffer[0] = 4;
- outbuffer[1] = -32;
- if(lanlink.type==0) send(lanlink.tcpsocket, outbuffer, 4, 0);
- } else {
- char outbuffer[12];
- int i;
- outbuffer[0] = 12;
- outbuffer[1] = -32;
- for(i=1;i<=lanlink.numgbas;i++){
- if(lanlink.type==0){
- send(ls.tcpsocket[i], outbuffer, 12, 0);
- }
- closesocket(ls.tcpsocket[i]);
- }
- }
- }
- linkmem->numgbas--;
- if(!linkid&&linkmem->numgbas!=0)
- linkmem->linkflags|=LINK_PARENTLOST;
- CloseHandle(mmf);
- UnmapViewOfFile(linkmem);
-
- for(i=0;i<4;i++){
- if(linksync[i]!=NULL){
- PulseEvent(linksync[i]);
- CloseHandle(linksync[i]);
- }
- }
- regSetDwordValue("LAN", lanlink.active);
- if(linklog) closeLinkLog();
- closesocket(lanlink.tcpsocket);
- WSACleanup();
-return;
-}
-
-lserver::lserver(void){
- intinbuffer = (int*)inbuffer;
- u16inbuffer = (u16*)inbuffer;
- intoutbuffer = (int*)outbuffer;
- u16outbuffer = (u16*)outbuffer;
- oncewait = false;
-}
-
-int lserver::Init(void *serverdlg){
- SOCKADDR_IN info;
- DWORD nothing;
- char str[100];
-
- info.sin_family = AF_INET;
- info.sin_addr.S_un.S_addr = INADDR_ANY;
- info.sin_port = htons(5738);
-
- if(bind(lanlink.tcpsocket, (LPSOCKADDR)&info, sizeof(SOCKADDR_IN))==SOCKET_ERROR){
- closesocket(lanlink.tcpsocket);
- if((lanlink.tcpsocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET)
- return WSAGetLastError();
- if(bind(lanlink.tcpsocket, (LPSOCKADDR)&info, sizeof(SOCKADDR_IN))==SOCKET_ERROR)
- return WSAGetLastError();
- }
-
- if(listen(lanlink.tcpsocket, lanlink.numgbas)==SOCKET_ERROR)
- return WSAGetLastError();
-
- if(lanlink.thread!=NULL){
- lanlink.terminate = true;
- WaitForSingleObject(linksync[vbaid], 500);
- lanlink.thread = NULL;
- }
- lanlink.terminate = false;
- linkid = 0;
-
- gethostname(str, 100);
- ((ServerWait*)serverdlg)->m_serveraddress.Format("Server IP address is: %s", inet_ntoa(*(LPIN_ADDR)(gethostbyname(str)->h_addr_list[0])));
-
- lanlink.thread = CreateThread(NULL, 0, LinkServerThread, serverdlg, 0, ¬hing);
-
- return 0;
-
-}
-
-DWORD WINAPI LinkServerThread(void *serverdlg){
- fd_set fdset;
- timeval wsocktimeout;
- char inbuffer[256], outbuffer[256];
- int *intinbuffer = (int*)inbuffer;
- u16 *u16inbuffer = (u16*)inbuffer;
- int *intoutbuffer = (int*)outbuffer;
- u16 *u16outbuffer = (u16*)outbuffer;
- BOOL disable = true;
-
- wsocktimeout.tv_sec = 1;
- wsocktimeout.tv_usec = 0;
- i = 0;
-
- while(im_plconn[i].Format("Player %d connected", i+1);
- ((ServerWait*)serverdlg)->UpdateData(false);
- i++;
- }
- }
- ((ServerWait*)serverdlg)->m_prgctrl.StepIt();
- }
- MessageBox(NULL, "All players connected", "Link", MB_OK);
- ((ServerWait*)serverdlg)->SendMessage(WM_CLOSE, 0, 0);
-
- for(i=1;i<=lanlink.numgbas;i++){
- outbuffer[0] = 4;
- send(ls.tcpsocket[i], outbuffer, 4, 0);
- }
-
- lanlink.connected = true;
-
- return 0;
-}
-
-void lserver::Send(void){
- if(lanlink.type==0){ // TCP
- if(savedlinktime==-1){
- outbuffer[0] = 4;
- outbuffer[1] = -32; //0xe0
- for(i=1;i<=lanlink.numgbas;i++){
- send(tcpsocket[i], outbuffer, 4, 0);
- recv(tcpsocket[i], inbuffer, 4, 0);
- }
- }
- outbuffer[1] = tspeed;
- u16outbuffer[1] = linkdata[0];
- intoutbuffer[1] = savedlinktime;
- if(lanlink.numgbas==1){
- if(lanlink.type==0){
- outbuffer[0] = 8;
- send(tcpsocket[1], outbuffer, 8, 0);
- }
- }
- else if(lanlink.numgbas==2){
- u16outbuffer[4] = linkdata[2];
- if(lanlink.type==0){
- outbuffer[0] = 10;
- send(tcpsocket[1], outbuffer, 10, 0);
- u16outbuffer[4] = linkdata[1];
- send(tcpsocket[2], outbuffer, 10, 0);
- }
- } else {
- if(lanlink.type==0){
- outbuffer[0] = 12;
- u16outbuffer[4] = linkdata[2];
- u16outbuffer[5] = linkdata[3];
- send(tcpsocket[1], outbuffer, 12, 0);
- u16outbuffer[4] = linkdata[1];
- send(tcpsocket[2], outbuffer, 12, 0);
- u16outbuffer[5] = linkdata[2];
- send(tcpsocket[3], outbuffer, 12, 0);
- }
- }
- }
- return;
-}
-
-void lserver::Recv(void){
- int numbytes;
- if(lanlink.type==0){ // TCP
- wsocktimeout.tv_usec = 0;
- wsocktimeout.tv_sec = linktimeout / 1000;
- fdset.fd_count = lanlink.numgbas;
- for(i=0;i1) memcpy(inbuffer, inbuffer+inbuffer[0]*(howmanytimes-1), inbuffer[0]);
- if(inbuffer[1]==-32){
- char message[30];
- lanlink.connected = false;
- sprintf(message, "Player %d disconnected.", i+2);
- MessageBox(NULL, message, "Link", MB_OK);
- outbuffer[0] = 4;
- outbuffer[1] = -32;
- for(i=1;ih_addr_list);
-
- if(ioctlsocket(lanlink.tcpsocket, FIONBIO, ¬block)==SOCKET_ERROR)
- return WSAGetLastError();
-
- if(lanlink.thread!=NULL){
- lanlink.terminate = true;
- WaitForSingleObject(linksync[vbaid], 500);
- lanlink.thread = NULL;
- }
-
- ((ServerWait*)waitdlg)->SetWindowText("Connecting...");
- lanlink.terminate = false;
- lanlink.thread = CreateThread(NULL, 0, LinkClientThread, waitdlg, 0, ¬hing);
- return 0;
-}
-
-DWORD WINAPI LinkClientThread(void *waitdlg){
- fd_set fdset;
- timeval wsocktimeout;
- int numbytes;
- char inbuffer[16];
- u16 *u16inbuffer = (u16*)inbuffer;
- unsigned long block = 0;
-
- if(connect(lanlink.tcpsocket, (LPSOCKADDR)&lc.serverinfo, sizeof(SOCKADDR_IN))==SOCKET_ERROR){
- if(WSAGetLastError()!=WSAEWOULDBLOCK){
- MessageBox(NULL, "Couldn't connect to server.", "Link", MB_OK);
- return 1;
- }
- wsocktimeout.tv_sec = 1;
- wsocktimeout.tv_usec = 0;
- do{
- if(lanlink.terminate) return 0;
- fdset.fd_count = 1;
- fdset.fd_array[0] = lanlink.tcpsocket;
- ((ServerWait*)waitdlg)->m_prgctrl.StepIt();
- } while(select(0, NULL, &fdset, NULL, &wsocktimeout)!=1&&connect(lanlink.tcpsocket, (LPSOCKADDR)&lc.serverinfo, sizeof(SOCKADDR_IN))!=0);
- }
-
- ioctlsocket(lanlink.tcpsocket, FIONBIO, &block);
-
- numbytes = 0;
- while(numbytes<4)
- numbytes += recv(lanlink.tcpsocket, inbuffer+numbytes, 16, 0);
- linkid = (int)u16inbuffer[0];
- lanlink.numgbas = (int)u16inbuffer[1];
-
- ((ServerWait*)waitdlg)->m_serveraddress.Format("Connected as #%d", linkid+1);
- if(lanlink.numgbas!=linkid) ((ServerWait*)waitdlg)->m_plconn[0].Format("Waiting for %d players to join", lanlink.numgbas-linkid);
- else ((ServerWait*)waitdlg)->m_plconn[0].Format("All players joined.");
-
- numbytes = 0;
- inbuffer[0] = 1;
- while(numbytesSendMessage(WM_CLOSE, 0, 0);
-
- block = 1;
-
- ioctlsocket(lanlink.tcpsocket, FIONBIO, &block);
-
- lanlink.connected = true;
- return 0;
-}
-
-void lclient::CheckConn(void){
- if((numbytes=recv(lanlink.tcpsocket, inbuffer, 256, 0))>0){
- while(numbytes
-
-#ifndef LINKH
-#define LINKH
-#define LINK_PARENTLOST 0x80
-#define UNSUPPORTED -1
-#define MULTIPLAYER 0
-#define NORMAL8 1
-#define NORMAL32 2
-#define UART 3
-#define JOYBUS 4
-#define GP 5
-#define RFU_INIT 0
-#define RFU_COMM 1
-#define RFU_SEND 2
-#define RFU_RECV 3
-
-typedef struct {
- WORD linkdata[4];
- WORD linkcmd[4];
- WORD numtransfers;
- int lastlinktime;
- unsigned char numgbas;
- unsigned char linkflags;
- int rfu_q[4];
- u8 rfu_request[4];
- int rfu_linktime[4];
- u32 rfu_bdata[4][7];
- u32 rfu_data[4][32];
-} LINKDATA;
-
-class lserver{
- int numbytes;
- fd_set fdset;
- timeval wsocktimeout;
- //timeval udptimeout;
- char inbuffer[256], outbuffer[256];
- int *intinbuffer;
- u16 *u16inbuffer;
- int *intoutbuffer;
- u16 *u16outbuffer;
- int counter;
- int done;
-public:
- int howmanytimes;
- SOCKET tcpsocket[4];
- SOCKADDR_IN udpaddr[4];
- lserver(void);
- int Init(void*);
- void Send(void);
- void Recv(void);
-};
-
-class lclient{
- fd_set fdset;
- timeval wsocktimeout;
- char inbuffer[256], outbuffer[256];
- int *intinbuffer;
- u16 *u16inbuffer;
- int *intoutbuffer;
- u16 *u16outbuffer;
- int numbytes;
-public:
- bool oncesend;
- SOCKADDR_IN serverinfo;
- SOCKET noblock;
- int numtransfers;
- lclient(void);
- int Init(LPHOSTENT, void*);
- void Send(void);
- void Recv(void);
- void CheckConn(void);
-};
-
-typedef struct {
- SOCKET tcpsocket;
- //SOCKET udpsocket;
- int numgbas;
- HANDLE thread;
- u8 type;
- u8 server;
- bool terminate;
- bool connected;
- bool speed;
- bool active;
-} LANLINKDATA;
-
-extern void LinkUpdate(void);
-extern void LinkChildStop(void);
-extern void LinkChildSend(u16);
-extern int openLinkLog(void);
-extern void closeLinkLog();
-extern void CloseLanLink(void);
-extern char *MakeInstanceFilename(const char *Input);
-
-extern LANLINKDATA lanlink;
-extern FILE *linklogfile;
-extern int vbaid;
-extern int linklog;
-extern bool adapter;
-extern bool linkenable;
-extern int linktimeout;
-extern lclient lc;
-extern int linkid;
-
-#endif
diff --git a/src/Mode0.cpp b/src/Mode0.cpp
index 1f5ed2e4..adf7d2bc 100644
--- a/src/Mode0.cpp
+++ b/src/Mode0.cpp
@@ -16,9 +16,9 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Globals.h"
-#include "Gfx.h"
+#include "agb/GBAGfx.h"
void mode0RenderLine()
{
diff --git a/src/Mode1.cpp b/src/Mode1.cpp
index 85f30383..954fabb9 100644
--- a/src/Mode1.cpp
+++ b/src/Mode1.cpp
@@ -16,9 +16,9 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Globals.h"
-#include "Gfx.h"
+#include "agb/GBAGfx.h"
void mode1RenderLine()
{
diff --git a/src/Mode2.cpp b/src/Mode2.cpp
index 132be0cd..e8b67857 100644
--- a/src/Mode2.cpp
+++ b/src/Mode2.cpp
@@ -16,9 +16,9 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Globals.h"
-#include "Gfx.h"
+#include "agb/GBAGfx.h"
void mode2RenderLine()
{
diff --git a/src/Mode3.cpp b/src/Mode3.cpp
index 6dd2067f..8047aee0 100644
--- a/src/Mode3.cpp
+++ b/src/Mode3.cpp
@@ -16,9 +16,9 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Globals.h"
-#include "Gfx.h"
+#include "agb/GBAGfx.h"
void mode3RenderLine()
{
diff --git a/src/Mode4.cpp b/src/Mode4.cpp
index 4b6d3e8d..d4766bf8 100644
--- a/src/Mode4.cpp
+++ b/src/Mode4.cpp
@@ -16,8 +16,8 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "GBA.h"
-#include "Gfx.h"
+#include "agb/GBA.h"
+#include "agb/GBAGfx.h"
#include "Globals.h"
void mode4RenderLine()
diff --git a/src/Mode5.cpp b/src/Mode5.cpp
index a2378e1a..65ae69ea 100644
--- a/src/Mode5.cpp
+++ b/src/Mode5.cpp
@@ -16,9 +16,9 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Globals.h"
-#include "Gfx.h"
+#include "agb/GBAGfx.h"
void mode5RenderLine()
{
diff --git a/src/RTC.cpp b/src/RTC.cpp
index 042ffb3c..9fc6d9e7 100644
--- a/src/RTC.cpp
+++ b/src/RTC.cpp
@@ -17,7 +17,7 @@
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "System.h"
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Globals.h"
#include "Port.h"
#include "Util.h"
diff --git a/src/Sound.cpp b/src/Sound.cpp
index 38b831fe..7992bdb2 100644
--- a/src/Sound.cpp
+++ b/src/Sound.cpp
@@ -22,13 +22,13 @@
#include "Sound.h"
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Globals.h"
#include "Util.h"
#include "Port.h"
-#include "gb/gb_apu/Gb_Apu.h"
-#include "gb/gb_apu/Multi_Buffer.h"
+#include "dmg/gb_apu/Gb_Apu.h"
+#include "dmg/gb_apu/Multi_Buffer.h"
extern bool stopState; // TODO: silence sound when true
diff --git a/src/Sram.cpp b/src/Sram.cpp
index 46e7108b..33cd8bf0 100644
--- a/src/Sram.cpp
+++ b/src/Sram.cpp
@@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Globals.h"
#include "Flash.h"
#include "Sram.h"
diff --git a/src/Util.cpp b/src/Util.cpp
index 4fd06b5b..44f98633 100644
--- a/src/Util.cpp
+++ b/src/Util.cpp
@@ -29,7 +29,7 @@ extern "C" {
#include "NLS.h"
#include "Util.h"
#include "Flash.h"
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Globals.h"
#include "RTC.h"
#include "Port.h"
diff --git a/src/agb/placeholder.txt b/src/agb/placeholder.txt
deleted file mode 100644
index 595686eb..00000000
--- a/src/agb/placeholder.txt
+++ /dev/null
@@ -1 +0,0 @@
-AGB files will go here once src folder is cleaned up.
\ No newline at end of file
diff --git a/src/agbprint.cpp b/src/agbprint.cpp
deleted file mode 100644
index 9b3ba566..00000000
--- a/src/agbprint.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
-// Copyright (C) 1999-2003 Forgotten
-// Copyright (C) 2004 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 "GBA.h"
-#include "Globals.h"
-#include "Port.h"
-
-#define debuggerWriteHalfWord(addr, value) \
- WRITE16LE((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask], (value))
-
-#define debuggerReadHalfWord(addr) \
- READ16LE(((u16*)&map[(addr)>>24].address[(addr) & map[(addr)>>24].mask]))
-
-static bool agbPrintEnabled = false;
-static bool agbPrintProtect = false;
-
-bool agbPrintWrite(u32 address, u16 value)
-{
- if(agbPrintEnabled) {
- if(address == 0x9fe2ffe) { // protect
- agbPrintProtect = (value != 0);
- debuggerWriteHalfWord(address, value);
- return true;
- } else {
- if(agbPrintProtect &&
- ((address >= 0x9fe20f8 && address <= 0x9fe20ff) // control structure
- || (address >= 0x8fd0000 && address <= 0x8fdffff)
- || (address >= 0x9fd0000 && address <= 0x9fdffff))) {
- debuggerWriteHalfWord(address, value);
- return true;
- }
- }
- }
- return false;
-}
-
-void agbPrintReset()
-{
- agbPrintProtect = false;
-}
-
-void agbPrintEnable(bool enable)
-{
- agbPrintEnabled = enable;
-}
-
-bool agbPrintIsEnabled()
-{
- return agbPrintEnabled;
-}
-
-extern void (*dbgOutput)(const char *, u32);
-
-void agbPrintFlush()
-{
- u16 get = debuggerReadHalfWord(0x9fe20fc);
- u16 put = debuggerReadHalfWord(0x9fe20fe);
-
- u32 address = (debuggerReadHalfWord(0x9fe20fa) << 16);
- if(address != 0xfd0000 && address != 0x1fd0000) {
- dbgOutput("Did you forget to call AGBPrintInit?\n", 0);
- // get rid of the text otherwise we will continue to be called
- debuggerWriteHalfWord(0x9fe20fc, put);
- return;
- }
-
- u8 *data = &rom[address];
-
- while(get != put) {
- char c = data[get++];
- char s[2];
- s[0] = c;
- s[1] = 0;
-
- if(systemVerbose & VERBOSE_AGBPRINT)
- dbgOutput(s, 0);
- if(c == '\n')
- break;
- }
- debuggerWriteHalfWord(0x9fe20fc, get);
-}
diff --git a/src/agbprint.h b/src/agbprint.h
deleted file mode 100644
index d7742dee..00000000
--- a/src/agbprint.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// -*- C++ -*-
-// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
-// Copyright (C) 1999-2003 Forgotten
-// Copyright (C) 2004 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_AGBPRINT_H
-#define VBA_AGBPRINT_H
-extern void agbPrintEnable(bool);
-extern bool agbPrintIsEnabled();
-extern void agbPrintReset();
-extern bool agbPrintWrite(u32, u16);
-extern void agbPrintFlush();
-#endif
diff --git a/src/armdis.cpp b/src/armdis.cpp
index b7517f4e..e1b9b58e 100644
--- a/src/armdis.cpp
+++ b/src/armdis.cpp
@@ -23,7 +23,7 @@
#include "System.h"
#include "Port.h"
-#include "GBA.h"
+#include "agb/GBA.h"
#include "armdis.h"
#include "elf.h"
diff --git a/src/bios.cpp b/src/bios.cpp
index 7fa2a0d2..68c74c03 100644
--- a/src/bios.cpp
+++ b/src/bios.cpp
@@ -20,9 +20,9 @@
#include
#include
-#include "GBA.h"
+#include "agb/GBA.h"
#include "bios.h"
-#include "GBAinline.h"
+#include "agb/GBAinline.h"
#include "Globals.h"
s16 sineTable[256] = {
diff --git a/src/dmg/gbGfx.cpp b/src/dmg/gbGfx.cpp
index c31a85a5..59f36868 100644
--- a/src/dmg/gbGfx.cpp
+++ b/src/dmg/gbGfx.cpp
@@ -18,7 +18,7 @@
#include
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "gbGlobals.h"
#include "gbSGB.h"
diff --git a/src/dmg/gbGlobals.cpp b/src/dmg/gbGlobals.cpp
index 6bcf339b..0bbc3ecc 100644
--- a/src/dmg/gbGlobals.cpp
+++ b/src/dmg/gbGlobals.cpp
@@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "../GBA.h"
+#include "../agb/GBA.h"
u8 *gbMemoryMap[16];
diff --git a/src/dmg/gbMemory.cpp b/src/dmg/gbMemory.cpp
index 82c43109..0670bcdf 100644
--- a/src/dmg/gbMemory.cpp
+++ b/src/dmg/gbMemory.cpp
@@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Port.h"
#include "gbGlobals.h"
#include "gbMemory.h"
diff --git a/src/dmg/gbPrinter.cpp b/src/dmg/gbPrinter.cpp
index ff525b24..3c2f2872 100644
--- a/src/dmg/gbPrinter.cpp
+++ b/src/dmg/gbPrinter.cpp
@@ -18,7 +18,7 @@
#include
#include
-#include "../GBA.h"
+#include "../agb/GBA.h"
u8 gbPrinterStatus = 0;
int gbPrinterState = 0;
diff --git a/src/elf.cpp b/src/elf.cpp
index 1521cadc..34326b5f 100644
--- a/src/elf.cpp
+++ b/src/elf.cpp
@@ -20,7 +20,7 @@
#include
#include
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Port.h"
#include "elf.h"
#include "NLS.h"
diff --git a/src/exprNode.cpp b/src/exprNode.cpp
index f7d8c64c..80e2d8e1 100644
--- a/src/exprNode.cpp
+++ b/src/exprNode.cpp
@@ -20,7 +20,7 @@
#include
#include
-#include "GBA.h"
+#include "agb/GBA.h"
#include "Port.h"
#include "elf.h"
#include "exprNode.h"
diff --git a/src/gbafilter.cpp b/src/gbafilter.cpp
deleted file mode 100644
index 1b5aee99..00000000
--- a/src/gbafilter.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-#include "gbafilter.h"
-
-#include
-
-extern int systemColorDepth;
-extern int systemRedShift;
-extern int systemGreenShift;
-extern int systemBlueShift;
-
-extern u16 systemColorMap16[0x10000];
-extern u32 systemColorMap32[0x10000];
-
-static const unsigned char curve[32] = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x10, 0x12,
- 0x14, 0x16, 0x18, 0x1c, 0x20, 0x28, 0x30, 0x38,
- 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x80,
- 0x88, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0};
-
-// output R G B
-static const unsigned char influence[3 * 3] = { 16, 4, 4, // red
- 8, 16, 8, // green
- 0, 8, 16};// blue
-
-inline void swap(short & a, short & b)
-{
- short temp = a;
- a = b;
- b = temp;
-}
-
-void gbafilter_pal(u16 * buf, int count)
-{
- short temp[3 * 3], s;
- unsigned pix;
- u8 red, green, blue;
-
- while (count--)
- {
- pix = *buf;
-
- s = curve[(pix >> systemGreenShift) & 0x1f];
- temp[3] = s * influence[3];
- temp[4] = s * influence[4];
- temp[5] = s * influence[5];
-
- s = curve[(pix >> systemRedShift) & 0x1f];
- temp[0] = s * influence[0];
- temp[1] = s * influence[1];
- temp[2] = s * influence[2];
-
- s = curve[(pix >> systemBlueShift) & 0x1f];
- temp[6] = s * influence[6];
- temp[7] = s * influence[7];
- temp[8] = s * influence[8];
-
- if (temp[0] < temp[3]) swap(temp[0], temp[3]);
- if (temp[0] < temp[6]) swap(temp[0], temp[6]);
- if (temp[3] < temp[6]) swap(temp[3], temp[6]);
- temp[3] <<= 1;
- temp[0] <<= 2;
- temp[0] += temp[3] + temp[6];
-
- red = ((int(temp[0]) * 160) >> 17) + 4;
- if (red > 31) red = 31;
-
- if (temp[2] < temp[5]) swap(temp[2], temp[5]);
- if (temp[2] < temp[8]) swap(temp[2], temp[8]);
- if (temp[5] < temp[8]) swap(temp[5], temp[8]);
- temp[5] <<= 1;
- temp[2] <<= 2;
- temp[2] += temp[5] + temp[8];
-
- blue = ((int(temp[2]) * 160) >> 17) + 4;
- if (blue > 31) blue = 31;
-
- if (temp[1] < temp[4]) swap(temp[1], temp[4]);
- if (temp[1] < temp[7]) swap(temp[1], temp[7]);
- if (temp[4] < temp[7]) swap(temp[4], temp[7]);
- temp[4] <<= 1;
- temp[1] <<= 2;
- temp[1] += temp[4] + temp[7];
-
- green = ((int(temp[1]) * 160) >> 17) + 4;
- if (green > 31) green = 31;
-
- pix = red << systemRedShift;
- pix += green << systemGreenShift;
- pix += blue << systemBlueShift;
-
- *buf++ = pix;
- }
-}
-
-void gbafilter_pal32(u32 * buf, int count)
-{
- short temp[3 * 3], s;
- unsigned pix;
- u8 red, green, blue;
-
- while (count--)
- {
- pix = *buf;
-
- s = curve[(pix >> systemGreenShift) & 0x1f];
- temp[3] = s * influence[3];
- temp[4] = s * influence[4];
- temp[5] = s * influence[5];
-
- s = curve[(pix >> systemRedShift) & 0x1f];
- temp[0] = s * influence[0];
- temp[1] = s * influence[1];
- temp[2] = s * influence[2];
-
- s = curve[(pix >> systemBlueShift) & 0x1f];
- temp[6] = s * influence[6];
- temp[7] = s * influence[7];
- temp[8] = s * influence[8];
-
- if (temp[0] < temp[3]) swap(temp[0], temp[3]);
- if (temp[0] < temp[6]) swap(temp[0], temp[6]);
- if (temp[3] < temp[6]) swap(temp[3], temp[6]);
- temp[3] <<= 1;
- temp[0] <<= 2;
- temp[0] += temp[3] + temp[6];
-
- //red = ((int(temp[0]) * 160) >> 17) + 4;
- red = ((int(temp[0]) * 160) >> 14) + 32;
-
- if (temp[2] < temp[5]) swap(temp[2], temp[5]);
- if (temp[2] < temp[8]) swap(temp[2], temp[8]);
- if (temp[5] < temp[8]) swap(temp[5], temp[8]);
- temp[5] <<= 1;
- temp[2] <<= 2;
- temp[2] += temp[5] + temp[8];
-
- //blue = ((int(temp[2]) * 160) >> 17) + 4;
- blue = ((int(temp[2]) * 160) >> 14) + 32;
-
- if (temp[1] < temp[4]) swap(temp[1], temp[4]);
- if (temp[1] < temp[7]) swap(temp[1], temp[7]);
- if (temp[4] < temp[7]) swap(temp[4], temp[7]);
- temp[4] <<= 1;
- temp[1] <<= 2;
- temp[1] += temp[4] + temp[7];
-
- //green = ((int(temp[1]) * 160) >> 17) + 4;
- green = ((int(temp[1]) * 160) >> 14) + 32;
-
- //pix = red << redshift;
- //pix += green << greenshift;
- //pix += blue << blueshift;
-
- pix = red << (systemRedShift - 3);
- pix += green << (systemGreenShift - 3);
- pix += blue << (systemBlueShift - 3);
-
- *buf++ = pix;
- }
-}
-
-// for palette mode to work with the three spoony filters in 32bpp depth
-
-void gbafilter_pad(u8 * buf, int count)
-{
- union
- {
- struct
- {
- u8 r;
- u8 g;
- u8 b;
- u8 a;
- } part;
- unsigned whole;
- }
- mask;
-
- mask.whole = 0x1f << systemRedShift;
- mask.whole += 0x1f << systemGreenShift;
- mask.whole += 0x1f << systemBlueShift;
-
- switch (systemColorDepth)
- {
- case 24:
- while (count--)
- {
- *buf++ &= mask.part.r;
- *buf++ &= mask.part.g;
- *buf++ &= mask.part.b;
- }
- break;
- case 32:
- while (count--)
- {
- *((u32*)buf) &= mask.whole;
- buf += 4;
- }
- }
-}
-
-/*
-void UpdateSystemColorMaps(int lcd)
-{
- switch(systemColorDepth) {
- case 16:
- {
- for(int i = 0; i < 0x10000; i++) {
- systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
- (((i & 0x3e0) >> 5) << systemGreenShift) |
- (((i & 0x7c00) >> 10) << systemBlueShift);
- }
- if (lcd == 1) gbafilter_pal(systemColorMap16, 0x10000);
- }
- break;
- case 24:
- case 32:
- {
- for(int i = 0; i < 0x10000; i++) {
- systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
- (((i & 0x3e0) >> 5) << systemGreenShift) |
- (((i & 0x7c00) >> 10) << systemBlueShift);
- }
- if (lcd == 1) gbafilter_pal32(systemColorMap32, 0x10000);
- }
- break;
- }
-}
-*/
diff --git a/src/gbafilter.h b/src/gbafilter.h
deleted file mode 100644
index f1d25daf..00000000
--- a/src/gbafilter.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "System.h"
-
-void gbafilter_pal(u16 * buf, int count);
-void gbafilter_pal32(u32 * buf, int count);
-void gbafilter_pad(u8 * buf, int count);
diff --git a/src/remote.cpp b/src/remote.cpp
index 0ae55c6d..54d82c91 100644
--- a/src/remote.cpp
+++ b/src/remote.cpp
@@ -42,7 +42,7 @@
# define write _write
#endif // _WIN32
-#include "GBA.h"
+#include "agb/GBA.h"
extern bool debugger;
extern void CPUUpdateCPSR();
diff --git a/src/win32/BugReport.cpp b/src/win32/BugReport.cpp
index adf38c53..d553e776 100644
--- a/src/win32/BugReport.cpp
+++ b/src/win32/BugReport.cpp
@@ -23,15 +23,15 @@
#include "vba.h"
#include "BugReport.h"
-#include "../agbprint.h"
+#include "../agb/agbprint.h"
#include "../AutoBuild.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../Port.h"
#include "../RTC.h"
#include "../Sound.h"
-#include "../gb/gbCheats.h"
-#include "../gb/gbGlobals.h"
+#include "../dmg/gbCheats.h"
+#include "../dmg/gbGlobals.h"
#ifdef _DEBUG
#define new DEBUG_NEW
diff --git a/src/win32/Direct3D.cpp b/src/win32/Direct3D.cpp
index 1cb4ed57..38ec4896 100644
--- a/src/win32/Direct3D.cpp
+++ b/src/win32/Direct3D.cpp
@@ -32,10 +32,10 @@
#include "FullscreenSettings.h"
#include "../System.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../Util.h"
-#include "../gb/gbGlobals.h"
+#include "../dmg/gbGlobals.h"
#include
diff --git a/src/win32/DirectSound.cpp b/src/win32/DirectSound.cpp
index 6b6d23c0..d486b9a3 100644
--- a/src/win32/DirectSound.cpp
+++ b/src/win32/DirectSound.cpp
@@ -27,7 +27,7 @@
// Internals
#include "../System.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../Sound.h"
diff --git a/src/win32/Disassemble.cpp b/src/win32/Disassemble.cpp
index 6023a1c7..463c0c07 100644
--- a/src/win32/Disassemble.cpp
+++ b/src/win32/Disassemble.cpp
@@ -25,7 +25,7 @@
#include "../System.h"
#include "../armdis.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#ifdef _DEBUG
diff --git a/src/win32/ExportGSASnapshot.cpp b/src/win32/ExportGSASnapshot.cpp
index fea7f00f..e5adc719 100644
--- a/src/win32/ExportGSASnapshot.cpp
+++ b/src/win32/ExportGSASnapshot.cpp
@@ -23,7 +23,7 @@
#include "vba.h"
#include "ExportGSASnapshot.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../NLS.h"
#ifdef _DEBUG
diff --git a/src/win32/GBACheats.cpp b/src/win32/GBACheats.cpp
index ae9ce33b..70588427 100644
--- a/src/win32/GBACheats.cpp
+++ b/src/win32/GBACheats.cpp
@@ -26,7 +26,7 @@
#include "../System.h"
#include "../Cheats.h"
#include "../CheatSearch.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "Reg.h"
diff --git a/src/win32/GBDisassemble.cpp b/src/win32/GBDisassemble.cpp
index b32a0ae7..a0ce5616 100644
--- a/src/win32/GBDisassemble.cpp
+++ b/src/win32/GBDisassemble.cpp
@@ -24,8 +24,8 @@
#include "GBDisassemble.h"
#include "../System.h"
-#include "../gb/GB.h"
-#include "../gb/gbGlobals.h"
+#include "../dmg/GB.h"
+#include "../dmg/gbGlobals.h"
#ifdef _DEBUG
#define new DEBUG_NEW
diff --git a/src/win32/GBMapView.cpp b/src/win32/GBMapView.cpp
index 59dcbbfc..d7dd800d 100644
--- a/src/win32/GBMapView.cpp
+++ b/src/win32/GBMapView.cpp
@@ -29,7 +29,7 @@
#include "../System.h"
#include "../NLS.h"
#include "../Util.h"
-#include "../gb/gbGlobals.h"
+#include "../dmg/gbGlobals.h"
extern "C" {
#include
diff --git a/src/win32/GBMemoryViewerDlg.cpp b/src/win32/GBMemoryViewerDlg.cpp
index 0a0a1ec2..73afd911 100644
--- a/src/win32/GBMemoryViewerDlg.cpp
+++ b/src/win32/GBMemoryViewerDlg.cpp
@@ -28,7 +28,7 @@
#include "WinResUtil.h"
#include "../System.h"
-#include "../gb/gbGlobals.h"
+#include "../dmg/gbGlobals.h"
#ifdef _DEBUG
#define new DEBUG_NEW
diff --git a/src/win32/GBOamView.cpp b/src/win32/GBOamView.cpp
index 4d0b876d..f4b90106 100644
--- a/src/win32/GBOamView.cpp
+++ b/src/win32/GBOamView.cpp
@@ -29,7 +29,7 @@
#include "../System.h"
#include "../NLS.h"
#include "../Util.h"
-#include "../gb/gbGlobals.h"
+#include "../dmg/gbGlobals.h"
extern "C" {
#include
diff --git a/src/win32/GBPaletteView.cpp b/src/win32/GBPaletteView.cpp
index 80fec688..ee92c498 100644
--- a/src/win32/GBPaletteView.cpp
+++ b/src/win32/GBPaletteView.cpp
@@ -26,7 +26,7 @@
#include "WinResUtil.h"
#include "../System.h"
-#include "../gb/gbGlobals.h"
+#include "../dmg/gbGlobals.h"
#ifdef _DEBUG
#define new DEBUG_NEW
diff --git a/src/win32/GBTileView.cpp b/src/win32/GBTileView.cpp
index 71ab1976..522f56c8 100644
--- a/src/win32/GBTileView.cpp
+++ b/src/win32/GBTileView.cpp
@@ -29,7 +29,7 @@
#include "../System.h"
#include "../NLS.h"
#include "../Util.h"
-#include "../gb/gbGlobals.h"
+#include "../dmg/gbGlobals.h"
extern "C" {
#include
diff --git a/src/win32/GameOverrides.cpp b/src/win32/GameOverrides.cpp
index 2ec84473..98cf1121 100644
--- a/src/win32/GameOverrides.cpp
+++ b/src/win32/GameOverrides.cpp
@@ -22,7 +22,7 @@
#include "stdafx.h"
#include "vba.h"
#include "GameOverrides.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#ifdef _DEBUG
#define new DEBUG_NEW
diff --git a/src/win32/IOViewer.cpp b/src/win32/IOViewer.cpp
index 1a96a0e5..933c580a 100644
--- a/src/win32/IOViewer.cpp
+++ b/src/win32/IOViewer.cpp
@@ -24,9 +24,9 @@
#include "IOViewer.h"
#include "../System.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
-#include "../GBAinline.h"
+#include "../agb/GBAinline.h"
#include "IOViewerRegs.h"
#ifdef _DEBUG
diff --git a/src/win32/LinkOptions.cpp b/src/win32/LinkOptions.cpp
index c76ddf3d..a4c9263f 100644
--- a/src/win32/LinkOptions.cpp
+++ b/src/win32/LinkOptions.cpp
@@ -4,7 +4,7 @@
#include "stdafx.h"
#include "vba.h"
#include "LinkOptions.h"
-#include "../Link.h"
+#include "../agb/GBALink.h"
extern int lspeed;
extern lserver ls;
diff --git a/src/win32/MainWnd.cpp b/src/win32/MainWnd.cpp
index 597f58db..dbe23a9a 100644
--- a/src/win32/MainWnd.cpp
+++ b/src/win32/MainWnd.cpp
@@ -34,17 +34,17 @@
#include "../System.h"
#include "../AutoBuild.h"
#include "../cheatSearch.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../Flash.h"
#include "../Globals.h"
-#include "../gb/GB.h"
-#include "../gb/gbCheats.h"
-#include "../gb/gbGlobals.h"
+#include "../dmg/GB.h"
+#include "../dmg/gbCheats.h"
+#include "../dmg/gbGlobals.h"
#include "../RTC.h"
#include "../Sound.h"
#include "../Util.h"
-#include "../Link.h"
+#include "../agb/GBALink.h"
#ifdef _DEBUG
#define new DEBUG_NEW
diff --git a/src/win32/MainWndCheats.cpp b/src/win32/MainWndCheats.cpp
index ebef9287..9b9f695b 100644
--- a/src/win32/MainWndCheats.cpp
+++ b/src/win32/MainWndCheats.cpp
@@ -25,9 +25,9 @@
#include "Reg.h"
#include "WinResUtil.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
-#include "../gb/gbCheats.h"
+#include "../dmg/gbCheats.h"
extern int emulating;
diff --git a/src/win32/MainWndFile.cpp b/src/win32/MainWndFile.cpp
index 3285ca79..f901fa9b 100644
--- a/src/win32/MainWndFile.cpp
+++ b/src/win32/MainWndFile.cpp
@@ -29,13 +29,13 @@
#include "WinResUtil.h"
#include "Logging.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../NLS.h"
#include "../Sound.h"
-#include "../gb/GB.h"
-#include "../gb/gbCheats.h"
-#include "../gb/gbGlobals.h"
+#include "../dmg/GB.h"
+#include "../dmg/gbCheats.h"
+#include "../dmg/gbGlobals.h"
extern int emulating;
diff --git a/src/win32/MainWndTools.cpp b/src/win32/MainWndTools.cpp
index dca7de13..91d9694d 100644
--- a/src/win32/MainWndTools.cpp
+++ b/src/win32/MainWndTools.cpp
@@ -41,7 +41,7 @@
#include "WinResUtil.h"
#include "Logging.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../Sound.h"
diff --git a/src/win32/MapView.cpp b/src/win32/MapView.cpp
index f93e755b..cd696168 100644
--- a/src/win32/MapView.cpp
+++ b/src/win32/MapView.cpp
@@ -27,7 +27,7 @@
#include "WinResUtil.h"
#include "../System.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../NLS.h"
#include "../Util.h"
diff --git a/src/win32/MemoryViewerDlg.cpp b/src/win32/MemoryViewerDlg.cpp
index 35e86a5f..9109f943 100644
--- a/src/win32/MemoryViewerDlg.cpp
+++ b/src/win32/MemoryViewerDlg.cpp
@@ -28,7 +28,7 @@
#include "WinResUtil.h"
#include "../System.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#ifdef _DEBUG
diff --git a/src/win32/OamView.cpp b/src/win32/OamView.cpp
index 2f1a417c..b96625d7 100644
--- a/src/win32/OamView.cpp
+++ b/src/win32/OamView.cpp
@@ -27,7 +27,7 @@
#include "WinResUtil.h"
#include "../System.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../NLS.h"
#include "../Util.h"
diff --git a/src/win32/OpenGL.cpp b/src/win32/OpenGL.cpp
index 2f7ffbdc..e5ed0aac 100644
--- a/src/win32/OpenGL.cpp
+++ b/src/win32/OpenGL.cpp
@@ -31,7 +31,7 @@
// Internals
#include "../System.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../Util.h"
#include "../dmg/gbGlobals.h"
diff --git a/src/win32/PaletteView.cpp b/src/win32/PaletteView.cpp
index f9bd7b45..69911151 100644
--- a/src/win32/PaletteView.cpp
+++ b/src/win32/PaletteView.cpp
@@ -26,7 +26,7 @@
#include "WinResUtil.h"
#include "../System.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#ifdef _DEBUG
diff --git a/src/win32/Reg.cpp b/src/win32/Reg.cpp
index 201ca7b5..60b6d5a1 100644
--- a/src/win32/Reg.cpp
+++ b/src/win32/Reg.cpp
@@ -17,7 +17,7 @@
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "stdafx.h"
-#include "..\Link.h"
+#include "..\agb\GBALink.h"
static char buffer[2048];
static HKEY vbKey = NULL;
diff --git a/src/win32/TileView.cpp b/src/win32/TileView.cpp
index 71b12fdb..83050b92 100644
--- a/src/win32/TileView.cpp
+++ b/src/win32/TileView.cpp
@@ -27,7 +27,7 @@
#include "WinResUtil.h"
#include "../System.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../NLS.h"
#include "../Util.h"
diff --git a/src/win32/VBA.cpp b/src/win32/VBA.cpp
index b873dd4c..7f960b2a 100644
--- a/src/win32/VBA.cpp
+++ b/src/win32/VBA.cpp
@@ -36,22 +36,22 @@
#include "rpi.h"
#include "../System.h"
-#include "../agbprint.h"
+#include "../agb/agbprint.h"
#include "../cheatSearch.h"
-#include "../GBA.h"
+#include "../agb/GBA.h"
#include "../Globals.h"
#include "../RTC.h"
#include "../Sound.h"
#include "../Util.h"
-#include "../gb/gbGlobals.h"
-#include "../gb/gbPrinter.h"
+#include "../dmg/gbGlobals.h"
+#include "../dmg/gbPrinter.h"
/* Link
---------------------*/
-#include "../Link.h"
+#include "../agb/GBALink.h"
/* ---------------- */
-#include "../gbafilter.h"
+#include "../agb/gbafilter.h"
#ifdef SDL
#pragma comment( lib, "SDL" )