From 7aef2948b1e260ee197a32339e85b462c7e81396 Mon Sep 17 00:00:00 2001 From: squall_leonhart69r Date: Wed, 27 Feb 2008 15:48:18 +0000 Subject: [PATCH] moved some of the GBA core files to the new agb directory and setup the paths, fixed some includes i didn't setup properly for GB. --- Makefile | 6 +- VBA.vcproj | 26 +- VBA2008.vcproj | 20 +- src/Cheats.cpp | 4 +- src/EEprom.cpp | 2 +- src/Flash.cpp | 2 +- src/GBA-arm.cpp | 2966 ----------------------- src/GBA-thumb.cpp | 2331 ------------------ src/GBA.cpp | 3983 ------------------------------- src/GBA.h | 160 -- src/GBAcpu.h | 302 --- src/GBAinline.h | 739 ------ src/Gfx.cpp | 47 - src/Gfx.h | 1602 ------------- src/Globals.cpp | 2 +- src/Link.cpp | 1083 --------- src/Link.h | 124 - src/Mode0.cpp | 4 +- src/Mode1.cpp | 4 +- src/Mode2.cpp | 4 +- src/Mode3.cpp | 4 +- src/Mode4.cpp | 4 +- src/Mode5.cpp | 4 +- src/RTC.cpp | 2 +- src/Sound.cpp | 6 +- src/Sram.cpp | 2 +- src/Util.cpp | 2 +- src/agb/placeholder.txt | 1 - src/agbprint.cpp | 99 - src/agbprint.h | 27 - src/armdis.cpp | 2 +- src/bios.cpp | 4 +- src/dmg/gbGfx.cpp | 2 +- src/dmg/gbGlobals.cpp | 2 +- src/dmg/gbMemory.cpp | 2 +- src/dmg/gbPrinter.cpp | 2 +- src/elf.cpp | 2 +- src/exprNode.cpp | 2 +- src/gbafilter.cpp | 227 -- src/gbafilter.h | 5 - src/remote.cpp | 2 +- src/win32/BugReport.cpp | 8 +- src/win32/Direct3D.cpp | 4 +- src/win32/DirectSound.cpp | 2 +- src/win32/Disassemble.cpp | 2 +- src/win32/ExportGSASnapshot.cpp | 2 +- src/win32/GBACheats.cpp | 2 +- src/win32/GBDisassemble.cpp | 4 +- src/win32/GBMapView.cpp | 2 +- src/win32/GBMemoryViewerDlg.cpp | 2 +- src/win32/GBOamView.cpp | 2 +- src/win32/GBPaletteView.cpp | 2 +- src/win32/GBTileView.cpp | 2 +- src/win32/GameOverrides.cpp | 2 +- src/win32/IOViewer.cpp | 4 +- src/win32/LinkOptions.cpp | 2 +- src/win32/MainWnd.cpp | 10 +- src/win32/MainWndCheats.cpp | 4 +- src/win32/MainWndFile.cpp | 8 +- src/win32/MainWndTools.cpp | 2 +- src/win32/MapView.cpp | 2 +- src/win32/MemoryViewerDlg.cpp | 2 +- src/win32/OamView.cpp | 2 +- src/win32/OpenGL.cpp | 2 +- src/win32/PaletteView.cpp | 2 +- src/win32/Reg.cpp | 2 +- src/win32/TileView.cpp | 2 +- src/win32/VBA.cpp | 12 +- 68 files changed, 105 insertions(+), 13801 deletions(-) delete mode 100644 src/GBA-arm.cpp delete mode 100644 src/GBA-thumb.cpp delete mode 100644 src/GBA.cpp delete mode 100644 src/GBA.h delete mode 100644 src/GBAcpu.h delete mode 100644 src/GBAinline.h delete mode 100644 src/Gfx.cpp delete mode 100644 src/Gfx.h delete mode 100644 src/Link.cpp delete mode 100644 src/Link.h delete mode 100644 src/agb/placeholder.txt delete mode 100644 src/agbprint.cpp delete mode 100644 src/agbprint.h delete mode 100644 src/gbafilter.cpp delete mode 100644 src/gbafilter.h 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> 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" )