mirror of
https://github.com/libretro/mgba.git
synced 2024-11-23 07:59:46 +00:00
Backwards compatibility patches for GCC 4.0.1 so that it compiles, links
and runs on PowerPC Mac (OSX 10.5). Anon unions no-go, anon structs in unions no-go too.
This commit is contained in:
parent
ebb5a43b16
commit
9b4ef89417
@ -25,6 +25,11 @@ ifeq ($(shell uname -a),)
|
||||
system_platform = win
|
||||
else ifneq ($(findstring Darwin,$(shell uname -a)),)
|
||||
system_platform = osx
|
||||
ifeq ($(shell uname -p),powerpc)
|
||||
arch = ppc
|
||||
else
|
||||
arch = intel
|
||||
endif
|
||||
else ifneq ($(findstring MINGW,$(shell uname -a)),)
|
||||
system_platform = win
|
||||
endif
|
||||
@ -54,6 +59,9 @@ else ifeq ($(platform), osx)
|
||||
CXXFLAGS += $(ARCHFLAGS)
|
||||
LDFLAGS += $(ARCHFLAGS)
|
||||
endif
|
||||
ifeq ($(arch),ppc)
|
||||
DEFINES += -D__POWERPC__ -D__PPC__ -DMSB_FIRST
|
||||
endif
|
||||
DEFINES += -DHAVE_LOCALE
|
||||
DEFINES += -std=c99
|
||||
# iOS
|
||||
|
@ -147,7 +147,7 @@ void ARMReset(struct ARMCore* cpu) {
|
||||
}
|
||||
|
||||
void ARMRaiseIRQ(struct ARMCore* cpu) {
|
||||
if (cpu->cpsr.i) {
|
||||
if (cpu->cpsr.a.i) {
|
||||
return;
|
||||
}
|
||||
union PSR cpsr = cpu->cpsr;
|
||||
@ -158,14 +158,14 @@ void ARMRaiseIRQ(struct ARMCore* cpu) {
|
||||
instructionWidth = WORD_SIZE_ARM;
|
||||
}
|
||||
ARMSetPrivilegeMode(cpu, MODE_IRQ);
|
||||
cpu->cpsr.priv = MODE_IRQ;
|
||||
cpu->cpsr.a.priv = MODE_IRQ;
|
||||
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM;
|
||||
cpu->gprs[ARM_PC] = BASE_IRQ;
|
||||
int currentCycles = 0;
|
||||
ARM_WRITE_PC;
|
||||
_ARMSetMode(cpu, MODE_ARM);
|
||||
cpu->spsr = cpsr;
|
||||
cpu->cpsr.i = 1;
|
||||
cpu->cpsr.a.i = 1;
|
||||
cpu->cycles += currentCycles;
|
||||
}
|
||||
|
||||
@ -178,14 +178,14 @@ void ARMRaiseSWI(struct ARMCore* cpu) {
|
||||
instructionWidth = WORD_SIZE_ARM;
|
||||
}
|
||||
ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR);
|
||||
cpu->cpsr.priv = MODE_SUPERVISOR;
|
||||
cpu->cpsr.a.priv = MODE_SUPERVISOR;
|
||||
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth;
|
||||
cpu->gprs[ARM_PC] = BASE_SWI;
|
||||
int currentCycles = 0;
|
||||
ARM_WRITE_PC;
|
||||
_ARMSetMode(cpu, MODE_ARM);
|
||||
cpu->spsr = cpsr;
|
||||
cpu->cpsr.i = 1;
|
||||
cpu->cpsr.a.i = 1;
|
||||
cpu->cycles += currentCycles;
|
||||
}
|
||||
|
||||
@ -198,14 +198,14 @@ void ARMRaiseUndefined(struct ARMCore* cpu) {
|
||||
instructionWidth = WORD_SIZE_ARM;
|
||||
}
|
||||
ARMSetPrivilegeMode(cpu, MODE_UNDEFINED);
|
||||
cpu->cpsr.priv = MODE_UNDEFINED;
|
||||
cpu->cpsr.a.priv = MODE_UNDEFINED;
|
||||
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth;
|
||||
cpu->gprs[ARM_PC] = BASE_UNDEF;
|
||||
int currentCycles = 0;
|
||||
ARM_WRITE_PC;
|
||||
_ARMSetMode(cpu, MODE_ARM);
|
||||
cpu->spsr = cpsr;
|
||||
cpu->cpsr.i = 1;
|
||||
cpu->cpsr.a.i = 1;
|
||||
cpu->cycles += currentCycles;
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ union PSR {
|
||||
unsigned z : 1;
|
||||
unsigned n : 1;
|
||||
#endif
|
||||
};
|
||||
} a;
|
||||
|
||||
int32_t packed;
|
||||
};
|
||||
|
@ -10,33 +10,33 @@
|
||||
#include "isa-inlines.h"
|
||||
|
||||
#define ADDR_MODE_1_SHIFT(OP) \
|
||||
info->op3.reg = opcode & 0x0000000F; \
|
||||
info->op3.shifterOp = ARM_SHIFT_ ## OP; \
|
||||
info->op3.shifterImm = (opcode >> 7) & 0x1F; \
|
||||
info->op3.a.reg = opcode & 0x0000000F; \
|
||||
info->op3.a.shifterOp = ARM_SHIFT_ ## OP; \
|
||||
info->op3.a.b.shifterImm = (opcode >> 7) & 0x1F; \
|
||||
info->operandFormat |= ARM_OPERAND_REGISTER_3 | \
|
||||
ARM_OPERAND_SHIFT_IMMEDIATE_3;
|
||||
|
||||
#define ADDR_MODE_1_SHIFTR(OP) \
|
||||
info->op3.reg = opcode & 0x0000000F; \
|
||||
info->op3.shifterOp = ARM_SHIFT_ ## OP; \
|
||||
info->op3.shifterReg = (opcode >> 8) & 0xF; \
|
||||
info->op3.a.reg = opcode & 0x0000000F; \
|
||||
info->op3.a.shifterOp = ARM_SHIFT_ ## OP; \
|
||||
info->op3.a.b.shifterReg = (opcode >> 8) & 0xF; \
|
||||
++info->iCycles; \
|
||||
info->operandFormat |= ARM_OPERAND_REGISTER_3 | \
|
||||
ARM_OPERAND_SHIFT_REGISTER_3;
|
||||
|
||||
#define ADDR_MODE_1_LSL \
|
||||
ADDR_MODE_1_SHIFT(LSL) \
|
||||
if (!info->op3.shifterImm) { \
|
||||
if (!info->op3.a.b.shifterImm) { \
|
||||
info->operandFormat &= ~ARM_OPERAND_SHIFT_IMMEDIATE_3; \
|
||||
info->op3.shifterOp = ARM_SHIFT_NONE; \
|
||||
info->op3.a.shifterOp = ARM_SHIFT_NONE; \
|
||||
}
|
||||
|
||||
#define ADDR_MODE_1_LSR ADDR_MODE_1_SHIFT(LSR)
|
||||
#define ADDR_MODE_1_ASR ADDR_MODE_1_SHIFT(ASR)
|
||||
#define ADDR_MODE_1_ROR \
|
||||
ADDR_MODE_1_SHIFT(ROR) \
|
||||
if (!info->op3.shifterImm) { \
|
||||
info->op3.shifterOp = ARM_SHIFT_RRX; \
|
||||
if (!info->op3.a.b.shifterImm) { \
|
||||
info->op3.a.shifterOp = ARM_SHIFT_RRX; \
|
||||
}
|
||||
|
||||
#define ADDR_MODE_1_LSLR ADDR_MODE_1_SHIFTR(LSL)
|
||||
@ -52,31 +52,31 @@
|
||||
|
||||
#define ADDR_MODE_2_SHIFT(OP) \
|
||||
info->memory.format |= ARM_MEMORY_REGISTER_OFFSET | ARM_MEMORY_SHIFTED_OFFSET; \
|
||||
info->memory.offset.shifterOp = ARM_SHIFT_ ## OP; \
|
||||
info->memory.offset.shifterImm = (opcode >> 7) & 0x1F; \
|
||||
info->memory.offset.reg = opcode & 0x0000000F;
|
||||
info->memory.offset.a.shifterOp = ARM_SHIFT_ ## OP; \
|
||||
info->memory.offset.a.b.shifterImm = (opcode >> 7) & 0x1F; \
|
||||
info->memory.offset.a.reg = opcode & 0x0000000F;
|
||||
|
||||
#define ADDR_MODE_2_LSL \
|
||||
ADDR_MODE_2_SHIFT(LSL) \
|
||||
if (!info->memory.offset.shifterImm) { \
|
||||
if (!info->memory.offset.a.b.shifterImm) { \
|
||||
info->memory.format &= ~ARM_MEMORY_SHIFTED_OFFSET; \
|
||||
info->memory.offset.shifterOp = ARM_SHIFT_NONE; \
|
||||
info->memory.offset.a.shifterOp = ARM_SHIFT_NONE; \
|
||||
}
|
||||
|
||||
#define ADDR_MODE_2_LSR ADDR_MODE_2_SHIFT(LSR) \
|
||||
if (!info->memory.offset.shifterImm) { \
|
||||
info->memory.offset.shifterImm = 32; \
|
||||
if (!info->memory.offset.a.b.shifterImm) { \
|
||||
info->memory.offset.a.b.shifterImm = 32; \
|
||||
}
|
||||
|
||||
#define ADDR_MODE_2_ASR ADDR_MODE_2_SHIFT(ASR) \
|
||||
if (!info->memory.offset.shifterImm) { \
|
||||
info->memory.offset.shifterImm = 32; \
|
||||
if (!info->memory.offset.a.b.shifterImm) { \
|
||||
info->memory.offset.a.b.shifterImm = 32; \
|
||||
}
|
||||
|
||||
#define ADDR_MODE_2_ROR \
|
||||
ADDR_MODE_2_SHIFT(ROR) \
|
||||
if (!info->memory.offset.shifterImm) { \
|
||||
info->memory.offset.shifterOp = ARM_SHIFT_RRX; \
|
||||
if (!info->memory.offset.a.b.shifterImm) { \
|
||||
info->memory.offset.a.shifterOp = ARM_SHIFT_RRX; \
|
||||
}
|
||||
|
||||
#define ADDR_MODE_2_IMM \
|
||||
@ -85,7 +85,7 @@
|
||||
|
||||
#define ADDR_MODE_3_REG \
|
||||
info->memory.format |= ARM_MEMORY_REGISTER_OFFSET; \
|
||||
info->memory.offset.reg = opcode & 0x0000000F;
|
||||
info->memory.offset.a.reg = opcode & 0x0000000F;
|
||||
|
||||
#define ADDR_MODE_3_IMM \
|
||||
info->memory.format |= ARM_MEMORY_IMMEDIATE_OFFSET; \
|
||||
@ -100,8 +100,8 @@
|
||||
|
||||
#define DEFINE_ALU_DECODER_EX_ARM(NAME, MNEMONIC, S, SHIFTER, OTHER_AFFECTED, SKIPPED) \
|
||||
DEFINE_DECODER_ARM(NAME, MNEMONIC, \
|
||||
info->op1.reg = (opcode >> 12) & 0xF; \
|
||||
info->op2.reg = (opcode >> 16) & 0xF; \
|
||||
info->op1.a.reg = (opcode >> 12) & 0xF; \
|
||||
info->op2.a.reg = (opcode >> 16) & 0xF; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
OTHER_AFFECTED | \
|
||||
ARM_OPERAND_REGISTER_2; \
|
||||
@ -114,7 +114,7 @@
|
||||
} else if (SKIPPED == 2) { \
|
||||
info->operandFormat &= ~ARM_OPERAND_2; \
|
||||
} \
|
||||
if (info->op1.reg == ARM_PC) { \
|
||||
if (info->op1.a.reg == ARM_PC) { \
|
||||
info->branchType = ARM_BRANCH_INDIRECT; \
|
||||
})
|
||||
|
||||
@ -151,26 +151,26 @@
|
||||
|
||||
#define DEFINE_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S, OTHER_AFFECTED) \
|
||||
DEFINE_DECODER_ARM(NAME, MNEMONIC, \
|
||||
info->op1.reg = (opcode >> 16) & 0xF; \
|
||||
info->op2.reg = opcode & 0xF; \
|
||||
info->op3.reg = (opcode >> 8) & 0xF; \
|
||||
info->op4.reg = (opcode >> 12) & 0xF; \
|
||||
info->op1.a.reg = (opcode >> 16) & 0xF; \
|
||||
info->op2.a.reg = opcode & 0xF; \
|
||||
info->op3.a.reg = (opcode >> 8) & 0xF; \
|
||||
info->op4.a.reg = (opcode >> 12) & 0xF; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | \
|
||||
ARM_OPERAND_REGISTER_2 | \
|
||||
ARM_OPERAND_REGISTER_3 | \
|
||||
OTHER_AFFECTED; \
|
||||
info->affectsCPSR = S; \
|
||||
if (info->op1.reg == ARM_PC) { \
|
||||
if (info->op1.a.reg == ARM_PC) { \
|
||||
info->branchType = ARM_BRANCH_INDIRECT; \
|
||||
})
|
||||
|
||||
#define DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S) \
|
||||
DEFINE_DECODER_ARM(NAME, MNEMONIC, \
|
||||
info->op1.reg = (opcode >> 12) & 0xF; \
|
||||
info->op2.reg = (opcode >> 16) & 0xF; \
|
||||
info->op3.reg = opcode & 0xF; \
|
||||
info->op4.reg = (opcode >> 8) & 0xF; \
|
||||
info->op1.a.reg = (opcode >> 12) & 0xF; \
|
||||
info->op2.a.reg = (opcode >> 16) & 0xF; \
|
||||
info->op3.a.reg = opcode & 0xF; \
|
||||
info->op4.a.reg = (opcode >> 8) & 0xF; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | \
|
||||
ARM_OPERAND_REGISTER_2 | \
|
||||
@ -178,7 +178,7 @@
|
||||
ARM_OPERAND_REGISTER_3 | \
|
||||
ARM_OPERAND_REGISTER_4; \
|
||||
info->affectsCPSR = S; \
|
||||
if (info->op1.reg == ARM_PC) { \
|
||||
if (info->op1.a.reg == ARM_PC) { \
|
||||
info->branchType = ARM_BRANCH_INDIRECT; \
|
||||
})
|
||||
|
||||
@ -192,7 +192,7 @@
|
||||
|
||||
#define DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, ADDRESSING_MODE, ADDRESSING_DECODING, CYCLES, TYPE) \
|
||||
DEFINE_DECODER_ARM(NAME, MNEMONIC, \
|
||||
info->op1.reg = (opcode >> 12) & 0xF; \
|
||||
info->op1.a.reg = (opcode >> 12) & 0xF; \
|
||||
info->memory.baseReg = (opcode >> 16) & 0xF; \
|
||||
info->memory.width = TYPE; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
@ -290,8 +290,8 @@
|
||||
#define DEFINE_SWP_DECODER_ARM(NAME, TYPE) \
|
||||
DEFINE_DECODER_ARM(NAME, SWP, \
|
||||
info->memory.baseReg = (opcode >> 16) & 0xF; \
|
||||
info->op1.reg = (opcode >> 12) & 0xF; \
|
||||
info->op2.reg = opcode & 0xF; \
|
||||
info->op1.a.reg = (opcode >> 12) & 0xF; \
|
||||
info->op2.a.reg = opcode & 0xF; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | \
|
||||
ARM_OPERAND_REGISTER_2 | \
|
||||
@ -364,7 +364,7 @@ DEFINE_DECODER_ARM(BL, BL,
|
||||
info->branchType = ARM_BRANCH_LINKED;)
|
||||
|
||||
DEFINE_DECODER_ARM(BX, BX,
|
||||
info->op1.reg = opcode & 0x0000000F;
|
||||
info->op1.a.reg = opcode & 0x0000000F;
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1;
|
||||
info->branchType = ARM_BRANCH_INDIRECT;)
|
||||
|
||||
@ -389,34 +389,34 @@ DEFINE_DECODER_ARM(ILL, ILL,
|
||||
|
||||
DEFINE_DECODER_ARM(MSR, MSR,
|
||||
info->affectsCPSR = 1;
|
||||
info->op1.reg = ARM_CPSR;
|
||||
info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
|
||||
info->op2.reg = opcode & 0x0000000F;
|
||||
info->op1.a.reg = ARM_CPSR;
|
||||
info->op1.a.b.psrBits = (opcode >> 16) & ARM_PSR_MASK;
|
||||
info->op2.a.reg = opcode & 0x0000000F;
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 |
|
||||
ARM_OPERAND_AFFECTED_1 |
|
||||
ARM_OPERAND_REGISTER_2;)
|
||||
|
||||
DEFINE_DECODER_ARM(MSRR, MSR,
|
||||
info->op1.reg = ARM_SPSR;
|
||||
info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
|
||||
info->op2.reg = opcode & 0x0000000F;
|
||||
info->op1.a.reg = ARM_SPSR;
|
||||
info->op1.a.b.psrBits = (opcode >> 16) & ARM_PSR_MASK;
|
||||
info->op2.a.reg = opcode & 0x0000000F;
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 |
|
||||
ARM_OPERAND_AFFECTED_1 |
|
||||
ARM_OPERAND_REGISTER_2;)
|
||||
|
||||
DEFINE_DECODER_ARM(MRS, MRS,
|
||||
info->affectsCPSR = 1;
|
||||
info->op1.reg = (opcode >> 12) & 0xF;
|
||||
info->op2.reg = ARM_CPSR;
|
||||
info->op2.psrBits = 0;
|
||||
info->op1.a.reg = (opcode >> 12) & 0xF;
|
||||
info->op2.a.reg = ARM_CPSR;
|
||||
info->op2.a.b.psrBits = 0;
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 |
|
||||
ARM_OPERAND_AFFECTED_1 |
|
||||
ARM_OPERAND_REGISTER_2;)
|
||||
|
||||
DEFINE_DECODER_ARM(MRSR, MRS,
|
||||
info->op1.reg = (opcode >> 12) & 0xF;
|
||||
info->op2.reg = ARM_SPSR;
|
||||
info->op2.psrBits = 0;
|
||||
info->op1.a.reg = (opcode >> 12) & 0xF;
|
||||
info->op2.a.reg = ARM_SPSR;
|
||||
info->op2.a.b.psrBits = 0;
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 |
|
||||
ARM_OPERAND_AFFECTED_1 |
|
||||
ARM_OPERAND_REGISTER_2;)
|
||||
@ -425,8 +425,8 @@ DEFINE_DECODER_ARM(MSRI, MSR,
|
||||
int rotate = (opcode & 0x00000F00) >> 7;
|
||||
int32_t operand = ROR(opcode & 0x000000FF, rotate);
|
||||
info->affectsCPSR = 1;
|
||||
info->op1.reg = ARM_CPSR;
|
||||
info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
|
||||
info->op1.a.reg = ARM_CPSR;
|
||||
info->op1.a.b.psrBits = (opcode >> 16) & ARM_PSR_MASK;
|
||||
info->op2.immediate = operand;
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 |
|
||||
ARM_OPERAND_AFFECTED_1 |
|
||||
@ -435,8 +435,8 @@ DEFINE_DECODER_ARM(MSRI, MSR,
|
||||
DEFINE_DECODER_ARM(MSRRI, MSR,
|
||||
int rotate = (opcode & 0x00000F00) >> 7;
|
||||
int32_t operand = ROR(opcode & 0x000000FF, rotate);
|
||||
info->op1.reg = ARM_SPSR;
|
||||
info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
|
||||
info->op1.a.reg = ARM_SPSR;
|
||||
info->op1.a.b.psrBits = (opcode >> 16) & ARM_PSR_MASK;
|
||||
info->op2.immediate = operand;
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 |
|
||||
ARM_OPERAND_AFFECTED_1 |
|
||||
|
@ -19,8 +19,8 @@
|
||||
#define DEFINE_IMMEDIATE_5_DECODER_DATA_THUMB(NAME, MNEMONIC) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op3.immediate = (opcode >> 6) & 0x0007; \
|
||||
info->op1.reg = opcode & 0x0007; \
|
||||
info->op2.reg = (opcode >> 3) & 0x0007; \
|
||||
info->op1.a.reg = opcode & 0x0007; \
|
||||
info->op2.a.reg = (opcode >> 3) & 0x0007; \
|
||||
info->affectsCPSR = 1; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | \
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
#define DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(NAME, MNEMONIC, CYCLES, WIDTH) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = opcode & 0x0007; \
|
||||
info->op1.a.reg = opcode & 0x0007; \
|
||||
info->memory.baseReg = (opcode >> 3) & 0x0007; \
|
||||
info->memory.offset.immediate = ((opcode >> 6) & 0x0007) * WIDTH; \
|
||||
info->memory.width = (enum ARMMemoryAccessType) WIDTH; \
|
||||
@ -52,9 +52,9 @@ DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STRH1, STR, STORE_CYCLES, 2)
|
||||
|
||||
#define DEFINE_DATA_FORM_1_DECODER_THUMB(NAME, MNEMONIC) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = opcode & 0x0007; \
|
||||
info->op2.reg = (opcode >> 3) & 0x0007; \
|
||||
info->op3.reg = (opcode >> 6) & 0x0007; \
|
||||
info->op1.a.reg = opcode & 0x0007; \
|
||||
info->op2.a.reg = (opcode >> 3) & 0x0007; \
|
||||
info->op3.a.reg = (opcode >> 6) & 0x0007; \
|
||||
info->affectsCPSR = 1; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | \
|
||||
@ -66,8 +66,8 @@ DEFINE_DATA_FORM_1_DECODER_THUMB(SUB3, SUB)
|
||||
|
||||
#define DEFINE_DATA_FORM_2_DECODER_THUMB(NAME, MNEMONIC) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = opcode & 0x0007; \
|
||||
info->op2.reg = (opcode >> 3) & 0x0007; \
|
||||
info->op1.a.reg = opcode & 0x0007; \
|
||||
info->op2.a.reg = (opcode >> 3) & 0x0007; \
|
||||
info->op3.immediate = (opcode >> 6) & 0x0007; \
|
||||
info->affectsCPSR = 1; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
@ -80,7 +80,7 @@ DEFINE_DATA_FORM_2_DECODER_THUMB(SUB1, SUB)
|
||||
|
||||
#define DEFINE_DATA_FORM_3_DECODER_THUMB(NAME, MNEMONIC, AFFECTED) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = (opcode >> 8) & 0x0007; \
|
||||
info->op1.a.reg = (opcode >> 8) & 0x0007; \
|
||||
info->op2.immediate = opcode & 0x00FF; \
|
||||
info->affectsCPSR = 1; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
@ -94,8 +94,8 @@ DEFINE_DATA_FORM_3_DECODER_THUMB(SUB2, SUB, ARM_OPERAND_AFFECTED_1)
|
||||
|
||||
#define DEFINE_DATA_FORM_5_DECODER_THUMB(NAME, MNEMONIC, AFFECTED) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = opcode & 0x0007; \
|
||||
info->op2.reg = (opcode >> 3) & 0x0007; \
|
||||
info->op1.a.reg = opcode & 0x0007; \
|
||||
info->op2.a.reg = (opcode >> 3) & 0x0007; \
|
||||
info->affectsCPSR = 1; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
AFFECTED | \
|
||||
@ -120,9 +120,9 @@ DEFINE_DATA_FORM_5_DECODER_THUMB(MVN, MVN, ARM_OPERAND_AFFECTED_1)
|
||||
|
||||
#define DEFINE_DECODER_WITH_HIGH_EX_THUMB(NAME, H1, H2, MNEMONIC, AFFECTED, CPSR) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = (opcode & 0x0007) | H1; \
|
||||
info->op2.reg = ((opcode >> 3) & 0x0007) | H2; \
|
||||
if (info->op1.reg == ARM_PC) { \
|
||||
info->op1.a.reg = (opcode & 0x0007) | H1; \
|
||||
info->op2.a.reg = ((opcode >> 3) & 0x0007) | H2; \
|
||||
if (info->op1.a.reg == ARM_PC) { \
|
||||
info->branchType = ARM_BRANCH_INDIRECT; \
|
||||
} \
|
||||
info->affectsCPSR = CPSR; \
|
||||
@ -143,8 +143,8 @@ DEFINE_DECODER_WITH_HIGH_THUMB(MOV3, MOV, ARM_OPERAND_AFFECTED_1, 0)
|
||||
|
||||
#define DEFINE_IMMEDIATE_WITH_REGISTER_DATA_THUMB(NAME, MNEMONIC, REG) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = (opcode >> 6) & 0x0007; \
|
||||
info->op2.reg = REG; \
|
||||
info->op1.a.reg = (opcode >> 6) & 0x0007; \
|
||||
info->op2.a.reg = REG; \
|
||||
info->op3.immediate = (opcode & 0x00FF) << 2; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | \
|
||||
@ -153,7 +153,7 @@ DEFINE_DECODER_WITH_HIGH_THUMB(MOV3, MOV, ARM_OPERAND_AFFECTED_1, 0)
|
||||
|
||||
#define DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(NAME, MNEMONIC, REG, CYCLES) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = (opcode >> 8) & 0x0007; \
|
||||
info->op1.a.reg = (opcode >> 8) & 0x0007; \
|
||||
info->memory.baseReg = REG; \
|
||||
info->memory.offset.immediate = (opcode & 0x00FF) << 2; \
|
||||
info->memory.width = ARM_ACCESS_WORD; \
|
||||
@ -173,8 +173,8 @@ DEFINE_IMMEDIATE_WITH_REGISTER_DATA_THUMB(ADD6, ADD, ARM_SP)
|
||||
|
||||
#define DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(NAME, MNEMONIC, CYCLES, TYPE) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->memory.offset.reg = (opcode >> 6) & 0x0007; \
|
||||
info->op1.reg = opcode & 0x0007; \
|
||||
info->memory.offset.a.reg = (opcode >> 6) & 0x0007; \
|
||||
info->op1.a.reg = opcode & 0x0007; \
|
||||
info->memory.baseReg = (opcode >> 3) & 0x0007; \
|
||||
info->memory.width = TYPE; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
@ -237,7 +237,7 @@ DEFINE_CONDITIONAL_BRANCH_THUMB(LE)
|
||||
|
||||
#define DEFINE_SP_MODIFY_THUMB(NAME, MNEMONIC) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = ARM_SP; \
|
||||
info->op1.a.reg = ARM_SP; \
|
||||
info->op2.immediate = (opcode & 0x7F) << 2; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | \
|
||||
@ -267,23 +267,23 @@ DEFINE_THUMB_DECODER(B, B,
|
||||
|
||||
DEFINE_THUMB_DECODER(BL1, BL,
|
||||
int16_t immediate = (opcode & 0x07FF) << 5;
|
||||
info->op1.reg = ARM_LR;
|
||||
info->op2.reg = ARM_PC;
|
||||
info->op1.a.reg = ARM_LR;
|
||||
info->op2.a.reg = ARM_PC;
|
||||
info->op3.immediate = (((int32_t) immediate) << 7);
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 |
|
||||
ARM_OPERAND_REGISTER_2 | ARM_OPERAND_AFFECTED_2 |
|
||||
ARM_OPERAND_IMMEDIATE_3;)
|
||||
|
||||
DEFINE_THUMB_DECODER(BL2, BL,
|
||||
info->op1.reg = ARM_PC;
|
||||
info->op2.reg = ARM_LR;
|
||||
info->op1.a.reg = ARM_PC;
|
||||
info->op2.a.reg = ARM_LR;
|
||||
info->op3.immediate = (opcode & 0x07FF) << 1;
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | ARM_OPERAND_AFFECTED_1 |
|
||||
ARM_OPERAND_REGISTER_2 | ARM_OPERAND_IMMEDIATE_3;
|
||||
info->branchType = ARM_BRANCH_LINKED;)
|
||||
|
||||
DEFINE_THUMB_DECODER(BX, BX,
|
||||
info->op1.reg = (opcode >> 3) & 0xF;
|
||||
info->op1.a.reg = (opcode >> 3) & 0xF;
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1;
|
||||
info->branchType = ARM_BRANCH_INDIRECT;)
|
||||
|
||||
@ -322,10 +322,10 @@ bool ARMDecodeThumbCombine(struct ARMInstructionInfo* info1, struct ARMInstructi
|
||||
if (info2->execMode != MODE_THUMB || info2->mnemonic != ARM_MN_BL) {
|
||||
return false;
|
||||
}
|
||||
if (info1->op1.reg != ARM_LR || info1->op2.reg != ARM_PC) {
|
||||
if (info1->op1.a.reg != ARM_LR || info1->op2.a.reg != ARM_PC) {
|
||||
return false;
|
||||
}
|
||||
if (info2->op1.reg != ARM_PC || info2->op2.reg != ARM_LR) {
|
||||
if (info2->op1.a.reg != ARM_PC || info2->op2.a.reg != ARM_LR) {
|
||||
return false;
|
||||
}
|
||||
out->op1.immediate = info1->op3.immediate | info2->op3.immediate;
|
||||
|
@ -182,7 +182,7 @@ static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer, in
|
||||
strncpy(buffer, "-", blen - 1);
|
||||
ADVANCE(1);
|
||||
}
|
||||
written = _decodeRegister(memory.offset.reg, buffer, blen);
|
||||
written = _decodeRegister(memory.offset.a.reg, buffer, blen);
|
||||
ADVANCE(written);
|
||||
}
|
||||
if (memory.format & ARM_MEMORY_SHIFTED_OFFSET) {
|
||||
@ -209,7 +209,7 @@ static int _decodeShift(union ARMOperand op, bool reg, char* buffer, int blen) {
|
||||
strncpy(buffer, ", ", blen - 1);
|
||||
ADVANCE(2);
|
||||
int written;
|
||||
switch (op.shifterOp) {
|
||||
switch (op.a.shifterOp) {
|
||||
case ARM_SHIFT_LSL:
|
||||
strncpy(buffer, "lsl ", blen - 1);
|
||||
ADVANCE(4);
|
||||
@ -232,10 +232,9 @@ static int _decodeShift(union ARMOperand op, bool reg, char* buffer, int blen) {
|
||||
return total;
|
||||
}
|
||||
if (!reg) {
|
||||
written = snprintf(buffer, blen - 1, "#%i", op.shifterImm);
|
||||
written = snprintf(buffer, blen - 1, "#%i", op.a.b.shifterImm);
|
||||
} else {
|
||||
written = _decodeRegister(op.shifterReg, buffer, blen);
|
||||
}
|
||||
written = _decodeRegister(op.a.b.shifterReg, buffer, blen); }
|
||||
ADVANCE(written);
|
||||
return total;
|
||||
}
|
||||
@ -395,10 +394,10 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
|
||||
written = _decodeMemory(info->memory, pc, buffer, blen);
|
||||
ADVANCE(written);
|
||||
} else if (info->operandFormat & ARM_OPERAND_REGISTER_1) {
|
||||
written = _decodeRegister(info->op1.reg, buffer, blen);
|
||||
written = _decodeRegister(info->op1.a.reg, buffer, blen);
|
||||
ADVANCE(written);
|
||||
if (info->op1.reg > ARM_PC) {
|
||||
written = _decodePSR(info->op1.psrBits, buffer, blen);
|
||||
if (info->op1.a.reg > ARM_PC) {
|
||||
written = _decodePSR(info->op1.a.b.psrBits, buffer, blen);
|
||||
ADVANCE(written);
|
||||
}
|
||||
}
|
||||
@ -420,7 +419,7 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
|
||||
written = _decodeMemory(info->memory, pc, buffer, blen);
|
||||
ADVANCE(written);
|
||||
} else if (info->operandFormat & ARM_OPERAND_REGISTER_2) {
|
||||
written = _decodeRegister(info->op2.reg, buffer, blen);
|
||||
written = _decodeRegister(info->op2.a.reg, buffer, blen);
|
||||
ADVANCE(written);
|
||||
}
|
||||
if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_2) {
|
||||
@ -441,7 +440,7 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
|
||||
written = _decodeMemory(info->memory, pc, buffer, blen);
|
||||
ADVANCE(written);
|
||||
} else if (info->operandFormat & ARM_OPERAND_REGISTER_3) {
|
||||
written = _decodeRegister(info->op3.reg, buffer, blen);
|
||||
written = _decodeRegister(info->op3.a.reg, buffer, blen);
|
||||
ADVANCE(written);
|
||||
}
|
||||
if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_3) {
|
||||
@ -462,7 +461,7 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
|
||||
written = _decodeMemory(info->memory, pc, buffer, blen);
|
||||
ADVANCE(written);
|
||||
} else if (info->operandFormat & ARM_OPERAND_REGISTER_4) {
|
||||
written = _decodeRegister(info->op4.reg, buffer, blen);
|
||||
written = _decodeRegister(info->op4.a.reg, buffer, blen);
|
||||
ADVANCE(written);
|
||||
}
|
||||
if (info->operandFormat & ARM_OPERAND_SHIFT_REGISTER_4) {
|
||||
|
@ -106,8 +106,8 @@ union ARMOperand {
|
||||
uint8_t shifterReg;
|
||||
uint8_t shifterImm;
|
||||
uint8_t psrBits;
|
||||
};
|
||||
};
|
||||
} b;
|
||||
} a;
|
||||
int32_t immediate;
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,7 @@ static inline void _shiftLSL(struct ARMCore* cpu, uint32_t opcode) {
|
||||
int immediate = (opcode & 0x00000F80) >> 7;
|
||||
if (!immediate) {
|
||||
cpu->shifterOperand = cpu->gprs[rm];
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = cpu->cpsr.a.c;
|
||||
} else {
|
||||
cpu->shifterOperand = cpu->gprs[rm] << immediate;
|
||||
cpu->shifterCarryOut = (cpu->gprs[rm] >> (32 - immediate)) & 1;
|
||||
@ -41,7 +41,7 @@ static inline void _shiftLSLR(struct ARMCore* cpu, uint32_t opcode) {
|
||||
}
|
||||
if (!shift) {
|
||||
cpu->shifterOperand = shiftVal;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = cpu->cpsr.a.c;
|
||||
} else if (shift < 32) {
|
||||
cpu->shifterOperand = shiftVal << shift;
|
||||
cpu->shifterCarryOut = (shiftVal >> (32 - shift)) & 1;
|
||||
@ -81,7 +81,7 @@ static inline void _shiftLSRR(struct ARMCore* cpu, uint32_t opcode) {
|
||||
}
|
||||
if (!shift) {
|
||||
cpu->shifterOperand = shiftVal;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = cpu->cpsr.a.c;
|
||||
} else if (shift < 32) {
|
||||
cpu->shifterOperand = shiftVal >> shift;
|
||||
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
|
||||
@ -121,7 +121,7 @@ static inline void _shiftASRR(struct ARMCore* cpu, uint32_t opcode) {
|
||||
}
|
||||
if (!shift) {
|
||||
cpu->shifterOperand = shiftVal;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = cpu->cpsr.a.c;
|
||||
} else if (shift < 32) {
|
||||
cpu->shifterOperand = shiftVal >> shift;
|
||||
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
|
||||
@ -142,7 +142,7 @@ static inline void _shiftROR(struct ARMCore* cpu, uint32_t opcode) {
|
||||
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||
} else {
|
||||
// RRX
|
||||
cpu->shifterOperand = (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1);
|
||||
cpu->shifterOperand = (cpu->cpsr.a.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1);
|
||||
cpu->shifterCarryOut = cpu->gprs[rm] & 0x00000001;
|
||||
}
|
||||
}
|
||||
@ -163,7 +163,7 @@ static inline void _shiftRORR(struct ARMCore* cpu, uint32_t opcode) {
|
||||
int rotate = shift & 0x1F;
|
||||
if (!shift) {
|
||||
cpu->shifterOperand = shiftVal;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = cpu->cpsr.a.c;
|
||||
} else if (rotate) {
|
||||
cpu->shifterOperand = ROR(shiftVal, rotate);
|
||||
cpu->shifterCarryOut = (shiftVal >> (rotate - 1)) & 1;
|
||||
@ -178,7 +178,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
||||
int immediate = opcode & 0x000000FF;
|
||||
if (!rotate) {
|
||||
cpu->shifterOperand = immediate;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = cpu->cpsr.a.c;
|
||||
} else {
|
||||
cpu->shifterOperand = ROR(immediate, rotate);
|
||||
cpu->shifterCarryOut = ARM_SIGN(cpu->shifterOperand);
|
||||
@ -191,40 +191,40 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
||||
#define NO_EXTEND64(V) (uint64_t)(uint32_t) (V)
|
||||
|
||||
#define ARM_ADDITION_S(M, N, D) \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.a.priv)) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
_ARMReadCPSR(cpu); \
|
||||
} else { \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = ARM_CARRY_FROM(M, N, D); \
|
||||
cpu->cpsr.v = ARM_V_ADDITION(M, N, D); \
|
||||
cpu->cpsr.a.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.a.z = !(D); \
|
||||
cpu->cpsr.a.c = ARM_CARRY_FROM(M, N, D); \
|
||||
cpu->cpsr.a.v = ARM_V_ADDITION(M, N, D); \
|
||||
}
|
||||
|
||||
#define ARM_SUBTRACTION_S(M, N, D) \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.a.priv)) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
_ARMReadCPSR(cpu); \
|
||||
} else { \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = ARM_BORROW_FROM(M, N, D); \
|
||||
cpu->cpsr.v = ARM_V_SUBTRACTION(M, N, D); \
|
||||
cpu->cpsr.a.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.a.z = !(D); \
|
||||
cpu->cpsr.a.c = ARM_BORROW_FROM(M, N, D); \
|
||||
cpu->cpsr.a.v = ARM_V_SUBTRACTION(M, N, D); \
|
||||
}
|
||||
|
||||
#define ARM_NEUTRAL_S(M, N, D) \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.a.priv)) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
_ARMReadCPSR(cpu); \
|
||||
} else { \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = cpu->shifterCarryOut; \
|
||||
cpu->cpsr.a.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.a.z = !(D); \
|
||||
cpu->cpsr.a.c = cpu->shifterCarryOut; \
|
||||
}
|
||||
|
||||
#define ARM_NEUTRAL_HI_S(DLO, DHI) \
|
||||
cpu->cpsr.n = ARM_SIGN(DHI); \
|
||||
cpu->cpsr.z = !((DHI) | (DLO));
|
||||
cpu->cpsr.a.n = ARM_SIGN(DHI); \
|
||||
cpu->cpsr.a.z = !((DHI) | (DLO));
|
||||
|
||||
#define ADDR_MODE_2_I_TEST (opcode & 0x00000F80)
|
||||
#define ADDR_MODE_2_I ((opcode & 0x00000F80) >> 7)
|
||||
@ -242,7 +242,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
||||
#define ADDR_MODE_2_LSL (cpu->gprs[rm] << ADDR_MODE_2_I)
|
||||
#define ADDR_MODE_2_LSR (ADDR_MODE_2_I_TEST ? ((uint32_t) cpu->gprs[rm]) >> ADDR_MODE_2_I : 0)
|
||||
#define ADDR_MODE_2_ASR (ADDR_MODE_2_I_TEST ? ((int32_t) cpu->gprs[rm]) >> ADDR_MODE_2_I : ((int32_t) cpu->gprs[rm]) >> 31)
|
||||
#define ADDR_MODE_2_ROR (ADDR_MODE_2_I_TEST ? ROR(cpu->gprs[rm], ADDR_MODE_2_I) : (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1))
|
||||
#define ADDR_MODE_2_ROR (ADDR_MODE_2_I_TEST ? ROR(cpu->gprs[rm], ADDR_MODE_2_I) : (cpu->cpsr.a.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1))
|
||||
|
||||
#define ADDR_MODE_3_ADDRESS ADDR_MODE_2_ADDRESS
|
||||
#define ADDR_MODE_3_RN ADDR_MODE_2_RN
|
||||
@ -440,7 +440,7 @@ DEFINE_ALU_INSTRUCTION_ARM(ADD, ARM_ADDITION_S(n, cpu->shifterOperand, cpu->gprs
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(ADC, ARM_ADDITION_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
int32_t n = cpu->gprs[rn];
|
||||
cpu->gprs[rd] = n + cpu->shifterOperand + cpu->cpsr.c;)
|
||||
cpu->gprs[rd] = n + cpu->shifterOperand + cpu->cpsr.a.c;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(AND, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = cpu->gprs[rn] & cpu->shifterOperand;)
|
||||
@ -471,12 +471,12 @@ DEFINE_ALU_INSTRUCTION_ARM(RSB, ARM_SUBTRACTION_S(cpu->shifterOperand, n, cpu->g
|
||||
cpu->gprs[rd] = cpu->shifterOperand - n;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(RSC, ARM_SUBTRACTION_S(cpu->shifterOperand, n, cpu->gprs[rd]),
|
||||
int32_t n = cpu->gprs[rn] + !cpu->cpsr.c;
|
||||
int32_t n = cpu->gprs[rn] + !cpu->cpsr.a.c;
|
||||
cpu->gprs[rd] = cpu->shifterOperand - n;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(SBC, ARM_SUBTRACTION_S(n, shifterOperand, cpu->gprs[rd]),
|
||||
int32_t n = cpu->gprs[rn];
|
||||
int32_t shifterOperand = cpu->shifterOperand + !cpu->cpsr.c;
|
||||
int32_t shifterOperand = cpu->shifterOperand + !cpu->cpsr.a.c;
|
||||
cpu->gprs[rd] = n - shifterOperand;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(SUB, ARM_SUBTRACTION_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
|
@ -10,20 +10,20 @@
|
||||
|
||||
#include "arm.h"
|
||||
|
||||
#define ARM_COND_EQ (cpu->cpsr.z)
|
||||
#define ARM_COND_NE (!cpu->cpsr.z)
|
||||
#define ARM_COND_CS (cpu->cpsr.c)
|
||||
#define ARM_COND_CC (!cpu->cpsr.c)
|
||||
#define ARM_COND_MI (cpu->cpsr.n)
|
||||
#define ARM_COND_PL (!cpu->cpsr.n)
|
||||
#define ARM_COND_VS (cpu->cpsr.v)
|
||||
#define ARM_COND_VC (!cpu->cpsr.v)
|
||||
#define ARM_COND_HI (cpu->cpsr.c && !cpu->cpsr.z)
|
||||
#define ARM_COND_LS (!cpu->cpsr.c || cpu->cpsr.z)
|
||||
#define ARM_COND_GE (!cpu->cpsr.n == !cpu->cpsr.v)
|
||||
#define ARM_COND_LT (!cpu->cpsr.n != !cpu->cpsr.v)
|
||||
#define ARM_COND_GT (!cpu->cpsr.z && !cpu->cpsr.n == !cpu->cpsr.v)
|
||||
#define ARM_COND_LE (cpu->cpsr.z || !cpu->cpsr.n != !cpu->cpsr.v)
|
||||
#define ARM_COND_EQ (cpu->cpsr.a.z)
|
||||
#define ARM_COND_NE (!cpu->cpsr.a.z)
|
||||
#define ARM_COND_CS (cpu->cpsr.a.c)
|
||||
#define ARM_COND_CC (!cpu->cpsr.a.c)
|
||||
#define ARM_COND_MI (cpu->cpsr.a.n)
|
||||
#define ARM_COND_PL (!cpu->cpsr.a.n)
|
||||
#define ARM_COND_VS (cpu->cpsr.a.v)
|
||||
#define ARM_COND_VC (!cpu->cpsr.a.v)
|
||||
#define ARM_COND_HI (cpu->cpsr.a.c && !cpu->cpsr.a.z)
|
||||
#define ARM_COND_LS (!cpu->cpsr.a.c || cpu->cpsr.a.z)
|
||||
#define ARM_COND_GE (!cpu->cpsr.a.n == !cpu->cpsr.a.v)
|
||||
#define ARM_COND_LT (!cpu->cpsr.a.n != !cpu->cpsr.a.v)
|
||||
#define ARM_COND_GT (!cpu->cpsr.a.z && !cpu->cpsr.a.n == !cpu->cpsr.a.v)
|
||||
#define ARM_COND_LE (cpu->cpsr.a.z || !cpu->cpsr.a.n != !cpu->cpsr.a.v)
|
||||
#define ARM_COND_AL 1
|
||||
|
||||
#define ARM_SIGN(I) ((I) >> 31)
|
||||
@ -81,23 +81,23 @@ static inline void _ARMSetMode(struct ARMCore* cpu, enum ExecutionMode execution
|
||||
cpu->executionMode = executionMode;
|
||||
switch (executionMode) {
|
||||
case MODE_ARM:
|
||||
cpu->cpsr.t = 0;
|
||||
cpu->cpsr.a.t = 0;
|
||||
break;
|
||||
case MODE_THUMB:
|
||||
cpu->cpsr.t = 1;
|
||||
cpu->cpsr.a.t = 1;
|
||||
}
|
||||
cpu->nextEvent = 0;
|
||||
}
|
||||
|
||||
static inline void _ARMReadCPSR(struct ARMCore* cpu) {
|
||||
_ARMSetMode(cpu, cpu->cpsr.t);
|
||||
ARMSetPrivilegeMode(cpu, cpu->cpsr.priv);
|
||||
_ARMSetMode(cpu, cpu->cpsr.a.t);
|
||||
ARMSetPrivilegeMode(cpu, cpu->cpsr.a.priv);
|
||||
cpu->irqh.readCPSR(cpu);
|
||||
}
|
||||
|
||||
static inline uint32_t _ARMPCAddress(struct ARMCore* cpu) {
|
||||
int instructionLength;
|
||||
enum ExecutionMode mode = cpu->cpsr.t;
|
||||
enum ExecutionMode mode = cpu->cpsr.a.t;
|
||||
if (mode == MODE_ARM) {
|
||||
instructionLength = WORD_SIZE_ARM;
|
||||
} else {
|
||||
|
@ -12,20 +12,20 @@
|
||||
// Beware pre-processor insanity
|
||||
|
||||
#define THUMB_ADDITION_S(M, N, D) \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = ARM_CARRY_FROM(M, N, D); \
|
||||
cpu->cpsr.v = ARM_V_ADDITION(M, N, D);
|
||||
cpu->cpsr.a.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.a.z = !(D); \
|
||||
cpu->cpsr.a.c = ARM_CARRY_FROM(M, N, D); \
|
||||
cpu->cpsr.a.v = ARM_V_ADDITION(M, N, D);
|
||||
|
||||
#define THUMB_SUBTRACTION_S(M, N, D) \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = ARM_BORROW_FROM(M, N, D); \
|
||||
cpu->cpsr.v = ARM_V_SUBTRACTION(M, N, D);
|
||||
cpu->cpsr.a.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.a.z = !(D); \
|
||||
cpu->cpsr.a.c = ARM_BORROW_FROM(M, N, D); \
|
||||
cpu->cpsr.a.v = ARM_V_SUBTRACTION(M, N, D);
|
||||
|
||||
#define THUMB_NEUTRAL_S(M, N, D) \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D);
|
||||
cpu->cpsr.a.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.a.z = !(D);
|
||||
|
||||
#define THUMB_ADDITION(D, M, N) \
|
||||
int n = N; \
|
||||
@ -65,31 +65,31 @@ DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LSL1,
|
||||
if (!immediate) {
|
||||
cpu->gprs[rd] = cpu->gprs[rm];
|
||||
} else {
|
||||
cpu->cpsr.c = (cpu->gprs[rm] >> (32 - immediate)) & 1;
|
||||
cpu->cpsr.a.c = (cpu->gprs[rm] >> (32 - immediate)) & 1;
|
||||
cpu->gprs[rd] = cpu->gprs[rm] << immediate;
|
||||
}
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
|
||||
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LSR1,
|
||||
if (!immediate) {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rm]);
|
||||
cpu->cpsr.a.c = ARM_SIGN(cpu->gprs[rm]);
|
||||
cpu->gprs[rd] = 0;
|
||||
} else {
|
||||
cpu->cpsr.c = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||
cpu->cpsr.a.c = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||
cpu->gprs[rd] = ((uint32_t) cpu->gprs[rm]) >> immediate;
|
||||
}
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
|
||||
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(ASR1,
|
||||
if (!immediate) {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rm]);
|
||||
if (cpu->cpsr.c) {
|
||||
cpu->cpsr.a.c = ARM_SIGN(cpu->gprs[rm]);
|
||||
if (cpu->cpsr.a.c) {
|
||||
cpu->gprs[rd] = 0xFFFFFFFF;
|
||||
} else {
|
||||
cpu->gprs[rd] = 0;
|
||||
}
|
||||
} else {
|
||||
cpu->cpsr.c = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||
cpu->cpsr.a.c = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||
cpu->gprs[rd] = cpu->gprs[rm] >> immediate;
|
||||
}
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
|
||||
@ -144,13 +144,13 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSL2,
|
||||
int rs = cpu->gprs[rn] & 0xFF;
|
||||
if (rs) {
|
||||
if (rs < 32) {
|
||||
cpu->cpsr.c = (cpu->gprs[rd] >> (32 - rs)) & 1;
|
||||
cpu->cpsr.a.c = (cpu->gprs[rd] >> (32 - rs)) & 1;
|
||||
cpu->gprs[rd] <<= rs;
|
||||
} else {
|
||||
if (rs > 32) {
|
||||
cpu->cpsr.c = 0;
|
||||
cpu->cpsr.a.c = 0;
|
||||
} else {
|
||||
cpu->cpsr.c = cpu->gprs[rd] & 0x00000001;
|
||||
cpu->cpsr.a.c = cpu->gprs[rd] & 0x00000001;
|
||||
}
|
||||
cpu->gprs[rd] = 0;
|
||||
}
|
||||
@ -161,13 +161,13 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSR2,
|
||||
int rs = cpu->gprs[rn] & 0xFF;
|
||||
if (rs) {
|
||||
if (rs < 32) {
|
||||
cpu->cpsr.c = (cpu->gprs[rd] >> (rs - 1)) & 1;
|
||||
cpu->cpsr.a.c = (cpu->gprs[rd] >> (rs - 1)) & 1;
|
||||
cpu->gprs[rd] = (uint32_t) cpu->gprs[rd] >> rs;
|
||||
} else {
|
||||
if (rs > 32) {
|
||||
cpu->cpsr.c = 0;
|
||||
cpu->cpsr.a.c = 0;
|
||||
} else {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
cpu->cpsr.a.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
}
|
||||
cpu->gprs[rd] = 0;
|
||||
}
|
||||
@ -178,11 +178,11 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ASR2,
|
||||
int rs = cpu->gprs[rn] & 0xFF;
|
||||
if (rs) {
|
||||
if (rs < 32) {
|
||||
cpu->cpsr.c = (cpu->gprs[rd] >> (rs - 1)) & 1;
|
||||
cpu->cpsr.a.c = (cpu->gprs[rd] >> (rs - 1)) & 1;
|
||||
cpu->gprs[rd] >>= rs;
|
||||
} else {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
if (cpu->cpsr.c) {
|
||||
cpu->cpsr.a.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
if (cpu->cpsr.a.c) {
|
||||
cpu->gprs[rd] = 0xFFFFFFFF;
|
||||
} else {
|
||||
cpu->gprs[rd] = 0;
|
||||
@ -194,11 +194,11 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ASR2,
|
||||
DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ADC,
|
||||
int n = cpu->gprs[rn];
|
||||
int d = cpu->gprs[rd];
|
||||
cpu->gprs[rd] = d + n + cpu->cpsr.c;
|
||||
cpu->gprs[rd] = d + n + cpu->cpsr.a.c;
|
||||
THUMB_ADDITION_S(d, n, cpu->gprs[rd]);)
|
||||
|
||||
DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(SBC,
|
||||
int n = cpu->gprs[rn] + !cpu->cpsr.c;
|
||||
int n = cpu->gprs[rn] + !cpu->cpsr.a.c;
|
||||
int d = cpu->gprs[rd];
|
||||
cpu->gprs[rd] = d - n;
|
||||
THUMB_SUBTRACTION_S(d, n, cpu->gprs[rd]);)
|
||||
@ -207,10 +207,10 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ROR,
|
||||
if (rs) {
|
||||
int r4 = rs & 0x1F;
|
||||
if (r4 > 0) {
|
||||
cpu->cpsr.c = (cpu->gprs[rd] >> (r4 - 1)) & 1;
|
||||
cpu->cpsr.a.c = (cpu->gprs[rd] >> (r4 - 1)) & 1;
|
||||
cpu->gprs[rd] = ROR(cpu->gprs[rd], r4);
|
||||
} else {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
cpu->cpsr.a.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
}
|
||||
}
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
|
||||
|
@ -23,7 +23,7 @@ static struct DebugBreakpoint* _lookupBreakpoint(struct DebugBreakpoint* breakpo
|
||||
|
||||
static void _checkBreakpoints(struct ARMDebugger* debugger) {
|
||||
int instructionLength;
|
||||
enum ExecutionMode mode = debugger->cpu->cpsr.t;
|
||||
enum ExecutionMode mode = debugger->cpu->cpsr.a.t;
|
||||
if (mode == MODE_ARM) {
|
||||
instructionLength = WORD_SIZE_ARM;
|
||||
} else {
|
||||
|
@ -55,12 +55,12 @@ struct DebuggerEntryInfo {
|
||||
struct {
|
||||
uint32_t oldValue;
|
||||
enum WatchpointType watchType;
|
||||
};
|
||||
} b;
|
||||
|
||||
struct {
|
||||
uint32_t opcode;
|
||||
};
|
||||
};
|
||||
} c;
|
||||
} a;
|
||||
};
|
||||
|
||||
enum DebuggerLogLevel {
|
||||
|
@ -88,17 +88,17 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
|
||||
if (!((watchpoints->address ^ address) & ~width)) {
|
||||
switch (width + 1) {
|
||||
case 1:
|
||||
info->oldValue = debugger->originalMemory.load8(debugger->cpu, address, 0);
|
||||
info->a.b.oldValue = debugger->originalMemory.load8(debugger->cpu, address, 0);
|
||||
break;
|
||||
case 2:
|
||||
info->oldValue = debugger->originalMemory.load16(debugger->cpu, address, 0);
|
||||
info->a.b.oldValue = debugger->originalMemory.load16(debugger->cpu, address, 0);
|
||||
break;
|
||||
case 4:
|
||||
info->oldValue = debugger->originalMemory.load32(debugger->cpu, address, 0);
|
||||
info->a.b.oldValue = debugger->originalMemory.load32(debugger->cpu, address, 0);
|
||||
break;
|
||||
}
|
||||
info->address = address;
|
||||
info->watchType = watchpoints->type;
|
||||
info->a.b.watchType = watchpoints->type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -686,11 +686,10 @@ void GBAHitStub(struct ARMCore* cpu, uint32_t opcode) {
|
||||
struct GBA* gba = (struct GBA*) cpu->master;
|
||||
enum GBALogLevel level = GBA_LOG_ERROR;
|
||||
if (gba->debugger) {
|
||||
struct DebuggerEntryInfo info;
|
||||
level = GBA_LOG_STUB;
|
||||
struct DebuggerEntryInfo info = {
|
||||
.address = _ARMPCAddress(cpu),
|
||||
.opcode = opcode
|
||||
};
|
||||
info.address = _ARMPCAddress(cpu);
|
||||
info.a.c.opcode = opcode;
|
||||
ARMDebuggerEnter(gba->debugger, DEBUGGER_ENTER_ILLEGAL_OP, &info);
|
||||
}
|
||||
GBALog(gba, level, "Stub opcode: %08x", opcode);
|
||||
@ -702,10 +701,9 @@ void GBAIllegal(struct ARMCore* cpu, uint32_t opcode) {
|
||||
GBALog(gba, GBA_LOG_WARN, "Illegal opcode: %08x", opcode);
|
||||
}
|
||||
if (gba->debugger) {
|
||||
struct DebuggerEntryInfo info = {
|
||||
.address = _ARMPCAddress(cpu),
|
||||
.opcode = opcode
|
||||
};
|
||||
struct DebuggerEntryInfo info;
|
||||
info.address = _ARMPCAddress(cpu);
|
||||
info.a.c.opcode = opcode;
|
||||
ARMDebuggerEnter(gba->debugger, DEBUGGER_ENTER_ILLEGAL_OP, &info);
|
||||
} else {
|
||||
ARMRaiseUndefined(cpu);
|
||||
|
@ -574,11 +574,11 @@ int32_t _gbpSioProcessEvents(struct GBASIODriver* driver, int32_t cycles) {
|
||||
}
|
||||
gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] = tx;
|
||||
gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] = tx >> 16;
|
||||
if (gbp->d.p->normalControl.irq) {
|
||||
if (gbp->d.p->a.normalControl.irq) {
|
||||
GBARaiseIRQ(gbp->p->p, IRQ_SIO);
|
||||
}
|
||||
gbp->d.p->normalControl.start = 0;
|
||||
gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt;
|
||||
gbp->d.p->a.normalControl.start = 0;
|
||||
gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->a.siocnt;
|
||||
gbp->p->gbpNextEvent = INT_MAX;
|
||||
}
|
||||
return gbp->p->gbpNextEvent;
|
||||
|
@ -598,7 +598,7 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
|
||||
}
|
||||
|
||||
case REG_SIOCNT:
|
||||
return gba->sio.siocnt;
|
||||
return gba->sio.a.siocnt;
|
||||
case REG_RCNT:
|
||||
return gba->sio.rcnt;
|
||||
|
||||
|
@ -143,7 +143,7 @@ static void _analyzeForIdleLoop(struct GBA* gba, struct ARMCore* cpu, uint32_t a
|
||||
if (info.memory.format & ARM_MEMORY_IMMEDIATE_OFFSET) {
|
||||
offset = info.memory.offset.immediate;
|
||||
} else if (info.memory.format & ARM_MEMORY_REGISTER_OFFSET) {
|
||||
int reg = info.memory.offset.reg;
|
||||
int reg = info.memory.offset.a.reg;
|
||||
if (gba->cachedRegisters[reg]) {
|
||||
gba->idleDetectionStep = -1;
|
||||
return;
|
||||
@ -160,22 +160,22 @@ static void _analyzeForIdleLoop(struct GBA* gba, struct ARMCore* cpu, uint32_t a
|
||||
return;
|
||||
}
|
||||
if ((loadAddress >> BASE_OFFSET) < REGION_CART0 || (loadAddress >> BASE_OFFSET) > REGION_CART2_EX) {
|
||||
gba->taintedRegisters[info.op1.reg] = true;
|
||||
gba->taintedRegisters[info.op1.a.reg] = true;
|
||||
} else {
|
||||
switch (info.memory.width) {
|
||||
case 1:
|
||||
gba->cachedRegisters[info.op1.reg] = GBALoad8(cpu, loadAddress, 0);
|
||||
gba->cachedRegisters[info.op1.a.reg] = GBALoad8(cpu, loadAddress, 0);
|
||||
break;
|
||||
case 2:
|
||||
gba->cachedRegisters[info.op1.reg] = GBALoad16(cpu, loadAddress, 0);
|
||||
gba->cachedRegisters[info.op1.a.reg] = GBALoad16(cpu, loadAddress, 0);
|
||||
break;
|
||||
case 4:
|
||||
gba->cachedRegisters[info.op1.reg] = GBALoad32(cpu, loadAddress, 0);
|
||||
gba->cachedRegisters[info.op1.a.reg] = GBALoad32(cpu, loadAddress, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (info.operandFormat & ARM_OPERAND_AFFECTED_1) {
|
||||
gba->taintedRegisters[info.op1.reg] = true;
|
||||
gba->taintedRegisters[info.op1.a.reg] = true;
|
||||
}
|
||||
nextAddress += WORD_SIZE_THUMB;
|
||||
break;
|
||||
|
@ -140,12 +140,12 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
||||
gba->cpu->nextEvent = state->cpu.nextEvent;
|
||||
memcpy(gba->cpu->bankedRegisters, state->cpu.bankedRegisters, 6 * 7 * sizeof(int32_t));
|
||||
memcpy(gba->cpu->bankedSPSRs, state->cpu.bankedSPSRs, 6 * sizeof(int32_t));
|
||||
gba->cpu->privilegeMode = gba->cpu->cpsr.priv;
|
||||
gba->cpu->privilegeMode = gba->cpu->cpsr.a.priv;
|
||||
gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]);
|
||||
if (state->biosPrefetch) {
|
||||
gba->memory.biosPrefetch = state->biosPrefetch;
|
||||
}
|
||||
if (gba->cpu->cpsr.t) {
|
||||
if (gba->cpu->cpsr.a.t) {
|
||||
gba->cpu->executionMode = MODE_THUMB;
|
||||
if (state->cpuPrefetch[0] && state->cpuPrefetch[1]) {
|
||||
gba->cpu->prefetch[0] = state->cpuPrefetch[0] & 0xFFFF;
|
||||
|
@ -29,7 +29,7 @@ static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mo
|
||||
}
|
||||
|
||||
static void _switchMode(struct GBASIO* sio) {
|
||||
unsigned mode = ((sio->rcnt & 0xC000) | (sio->siocnt & 0x3000)) >> 12;
|
||||
unsigned mode = ((sio->rcnt & 0xC000) | (sio->a.siocnt & 0x3000)) >> 12;
|
||||
enum GBASIOMode oldMode = sio->mode;
|
||||
if (mode < 8) {
|
||||
sio->mode = (enum GBASIOMode) (mode & 0x3);
|
||||
@ -49,7 +49,7 @@ static void _switchMode(struct GBASIO* sio) {
|
||||
|
||||
void GBASIOInit(struct GBASIO* sio) {
|
||||
sio->rcnt = RCNT_INITIAL;
|
||||
sio->siocnt = 0;
|
||||
sio->a.siocnt = 0;
|
||||
sio->mode = -1;
|
||||
sio->activeDriver = 0;
|
||||
sio->drivers.normal = 0;
|
||||
@ -131,8 +131,8 @@ void GBASIOWriteRCNT(struct GBASIO* sio, uint16_t value) {
|
||||
}
|
||||
|
||||
void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
|
||||
if ((value ^ sio->siocnt) & 0x3000) {
|
||||
sio->siocnt = value & 0x3000;
|
||||
if ((value ^ sio->a.siocnt) & 0x3000) {
|
||||
sio->a.siocnt = value & 0x3000;
|
||||
_switchMode(sio);
|
||||
}
|
||||
if (sio->activeDriver && sio->activeDriver->writeRegister) {
|
||||
@ -154,7 +154,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
sio->siocnt = value;
|
||||
sio->a.siocnt = value;
|
||||
}
|
||||
|
||||
void GBASIOWriteSIOMLT_SEND(struct GBASIO* sio, uint16_t value) {
|
||||
|
@ -60,7 +60,7 @@ struct GBASIO {
|
||||
} multiplayerControl;
|
||||
|
||||
uint16_t siocnt;
|
||||
};
|
||||
} a;
|
||||
};
|
||||
|
||||
void GBASIOInit(struct GBASIO* sio);
|
||||
|
@ -81,7 +81,7 @@ void GBASIOLockstepDetachNode(struct GBASIOLockstep* lockstep, struct GBASIOLock
|
||||
bool GBASIOLockstepNodeInit(struct GBASIODriver* driver) {
|
||||
struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver;
|
||||
node->nextEvent = LOCKSTEP_INCREMENT;
|
||||
node->d.p->multiplayerControl.slave = node->id > 0;
|
||||
node->d.p->a.multiplayerControl.slave = node->id > 0;
|
||||
GBALog(node->d.p->p, GBA_LOG_SIO, "Lockstep %i: Node init", node->id);
|
||||
return true;
|
||||
}
|
||||
@ -98,7 +98,7 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) {
|
||||
node->d.p->rcnt |= 3;
|
||||
if (node->id) {
|
||||
node->d.p->rcnt |= 4;
|
||||
node->d.p->multiplayerControl.slave = 1;
|
||||
node->d.p->a.multiplayerControl.slave = 1;
|
||||
}
|
||||
MutexUnlock(&node->p->mutex);
|
||||
return true;
|
||||
@ -122,7 +122,7 @@ static uint16_t GBASIOLockstepNodeWriteRegister(struct GBASIODriver* driver, uin
|
||||
GBALog(node->d.p->p, GBA_LOG_SIO, "Lockstep %i: Transfer initiated", node->id);
|
||||
MutexLock(&node->p->mutex);
|
||||
node->p->transferActive = true;
|
||||
node->p->transferCycles = GBASIOCyclesPerTransfer[node->d.p->multiplayerControl.baud][node->p->attached - 1];
|
||||
node->p->transferCycles = GBASIOCyclesPerTransfer[node->d.p->a.multiplayerControl.baud][node->p->attached - 1];
|
||||
node->multiSend = node->d.p->p->memory.io[REG_SIOMLT_SEND >> 1];
|
||||
MutexUnlock(&node->p->mutex);
|
||||
} else {
|
||||
@ -130,7 +130,7 @@ static uint16_t GBASIOLockstepNodeWriteRegister(struct GBASIODriver* driver, uin
|
||||
}
|
||||
}
|
||||
value &= 0xFF83;
|
||||
value |= driver->p->siocnt & 0x00FC;
|
||||
value |= driver->p->a.siocnt & 0x00FC;
|
||||
} else if (address == REG_SIOMLT_SEND) {
|
||||
GBALog(node->d.p->p, GBA_LOG_SIO, "Lockstep %i: SIOMLT_SEND <- %04x", node->id, value);
|
||||
}
|
||||
@ -176,11 +176,11 @@ static int32_t GBASIOLockstepNodeProcessEvents(struct GBASIODriver* driver, int3
|
||||
node->d.p->p->memory.io[REG_SIOMULTI3 >> 1] = node->p->multiRecv[3];
|
||||
node->d.p->rcnt |= 1;
|
||||
node->state = LOCKSTEP_IDLE;
|
||||
if (node->d.p->multiplayerControl.irq) {
|
||||
if (node->d.p->a.multiplayerControl.irq) {
|
||||
GBARaiseIRQ(node->d.p->p, IRQ_SIO);
|
||||
}
|
||||
node->d.p->multiplayerControl.id = node->id;
|
||||
node->d.p->multiplayerControl.busy = 0;
|
||||
node->d.p->a.multiplayerControl.id = node->id;
|
||||
node->d.p->a.multiplayerControl.busy = 0;
|
||||
} else if (node->state == LOCKSTEP_IDLE && node->p->transferActive) {
|
||||
node->state = LOCKSTEP_STARTED;
|
||||
node->d.p->p->memory.io[REG_SIOMULTI0 >> 1] = 0xFFFF;
|
||||
@ -190,10 +190,10 @@ static int32_t GBASIOLockstepNodeProcessEvents(struct GBASIODriver* driver, int3
|
||||
node->d.p->rcnt &= ~1;
|
||||
if (node->id) {
|
||||
node->multiSend = node->d.p->p->memory.io[REG_SIOMLT_SEND >> 1];
|
||||
node->d.p->multiplayerControl.busy = 1;
|
||||
node->d.p->a.multiplayerControl.busy = 1;
|
||||
}
|
||||
}
|
||||
node->d.p->multiplayerControl.ready = node->p->loaded == node->p->attached;
|
||||
node->d.p->a.multiplayerControl.ready = node->p->loaded == node->p->attached;
|
||||
node->nextEvent += node->p->nextEvent;
|
||||
MutexUnlock(&node->p->mutex);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user