mirror of
https://github.com/libretro/mgba.git
synced 2024-11-27 10:11:00 +00:00
GBA Memory: Simplify memory API and use fixed bus width
This commit is contained in:
parent
f0f929665e
commit
6d18b9aea5
1
CHANGES
1
CHANGES
@ -56,6 +56,7 @@ Misc:
|
||||
- Qt: Clarify some phrasing in the menus
|
||||
- GBA Memory: Implement 16- and 32-bit loads from SRAM
|
||||
- Qt: Clear active buttons when focus is lost
|
||||
- GBA Memory: Simplify memory API and use fixed bus width
|
||||
|
||||
0.1.0: (2014-12-13)
|
||||
- Initial release
|
||||
|
@ -93,11 +93,9 @@ union PSR {
|
||||
};
|
||||
|
||||
struct ARMMemory {
|
||||
int32_t (*load32)(struct ARMCore*, uint32_t address, int* cycleCounter);
|
||||
int16_t (*load16)(struct ARMCore*, uint32_t address, int* cycleCounter);
|
||||
uint16_t (*loadU16)(struct ARMCore*, uint32_t address, int* cycleCounter);
|
||||
int8_t (*load8)(struct ARMCore*, uint32_t address, int* cycleCounter);
|
||||
uint8_t (*loadU8)(struct ARMCore*, uint32_t address, int* cycleCounter);
|
||||
uint32_t (*load32)(struct ARMCore*, uint32_t address, int* cycleCounter);
|
||||
uint32_t (*load16)(struct ARMCore*, uint32_t address, int* cycleCounter);
|
||||
uint32_t (*load8)(struct ARMCore*, uint32_t address, int* cycleCounter);
|
||||
|
||||
void (*store32)(struct ARMCore*, uint32_t address, int32_t value, int* cycleCounter);
|
||||
void (*store16)(struct ARMCore*, uint32_t address, int16_t value, int* cycleCounter);
|
||||
|
@ -47,7 +47,7 @@
|
||||
#define ADDR_MODE_1_IMM \
|
||||
int rotate = (opcode & 0x00000F00) >> 7; \
|
||||
int immediate = opcode & 0x000000FF; \
|
||||
info->op3.immediate = ARM_ROR(immediate, rotate); \
|
||||
info->op3.immediate = ROR(immediate, rotate); \
|
||||
info->operandFormat |= ARM_OPERAND_IMMEDIATE_3;
|
||||
|
||||
#define ADDR_MODE_2_SHIFT(OP) \
|
||||
@ -416,7 +416,7 @@ DEFINE_DECODER_ARM(MRSR, MRS, info->affectsCPSR = 1;
|
||||
|
||||
DEFINE_DECODER_ARM(MSRI, MSR, info->affectsCPSR = 1;
|
||||
int rotate = (opcode & 0x00000F00) >> 7;
|
||||
int32_t operand = ARM_ROR(opcode & 0x000000FF, rotate);
|
||||
int32_t operand = ROR(opcode & 0x000000FF, rotate);
|
||||
info->affectsCPSR = 1;
|
||||
info->op1.reg = ARM_CPSR;
|
||||
info->op2.immediate = operand;
|
||||
@ -426,7 +426,7 @@ DEFINE_DECODER_ARM(MSRI, MSR, info->affectsCPSR = 1;
|
||||
|
||||
DEFINE_DECODER_ARM(MSRRI, MSR, info->affectsCPSR = 1;
|
||||
int rotate = (opcode & 0x00000F00) >> 7;
|
||||
int32_t operand = ARM_ROR(opcode & 0x000000FF, rotate);
|
||||
int32_t operand = ROR(opcode & 0x000000FF, rotate);
|
||||
info->affectsCPSR = 1;
|
||||
info->op1.reg = ARM_SPSR;
|
||||
info->op2.immediate = operand;
|
||||
|
@ -138,7 +138,7 @@ static inline void _shiftROR(struct ARMCore* cpu, uint32_t opcode) {
|
||||
int rm = opcode & 0x0000000F;
|
||||
int immediate = (opcode & 0x00000F80) >> 7;
|
||||
if (immediate) {
|
||||
cpu->shifterOperand = ARM_ROR(cpu->gprs[rm], immediate);
|
||||
cpu->shifterOperand = ROR(cpu->gprs[rm], immediate);
|
||||
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||
} else {
|
||||
// RRX
|
||||
@ -165,7 +165,7 @@ static inline void _shiftRORR(struct ARMCore* cpu, uint32_t opcode) {
|
||||
cpu->shifterOperand = shiftVal;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
} else if (rotate) {
|
||||
cpu->shifterOperand = ARM_ROR(shiftVal, rotate);
|
||||
cpu->shifterOperand = ROR(shiftVal, rotate);
|
||||
cpu->shifterCarryOut = (shiftVal >> (rotate - 1)) & 1;
|
||||
} else {
|
||||
cpu->shifterOperand = shiftVal;
|
||||
@ -180,7 +180,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
||||
cpu->shifterOperand = immediate;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
} else {
|
||||
cpu->shifterOperand = ARM_ROR(immediate, rotate);
|
||||
cpu->shifterOperand = ROR(immediate, rotate);
|
||||
cpu->shifterCarryOut = ARM_SIGN(cpu->shifterOperand);
|
||||
}
|
||||
}
|
||||
@ -237,7 +237,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 ? ARM_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.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
|
||||
@ -524,10 +524,10 @@ DEFINE_MULTIPLY_INSTRUCTION_ARM(UMULL,
|
||||
// Begin load/store definitions
|
||||
|
||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR, cpu->gprs[rd] = cpu->memory.load32(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, cpu->gprs[rd] = cpu->memory.loadU8(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, cpu->gprs[rd] = cpu->memory.loadU16(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, cpu->gprs[rd] = cpu->memory.load8(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSH, cpu->gprs[rd] = cpu->memory.load16(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, cpu->gprs[rd] = cpu->memory.load8(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, cpu->gprs[rd] = cpu->memory.load16(cpu, address, ¤tCycles); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, cpu->gprs[rd] = ARM_SXT_8(cpu->memory.load8(cpu, address, ¤tCycles)); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSH, cpu->gprs[rd] = ARM_SXT_16(cpu->memory.load16(cpu, address, ¤tCycles)); ARM_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR, cpu->memory.store32(cpu, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB, cpu->memory.store8(cpu, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(STRH, cpu->memory.store16(cpu, address, cpu->gprs[rd], ¤tCycles); ARM_STORE_POST_BODY;)
|
||||
@ -535,7 +535,7 @@ DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(STRH, cpu->memory.store16(cpu, address,
|
||||
DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(LDRBT,
|
||||
enum PrivilegeMode priv = cpu->privilegeMode;
|
||||
ARMSetPrivilegeMode(cpu, MODE_USER);
|
||||
cpu->gprs[rd] = cpu->memory.loadU8(cpu, address, ¤tCycles);
|
||||
cpu->gprs[rd] = cpu->memory.load8(cpu, address, ¤tCycles);
|
||||
ARMSetPrivilegeMode(cpu, priv);
|
||||
ARM_LOAD_POST_BODY;)
|
||||
|
||||
@ -583,7 +583,7 @@ DEFINE_INSTRUCTION_ARM(SWPB,
|
||||
int rm = opcode & 0xF;
|
||||
int rd = (opcode >> 12) & 0xF;
|
||||
int rn = (opcode >> 16) & 0xF;
|
||||
int32_t d = cpu->memory.loadU8(cpu, cpu->gprs[rn], ¤tCycles);
|
||||
int32_t d = cpu->memory.load8(cpu, cpu->gprs[rn], ¤tCycles);
|
||||
cpu->memory.store8(cpu, cpu->gprs[rn], cpu->gprs[rm], ¤tCycles);
|
||||
cpu->gprs[rd] = d;)
|
||||
|
||||
@ -662,7 +662,7 @@ DEFINE_INSTRUCTION_ARM(MSRI,
|
||||
int c = opcode & 0x00010000;
|
||||
int f = opcode & 0x00080000;
|
||||
int rotate = (opcode & 0x00000F00) >> 7;
|
||||
int32_t operand = ARM_ROR(opcode & 0x000000FF, rotate);
|
||||
int32_t operand = ROR(opcode & 0x000000FF, rotate);
|
||||
int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0);
|
||||
if (mask & PSR_USER_MASK) {
|
||||
cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & PSR_USER_MASK);
|
||||
@ -677,7 +677,7 @@ DEFINE_INSTRUCTION_ARM(MSRRI,
|
||||
int c = opcode & 0x00010000;
|
||||
int f = opcode & 0x00080000;
|
||||
int rotate = (opcode & 0x00000F00) >> 7;
|
||||
int32_t operand = ARM_ROR(opcode & 0x000000FF, rotate);
|
||||
int32_t operand = ROR(opcode & 0x000000FF, rotate);
|
||||
int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0);
|
||||
mask &= PSR_USER_MASK | PSR_PRIV_MASK | PSR_STATE_MASK;
|
||||
cpu->spsr.packed = (cpu->spsr.packed & ~mask) | (operand & mask);)
|
||||
|
@ -27,8 +27,8 @@
|
||||
#define ARM_COND_AL 1
|
||||
|
||||
#define ARM_SIGN(I) ((I) >> 31)
|
||||
#define ARM_ROR(I, ROTATE) ((((uint32_t) (I)) >> ROTATE) | ((uint32_t) (I) << ((-ROTATE) & 31)))
|
||||
|
||||
#define ARM_SXT_8(I) (((int8_t) (I) << 24) >> 24)
|
||||
#define ARM_SXT_16(I) (((int16_t) (I) << 16) >> 16)
|
||||
|
||||
#define ARM_CARRY_FROM(M, N, D) (((uint32_t) (M) >> 31) + ((uint32_t) (N) >> 31) > ((uint32_t) (D) >> 31))
|
||||
#define ARM_BORROW_FROM(M, N, D) (((uint32_t) (M)) >= ((uint32_t) (N)))
|
||||
|
@ -97,8 +97,8 @@ DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(ASR1,
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
|
||||
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDR1, cpu->gprs[rd] = cpu->memory.load32(cpu, cpu->gprs[rm] + immediate * 4, ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRB1, cpu->gprs[rd] = cpu->memory.loadU8(cpu, cpu->gprs[rm] + immediate, ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRH1, cpu->gprs[rd] = cpu->memory.loadU16(cpu, cpu->gprs[rm] + immediate * 2, ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRB1, cpu->gprs[rd] = cpu->memory.load8(cpu, cpu->gprs[rm] + immediate, ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LDRH1, cpu->gprs[rd] = cpu->memory.load16(cpu, cpu->gprs[rm] + immediate * 2, ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(STR1, cpu->memory.store32(cpu, cpu->gprs[rm] + immediate * 4, cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(STRB1, cpu->memory.store8(cpu, cpu->gprs[rm] + immediate, cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(STRH1, cpu->memory.store16(cpu, cpu->gprs[rm] + immediate * 2, cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
@ -219,7 +219,7 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ROR,
|
||||
int r4 = rs & 0x1F;
|
||||
if (r4 > 0) {
|
||||
cpu->cpsr.c = (cpu->gprs[rd] >> (r4 - 1)) & 1;
|
||||
cpu->gprs[rd] = ARM_ROR(cpu->gprs[rd], r4);
|
||||
cpu->gprs[rd] = ROR(cpu->gprs[rd], r4);
|
||||
} else {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
}
|
||||
@ -286,10 +286,10 @@ DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(ADD6, cpu->gprs[rd] = cpu->gprs[ARM_SP] + i
|
||||
COUNT_CALL_3(DEFINE_LOAD_STORE_WITH_REGISTER_EX_THUMB, NAME ## _R, BODY)
|
||||
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDR2, cpu->gprs[rd] = cpu->memory.load32(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRB2, cpu->gprs[rd] = cpu->memory.loadU8(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRH2, cpu->gprs[rd] = cpu->memory.loadU16(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSB, cpu->gprs[rd] = cpu->memory.load8(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSH, cpu->gprs[rd] = cpu->memory.load16(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRB2, cpu->gprs[rd] = cpu->memory.load8(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRH2, cpu->gprs[rd] = cpu->memory.load16(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSB, cpu->gprs[rd] = ARM_SXT_8(cpu->memory.load8(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles)); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSH, cpu->gprs[rd] = ARM_SXT_16(cpu->memory.load16(cpu, cpu->gprs[rn] + cpu->gprs[rm], ¤tCycles)); THUMB_LOAD_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STR2, cpu->memory.store32(cpu, cpu->gprs[rn] + cpu->gprs[rm], cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRB2, cpu->memory.store8(cpu, cpu->gprs[rn] + cpu->gprs[rm], cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, cpu->memory.store16(cpu, cpu->gprs[rn] + cpu->gprs[rm], cpu->gprs[rd], ¤tCycles); THUMB_STORE_POST_BODY;)
|
||||
|
@ -69,4 +69,7 @@
|
||||
|
||||
#define LIKELY(X) __builtin_expect(!!(X), 1)
|
||||
#define UNLIKELY(X) __builtin_expect(!!(X), 0)
|
||||
|
||||
#define ROR(I, ROTATE) ((((uint32_t) (I)) >> ROTATE) | ((uint32_t) (I) << ((-ROTATE) & 31)))
|
||||
|
||||
#endif
|
||||
|
@ -248,7 +248,7 @@ static inline void _printLine(struct CLIDebugger* debugger, uint32_t address, en
|
||||
ARMDisassemble(&info, address + WORD_SIZE_ARM * 2, disassembly, sizeof(disassembly));
|
||||
printf("%08X\t%s\n", instruction, disassembly);
|
||||
} else {
|
||||
uint16_t instruction = debugger->d.cpu->memory.loadU16(debugger->d.cpu, address, 0);
|
||||
uint16_t instruction = debugger->d.cpu->memory.load16(debugger->d.cpu, address, 0);
|
||||
ARMDecodeThumb(instruction, &info);
|
||||
ARMDisassemble(&info, address + WORD_SIZE_THUMB * 2, disassembly, sizeof(disassembly));
|
||||
printf("%04X\t%s\n", instruction, disassembly);
|
||||
@ -287,7 +287,7 @@ static void _readByte(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||
return;
|
||||
}
|
||||
uint32_t address = dv->intValue;
|
||||
uint8_t value = debugger->d.cpu->memory.loadU8(debugger->d.cpu, address, 0);
|
||||
uint8_t value = debugger->d.cpu->memory.load8(debugger->d.cpu, address, 0);
|
||||
printf(" 0x%02X\n", value);
|
||||
}
|
||||
|
||||
@ -303,7 +303,7 @@ static void _readHalfword(struct CLIDebugger* debugger, struct CLIDebugVector* d
|
||||
return;
|
||||
}
|
||||
uint32_t address = dv->intValue;
|
||||
uint16_t value = debugger->d.cpu->memory.loadU16(debugger->d.cpu, address, 0);
|
||||
uint16_t value = debugger->d.cpu->memory.load16(debugger->d.cpu, address & ~1, 0);
|
||||
printf(" 0x%04X\n", value);
|
||||
}
|
||||
|
||||
@ -313,7 +313,7 @@ static void _readWord(struct CLIDebugger* debugger, struct CLIDebugVector* dv) {
|
||||
return;
|
||||
}
|
||||
uint32_t address = dv->intValue;
|
||||
uint32_t value = debugger->d.cpu->memory.load32(debugger->d.cpu, address, 0);
|
||||
uint32_t value = debugger->d.cpu->memory.load32(debugger->d.cpu, address & ~3, 0);
|
||||
printf(" 0x%08X\n", value);
|
||||
}
|
||||
|
||||
|
@ -40,11 +40,9 @@ static bool _checkWatchpoints(struct DebugBreakpoint* watchpoints, uint32_t addr
|
||||
return debugger->originalMemory.NAME(cpu, ARGS); \
|
||||
}
|
||||
|
||||
CREATE_WATCHPOINT_SHIM(load32, 4, int32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(load16, 2, int16_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(loadU16, 2, uint16_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(load8, 1, int8_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(loadU8, 1, uint8_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(load32, 4, uint32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(load16, 2, uint32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(load8, 1, uint32_t, (struct ARMCore* cpu, uint32_t address, int* cycleCounter), address, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(store32, 4, void, (struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter), address, value, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(store16, 2, void, (struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter), address, value, cycleCounter)
|
||||
CREATE_WATCHPOINT_SHIM(store8, 1, void, (struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCounter), address, value, cycleCounter)
|
||||
@ -67,9 +65,7 @@ void ARMDebuggerInstallMemoryShim(struct ARMDebugger* debugger) {
|
||||
debugger->cpu->memory.store8 = ARMDebuggerShim_store8;
|
||||
debugger->cpu->memory.load32 = ARMDebuggerShim_load32;
|
||||
debugger->cpu->memory.load16 = ARMDebuggerShim_load16;
|
||||
debugger->cpu->memory.loadU16 = ARMDebuggerShim_loadU16;
|
||||
debugger->cpu->memory.load8 = ARMDebuggerShim_load8;
|
||||
debugger->cpu->memory.loadU8 = ARMDebuggerShim_loadU8;
|
||||
debugger->cpu->memory.setActiveRegion = ARMDebuggerShim_setActiveRegion;
|
||||
}
|
||||
|
||||
@ -79,8 +75,6 @@ void ARMDebuggerRemoveMemoryShim(struct ARMDebugger* debugger) {
|
||||
debugger->cpu->memory.store8 = debugger->originalMemory.store8;
|
||||
debugger->cpu->memory.load32 = debugger->originalMemory.load32;
|
||||
debugger->cpu->memory.load16 = debugger->originalMemory.load16;
|
||||
debugger->cpu->memory.loadU16 = debugger->originalMemory.loadU16;
|
||||
debugger->cpu->memory.load8 = debugger->originalMemory.load8;
|
||||
debugger->cpu->memory.loadU8 = debugger->originalMemory.loadU8;
|
||||
debugger->cpu->memory.setActiveRegion = debugger->originalMemory.setActiveRegion;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ static void _BgAffineSet(struct GBA* gba) {
|
||||
cy = cpu->memory.load16(cpu, offset + 10, 0);
|
||||
sx = cpu->memory.load16(cpu, offset + 12, 0) / 256.f;
|
||||
sy = cpu->memory.load16(cpu, offset + 14, 0) / 256.f;
|
||||
theta = (cpu->memory.loadU16(cpu, offset + 16, 0) >> 8) / 128.f * M_PI;
|
||||
theta = (cpu->memory.load16(cpu, offset + 16, 0) >> 8) / 128.f * M_PI;
|
||||
offset += 20;
|
||||
// Rotation
|
||||
a = d = cosf(theta);
|
||||
@ -131,7 +131,7 @@ static void _ObjAffineSet(struct GBA* gba) {
|
||||
// [ 0 sy ] * [ sin(theta) cos(theta) ] = [ C D ]
|
||||
sx = cpu->memory.load16(cpu, offset, 0) / 256.f;
|
||||
sy = cpu->memory.load16(cpu, offset + 2, 0) / 256.f;
|
||||
theta = (cpu->memory.loadU16(cpu, offset + 4, 0) >> 8) / 128.f * M_PI;
|
||||
theta = (cpu->memory.load16(cpu, offset + 4, 0) >> 8) / 128.f * M_PI;
|
||||
offset += 8;
|
||||
// Rotation
|
||||
a = d = cosf(theta);
|
||||
@ -321,13 +321,13 @@ static void _unLz77(struct GBA* gba, int width) {
|
||||
if (blocksRemaining) {
|
||||
if (blockheader & 0x80) {
|
||||
// Compressed
|
||||
block = cpu->memory.loadU8(cpu, source, 0) | (cpu->memory.loadU8(cpu, source + 1, 0) << 8);
|
||||
block = cpu->memory.load8(cpu, source, 0) | (cpu->memory.load8(cpu, source + 1, 0) << 8);
|
||||
source += 2;
|
||||
disp = dest - (((block & 0x000F) << 8) | ((block & 0xFF00) >> 8)) - 1;
|
||||
bytes = ((block & 0x00F0) >> 4) + 3;
|
||||
while (bytes-- && remaining) {
|
||||
--remaining;
|
||||
byte = cpu->memory.loadU8(cpu, disp, 0);
|
||||
byte = cpu->memory.load8(cpu, disp, 0);
|
||||
++disp;
|
||||
if (width == 2) {
|
||||
if (dest & 1) {
|
||||
@ -343,7 +343,7 @@ static void _unLz77(struct GBA* gba, int width) {
|
||||
}
|
||||
} else {
|
||||
// Uncompressed
|
||||
byte = cpu->memory.loadU8(cpu, source, 0);
|
||||
byte = cpu->memory.load8(cpu, source, 0);
|
||||
++source;
|
||||
if (width == 2) {
|
||||
if (dest & 1) {
|
||||
@ -361,7 +361,7 @@ static void _unLz77(struct GBA* gba, int width) {
|
||||
blockheader <<= 1;
|
||||
--blocksRemaining;
|
||||
} else {
|
||||
blockheader = cpu->memory.loadU8(cpu, source, 0);
|
||||
blockheader = cpu->memory.load8(cpu, source, 0);
|
||||
++source;
|
||||
blocksRemaining = 8;
|
||||
}
|
||||
@ -390,7 +390,7 @@ static void _unHuffman(struct GBA* gba) {
|
||||
int padding = (4 - remaining) & 0x3;
|
||||
remaining &= 0xFFFFFFFC;
|
||||
// We assume the signature byte (0x20) is correct
|
||||
int treesize = (cpu->memory.loadU8(cpu, source + 4, 0) << 1) + 1;
|
||||
int treesize = (cpu->memory.load8(cpu, source + 4, 0) << 1) + 1;
|
||||
int block = 0;
|
||||
uint32_t treeBase = source + 5;
|
||||
source += 5 + treesize;
|
||||
@ -458,13 +458,13 @@ static void _unRl(struct GBA* gba, int width) {
|
||||
uint32_t dest = cpu->gprs[1];
|
||||
int halfword = 0;
|
||||
while (remaining > 0) {
|
||||
blockheader = cpu->memory.loadU8(cpu, source, 0);
|
||||
blockheader = cpu->memory.load8(cpu, source, 0);
|
||||
++source;
|
||||
if (blockheader & 0x80) {
|
||||
// Compressed
|
||||
blockheader &= 0x7F;
|
||||
blockheader += 3;
|
||||
block = cpu->memory.loadU8(cpu, source, 0);
|
||||
block = cpu->memory.load8(cpu, source, 0);
|
||||
++source;
|
||||
while (blockheader-- && remaining) {
|
||||
--remaining;
|
||||
@ -485,7 +485,7 @@ static void _unRl(struct GBA* gba, int width) {
|
||||
blockheader++;
|
||||
while (blockheader-- && remaining) {
|
||||
--remaining;
|
||||
int byte = cpu->memory.loadU8(cpu, source, 0);
|
||||
int byte = cpu->memory.load8(cpu, source, 0);
|
||||
++source;
|
||||
if (width == 2) {
|
||||
if (dest & 1) {
|
||||
@ -532,9 +532,9 @@ static void _unFilter(struct GBA* gba, int inwidth, int outwidth) {
|
||||
while (remaining > 0) {
|
||||
uint16_t new;
|
||||
if (inwidth == 1) {
|
||||
new = cpu->memory.loadU8(cpu, source, 0);
|
||||
new = cpu->memory.load8(cpu, source, 0);
|
||||
} else {
|
||||
new = cpu->memory.loadU16(cpu, source, 0);
|
||||
new = cpu->memory.load16(cpu, source, 0);
|
||||
}
|
||||
new += old;
|
||||
if (outwidth > inwidth) {
|
||||
|
@ -31,9 +31,7 @@ void GBAMemoryInit(struct GBA* gba) {
|
||||
struct ARMCore* cpu = gba->cpu;
|
||||
cpu->memory.load32 = GBALoad32;
|
||||
cpu->memory.load16 = GBALoad16;
|
||||
cpu->memory.loadU16 = GBALoadU16;
|
||||
cpu->memory.load8 = GBALoad8;
|
||||
cpu->memory.loadU8 = GBALoadU8;
|
||||
cpu->memory.loadMultiple = GBALoadMultiple;
|
||||
cpu->memory.store32 = GBAStore32;
|
||||
cpu->memory.store16 = GBAStore16;
|
||||
@ -227,7 +225,7 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
||||
value |= value << 8; \
|
||||
value |= value << 16;
|
||||
|
||||
int32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
uint32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
struct GBA* gba = (struct GBA*) cpu->master;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
uint32_t value = 0;
|
||||
@ -278,17 +276,13 @@ int32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
}
|
||||
// Unaligned 32-bit loads are "rotated" so they make some semblance of sense
|
||||
int rotate = (address & 3) << 3;
|
||||
return (value >> rotate) | (value << (32 - rotate));
|
||||
return ROR(value, rotate);
|
||||
}
|
||||
|
||||
uint16_t GBALoadU16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
return GBALoad16(cpu, address, cycleCounter);
|
||||
}
|
||||
|
||||
int16_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
struct GBA* gba = (struct GBA*) cpu->master;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
uint16_t value = 0;
|
||||
uint32_t value = 0;
|
||||
int wait = 0;
|
||||
|
||||
switch (address >> BASE_OFFSET) {
|
||||
@ -373,17 +367,13 @@ int16_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
}
|
||||
// Unaligned 16-bit loads are "unpredictable", but the GBA rotates them, so we have to, too.
|
||||
int rotate = (address & 1) << 3;
|
||||
return (value >> rotate) | (value << (16 - rotate));
|
||||
return ROR(value, rotate);
|
||||
}
|
||||
|
||||
uint8_t GBALoadU8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
return GBALoad8(cpu, address, cycleCounter);
|
||||
}
|
||||
|
||||
int8_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||
struct GBA* gba = (struct GBA*) cpu->master;
|
||||
struct GBAMemory* memory = &gba->memory;
|
||||
int8_t value = 0;
|
||||
uint8_t value = 0;
|
||||
int wait = 0;
|
||||
|
||||
switch (address >> BASE_OFFSET) {
|
||||
|
@ -144,11 +144,9 @@ void GBAMemoryDeinit(struct GBA* gba);
|
||||
|
||||
void GBAMemoryReset(struct GBA* gba);
|
||||
|
||||
int32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
|
||||
int16_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
|
||||
uint16_t GBALoadU16(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
|
||||
int8_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
|
||||
uint8_t GBALoadU8(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
|
||||
uint32_t GBALoad32(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
|
||||
uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
|
||||
uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter);
|
||||
|
||||
void GBAStore32(struct ARMCore* cpu, uint32_t address, int32_t value, int* cycleCounter);
|
||||
void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycleCounter);
|
||||
|
Loading…
Reference in New Issue
Block a user